• Congratulations to the OTLand January Mapping Competition Winner! The grand prize of Otland Premium goes to Andréew.
  • Sign up for February Mapping Competition! The prize includes Otland Premium time.
  • 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!

Feature Attributes MOD

HOC OT

New Member
Joined
May 17, 2016
Messages
13
Best answers
0
Reaction score
1
Attributes MOD additional attributes

ADDITIONAL ATTRIBUTES
  • managain
  • manaticks
  • healthgain
  • healthticks
  • maxhealthpercent
  • maxmanapercent
  • soulpercent
  • magiclevelpercent

IMPLEMENTATION

  1. Find the following code in attributesmod.h:
    PHP:
    struct CONVERSION { 
        static const char* SKILL[7]; 
        static const char* STATS[5]; 
    };
  2. Replace with:
    PHP:
    struct CONVERSION {
        static const char* SKILL[7];
        static const char* STATS[5];
        static const char* STAT_PERCENT[5];
    
        static const char* MANA_REGEN_GAIN;
        static const char* MANA_REGEN_TICK;
        static const char* HEALTH_REGEN_GAIN;
        static const char* HEALTH_REGEN_TICK;
    };
  3. Find the following code in attributesmod.cpp:
    PHP:
    const char* CONVERSION::STATS[5] =
    {
        "maxhealthpoints",          // Increase max health
        "maxmanapoints",            // Increase max mana
        "soulpoints",               // Soul points bonus
        "level_not_implemented",    // Level increase not implemented, but can easily be
                                    // Just set an appropriate attribute name here and follow the comments in movement.cpp and item.cpp
        "magiclevel",               // Magic level bonus
    };
  4. Add this underneath:
    PHP:
    const char* CONVERSION::STAT_PERCENT[5] =
    {
        "maxhealthpercent",           // Increase max health
        "maxmanapercent",             // Increase max mana
        "soulpercent",                  // Soul points bonus
        "level_not_implemented",      // Level increase not implemented, but can easily be
                                      // Just set an appropriate attribute name here and follow the comments in movement.cpp and item.cpp
        "magiclevelpercent",          // Magic level bonus
    };
    
    const char* CONVERSION::HEALTH_REGEN_GAIN = "healthgain";
    const char* CONVERSION::HEALTH_REGEN_TICK = "healthticks";
    const char* CONVERSION::MANA_REGEN_GAIN = "managain";
    const char* CONVERSION::MANA_REGEN_TICK = "manaticks";
  5. Find the following code in movement.cpp:
    PHP:
        if(it.abilities.regeneration)
        {
            Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_REGENERATION, -1, 0);
            if(it.abilities.healthGain)
                condition->setParam(CONDITIONPARAM_HEALTHGAIN, it.abilities.healthGain);
    
            if(it.abilities.healthTicks)
                condition->setParam(CONDITIONPARAM_HEALTHTICKS, it.abilities.healthTicks);
    
            if(it.abilities.manaGain)
                condition->setParam(CONDITIONPARAM_MANAGAIN, it.abilities.manaGain);
    
            if(it.abilities.manaTicks)
                condition->setParam(CONDITIONPARAM_MANATICKS, it.abilities.manaTicks);
    
            player->addCondition(condition);
        }
  6. Replace with:
    PHP:
    // BEGIN ATTRIBUTES MOD
        if(it.abilities.regeneration || 
                !item->getAttribute(CONVERSION::HEALTH_REGEN_GAIN).empty() ||
                !item->getAttribute(CONVERSION::HEALTH_REGEN_TICK).empty() ||
                !item->getAttribute(CONVERSION::MANA_REGEN_GAIN).empty() ||
                !item->getAttribute(CONVERSION::MANA_REGEN_TICK).empty() )
        {
            Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_REGENERATION, -1, 0);
            boost::any attr;
    
            attr = item->getAttribute(CONVERSION::HEALTH_REGEN_GAIN);
            if(it.abilities.healthGain || !attr.empty())
            {
                int32_t val = 0;
    
                if (it.abilities.healthGain)
                    val += it.abilities.healthGain;
                if (!attr.empty() && ((attr.type() == typeid(float)) || (attr.type() == typeid(int32_t))))
                    val += boost::any_cast<int32_t>(attr);
    
                condition->setParam(CONDITIONPARAM_HEALTHGAIN, val);
            }
    
            attr = item->getAttribute(CONVERSION::HEALTH_REGEN_TICK);
            if(it.abilities.healthTicks || !attr.empty())
            {
                int32_t val = 0;
    
                if (it.abilities.healthTicks)
                    val += it.abilities.healthTicks;
                if (!attr.empty() && ((attr.type() == typeid(float)) || (attr.type() == typeid(int32_t))))
                    val += boost::any_cast<int32_t>(attr);
    
                condition->setParam(CONDITIONPARAM_HEALTHTICKS, val);
            }
    
            attr = item->getAttribute(CONVERSION::MANA_REGEN_GAIN);
            if(it.abilities.manaGain || !attr.empty())
            {
                int32_t val = 0;
    
                if (it.abilities.manaGain)
                    val += it.abilities.manaGain;
                if (!attr.empty() && ((attr.type() == typeid(float)) || (attr.type() == typeid(int32_t))))
                    val += boost::any_cast<int32_t>(attr);
    
                condition->setParam(CONDITIONPARAM_MANAGAIN, val);
            }
    
            attr = item->getAttribute(CONVERSION::MANA_REGEN_TICK);
            if(it.abilities.manaTicks || !attr.empty())
            {
                int32_t val = 0;
    
                if (it.abilities.manaTicks)
                    val += it.abilities.manaTicks;
                if (!attr.empty() && ((attr.type() == typeid(float)) || (attr.type() == typeid(int32_t))))
                    val += boost::any_cast<int32_t>(attr);
    
                condition->setParam(CONDITIONPARAM_MANATICKS, val);
            }
    
            player->addCondition(condition);
        }
        // END ATTRIBUTES MOD
  7. Find the following code in movement.cpp:
    PHP:
    // BEGIN ATTRIBUTES MOD 
            if ((stats_t)s != STAT_LEVEL) 
            { 
                boost::any statValue = item->getAttribute(CONVERSION::STATS[s]); 
    
                if (!statValue.empty())  
                { 
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t)))  
                    { 
                        player->setVarStats((stats_t)s, boost::any_cast<int32_t>(statValue)); 
                        if(!needUpdateStats) 
                            needUpdateStats = true; 
                    } 
                } 
            } 
            // END ATTRIBUTES MOD
  8. Replace with:
    PHP:
            // BEGIN ATTRIBUTES MOD
            if((stats_t)s != STAT_LEVEL) 
            {
                boost::any statValue = item->getAttribute(CONVERSION::STATS[s]);
    
                if (!statValue.empty())
                {
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t)))
                    {
                        player->setVarStats((stats_t)s, boost::any_cast<int32_t>(statValue));
                        if(!needUpdateStats)
                            needUpdateStats = true;
                    }
                }
    
                statValue = item->getAttribute(CONVERSION::STAT_PERCENT[s]);
    
                if(!statValue.empty())
                {
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t)))
                    {
                        player->setVarStats((stats_t)s, (int32_t)(player->getDefaultStats((stats_t)s) * ((boost::any_cast<int32_t>(statValue) - 100) / 100.f)));
                        if(!needUpdateStats)
                            needUpdateStats = true;
                    }
                }
            }
            // END ATTRIBUTES MOD
  9. Find the following code in movement.cpp:
    PHP:
    // BEGIN ATTRIBUTES MOD 
            if ((stats_t)s != STAT_LEVEL) 
            { 
                boost::any statValue = item->getAttribute(CONVERSION::STATS[s]); 
    
                if (!statValue.empty())  
                { 
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t)))  
                    { 
                        player->setVarStats((stats_t)s, -boost::any_cast<int32_t>(statValue)); 
                        if(!needUpdateStats) 
                            needUpdateStats = true; 
                    } 
                } 
            } 
            // END ATTRIBUTES MOD
  10. Replace with:
    PHP:
            // BEGIN ATTRIBUTES MOD
            if ((stats_t)s != STAT_LEVEL)
            {
                boost::any statValue = item->getAttribute(CONVERSION::STATS[s]);
    
                if (!statValue.empty()) 
                {
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t))) 
                    {
                        player->setVarStats((stats_t)s, -boost::any_cast<int32_t>(statValue));
                        if(!needUpdateStats)
                            needUpdateStats = true;
                    }
                }
    
                statValue = item->getAttribute(CONVERSION::STAT_PERCENT[s]);
    
                if(!statValue.empty())
                {
                    if ((statValue.type() == typeid(float)) || (statValue.type() == typeid(int32_t)))
                    {
                        player->setVarStats((stats_t)s, -(int32_t)(player->getDefaultStats((stats_t)s) * ((boost::any_cast<int32_t>(statValue) - 100) / 100.f)));
                        if(!needUpdateStats)
                            needUpdateStats = true;
                    }
                }
            }
            // END ATTRIBUTES MOD
  11. Find the following code in item.cpp:
    PHP:
    if(it.abilities.regeneration)
        {
  12. Replace all occurrences with:
    PHP:
    // BEGIN ATTRIBUTES MOD
            if(it.abilities.regeneration || 
                !item->getAttribute(CONVERSION::HEALTH_REGEN_GAIN).empty() ||
                !item->getAttribute(CONVERSION::HEALTH_REGEN_TICK).empty() ||
                !item->getAttribute(CONVERSION::MANA_REGEN_GAIN).empty() ||
                !item->getAttribute(CONVERSION::MANA_REGEN_TICK).empty() )
                // END ATTRIBUTES MOD
            {

Just recompile and you are done!
Does magic level percent work like increaceMagicpercent? The old attribute.
 

yoiker

Member
Joined
Jan 21, 2012
Messages
194
Best answers
1
Reaction score
8
This code have 4 years... So it won't work on TFS 1.0, 1.1 and 1.2
Oh, that hurts the truth would be great if you were to tfs 1.x+.
But thanks for taking the time to respond! :D
 

GhostWD

I'm in love with the var_dump()
Joined
Jan 25, 2009
Messages
185
Best answers
6
Reaction score
28
#digging I have seg fault on TFS 0.4 after adding this anybody could help me with that :C
 

Togu

Intermediate OT User
Joined
Jun 22, 2018
Messages
301
Best answers
1
Reaction score
143
Location
Brazil
Can I make an attribute that changes attack speed, walk speed, critical hit, critical chance, etc?
 

zyzz7omg

New Member
Joined
Jun 21, 2016
Messages
6
Best answers
0
Reaction score
1
Hello,
First of all, thank you for sharing this amazing MOD.
I made all you posted in your thread "attributes MOD" Feature - Attributes MOD and works fine for all skills. Problem comes with STATS, ONLY works with "magiclevel" stat... not with any others.
Maybe you have to source-edit the other stats like maxhealth, maxmana...? to get them work? So, I just did the same as you did for STAT_MAGICLEVEL, but for MAXHEALTH:
C++:
boost::any attr2 = item->getAttribute(CONVERSION::STATS[STAT_MAXHEALTH]);
            if (it.abilities->stats[STAT_MAXHEALTH] || !attr2.empty())
           
            {
                if (begin)
                {
                    begin = false;
                    s << " (";
                }
                else
                    s << ", ";
                // Holds the total increased value
                int32_t val2 = 0;

                // If we have an ability then include that into the value
                if (it.abilities->stats[STAT_MAXHEALTH])
                    val2 = (int32_t)it.abilities->stats[STAT_MAXHEALTH];
                // Make sure the value exist and that it is either float or integer.
                if (!attr2.empty() && ((attr2.type() == typeid(float)) || (attr2.type() == typeid(int32_t))))
                {
                    // Add attribute value to val
                    val2 += boost::any_cast<int32_t>(attr2);
                }
                s << "max health " << std::showpos << it.abilities->stats[STAT_MAXHEALTH] << std::noshowpos;
            }
It seems fine, but then my item gets 'max health +0' BUT when I equip it, IT WORKS! how is it possible?
PS. If you noted, I used variables 'attr' and 'val', as 'attr2' and 'val2' because if not, visual studio doesn't let me compile it.
 

Engradiel

Global 10.76 webpage: www.globalzera.com
Joined
May 3, 2009
Messages
49
Best answers
0
Reaction score
0
Location
Brazil
Hello guys. I know this is old. But I have an issue.
Is possible do it with the function absorbpercent?
Can someone help me?
Thanks.
 

ConAn Edujawa

Member
Joined
Feb 23, 2015
Messages
320
Best answers
0
Reaction score
5
this system work good but need to make it work auto without registering anyone can help me in code
im use 0.4
 

Engradiel

Global 10.76 webpage: www.globalzera.com
Joined
May 3, 2009
Messages
49
Best answers
0
Reaction score
0
Location
Brazil
all itens movements need to add in movements.lua. The almost just is there.
You have sucess to add this in tfs 0.4?
 

ConAn Edujawa

Member
Joined
Feb 23, 2015
Messages
320
Best answers
0
Reaction score
5
all itens movements need to add in movements.lua. The almost just is there.
You have sucess to add this in tfs 0.4?
if use real map i have to add all items in movements?? in real map not all items added in movements
 

Engradiel

Global 10.76 webpage: www.globalzera.com
Joined
May 3, 2009
Messages
49
Best answers
0
Reaction score
0
Location
Brazil
Just a simple itens dont are in movements. But if you hunt to upgrade someone is needed to put there to active.
 

heba

Advanced OT User
Joined
Aug 5, 2011
Messages
1,400
Best answers
14
Reaction score
197
anyone use this system must be careful about 2 things.
first one this system crash server when player look on items from npc windows
u can fix it by this way

second thing regeneration work after you remove items from slot
u can fix this by
remove this
Code:
    if(it.abilities.regeneration)
        player->removeCondition(CONDITION_REGENERATION, (ConditionId_t)slot);
to be like be
Code:
    if(it.abilities.regeneration || item->getAttribute(CONVERSION::HEALTH_REGEN_GAIN).empty()
        || item->getAttribute(CONVERSION::HEALTH_REGEN_TICK).empty()
        || item->getAttribute(CONVERSION::MANA_REGEN_GAIN).empty()
        ||item->getAttribute(CONVERSION::MANA_REGEN_TICK).empty())
        player->removeCondition(CONDITION_REGENERATION, (ConditionId_t)slot);
no more error

to use speed
change
Code:
    if(it.abilities.speed)
        g_game.changeSpeed(player, it.abilities.speed);
to
Code:
 if(it.abilities.speed  || item->getAttribute(CONVERSION::SPEED).empty())
    {
        boost::any attr;
        attr = item->getAttribute(CONVERSION::SPEED);
        int32_t val = 0;
                if (it.abilities.speed)
                val += it.abilities.speed;
            if (!attr.empty() && ((attr.type() == typeid(float)) || (attr.type() == typeid(int32_t))))
                val += boost::any_cast<int32_t>(attr);
        g_game.changeSpeed(player, val);
};
and replace
Code:
    if(it.abilities.speed)
        g_game.changeSpeed(player, -it.abilities.speed);
to
Code:
    if(it.abilities.speed || item->getAttribute(CONVERSION::SPEED).empty())
        g_game.changeSpeed(player, -it.abilities.speed);
and in attributesmod.cpp replace
Code:
const char* CONVERSION::HEALTH_REGEN_GAIN = "healthgain";
const char* CONVERSION::HEALTH_REGEN_TICK = "healthticks";
const char* CONVERSION::MANA_REGEN_GAIN = "managain";
const char* CONVERSION::MANA_REGEN_TICK = "manaticks";
to

Code:
const char* CONVERSION::SPEED = "speed";
const char* CONVERSION::HEALTH_REGEN_GAIN = "healthgain";
const char* CONVERSION::HEALTH_REGEN_TICK = "healthticks";
const char* CONVERSION::MANA_REGEN_GAIN = "managain";
const char* CONVERSION::MANA_REGEN_TICK = "manaticks";
and in attributesmod.h replace
Code:
    static const char* MANA_REGEN_GAIN;
    static const char* MANA_REGEN_TICK;
    static const char* HEALTH_REGEN_GAIN;
    static const char* HEALTH_REGEN_TICK;
to
Code:
    static const char* SPEED;
    static const char* MANA_REGEN_GAIN;
    static const char* MANA_REGEN_TICK;
    static const char* HEALTH_REGEN_GAIN;
    static const char* HEALTH_REGEN_TICK;
 
Last edited:
Top