Files
wnsrc/lua/entities/obj_vj_spawner_base/init.lua

258 lines
17 KiB
Lua
Raw Normal View History

2024-08-04 23:54:45 +03:00
--[[
| 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/
--]]
if (!file.Exists("autorun/vj_base_autorun.lua","LUA")) then return end
AddCSLuaFile("shared.lua")
include("shared.lua")
/*--------------------------------------------------
*** Copyright (c) 2012-2023 by DrVrej, All rights reserved. ***
No parts of this code or any of its contents may be reproduced, copied, modified or adapted,
without the prior written consent of the author, unless otherwise indicated for stand-alone materials.
--------------------------------------------------*/
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ Core Variables ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ENT.SingleSpawner = false -- If set to true, it will spawn the entities once then remove itself
ENT.VJBaseSpawnerDisabled = false -- If set to true, it will stop spawning the entities
ENT.OverrideDisableOnSpawn = false -- If set to true, the spawner will create entities on initialize even if it's disabled!
ENT.Model = {} -- The models it should spawn with | Picks a random one from the table
ENT.EntitiesToSpawn = {}
/* Example (3 NPCs):
ENT.EntitiesToSpawn = {
{SpawnPosition = {vForward=0, vRight=0, vUp=0}, Entities = {"npc_name_one"}},
{SpawnPosition = {vForward=0, vRight=0, vUp=0}, Entities = {"npc_name_one:1", "npc_name_two:5"}},
{SpawnPosition = {vForward=0, vRight=0, vUp=0}, Entities = {"npc_name_three", "npc_name_one:1", "npc_name_two:5"}},
}
Options:
Entities = {} -- The table of entities it spawns randomly, REQUIRED!
- ":" = Add at the end to apply a chance, it starts from 1
- ":1" = Spawn always or leave it empty
- WARNING: If no entity is left empty or set to ":1" then during randomization, the base will spawn the last NPC it checks if no other passes!
SpawnPosition = {vForward=0, vRight=0, vUp=0} -- The spawn position of the entity, it's based on the spawner's position, OPTIONAL | DEFAULT: Origin of the spawner
SpawnAngle = Angle(0, 0, 0) -- The spawn angle, it's based on the spawner's angle, OPTIONAL | DEFAULT: Spawners current angle
WeaponsList = {} -- The list of weapons it spawns with randomly, OPTIONAL | DEFAULT: Empty table
- "default" = Spawns the NPC with its default weapons list from the spawn menu
NPC_Class = "" or {} -- Overrides the NPC's relation class with the given string or table | DEFAULT: ""
FriToPlyAllies = false or true -- If set to true, the NPC will be allied with the player, must have NPC class "CLASS_PLAYER_ALLY" | DEFAULT: false
*/
ENT.TimedSpawn_Time = 3 -- How much time until it spawns another SNPC?
ENT.TimedSpawn_OnlyOne = true -- If it's true then it will only have one SNPC spawned at a time
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ Sound Variables ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Idle
ENT.HasIdleSounds = true -- Does it have idle sounds?
ENT.SoundTbl_Idle = {}
ENT.IdleSoundChance = 1 -- How much chance to play the sound? 1 = always
ENT.IdleSoundLevel = 80
ENT.IdleSoundPitch = VJ_Set(80, 100)
ENT.NextSoundTime_Idle = VJ_Set(0.2, 0.5)
-- On Entity Spawn
ENT.HasSpawnEntitySound = true -- Does it play a sound on entity spawn?
ENT.SoundTbl_SpawnEntity = {}
ENT.SpawnEntitySoundChance = 1 -- How much chance to play the sound? 1 = always
ENT.SpawnEntitySoundLevel = 80
ENT.SpawnEntitySoundPitch = VJ_Set(80, 100)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ Customization Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Use the functions below to customize certain parts of the base or to add new custom systems
---------------------------------------------------------------------------------------------------------------------------------------------
--[[---------------------------------------------------------
Called when an entity spawns.
- ent = The entity it spawned
- spawnKey = The key or the position in the table of the current entity it spawned
- spawnTbl = Table of information for the entity it spawned including class names, spawn position, weapons, etc.
- initSpawn = Was this an initial spawn? Used by the base during initialization
-----------------------------------------------------------]]
function ENT:CustomOnEntitySpawn(ent, spawnKey, spawnTbl, initSpawn) end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnInitialize() end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnInitialize_AfterNPCSpawn() end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnThink() end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnThink_AfterAliveChecks() end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:CustomOnRemove() end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------ ///// WARNING: Don't touch anything below this line! \\\\\ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ENT.Dead = false
ENT.NextIdleSoundT = 0
local string_explode = string.Explode
local defSpawnPos = {vForward=0, vRight=0, vUp=0}
local defAng = Angle(0, 0, 0)
---------------------------------------------------------------------------------------------------------------------------------------------
--[[---------------------------------------------------------
Spawns an entity from the given information, recommended to not manually call this function!
- spawnKey = The key or the position in the table of the current entity to spawn
- spawnTbl = Table of information for the entity to spawn including class names, spawn position, weapons, etc.
- initSpawn = Is this a initial spawn? Used by the base during initialization | DEFAULT: false
-----------------------------------------------------------]]
function ENT:SpawnAnEntity(spawnKey, spawnTbl, initSpawn)
local initOverrideDisable = (initSpawn == true && self.OverrideDisableOnSpawn)
if self.VJBaseSpawnerDisabled == true && initOverrideDisable == false then return end
local spawnPos = spawnTbl.SpawnPosition or defSpawnPos
local spawnAng = spawnTbl.SpawnAngle
local spawnEnts = spawnTbl.Entities
local spawnNPCClass = spawnTbl.NPC_Class or ""
local spawnFriToPlyAllies = spawnTbl.FriToPlyAllies or false
local spawnWepPicked = VJ_PICK(spawnTbl.WeaponsList)
local entPicked; -- The entity that we will spawn
local entsNum = #spawnEnts -- The number of entities
local i = 0 -- If this number equals entsNum, then its the last entity
for _, v in RandomPairs(spawnEnts) do
i = i + 1
local strExp = string_explode(":", v) -- Separates the entity class and the number after ":"
//PrintTable(strExp)
if strExp[2] then
if i == entsNum then -- If we are the last entity, then just spawn it anyway
entPicked = strExp[1]
break
elseif math.random(1, strExp[2]) == 1 then
entPicked = strExp[1]
break
end
else -- String does NOT contain ":", so just pick this
entPicked = v
break
end
end
local ent = ents.Create(entPicked)
ent:SetPos(self:GetPos() + self:GetForward()*(spawnPos.vForward or 0) + self:GetRight()*(spawnPos.vRight or 0) + self:GetUp()*(spawnPos.vUp or 0))
ent:SetAngles((spawnAng or defAng) + self:GetAngles())
ent:Spawn()
ent:Activate()
if spawnNPCClass != "" then
ent.VJ_NPC_Class = istable(spawnNPCClass) && spawnNPCClass or {spawnNPCClass}
end
if spawnFriToPlyAllies then
ent.FriendsWithAllPlayerAllies = true
end
if ent:IsNPC() && spawnWepPicked != false && string.lower(spawnWepPicked) != "none" then
if string.lower(spawnWepPicked) == "default" then -- Default weapon from the spawn menu
local getDefWep = VJ_PICK(list.Get("NPC")[ent:GetClass()].Weapons)
if getDefWep then
ent:Give(getDefWep)
end
else
ent:Give(spawnWepPicked)
end
end
self.CurrentEntities[spawnKey] = {Entities=spawnEnts, SpawnPosition=spawnPos, SpawnAngle=spawnAng, WeaponsList=spawnTbl.WeaponsList, NPC_Class=spawnNPCClass, FriToPlyAllies=spawnFriToPlyAllies, Ent=ent, Dead=false}
//table_remove(self.CurrentEntities, spawnKey)
//table.insert(self.CurrentEntities, spawnKey, {SpawnPosition=spawnPos, Entities=spawnEnts, WeaponsList=wepList, Ent=ent, Dead=false})
self:CustomOnEntitySpawn(ent, spawnKey, spawnTbl, initSpawn)
self:SpawnEntitySoundCode()
timer.Simple(0.1, function() if IsValid(self) && self.SingleSpawner == true then self:DoSingleSpawnerRemove() end end)
end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:Initialize()
self:CustomOnInitialize()
self:CustomOnInitialize_BeforeNPCSpawn() -- !!!!!!!!!!!!!! DO NOT USE THIS VARIABLE !!!!!!!!!!!!!! [Backwards Compatibility!]
if self:GetModel() == "models/error.mdl" then -- No model was detected
local mdls = VJ_PICK(self.Model)
if mdls && mdl !="models/props_junk/popcan01a.mdl" then
self:SetModel(mdls)
else -- No models found in self.Model
self:DrawShadow(false)
self:SetNoDraw(true)
self:SetNotSolid(true)
end
end
self.CurrentEntities = {}
for spawnKey, spawnTbl in ipairs(self.EntitiesToSpawn) do
self:SpawnAnEntity(spawnKey, spawnTbl, true)
end
self:CustomOnInitialize_AfterNPCSpawn()
end
function ENT:CustomOnInitialize_BeforeNPCSpawn() end -- !!!!!!!!!!!!!! DO NOT USE THIS VARIABLE !!!!!!!!!!!!!! [Backwards Compatibility!]
// lua_run for spawnKey,spawnTbl in ipairs(ents.GetAll()) do if spawnTbl.IsVJBaseSpawner == true then spawnTbl.VJBaseSpawnerDisabled = false end end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:Think()
//print("-----------------------------------------------------------")
//PrintTable(self.CurrentEntities)
self:CustomOnThink()
self:IdleSoundCode()
-- If it's a continuous spawner then make sure to respawn any entity that has been removed
if self.VJBaseSpawnerDisabled == false && self.SingleSpawner == false then
for spawnKey, spawnTbl in ipairs(self.CurrentEntities) do
-- If entity is removed AND we are NOT already respawning it, then respawn!
if !IsValid(spawnTbl.Ent) && spawnTbl.Dead == false then
spawnTbl.Dead = true -- To make sure we do NOT respawn it more than once!
timer.Simple(self.TimedSpawn_Time, function()
if IsValid(self) then
self:SpawnAnEntity(spawnKey, spawnTbl, false)
end
end)
end
end
end
self:CustomOnThink_AfterAliveChecks()
end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:IdleSoundCode()
if self.HasIdleSounds == false then return end
if CurTime() > self.NextIdleSoundT then
if math.random(1, self.IdleSoundChance) == 1 then
self.CurrentIdleSound = VJ_CreateSound(self, self.SoundTbl_Idle, self.IdleSoundLevel, math.random(self.IdleSoundPitch.a, self.IdleSoundPitch.b))
end
self.NextIdleSoundT = CurTime() + math.Rand(self.NextSoundTime_Idle.a, self.NextSoundTime_Idle.b)
end
end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:SpawnEntitySoundCode()
if self.HasSpawnEntitySound == false then return end
if math.random(1, self.SpawnEntitySoundChance) then
self.CurrentSpawnEntitySound = VJ_CreateSound(self, self.SoundTbl_SpawnEntity, self.SpawnEntitySoundLevel, math.random(self.SpawnEntitySoundPitch.a, self.SpawnEntitySoundPitch.b))
end
end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:DoSingleSpawnerRemove()
if self.Dead then return end
if IsValid(self:GetCreator()) then
for _, spawnTbl in ipairs(self.CurrentEntities) do
if IsValid(spawnTbl.Ent) then
undo.Create(spawnTbl.Ent:GetName())
undo.AddEntity(spawnTbl.Ent)
undo.SetPlayer(self:GetCreator())
undo.Finish()
end
end
end
self.Dead = true
VJ_STOPSOUND(self.CurrentIdleSound)
self:Remove()
end
---------------------------------------------------------------------------------------------------------------------------------------------
function ENT:OnRemove()
self:CustomOnRemove()
self.Dead = true
VJ_STOPSOUND(self.CurrentIdleSound)
-- If it's a continuous spawner then remove all the spawned entities!
if self.SingleSpawner == false && self.CurrentEntities != nil then
for _, spawnTbl in ipairs(self.CurrentEntities) do
if IsValid(spawnTbl.Ent) then
spawnTbl.Ent:Remove()
end
end
end
end