Fix bodygroup bugs, add citizen edge case fixes, better ragdolling that doesn't deal lots of damage

This commit is contained in:
toasterpanic 2026-05-28 18:18:18 -04:00
parent 02210df130
commit 5d1af1dc1e
2 changed files with 49 additions and 18 deletions

View file

@ -36,6 +36,8 @@ local last_dmgpos = {}
local last_hitgroup = {}
local last_attacker = {}
local npcs_to_fake = {}
-- These NPCs do not have organisms by default, despite being humanoid characters built into the game.
local base_npc_whitelist = {
"npc_kleiner",
@ -119,6 +121,12 @@ hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll)
ragdoll:GetPhysicsObject():SetVelocity(ent.npcfakeknockback)
end
-- For some reason, citizen types such as rebels, medics, refugees, etc. use a keyvalue.
-- That keyvalue does not transfer over to the ragdoll, despite it looking like the NPC,
-- and you have to manually save it to the ragdoll to be able to make it work.
-- Why is it like this? Fuck if I know, I just know I don't wanna deal with it again.
ragdoll.citizentype = ent:GetInternalVariable("citizentype")
timer.Simple(0, function()
ragdoll.organism.alive = true
@ -150,13 +158,18 @@ hook.Add("HomigradDamage", "zcnpci", function(ent, dmginfo)
ent:TakeDamage(ent:Health())
end
elseif dmginfo:IsDamageType(DMG_CLUB + DMG_SLASH) then
local fists = dmginfo:GetAttacker():GetWeapon("weapon_hands_sh")
if !IsValid(fists) then fists = dmginfo:GetAttacker():GetWeapon("weapon_hg_coolhands") end
-- If it's hands and has more than 7.5 damage, it's a kick probably
if IsValid(dmginfo:GetInflictor()) and (dmginfo:GetDamage() >= 7.5) and (
(dmginfo:GetInflictor():GetClass() == "weapon_hands_sh") or
(dmginfo:GetInflictor():GetClass() == "weapon_hg_coolhands")
) then
ent.neednpcfake = true
local attacker = dmginfo:GetAttacker()
print(fists.InLegKick)
-- Kicks should knock NPCs down
if IsValid(dmginfo:GetInflictor()) and IsValid(fists) and attacker.InLegKick and ((attacker.InLegKick + 0.1) > CurTime()) then
table.insert(npcs_to_fake, ent)
print("ADD TO LIST!!!")
local attacker_angle = dmginfo:GetAttacker():EyeAngles()
local normal = attacker_angle:Forward(normal)
@ -211,13 +224,7 @@ hook.Add("Tick", "zcnpci", function()
ent.neednpcfake or
debug_ragdoll_all:GetBool()
) then
local damage_info = DamageInfo()
damage_info:SetDamage(ent:Health())
damage_info:SetAttacker(ent)
damage_info:SetDamageType( DMG_DIRECT )
damage_info:SetDamageForce(Vector(0, 0, 0))
ent:TakeDamageInfo(damage_info)
table.insert(npcs_to_fake, ent)
end
elseif do_corpse_loop and remove_corpses and ent.is_npc_corpse then
local clearable = false
@ -237,7 +244,7 @@ hook.Add("Tick", "zcnpci", function()
if treat_unconscious_as_dead:GetBool() and (ent.organism.consciousness <= 0.3)
then clearable = true end
if !clearable then return end
if !clearable then continue end
-- Add to corpse list if not there already
if !table.HasValue(corpses, ent) then
@ -276,12 +283,25 @@ hook.Add("Tick", "zcnpci", function()
ent:Remove()
continue
end
print((CurTime() - ent.corpse_timestamp) > max_corpse_time:GetFloat())
end
end
end
end
PrintTable(npcs_to_fake)
-- NPC faking is in a seperate area because we want NPCs to ragdoll as soon as they can
for i,ent in pairs(npcs_to_fake) do
local damage_info = DamageInfo()
damage_info:SetDamage(0)
damage_info:SetAttacker(ent)
damage_info:SetDamageType( DMG_DIRECT )
damage_info:SetDamageForce(Vector(0, 0, 0))
ent:BecomeRagdoll(damage_info)
table.remove(npcs_to_fake, 1)
end
end)
--[[hook.Add("OnNPCKilled", "Fedhoria", function(ent, attacker, inflictor)

View file

@ -297,11 +297,16 @@ function MODULE:PhysicsSimulate(phys, dt)
local ent = ents.Create(target.class_in_previous_life)
ent:SetPos(target:GetPos())
ent:SetModel(target:GetModel())
ent:SetMaterial(target:GetMaterial())
ent:SetSkin(ragdoll:GetSkin())
ent:SetSkin(target:GetSkin())
for i = 0, ragdoll:GetNumBodyGroups() - 1 do
ent:SetBodygroup(i, ragdoll:GetBodygroup(i))
if target.citizentype then
ent:SetKeyValue("citizentype", target.citizentype)
end
for i = 0, target:GetNumBodyGroups() - 1 do
ent:SetBodygroup(i, target:GetBodygroup(i))
end
ent:Spawn()
@ -319,6 +324,12 @@ function MODULE:PhysicsSimulate(phys, dt)
ent:CallOnRemove("organism", hg.organism.Remove, ent)
hg.send_bareinfo(ent.organism)
ent:SetSkin(target:GetSkin())
for i = 0, target:GetNumBodyGroups() - 1 do
ent:SetBodygroup(i, target:GetBodygroup(i))
end
target:Remove()
end)