[v1.6.0-1.6.7] False negatives in ActorAI:canBumpDisplace()
Posted: Thu Apr 09, 2020 11:33 pm
I was digging around in the code trying to find out why the Alchemist's golem can no longer push past non-hostile NPCs, and I think it's a bug. The relevant method is in mod.class.interface.ActorAI:
The trick here is that the 'never_move' and 'cant_be_moved' fields are both manipulated via Entity:addTemporaryValue() by various temporary effects, so if the golem has ever in its life been pinned or frozen or dazed or dominated or any of a number of paralyzing effects, its 'never_move' field will be 0 — and in Lua, unlike in C, 0 is treated as a true value.
In principle, this affects all NPCs, but only the golem (and presumably other semi-permanent player sidekicks) is likely to hang around long enough for the problem to be seen.
Fortunately, Entity:attr() is designed to handle that sort of thing, and it's how those fields are accessed everywhere else in the code. In particular, modifying the relevant line as follows appears to fix the bug:
(For the impatient, I've released a stopgap addon to paper over the bug.
)
Code: Select all
-- Can an NPC shove or swap positions with a space occupied by another NPC?
function _M:canBumpDisplace(target)
if target == game.player then return end
if target.rank >= self.rank then return false end
if not target.x then return end
if self.never_move or target.never_move or target.cant_be_moved then return false end
if not self.move_others then return false end
return true
end

Fortunately, Entity:attr() is designed to handle that sort of thing, and it's how those fields are accessed everywhere else in the code. In particular, modifying the relevant line as follows appears to fix the bug:
Code: Select all
if self:attr('never_move') or target:attr('never_move') or target:attr('cant_be_moved') then return false end
