Project Zomboid

Project Zomboid

[B42/B41] Bandits NPC
Solution for Random Zombie Freezing - Lua Code for BanditUpdate.lua
Hey everyone, I think (and hope) I’ve fixed the issue where zombies freeze and stay stuck during a movement animation.

What I did:
_ Started from the known fix that removes the <m_Conditions> blocks checking whether the zombie is a bandit.
_ Added extra checks and an “unfreezer” routine directly in the BanditUpdate.lua file.

---

### Solution

**File:** `42\media\lua\client\BanditUpdate.lua`

At the very end of the file, **after** the function
`local function OnDeadBodySpawn(body)`
(code …)
**line 2241 →** `end`

and **before**
**line 2243 →** `Events.OnZombieUpdate.Remove(OnBanditUpdate)`

insert on **line 2242**:

```lua
-- Function to check and fix zombies stuck in turnalerted animation
local function CheckZombieAnimationState()
if isClient() or isServer() then
local zombies = getCell():getZombieList()
for i = 0, zombies:size() - 1 do
local zombie = zombies:get(i)
if zombie and not zombie:getVariableBoolean("Bandit") then
local currentState = zombie:getActionStateName()
local stuckTime = zombie:getModData().stuckTime or 0

if currentState == "turnalerted" then
stuckTime = stuckTime + 1
zombie:getModData().stuckTime = stuckTime

-- If the zombie stays in turnalerted for too long (≈5 seconds)
if stuckTime > 300 then
zombie:getModData().stuckTime = 0
-- Force zombie out of turnalerted state
zombie:setActionStateName("idle")
-- Reset rotation so it can turn properly
zombie:setTurnDelta(0)
zombie:setTurnAlertedValues(0, 0)
-- Force model update
zombie:resetModelNextFrame()
end
else
zombie:getModData().stuckTime = 0
end
end
end
end
end

-- Add this function to the OnTick event so it runs regularly
Events.OnTick.Add(function()
-- Only check every 60 ticks for performance
if getTimestampMs() % 60 == 0 then
CheckZombieAnimationState()
end
end)
```

---

At **line 1535** you currently have:

```lua
-- Approach bandit if in range
else
-- zombie:addLineChatElement(string.format("mid %.2f", enemy.dist), 0.6, 0.6, 1)
```

which becomes:

```lua
-- Approach bandit if in range
else
-- zombie:addLineChatElement(string.format("mid %.2f", enemy.dist), 0.6, 0.6, 1)
local player = getSpecificPlayer(0)

-- Check if the zombie is already performing a turnalerted animation
local currentState = zombie:getActionStateName()
if currentState == "turnalerted" then
-- Do not interfere with the current animation
return
end
-- local tempTarget = BanditUtils.CloneIsoPlayer(bandit)
```

---

At **line 152** replace:

```lua
-- makes bandit unstuck after spawns
zombie:setTurnAlertedValues(-5, 5)
```

with:

```lua
-- makes bandit unstuck after spawns
if zombie:getVariableBoolean("Bandit") then
zombie:setTurnAlertedValues(-5, 5)
end
```

---

In **all XML files** under:

```
Steam\steamapps\workshop\content\108600\3268487204\mods\Bandits\42\media\AnimSets\zombie\turnalerted
Steam\steamapps\workshop\content\108600\3268487204\mods\Bandits\media\AnimSets\zombie\turnalerted
```

remove the following block:

```xml
<m_Conditions>
<m_Name>Bandit</m_Name>
<m_Type>BOOL</m_Type>
<m_BoolValue>true</m_BoolValue>
</m_Conditions>
```
< >
正在显示第 1 - 2 条,共 2 条留言
Slayer  [开发者] 9 月 15 日 下午 12:29 
thanks Zunder, this may work but there is a lot of unoptimal code. as said in another post deleting the animations in turnalerted folder should be eough
BeautifulRnr 9 月 15 日 下午 8:38 
lua

-- Checks and fixes zombies stuck in turnalerted animation (runs every ~1 second)
local function CheckZombieAnimationState()
if not (isClient() or isServer()) then return end -- Skip in single-player

local cell = getCell()
local zombies = cell:getZombieList()
if not zombies then return end -- Early exit if no zombies

local size = zombies:size() -- Cache size to avoid repeated calls
for i = 0, size - 1 do
local zombie = zombies:get(i)
if zombie and not zombie:getVariableBoolean("Bandit") then
local modData = zombie:getModData() -- Cache mod data
local currentState = zombie:getActionStateName()
local stuckTime = modData.stuckTime or 0

if currentState == "turnalerted" then
stuckTime = stuckTime + 1
modData.stuckTime = stuckTime

-- Reset zombie if stuck in turnalerted for ~5 seconds (300 ticks at 60 FPS)
if stuckTime > 300 then
modData.stuckTime = 0
zombie:setActionStateName("idle")
zombie:setTurnDelta(0)
zombie:setTurnAlertedValues(0, 0)
zombie:resetModelNextFrame()
end
else
modData.stuckTime = 0
end
end
end
end

-- Run CheckZombieAnimationState every 60 ticks (~1 second at 60 FPS)
local tickCounter = 0
Events.OnTick.Add(function()
tickCounter = tickCounter + 1
if tickCounter >= 60 then
CheckZombieAnimationState()
tickCounter = 0 -- Reset counter
end
end)

optimized?
< >
正在显示第 1 - 2 条,共 2 条留言
每页显示数: 1530 50