Ir para conteúdo
  • 0

Statschange (Call Stack Overflow)


LuckOake

Pergunta

Oi povo.

 

Seguinte, tem uns 2 meses que tô tentando desenvolver um sistema, mas tô apanhando pra ele. Não, eu não vou falar que sistema é esse, apenas quero ajuda. Sério, tô entalado num trecho do script há tempos e não importa o que eu tente, nunca consigo resolver.

 

O que ele faz: Quando um summon ataca um monstro, o ataque é aumentado em 30% e eu recebo uma mensagem dizendo quanto foi o dano. Simples, não?

 

Script:

 

function onStatsChange(cid, attacker, type, combat, value)
if isSummon(attacker) and isMonster(cid) and getPlayerStorageValue(getCreatureMaster(attacker), 17823) >= 1 then
if type == STATSCHANGE_HEALTHLOSS and value >= 1 then
local dmg = math.floor(value*1.3)
doTargetCombatHealth(attacker, cid, COMBAT_PHYSICALDAMAGE, -dmg, -dmg, CONST_ME_NONE)
doPlayerSendTextMessage(getCreatureMaster(attacker), MESSAGE_STATUS_CONSOLE_ORANGE, "Your "..getCreatureName(attacker).." deals "..dmg.." damage.")
end
end
return true
end

 

 

OBS: Sim, eu tenho a função isSummon. Caso precise dela, tó:

 

function isSummon(sid)
for i, pid in ipairs(getPlayersOnline()) do
for c, cid in pairs(getCreatureSummons(pid)) do
if (cid == sid) then
return true
end
end
end
return false
end

 

 

O que acontece é o seguinte: quando meu summon ataca o monstro, dá a mensagem:

 

[Error - CreatureEvent::executeStatsChange] Call stack overflow.

 

E ingame, o summon ranca uns 7k de dano, sendo que o attacker é um rat, e recebo a mensagem várias vezes:

 

 

21:54 Your Rat deals 104 damage.
21:54 Your Rat deals 80 damage.
21:54 Your Rat deals 62 damage.
21:54 Your Rat deals 48 damage.
21:54 Your Rat deals 37 damage.
21:54 Your Rat deals 29 damage.
21:54 Your Rat deals 23 damage.
21:54 Your Rat deals 18 damage.
21:54 Your Rat deals 14 damage.
21:54 Your Rat deals 1090 damage.
21:54 Your Rat deals 839 damage.
21:54 Your Rat deals 646 damage.
21:54 Your Rat deals 497 damage.
21:54 Your Rat deals 383 damage.
21:54 Your Rat deals 295 damage.
21:54 Your Rat deals 227 damage.
21:54 Your Rat deals 175 damage.
21:54 Your Rat deals 135 damage.
21:54 Your Rat deals 104 damage.
21:54 Your Rat deals 80 damage.
21:54 Your Rat deals 62 damage.
21:54 Your Rat deals 48 damage.
21:54 Your Rat deals 37 damage.
21:54 Your Rat deals 29 damage.
21:54 Your Rat deals 23 damage.
21:54 Your Rat deals 18 damage.
21:54 Your Rat deals 14 damage.
21:54 Your Rat deals 11 damage.
21:54 Your Rat deals 9 damage.
21:54 Your Rat deals 7 damage.

 

 

Então, quem vai me salvar?

Editado por LuckOake
Link para o comentário
Compartilhar em outros sites

9 respostass a esta questão

Posts Recomendados

  • 1

callstack overflow é significa que você realizou um loop infinito na mesma função, no caso a stats change, quando a criatura que tem esse evento registrado perde vida, a doTargetCombatHealth faz com que ela perca vida novamente ativando de novo o onstats change, que faz com que a doTargetCombatHealth seja executada de novo e assim vai até o servidor perceber que a mesma função não tem saída e indica o erro.

 

o que o slicer falou está certo, mesmo que você tire esse erro, se deixar o return true, o monstro vai bater o dano normal, digamos que seja 100, mais o valor do doTargetCombatHealth, que seria 130, totalizando 230, colocando return false, você anula o dano de 100 e aí sim você vai ter a aparência de na verdade o monstro estar tirando 130.

 

usa a script assim:

 

local overflow_protection = {}

function onStatsChange(cid, attacker, type, combat, value)

   if isSummon(attacker) and isMonster(cid) and
   getPlayerStorageValue(getCreatureMaster(attacker), 17823) >= 1 and
   type == STATSCHANGE_HEALTHLOSS and value >= 1 then

    if overflow_protection[attacker] then
	    overflow_protection[attacker] = nil
    return true
    end

    local dmg = math.floor(value * 1.3)
    overflow_protection[attacker] = true
    doTargetCombatHealth(attacker, cid, COMBAT_PHYSICALDAMAGE, -dmg, -dmg, CONST_ME_NONE)
    doPlayerSendTextMessage(getCreatureMaster(attacker), MESSAGE_STATUS_CONSOLE_ORANGE, "Your "..getCreatureName(attacker).." deals "..dmg.." damage.")

   return false
   end

return true
end

Link para o comentário
Compartilhar em outros sites

  • 0

Nunca vi este erro, a conta deve estar errada mais tente aí.

 

function onStatsChange(cid, attacker, type, combat, value)
if isSummon(attacker) and getCreatureMaster(attacker) == cid and isMonster(cid) and getPlayerStorageValue(getCreatureMaster(attacker), 17823) >= 1 then

if type == STATSCHANGE_HEALTHLOSS then

local dano = math.floor(value/100*3)
doTargetCombatHealth(attacker, cid, COMBAT_PHYSICALDAMAGE, -dano, -dano, CONST_ME_NONE)
doPlayerSendTextMessage(getCreatureMaster(attacker), MESSAGE_STATUS_CONSOLE_ORANGE, "Your's ".. getCreatureName(attacker) .." deals ".. dano .." damage to " .. getCreatureName(cid) .. ".")
end
end
return true
end

 

tu registro certin tudo? acho que quando se trata de mostro não tem que registar o evento na xml dele sla.

Link para o comentário
Compartilhar em outros sites

  • 0

Não rolou.

 

Sua fórmula faz o dano adicional ser 0, pois imaginando que um summon dê um hit de 10. 10/100 = 0.1 * 3 = 0,3, mas como é math.floor, vai arredondar pra 0. Mas se colocar math.ceil vai arredondar pra 1 e o script não chega a dar Call Stack Overflow, mas ele se repete três vezes.

 

Sim, esse script tá tenso.

Link para o comentário
Compartilhar em outros sites

  • 0

pelo q sei tens q da return false no script.. ;x pq se n vai sair o dano q tu deu e mais o dano normal q sairia...

 

function isSummon(cid)

return (isCreature(cid) and isPlayer(getCreatureMaster(cid)))

end

 

function onStatsChange(cid, attacker, type, combat, value)

if isSummon(attacker) and isMonster(cid) and getPlayerStorageValue(getCreatureMaster(attacker), 17823) >= 1 then

if type == STATSCHANGE_HEALTHLOSS and value >= 1 then

local dmg = math.floor(value*1.3)

doCreatureAddHealth(cid, -math.abs(dmg))

doPlayerSendTextMessage(getCreatureMaster(attacker), 20, "Your "..getCreatureName(attacker).." deals "..dmg.." damage.")

return false

end

end

return true

end

 

Link para o comentário
Compartilhar em outros sites

  • 0

@Slicer

 

Se colocar return false, o monstro para de receber dano (não leva hit, fica imortal).

 

Dá pra driblar isso que você falou com a fórmula value-math.floor(value*0.7) <-- 30% do valor do dano

 

(Vamos lá scripters, será que ninguém vai conseguir solucionar isso?)

Editado por LuckOake
Link para o comentário
Compartilhar em outros sites

  • 0

veio com o addHealth ali n era pra da isso com o return false ;x pode ir ver no PDA do brun.. no final do exp.lua, q eh statschange, ele coloca return false... e o dano sai normal ;x o caso eh esperar o brun aparecer... kk

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...