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

Solved C++ issue: Adding percent skill attribute to items (SOLVED)

X X X

Newb
Joined
Jul 26, 2015
Messages
148
Reaction score
13
Hello,

I'm trying to add percent-based skill modifiers to items (TFS 1.2).

For example, I want to be able to add <attribute key="skillDistSword" value="XX" /> as an attribute to an item in items.xml.

Now, I understand that this is not included, and I have already done the source edits, but I know I goofed something up because while I don't get errors, the math is not behaving normally.

With my new code, I added <attribute key="skillDistSword" value="50" /> to a blue robe. There is already a movement for blue robe in movements.xml.

On my character with sword fighting level 10, I put on the blue robe, and it goes down to 5. Great! that's what it should do! Then I take the blue robe off, and...uh oh...it only goes back up to 9. Put the robe back on, down to 4. So on and so forth until eventually the character's sword skill gets to 1. Obviously I did something wrong, but I do not know what.

Here is what I changed:

First, in items.h:

C++:
//extra skill modifiers
    int32_t skills[SKILL_LAST + 1] = { 0 };
    int32_t skillsPercent[SKILL_LAST + 1] = { 0 }; //Added this line here

Then, in items.cpp:
C++:
} else if (tmpStrValue == "skillDistPercent") {
            it.getAbilities().skillsPercent[SKILL_SWORD] = pugi::cast<int32_t>(valueAttribute.value());

Then, in movement.cpp:
C++:
//skill modifiers
    bool needUpdateSkills = false;

    for (int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        if (it.abilities->skills[i]) {
            needUpdateSkills = true;
            player->setVarSkill(static_cast<skills_t>(i), it.abilities->skills[i]);
        }
        //Added this in here under moveevent equip
        if (it.abilities->skillsPercent[i]) {
            needUpdateSkills = true;
            player->setVarSkill(static_cast<skills_t>(i), static_cast<int32_t>(player->getDefaultSkills(static_cast<skills_t>(i)) * ((it.abilities->skillsPercent[i] - 100) / 100.f)));
        }
    }

    if (needUpdateSkills) {
        player->sendSkills();
    }


    //skill modifiers
    bool needUpdateSkills = false;

    for (int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        if (it.abilities->skills[i] != 0) {
            needUpdateSkills = true;
            player->setVarSkill(static_cast<skills_t>(i), -it.abilities->skills[i]);
        }
        //Added this here under moveevent deequip
        if (it.abilities->skillsPercent[i]) {
            needUpdateSkills = true;
            player->setVarSkill(static_cast<skills_t>(i), -static_cast<int32_t>(player->getDefaultSkills(static_cast<skills_t>(i)) * ((it.abilities->skillsPercent[i] - 100) / 100.f)));
        }
    }

Then, in player.cpp:
C++:
//added this under int32_t Player::getDefaultStats(stats_t stat) const
int32_t Player::getDefaultSkills(skills_t skill) const
{
    switch (skill) {
        case SKILL_SWORD: return getSkillLevel(SKILL_SWORD);
        default: return 0;
    }
}

Finally, under player.h:
C++:
void setVarSkill(skills_t skill, int32_t modifier) {
            varSkills[skill] += modifier;
        }
int32_t getDefaultSkills(skills_t stat) const; //Added this line here

Thank you!
 
Last edited:
Solution
Here is your problem:

C++:
int32_t Player::getDefaultSkills(skills_t skill) const
{
    switch (skill) {
        case SKILL_SWORD: return getSkillLevel(SKILL_SWORD);
        default: return 0;
    }
}
You're making it so the game is evaluating the modified skill every time, that's why you're seeing that behavior.

Should be:
C++:
int32_t Player::getDefaultSkills(skills_t skill) const
{
    switch (skill) {
        case SKILL_SWORD: return getBaseSkill(SKILL_SWORD);
        default: return 0;
    }
}
You could repeat this for every single skill if you wanted.
Thanks for replying, yes I have the DeEquip in movements.xml as well. If I didn’t have that, it wouldn’t change at all when I take the armor off. The problem is with the arithmetic in the source code. Like it’s not saving the base value, it keeps reducing it over and over.
 
Here is your problem:

C++:
int32_t Player::getDefaultSkills(skills_t skill) const
{
    switch (skill) {
        case SKILL_SWORD: return getSkillLevel(SKILL_SWORD);
        default: return 0;
    }
}
You're making it so the game is evaluating the modified skill every time, that's why you're seeing that behavior.

Should be:
C++:
int32_t Player::getDefaultSkills(skills_t skill) const
{
    switch (skill) {
        case SKILL_SWORD: return getBaseSkill(SKILL_SWORD);
        default: return 0;
    }
}
You could repeat this for every single skill if you wanted.
 
Solution
Back
Top