[v1.6.0-1.6.7] False negatives in ActorAI:canBumpDisplace()

Where bugs go to lie down and rest

Moderator: Moderator

Post Reply
Message
Author
Zizzo
Sher'Tul Godslayer
Posts: 2521
Joined: Thu Jan 23, 2003 8:13 pm
Location: A shallow water area south of Bree
Contact:

[v1.6.0-1.6.7] False negatives in ActorAI:canBumpDisplace()

#1 Post by Zizzo »

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:

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
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. :o 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:

Code: Select all

if self:attr('never_move') or target:attr('never_move') or target:attr('cant_be_moved') then return false end
(For the impatient, I've released a stopgap addon to paper over the bug. :wink: )
"Blessed are the yeeks, for they shall inherit Arda..."

Post Reply