• 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++ Upgraded Healing

115820

Member
Joined
Feb 27, 2011
Messages
193
Solutions
1
Reaction score
5
Location
London, England
Dear all, how i make a UPGRAD healing in c++, because i have so many spells and runes on my server, and no want change all scripts with formulas, i want make for storage in sources.


TIBIA VERSION: 8.6
TFS VERSION: 0.4
EXEMPLE:
The exura heals 100 without storage 100 - 1, with storage 1 will heals 110 (each 1 storage will add more 10% healing).

But i want make in sources not LUA.
 
Last edited:
Solution
game.cpp
C++:
bool Game::combatChangeHealth(const CombatParams& params, Creature* attacker, Creature* target, int32_t healthChange, bool force)
{
    const Position& targetPos = target->getPosition();
    if(healthChange > 0)
    {
        if(!force && target->getHealth() <= 0)
            return false;

        // START BONUS STORAGE HEALING
        std::string value;
        target->getPlayer()->getStorage(8888, value); // SET STORAGE HERE
        int32_t storageBonus = atoi(value.c_str());
      
        if (storageBonus >= 1)
            healthChange = healthChange * (1 + (storageBonus * 0.1)); // 0.1 = 10%
      
        // END BONUS STORAGE HEALING
      
        bool deny = false;
        CreatureEventList statsChangeEvents =...
Pretty sure you can just create a onHealthChange or what/ever it is for your distro. Then you don't have to add code to all spells.
 
I did, its just clear you don't want to help yourself. So im not going to either. Use the search function.
 
okay, try this:
Lua:
function onStatChange(cid, attacker, combat, type, value)
    local healBonus = getPlayerStorageValue(cid, 1234)
    print(healBonus)
    if type == STATSCHANGE_HEALTHGAIN and healBonus > 0 then
        value = value + (healBonus * 10)
        print(value)
    end
    return true
end

not tested since I don't have a 0.4 to test, and tell me what number it print on console so we can debug it further

also I'm assuming you know how to add it to creature events and to register it on login.lua (idk if onStatChange need to do it, but whatever)
 
Last edited by a moderator:
game.cpp
C++:
bool Game::combatChangeHealth(const CombatParams& params, Creature* attacker, Creature* target, int32_t healthChange, bool force)
{
    const Position& targetPos = target->getPosition();
    if(healthChange > 0)
    {
        if(!force && target->getHealth() <= 0)
            return false;

        // START BONUS STORAGE HEALING
        std::string value;
        target->getPlayer()->getStorage(8888, value); // SET STORAGE HERE
        int32_t storageBonus = atoi(value.c_str());
      
        if (storageBonus >= 1)
            healthChange = healthChange * (1 + (storageBonus * 0.1)); // 0.1 = 10%
      
        // END BONUS STORAGE HEALING
      
        bool deny = false;
        CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
        for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
        {
            if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHGAIN, params.combatType, healthChange))
                deny = true;
        }

        if(deny)
            return false;

        int32_t oldHealth = target->getHealth();
        target->gainHealth(attacker, healthChange);
        if(oldHealth != target->getHealth() && g_config.getBool(ConfigManager::SHOW_HEALTH_CHANGE) && !target->isGhost() &&
            (g_config.getBool(ConfigManager::SHOW_HEALTH_CHANGE_MONSTER) || !target->getMonster()))
        {
            const SpectatorVec& list = getSpectators(targetPos);
            if(params.combatType != COMBAT_HEALING)
                addMagicEffect(list, targetPos, MAGIC_EFFECT_WRAPS_BLUE);

            SpectatorVec textList;
            for(SpectatorVec::const_iterator it = list.begin(); it != list.end(); ++it)
            {
                if(!(*it)->getPlayer())
                    continue;

                if((*it) != attacker && (*it) != target && (*it)->getPosition().z == target->getPosition().z)
                    textList.push_back(*it);
            }

            healthChange = (target->getHealth() - oldHealth);
            std::string plural = (healthChange != 1 ? "s." : ".");

            std::stringstream ss;
            char buffer[20];
            sprintf(buffer, "+%d", healthChange);
            addAnimatedText(list, targetPos, COLOR_MAYABLUE, buffer);
            if(!textList.empty())
            {
                if(!attacker)
                    ss << ucfirst(target->getNameDescription()) << " is healed for " << healthChange << " hitpoint" << plural;
                else if(attacker != target)
                    ss << ucfirst(attacker->getNameDescription()) << " heals " << target->getNameDescription() << " for " << healthChange << " hitpoint" << plural;
                else
                {
                    ss << ucfirst(attacker->getNameDescription()) << " heals ";
                    if(Player* attackerPlayer = attacker->getPlayer())
                        ss << (attackerPlayer->getSex(false) == PLAYERSEX_FEMALE ? "herself" : "himself") << " for " << healthChange << " hitpoint" << plural;
                    else
                        ss << "itself for " << healthChange << " hitpoint" << plural;
                }

                addStatsMessage(textList, MSG_HEALED_OTHERS, ss.str(), targetPos);
                ss.str("");
            }

            Player* player = NULL;
            if(attacker && (player = attacker->getPlayer()))
            {
                if(attacker != target)
                    ss << "You healed " << target->getNameDescription() << " for " << healthChange << " hitpoint" << plural;
                else
                    ss << "You healed yourself for " << healthChange << " hitpoint" << plural;

                player->sendStatsMessage(MSG_HEALED, ss.str(), targetPos);
                ss.str("");
            }

            if((player = target->getPlayer()) && attacker != target)
            {
                if(attacker)
                    ss << ucfirst(attacker->getNameDescription()) << " heals you for " << healthChange << " hitpoint" << plural;
                else
                    ss << "You are healed for " << healthChange << " hitpoint" << plural;

                player->sendStatsMessage(MSG_HEALED, ss.str(), targetPos);
            }
        }
    }
    else
    {
        const SpectatorVec& list = getSpectators(targetPos);
        if(target->getHealth() < 1 || Combat::canDoCombat(attacker, target, true) != RET_NOERROR)
        {
            addMagicEffect(list, targetPos, MAGIC_EFFECT_POFF);
            return true;
        }

        int32_t elementDamage = 0;
        if(params.element.damage && params.element.type != COMBAT_NONE)
            elementDamage = -params.element.damage;

        int32_t damage = -healthChange;
        if(damage > 0)
        {
            if(target->hasCondition(CONDITION_MANASHIELD) && params.combatType != COMBAT_UNDEFINEDDAMAGE)
            {
                int32_t manaDamage = std::min(target->getMana(), damage + elementDamage);
                damage = std::max((int32_t)0, damage + elementDamage - manaDamage);

                elementDamage = 0; // TODO: I don't know how it works ;(
                if(manaDamage && combatChangeMana(attacker, target, -manaDamage, params.combatType, true))
                    addMagicEffect(list, targetPos, MAGIC_EFFECT_LOSE_ENERGY);
            }

            damage = std::min(target->getHealth(), damage);
            if(damage > 0)
            {
                bool deny = false;
                CreatureEventList statsChangeEvents = target->getCreatureEvents(CREATURE_EVENT_STATSCHANGE);
                for(CreatureEventList::iterator it = statsChangeEvents.begin(); it != statsChangeEvents.end(); ++it)
                {
                    if(!(*it)->executeStatsChange(target, attacker, STATSCHANGE_HEALTHLOSS, params.combatType, damage))
                        deny = true;
                }

                if(deny)
                    return false;

                target->drainHealth(attacker, params.combatType, damage);
                if(elementDamage)
                    target->drainHealth(attacker, params.element.type, elementDamage);

                Color_t textColor = COLOR_NONE;
                MagicEffect_t magicEffect = MAGIC_EFFECT_NONE;

                addCreatureHealth(list, target);
                if(params.combatType == COMBAT_PHYSICALDAMAGE)
                {
                    Item* splash = NULL;
                    switch(target->getRace())
                    {
                        case RACE_VENOM:
                            textColor = COLOR_LIGHTGREEN;
                            magicEffect = MAGIC_EFFECT_POISON;
                            splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_GREEN);
                            break;

                        case RACE_BLOOD:
                            textColor = COLOR_RED;
                            magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
                            splash = Item::CreateItem(ITEM_SMALLSPLASH, FLUID_BLOOD);
                            break;

                        case RACE_UNDEAD:
                            textColor = COLOR_GREY;
                            magicEffect = MAGIC_EFFECT_HIT_AREA;
                            break;

                        case RACE_FIRE:
                            textColor = COLOR_ORANGE;
                            magicEffect = MAGIC_EFFECT_DRAW_BLOOD;
                            break;

                        case RACE_ENERGY:
                            textColor = COLOR_PURPLE;
                            magicEffect = MAGIC_EFFECT_PURPLEENERGY;
                            break;

                        default:
                            break;
                    }

                    if(splash)
                    {
                        internalAddItem(NULL, target->getTile(), splash, INDEX_WHEREEVER, FLAG_NOLIMIT);
                        startDecay(splash);
                    }
                }
                else
                    getCombatDetails(params.combatType, magicEffect, textColor);

                if(params.effects.hit != MAGIC_EFFECT_UNKNOWN)
                    magicEffect = params.effects.hit;

                if(params.effects.color != COLOR_UNKNOWN)
                    textColor = params.effects.color;

                if(textColor < COLOR_NONE && magicEffect < MAGIC_EFFECT_NONE)
                {
                    addMagicEffect(list, targetPos, magicEffect);
                    SpectatorVec textList;
                    for(SpectatorVec::const_iterator it = list.begin(); it != list.end(); ++it)
                    {
                        if(!(*it)->getPlayer())
                            continue;

                        if((*it) != attacker && (*it) != target && (*it)->getPosition().z == target->getPosition().z)
                            textList.push_back(*it);
                    }

                    MessageDetails* details = new MessageDetails(damage, textColor);
                    if(elementDamage)
                    {
                        getCombatDetails(params.element.type, magicEffect, textColor);
                        details->sub = new MessageDetails(elementDamage, textColor);
                        addMagicEffect(list, targetPos, magicEffect);
                    }

                    std::stringstream ss;
                    int32_t totalDamage = damage + elementDamage;

                    std::string plural = (totalDamage != 1 ? "s" : "");
                    if(!textList.empty())
                    {
                        if(!attacker)
                            ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << ".";
                        else if(attacker != target)
                            ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to an attack by " << attacker->getNameDescription() << ".";
                        else
                            ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to a self attack.";

                        addStatsMessage(textList, MSG_DAMAGE_OTHERS, ss.str(), targetPos, details);
                        ss.str("");
                    }

                    Player* player = NULL;
                    if(attacker && (player = attacker->getPlayer()))
                    {
                        if(attacker != target)
                            ss << ucfirst(target->getNameDescription()) << " loses " << totalDamage << " hitpoint" << plural << " due to your attack.";
                        else
                            ss << "You lose " << totalDamage << " hitpoint" << plural << " due to your attack.";

                        player->sendStatsMessage(MSG_DAMAGE_DEALT, ss.str(), targetPos, details);
                        ss.str("");
                    }

                    if((player = target->getPlayer()) && attacker != target)
                    {
                        if(attacker)
                            ss << "You lose " << totalDamage << " hitpoint" << plural << " due to an attack by " << attacker->getNameDescription() << ".";
                        else
                            ss << "You lose " << totalDamage << " hitpoint" << plural << ".";

                        player->sendStatsMessage(MSG_DAMAGE_RECEIVED, ss.str(), targetPos, details);
                    }

                    if(details->sub)
                        delete details->sub;

                    delete details;
                }
            }
        }
    }

    return true;
}
All healing recived are boosted for player with storage 8888 (potions, sio, etc..).
Storage = -1
HUDwi2v.png

Storage = 1000
HXpzLTS.png
 
Solution
okay, try this:
Lua:
function onStatChange(cid, attacker, combat, type, value)
    local healBonus = getPlayerStorageValue(cid, 1234)
    print(healBonus)
    if type == STATSCHANGE_HEALTHGAIN and healBonus > 0 then
        value = value + (healBonus * 10)
        print(value)
    end
    return true
end

not tested since I don't have a 0.4 to test, and tell me what number it print on console so we can debug it further

also I'm assuming you know how to add it to creature events and to register it on login.lua (idk if onStatChange need to do it, but whatever)
Hey i try use you script too, i just change that.

Code:
function onStatsChange(cid, attacker, type, combat, value)
    local healBonus = getPlayerStorageValue(cid, 1234)
    print(healBonus)
    if isPlayer(cid) then
        if type == STATSCHANGE_HEALTHGAIN or type == STATSCHANGE_MANAGAIN then
            value = value + (healBonus * 10)
            print(value)
        end
    end   
    return true
end
And return that
1594855576557.png
 
Back
Top