• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Programmer Tfs 1.2 (player die in arena( PvP Zone) by monster and drop level) pay for job $$

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,210
Solutions
35
Reaction score
207
I am using tfs 1.2 downgraded 8.6.
When a player dies by a monster in the arena (PVP Zone Tool), the player loses level (as if in a normal zone).
I tried to use this fix:

But not solved, the bug still occurs.
I am looking for someone who knows how to solve and we will combine the value of the service!
Thankful!

here is the original code of tfs 1.2 (with bug), that need to be fixed up
C++:
bool Player::dropCorpse(Creature* _lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
    if (getZone() == ZONE_PVP) {
        setDropLoot(true);
        return false;
    }
    return Creature::dropCorpse(_lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
}

Item* Player::getCorpse(Creature* _lastHitCreature, Creature* mostDamageCreature)
{
    Item* corpse = Creature::getCorpse(_lastHitCreature, mostDamageCreature);
    if (corpse && corpse->getContainer()) {
        std::ostringstream ss;
        if (_lastHitCreature) {
            ss << "You recognize " << getNameDescription() << ". " << (getSex() == PLAYERSEX_FEMALE ? "She" : "He") << " was killed by " << _lastHitCreature->getNameDescription() << '.';
        } else {
            ss << "You recognize " << getNameDescription() << '.';
        }

        corpse->setSpecialDescription(ss.str());
    }
    return corpse;
}
 
Last edited:
C++:
bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
    if (getZone() != ZONE_PVP || !Player::lastHitIsPlayer(lastHitCreature)) {
        return Creature::dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
    }

    setDropLoot(true);
    return false;
}
 
C++:
bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
    if (getZone() != ZONE_PVP || !Player::lastHitIsPlayer(lastHitCreature)) {
        return Creature::dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
    }

    setDropLoot(true);
    return false;
}
i tried it, but i get some error during compilation, someone now how can i solve?:1565308826432.png
 
Last edited:
C++:
bool Player::lastHitIsPlayer(Creature* lastHitCreature)
{
    if (!lastHitCreature) {
        return false;
    }

    if (lastHitCreature->getPlayer()) {
        return true;
    }

    Creature* lastHitMaster = lastHitCreature->getMaster();
    return lastHitMaster && lastHitMaster->getPlayer();
}
 
C++:
bool Player::lastHitIsPlayer(Creature* lastHitCreature)
{
    if (!lastHitCreature) {
        return false;
    }

    if (lastHitCreature->getPlayer()) {
        return true;
    }

    Creature* lastHitMaster = lastHitCreature->getMaster();
    return lastHitMaster && lastHitMaster->getPlayer();
}

compiled fine, but dont works. In arena PvP player die by a player (ok, dont drop level).
In area player die by a monster (player drop level)
 
Do you give your players blessings when they log in?
 
KEEP IN MIND
This solution works for tfs 1.4.2 I dont really know how its built in other tfs versions BUT I imagine very similar if not identical.


in:
C++:
void Player::death(Creature* lastHitCreature)

at the top right under:
C++:
    loginPosition = town->getTemplePosition();

add this:
C++:
    if (getZone() == ZONE_PVP && lastHitCreature) {
        setSkillLoss(true);

        auto it = conditions.begin(), end = conditions.end();
        while (it != end) {
            Condition* condition = *it;
            if (condition->isPersistent()) {
                it = conditions.erase(it);

                condition->endCondition(this);
                onEndCondition(condition->getType());
                delete condition;
            }
            else {
                ++it;
            }
        }

        health = healthMax;
        g_game.internalTeleport(this, getTemplePosition(), true);
        g_game.addCreatureHealth(this);
        onThink(EVENT_CREATURE_THINK_INTERVAL);
        onIdleStatus();
        sendStats();
        return;
    }

this is a code snippet from the last else block of the entire death() function.
what i effectivly did was copy it to the top with a new condition "if (getZone() == ZONE_PVP && lastHitCreature)" and a early return statement.

at the bottom of the death function simply remove the else block that we copied since we already have it declared at the top.

remove this snippet from the bottom:
C++:
    } else {
        setSkillLoss(true);

        auto it = conditions.begin(), end = conditions.end();
        while (it != end) {
            Condition* condition = *it;
            if (condition->isPersistent()) {
                it = conditions.erase(it);

                condition->endCondition(this);
                onEndCondition(condition->getType());
                delete condition;
            } else {
                ++it;
            }
        }

        health = healthMax;
        g_game.internalTeleport(this, getTemplePosition(), true);
        g_game.addCreatureHealth(this);
        onThink(EVENT_CREATURE_THINK_INTERVAL);
        onIdleStatus();
        sendStats();
    }

and close the function.


in:
C++:
bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)

change it from this:

C++:
bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
    if (getZone() != ZONE_PVP || !Player::lastHitIsPlayer(lastHitCreature)) {
        return Creature::dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
    }

    setDropLoot(true);
    return false;
}


to:

C++:
bool Player::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreature, bool lastHitUnjustified, bool mostDamageUnjustified)
{
    if (getZone() == ZONE_PVP && lastHitCreature) {
        setDropLoot(false);
        return false;
    }

    return Creature::dropCorpse(lastHitCreature, mostDamageCreature, lastHitUnjustified, mostDamageUnjustified);
}


And you are done.

I've tested this a bit and I couldnt find or see any flaws with it but if anyone knows how this potentionally could be bad/critical id love to hear your input.

Thank you.
Best Regards
Wusse

EDIT:
I just realized this was in the Jobs section and not actually the support section of Otland, I hope nobody minds.
 
Last edited:
Back
Top