Index: game/engines/default/engine/GameEnergyBased.lua =================================================================== --- game/engines/default/engine/GameEnergyBased.lua (revision 3708) +++ game/engines/default/engine/GameEnergyBased.lua (working copy) @@ -77,7 +77,7 @@ if e.energy.value < self.energy_to_act then e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1) * (e.global_speed or 1) end - if e.energy.value >= self.energy_to_act then + if e.energy.value >= self.energy_to_act or e.doForceAct and e:doForceAct() then e.energy.used = false e:act(self) end @@ -104,7 +104,7 @@ if e.energy.value < self.energy_to_act then e.energy.value = (e.energy.value or 0) + self.energy_per_tick * (e.energy.mod or 1) * (e.global_speed or 1) end - if e.energy.value >= self.energy_to_act then + if e.energy.value >= self.energy_to_act or e.doForceAct and e:doForceAct() then e.energy.used = false e:act(self) end Index: game/modules/tome/class/Actor.lua =================================================================== --- game/modules/tome/class/Actor.lua (revision 3708) +++ game/modules/tome/class/Actor.lua (working copy) @@ -323,6 +323,15 @@ end end +-- Checks if actions intended to occur on game turns need to be forced to happen this game turn (needed if actor is slowed or drained of energy) +function _M:doForceAct() + local actturn = math.floor(game.turn / (game.zone.wilderness and 1000 or 10)) + local nextturn = math.floor((game.turn + 1) / (game.zone.wilderness and 1000 or 10)) + if not self.last_act_turn then self.last_act_turn = actturn - 1 end + + return actturn ~= nextturn and actturn > self.last_act_turn +end + function _M:act() if not engine.Actor.act(self) then return end @@ -364,7 +373,7 @@ end -- Auto stealth? - if self:isTalentActive(self.T_AUTOMATIC_STEALTH) and not self:isTalentActive(self.T_STEALTH) then + if self:isTalentActive(self.T_AUTOMATIC_STEALTH) and not self:isTalentActive(self.T_STEALTH) and self.energy.value >= game.energy_to_act then local t = self:getTalentFromId(self.T_STEALTH) if self:preUseTalent(t, true, true) and not self:isTalentCoolingDown(t) then self:useTalent(self.T_STEALTH) Index: game/modules/tome/class/NPC.lua =================================================================== --- game/modules/tome/class/NPC.lua (revision 3708) +++ game/modules/tome/class/NPC.lua (working copy) @@ -34,10 +34,12 @@ end function _M:act() + -- Do basic actor stuff + if not mod.class.Actor.act(self) then return end + local firstpass = true while self:enoughEnergy() and not self.dead do - -- Do basic actor stuff - if not mod.class.Actor.act(self) then return end local old_energy = self.energy.value + if not firstpass and not mod.class.Actor.act(self) then return end -- Compute FOV, if needed self:doFOV() @@ -56,6 +58,7 @@ if not self.energy.used then self:useEnergy() end if old_energy == self.energy.value then break end -- Prevent infinite loops + firstpass = nil end end Index: game/modules/tome/class/WorldNPC.lua =================================================================== --- game/modules/tome/class/WorldNPC.lua (revision 3708) +++ game/modules/tome/class/WorldNPC.lua (working copy) @@ -164,10 +164,11 @@ end function _M:act() + -- Do basic actor stuff + if not mod.class.Actor.act(self) then return end + local firstpass = true while self:enoughEnergy() and not self.dead do - -- Do basic actor stuff - if not mod.class.Actor.act(self) then return end - + if not firstpass and not mod.class.Actor.act(self) then return end -- Compute FOV, if needed self:doFOV() @@ -176,6 +177,7 @@ self:doAI() if not self.energy.used then self:useEnergy() end + firstpass = nil end end