mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 05:43:46 +03:00
Upload
This commit is contained in:
247
lua/entities/sent_vj_antlion_director/init.lua
Normal file
247
lua/entities/sent_vj_antlion_director/init.lua
Normal file
@@ -0,0 +1,247 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
AddCSLuaFile("shared.lua")
|
||||
include('shared.lua')
|
||||
|
||||
ENT.Antlion = {
|
||||
"npc_vj_hla_antlion"
|
||||
}
|
||||
|
||||
ENT.previousNodes = {} -- Leave this here, for some reason it doesn't work in the initialize
|
||||
ENT.HordeSpawnRate = 0.19 -- The difference in time between each spawned Horde
|
||||
ENT.SkipOnRemove = false
|
||||
|
||||
function ENT:Initialize()
|
||||
local i = 0
|
||||
for k, v in ipairs(ents.GetAll()) do
|
||||
if v:GetClass() == "sent_vj_antlion_director" then
|
||||
i = i + 1
|
||||
if i > 1 then PrintMessage(HUD_PRINTTALK, "Only one A.I. Director can be present in the map.") self.SkipOnRemove = true self:Remove() return end
|
||||
end
|
||||
end
|
||||
|
||||
if table.Count(VJ_ANT_NODEPOS) <= 0 then
|
||||
error("No nodegraph detected! Play on a noded map to use the director. Nodes made using the nodegraph editor are undetectable as they're not actually nodes")
|
||||
self:Remove()
|
||||
return
|
||||
end
|
||||
self:SetCollisionGroup(COLLISION_GROUP_NONE)
|
||||
self:SetMoveType(MOVETYPE_NONE)
|
||||
self:SetSolid(SOLID_NONE)
|
||||
self:SetPos(Vector(0,0,0))
|
||||
self:SetNoDraw(true)
|
||||
self:DrawShadow(false)
|
||||
|
||||
self.IsActivated = tobool(GetConVarNumber("vj_antlion_director_enabled"))
|
||||
self.Antlion_SpawnDistance = GetConVarNumber("vj_antlion_director_spawnmax")
|
||||
self.Antlion_SpawnDistanceClose = GetConVarNumber("vj_antlion_director_spawnmin")
|
||||
self.Antlion_HordeChance = GetConVarNumber("vj_antlion_director_hordechance")
|
||||
self.Antlion_HordeCooldownMin = GetConVarNumber("vj_antlion_director_hordecooldownmin")
|
||||
self.Antlion_HordeCooldownMax = GetConVarNumber("vj_antlion_director_hordecooldownmax")
|
||||
self.Antlion_MaxAntlions = GetConVarNumber("vj_antlion_director_max")
|
||||
self.Antlion_MaxHordeSpawn = GetConVarNumber("vj_antlion_director_hordecount")
|
||||
self.tbl_SpawnedNPCs = {}
|
||||
self.tbl_NPCsWithEnemies = {}
|
||||
self.NextAICheckTime = CurTime() +5
|
||||
self.NextAntlionSpawnTime = CurTime() +1
|
||||
self.NextHordeSpawnTime = CurTime() +math.Rand(self.Antlion_HordeCooldownMin,self.Antlion_HordeCooldownMax)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
if self.SkipOnRemove == true then return end
|
||||
for index,object in ipairs(self.tbl_SpawnedNPCs) do
|
||||
if IsValid(object) then
|
||||
object:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self.IsActivated = tobool(GetConVarNumber("vj_antlion_director_enabled"))
|
||||
if self.IsActivated then
|
||||
self:ManageVars()
|
||||
self:ManageAI()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:ManageVars()
|
||||
self.Antlion_SpawnDistance = GetConVarNumber("vj_antlion_director_spawnmax")
|
||||
self.Antlion_SpawnDistanceClose = GetConVarNumber("vj_antlion_director_spawnmin")
|
||||
self.Antlion_HordeChance = GetConVarNumber("vj_antlion_director_hordechance")
|
||||
self.Antlion_HordeCooldownMin = GetConVarNumber("vj_antlion_director_hordecooldownmin")
|
||||
self.Antlion_HordeCooldownMax = GetConVarNumber("vj_antlion_director_hordecooldownmax")
|
||||
self.Antlion_MaxAntlions = GetConVarNumber("vj_antlion_director_max")
|
||||
self.Antlion_MaxHordeSpawn = GetConVarNumber("vj_antlion_director_hordecount")
|
||||
self.AI_RefreshTime = GetConVarNumber("vj_l4d_director_refreshrate")
|
||||
end
|
||||
|
||||
function ENT:CheckSurvivorDistance(ent)
|
||||
local survivors = self:FindSurvivors(ent:GetPos())
|
||||
local farthestSurvivor = survivors[table.Count(survivors)]
|
||||
if ent:GetPos():Distance(farthestSurvivor:GetPos()) >= GetConVarNumber("vj_antlion_director_spawnmax") +750 && !ent:Visible(farthestSurvivor) then
|
||||
ent:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:ManageAI()
|
||||
-- Checks for inactive AI
|
||||
if CurTime() > self.NextAICheckTime then
|
||||
if #self.tbl_SpawnedNPCs <= 0 then return end
|
||||
for _,v in ipairs(self.tbl_SpawnedNPCs) do
|
||||
if IsValid(v) then
|
||||
self:CheckSurvivorDistance(v)
|
||||
if IsValid(v:GetEnemy()) && !table.HasValue(self.tbl_NPCsWithEnemies,v) then
|
||||
table.insert(self.tbl_NPCsWithEnemies,v)
|
||||
elseif !IsValid(v:GetEnemy()) then
|
||||
if table.HasValue(self.tbl_NPCsWithEnemies,v) then
|
||||
table.remove(self.tbl_NPCsWithEnemies,self.tbl_NPCsWithEnemies[v])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
table.Empty(self.previousNodes) -- Reset the previously spawned-on nodes to refresh spawn positions
|
||||
self.previousNodes = {}
|
||||
self.NextAICheckTime = CurTime() +5
|
||||
end
|
||||
|
||||
-- Spawns AI
|
||||
if CurTime() > self.NextAntlionSpawnTime then
|
||||
if table.Count(self.tbl_SpawnedNPCs) >= self.Antlion_MaxAntlions -self.Antlion_MaxHordeSpawn then return end -- Makes sure that we can at least spawn a Horde when it's time
|
||||
self:SpawnAntlion(VJ_PICKRANDOMTABLE(self.Antlion),self:FindClearArea(false))
|
||||
self.NextAntlionSpawnTime = CurTime() + math.Rand(GetConVarNumber("vj_antlion_director_delaymin"),GetConVarNumber("vj_antlion_director_delaymax"))
|
||||
end
|
||||
|
||||
-- Spawns Hordes
|
||||
if CurTime() > self.NextHordeSpawnTime && math.random(1,self.Antlion_HordeChance) == 1 then
|
||||
for i = 1,self.Antlion_MaxHordeSpawn do
|
||||
timer.Simple(self.HordeSpawnRate *i,function() -- Help with lag when spawning
|
||||
if IsValid(self) then
|
||||
self:SpawnAntlion(VJ_PICKRANDOMTABLE(self.Antlion),self:FindClearArea(true),true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
self.NextHordeSpawnTime = CurTime() + math.Rand(self.Antlion_HordeCooldownMin,self.Antlion_HordeCooldownMax)
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CheckNodeVisibility(pos,survivor)
|
||||
local nodeCheck = ents.Create("prop_vj_animatable")
|
||||
nodeCheck:SetModel("models/cpthazama/l4d1/common/common_patient_male01.mdl")
|
||||
nodeCheck:SetPos(pos)
|
||||
nodeCheck:SetCollisionGroup(COLLISION_GROUP_IN_VEHICLE)
|
||||
nodeCheck:Spawn()
|
||||
nodeCheck:Activate()
|
||||
nodeCheck:SetNoDraw(true)
|
||||
nodeCheck:DrawShadow(false)
|
||||
timer.Simple(0.02,function()
|
||||
if IsValid(nodeCheck) then
|
||||
nodeCheck:Remove()
|
||||
end
|
||||
end)
|
||||
return nodeCheck:Visible(survivor)
|
||||
end
|
||||
|
||||
function ENT:ConfigureNodeTable(tbl)
|
||||
local newTable = {}
|
||||
local ply = self:PickRandomSurvivor()
|
||||
for _,v in pairs(tbl) do
|
||||
newTable[v] = v:Distance(ply:GetPos())
|
||||
end
|
||||
return table.SortByKey(newTable,true)
|
||||
end
|
||||
|
||||
function ENT:FindClearArea(getClosest)
|
||||
if table.Count(self.tbl_SpawnedNPCs) >= self.Antlion_MaxAntlions then return end
|
||||
if getClosest then
|
||||
if table.Count(VJ_ANT_NODEPOS) > 0 then
|
||||
for _,i in ipairs(self:ConfigureNodeTable(VJ_ANT_NODEPOS)) do
|
||||
local nodePos = i
|
||||
local survivor = self:FindSurvivors(nodePos)[1]
|
||||
if nodePos:Distance(survivor:GetPos()) <= self.Antlion_SpawnDistance && nodePos:Distance(survivor:GetPos()) > self.Antlion_SpawnDistanceClose then
|
||||
if !self:CheckNodeVisibility(nodePos,survivor) then
|
||||
table.insert(self.previousNodes,nodePos)
|
||||
return nodePos
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if table.Count(VJ_ANT_NODEPOS) > 0 then
|
||||
for _,i in ipairs(self:ConfigureNodeTable(VJ_ANT_NODEPOS)) do
|
||||
local nodePos = i
|
||||
local survivor = self:FindSurvivors(nodePos)[1]
|
||||
if self.previousNodes[nodePos] then return end
|
||||
if nodePos:Distance(survivor:GetPos()) <= self.Antlion_SpawnDistance && nodePos:Distance(survivor:GetPos()) > self.Antlion_SpawnDistanceClose then
|
||||
-- if !survivor:VisibleVec(nodePos) then
|
||||
if !self:CheckNodeVisibility(nodePos,survivor) then
|
||||
if table.HasValue(self.previousNodes,nodePos) then return end
|
||||
table.insert(self.previousNodes,nodePos)
|
||||
return nodePos
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:PickRandomSurvivor()
|
||||
local tbl = {}
|
||||
for _,v in ipairs(player.GetAll()) do
|
||||
table.insert(tbl,v)
|
||||
end
|
||||
return VJ_PICKRANDOMTABLE(tbl)
|
||||
end
|
||||
|
||||
function ENT:FindSurvivors(vec)
|
||||
local tb = {}
|
||||
if vec then
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
tb[v] = v:GetPos():Distance(vec)
|
||||
end
|
||||
return table.SortByKey(tb,true)
|
||||
else
|
||||
for _,v in pairs(player.GetAll()) do
|
||||
table.insert(tb,v)
|
||||
end
|
||||
return tb
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:SpawnAntlion(ent,pos,isHorde)
|
||||
if pos == nil then /*MsgN("AI Director: Could not spawn Antlion, no position specified!")*/ return end
|
||||
if table.Count(self.tbl_SpawnedNPCs) >= self.Antlion_MaxAntlions then return end
|
||||
local Antlion = ents.Create(ent)
|
||||
Antlion:SetPos(pos)
|
||||
Antlion:Spawn()
|
||||
Antlion:Activate()
|
||||
table.insert(self.tbl_SpawnedNPCs,Antlion)
|
||||
Antlion:VJ_ACT_PLAYACTIVITY("UnBurrow01",true,false,false)
|
||||
if isHorde then
|
||||
Antlion.FindEnemy_UseSphere = true
|
||||
Antlion.FindEnemy_CanSeeThroughWalls = true
|
||||
Antlion:DrawShadow(false)
|
||||
timer.Simple(0.02,function()
|
||||
if IsValid(Antlion) then
|
||||
Antlion:DrawShadow(false)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Antlion.AI_Director = self
|
||||
function Antlion:CustomOnRemove()
|
||||
if IsValid(self.AI_Director) then
|
||||
table.remove(self.AI_Director.tbl_SpawnedNPCs,self.AI_Director.tbl_SpawnedNPCs[self])
|
||||
if table.HasValue(self.AI_Director.tbl_NPCsWithEnemies,self) then table.remove(self.AI_Director.tbl_NPCsWithEnemies,self.AI_Director.tbl_NPCsWithEnemies[self]) end
|
||||
end
|
||||
end
|
||||
Antlion.EntitiesToNoCollide = {
|
||||
"npc_vj_hla_antlion"
|
||||
}
|
||||
end
|
||||
27
lua/entities/sent_vj_antlion_director/shared.lua
Normal file
27
lua/entities/sent_vj_antlion_director/shared.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "base_anim"
|
||||
ENT.PrintName = "AI Director"
|
||||
ENT.Author = "Cpt. Hazama"
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
-- ENT.Category = "VJ Base - HLA Antlion" Thank you Hazama for making this.
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
if CLIENT then
|
||||
function ENT:Draw()
|
||||
return false
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user