• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFS 1.X+ tfs 1.3 not support dotted exp stages.

roriscrave

Advanced OT User
Joined
Dec 7, 2011
Messages
1,210
Solutions
35
Reaction score
207
Hi, I noticed that in tfs 1.3 there is a bug, stages.xml does not support dotted exp stages.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<stages>
    <config enabled="1" />
        <stage minlevel="1" maxlevel="10" multiplier="10"/>
        <stage minlevel="101" maxlevel="200" multiplier="5"/>
        <stage minlevel="201" maxlevel="300" multiplier="2.5"/>
        <stage minlevel="301" maxlevel="400" multiplier="1.5"/>
        <stage minlevel="401" maxlevel="500" multiplier="1"/>
        <stage minlevel="501" multiplier="0.5"/>
</stages>
for exemple, if player is in stage (201 to 300) and i print
Code:
Game.getExperienceStage(self:getLevel())
it print 0, because have a dot in multiplier (2.5)
if i put multiplier value 2 or 3 it print correct....

I triedto change
uint32_t to float here:
game.cpp
C++:
multiplier = pugi::cast<float>(multiplierAttribute.value());
and
C++:
float Game::getExperienceStage(uint32_t level)

game.h
C++:
std::map<uint32_t, float> stages;
and
C++:
float getExperienceStage(uint32_t level);
but with this new configurations (float) it print.
if stage is 3.7 -> return 3
if stage is 1.5 -> return 1
if stage is 0.8 -> return 0
it seems to round down
what was left to do?
 
Already noticed this problem :p
<stage minlevel="1" maxlevel="10" multiplier="10"/>
Should be maxlevel="100"

multiplier = pugi::cast<float>(multiplierAttribute.value());
float means rounding to lower

No idea, how looks correct solution, but it could help you, logically:
x = (float(exp * multiplier * 10)) / 10
multiply all stages by 10, delete all float, add dividing by 10 to each place where stage is checked.
 
Last edited:
as delusion said in the other thread, there is a lot to change in order to achieve it, and my bet is you have to hire someone to do it for you
 
There is no math.max in the commit I sent. And either way, you're looking at a benchmark of 1 million runs of both sets of code, and math.max is ~0.2 sec slower which is approximately 200 nanoseconds per call to math.max, and 100 nanoseconds to the < operator, you're not going to tell the difference when a server is running and executing those at separate times with unpredictable intervals, not 1 million executions at a time.
If you're going to actually believe what that says, then you should just stop using functions altogether since functions add a few nanoseconds of execution time just to lookup the function in the environment and call it.
I'm not saying that the code is wrong, I'm just saying it's dumb to use benchmarks like that to completely avoid using a function in exchange for a few nanoseconds of execution time, especially in code that's lightweight and won't be running that often to make a difference in your server.
 
Last edited:
Already noticed this problem :p
<stage minlevel="1" maxlevel="10" multiplier="10"/>
Should be maxlevel="100"

multiplier = pugi::cast<float>(multiplierAttribute.value());
float means rounding to lower

No idea, how looks correct solution, but it could help you, logically:
x = (float(exp * multiplier * 10)) / 10
multiply all stages by 10, delete all float, add dividing by 10 to each place where stage is checked.



THIS NEED TO BE ON TOP ANSWER!!!!!!!!!!!!!!

i did exactly what you said and it worked perfectly! i've been looking for an answer for at least an hour ! :)


<stage minlevel="1" maxlevel="4" multiplier="10" />
<stage minlevel="5" maxlevel="9" multiplier="12" />
<stage minlevel="10" maxlevel="14" multiplier="14" />
...

instead of


<stage minlevel="1" maxlevel="4" multiplier="1.0" />
<stage minlevel="5" maxlevel="9" multiplier="1.2" />
<stage minlevel="10" maxlevel="14" multiplier="1.4" />
...
then in data/events/scripts/player.lua

look for that function

function Player: onGainExperience(source, exp, rawExp)
...
exp = exp * 0.1 <-- add this line at the end!!!!
return exp
end


easy manipulation that require no time! thanks again!!
 
Eu resolvi da seguinte maneira :
Old :
function Player:onGainExperience(source, exp, rawExp)
if not source or source:isPlayer() then
return exp

New :


function Player:onGainExperience(source, exp, rawExp)
-- Se não houver source ou for outro player, retorna exp normal
if not source or source:isPlayer() then
return exp
end

local level = self:getLevel()
local rate = 1

-- Tabela de multiplicadores por level
if level >= 1 and level <= 50 then
rate = 20
elseif level >= 51 and level <= 70 then
rate = 10
elseif level >= 71 and level <= 100 then
rate = 8
elseif level >= 101 and level <= 120 then
rate = 6
elseif level >= 121 and level <= 150 then
rate = 5
elseif level >= 151 and level <= 180 then
rate = 4
elseif level >= 181 and level <= 200 then
rate = 3
elseif level >= 201 and level <= 250 then
rate = 2
elseif level >= 251 and level <= 300 then
rate = 1
elseif level >= 301 and level <= 350 then
rate = 0.8
elseif level >= 351 and level <= 380 then
rate = 0.5
elseif level >= 381 and level <= 400 then
rate = 0.3
elseif level >= 401 then
rate = 0.1
end

-- Multiplica pela tabela
exp = exp * rate

-- Garante que EXP nunca seja menor que 1
exp = math.max(1, exp)

-- Soul regeneration
local vocation = self:getVocation()
if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
self:addCondition(soulCondition)
end

-- Experience stage (opcional, se estiver usando stages.xml)
exp = exp * Game.getExperienceStage(self:getLevel())

-- Stamina system
if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
useStamina(self)

-- Bônus premium fixo
if self:isPremium() then
exp = exp * 1.2 -- sempre +20% de EXP
end
end

return exp
end
 
Back
Top