Files
wnsrc/lua/includes/util.lua
lifestorm 94063e4369 Upload
2024-08-04 22:55:00 +03:00

543 lines
15 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/
--]]
-- Temporary, DELETE ME after an update after May 2024
if ( CLIENT and !vgui.GetAll ) then function vgui.GetAll() return {} end end
if ( !RegisterMetaTable ) then
local metas = {}
local oldFindMetaTable = FindMetaTable
FindMetaTable = function( name )
local f = oldFindMetaTable( name )
if ( f ) then return f end
return metas[ name ]
end
function RegisterMetaTable( key, value )
metas[ key ] = value
end
end
--
-- Hack for debug.getregistry
--
local meta = {}
function meta.__index( self, key )
return FindMetaTable( key )
end
function meta.__newindex( self, key, value )
rawset( self, key, value )
if ( isstring( key ) and istable( value ) ) then
RegisterMetaTable( key, value )
end
end
local tbl = {}
setmetatable( tbl, meta )
function debug.getregistry() return tbl end
--
-- Seed the rand!
--
math.randomseed( os.time() )
--
-- Alias string.Format to global Format
--
Format = string.format
--
-- Send C the flags for any materials we want to create
--
local C_Material = Material
function Material( name, words )
if ( !words ) then return C_Material( name ) end
local str = (words:find("vertexlitgeneric") and "1" or "0")
str = str .. (words:find("nocull") and "1" or "0")
str = str .. (words:find("alphatest") and "1" or "0")
str = str .. (words:find("mips") and "1" or "0")
str = str .. (words:find("noclamp") and "1" or "0")
str = str .. (words:find("smooth") and "1" or "0")
str = str .. (words:find("ignorez") and "1" or "0")
return C_Material( name, str )
end
--[[---------------------------------------------------------
IsTableOfEntitiesValid
-----------------------------------------------------------]]
function IsTableOfEntitiesValid( tab )
if ( !tab ) then return false end
for k, v in pairs( tab ) do
if ( !IsValid( v ) ) then return false end
end
return true
end
--[[---------------------------------------------------------
Color related functions - they now have their own
metatable so better put them in their own separate
file
-----------------------------------------------------------]]
include( "util/color.lua" )
--[[---------------------------------------------------------
Prints a table to the console
-----------------------------------------------------------]]
function PrintTable( t, indent, done )
local Msg = Msg
done = done or {}
indent = indent or 0
local keys = table.GetKeys( t )
table.sort( keys, function( a, b )
if ( isnumber( a ) and isnumber( b ) ) then return a < b end
return tostring( a ) < tostring( b )
end )
done[ t ] = true
for i = 1, #keys do
local key = keys[ i ]
local value = t[ key ]
key = ( type( key ) == "string" ) and "[\"" .. key .. "\"]" || "[" .. tostring( key ) .. "]"
Msg( string.rep( "\t", indent ) )
if ( istable( value ) and !done[ value ] ) then
done[ value ] = true
Msg( key, ":\n" )
PrintTable ( value, indent + 2, done )
done[ value ] = nil
else
Msg( key, "\t=\t", value, "\n" )
end
end
end
--[[---------------------------------------------------------
Returns a random vector
-----------------------------------------------------------]]
function VectorRand( min, max )
min = min || -1
max = max || 1
return Vector( math.Rand( min, max ), math.Rand( min, max ), math.Rand( min, max ) )
end
--[[---------------------------------------------------------
Returns a random angle
-----------------------------------------------------------]]
function AngleRand( min, max )
return Angle( math.Rand( min || -90, max || 90 ), math.Rand( min || -180, max || 180 ), math.Rand( min || -180, max || 180 ) )
end
--[[---------------------------------------------------------
Returns a random color
-----------------------------------------------------------]]
function ColorRand( alpha )
if ( alpha ) then
return Color( math.random( 0, 255 ), math.random( 0, 255 ), math.random( 0, 255 ), math.random( 0, 255 ) )
end
return Color( math.random( 0, 255 ), math.random( 0, 255 ), math.random( 0, 255 ) )
end
--[[---------------------------------------------------------
Convenience function to precache a sound
-----------------------------------------------------------]]
function Sound( name )
util.PrecacheSound( name )
return name
end
--[[---------------------------------------------------------
Convenience function to precache a model
-----------------------------------------------------------]]
function Model( name )
util.PrecacheModel( name )
return name
end
--[[---------------------------------------------------------
Convenience function to precache a particle
-----------------------------------------------------------]]
function Particle( name )
if ( CLIENT ) then
game.AddParticles( name )
end
return name
end
-- Some nice globals so we don't keep creating objects for no reason
vector_origin = Vector( 0, 0, 0 )
vector_up = Vector( 0, 0, 1 )
angle_zero = Angle( 0, 0, 0 )
color_white = Color( 255, 255, 255, 255 )
color_black = Color( 0, 0, 0, 255 )
color_transparent = Color( 255, 255, 255, 0 )
--[[---------------------------------------------------------
Includes the file - and adds it so the CS file list
-----------------------------------------------------------]]
function IncludeCS( filename )
if ( SERVER ) then
AddCSLuaFile( filename )
end
return include( filename )
end
-- Globals
FORCE_STRING = 1
FORCE_NUMBER = 2
FORCE_BOOL = 3
FORCE_ANGLE = 4
FORCE_COLOR = 5
FORCE_VECTOR = 6
--[[---------------------------------------------------------
AccessorFunc
Quickly make Get/Set accessor fuctions on the specified table
-----------------------------------------------------------]]
function AccessorFunc( tab, varname, name, iForce )
if ( !tab ) then debug.Trace() end
tab[ "Get" .. name ] = function( self ) return self[ varname ] end
if ( iForce == FORCE_STRING ) then
tab[ "Set" .. name ] = function( self, v ) self[ varname ] = tostring( v ) end
return end
if ( iForce == FORCE_NUMBER ) then
tab[ "Set" .. name ] = function( self, v ) self[ varname ] = tonumber( v ) end
return end
if ( iForce == FORCE_BOOL ) then
tab[ "Set" .. name ] = function( self, v ) self[ varname ] = tobool( v ) end
return end
if ( iForce == FORCE_ANGLE ) then
tab[ "Set" .. name ] = function( self, v ) self[ varname ] = Angle( v ) end
return end
if ( iForce == FORCE_COLOR ) then
tab[ "Set" .. name ] = function( self, v )
if ( type( v ) == "Vector" ) then self[ varname ] = v:ToColor()
else self[ varname ] = string.ToColor( tostring( v ) ) end
end
return end
if ( iForce == FORCE_VECTOR ) then
tab[ "Set" .. name ] = function( self, v )
if ( IsColor( v ) ) then self[ varname ] = v:ToVector()
else self[ varname ] = Vector( v ) end
end
return end
tab[ "Set" .. name ] = function( self, v ) self[ varname ] = v end
end
--[[---------------------------------------------------------
Returns true if object is valid (is not nil and IsValid)
-----------------------------------------------------------]]
function IsValid( object )
if ( !object ) then return false end
local isvalid = object.IsValid
if ( !isvalid ) then return false end
return isvalid( object )
end
--[[---------------------------------------------------------
Safely remove an entity
-----------------------------------------------------------]]
function SafeRemoveEntity( ent )
if ( !IsValid( ent ) || ent:IsPlayer() ) then return end
ent:Remove()
end
--[[---------------------------------------------------------
Safely remove an entity (delayed)
-----------------------------------------------------------]]
function SafeRemoveEntityDelayed( ent, timedelay )
if ( !IsValid( ent ) || ent:IsPlayer() ) then return end
timer.Simple( timedelay, function() SafeRemoveEntity( ent ) end )
end
--[[---------------------------------------------------------
Simple lerp
-----------------------------------------------------------]]
function Lerp( delta, from, to )
if ( delta > 1 ) then return to end
if ( delta < 0 ) then return from end
return from + ( to - from ) * delta
end
--[[---------------------------------------------------------
Convert Var to Bool
-----------------------------------------------------------]]
function tobool( val )
if ( val == nil || val == false || val == 0 || val == "0" || val == "false" ) then return false end
return true
end
--[[---------------------------------------------------------
Universal function to filter out crappy models by name
-----------------------------------------------------------]]
local UselessModels = {
"_gesture", "_anim", "_gst", "_pst", "_shd", "_ss", "_posture", "_anm",
"ghostanim","_paths", "_shared", "anim_", "gestures_", "shared_ragdoll_"
}
function IsUselessModel( modelname )
modelname = modelname:lower()
if ( !modelname:find( ".mdl", 1, true ) ) then return true end
for k, v in ipairs( UselessModels ) do
if ( modelname:find( v, 1, true ) ) then
return true
end
end
return false
end
UTIL_IsUselessModel = IsUselessModel
--[[---------------------------------------------------------
Given a number, returns the right 'th
-----------------------------------------------------------]]
local STNDRD_TBL = { "st", "nd", "rd" }
function STNDRD( num )
num = num % 100
if ( num > 10 and num < 20 ) then
return "th"
end
return STNDRD_TBL[ num % 10 ] or "th"
end
--[[---------------------------------------------------------
From Simple Gamemode Base (Rambo_9)
-----------------------------------------------------------]]
function TimedSin( freq, min, max, offset )
return math.sin( freq * math.pi * 2 * CurTime() + offset ) * ( max - min ) * 0.5 + min
end
--[[---------------------------------------------------------
From Simple Gamemode Base (Rambo_9)
-----------------------------------------------------------]]
function TimedCos( freq, min, max, offset )
return math.cos( freq * math.pi * 2 * CurTime() + offset ) * ( max - min ) * 0.5 + min
end
--[[---------------------------------------------------------
IsEnemyEntityName
-----------------------------------------------------------]]
local EnemyNames = {
-- Half-Life 1.
monster_alien_grunt = true, monster_nihilanth = true, monster_tentacle = true, monster_alien_slave = true,
monster_bigmomma = true, monster_bullchicken = true, monster_gargantua = true, monster_human_assassin = true,
monster_babycrab = true, monster_human_grunt = true, monster_cockroach = true, monster_houndeye = true,
monster_zombie = true, monster_headcrab = true, monster_alien_controller = true, monster_turret = true,
monster_miniturret = true, monster_sentry = true,
-- Half-Life 2.
npc_antlion = true, npc_antlionguard = true, npc_antlionguardian = true, npc_barnacle = true,
npc_breen = true, npc_clawscanner = true, npc_combine_s = true, npc_cscanner = true, npc_fastzombie = true,
npc_fastzombie_torso = true, npc_headcrab = true, npc_headcrab_fast = true, npc_headcrab_poison = true,
npc_hunter = true, npc_metropolice = true, npc_manhack = true, npc_poisonzombie = true, npc_strider = true,
npc_stalker = true, npc_zombie = true, npc_zombie_torso = true, npc_zombine = true, npc_combine_camera = true,
npc_turret_ceiling = true, npc_combinedropship = true, npc_combinegunship = true, npc_helicopter = true,
npc_turret_floor = true, npc_antlion_worker = true, npc_headcrab_black = true
}
function IsEnemyEntityName( victimtype )
return EnemyNames[ victimtype ] or false
end
--[[---------------------------------------------------------
IsFriendEntityName
-----------------------------------------------------------]]
local FriendlyNames = {
-- Half-Life 1.
monster_scientist = true, monster_barney = true,
-- Half-Life 2.
npc_alyx = true, npc_barney = true, npc_citizen = true, npc_dog = true, npc_eli = true,
npc_fisherman = true, npc_gman = true, npc_kleiner = true, npc_magnusson = true,
npc_monk = true, npc_mossman = true, npc_odessa = true, npc_vortigaunt = true
}
function IsFriendEntityName( victimtype )
return FriendlyNames[ victimtype ] or false
end
--[[---------------------------------------------------------
Is content mounted?
IsMounted( "cstrike" )
IsMounted( 4010 )
-----------------------------------------------------------]]
function IsMounted( name )
local games = engine.GetGames()
for k, v in pairs( games ) do
if ( !v.mounted ) then continue end
if ( v.depot == name ) then return true end
if ( v.folder == name ) then return true end
end
return false
end
--[[---------------------------------------------------------
Replacement for C++'s iff ? aa : bb
-----------------------------------------------------------]]
function Either( iff, aa, bb )
if ( iff ) then return aa end
return bb
end
--
-- You can use this function to add your own CLASS_ var.
-- Adding in this way will ensure your CLASS_ doesn't collide with another
--
-- ie Add_NPC_Class( "MY_CLASS" )
function Add_NPC_Class( name )
_G[ name ] = NUM_AI_CLASSES
NUM_AI_CLASSES = NUM_AI_CLASSES + 1
end
if ( CLIENT ) then
--[[---------------------------------------------------------
Remember/Restore cursor position..
Clientside only
If you have a system where you hold a key to show the cursor
Call RememberCursorPosition when the key is released and call
RestoreCursorPosition to restore the cursor to where it was
when the key was released.
If you don't the cursor will appear in the middle of the screen
-----------------------------------------------------------]]
local StoredCursorPos = {}
function RememberCursorPosition()
local x, y = input.GetCursorPos()
-- If the cursor isn't visible it will return 0,0 ignore it.
if ( x == 0 and y == 0 ) then return end
StoredCursorPos.x, StoredCursorPos.y = x, y
end
function RestoreCursorPosition()
if ( !StoredCursorPos.x || !StoredCursorPos.y ) then return end
input.SetCursorPos( StoredCursorPos.x, StoredCursorPos.y )
end
end
--
-- This is supposed to be clientside, but was exposed to both states for years due to a bug.
--
function CreateClientConVar( name, default, shouldsave, userdata, helptext, min, max )
local iFlags = 0
if ( shouldsave || shouldsave == nil ) then
iFlags = bit.bor( iFlags, FCVAR_ARCHIVE )
end
if ( userdata ) then
iFlags = bit.bor( iFlags, FCVAR_USERINFO )
end
return CreateConVar( name, default, iFlags, helptext, min, max )
end
--[[---------------------------------------------------------
Convar access functions
-----------------------------------------------------------]]
local ConVarCache = {}
function GetConVar( name )
local c = ConVarCache[ name ]
if ( !c ) then
c = GetConVar_Internal( name )
if ( !c ) then
return
end
ConVarCache[ name ] = c
end
return c
end
function GetConVarNumber( name )
if ( name == "maxplayers" ) then return game.MaxPlayers() end -- Backwards compatibility
local c = GetConVar( name )
return ( c and c:GetFloat() ) or 0
end
function GetConVarString( name )
if ( name == "maxplayers" ) then return tostring( game.MaxPlayers() ) end -- ew
local c = GetConVar( name )
return ( c and c:GetString() ) or ""
end