Problems with callbackOnTakeDamage

Moderator: Moderator

Post Reply
Message
Author
ghostbuster
Uruivellas
Posts: 617
Joined: Mon Oct 09, 2006 7:47 pm

Problems with callbackOnTakeDamage

#1 Post by ghostbuster »

I try to make an addon with a talent that converts part of the damage *taken* to a specific type (mind) (for a psionic class that gets some benefits from taking mind damage).

I did not find anything similar in any vaniila or addon talent.
So here is what I tried in the talent code.
The idea is to have a callback in the default projector that reduces the original damage and projects the new converted mind damage on the grid.

Code: Select all

callbackOnTakeDamage = function(self, t, src, x, y, type, dam, tmp)
   local ff = self:isTalentActive(t.id)
   if not ff then return dam end
   if type == DamageType.MIND then	return dam end
   local mdam = dam * t.getMindConvert(self,t)
   DamageType:get(DamageType.MIND).projector(src, x, y, DamageType.MIND, mdam)
   game:delayedLogDamage(self, self, 0, "#YELLOW_GREEN##Target# displaced some damage to its mind!")
    dam = dam - mdam
   return {dam=dam}
end,


There are indeed two different problems:

1/ there is lua error with this code. The problem obviously comes from the call to a projector in the callback.

Code: Select all

Lua Error: /engine/interface/ActorTalents.lua:322: /engine/interface/ActorTalents.lua:295: /engine/interface/ActorTalents.lua:162: /data/damage_types.lu
a:477: attempt to index local 'ret' (a number value)
stack traceback:
        /data/damage_types.lua:477: in function 'projector'
        /data-mentalist/talents/psionic/mental-resilience.lua:59: in function 'callTalent'
        /mod/class/Actor.lua:5247: in function 'cb'
        /data/damage_types.lua:475: in function 'defaultProjector'
        /data/damage_types.lua:703: in function 'projector'
        /mod/class/interface/Combat.lua:600: in function 'attackTargetWith'
        /mod/class/interface/Combat.lua:225: in function 'attackTarget'
        /data/talents/misc/misc.lua:75: in function </data/talents/misc/misc.lua:54>
        [C]: in function 'xpcall'
        /engine/interface/ActorTalents.lua:160: in function </engine/interface/ActorTalents.lua:149>
        At [C]:-1 
        At [C]:-1 error
        At /engine/interface/ActorTalents.lua:322 useTalent
        At /mod/class/interface/Combat.lua:37 attack
   ...
I do not understand what I am doing wrong. Anybody has an idea?

2/ Actually, what I would like to use is callbackOnTakeDamageBeforeResists, instead of callbackOnTakeDamage in order to avoid the double resists application for the original damage and the converted mind damage. If I replace in the talent with callbackOnTakeDamageBeforeResists, absolutely nothing happens. The callback seems to be completely ignored.
I 'grep -r' in the source tree and the callback is only used in one place for an effect that I never noticed (chromatic resonance). Does anybody knows if there is problem with the callback or if I use it incorrectly?

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Problems with callbackOnTakeDamage

#2 Post by HousePet »

Problem 1:
Remember that dam is sometimes a single value and sometimes a table. You don't seem to have checked for this.
Also, you appear to be taking a single value and then returning it as a value in a table.
My feedback meter decays into coding. Give me feedback and I make mods.

ghostbuster
Uruivellas
Posts: 617
Joined: Mon Oct 09, 2006 7:47 pm

Re: Problems with callbackOnTakeDamage

#3 Post by ghostbuster »

I changed the code to take into account if dam is a table, but there is still the same error.

Code: Select all

callbackOnTakeDamage = function(self, t, src, x, y, dtype, dam, tmp)
   local ff = self:isTalentActive(t.id)
   if dtype == DamageType.MIND then   return dam end
   local mdam
   if not ff then return dam end
   if type(dam) == 'number' then
      mdam = dam * t.getMindConvert(self,t)
      dam = dam - mdam
   else
      mdam = dam.dam * t.getMindConvert(self,t)
      dam.dam = dam.dam - mdam
   end
   DamageType:get(DamageType.MIND).projector(src, x, y, DamageType.MIND, mdam)
   game:delayedLogDamage(self, self, 0, "#YELLOW_GREEN##Target# displaced some damage to its mind!")
   return dam
end,
Actually, I think the problem is really the call of a projector in the callback. If the line is commented out, there are no longer any error.
It is strange as the default projector in damage_types.lua calls many projectors for damage conversion of the damage dealt. I do not understand why it is not possible to do that in a callback for the damage taken.

ghostbuster
Uruivellas
Posts: 617
Joined: Mon Oct 09, 2006 7:47 pm

Re: Problems with callbackOnTakeDamage

#4 Post by ghostbuster »

I tried in a hook and it worked solving all the problems.

But I was still worried not to understand why my code was incorrect.
I finally discovered that damage hooks always expect that the damage is returned in an array, even if it was initially a number.
So always returning an array fixed the problem.

Code: Select all

callbackOnTakeDamage = function(self, t, src, x, y, dtype, dam, tmp)
   local ff = self:isTalentActive(t.id)
   local ret
   if type(dam) == 'number' then
       ret={dam = dam}
   else
       ret = dam
   end
   if not ff then return ret end
   if dtype == DamageType.MIND then   return ret end
   local mdam = ret.dam * t.getMindConvert(self,t)
   ret.dam = ret.dam- mdam
   DamageType:get(DamageType.MIND).projector(src, x, y, DamageType.MIND, mdam)
   game:delayedLogDamage(self, self, 0, "#YELLOW_GREEN##Target# displaced some damage to its mind!")
   return ret
end,
Concerning problem #2 (using before resist hook), it was probably an interaction with my buggy code. It works well.

Post Reply