• 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++ monster ranged attack tfs 1.5 are very off is there a way to fix this?

Diarreamental

Well-Known Member
Joined
Jul 6, 2015
Messages
453
Solutions
1
Reaction score
80
Hello

As stated in the title ranged attack are off like gfb , spears or any ranged attack made by monsters

doing a research i found that nostarlius based off tfs 1.2 was having or has this problem too, they have fixed it by changing normal_random to unfirom_random in sources Nostalrius 7.7 (https://otland.net/threads/nostalrius-7-7.262406/page-18)
the code is this:
Lua:
void Monster::onThinkDefense(uint32_t)
{
    for (const spellBlock_t& spellBlock : mType->info.defenseSpells) {
        if (uniform_random(0, spellBlock.chance) == 0 && (master || health > mType->info.runAwayHealth || uniform_random(1, 3) == 1)) {
            minCombatValue = spellBlock.minCombatValue;
            maxCombatValue = spellBlock.maxCombatValue;
            spellBlock.spell->castSpell(this, this);
        }
    }

    if (!isSummon() && summons.size() < mType->info.maxSummons && hasFollowPath) {
        for (const summonBlock_t& summonBlock : mType->info.summons) {
            if (summons.size() >= mType->info.maxSummons) {
                continue;
            }

            uint32_t summonCount = 0;
            for (Creature* summon : summons) {
                if (summon->getName() == summonBlock.name) {
                    ++summonCount;
                }
            }

            if (summonCount >= summonBlock.max) {
                continue;
            }

            if (uniform_random(0, summonBlock.chance) == 0 && (health > mType->info.runAwayHealth || uniform_random(1, 3) == 1)) {
                Monster* summon = Monster::createMonster(summonBlock.name);
                if (summon) {
                    const Position& summonPos = getPosition();

                    addSummon(summon);

                    if (!g_game.placeCreature(summon, summonPos, false, summonBlock.force)) {
                        removeSummon(summon);
                    } else {
                        g_game.addMagicEffect(getPosition(), CONST_ME_MAGIC_BLUE);
                        g_game.addMagicEffect(summon->getPosition(), CONST_ME_TELEPORT);
                    }
                }
            }
        }
    }
}
the other part:
Code:
void Monster::doAttacking(uint32_t)
{
    if (!attackedCreature || (isSummon() && attackedCreature == this)) {
        return;
    }

    const Position& myPos = getPosition();
    const Position& targetPos = attackedCreature->getPosition();

    bool updateLook = false;

    if (OTSYS_TIME() >= earliestAttackTime && !isFleeing()) {
        updateLook = true;
        if (Combat::closeAttack(this, attackedCreature, FIGHTMODE_BALANCED)) {
            egibleToDance = true;
            earliestAttackTime = OTSYS_TIME() + 2000;
            removeCondition(CONDITION_AGGRESSIVE, true);
        }
    }

    for (spellBlock_t& spellBlock : mType->info.attackSpells) {
        if (spellBlock.range != 0 && std::max<uint32_t>(Position::getDistanceX(myPos, targetPos), Position::getDistanceY(myPos, targetPos)) <= spellBlock.range) {
            if (uniform_random(0, spellBlock.chance) == 0 && (master || health > mType->info.runAwayHealth || uniform_random(1, 3) == 1)) {
                updateLookDirection();

                minCombatValue = spellBlock.minCombatValue;
                maxCombatValue = spellBlock.maxCombatValue;

                spellBlock.spell->castSpell(this, attackedCreature);
                egibleToDance = true;
            }
        }
    }

    if (updateLook) {
        updateLookDirection();
    }
}

the code is a bit different in tfs 1.5 qnd seems to be "fixed" but it isn't. as i stated in the main title the ranged attacks are very off in comparision with othire or tfs 0.4

here is the code
Code:
void Monster::doAttacking(uint32_t interval)
{
    if (!attackedCreature || (isSummon() && attackedCreature == this)) {
        return;
    }

    bool updateLook = true;
    bool resetTicks = interval != 0;
    attackTicks += interval;

    const Position& myPos = getPosition();
    const Position& targetPos = attackedCreature->getPosition();

    for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
        bool inRange = false;

        if (attackedCreature == nullptr) {
            break;
        }

        if (canUseSpell(myPos, targetPos, spellBlock, interval, inRange, resetTicks)) {
            if (spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100))) {
                if (updateLook) {
                    updateLookDirection();
                    updateLook = false;
                }

                minCombatValue = spellBlock.minCombatValue;
                maxCombatValue = spellBlock.maxCombatValue;
                spellBlock.spell->castSpell(this, attackedCreature);

                if (spellBlock.isMelee) {
                    lastMeleeAttack = OTSYS_TIME();
                }
            }
        }

        if (!inRange && spellBlock.isMelee) {
            //melee swing out of reach
            lastMeleeAttack = 0;
        }
    }

    if (updateLook) {
        updateLookDirection();
    }

    if (resetTicks) {
        attackTicks = 0;
    }
}

the other part
Code:
void Monster::onThinkDefense(uint32_t interval)
{
    bool resetTicks = true;
    defenseTicks += interval;

    for (const spellBlock_t& spellBlock : mType->info.defenseSpells) {
        if (spellBlock.speed > defenseTicks) {
            resetTicks = false;
            continue;
        }

        if (defenseTicks % spellBlock.speed >= interval) {
            //already used this spell for this round
            continue;
        }

        if ((spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100)))) {
            minCombatValue = spellBlock.minCombatValue;
            maxCombatValue = spellBlock.maxCombatValue;
            spellBlock.spell->castSpell(this, this);
        }
    }

    if (!isSummon() && summons.size() < mType->info.maxSummons && hasFollowPath) {
        for (const summonBlock_t& summonBlock : mType->info.summons) {
            if (summonBlock.speed > defenseTicks) {
                resetTicks = false;
                continue;
            }

            if (summons.size() >= mType->info.maxSummons) {
                continue;
            }

            if (defenseTicks % summonBlock.speed >= interval) {
                //already used this spell for this round
                continue;
            }

            uint32_t summonCount = 0;
            for (Creature* summon : summons) {
                if (summon->getName() == summonBlock.name) {
                    ++summonCount;
                }
            }

            if (summonCount >= summonBlock.max) {
                continue;
            }

            if (summonBlock.chance < static_cast<uint32_t>(uniform_random(1, 100))) {
                continue;
            }

            Monster* summon = Monster::createMonster(summonBlock.name);
            if (summon) {
                if (g_game.placeCreature(summon, getPosition(), false, summonBlock.force)) {
                    summon->setDropLoot(false);
                    summon->setSkillLoss(false);
                    summon->setMaster(this);
                    g_game.addMagicEffect(getPosition(), CONST_ME_MAGIC_BLUE);
                    g_game.addMagicEffect(summon->getPosition(), CONST_ME_TELEPORT);
                } else {
                    delete summon;
                }
            }
        }
    }

    if (resetTicks) {
        defenseTicks = 0;
    }
}

can somebody point out what to change or how to?

thank
 
As stated in the title ranged attack are off like gfb , spears or any ranged attack made by monsters
Hi! Is there a chance that you could record the behaviour? And if possible have a reference of how should behave. I'm not good at c++ hope that @Itutorial take a look into it, this way the a* can be improved more, for what I can say a recording could speed up the fix. Regards!
 
mp4: OldschoolWar - Blex 2022-10-28 08-35-57.mp4 (https://files.fm/u/2d7x6ftjz) there i explain everything and can be easily observed

}
when a player reaches a monster that attack from distance this monster just stand still and stop walking almost every 2 seconds then stop again attack and walk 1 sqm then attack and repeat this over and over, the monster can gain distance once the player have stop chasing the monster ( monster need 2 sqm to behave normally again)
@ralke
sorry if i can't upload the video to youtube my account has been banned because it was hacked

the same problem occurs for mosnter heal and magic attacks
 
Last edited:
mp4: OldschoolWar - Blex 2022-10-28 08-35-57.mp4 (https://files.fm/u/2d7x6ftjz) there i explain everything and can be easily observed

}
when a player reaches a monster that attack from distance this monster just stand still and stop walking almost every 2 seconds then stop again attack and walk 1 sqm then attack and repeat this over and over, the monster can gain distance once the player have stop chasing the monster ( monster need 2 sqm to behave normally again)
@ralke
sorry if i can't upload the video to youtube my account has been banned because it was hacked

the same problem occurs for mosnter heal and magic attacks
I couldn't record RL tibia, not sure why. But it behaves the same when i'm in close range (this means it has the correct behaviour), anyone can confirm? For what I see everything works like it should. I used my real tibia character to check with Orc Spearmeans.
 
Sad but true ATM. although with this new code monster ar working way better than they used to. Anyway in TFS 0.4 the monste behavior is bad too u.u
The code works well, I don't see anything wrong. Check your videos and compare to this one I recorded on real-tibia:
 
The code works well, I don't see anything wrong. Check your videos and compare to this one I recorded on real-tibia:
check how behave monster like fire devil witch warlock hunter they barely attack(shoot spells)when they are being chased, they just hit melee
 
up
meant something like this "Ranged monsters execute actions every 1 seconds at a distance, as well as take an extra attack while stepping. Because of this, they are more likely to combo/spam attacks while running towards/away from you
 
Sad but true ATM. although with this new code monster ar working way better than they used to. Anyway in TFS 0.4 the monste behavior is bad too u.u
"Anyway in TFS 0.4 the monste behavior is bad too u.u"
No, it isn't if we are talking about the AI, not CPU consumption. They are as reactive as they can be in any TFS.
OTX 2 (something like 0.4) (situation on image):
1670424335689.png
is taking 4 up to 4,5% of CPU.
---
If you apply available fixes to e.g. tfs 1.4.2 to get the exact same effect as it is on otx you would be using (based on gesior's benchmarking):
Algo nr 4 with 15 demons: 5.12% CPU
5.12% with 15 demons...
 
Back
Top