Bug fixes of varying degrees
This commit is contained in:
parent
786e997351
commit
5af8fdc14a
4 changed files with 33 additions and 103 deletions
13
README.md
13
README.md
|
|
@ -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?)
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue