mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
289 lines
5.8 KiB
Lua
289 lines
5.8 KiB
Lua
--[[
|
|
| 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/
|
|
--]]
|
|
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: scripted_ents
|
|
Desc: Scripted Entity factory
|
|
-----------------------------------------------------------]]
|
|
|
|
module( "scripted_ents", package.seeall )
|
|
|
|
local Aliases = {}
|
|
local SEntList = {}
|
|
|
|
local BaseClasses = {}
|
|
BaseClasses[ "anim" ] = "base_anim"
|
|
BaseClasses[ "point" ] = "base_point"
|
|
BaseClasses[ "brush" ] = "base_brush"
|
|
BaseClasses[ "filter" ] = "base_filter"
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: TableInherit( t, base )
|
|
Desc: Copies any missing data from base to t
|
|
-----------------------------------------------------------]]
|
|
local function TableInherit( t, base )
|
|
|
|
for k, v in pairs( base ) do
|
|
|
|
if ( t[ k ] == nil ) then
|
|
t[ k ] = v
|
|
elseif ( k != "BaseClass" && istable( t[ k ] ) && istable( v ) ) then
|
|
TableInherit( t[ k ], v )
|
|
end
|
|
|
|
end
|
|
|
|
t[ "BaseClass" ] = base
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: IsBasedOn( name, base )
|
|
Desc: Checks if name is based on base
|
|
-----------------------------------------------------------]]
|
|
function IsBasedOn( name, base )
|
|
local t = GetStored( name )
|
|
if not t then return false end
|
|
if t.Base == name then return false end
|
|
|
|
if t.Base == base then return true end
|
|
return IsBasedOn( t.Base, base )
|
|
end
|
|
|
|
function Register( t, name )
|
|
|
|
if ( hook.Run( "PreRegisterSENT", t, name ) == false ) then return end
|
|
|
|
if ( isstring( t.ClassNameOverride ) ) then name = t.ClassNameOverride end
|
|
|
|
local Base = t.Base
|
|
if ( !Base ) then Base = BaseClasses[ t.Type ] end
|
|
|
|
local old = SEntList[ name ]
|
|
local tab = {}
|
|
|
|
tab.type = t.Type
|
|
tab.t = t
|
|
tab.isBaseType = true
|
|
tab.Base = Base
|
|
tab.t.ClassName = name
|
|
|
|
if ( !Base ) then
|
|
Msg( "WARNING: Scripted entity " .. name .. " has an invalid base entity!\n" )
|
|
end
|
|
|
|
SEntList[ name ] = tab
|
|
|
|
-- Allow all SENTS to be duplicated, unless specified
|
|
if ( !t.DisableDuplicator ) then
|
|
duplicator.Allow( name )
|
|
end
|
|
|
|
--
|
|
-- If we're reloading this entity class
|
|
-- then refresh all the existing entities.
|
|
--
|
|
if ( old != nil ) then
|
|
|
|
--
|
|
-- For each entity using this class
|
|
--
|
|
for _, entity in ipairs( ents.FindByClass( name ) ) do
|
|
|
|
--
|
|
-- Replace the contents with this entity table
|
|
--
|
|
table.Merge( entity, tab.t )
|
|
|
|
--
|
|
-- Call OnReloaded hook (if it has one)
|
|
--
|
|
if ( entity.OnReloaded ) then
|
|
entity:OnReloaded()
|
|
end
|
|
|
|
end
|
|
|
|
-- Update entity table of entities that are based on this entity
|
|
for _, e in ipairs( ents.GetAll() ) do
|
|
if ( IsBasedOn( e:GetClass(), name ) ) then
|
|
|
|
table.Merge( e, Get( e:GetClass() ) )
|
|
|
|
if ( e.OnReloaded ) then
|
|
e:OnReloaded()
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
if ( !t.Spawnable ) then return end
|
|
|
|
list.Set( "SpawnableEntities", name, {
|
|
-- Required information
|
|
PrintName = t.PrintName,
|
|
ClassName = name,
|
|
Category = t.Category,
|
|
|
|
-- Optional information
|
|
NormalOffset = t.NormalOffset,
|
|
DropToFloor = t.DropToFloor,
|
|
Author = t.Author,
|
|
AdminOnly = t.AdminOnly,
|
|
Information = t.Information,
|
|
ScriptedEntityType = t.ScriptedEntityType,
|
|
IconOverride = t.IconOverride
|
|
} )
|
|
|
|
end
|
|
|
|
--
|
|
-- All scripts have been loaded...
|
|
--
|
|
function OnLoaded()
|
|
|
|
--
|
|
-- Once all the scripts are loaded we can set up the baseclass
|
|
-- - we have to wait until they're all setup because load order
|
|
-- could cause some entities to load before their bases!
|
|
--
|
|
for k, v in pairs( SEntList ) do
|
|
|
|
baseclass.Set( k, Get( k ) )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
function Get( name, retval )
|
|
|
|
-- Do we have an alias?
|
|
if ( Aliases[ name ] ) then
|
|
name = Aliases[ name ]
|
|
end
|
|
|
|
if ( SEntList[ name ] == nil ) then return nil end
|
|
|
|
-- Create/copy a new table
|
|
local retval = retval or {}
|
|
for k, v in pairs( SEntList[ name ].t ) do
|
|
if ( istable( v ) ) then
|
|
retval[ k ] = table.Copy( v )
|
|
else
|
|
retval[ k ] = v
|
|
end
|
|
end
|
|
|
|
-- Derive from base class
|
|
if ( SEntList[ name ].Base != name ) then
|
|
|
|
local base = Get( SEntList[ name ].Base )
|
|
|
|
if ( !base ) then
|
|
Msg("ERROR: Trying to derive entity " .. tostring( name ) .. " from non existant entity " .. tostring( SEntList[ name ].Base ) .. "!\n" )
|
|
else
|
|
retval = TableInherit( retval, base )
|
|
end
|
|
|
|
end
|
|
|
|
return retval
|
|
|
|
end
|
|
|
|
function GetType( name )
|
|
|
|
for k, v in pairs( BaseClasses ) do
|
|
if ( name == v ) then return k end
|
|
end
|
|
|
|
local ent = SEntList[ name ]
|
|
if ( ent == nil ) then return nil end
|
|
|
|
if ( ent.type ) then
|
|
return ent.type
|
|
end
|
|
|
|
if ( ent.Base ) then
|
|
return GetType( ent.Base )
|
|
end
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: GetStored( string )
|
|
Desc: Gets the REAL sent table, not a copy
|
|
-----------------------------------------------------------]]
|
|
function GetStored( name )
|
|
return SEntList[ name ]
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: GetList( string )
|
|
Desc: Get a list of all the registered SENTs
|
|
-----------------------------------------------------------]]
|
|
function GetList()
|
|
local result = {}
|
|
|
|
for k,v in pairs( SEntList ) do
|
|
result[ k ] = v
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
function GetSpawnable()
|
|
|
|
local result = {}
|
|
|
|
for k, v in pairs( SEntList ) do
|
|
|
|
local tab = v.t
|
|
|
|
if ( tab.Spawnable ) then
|
|
table.insert( result, tab )
|
|
end
|
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
function Alias( From, To )
|
|
|
|
Aliases[ From ] = To
|
|
|
|
end
|
|
|
|
function GetMember( entity_name, membername )
|
|
|
|
if ( !entity_name ) then return end
|
|
|
|
local ent = SEntList[ entity_name ]
|
|
|
|
if ( !ent ) then return end
|
|
|
|
local member = ent.t[ membername ]
|
|
if ( member != nil ) then return member end
|
|
|
|
-- If our base is the same as us - don't infinite loop!
|
|
if ( entity_name == ent.Base ) then return end
|
|
|
|
return GetMember( ent.Base, membername )
|
|
|
|
end
|