Project Zomboid

Project Zomboid

Subpar Survivors
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.
< >
Näytetään 1-15 / 15 kommentista
Oh great, it deletes all spaces and tabs... Any way I can send it to you, if you are interested?
Viimeisin muokkaaja on Sardes; 17.8.2021 klo 11.35
SlightlyMadman  [kehittäjä] 17.8.2021 klo 17.38 
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
not sure if did it right, never did it before. Check...
SlightlyMadman  [kehittäjä] 18.8.2021 klo 7.21 
I see your fork, I'll make the PR.
Ok, good. BTW I have same fix for NPC damage, if you are interested.
SlightlyMadman  [kehittäjä] 18.8.2021 klo 9.21 
Yes actually, I'm sure it's better than my quick hack!
Done, I guess, in SuperSurvivorUpdate
SlightlyMadman  [kehittäjä] 18.8.2021 klo 11.43 
Thanks, got it! I'll get these in ASAP but I'm heading out of town tomorrow for the weekend.
SlightlyMadman  [kehittäjä] 19.8.2021 klo 10.10 
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.
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.
Viimeisin muokkaaja on Sardes; 19.8.2021 klo 13.11
SlightlyMadman  [kehittäjä] 19.8.2021 klo 14.27 
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  [kehittäjä] 19.8.2021 klo 14.32 
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  [kehittäjä] 22.8.2021 klo 18.24 
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!
SlightlyMadman lähetti viestin:
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  [kehittäjä] 13.9.2021 klo 6.11 
It's been working for me. Try setting an NPC to follow and running away from them. They should now jog to catch up.
< >
Näytetään 1-15 / 15 kommentista
Sivua kohden: 1530 50