• 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!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

C++ TFS 1.2 downgrade by Ninja show healing

Kahras

Member
Joined
Aug 6, 2012
Messages
97
Reaction score
7
Location
Warsaw
Hello i am using TFS 1.2 downgrade by Ninja and want it to show healing.
my function combatChangeHealth on game.cpp:
C++:
bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
{
    const Position& targetPos = target->getPosition();
    if (damage.primary.value > 0) {
        if (target->getHealth() <= 0) {
            return false;
        }

        if (damage.origin != ORIGIN_NONE) {
            const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE);
            if (!events.empty()) {
                for (CreatureEvent* creatureEvent : events) {
                    creatureEvent->executeHealthChange(target, attacker, damage);
                }
                damage.origin = ORIGIN_NONE;
                return combatChangeHealth(attacker, target, damage);
            }
        }
        target->gainHealth(attacker, damage.primary.value);
    } else {
        if (!target->isAttackable()) {
            if (!target->isInGhostMode()) {
                addMagicEffect(targetPos, CONST_ME_POFF);
            }
            return true;
        }

        Player* attackerPlayer;
        if (attacker) {
            attackerPlayer = attacker->getPlayer();
        } else {
            attackerPlayer = nullptr;
        }

        Player* targetPlayer = target->getPlayer();
        damage.primary.value = std::abs(damage.primary.value);
        damage.secondary.value = std::abs(damage.secondary.value);

        int32_t healthChange = damage.primary.value + damage.secondary.value;
        if (healthChange == 0) {
            return true;
        }

        TextMessage message;
        SpectatorVec list;
        if (target->hasCondition(CONDITION_MANASHIELD) && damage.primary.type != COMBAT_UNDEFINEDDAMAGE) {
            int32_t manaDamage = std::min<int32_t>(target->getMana(), healthChange);
            if (manaDamage != 0) {
                if (damage.origin != ORIGIN_NONE) {
                    const auto& events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE);
                    if (!events.empty()) {
                        for (CreatureEvent* creatureEvent : events) {
                            creatureEvent->executeManaChange(target, attacker, healthChange, damage.origin);
                        }
                        if (healthChange == 0) {
                            return true;
                        }
                        manaDamage = std::min<int32_t>(target->getMana(), healthChange);
                    }
                }

                target->drainMana(attacker, manaDamage);
                map.getSpectators(list, targetPos, true, true);
                addMagicEffect(list, targetPos, CONST_ME_LOSEENERGY);

                std::string damageString = std::to_string(manaDamage);

                std::ostringstream strManaDamage;
                strManaDamage << manaDamage;
                addAnimatedText(strManaDamage.str(), targetPos, TEXTCOLOR_BLUE);
                if (targetPlayer) {
                    message.type = MESSAGE_EVENT_DEFAULT;
                    if (!attacker || targetPlayer == attackerPlayer) {
                        message.text = "You lose " + damageString + " mana.";
                    } else {
                        message.text = "You lose " + damageString + " mana blocking an attack by " + attacker->getNameDescription() + '.';
                    }
                    targetPlayer->sendTextMessage(message);
 
                }
                damage.primary.value -= manaDamage;
                if (damage.primary.value < 0) {
                    damage.secondary.value = std::max<int32_t>(0, damage.secondary.value + damage.primary.value);
                    damage.primary.value = 0;
                }
            }
        }

        int32_t realDamage = damage.primary.value + damage.secondary.value;
        if (realDamage == 0) {
            return true;
        }

        if (damage.origin != ORIGIN_NONE) {
            const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE);
            if (!events.empty()) {
                for (CreatureEvent* creatureEvent : events) {
                    creatureEvent->executeHealthChange(target, attacker, damage);
                }
                damage.origin = ORIGIN_NONE;
                return combatChangeHealth(attacker, target, damage);
            }
        }

        int32_t targetHealth = target->getHealth();
        if (damage.primary.value >= targetHealth) {
            damage.primary.value = targetHealth;
            damage.secondary.value = 0;
        } else if (damage.secondary.value) {
            damage.secondary.value = std::min<int32_t>(damage.secondary.value, targetHealth - damage.primary.value);
        }

        realDamage = damage.primary.value + damage.secondary.value;
        if (realDamage == 0) {
            return true;
        } else if (realDamage >= targetHealth) {
            for (CreatureEvent* creatureEvent : target->getCreatureEvents(CREATURE_EVENT_PREPAREDEATH)) {
                if (!creatureEvent->executeOnPrepareDeath(target, attacker)) {
                    return false;
                }
            }
        }

        target->drainHealth(attacker, realDamage);
        if (list.empty()) {
            map.getSpectators(list, targetPos, true, true);
        }
        addCreatureHealth(list, target);

        message.primary.value = damage.primary.value;
        message.secondary.value = damage.secondary.value;

        uint8_t hitEffect;
        if (message.primary.value) {
            combatGetTypeInfo(damage.primary.type, target, message.primary.color, hitEffect);
            if (hitEffect != CONST_ME_NONE) {
                addMagicEffect(list, targetPos, hitEffect);
            }

            if (message.primary.color != TEXTCOLOR_NONE) {
                std::ostringstream strPrimaryDamage;
                strPrimaryDamage << message.primary.value;
                addAnimatedText(strPrimaryDamage.str(), targetPos, message.primary.color);
            }
        }

        if (message.secondary.value) {
            combatGetTypeInfo(damage.secondary.type, target, message.secondary.color, hitEffect);
            if (hitEffect != CONST_ME_NONE) {
                addMagicEffect(list, targetPos, hitEffect);
            }

            if (message.secondary.color != TEXTCOLOR_NONE) {
                std::ostringstream strSecondaryDamage;
                strSecondaryDamage << message.secondary.value;
                addAnimatedText(strSecondaryDamage.str(), targetPos, message.secondary.color);
            }
        }

        if (message.primary.color != TEXTCOLOR_NONE || message.secondary.color != TEXTCOLOR_NONE) {
            std::string damageString = std::to_string(realDamage) + (realDamage != 1 ? " hitpoints" : " hitpoint");
            if (targetPlayer) {
                message.type = MESSAGE_EVENT_DEFAULT;
                if (!attacker || targetPlayer == attackerPlayer) {
                    message.text = "You lose " + damageString + '.';
                } else {
                    message.text = "You lose " + damageString + " due to an attack by " + attacker->getNameDescription() + '.';
                }
                targetPlayer->sendTextMessage(message);
            }
        }
    }

    return true;
}
 
Solution
Try:
C++:
bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
{
    const Position& targetPos = target->getPosition();
    if (damage.primary.value > 0) {
        if (target->getHealth() <= 0) {
            return false;
        }

        if (damage.origin != ORIGIN_NONE) {
            const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE);
            if (!events.empty()) {
                for (CreatureEvent* creatureEvent : events) {
                    creatureEvent->executeHealthChange(target, attacker, damage);
                }
                damage.origin = ORIGIN_NONE;
                return combatChangeHealth(attacker, target, damage);
            }
        }...

Madusa

Member
Joined
Sep 8, 2022
Messages
58
Reaction score
12
Location
Egypt
You can take it from tfs 1.2 better and newer I don't know exactly what you want but look what you want here in game.cpp
This is the latest tfs 1.2 that has been worked on and is still in progress
You can use this link to find out the difference in the sources or texts
Explain what you want better and you can use this link to publish long texts on it. I wish you success
 
OP
OP
K

Kahras

Member
Joined
Aug 6, 2012
Messages
97
Reaction score
7
Location
Warsaw
What I mean:

oFh2Mv4.png


found this function in condition.cpp:

C++:
bool ConditionRegeneration::executeCondition(Creature* creature, int32_t interval)
{
    internalHealthTicks += interval;
    internalManaTicks += interval;

    if (creature->getZone() != ZONE_PROTECTION) {
        if (internalHealthTicks >= healthTicks) {
            internalHealthTicks = 0;

            int32_t realHealthGain = creature->getHealth();
            creature->changeHealth(healthGain);
            realHealthGain = creature->getHealth() - realHealthGain;

            if (isBuff && realHealthGain > 0) {
                Player* player = creature->getPlayer();
                if (player) {
                    std::string healString = std::to_string(realHealthGain) + (realHealthGain != 1 ? " hitpoints." : " hitpoint.");

                    TextMessage message(MESSAGE_STATUS_SMALL, "You were healed for " + healString);
                    player->sendTextMessage(message);

                    std::ostringstream strHealthGain;
                    strHealthGain << realHealthGain;
                    g_game.addAnimatedText(strHealthGain.str(), player->getPosition(), TEXTCOLOR_MAYABLUE);

                    SpectatorVec list;
                    g_game.map.getSpectators(list, player->getPosition(), false, true);
                    list.erase(player);
                    if (!list.empty()) {
                        message.type = MESSAGE_STATUS_SMALL;
                        message.text = player->getName() + " was healed for " + healString;
                        for (Creature* spectator : list) {
                            spectator->getPlayer()->sendTextMessage(message);
                        }
                    }
                }
            }
        }

        if (internalManaTicks >= manaTicks) {
            internalManaTicks = 0;
            creature->changeMana(manaGain);
        }
    }

    return ConditionGeneric::executeCondition(creature, interval);
}

but it's off because it's not working
 

celohere

Intermediate OT User
Joined
Nov 27, 2007
Messages
268
Solutions
20
Reaction score
148
Try:
C++:
bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage& damage)
{
    const Position& targetPos = target->getPosition();
    if (damage.primary.value > 0) {
        if (target->getHealth() <= 0) {
            return false;
        }

        if (damage.origin != ORIGIN_NONE) {
            const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE);
            if (!events.empty()) {
                for (CreatureEvent* creatureEvent : events) {
                    creatureEvent->executeHealthChange(target, attacker, damage);
                }
                damage.origin = ORIGIN_NONE;
                return combatChangeHealth(attacker, target, damage);
            }
        }

        int32_t realHealthChange = target->getHealth();
        target->gainHealth(attacker, damage.primary.value);
        realHealthChange = target->getHealth() - realHealthChange;

        if (realHealthChange > 0 && !target->isInGhostMode()) {
            std::ostringstream strHealthHeal;
            strHealthHeal << realHealthChange;
            addAnimatedText(strHealthHeal.str(), target->getPosition(), TEXTCOLOR_GREEN);
        }
    } else {
        if (!target->isAttackable()) {
            if (!target->isInGhostMode()) {
                addMagicEffect(targetPos, CONST_ME_POFF);
            }
            return true;
        }

        Player* attackerPlayer;
        if (attacker) {
            attackerPlayer = attacker->getPlayer();
        } else {
            attackerPlayer = nullptr;
        }

        Player* targetPlayer = target->getPlayer();
        damage.primary.value = std::abs(damage.primary.value);
        damage.secondary.value = std::abs(damage.secondary.value);

        int32_t healthChange = damage.primary.value + damage.secondary.value;
        if (healthChange == 0) {
            return true;
        }

        TextMessage message;
        SpectatorVec list;
        if (target->hasCondition(CONDITION_MANASHIELD) && damage.primary.type != COMBAT_UNDEFINEDDAMAGE) {
            int32_t manaDamage = std::min<int32_t>(target->getMana(), healthChange);
            if (manaDamage != 0) {
                if (damage.origin != ORIGIN_NONE) {
                    const auto& events = target->getCreatureEvents(CREATURE_EVENT_MANACHANGE);
                    if (!events.empty()) {
                        for (CreatureEvent* creatureEvent : events) {
                            creatureEvent->executeManaChange(target, attacker, healthChange, damage.origin);
                        }
                        if (healthChange == 0) {
                            return true;
                        }
                        manaDamage = std::min<int32_t>(target->getMana(), healthChange);
                    }
                }

                target->drainMana(attacker, manaDamage);
                map.getSpectators(list, targetPos, true, true);
                addMagicEffect(list, targetPos, CONST_ME_LOSEENERGY);

                std::string damageString = std::to_string(manaDamage);

                std::ostringstream strManaDamage;
                strManaDamage << manaDamage;
                addAnimatedText(strManaDamage.str(), targetPos, TEXTCOLOR_BLUE);
                if (targetPlayer) {
                    message.type = MESSAGE_EVENT_DEFAULT;
                    if (!attacker || targetPlayer == attackerPlayer) {
                        message.text = "You lose " + damageString + " mana.";
                    } else {
                        message.text = "You lose " + damageString + " mana blocking an attack by " + attacker->getNameDescription() + '.';
                    }
                    targetPlayer->sendTextMessage(message);
 
                }
                damage.primary.value -= manaDamage;
                if (damage.primary.value < 0) {
                    damage.secondary.value = std::max<int32_t>(0, damage.secondary.value + damage.primary.value);
                    damage.primary.value = 0;
                }
            }
        }

        int32_t realDamage = damage.primary.value + damage.secondary.value;
        if (realDamage == 0) {
            return true;
        }

        if (damage.origin != ORIGIN_NONE) {
            const auto& events = target->getCreatureEvents(CREATURE_EVENT_HEALTHCHANGE);
            if (!events.empty()) {
                for (CreatureEvent* creatureEvent : events) {
                    creatureEvent->executeHealthChange(target, attacker, damage);
                }
                damage.origin = ORIGIN_NONE;
                return combatChangeHealth(attacker, target, damage);
            }
        }

        int32_t targetHealth = target->getHealth();
        if (damage.primary.value >= targetHealth) {
            damage.primary.value = targetHealth;
            damage.secondary.value = 0;
        } else if (damage.secondary.value) {
            damage.secondary.value = std::min<int32_t>(damage.secondary.value, targetHealth - damage.primary.value);
        }

        realDamage = damage.primary.value + damage.secondary.value;
        if (realDamage == 0) {
            return true;
        } else if (realDamage >= targetHealth) {
            for (CreatureEvent* creatureEvent : target->getCreatureEvents(CREATURE_EVENT_PREPAREDEATH)) {
                if (!creatureEvent->executeOnPrepareDeath(target, attacker)) {
                    return false;
                }
            }
        }

        target->drainHealth(attacker, realDamage);
        if (list.empty()) {
            map.getSpectators(list, targetPos, true, true);
        }
        addCreatureHealth(list, target);

        message.primary.value = damage.primary.value;
        message.secondary.value = damage.secondary.value;

        uint8_t hitEffect;
        if (message.primary.value) {
            combatGetTypeInfo(damage.primary.type, target, message.primary.color, hitEffect);
            if (hitEffect != CONST_ME_NONE) {
                addMagicEffect(list, targetPos, hitEffect);
            }

            if (message.primary.color != TEXTCOLOR_NONE) {
                std::ostringstream strPrimaryDamage;
                strPrimaryDamage << message.primary.value;
                addAnimatedText(strPrimaryDamage.str(), targetPos, message.primary.color);
            }
        }

        if (message.secondary.value) {
            combatGetTypeInfo(damage.secondary.type, target, message.secondary.color, hitEffect);
            if (hitEffect != CONST_ME_NONE) {
                addMagicEffect(list, targetPos, hitEffect);
            }

            if (message.secondary.color != TEXTCOLOR_NONE) {
                std::ostringstream strSecondaryDamage;
                strSecondaryDamage << message.secondary.value;
                addAnimatedText(strSecondaryDamage.str(), targetPos, message.secondary.color);
            }
        }

        if (message.primary.color != TEXTCOLOR_NONE || message.secondary.color != TEXTCOLOR_NONE) {
            std::string damageString = std::to_string(realDamage) + (realDamage != 1 ? " hitpoints" : " hitpoint");
            if (targetPlayer) {
                message.type = MESSAGE_EVENT_DEFAULT;
                if (!attacker || targetPlayer == attackerPlayer) {
                    message.text = "You lose " + damageString + '.';
                } else {
                    message.text = "You lose " + damageString + " due to an attack by " + attacker->getNameDescription() + '.';
                }
                targetPlayer->sendTextMessage(message);
            }
        }
    }

    return true;
}
 
Solution
Top