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

Show mana healing numbers in purple

I'm not very good at working with c+ ;/, can someone adapt or try to add this to the source?
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);
            }
        }

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

        if (realHealthChange > 0 && !target->isInGhostMode()) {
            std::string healString = "+" + std::to_string(realHealthChange);
            addAnimatedText(healString, target->getPosition(), TEXTCOLOR_GREEN);
        }
    } else {
        if (!target->isAttackable()) {
            if (!target->isInGhostMode()) {
                addMagicEffect(targetPos, CONST_ME_POFF);
            }
            return true;
        }

        Player* attackerPlayer = attacker ? attacker->getPlayer() : 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;
        std::vector<Creature*> spectators;
        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);
                target->getSpectators(spectators, true, true);
                addMagicEffect(spectators, targetPos, CONST_ME_LOSEENERGY);

                std::string damageString = std::to_string(manaDamage);
                addAnimatedText(damageString, 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
                .value + damage.primary.value);
            }
        }

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

        target->drainHealth(attacker, realDamage);
        if (spectators.empty()) {
            target->getSpectators(spectators, true, true);
        }
        addCreatureHealth(spectators, 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(spectators, targetPos, hitEffect);
            }

            if (message.primary.color != TEXTCOLOR_NONE) {
                std::string primaryDamageString = std::to_string(message.primary.value);
                addAnimatedText(primaryDamageString, targetPos, message.primary.color);
            }
        }

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

            if (message.secondary.color != TEXTCOLOR_NONE) {
                std::string secondaryDamageString = std::to_string(message.secondary.value);
                addAnimatedText(secondaryDamageString, 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;
}
 
This for mana: Game.ccp

This:

Lua:
int32_t realManaChange = targetPlayer->getMana();
targetPlayer->changeMana(manaChange);
realManaChange = targetPlayer->getMana() - realManaChange;

To:
Code:
int32_t realManaChange = targetPlayer->getMana();
targetPlayer->changeMana(manaChange);
realManaChange = targetPlayer->getMana() - realManaChange;
if (realManaChange > 0 && !targetPlayer->isInGhostMode()) {
addAnimatedText(fmt::format("+{:d}", realManaChange), targetPlayer->getPosition(), TEXTCOLOR_WHITE);
}

Preview:
Recording 2023-05-16 at 10.54.05.gif
 
Or simply register custom callback to onHealthChange/onManaChange CreatureEvent's and code that in LUA:

Lua:
onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

Small POC, adjust to your needs:
data/scripts/creaturescripts/player/animated_spells.lua
Lua:
local combatHandler = {
    [COMBAT_HEALING] = {
        color = TEXTCOLOR_RED,
        format = '%s%d',
        effect = CONST_ME_DRAWBLOOD,
        origin = ORIGIN_SPELL,
        selfOnly = true
    },
    [COMBAT_MANADRAIN] = {
        color = TEXTCOLOR_LIGHTBLUE,
        format = '%s%d',
        effect = CONST_ME_SOUND_BLUE,
        origin = ORIGIN_SPELL,
        selfOnly = true
    }
}

local function executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local requiredOrigin = handler.origin or -1
    if requiredOrigin ~= -1 and origin ~= requiredOrigin then
        return
    end

    local selfDamageOnly = handler.selfOnly or false
    if selfDamageOnly and player ~= attacker then
        return
    end

    local color = handler.color
    local textFormat = handler.format
    local magicEffect = handler.effect
    local playerPos = player:getPosition()
    local dmg = primaryDamage + secondaryDamage

    local animatedText = textFormat:format((dmg > 0 and "+" or ""), dmg)
    Game.sendAnimatedText(animatedText, playerPos, color)
    if magicEffect then
        playerPos:sendMagicEffect(magicEffect)
    end
end

local healthChangeEvent = CreatureEvent("PlayerHealthChange")
healthChangeEvent:type("healthchange")

function healthChangeEvent.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local player = Player(creature)
    local handler = combatHandler[primaryType or secondaryType]
    if player and handler then
        executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    end

    return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end

healthChangeEvent:register()

local manaChangeEvent = CreatureEvent("PlayerManaChange")
manaChangeEvent:type("manachange")

function manaChangeEvent.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local player = Player(creature)
    local handler = combatHandler[primaryType or secondaryType]
    if player and handler then
        executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    end

    return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end

manaChangeEvent:register()

local loginEvent = CreatureEvent("RegisterPlayerStatsChangeEvents")

function loginEvent.onLogin(player)
    player:registerEvent("PlayerHealthChange")
    player:registerEvent("PlayerManaChange")
    return true
end

loginEvent:register()

For animated text feature I'd suggest to use this implementation (Author: @Sarah Wesker):
 
Last edited:
int32_t realManaChange = targetPlayer->getMana(); targetPlayer->changeMana(manaChange); realManaChange = targetPlayer->getMana() - realManaChange; if (realManaChange > 0 && !targetPlayer->isInGhostMode()) { addAnimatedText(fmt::format("+{:d}", realManaChange), targetPlayer->getPosition(), TEXTCOLOR_WHITE); }

game.png
when I
replace that code you mentioned, it gave an error.. it says needs to be declared, should include example" Game.h in game.cpp? somewhere?

or do i have to uncomment this /* and at the end */ somewhere? if so, which ones do need for me to be able to uncomment?
Small POC, adjust to your needs:
data/scripts/creaturescripts/player/animated_spells.lua
I've never seen this, thanks for sharing this.. as soon as I get home I'm going to test it, I'd like to know this code you sent is only good for spells? example "exura gran" etc? I use a portion of mana and healing in actions... will actions work too?? thank you very much!
 
I have added this code and it does work
Lua:
if (realManaChange > 0 && !targetPlayer->isInGhostMode()) {
            addAnimatedText(fmt::format("+{:d}", realManaChange), targetPlayer->getPosition(), TEXTCOLOR_PURPLE);
        }
        /*

wanna do the same but for heal the code is a bit different
i tried what i commented out, but does not worked. please help, would be cool that have this working and in old tfs to give the server the sense of being an ot
Code:
auto damageString = fmt::format("{:d} hitpoint{:s}", realHealthChange, realHealthChange != 1 ? "s" : "");
            //auto damageString = addAnimatedText(fmt::format("+{:d}", realHealthChange), targetPlayer->getPosition(), TEXTCOLOR_PASTELRED);
Post automatically merged:

Or simply register custom callback to onHealthChange/onManaChange CreatureEvent's and code that in LUA:

Lua:
onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)

Small POC, adjust to your needs:
data/scripts/creaturescripts/player/animated_spells.lua
Lua:
local combatHandler = {
    [COMBAT_HEALING] = {
        color = TEXTCOLOR_RED,
        format = '%s%d',
        effect = CONST_ME_DRAWBLOOD,
        origin = ORIGIN_SPELL,
        selfOnly = true
    },
    [COMBAT_MANADRAIN] = {
        color = TEXTCOLOR_LIGHTBLUE,
        format = '%s%d',
        effect = CONST_ME_SOUND_BLUE,
        origin = ORIGIN_SPELL,
        selfOnly = true
    }
}

local function executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local requiredOrigin = handler.origin or -1
    if requiredOrigin ~= -1 and origin ~= requiredOrigin then
        return
    end

    local selfDamageOnly = handler.selfOnly or false
    if selfDamageOnly and player ~= attacker then
        return
    end

    local color = handler.color
    local textFormat = handler.format
    local magicEffect = handler.effect
    local playerPos = player:getPosition()
    local dmg = primaryDamage + secondaryDamage

    local animatedText = textFormat:format((dmg > 0 and "+" or ""), dmg)
    Game.sendAnimatedText(animatedText, playerPos, color)
    if magicEffect then
        playerPos:sendMagicEffect(magicEffect)
    end
end

local healthChangeEvent = CreatureEvent("PlayerHealthChange")
healthChangeEvent:type("healthchange")

function healthChangeEvent.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local player = Player(creature)
    local handler = combatHandler[primaryType or secondaryType]
    if player and handler then
        executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    end

    return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end

healthChangeEvent:register()

local manaChangeEvent = CreatureEvent("PlayerManaChange")
manaChangeEvent:type("manachange")

function manaChangeEvent.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local player = Player(creature)
    local handler = combatHandler[primaryType or secondaryType]
    if player and handler then
        executeHandler(handler, player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    end

    return primaryDamage, primaryType, secondaryDamage, secondaryType, origin
end

manaChangeEvent:register()

local loginEvent = CreatureEvent("RegisterPlayerStatsChangeEvents")

function loginEvent.onLogin(player)
    player:registerEvent("PlayerHealthChange")
    player:registerEvent("PlayerManaChange")
    return true
end

loginEvent:register()

For animated text feature I'd suggest to use this implementation (Author: @Sarah Wesker):
what do i need to add in lua?
Post automatically merged:

This for mana: Game.ccp

This:

Lua:
int32_t realManaChange = targetPlayer->getMana();
targetPlayer->changeMana(manaChange);
realManaChange = targetPlayer->getMana() - realManaChange;

To:
Code:
int32_t realManaChange = targetPlayer->getMana();
targetPlayer->changeMana(manaChange);
realManaChange = targetPlayer->getMana() - realManaChange;
if (realManaChange > 0 && !targetPlayer->isInGhostMode()) {
addAnimatedText(fmt::format("+{:d}", realManaChange), targetPlayer->getPosition(), TEXTCOLOR_WHITE);
}

Preview:
View attachment 75618
how would it be for health @Fabi Marzan
 
Last edited:
The problem was successfully resolved, and best of all, I didn't have to change the source or use an alternative script in creaturescript. Now it is possible to implement the functionality in both spells and actions, anywhere where the health and mana animations are displayed, and it is working perfectly. I am very pleased with the result!
If you want, I can create a tutorial teaching how to show mana healing numbers in purple AND life in green. It would be a way to share knowledge with everyone. watch the video that shows the use of the "UH" rune spell, which displays the healing numbers in green.
 
The problem was successfully resolved, and best of all, I didn't have to change the source or use an alternative script in creaturescript. Now it is possible to implement the functionality in both spells and actions, anywhere where the health and mana animations are displayed, and it is working perfectly. I am very pleased with the result!
If you want, I can create a tutorial teaching how to show mana healing numbers in purple AND life in green. It would be a way to share knowledge with everyone. watch the video that shows the use of the "UH" rune spell, which displays the healing numbers in green.
Would you mind show us how you did it?
 
Would you mind show us how you did it?
Of course, I can show yes! Once I get home, I'll share it here or create a new post for you.

I have a question, do you have animated text in your source? If you do not have, you'll need to add it to your source.
 
Last edited:
Of course, I can show yes! Once I get home, I'll share it here or create a new post for you.

I have a question, do you have animated text in your source? If you do not have, you'll need to add it to your source.
Yes i already have it into my soruce
 
Yes i already have it into my soruce
I'll explain step by step how to add an animated effect to display the number of healing and mana.
Here is an example of the original UH (ultimate_healing) spell.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

Let's work on how to correctly replace the proper place.
Lua:
return min, max
for this
Lua:
local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    doSendAnimatedText(formattedText, getPlayerPosition(cid), 12)


    return totalIncrease, totalIncrease
Look how the end result is here.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
 
    local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    Game.sendAnimatedText(formattedText, player:getPosition(), 12)

    return totalIncrease, totalIncrease
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end
In green color it is 12, if you want to change it, just modify that line.
Lua:
doSendAnimatedText(formattedText, getPlayerPosition(cid), 12)

Please, after making the changes or modifications, let us know here so we know if it worked or not.

Hope you understood!
 
Last edited:
I'll explain step by step how to add an animated effect to display the number of healing and mana.
Here is an example of the original UH (ultimate_healing) spell.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
    return min, max
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

Let's work on how to correctly replace the proper place.

for this

And also don't forget to replace "player" with "cid".

for this

Look how the end result is here.
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(cid, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
  
    local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    doSendAnimatedText(formattedText, getPlayerPosition(cid), 12)

    return totalIncrease, totalIncrease
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end
In green color it is 12, if you want to change it, just modify that line.


Please, after making the changes or modifications, let us know here so we know if it worked or not.

Hope you understood!
Thank you. i can't access to my serv atm due to an issue, i'll check this later. I'm sure it does work. Thank you!
 
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
 
    local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    Game.sendAnimatedText(formattedText, player:getPosition(), 12)

    return totalIncrease, totalIncrease
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

no need for cid :p

btw I think this will not work correctly when using healing to other players
as it will get the position of the player using the rune 🤔

I still think the best approach is the two line code edit that @Fabi Marzan posted so you don't have to edit every action and spell separately
 
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
 
    local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    Game.sendAnimatedText(formattedText, player:getPosition(), 12)

    return totalIncrease, totalIncrease
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

no need for cid :p

btw I think this will not work correctly when using healing to other players
as it will get the position of the player using the rune 🤔

I still think the best approach is the two line code edit that @Fabi Marzan posted so you don't have to edit every action and spell separately
Sorry, now that I understand... thanks for the correction. I'll update the post then. xD
Post automatically merged:

I still think the best approach is the two line code edit that @Fabi Marzan posted so you don't have to edit every action and spell separately
I already solved his code. I just changed "white" to "purple" and compiled, and it worked. Before it didn't work and there were several errors, hahaha.
 
Last edited:
Lua:
local combat = Combat()
combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_HEALING)
combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE)
combat:setParameter(COMBAT_PARAM_DISPEL, CONDITION_PARALYZE)
combat:setParameter(COMBAT_PARAM_AGGRESSIVE, false)

function onGetFormulaValues(player, level, magicLevel)
    local min = (level / 5) + (magicLevel * 6.8) + 42
    local max = (level / 5) + (magicLevel * 12.9) + 90
 
    local totalIncrease = math.random(min, max)
    local formattedText = string.format("+%d", totalIncrease)
    Game.sendAnimatedText(formattedText, player:getPosition(), 12)

    return totalIncrease, totalIncrease
end

combat:setCallback(CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues")

function onCastSpell(creature, variant)
    return combat:execute(creature, variant)
end

no need for cid :p

btw I think this will not work correctly when using healing to other players
as it will get the position of the player using the rune 🤔

I still think the best approach is the two line code edit that @Fabi Marzan posted so you don't have to edit every action and spell separately
Sorry, now that I understand... thanks for the correction. I'll update the post then. xD
Post automatically merged:


I already solved his code. I just changed "white" to "purple" and compiled, and it worked. Before it didn't work and there were several errors, hahaha.
how to do that but for heal in c++? it display when a player heaks but if the lifebar is full number are not being displayed.
 
how to do that but for heal in c++? it display when a player heaks but if the lifebar is full number are not being displayed.
I just added the animation to display the heal. Test it and see how it goes.
C++:
int32_t realHealthChange = target->getHealth();
        target->gainHealth(attacker, damage.primary.value);
        realHealthChange = target->getHealth() - realHealthChange;

        if (realHealthChange > 0 && !target->isInGhostMode()) {
            std::string damageString = fmt::format("{:d} hitpoint{:s}", realHealthChange, realHealthChange != 1 ? "s" : "");

            std::string spectatorMessage;

            TextMessage message;
            message.position = targetPos;
            message.primary.value = realHealthChange;
            message.primary.color = TEXTCOLOR_PASTELRED;

            SpectatorVec spectators;
            map.getSpectators(spectators, targetPos, false, true);
            for (Creature* spectator : spectators) {
                Player* tmpPlayer = spectator->getPlayer();
                if (tmpPlayer == attackerPlayer && attackerPlayer != targetPlayer) {
                    message.type = MESSAGE_EVENT_DEFAULT;
                    message.text = fmt::format("You heal {:s} for {:s}.", target->getNameDescription(), damageString);
                    tmpPlayer->sendTextMessage(message);
                    addAnimatedText(fmt::format("+{:d}", realHealthChange), target->getPosition(), TEXTCOLOR_LIGHTGREEN);
                }
                else if (tmpPlayer == targetPlayer) {
                    message.type = MESSAGE_EVENT_DEFAULT;
                    if (!attacker) {
                        message.text = fmt::format("You were healed for {:s}.", damageString);
                    }
                    else if (targetPlayer == attackerPlayer) {
                        message.text = fmt::format("You healed yourself for {:s}.", damageString);
                    }
                    else {
                        message.text = fmt::format("You were healed by {:s} for {:s}.", attacker->getNameDescription(), damageString);
                    }
                    tmpPlayer->sendTextMessage(message);
                    addAnimatedText(fmt::format("+{:d}", realHealthChange), target->getPosition(), TEXTCOLOR_LIGHTGREEN);
                }
                else {
                    message.type = MESSAGE_EVENT_DEFAULT;
                    if (spectatorMessage.empty()) {
                        if (!attacker) {
                            spectatorMessage = fmt::format("{:s} was healed for {:s}.", target->getNameDescription(), damageString);
                        }
                        else if (attacker == target) {
                            spectatorMessage = fmt::format("{:s} healed {:s}self for {:s}.", attacker->getNameDescription(), targetPlayer ? (targetPlayer->getSex() == PLAYERSEX_FEMALE ? "her" : "him") : "it", damageString);
                        }
                        else {
                            spectatorMessage = fmt::format("{:s} healed {:s} for {:s}.", attacker->getNameDescription(), target->getNameDescription(), damageString);
                        }
                        spectatorMessage[0] = std::toupper(spectatorMessage[0]);
                    }
                    message.text = spectatorMessage;
                    tmpPlayer->sendTextMessage(message);
                    addAnimatedText(fmt::format("+{:d}", realHealthChange), target->getPosition(), TEXTCOLOR_LIGHTGREEN);
                }
            }
        }
You need to replace the old one with the new one and compile. Test to see if it works.
Post automatically merged:

I still think the best approach is the two line code edit that @Fabi Marzan posted so you don't have to edit every action and spell separately
His code has some bugs. I compiled and it worked correctly, however it displayed the animated effect only once. When I tried to click on the pot again, the effect no longer appeared.
 
Last edited:
Back
Top