• 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 0.X Why is this statsChange calling stack overflow?

Lurk

Active Member
Joined
Dec 4, 2017
Messages
336
Reaction score
48
I'm using tfs 0.4, rev 3777
I'm trying to use this script to increase damage by each player reset and it also has a chance to crit but it always returns a lot of errors in console even tho the values are fine
here's the script

Lua:
function onStatsChange(cid, attacker, type, combat, value)
    if (type == STATSCHANGE_HEALTHLOSS or type == STATSCHANGE_MANALOSS) and isPlayer(attacker) then
    local reset = getResets(attacker) -- get number of resets
    print("Resets: " ..reset)
    local bonusss = getPlayerStorageValue(attacker, bonuscrit) -- extra critical
        if reset > 0 then -- if the attacker has more than  reset
        print("Entrou no reset > 0")
        local extra_whith_resets = reset*40000 -- extra damage with each reset
            if (getPlayerStorageValue(attacker, lvlcrit)*3) >= math.random (0,1000) then -- if the attack has crited
                if bonusss <= 0 then -- if the guy doesn't have any crit boost
                    dano = math.ceil((value*(multiplier)) + extra_whith_resets)
                else
                    dano = math.ceil((value*(multiplier+(bonusss/10))) + extra_whith_resets)
                end
                doTargetCombatHealth(attacker, cid, combat, -dano, -dano, 255) -- wil do this damage with the extra by reset + crit boost + critical multiplier
                doSendAnimatedText(getCreaturePos(attacker), "CRITICAL", 105) -- color, can be checked with /y 200 in game
                doSendMagicEffect(getCreaturePos(attacker), 32) -- effect
                doPlayerSendCancel(attacker,"You have scored a CRITICAL HIT!") -- message so the player knows he crited
                return false -- dunno why it has to be a return false here
            end
            dano = math.ceil(value + extra_whith_resets) -- damage only with extra by reset, no crit involved
            print("Dano:" ..dano)
            doTargetCombatHealth(attacker, cid, combat, -dano, -dano, 255) -- applying the damage with this ugly ass effect
            return false
        end
    end
    return true
end

console:
Code:
[4:25:56.653] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.656] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.663] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.666] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.669] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.672] [Error - CreatureEvent::executeCombat] Call stack overflow.
[4:25:56.677] [Error - CreatureEvent::executeCombat] Call stack overflow.
Resets: 2
Entrou no reset > 0
Dano:85879
also, the character deals no damage to whoever he is trying to attack even tho the console prints the damage correctly
 
Last edited:
Solution
It's giving you a stack overflow, because you're looping the damage indefinitely.

return true -- allows the damage to go through.
return false -- disallows the damage (disallows original damage, so you can send a new damage.)

Here's a simple way to stop the infinite loop issue. (actually return true the damage at some point, instead of return false forever)
Lua:
local creatures = {} -- my addition

function onStatsChange(cid, attacker, type, combat, value)
    if (type == STATSCHANGE_HEALTHLOSS or type == STATSCHANGE_MANALOSS) and isPlayer(attacker) then
        local reset = getResets(attacker)
        local bonusss = getPlayerStorageValue(attacker, bonuscrit)
        if reset > 0 then
       
            -- my...
I'm printing dano already, in this particular instance it returned
Dano:85879
I dunno what more to print honestly
just printed extra_whith_resets, returned 80000 as it should
 
is this specific console log it wasn't entering the critical part since my character didn't had any crit chance but the prints over there showed perfectly fine numbers as well when I printed them (I'm not home rn to get print values but they're almost the same, just a bit higher like 10k or so )
Post automatically merged:

also I had tested this script before without any extra damage with resets (just the crits) and it worked perfecly, I added extra damage with reset and it bugged out
 
It's giving you a stack overflow, because you're looping the damage indefinitely.

return true -- allows the damage to go through.
return false -- disallows the damage (disallows original damage, so you can send a new damage.)

Here's a simple way to stop the infinite loop issue. (actually return true the damage at some point, instead of return false forever)
Lua:
local creatures = {} -- my addition

function onStatsChange(cid, attacker, type, combat, value)
    if (type == STATSCHANGE_HEALTHLOSS or type == STATSCHANGE_MANALOSS) and isPlayer(attacker) then
        local reset = getResets(attacker)
        local bonusss = getPlayerStorageValue(attacker, bonuscrit)
        if reset > 0 then
       
            -- my addition
            if creatures[cid] and creatures[cid] == 1 then
                creatures[cid] = 0
                return true
            end
            creatures[cid] = 1
            -- my addition
           
            local extra_whith_resets = reset * 40000
            if (getPlayerStorageValue(attacker, lvlcrit)*3) >= math.random (0,1000) then
                if bonusss <= 0 then
                    dano = math.ceil((value*(multiplier)) + extra_whith_resets)
                else
                    dano = math.ceil((value*(multiplier+(bonusss/10))) + extra_whith_resets)
                end
                doTargetCombatHealth(attacker, cid, combat, -dano, -dano, 255)
                doSendAnimatedText(getCreaturePos(attacker), "CRITICAL", 105)
                doSendMagicEffect(getCreaturePos(attacker), 32)
                doPlayerSendCancel(attacker,"You have scored a CRITICAL HIT!")
                return false
            end
            dano = math.ceil(value + extra_whith_resets)
            print("Dano:" ..dano)
            doTargetCombatHealth(attacker, cid, combat, -dano, -dano, 255)
            return false
        end
    end
    return true
end
 
Solution
holy fuck you're always saving my ass man, thank you so much <3
what does this
Lua:
             if creatures[cid] and creatures[cid] == 1 then
                creatures[cid] = 0
                return true
            end
            creatures[cid] = 1
actually do? I'm a noob and can't understand it
 
holy fuck you're always saving my ass man, thank you so much <3
what does this
Lua:
             if creatures[cid] and creatures[cid] == 1 then
                creatures[cid] = 0
                return true
            end
            creatures[cid] = 1
actually do? I'm a noob and can't understand it
We created a local table in order to hold creature data.

local creatures = {}

Then, we populate the table with information.
Lua:
local creatures = {
 --[cid] = 1,
    [982374987324] = 1, -- can use any value, but in this case '1' means that the next time the script loops, we are going to make them take damage.
    [982374987325] = 0, -- 0 means that damage was taken and we can now calculate a new damage.
  --[982374987326] <-- this big number is what cid actually looks like more or less.
}
if creatures[cid] and creatures[cid] == 1 then
This roughly translates to.. if cid exists in the table and cid is currently 1 then
creatures[cid] = 0
-- set cid to 0 (so it can do damage calculation again)
return true
let the damage go through

--
So, it goes through like this.

Step 1
-> confirm that it was actually damage and that the damage came from a player
Step 2
-> Check if the damage needs to be altered at all (reset)
Step 3
-> Add creature into table with value of '1'
-> Perform damage calculation
-> send new damage value (doTargetCombatHealth)
->negate the original damage (return false)

Step 4
-> confirm that it was actually damage and that the damage came from a player
Step 5
-> Check if the damage needs to be altered at all (reset)
Step 6
-> change creature information in table to '0'
->allow the modified damage to go through to cid successfully (return true)
 
Back
Top