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

TFS 1.X+ Skill Loss

ManuelOficial

Member
Joined
Jul 20, 2012
Messages
25
Solutions
1
Reaction score
6
Hello guys!
I'm here to ask you guys if there's a way to always "remove" 1 players skill by db.query (or another way that I don't know) when they die. I'm using TFS 1.3 (10.98) and I need to remove exact numbers and not only skill tries, so thats why I'm using db.query: didn't found any function to do it.

I tried to set a query just after player dies on playerdeath.lua but it doesn't works.

Do you guys knows how to do it?

Thanks
 
Example
Lua:
local skill = player:getSkillLevel(SKILL_FIST)
player:setSkillLevel(SKILL_FIST, skill - 1)

Lua:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/playerdeath.lua:onDeath
data/creaturescripts/scripts/playerdeath.lua:7: attempt to call method 'setSkillLevel' (a nil value)
stack traceback:
        [C]: in function 'setSkillLevel'
        data/creaturescripts/scripts/playerdeath.lua:7: in function <data/creaturescripts/scripts/playerdeath.lua:4>

found setSkillLoss instead of setSkillLevel on luascript.cpp
Code:
registerMethod("Creature", "setSkillLoss", LuaScriptInterface::luaCreatureSetSkillLoss);
Maybe this is the right one?
 
Lua:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/playerdeath.lua:onDeath
data/creaturescripts/scripts/playerdeath.lua:7: attempt to call method 'setSkillLevel' (a nil value)
stack traceback:
        [C]: in function 'setSkillLevel'
        data/creaturescripts/scripts/playerdeath.lua:7: in function <data/creaturescripts/scripts/playerdeath.lua:4>

found setSkillLoss instead of setSkillLevel on luascript.cpp
Code:
registerMethod("Creature", "setSkillLoss", LuaScriptInterface::luaCreatureSetSkillLoss);
Maybe this is the right one?
Try player:addSkill
 
Try player:addSkill

Lua:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/playerdeath.lua:onDeath
data/creaturescripts/scripts/playerdeath.lua:7: attempt to call method 'addSkill' (a nil value)
stack traceback:
        [C]: in function 'addSkill'
        data/creaturescripts/scripts/playerdeath.lua:7: in function <data/creaturescripts/scripts/playerdeath.lua:4>

Maybe these functions are missing on my sources. :/
 
Lua:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/playerdeath.lua:onDeath
data/creaturescripts/scripts/playerdeath.lua:7: attempt to call method 'addSkill' (a nil value)
stack traceback:
        [C]: in function 'addSkill'
        data/creaturescripts/scripts/playerdeath.lua:7: in function <data/creaturescripts/scripts/playerdeath.lua:4>

Maybe these functions are missing on my sources. :/
Hmm... Yes maybe cuz i have highly edited one. This thread should help you Solved - [Movements] OnStepIn update player skills(db.query) (https://otland.net/threads/movements-onstepin-update-player-skills-db-query.220047/)
 
Dear @ManuelOficial,

I guess you are looking for this LUA line:
Lua:
target:addSkillTries(skillId, target:getVocation():getRequiredSkillTries(skillId, target:getSkillLevel(skillId) + 1) - target:getSkillTries(skillId))

I hope this was what you're looking for.

Sincerely,
Ralumbi(Caleb)
 
Dear @ManuelOficial,

I guess you are looking for this LUA line:
Lua:
target:addSkillTries(skillId, target:getVocation():getRequiredSkillTries(skillId, target:getSkillLevel(skillId) + 1) - target:getSkillTries(skillId))

I hope this was what you're looking for.

Sincerely,
Ralumbi(Caleb)
You cant make via lua negative values in skill tries
 
Then make it hardcoded indeed. Do you want this to be permanent or be adjustable?
I could help you if I know the exact idea of your action.
 
Then make it hardcoded indeed. Do you want this to be permanent or be adjustable?
I could help you if I know the exact idea of your action.

Hello sir,
the idea is to make the player lose an exact skill level when he dies. Example: a player has 30 sword skill, if he dies, he will have 29.

The problem is that i have no function in my sources that does this, the only way out was to try db.query, but unfortunately it doesn't work because the action is taken while the player is still online (even using the parameter onDeath).

I didn't find a way to run db.query when the player is effectively offline.
 
Your skill loss code is probably going to be in player.cpp regardless of what codebase your server is based on

Just find it! The best documentation is your code. Just search for "loss"
 
what if you change the database on login? give player a special storagevalue when he dies, and if he has it on login the if will be executed Before he is online? idk

Each exp, and full skill advancement can be saved in personal storagevalues and when player dies you have in config 100% skill and exp loss, go back to level 1, all skills to 10 and when he logs back in, or at the end of onDeath, for loop on each storagevalue to increase skills to desired level, and add the exp he should have so he returned to the level he was supposed to
 
I put the for loop inside an if/else statement and created an extra config which can be used in the config.lua and set true/false.
Inside your configmanager.h around line 71 you must write inside the array ON_DEATH_MINUS_SKILLS
Inside the configmanager.cpp you must add the following line near line 150 integer[ON_DEATH_MINUS_SKILLS] = getGlobalNumber(L, "onDeathMinusSkills", true);

Use this code instead of the skill loss only for statement used in player.cpp (most likely around line 2019)
C++:
uint32_t onDeathMinusSkills = g_config.getNumber(ConfigManager::ON_DEATH_MINUS_SKILLS);
        if (onDeathMinusSkills == true)
        {
            std::ostringstream query;
            query.str(std::string());
            query << "UPDATE `players` SET config_value = CASE config_name WHEN 'skill_fist' THEN '-1' WHEN 'skill_club' THEN '-1' WHEN 'skill_sword' THEN '-1' WHEN 'skill_axe' THEN '-1' WHEN 'skill_dist' THEN '-1' WHEN 'skill_shielding' THEN '-1' WHEN 'skill_fishing' THEN '-1' WHEN 'maglevel' THEN '-1' ELSE config_value END WHERE config_name IN('skill_fist', 'skill_club', 'skill_sword', 'skill_axe', 'skill_dist', 'skill_shielding', 'skill_fishing', 'skill_maglevel');";
            g_databaseTasks.addTask(query.str());
        }
        else
        {
            for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
                uint64_t sumSkillTries = 0;
                for (uint16_t c = 11; c <= skills[i].level; ++c) { //sum up all required tries for all skill levels
                    sumSkillTries += vocation->getReqSkillTries(i, c);
                }

                sumSkillTries += skills[i].tries;

                uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);
                while (lostSkillTries > skills[i].tries) {
                    lostSkillTries -= skills[i].tries;

                    if (skills[i].level <= 10) {
                        skills[i].level = 10;
                        skills[i].tries = 0;
                        lostSkillTries = 0;
                        break;
                    }

                    skills[i].tries = vocation->getReqSkillTries(i, skills[i].level);
                    skills[i].level--;
                }

                skills[i].tries = std::max<int32_t>(0, skills[i].tries - lostSkillTries);
                skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
            }
        }

Hope this is what you were looking for :)
Don't forget to add onDeathMinusSkills = true inside your config.lua (anywhere in there is fine)

EDIT:
Also add these two lines in your player.cpp:
#include "database.h"
#include "databasetasks.h"

Not 100% sure about the query though.

Sincerely,
Ralumbi(Caleb)
 
Last edited:
Hello sir,
the idea is to make the player lose an exact skill level when he dies. Example: a player has 30 sword skill, if he dies, he will have 29.

The problem is that i have no function in my sources that does this, the only way out was to try db.query, but unfortunately it doesn't work because the action is taken while the player is still online (even using the parameter onDeath).

I didn't find a way to run db.query when the player is effectively offline.
@edit
player.cpp
uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);

Now you must change it
Something like that, then when player die, should lose always only 1 skill
C++:
uint32_t lostSkillTries = static_cast<uint32_t>(skills[i].tries - (skills[i].tries - getReqSkillTries(i, skills[i].level - 1));
Im not sure, cant test it right now.
 
Last edited:
I put the for loop inside an if/else statement and created an extra config which can be used in the config.lua and set true/false.
Inside your configmanager.h around line 71 you must write inside the array ON_DEATH_MINUS_SKILLS
Inside the configmanager.cpp you must add the following line near line 150 integer[ON_DEATH_MINUS_SKILLS] = getGlobalNumber(L, "onDeathMinusSkills", true);

Use this code instead of the skill loss only for statement used in player.cpp (most likely around line 2019)
C++:
uint32_t onDeathMinusSkills = g_config.getNumber(ConfigManager::ON_DEATH_MINUS_SKILLS);
        if (onDeathMinusSkills == true)
        {
            std::ostringstream query;
            query.str(std::string());
            query << "UPDATE `players` SET `skill_fist` = -1";
            g_databaseTasks.addTask(query.str());
        }
        else
        {
            for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { //for each skill
                uint64_t sumSkillTries = 0;
                for (uint16_t c = 11; c <= skills[i].level; ++c) { //sum up all required tries for all skill levels
                    sumSkillTries += vocation->getReqSkillTries(i, c);
                }

                sumSkillTries += skills[i].tries;

                uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);
                while (lostSkillTries > skills[i].tries) {
                    lostSkillTries -= skills[i].tries;

                    if (skills[i].level <= 10) {
                        skills[i].level = 10;
                        skills[i].tries = 0;
                        lostSkillTries = 0;
                        break;
                    }

                    skills[i].tries = vocation->getReqSkillTries(i, skills[i].level);
                    skills[i].level--;
                }

                skills[i].tries = std::max<int32_t>(0, skills[i].tries - lostSkillTries);
                skills[i].percent = Player::getPercentLevel(skills[i].tries, vocation->getReqSkillTries(i, skills[i].level));
            }
        }

Hope this is what you were looking for :)
Don't forget to add onDeathMinusSkills = true inside your config.lua (anywhere in there is fine)

EDIT:
Also add these two lines in your player.cpp:
#include "database.h"
#include "databasetasks.h"


Sincerely,
Ralumbi(Caleb)

@edit
player.cpp
uint32_t lostSkillTries = static_cast<uint32_t>(sumSkillTries * deathLossPercent);

Now you must change it
Something like that, then when player die, should lose always only 1 skill
C++:
uint32_t lostSkillTries = static_cast<uint32_t>(skills[i].tries - (skills[i].tries - getReqSkillTries(i, skills[i].level - 1));
Im not sure, cant test it right now.
Your skill loss code is probably going to be in player.cpp regardless of what codebase your server is based on

Just find it! The best documentation is your code. Just search for "loss"
what if you change the database on login? give player a special storagevalue when he dies, and if he has it on login the if will be executed Before he is online? idk

Each exp, and full skill advancement can be saved in personal storagevalues and when player dies you have in config 100% skill and exp loss, go back to level 1, all skills to 10 and when he logs back in, or at the end of onDeath, for loop on each storagevalue to increase skills to desired level, and add the exp he should have so he returned to the level he was supposed to

Thanks you guys for the support! I'll try it all!
You guys are the best.

I'll come back to talk about the results
 
@ManuelOficial
I've tested the source edit I made, it works. You just have to fix the SQL yourself. As what I got myself it changing all the players tables at once instead of just the players table. SO BE CAREFUL!!! Also making it able to turn it on and off worked as well :)

Learned myself a bit again as well.

Sincerely,
Ralumbi(Caleb)
 
Back
Top