Thankfully, there is an easy answer, and if it was standardized, this problem would disappear (and as this spread to other on_Xs, you might even reclaim some existing endless wasteland functions). Implement a stack of on_act functions.
Code: Select all
_M.on_act = function(self)
if not self.stack or not self.stack.on_act then return end
for key, fct in pairs(self.stack.on_act) do fct(self) end --not ipairs; we don't want to skip holes
end
_M.pushOnStack = function(self, stackName, func) --call with example self:pushStack("on_act", myFct)
self.stack = self.stack or {}; self.stack[stackName] = self.stack[stackName] or {}
local pos = 0
for key, value in ipairs(self.stack[stackName]) do pos = key end --we want the first nil space
pos = pos+1
self.stack[stackName][pos] = func
return pos
end
_M.popOnStack = function(self, stackName, pos)
if not self.stack or not self.stack[stackName] or not self.stack[stackName][pos] then return err, "No stack or no entry at that position" end
self.stack[stackName][pos] = nil --we've got a table full of holes, it's the price of consistent IDs for removal
return true
end
These three simple functions should solve all of the problems with on_act and with any similar fields. There are a lot of possible permutations depending on how much work you wanted to put into it-- you could make call, push, pop all a single function, with the entire stack maintained inside of the function. You could allow functions to be assigned to on_act with keys, in case the author was willing to accept the risk of error in the case of duplicate keys in exchange for code clarity.
Currently, on_act is used by very few talents (probably for the reasons already described). The earlier this change is made, the less painful it is to change. Fields like on_hit would benefit from the same change, but their prevalence makes it much more painful to make a stack for on_hit (you could monitor for changes to on_hit and update stack based on that, but that's a temporary solution, not very elegant). You'll notice that I specifically wrote these prototype pushOnStack and popOnStack functions to work with any number of different on_X fields.