zcnpci/lua/fedhoria.lua

218 lines
No EOL
5.9 KiB
Lua

include("zcnpci/modules.lua")
local enabled = CreateConVar("zcnpci_enabled", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local active_range = CreateConVar("zcnpci_active_range", 300, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local always_active_on_player_kill = CreateConVar("zcnpci_always_active_on_player_kill", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local last_dmgpos = {}
local last_hitgroup = {}
local last_attacker = {}
hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll)
if !ent.organism then return end
if !enabled:GetBool() then return end
local dmgpos = last_dmgpos[ent]
local active_by_default = false
if always_active_on_player_kill:GetBool() then
if last_attacker[ent] and last_attacker[ent]:IsPlayer() then active_by_default = true end
end
if !active_by_default then
local entity_position = ragdoll:GetPos()
local in_range = false
local players = player.GetAll()
for i, loop_player in pairs(players) do
local player_position = loop_player:GetPos()
local distance = entity_position:Distance(player_position)
if distance <= active_range:GetFloat() then
in_range = true
break
end
end
if !in_range then return end
end
local phys_bone, lpos
if dmgpos then
phys_bone = ragdoll:GetClosestPhysBone(dmgpos)
if phys_bone then
local phys = ragdoll:GetPhysicsObjectNum(phys_bone)
lpos = phys:WorldToLocal(dmgpos)
end
end
ragdoll.class_in_previous_life = ent:GetClass()
timer.Simple(0, function()
ragdoll.organism.alive = true
if !IsValid(ragdoll) then return end
zcnpci.StartModule(ragdoll, "stumble_legs", phys_bone, lpos)
last_dmgpos[ent] = nil
end)
end)
hook.Add("EntityTakeDamage", "zcnpci", function(ent, dmginfo)
if !enabled:GetBool() then return end
if (!ent:IsNPC() or dmginfo:GetDamage() < ent:Health()) then return end
last_dmgpos[ent] = dmginfo:GetDamagePosition()
last_attacker[ent] = dmginfo:GetAttacker()
end)
hook.Add("ScaleNPCDamage", "zcnpci", function(npc, hitgroup, dmginfo)
if not IsValid(npc) then return end
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
last_dmgpos[ent] = dmginfo:GetDamagePosition()
end)]]
local once = true
--RagMod/TTT support
--[[hook.Add("OnEntityCreated", "Fedhoria", function(ent)
--If RagMod isn't installed remove this hook
if once then
once = nil
if (!RMA_Ragdolize and !CORPSE) then
hook.Remove("OnEntityCreated", "Fedhoria")
return
end
--these hooks fucks shit up
if RMA_Ragdolize then
hook.Remove( "PlayerDeath", "RM_PlayerDies")
hook.Add( "PostPlayerDeath", "RemoveRagdoll", function(ply)
if IsValid(ply.RM_Ragdoll) then
SafeRemoveEntity(ply:GetRagdollEntity())
ply:SpectateEntity(ply.RM_Ragdoll)
end
end)
end
end
if (!enabled:GetBool() or !players:GetBool() or !ent:IsRagdoll()) then return end
timer.Simple(0, function()
if !IsValid(ent) then return end
if CORPSE then
local ply = ent:GetDTEntity(CORPSE.dti.ENT_PLAYER)
if (IsValid(ply) and ply:IsPlayer()) then
fedhoria.StartModule(ent, "stumble_legs")
return
end
end
for _, ply in ipairs(player.GetAll()) do
if (ply.RM_IsRagdoll and ply.RM_Ragdoll == ent) then
fedhoria.StartModule(ent, "stumble_legs")
return
end
end
end)
end)]]
local PLAYER = FindMetaTable("Player")
local oldCreateRagdoll = PLAYER.CreateRagdoll
local dolls = {}
local function CreateRagdoll(self)
SafeRemoveEntity(dolls[self])
local ragdoll = ents.Create("prop_ragdoll")
ragdoll:SetModel(self:GetModel())
ragdoll:SetPos(self:GetPos())
ragdoll:SetAngles(self:GetAngles())
ragdoll:Spawn()
ragdoll:SetSkin(self:GetSkin())
for i = 0, self:GetNumBodyGroups() - 1 do
ragdoll:SetBodygroup(i, self:GetBodygroup(i))
end
for i = 0, ragdoll:GetPhysicsObjectCount()-1 do
local phys = ragdoll:GetPhysicsObjectNum(i)
local bone = ragdoll:TranslatePhysBoneToBone(i)
local matrix = self:GetBoneMatrix(bone)
local pos, ang = matrix:GetTranslation(), matrix:GetAngles()--self:GetBonePosition(bone)
phys:SetPos(pos)
phys:SetAngles(ang)
phys:SetVelocity(self:GetVelocity())
end
self:SpectateEntity(ragdoll)
self:Spectate(OBS_MODE_CHASE)
dolls[self] = ragdoll
end
local oldGetRagdollEntity = PLAYER.GetRagdollEntity
local function GetRagdollEntity(self)
return dolls[self] or NULL
end
--[[
if enabled:GetBool() then
PLAYER.CreateRagdoll = CreateRagdoll
PLAYER.GetRagdollEntity = GetRagdollEntity
end]]
--[[
cvars.AddChangeCallback("fedhoria_enabled", function(name, old, new)
if (new == "1") then
if players:GetBool() then
PLAYER.CreateRagdoll = CreateRagdoll
PLAYER.GetRagdollEntity = GetRagdollEntity
end
else
PLAYER.CreateRagdoll = oldCreateRagdoll
PLAYER.GetRagdollEntity = oldGetRagdollEntity
end
end)
cvars.AddChangeCallback("fedhoria_players", function(name, old, new)
if (new == "1") then
if enabled:GetBool() then
if (debug.getinfo(PLAYER.CreateRagdoll).short_src == "[C]") then
PLAYER.CreateRagdoll = CreateRagdoll
PLAYER.GetRagdollEntity = GetRagdollEntity
end
end
else
PLAYER.CreateRagdoll = oldCreateRagdoll
PLAYER.GetRagdollEntity = oldGetRagdollEntity
end
end)]]