Bug fixes of varying degrees

This commit is contained in:
toasterpanic 2026-05-30 21:35:28 -04:00
parent 786e997351
commit 5af8fdc14a
4 changed files with 33 additions and 103 deletions

View file

@ -30,10 +30,13 @@ It is, however, not compatbile with:
- Most mods that modify the behavior of death ragdolls (Reagdoll, Artagdoll, especially Fedhoria.) - Most mods that modify the behavior of death ragdolls (Reagdoll, Artagdoll, especially Fedhoria.)
- Mods that automatically remove death ragdolls (it will delete all ragdolled NPCs, even if they're still alive! Try the built-in automatic corpse removal instead.) - Mods that automatically remove death ragdolls (it will delete all ragdolled NPCs, even if they're still alive! Try the built-in automatic corpse removal instead.)
## Future plans ## Todo list
No guarantees any of this will become real. - NPC targeting works, but works really weirdly (sometimes it just. keeps targeting corpses when it shouldn't.) Why? Who knows!!!!
- Look into improving the unfake animation? Really scared to try and touch it again but it would be worthwhile
- NPCs will back out of combat when injured. Post release ideas:
- Friendly NPCs can heal each other.
- NPCs can heal themselves. - Localization support for other languages
- ReaSFX integration would probably be nice. I mean there's so many SFX packs to choose from, so I don't even have to pack it in
- To be entirely honest Fedhoria isn't the best addon out there for euphoria physics. Maybe rebase to another addon (or alternatively build a new one?)

View file

@ -10,7 +10,7 @@ local function UpdateRelationship(ent, me)
if !IsValid(ent) or !ent:IsNPC() then return end if !IsValid(ent) or !ent:IsNPC() then return end
if ent:Disposition(me.dummy_entity) == D_HT then if ent:Disposition(me.dummy_entity) == D_HT then
ent:AddEntityRelationship(me, D_HT) ent:AddEntityRelationship(me, D_HT, -1)
end end
end end
@ -18,8 +18,13 @@ local function RemoveRelationship(ent, me)
if !IsValid(ent) or !ent:IsNPC() then return end if !IsValid(ent) or !ent:IsNPC() then return end
if ent:Disposition(me.dummy_entity) == D_HT then if ent:Disposition(me.dummy_entity) == D_HT then
ent:AddEntityRelationship(me, D_NU) ent:AddEntityRelationship(me, D_NU, -1)
ent:ClearEnemyMemory(me) ent:ClearEnemyMemory(me)
if ent:GetEnemy() == me then
ent:SetEnemy(nil)
ent:ClearSchedule()
end
end end
end end
@ -30,7 +35,7 @@ function ENT:Initialize()
self:SetHullType(HULL_TINY_CENTERED) self:SetHullType(HULL_TINY_CENTERED)
self:SetNoDraw(!debug_show_ragdoll_targets:GetBool()) self:SetNoDraw(!debug_show_ragdoll_targets:GetBool())
self.dummy_entity = ents.Create(self.ragdoll_to_follow.class_in_previous_life) self.dummy_entity = ents.Create(self.ragdoll_to_follow.class_in_previous_life)
self.last_stop_targeting = debug_show_ragdoll_targets:GetBool() self.last_stop_targeting = nil
hook.Add("OnEntityCreated", "zcnpci-"..self:GetCreationID(), function(new_entity) hook.Add("OnEntityCreated", "zcnpci-"..self:GetCreationID(), function(new_entity)
if !IsValid(new_entity) or !new_entity:IsNPC() then return end if !IsValid(new_entity) or !new_entity:IsNPC() then return end
@ -39,10 +44,6 @@ function ENT:Initialize()
UpdateRelationship(new_entity, self) UpdateRelationship(new_entity, self)
end end
end) end)
for i,ent in ipairs(ents.GetAll()) do
UpdateRelationship(ent, self)
end
end end
end end
@ -87,10 +88,12 @@ end
function ENT:OnRemove() function ENT:OnRemove()
if SERVER then if SERVER then
print("I AM DYING!!!!!!")
for i,ent in ipairs(ents.GetAll()) do for i,ent in ipairs(ents.GetAll()) do
RemoveRelationship(ent, self) RemoveRelationship(ent, self)
end end
self.dummy_entity:Remove()
hook.Remove("OnEntityCreated", "zcnpci-"..self:GetCreationID()) hook.Remove("OnEntityCreated", "zcnpci-"..self:GetCreationID())
end end
end end

View file

@ -19,7 +19,9 @@ local treat_near_death_as_dead = CreateConVar("zcnpci_treat_near_death_as_dead"
local allow_extended_base_npcs = CreateConVar("zcnpci_allow_extended_base_npcs", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED)) local allow_extended_base_npcs = CreateConVar("zcnpci_allow_extended_base_npcs", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local allow_modded_npcs = CreateConVar("zcnpci_allow_modded_npcs", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED)) local allow_modded_npcs = CreateConVar("zcnpci_allow_modded_npcs", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local auto_enable_humanoid_npcs = CreateConVar("zcnpci_auto_enable_humanoid_npcs", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED)) local auto_enable_humanoid_npcs = CreateConVar("zcnpci_auto_enable_humanoid_npcs", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local modded_npc_whitelist = CreateConVar("zcnpci_modded_npc_whitelist", "nb_example", bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED)) local modded_npc_whitelist = CreateConVar("zcnpci_modded_npc_whitelist", "npc_example_class", bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local debug_ragdoll_all = CreateConVar("zcnpci_debug_ragdoll_all", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
-- The way I have to set up the npc whitelist client-side makes it so the host can't configure it without console commands, so we have to do this shit -- The way I have to set up the npc whitelist client-side makes it so the host can't configure it without console commands, so we have to do this shit
local set_modded_npc_whitelist = concommand.Add("zcnpci_set_modded_npc_whitelist", function(ply, cmd, args) local set_modded_npc_whitelist = concommand.Add("zcnpci_set_modded_npc_whitelist", function(ply, cmd, args)
@ -30,8 +32,6 @@ local set_modded_npc_whitelist = concommand.Add("zcnpci_set_modded_npc_whitelis
modded_npc_whitelist:SetString(args[1]) modded_npc_whitelist:SetString(args[1])
end) end)
local debug_ragdoll_all = CreateConVar("zcnpci_debug_ragdoll_all", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
local last_dmgpos = {} local last_dmgpos = {}
local last_hitgroup = {} local last_hitgroup = {}
local last_attacker = {} local last_attacker = {}
@ -139,31 +139,6 @@ hook.Add("CreateEntityRagdoll", "zcnpci", function(ent, ragdoll)
end) end)
end) end)
hook.Add("EntityTakeDamage", "zcnpci", function(ent, dmginfo)
if !IsValid(ent) or !IsValid(dmginfo) then return end
print('damage taken')
if ent:GetClass() == "bullseye_strider_focus" then
print("BULLSEYE!")
local npc_rag = IsValid(ent.npc_rag) and ent.npc_rag
if IsValid(npc_rag) then
if !IsValid(dmginfo) then
print("FUUUUCK NO DMGINFO")
return true
end
print("DAMAGE MOVED")
--ent.npc_rag:TakeDamageInfo(dmginfo)
--hook.Run("HomigradDamage", , dmginfo)
end
return true
end
end)
hook.Add("HomigradDamage", "zcnpci", function(ent, dmginfo) hook.Add("HomigradDamage", "zcnpci", function(ent, dmginfo)
if !enabled:GetBool() or !IsValid(dmginfo) then return end if !enabled:GetBool() or !IsValid(dmginfo) then return end
@ -187,13 +162,16 @@ hook.Add("HomigradDamage", "zcnpci", function(ent, dmginfo)
table.insert(npcs_to_fake, ent) table.insert(npcs_to_fake, ent)
end end
elseif dmginfo:IsDamageType(DMG_CLUB + DMG_SLASH) then elseif dmginfo:IsDamageType(DMG_CLUB + DMG_SLASH) then
local fists = dmginfo:GetAttacker():GetWeapon("weapon_hands_sh") local attacker = dmginfo:GetAttacker()
if !IsValid(fists) then fists = dmginfo:GetAttacker():GetWeapon("weapon_hg_coolhands") end if !IsValid(attacker) then return end
local fists = attacker:HasWeapon("weapon_hands_sh")
if !fists then fists = dmginfo:GetAttacker():HasWeapon("weapon_hg_coolhands") end
local attacker = dmginfo:GetAttacker() local attacker = dmginfo:GetAttacker()
-- Kicks should knock NPCs down -- Kicks should knock NPCs down
if IsValid(dmginfo:GetInflictor()) and IsValid(fists) and attacker.InLegKick and ((attacker.InLegKick + 0.1) > CurTime()) then if IsValid(dmginfo:GetInflictor()) and fists and attacker.InLegKick and ((attacker.InLegKick + 0.1) > CurTime()) then
table.insert(npcs_to_fake, ent) table.insert(npcs_to_fake, ent)
local attacker_angle = dmginfo:GetAttacker():EyeAngles() local attacker_angle = dmginfo:GetAttacker():EyeAngles()

View file

@ -330,6 +330,8 @@ function MODULE:PhysicsSimulate(phys, dt)
if parent_bone == -1 then continue end if parent_bone == -1 then continue end
local parent_bone_matrix = parent:GetBoneMatrix(parent_bone) local parent_bone_matrix = parent:GetBoneMatrix(parent_bone)
if !parent_bone_matrix then continue end
local parent_bone_pos, parent_bone_angle = parent_bone_matrix:GetTranslation(), parent_bone_matrix:GetAngles() local parent_bone_pos, parent_bone_angle = parent_bone_matrix:GetTranslation(), parent_bone_matrix:GetAngles()
parent_bone_angle.y = parent_bone_angle.y + 90 parent_bone_angle.y = parent_bone_angle.y + 90
@ -479,6 +481,8 @@ function MODULE:PhysicsSimulate(phys, dt)
ent:SetRenderMode(RENDERMODE_NONE) ent:SetRenderMode(RENDERMODE_NONE)
timer.Simple(self.FakeUpTime, function() timer.Simple(self.FakeUpTime, function()
if !IsValid(ent) then return end
ent:SetNotSolid(false) ent:SetNotSolid(false)
ent:SetNPCState(NPC_STATE_IDLE) ent:SetNPCState(NPC_STATE_IDLE)
@ -488,70 +492,12 @@ function MODULE:PhysicsSimulate(phys, dt)
self:Remove() self:Remove()
end) end)
--[[]
local parent = self.FakeParent
if !self.ModelBoneList then
self.ModelBoneList = {}
local i = 0
while i < target:GetBoneCount() do
table.insert(self.ModelBoneList, target:GetBoneName(i))
i = i + 1
end
end
for i,v in pairs(self.ModelBoneList) do
print(v)
print("I'm here")
local bone = target:TranslateBoneToPhysBone(target:LookupBone(v))
local object = target:GetPhysicsObjectNum(bone)
if !IsValid(object) then i = i + 1; continue end
print("I'm getting to object")
local parent_bone = parent:TranslateBoneToPhysBone(parent:LookupBone(v))
if parent_bone == nil then i = i + 1; continue end
print("I'm getting to parent object")
object:Wake()
local shadow_data = {
secondstoarrive = 0.01,
pos = LerpVector(0.1, object:GetPos(), parent:GetBonePosition(parent_bone)),
angle = LerpAngle(0.1, object:GetAngles(), parent:GetBoneMatrix(parent_bone):GetAngles()),
maxspeed = 5000,
maxangular = 5000,
maxspeeddamp = 2000,
maxangularspeeddamp = 2000,
}
object:ComputeShadowControl(shadow_data)
--object:SetPos(LerpVector(0.2, object:GetPos(), parent:GetBonePosition(parent_bone)))
--object:SetAngles(LerpAngle(0.2, object:GetAngles(), parent:GetBoneMatrix(parent_bone):GetAngles()))
--object:EnableMotion(false)
--object:SetVelocity(Vector())
object:EnableGravity(false)
i = i + 1
end]]
self.bullseye:Remove() self.bullseye:Remove()
return false return false
end end
end end
-- Getting up
-- Don't need to check for consciousness and the like because we've done it already above
local phys_bone_id = phys:GetID() local phys_bone_id = phys:GetID()
-- Main logic for the root bone -- Main logic for the root bone