Project Zomboid

Project Zomboid

Subpar Survivors
Sardes 17 Aug, 2021 @ 11:33am
NPC cant run issue
The only safe way to fix NPC run issue I have found is to recreate all original code from TIS. Here it is (copy and past to SuperSurvivor.lua):

function SuperSurvivor:NPCcalculateInjurySpeed(bodypart,b)
local scratchSpeedModifier = bodypart:getScratchSpeedModifier();
local cutSpeedModifier = bodypart:getCutSpeedModifier();
local burnSpeedModifier = bodypart:getBurnSpeedModifier();
local deepWoundSpeedModifier = bodypart:getDeepWoundSpeedModifier();
local n = 0.0;
if ((bodypart:getType() == "Foot_L" or bodypart:getType() == "Foot_R") and (bodypart:getBurnTime() > 5.0 or bodypart:getBiteTime() > 0.0 or bodypart:deepWounded() or bodypart:isSplint() or bodypart:getFractureTime() > 0.0 or bodypart:haveGlass())) then
n = 1.0f
if (bodypart:bandaged()) then
n = 0.7;
end
if (bodypart:getFractureTime() > 0.0) then
n = self:NPCcalcFractureInjurySpeed(bodypart);
end
end
if (bodypart:haveBullet()) then
return 1.0;
end
if (bodypart:getScratchTime() > 2.0 or bodypart:getCutTime() > 5.0 or bodypart:getBurnTime() > 0.0 or bodypart:getDeepWoundTime() > 0.0 or bodypart:isSplint() or bodypart:getFractureTime() > 0.0 or bodypart:getBiteTime() > 0.0) then
n = n + (bodypart:getScratchTime() / scratchSpeedModifier + bodypart:getCutTime() / cutSpeedModifier + bodypart:getBurnTime() / burnSpeedModifier + bodypart:getDeepWoundTime() / deepWoundSpeedModifier) + bodypart:getBiteTime() / 20.0;
if (bodypart:bandaged()) then
n = n / 2.0;
end
if (bodypart:getFractureTime() > 0.0) then
n = self:NPCcalcFractureInjurySpeed(bodypart);
end
end
if (b and bodypart:getPain() > 20.0) then
n = n + bodypart:getPain() / 10.0;
end
return n;
end

function SuperSurvivor:NPCgetFootInjurySpeedModifier()
local b = true;
local n = 0.0;
local n2 = 0.0;
for i = BodyPartType.UpperLeg_L:index(), (BodyPartType.MAX:index() - 1) do
local bodydamage = self.player:getBodyDamage()
local bodypart = bodydamage:getBodyPart(BodyPartType.FromIndex(i));
local calculateInjurySpeed = self:NPCcalculateInjurySpeed(bodypart, false);
if (b) then
n = n + calculateInjurySpeed;
b = false
else
n2 = n2 + calculateInjurySpeed;
b = true
end
end
if (n > n2) then
return -(n + n2);
else
return n + n2;
end
end

function SuperSurvivor:NPCgetrunSpeedModifier()
local NPCrunSpeedModifier = 1.0;
local items = self.player:getWornItems()
for i=0, items:size()-1 do
local item = items:getItemByIndex(i)
if item ~= nil and (item:getCategory() == "Clothing") then
NPCrunSpeedModifier = NPCrunSpeedModifier + (item:getRunSpeedModifier() - 1.0);
end
end
local shoeitem = items:getItem("Shoes");
if not (shoeitem) or (shoeitem:getCondition() == 0) then
NPCrunSpeedModifier = NPCrunSpeedModifier * 0.85;
end
return NPCrunSpeedModifier
end

function SuperSurvivor:NPCgetwalkSpeedModifier()
local NPCwalkSpeedModifier = 1.0;
local items = self.player:getWornItems()
local shoeitem = items:getItem("Shoes");
if not (shoeitem) or (shoeitem:getCondition() == 0) then
NPCwalkSpeedModifier = NPCwalkSpeedModifier * 0.85;
end
return NPCwalkSpeedModifier
end

function SuperSurvivor:NPCcalcRunSpeedModByBag(bag)
return (bag:getScriptItem().runSpeedModifier - 1.0) * (1.0 + bag:getContentsWeight() / bag:getEffectiveCapacity(self.player) / 2.0);
end

function SuperSurvivor:NPCgetfullSpeedMod()
local NPCfullSpeedMod
local NPCbagRunSpeedModifier = 0
if (self.player:getClothingItem_Back() ~= nil) and (instanceof(self.player:getClothingItem_Back(),"InventoryContainer")) then
NPCbagRunSpeedModifier = NPCbagRunSpeedModifier + self:NPCcalcRunSpeedModByBag(self.player:getClothingItem_Back():getItemContainer())
end
if (self.player:getSecondaryHandItem() ~= nil) and (instanceof(self.player:getSecondaryHandItem(),"InventoryContainer")) then
NPCbagRunSpeedModifier = NPCbagRunSpeedModifier + self:NPCcalcRunSpeedModByBag(self.player:getSecondaryHandItem():getItemContainer());
end
if (self.player:getPrimaryHandItem() ~= nil) and (instanceof(self.player:getPrimaryHandItem(),"InventoryContainer")) then
NPCbagRunSpeedModifier = NPCbagRunSpeedModifier + self:NPCcalcRunSpeedModByBag(self.player:getPrimaryHandItem():getItemContainer());
end
NPCfullSpeedMod = self:NPCgetrunSpeedModifier() + (NPCbagRunSpeedModifier - 1.0);
return NPCfullSpeedMod
end

function SuperSurvivor:NPCcalculateWalkSpeed()
local NPCfootInjurySpeedModifier = self:NPCgetFootInjurySpeedModifier();
self.player:setVariable("WalkInjury", NPCfootInjurySpeedModifier);
local NPCcalculateBaseSpeed = self.player:calculateBaseSpeed();
local wmax;
if self:getRunning() == true then
wmax = ((NPCcalculateBaseSpeed - 0.15) * self:NPCgetfullSpeedMod() + self.player:getPerkLevel(Perks.FromString("Sprinting")) / 20.0 - AbsoluteValue(NPCfootInjurySpeedModifier / 1.5));
else
wmax = NPCcalculateBaseSpeed * self:NPCgetwalkSpeedModifier();
end
if (self.player:getSlowFactor() > 0.0) then
wmax = wmax * 0.05;
end
local wmin = math.min(1.0, wmax);
local bodydamage = self.player:getBodyDamage()
if (bodydamage) then
local thermo = bodydamage:getThermoregulator()
end
if (thermo) then
wmin = wmin * thermo:getMovementModifier();
end
--local gametime = getGameTime()
if (self.player:isAiming()) then
self.player:setVariable("StrafeSpeed", math.max(math.min(0.9 + self.player:getPerkLevel(Perks.FromString("Nimble")) / 10.0, 1.5) * math.min(wmin * 2.5, 1.0), 0.6) * 0.8);
end
if (self.player:isInTreesNoBush()) then
local cs = self.player:getCurrentSquare()
if (cs) and cs:HasTree() then
local tree = cs:getTree();
end
if tree then
wmin = wmin * tree:getSlowFactor(self.player);
end
end
self.player:setVariable("WalkSpeed", wmin * 0.8);
end

And in update() function add self:NPCcalculateWalkSpeed() before dovision for example. You can also call this in other places. It need to be tested though, cos I have not tested it well, but it works for random single spawned NPC.
< >
Showing 1-15 of 15 comments
Sardes 17 Aug, 2021 @ 11:34am 
Oh great, it deletes all spaces and tabs... Any way I can send it to you, if you are interested?
Last edited by Sardes; 17 Aug, 2021 @ 11:35am
SlightlyMadman  [developer] 17 Aug, 2021 @ 5:38pm 
Oh wow, great work! Do you use git? If so, you can just submit a PR to my repo https://github.com/bsarsgard/Subpar-Survivors
Sardes 17 Aug, 2021 @ 8:32pm 
not sure if did it right, never did it before. Check...
SlightlyMadman  [developer] 18 Aug, 2021 @ 7:21am 
I see your fork, I'll make the PR.
Sardes 18 Aug, 2021 @ 7:50am 
Ok, good. BTW I have same fix for NPC damage, if you are interested.
SlightlyMadman  [developer] 18 Aug, 2021 @ 9:21am 
Yes actually, I'm sure it's better than my quick hack!
Sardes 18 Aug, 2021 @ 9:37am 
Done, I guess, in SuperSurvivorUpdate
SlightlyMadman  [developer] 18 Aug, 2021 @ 11:43am 
Thanks, got it! I'll get these in ASAP but I'm heading out of town tomorrow for the weekend.
SlightlyMadman  [developer] 19 Aug, 2021 @ 10:10am 
These updates seem to work, but I'm getting a lot of glitches like survivors getting stuck after attacking. I'll need to debug a bit more before I can release.
Sardes 19 Aug, 2021 @ 1:11pm 
That's strange, coz I tested it with many NPC spawned. The only problem I saw is problems with AI-manager and flee task, but I thought it was always like that.
Anyway, there is a bug actualy with damage logic, needs to add these strings at the begining

if weapon:getType() == "BareHands" then
return
end

Without it pushing with hands damages too.

I will try to look again too.
Last edited by Sardes; 19 Aug, 2021 @ 1:11pm
SlightlyMadman  [developer] 19 Aug, 2021 @ 2:27pm 
Yes, for some reason friendly NPCs are going directly into the FleeFromHere task, which also doesn't seem to be working properly.

Still testing more, but also just watched an NPC get swarmed by 5 melee-armed raiders for at least 10-20 hits. He fought them off and I inspected him, and he'd taken barely any damage. Damage from the PC to NPCs seems good.
SlightlyMadman  [developer] 19 Aug, 2021 @ 2:32pm 
BTW it's entirely possible this behavior all has nothing to do with your changes and I'm just noticing it for the first time because of my test setup. Actually it would explain some other bug reports I've seen if this has been around since the 41.51 update.
SlightlyMadman  [developer] 22 Aug, 2021 @ 6:24pm 
It looks like the fleeing issues are entirely an old bug, I've included these and update the mod. Thank you so much for this fix!
Datboi 10 Sep, 2021 @ 9:01pm 
Originally posted by SlightlyMadman:
It looks like the fleeing issues are entirely an old bug, I've included these and update the mod. Thank you so much for this fix!

Does running work then? Right now it doesn't seem to work still
SlightlyMadman  [developer] 13 Sep, 2021 @ 6:11am 
It's been working for me. Try setting an NPC to follow and running away from them. They should now jog to catch up.
< >
Showing 1-15 of 15 comments
Per page: 1530 50