• 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!

TFS 1.X+ Frag unjustified for every attacker

TiffiED

New Member
Joined
Oct 17, 2024
Messages
3
Solutions
1
Reaction score
0
Hello, could someone help me change this script or something else so that everyone who attacked a player who death gets a kill, and not as it is currently that the player who dealt damage last gets the kill.
I am using tfs 1.5.

C++:
bool Player::onKilledCreature(Creature* target, bool lastHit/* = true*/)
{
    bool unjustified = false;

    if (hasFlag(PlayerFlag_NotGenerateLoot)) {
        target->setDropLoot(false);
    }

    Creature::onKilledCreature(target, lastHit);

    Player* targetPlayer = target->getPlayer();
    if (!targetPlayer) {
        return false;
    }

    if (targetPlayer->getZone() == ZONE_PVP) {
        targetPlayer->setDropLoot(false);
        targetPlayer->setSkillLoss(false);
    } else if (!hasFlag(PlayerFlag_NotGainInFight) && !isPartner(targetPlayer)) {
        if (!Combat::isInPvpZone(this, targetPlayer) && hasAttacked(targetPlayer) && !targetPlayer->hasAttacked(this) && !isGuildMate(targetPlayer) && targetPlayer != this) {
            if (targetPlayer->getSkull() == SKULL_NONE && !isInWar(targetPlayer)) {
                unjustified = true;
                addUnjustifiedDead(targetPlayer);
            }

            if (lastHit && hasCondition(CONDITION_INFIGHT)) {
                pzLocked = true;
                Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_config.getNumber(ConfigManager::WHITE_SKULL_TIME) * 1000, 0);
                addCondition(condition);
            }
        }
    }

    return unjustified;
}
 
Solution
The solution if anyone needs it. Player.cpp
C++:
bool Player::onKilledCreature(Creature* target, bool lastHit /* = true */)
{
    bool unjustified = false;

    if (hasFlag(PlayerFlag_NotGenerateLoot)) {
        target->setDropLoot(false);
    }

    Creature::onKilledCreature(target, lastHit);

    Player* targetPlayer = target->getPlayer();
    if (!targetPlayer) {
        return false;
    }

    if (targetPlayer->getZone() == ZONE_PVP) {
        targetPlayer->setDropLoot(false);
        targetPlayer->setSkillLoss(false);
    } else if (!hasFlag(PlayerFlag_NotGainInFight) && !isPartner(targetPlayer)) {
        if (!Combat::isInPvpZone(this, targetPlayer) &&
            !targetPlayer->hasAttacked(this) &&...
The solution if anyone needs it. Player.cpp
C++:
bool Player::onKilledCreature(Creature* target, bool lastHit /* = true */)
{
    bool unjustified = false;

    if (hasFlag(PlayerFlag_NotGenerateLoot)) {
        target->setDropLoot(false);
    }

    Creature::onKilledCreature(target, lastHit);

    Player* targetPlayer = target->getPlayer();
    if (!targetPlayer) {
        return false;
    }

    if (targetPlayer->getZone() == ZONE_PVP) {
        targetPlayer->setDropLoot(false);
        targetPlayer->setSkillLoss(false);
    } else if (!hasFlag(PlayerFlag_NotGainInFight) && !isPartner(targetPlayer)) {
        if (!Combat::isInPvpZone(this, targetPlayer) &&
            !targetPlayer->hasAttacked(this) &&
            !isGuildMate(targetPlayer) &&
            targetPlayer != this) {

            if (targetPlayer->getSkull() == SKULL_NONE && !isInWar(targetPlayer)) {
                unjustified = true;
                addUnjustifiedDead(targetPlayer);
                // Możesz dodać addPlayerKilled(targetPlayer); jeśli chcesz fragi ręcznie
            }

            // Add PZ-lock all kills
            pzLocked = true;
            Condition* condition = Condition::createCondition(
                CONDITIONID_DEFAULT,
                CONDITION_INFIGHT,
                g_config.getNumber(ConfigManager::WHITE_SKULL_TIME) * 1000,
                0
            );
            addCondition(condition);
        }
    }

    return unjustified;
}
and Creature.cpp
C++:
void Creature::onDeath()
{
    bool lastHitUnjustified = false;
    Creature* lastHitCreature = g_game.getCreatureByID(lastHitCreatureId);
    Creature* lastHitCreatureMaster = lastHitCreature ? lastHitCreature->getMaster() : nullptr;

    if (lastHitCreature) {
        lastHitUnjustified = lastHitCreature->onKilledCreature(this, true);
    }

    const int64_t timeNow = OTSYS_TIME();
    const uint32_t inFightTicks = g_config.getNumber(ConfigManager::PZ_LOCKED);
    int32_t mostDamage = 0;
    std::map<Creature*, uint64_t> experienceMap;

    std::set<Player*> processedKillers;

    for (const auto& it : damageMap) {
        if (Creature* attacker = g_game.getCreatureByID(it.first)) {
            CountBlock_t cb = it.second;

            if ((cb.total > mostDamage && (timeNow - cb.ticks <= inFightTicks))) {
                mostDamage = cb.total;
            }

            if (attacker != this) {
                uint64_t gainExp = getGainedExperience(attacker);

                if (Player* attackerPlayer = attacker->getPlayer()) {
                    attackerPlayer->removeAttacked(getPlayer());

                    // Party EXP sharing
                    Party* party = attackerPlayer->getParty();
                    if (party && party->getLeader() && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) {
                        attacker = party->getLeader();
                    }
                }

                auto tmpIt = experienceMap.find(attacker);
                if (tmpIt == experienceMap.end()) {
                    experienceMap[attacker] = gainExp;
                } else {
                    tmpIt->second += gainExp;
                }
            }

            // Ważne: Przekazujemy false jako "lastHit", ale każdy dostaje condition/skull
            Player* attackerPlayer = attacker->getPlayer();
            if (attackerPlayer && attackerPlayer != lastHitCreature && processedKillers.find(attackerPlayer) == processedKillers.end()) {
                attackerPlayer->onKilledCreature(this, false);
                processedKillers.insert(attackerPlayer);
            }
        }
    }

    for (const auto& it : experienceMap) {
        it.first->onGainExperience(it.second, this);
    }

    bool droppedCorpse = dropCorpse(lastHitCreature, nullptr, lastHitUnjustified, false);
    death(lastHitCreature);

    if (master) {
        setMaster(nullptr);
    }

    if (droppedCorpse) {
        g_game.removeCreature(this, false);
    }
}
 
Solution
Back
Top