From 439e152b19238db3b3ad006d560229660b921cce Mon Sep 17 00:00:00 2001 From: toasterpanic Date: Mon, 25 May 2026 14:17:06 -0400 Subject: [PATCH] Enemies now fall over when they're supposed to be unconscious/crippled, and they get up when they are capable --- lua/autorun/client/fedh_menu.lua | 5 ++- lua/fedhoria.lua | 21 ++++++++++ lua/zcnpci/modules/falling_legs.lua | 57 +++++++++++++++++++++------- lua/zcnpci/modules/falling_torso.lua | 3 +- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/lua/autorun/client/fedh_menu.lua b/lua/autorun/client/fedh_menu.lua index 76eb267..0a394a1 100644 --- a/lua/autorun/client/fedh_menu.lua +++ b/lua/autorun/client/fedh_menu.lua @@ -5,7 +5,7 @@ local function PopulateRagdollSBXToolMenu(pnl) pnl:Help(" ") pnl:NumSlider("Stumble time", "zcnpci_stumble_time", 0, 10, 3) - pnl:ControlHelp("How long the ragdoll should stumble for.") + pnl:ControlHelp("How long the ragdoll should try to stumble for.") pnl:NumSlider("Wound grab chance", "zcnpci_woundgrab_chance", 0, 1, 3) pnl:ControlHelp("The chance the ragdoll will grab it's wound when shot.") @@ -13,6 +13,9 @@ local function PopulateRagdollSBXToolMenu(pnl) pnl:NumSlider("Wound grab time", "zcnpci_woundgrab_time", 0, 10, 3) pnl:ControlHelp("How long the ragdoll should hold its wound.") + pnl:NumSlider("Minimum down time", "zcnpci_down_time", 0, 20, 3) + pnl:ControlHelp("The minimum amount of time the ragdoll should be down before trying to get back up.") + pnl:Help(" ") pnl:NumSlider("Activation range", "zcnpci_active_range", 0, 5000, 0) diff --git a/lua/fedhoria.lua b/lua/fedhoria.lua index c781402..37a7a61 100644 --- a/lua/fedhoria.lua +++ b/lua/fedhoria.lua @@ -49,6 +49,8 @@ hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll) end end + ragdoll.class_in_previous_life = ent:GetClass() + timer.Simple(0, function() ragdoll.organism.alive = true @@ -72,6 +74,25 @@ hook.Add("ScaleNPCDamage", "zcnpci", function(npc, hitgroup, dmginfo) last_hitgroup[npc] = hitgroup end) +hook.Add("Think", "zcnpci", function() + for i, ent in pairs(ents.GetAll()) do + if !IsValid(ent) then continue end + if !ent:IsNPC() then continue end + if !ent.organism then continue end + + -- Knock them down if something is off + if ( + ((ent.organism.lleg >= 1) and (ent.organism.rleg >= 1)) or + ent.organism.llegamputated or + ent.organism.rlegamputated or + (ent.organism.consciousness <= 0.3) or + (ent.organism.pain > 0.9) + ) then + ent:TakeDamage(ent:Health()) + end + end +end) + --[[hook.Add("OnNPCKilled", "Fedhoria", function(ent, attacker, inflictor) if (!enabled:GetBool() or !npcs:GetBool()) then return end if (!ent:IsNPC() or dmginfo:GetDamage() < ent:Health()) then return end diff --git a/lua/zcnpci/modules/falling_legs.lua b/lua/zcnpci/modules/falling_legs.lua index 792d8a0..130e533 100644 --- a/lua/zcnpci/modules/falling_legs.lua +++ b/lua/zcnpci/modules/falling_legs.lua @@ -68,6 +68,9 @@ local cv_anim_roll_duration = CreateConVar("zcnpci_falling_anim_roll_duration", local cv_anim_roll_impact_threshold = CreateConVar("zcnpci_falling_anim_roll_impact_threshold", "300", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. скорость удара для запуска анимации") local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации") +-- Down time +local minimum_down_time = CreateConVar("zcnpci_down_time", "5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Down time!!!!!!!!!") + --[[------------------------------------------------------------------------- Tug function Applies a random impulse to one of the leg bones. @@ -157,6 +160,7 @@ function MODULE:Init() self.LastGroundCollideTime = 0 self.StartDie = nil self.AnimationRollEndTime = 0 + self.StopProcessing = false -- Add damping to all bones. local phys = self:GetPhysicsObject() @@ -219,10 +223,14 @@ end Physics Simulation Hook (FIXED) ---------------------------------------------------------------------------]] function MODULE:PhysicsSimulate(phys, dt) + if self.StopProcessing then return false end + local cur_time = CurTime() local target = self:GetTarget() if not IsValid(target) then self:Remove(); return false end + if !self.StartDie then self.StartDie = cur_time end + -- Check for active animation if cur_time < self.AnimationRollEndTime then --self.StartDie = nil -- Resetting the "death" timer @@ -231,20 +239,13 @@ function MODULE:PhysicsSimulate(phys, dt) -- Logic for the disappearance timer local f = 1 -- Force multiplier (default: 1) - --[[if self.StartDie then - f = math_Clamp(1 - (cur_time - self.StartDie) / die_time:GetFloat(), 0, 1) - end]] - - -- Support for RagMod - if ragmod and ragmod:IsRagmodRagdoll(target) then - local owner = target:GetOwningPlayer() - f = (IsValid(owner) and owner:Alive()) and 1 or 0 - --self.StartDie = nil - - if f <= 0 then self.AnimationRollEndTime = 0 end + + local minimum_down_timer = 0 + if self.StartDie then + minimum_down_timer = math_Clamp((cur_time - self.StartDie) / minimum_down_time:GetFloat(), 0, 1) end - if !target or !target.organism then + if !target.organism then self:Remove() return false -- Cut the bullshit end @@ -253,7 +254,37 @@ function MODULE:PhysicsSimulate(phys, dt) -- If the NPC is dead, they probably aren't coming back; don't bother bringing them back to life self:Remove() return false -- Cut the bullshit - elseif (target.organism.consciousness <= 0.3) then + elseif (target.organism.consciousness <= 0.3) or ((target.organism.lleg >= 1) and (target.organism.rleg >= 1)) then + self.StartDie = cur_time + return false + end + + -- Getting up + -- Don't need to check for consciousness and the like because we've done it already above + if ( + (minimum_down_timer >= 1.0) and + (target.class_in_previous_life != nil) and + !(target.organism.llegamputated or target.organism.rlegamputated or target.organism.larmamputated or target.organism.rarmamputated) + ) then + local ent = ents.Create(target.class_in_previous_life) + ent:SetPos(target:GetPos()) + ent:SetModel(target:GetModel()) + + if target:GetNumBodyGroups() > 0 then + local i = 1 + while (i <= target:GetNumBodyGroups()) do + ent:SetBodygroup(i, target:GetBodygroup(i)) + + i = i + 1 + end + end + + ent:Spawn() + + self.StopProcessing = true + + self:Remove() + target:Remove() return false end diff --git a/lua/zcnpci/modules/falling_torso.lua b/lua/zcnpci/modules/falling_torso.lua index b5a44b1..4e944c4 100644 --- a/lua/zcnpci/modules/falling_torso.lua +++ b/lua/zcnpci/modules/falling_torso.lua @@ -35,7 +35,8 @@ local cv_anim_roll_duration = CreateConVar("zcnpci_falling_anim_roll_duration", local cv_anim_roll_impact_threshold = CreateConVar("zcnpci_falling_anim_roll_impact_threshold", "300", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Мин. скорость удара для запуска анимации") local cv_anim_roll_playback_rate = CreateConVar("zcnpci_falling_anim_roll_playback_rate", "3.0", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Скорость воспроизведения анимации") - +-- Down time +local minimum_down_time = CreateConVar("zcnpci_down_time", "5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Down time!!!!!!!!!") -- Do it! function MODULE:DoTwitch()