• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ Slowly dying monsters (OTHire 0.0.3) [Solved]

jakub742

New Member
Joined
May 1, 2010
Messages
81
Solutions
1
Reaction score
3
Location
Slovakia
Hi. If i kill a creature its dying very slowly till the corpse is created. If im using spell that is attacking the monsters at screen, sometimes its also targeting a dying monsters and it looks weird. Also they dont die at the same time.

Using OTHire 0.0.3 distro.

bXqxlK8AtP.gif
 
Solution
Had a quick look at it, and if I am not mistaken, it has to do with the EVENT_CHECK_CREATURE_INTERVAL, which is used as a delay in Game::checkCreatures()

If it doesn't hurt you that much you can let it be, else you can try reduce EVENT_CREATURE_THINK_INTERVAL. It is currently defined at 1000 in creature.h. But I don't recomend it because it might affect other parts of the code.

And note: I might be fully wrong.

Marcus

User.postCount++;
Joined
Nov 14, 2015
Messages
1,080
Solutions
10
Reaction score
382
Location
Sweden
In sources somewhere, there's something similar to "addevent" for the function that make the monster die.
Normally it's a random function that decide how long it will take before the creature falls.
 
OP
OP
J

jakub742

New Member
Joined
May 1, 2010
Messages
81
Solutions
1
Reaction score
3
Location
Slovakia
I see addevent only with addeventWalk
Creature.cpp
Code:
void Creature::onDie()
{
    DeathList killers = getKillers(g_config.getNumber(ConfigManager::DEATH_ASSIST_COUNT));

    for(DeathList::const_iterator it = killers.begin(); it != killers.end(); ++it){
        if(it->isCreatureKill()){
            Creature* attacker = it->getKillerCreature();
            if(attacker){
                attacker->onKilledCreature(this, (it == killers.begin()));
            }
        }
    }
   
    std::map<Creature*, uint64_t> experienceMap;

    for(CountMap::iterator it = damageMap.begin(); it != damageMap.end(); ++it){
        if(Creature* attacker = g_game.getCreatureByID((*it).first)){
            if (attacker != this) {
                uint64_t gainExp = getGainedExperience(attacker);
                if (Player* player = attacker->getPlayer()) {
                    Party* party = player->getParty();
                    if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
                        attacker = party->getLeader();
                    }
                }

                std::map<Creature*, uint64_t>::iterator it = experienceMap.find(attacker);
                if (it == experienceMap.end()) {
                    experienceMap[attacker] = gainExp;
                } else {
                    it->second += gainExp;
                }
            }
        }
    }

    dropCorpse();
    die();
   
    bool fromMonster = false;
    if (this->getMonster()) {
        fromMonster = true;
    }
   
    for (std::map<Creature*, uint64_t>::iterator it = experienceMap.begin(); it != experienceMap.end(); it++) {
        it->first->onGainExperience(it->second, fromMonster);
    }

    if(getMaster()){
        getMaster()->removeSummon(this);
    }
}


void Creature::die()
{
    g_game.removeCreature(this, false);
}

monster.cpp
Code:
void Monster::die()
{
    setAttackedCreature(NULL);
    destroySummons();
    clearTargetList();
    clearFriendList();
    onIdleStatus();
    Creature::die();
}

Item* Monster::createCorpse()
{
    Item* corpse = Creature::createCorpse();
    return corpse;
}
 

ond

Veteran OT User
Joined
Mar 24, 2008
Messages
2,742
Solutions
21
Reaction score
462
Location
Sweden
Had a quick look at it, and if I am not mistaken, it has to do with the EVENT_CHECK_CREATURE_INTERVAL, which is used as a delay in Game::checkCreatures()

If it doesn't hurt you that much you can let it be, else you can try reduce EVENT_CREATURE_THINK_INTERVAL. It is currently defined at 1000 in creature.h. But I don't recomend it because it might affect other parts of the code.

And note: I might be fully wrong.
 
Solution

jlnunez89

a.k.a BurnMc
Premium User
Joined
Jul 5, 2007
Messages
175
Solutions
1
Reaction score
68
Location
Seattle, WA
Lol. I was around when otserv began and it was the exact opposite. Now ppl want that? oh well..

For the record, having all die the exact moment they are killed was way more weird :)
 
Last edited:
OP
OP
J

jakub742

New Member
Joined
May 1, 2010
Messages
81
Solutions
1
Reaction score
3
Location
Slovakia
I changed the #define EVENT_CREATURE_THINK_INTERVAL to 500. The delay is smaller and everythink looks OK. They still dont die at the exact same time but thats ok. I check the game.cpp and found this
Code:
void Game::checkCreatures()
{
    g_scheduler.addEvent(createSchedulerTask(
        EVENT_CHECK_CREATURE_INTERVAL, boost::bind(&Game::checkCreatures, this)));

    Creature* creature;
    std::vector<Creature*>::iterator it;

    //add any new creatures
    for(it = toAddCheckCreatureVector.begin(); it != toAddCheckCreatureVector.end(); ++it){
        creature = (*it);
        checkCreatureVectors[creature->checkCreatureVectorIndex].push_back(creature);
    }
    toAddCheckCreatureVector.clear();

    checkCreatureLastIndex++;
    if(checkCreatureLastIndex == EVENT_CREATURECOUNT){
        checkCreatureLastIndex = 0;
    }

    std::vector<Creature*>& checkCreatureVector = checkCreatureVectors[checkCreatureLastIndex];

    for(it = checkCreatureVector.begin(); it != checkCreatureVector.end();){
        creature = (*it);

        if(creature->creatureCheck){
            if(creature->getHealth() > 0){
                creature->onThink(EVENT_CREATURE_THINK_INTERVAL);
            }
            else{
                creature->onDie();
            }
            ++it;
        }
        else{
            creature->checkCreatureVectorIndex = -1;
            it = checkCreatureVector.erase(it);
            FreeThing(creature);
        }
    }

    cleanup();
}

So i guess thats okay because its checking one creature per iteration.
 

ond

Veteran OT User
Joined
Mar 24, 2008
Messages
2,742
Solutions
21
Reaction score
462
Location
Sweden
They don't drop at the same time since they were not spawned at the exact same time (again speculation)
 
OP
OP
J

jakub742

New Member
Joined
May 1, 2010
Messages
81
Solutions
1
Reaction score
3
Location
Slovakia
So it should not be a problem with setting #define EVENT_CREATURE_THINK_INTERVAL to 500 right ?. I checked some distros and some of them had 500 too.
 

ond

Veteran OT User
Joined
Mar 24, 2008
Messages
2,742
Solutions
21
Reaction score
462
Location
Sweden
So it should not be a problem with setting #define EVENT_CREATURE_THINK_INTERVAL to 500 right ?. I checked some distros and some of them had 500 too.
Well it depends on what you want to achieve. Do you want the monsters to die and become corpses instantly or do you just want them to drop at the same time? Because the latter is probably not so tricky, to make newly created monsters fit the onThink interval simultaneously with current, alive, creatures.

As the code is created now, we need to constantly check the creatures being "alive" and that is what the checkCreatures function does. However, I don't think it's impossible to make it so you check creature health (if creature should be alive or not) when damage has ben dealt to it, which means you can make the corpse drop in an instance.

But to me it seems like a lot of work for basically nothing more than aesthetics
 
OP
OP
J

jakub742

New Member
Joined
May 1, 2010
Messages
81
Solutions
1
Reaction score
3
Location
Slovakia
Well it depends on what you want to achieve. Do you want the monsters to die and become corpses instantly or do you just want them to drop at the same time? Because the latter is probably not so tricky, to make newly created monsters fit the onThink interval simultaneously with current, alive, creatures.

As the code is created now, we need to constantly check the creatures being "alive" and that is what the checkCreatures function does. However, I don't think it's impossible to make it so you check creature health (if creature should be alive or not) when damage has ben dealt to it, which means you can make the corpse drop in an instance.

But to me it seems like a lot of work for basically nothing more than aesthetics
Yea i dont care about dropping the corpse at the same time. I just wanted to lower the interval from die() to dropCorpse() and i achieved that. Thanks for your help ;)
 
Top