ACTUALLY make NPC targeting actually work
This commit is contained in:
parent
e8112ffd8a
commit
6906b0ba6f
3 changed files with 45 additions and 6 deletions
|
|
@ -1,3 +1,16 @@
|
||||||
|
local function PopulateAISBXToolMenu(pnl)
|
||||||
|
pnl:CheckBox("Allow NPCs to target downed NPCs", "zcnpci_npc_targeting_enabled")
|
||||||
|
pnl:ControlHelp("If enabled, NPCs target downed hostile NPCs.")
|
||||||
|
|
||||||
|
pnl:CheckBox("NPCs should target head", "zcnpci_target_should_follow_head")
|
||||||
|
pnl:ControlHelp("Should NPCs target the player's head? This can result in more effective targeting.")
|
||||||
|
|
||||||
|
pnl:CheckBox("NPCs shouldn't target unconscious NPCs", "zcnpci_no_unconscious_targeting")
|
||||||
|
|
||||||
|
pnl:CheckBox("NPCs shouldn't target unconscious players", "zcnpci_no_unconscious_targeting_players")
|
||||||
|
pnl:ControlHelp("This may or may not work.")
|
||||||
|
end
|
||||||
|
|
||||||
local function PopulateCustomNPCSBXToolMenu(pnl)
|
local function PopulateCustomNPCSBXToolMenu(pnl)
|
||||||
local modded_npc_whitelist = CreateConVar("zcnpci_modded_npc_whitelist", "NPC-classes-here!", bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
local modded_npc_whitelist = CreateConVar("zcnpci_modded_npc_whitelist", "NPC-classes-here!", bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
|
|
||||||
|
|
@ -25,7 +38,7 @@ local function PopulateCustomNPCSBXToolMenu(pnl)
|
||||||
|
|
||||||
pnl:AddItem(text)
|
pnl:AddItem(text)
|
||||||
|
|
||||||
pnl:Help("One NPC class per line. No spaces or other characters. Can only be set by a superadmin or server operator.")
|
pnl:Help("A list of NPC classes, seperated by spaces or line breaks. Can only be set by a superadmin or server operator.")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function PopulateRagdollSBXToolMenu(pnl)
|
local function PopulateRagdollSBXToolMenu(pnl)
|
||||||
|
|
@ -125,6 +138,11 @@ if engine.ActiveGamemode() == "sandbox" then
|
||||||
PopulateRagdollSBXToolMenu(pnl)
|
PopulateRagdollSBXToolMenu(pnl)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
spawnmenu.AddToolMenuOption("Utilities", "zcnpci", "AISettings", "AI", "", "", function(pnl)
|
||||||
|
pnl:ClearControls()
|
||||||
|
PopulateAISBXToolMenu(pnl)
|
||||||
|
end)
|
||||||
|
|
||||||
spawnmenu.AddToolMenuOption("Utilities", "zcnpci", "MainSettings", "Main", "", "", function(pnl)
|
spawnmenu.AddToolMenuOption("Utilities", "zcnpci", "MainSettings", "Main", "", "", function(pnl)
|
||||||
pnl:ClearControls()
|
pnl:ClearControls()
|
||||||
PopulateMainSBXToolMenu(pnl)
|
PopulateMainSBXToolMenu(pnl)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ ENT.AutomaticFrameAdvance = true
|
||||||
|
|
||||||
local debug_show_ragdoll_targets = CreateConVar("zcnpci_debug_show_ragdoll_targets", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
local debug_show_ragdoll_targets = CreateConVar("zcnpci_debug_show_ragdoll_targets", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
|
|
||||||
|
local should_follow_head = CreateConVar("zcnpci_target_should_follow_head", 0, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
|
local stop_targeting_when_unconscious = CreateConVar("zcnpci_no_unconscious_targeting", 1, bit.bor(FCVAR_ARCHIVE, FCVAR_REPLICATED))
|
||||||
|
|
||||||
|
local vector_offset_to_shoot_at = Vector(0, 0, 8)
|
||||||
|
|
||||||
local function UpdateRelationship(ent, me)
|
local function UpdateRelationship(ent, me)
|
||||||
if !IsValid(ent) or !ent:IsNPC() then return end
|
if !IsValid(ent) or !ent:IsNPC() then return end
|
||||||
|
|
||||||
|
|
@ -28,15 +33,23 @@ local function RemoveRelationship(ent, me)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ENT:Classify()
|
||||||
|
return self.dummy_entity:Classify()
|
||||||
|
end
|
||||||
|
|
||||||
function ENT:Initialize()
|
function ENT:Initialize()
|
||||||
if SERVER then
|
if SERVER then
|
||||||
self:SetModel("models/maxofs2d/hover_basic.mdl")
|
self:SetModel("models/maxofs2d/hover_basic.mdl")
|
||||||
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
self:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||||
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 = nil
|
self.last_stop_targeting = nil
|
||||||
|
|
||||||
|
-- Have to use this collision group otherwise ragdoll will obstruct visibility of target
|
||||||
|
self.ragdoll_to_follow:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -52,18 +65,23 @@ function ENT:Think()
|
||||||
local ragdoll = self.ragdoll_to_follow
|
local ragdoll = self.ragdoll_to_follow
|
||||||
if !IsValid(ragdoll) then return end
|
if !IsValid(ragdoll) then return end
|
||||||
|
|
||||||
|
if should_follow_head:GetBool() then
|
||||||
|
local head = ragdoll:GetPhysicsObjectNum(ragdoll:TranslateBoneToPhysBone(ragdoll:LookupBone("ValveBiped.Bip01_Head1")))
|
||||||
|
self:SetPos(head:GetPos() + vector_offset_to_shoot_at)
|
||||||
|
else
|
||||||
self:SetPos(ragdoll:GetPos())
|
self:SetPos(ragdoll:GetPos())
|
||||||
|
end
|
||||||
|
|
||||||
self:SetNoDraw(!debug_show_ragdoll_targets:GetBool())
|
self:SetNoDraw(!debug_show_ragdoll_targets:GetBool())
|
||||||
|
|
||||||
if !ragdoll.organism then return true end
|
if !ragdoll.organism then return true end
|
||||||
|
|
||||||
local should_stop_targeting = (
|
local should_stop_targeting = !zcnpci_no_unconscious_targeting:GetBool() or (
|
||||||
(ragdoll.organism.consciousness <= 0.4) or
|
(ragdoll.organism.consciousness <= 0.4) or
|
||||||
(ragdoll.organism.critical)
|
(ragdoll.organism.critical)
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_stop_targeting != self.last_stop_targeting then
|
if true or (should_stop_targeting != self.last_stop_targeting) then
|
||||||
self.last_stop_targeting = should_stop_targeting
|
self.last_stop_targeting = should_stop_targeting
|
||||||
|
|
||||||
if should_stop_targeting then
|
if should_stop_targeting then
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,9 @@ local minimum_down_time = CreateConVar("zcnpci_down_time", "5", {FCVAR_ARCHIVE,
|
||||||
local can_unfake = CreateConVar("zcnpci_unfake_enabled", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Whether an NPC can unfake")
|
local can_unfake = CreateConVar("zcnpci_unfake_enabled", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Whether an NPC can unfake")
|
||||||
local unfake_time = CreateConVar("zcnpci_unfake_time", "1.5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Time it takes for an NPC to unfake")
|
local unfake_time = CreateConVar("zcnpci_unfake_time", "1.5", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Time it takes for an NPC to unfake")
|
||||||
|
|
||||||
|
-- Targeting
|
||||||
|
local npc_targeting_enabled = CreateConVar("zcnpci_npc_targeting_enabled", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Should NPCs target downed NPCs")
|
||||||
|
|
||||||
--[[-------------------------------------------------------------------------
|
--[[-------------------------------------------------------------------------
|
||||||
Tug function
|
Tug function
|
||||||
Applies a random impulse to one of the leg bones.
|
Applies a random impulse to one of the leg bones.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue