Untitled diff

Created Diff never expires
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
Improved Stacker
Improved Stacker
File name:
File name:
stacker.lua
stacker.lua
Author:
Author:
Original - OverloadUT
Original - OverloadUT
Updated for GMod 13 - Marii
Updated for GMod 13 - Marii
Cleaned and optimized - Mista Tea
Cleaned and optimized - Mista Tea
Changelog:
Changelog:
- Added to GitHub May 27th, 2014
- Added to GitHub May 27th, 2014
- Added to Workshop May 28th, 2014
- Added to Workshop May 28th, 2014
- Massive overhaul Jun 5th, 2014
- Massive overhaul Jun 5th, 2014
- Large update Jul 24th, 2014
- Large update Jul 24th, 2014
- Optimizations Aug 12th, 2014
- Optimizations Aug 12th, 2014
- Bug fixes/features Jun 30th, 2015
- Bug fixes/features Jun 30th, 2015
- Bug fixes Jul 11th, 2015
- Bug fixes Jul 11th, 2015
Fixes:
Fixes:
- Prevents crash from players using very high X/Y/Z offset values.
- Prevents crash from players using very high X/Y/Z offset values.
- Prevents crash from players using very high P/Y/R rotate values.
- Prevents crash from players using very high P/Y/R rotate values.
- Prevents crash from very specific constraint settings.
- Prevents crash from very specific constraint settings.
- Fixed the halo option for ghosted props not working.
- Fixed the halo option for ghosted props not working.
- Fixed massive FPS drop from halos being rendered in a Think hook instead of a PreDrawHalos hooks.
- Fixed massive FPS drop from halos being rendered in a Think hook instead of a PreDrawHalos hooks.
- Had to move back to using TOOL:Think
- Had to move back to using TOOL:Think
- Fixed materials and colors being saved when duping stacked props.
- Fixed materials and colors being saved when duping stacked props.
Tweaks:
Tweaks:
- Added convenience functions to retrieve the client convars.
- Added convenience functions to retrieve the client convars.
- Added option to enable/disable automatically applying materials to the stacked props.
- Added option to enable/disable automatically applying materials to the stacked props.
- Added option to enable/disable automatically applying colors to the stacked props.
- Added option to enable/disable automatically applying colors to the stacked props.
- Added option to enable/disable automatically applying physical properties (gravity, physics material, weight) to the stacked props.
- Added option to enable/disable automatically applying physical properties (gravity, physics material, weight) to the stacked props.
- Added support for props with multiple skins.
- Added support for props with multiple skins.
- Added support for external prop protections/anti-spam addons with the StackerEntity hook.
- Added support for external prop protections/anti-spam addons with the StackerEntity hook.
- Modified NoCollide to actually no-collide each stacker prop with every other prop in the stack.
- Modified NoCollide to actually no-collide each stacker prop with every other prop in the stack.
- Added console variables for server operators to limit various parts of stacker.
- Added console variables for server operators to limit various parts of stacker.
> stacker_max_total <-inf/inf> (less than 0 == no limit)
> stacker_max_total <-inf/inf> (less than 0 == no limit)
> stacker_max_count <-inf/inf> (less than 0 == no limit)
> stacker_max_count <-inf/inf> (less than 0 == no limit)
> stacker_max_offsetx <-inf/inf>
> stacker_max_offsetx <-inf/inf>
> stacker_max_offsety <-inf/inf>
> stacker_max_offsety <-inf/inf>
> stacker_max_offsetz <-inf/inf>
> stacker_max_offsetz <-inf/inf>
> stacker_stayinworld <0/1>
> stacker_stayinworld <0/1>
> stacker_force_weld <0/1>
> stacker_force_weld <0/1>
> stacker_force_freeze <0/1>
> stacker_force_freeze <0/1>
> stacker_force_nocollide <0/1>
> stacker_force_nocollide <0/1>
> stacker_delay <0/inf>
> stacker_delay <0/inf>


- Added console commands for server admins to control the console variables that limit stacker.
- Added console commands for server admins to control the console variables that limit stacker.
> stacker_set_maxtotal <-inf/inf> (less than 0 == no limit)
> stacker_set_maxtotal <-inf/inf> (less than 0 == no limit)
> stacker_set_maxcount <-inf/inf> (less than 0 == no limit)
> stacker_set_maxcount <-inf/inf> (less than 0 == no limit)
> stacker_set_maxoffset <-inf/inf>
> stacker_set_maxoffset <-inf/inf>
> stacker_set_maxoffsetx <-inf/inf>
> stacker_set_maxoffsetx <-inf/inf>
> stacker_set_maxoffsety <-inf/inf>
> stacker_set_maxoffsety <-inf/inf>
> stacker_set_maxoffsetz <-inf/inf>
> stacker_set_maxoffsetz <-inf/inf>
> stacker_set_stayinworld <0/1>
> stacker_set_stayinworld <0/1>
> stacker_set_weld <0/1>
> stacker_set_weld <0/1>
> stacker_set_freeze <0/1>
> stacker_set_freeze <0/1>
> stacker_set_nocollide <0/1>
> stacker_set_nocollide <0/1>
> stacker_set_delay <0/inf>
> stacker_set_delay <0/inf>


----------------------------------------------------------------------------]]
----------------------------------------------------------------------------]]


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Localized Functions & Variables
-- Localized Functions & Variables
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


-- localizing global functions/tables is an encouraged practice that improves code efficiency,
-- localizing global functions/tables is an encouraged practice that improves code efficiency,
-- since accessing a local value is considerably faster than a global value
-- since accessing a local value is considerably faster than a global value
local bit = bit
local bit = bit
local util = util
local util = util
local math = math
local math = math
local undo = undo
local undo = undo
local halo = halo
local halo = halo
local game = game
local game = game
local ents = ents
local ents = ents
local pairs = pairs
local pairs = pairs
local table = table
local table = table
local Angle = Angle
local Angle = Angle
local Color = Color
local Color = Color
local Vector = Vector
local Vector = Vector
local IsValid = IsValid
local IsValid = IsValid
local language = language
local language = language
local tonumber = tonumber
local tonumber = tonumber
local constraint = constraint
local constraint = constraint
local concommand = concommand
local concommand = concommand
local LocalPlayer = LocalPlayer
local LocalPlayer = LocalPlayer
local CreateConVar = CreateConVar
local CreateConVar = CreateConVar
local GetConVarNumber = GetConVarNumber
local GetConVarNumber = GetConVarNumber
local RunConsoleCommand = RunConsoleCommand
local RunConsoleCommand = RunConsoleCommand


local MOVETYPE_NONE = MOVETYPE_NONE
local MOVETYPE_NONE = MOVETYPE_NONE
local SOLID_VPHYSICS = SOLID_VPHYSICS
local SOLID_VPHYSICS = SOLID_VPHYSICS
local RENDERMODE_TRANSALPHA = RENDERMODE_TRANSALPHA
local RENDERMODE_TRANSALPHA = RENDERMODE_TRANSALPHA


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Tool Settings
-- Tool Settings
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


TOOL.Category = "Construction"
TOOL.Category = "Construction"
TOOL.Name = "#Tool.stacker.name"
TOOL.Name = "#Tool.stacker.name"
TOOL.Command = nil
TOOL.Command = nil
TOOL.ConfigName = ""
TOOL.ConfigName = ""


TOOL.ClientConVar[ "mode" ] = "1"
TOOL.ClientConVar[ "mode" ] = "1"
TOOL.ClientConVar[ "dir" ] = "1"
TOOL.ClientConVar[ "dir" ] = "1"
TOOL.ClientConVar[ "count" ] = "1"
TOOL.ClientConVar[ "count" ] = "1"
TOOL.ClientConVar[ "freeze" ] = "1"
TOOL.ClientConVar[ "freeze" ] = "1"
TOOL.ClientConVar[ "weld" ] = "1"
TOOL.ClientConVar[ "weld" ] = "1"
TOOL.ClientConVar[ "nocollide" ] = "1"
TOOL.ClientConVar[ "nocollide" ] = "1"
TOOL.ClientConVar[ "ghostall" ] = "1"
TOOL.ClientConVar[ "ghostall" ] = "1"
TOOL.ClientConVar[ "material" ] = "1"
TOOL.ClientConVar[ "material" ] = "1"
TOOL.ClientConVar[ "physprop" ] = "1"
TOOL.ClientConVar[ "physprop" ] = "1"
TOOL.ClientConVar[ "color" ] = "1"
TOOL.ClientConVar[ "color" ] = "1"
TOOL.ClientConVar[ "model" ] = ""
TOOL.ClientConVar[ "model" ] = ""
TOOL.ClientConVar[ "offsetx" ] = "0"
TOOL.ClientConVar[ "offsetx" ] = "0"
TOOL.ClientConVar[ "offsety" ] = "0"
TOOL.ClientConVar[ "offsety" ] = "0"
TOOL.ClientConVar[ "offsetz" ] = "0"
TOOL.ClientConVar[ "offsetz" ] = "0"
TOOL.ClientConVar[ "rotp" ] = "0"
TOOL.ClientConVar[ "rotp" ] = "0"
TOOL.ClientConVar[ "roty" ] = "0"
TOOL.ClientConVar[ "roty" ] = "0"
TOOL.ClientConVar[ "rotr" ] = "0"
TOOL.ClientConVar[ "rotr" ] = "0"
TOOL.ClientConVar[ "recalc" ] = "0"
TOOL.ClientConVar[ "recalc" ] = "0"
TOOL.ClientConVar[ "halo" ] = "0"
TOOL.ClientConVar[ "halo" ] = "0"
TOOL.ClientConVar[ "halo_r" ] = "0"
TOOL.ClientConVar[ "halo_r" ] = "0"
TOOL.ClientConVar[ "halo_g" ] = "200"
TOOL.ClientConVar[ "halo_g" ] = "200"
TOOL.ClientConVar[ "halo_b" ] = "190"
TOOL.ClientConVar[ "halo_b" ] = "190"
TOOL.ClientConVar[ "halo_a" ] = "255"
TOOL.ClientConVar[ "halo_a" ] = "255"


if ( CLIENT ) then
if ( CLIENT ) then


language.Add( "Tool.stacker.name", "Stacker - Improved" )
language.Add( "Tool.stacker.name", "Stacker - Improved" )
language.Add( "Tool.stacker.desc", "Easily stack duplicated props in any direction" )
language.Add( "Tool.stacker.desc", "Easily stack duplicated props in any direction" )
language.Add( "Tool.stacker.0", "Click to stack the prop you're pointing at" )
language.Add( "Tool.stacker.0", "Click to stack the prop you're pointing at" )
language.Add( "Undone_stacker", "Undone stacked prop(s)" )
language.Add( "Undone_stacker", "Undone stacked prop(s)" )
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Enumerations
-- Enumerations
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


local MODE_WORLD = 1 -- stacking relative to the world
local MODE_WORLD = 1 -- stacking relative to the world
local MODE_PROP = 2 -- stacking relative to the prop
local MODE_PROP = 2 -- stacking relative to the prop


local DIRECTION_UP = 1
local DIRECTION_UP = 1
local DIRECTION_DOWN = 2
local DIRECTION_DOWN = 2
local DIRECTION_FRONT = 3
local DIRECTION_FRONT = 3
local DIRECTION_BEHIND = 4
local DIRECTION_BEHIND = 4
local DIRECTION_RIGHT = 5
local DIRECTION_RIGHT = 5
local DIRECTION_LEFT = 6
local DIRECTION_LEFT = 6


local VECTOR_ZERO = Vector( 0, 0, 0 )
local VECTOR_ZERO = Vector( 0, 0, 0 )


local ANGLE_ZERO = Angle( 0, 0, 0 )
local ANGLE_ZERO = Angle( 0, 0, 0 )
local ANGLE_FRONT = ANGLE_ZERO:Forward()
local ANGLE_FRONT = ANGLE_ZERO:Forward()
local ANGLE_RIGHT = ANGLE_ZERO:Right()
local ANGLE_RIGHT = ANGLE_ZERO:Right()
local ANGLE_UP = ANGLE_ZERO:Up()
local ANGLE_UP = ANGLE_ZERO:Up()
local ANGLE_BEHIND = -ANGLE_FRONT
local ANGLE_BEHIND = -ANGLE_FRONT
local ANGLE_LEFT = -ANGLE_RIGHT
local ANGLE_LEFT = -ANGLE_RIGHT
local ANGLE_DOWN = -ANGLE_UP
local ANGLE_DOWN = -ANGLE_UP


local TRANSPARENT = Color( 255, 255, 255, 150 )
local TRANSPARENT = Color( 255, 255, 255, 150 )


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Console Variables
-- Console Variables
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


local cvarMaxTotal = CreateConVar( "stacker_max_total", -1, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max amount of props that a player can have spawned from stacker
local cvarMaxTotal = CreateConVar( "stacker_max_total", -1, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max amount of props that a player can have spawned from stacker
local cvarMaxCount = CreateConVar( "stacker_max_count", 30, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max amount of props that can be stacked at a time
local cvarMaxCount = CreateConVar( "stacker_max_count", 30, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max amount of props that can be stacked at a time
local cvarMaxOffX = CreateConVar( "stacker_max_offsetx", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the x plane that stacked props can be offset (for individual control)
local cvarMaxOffX = CreateConVar( "stacker_max_offsetx", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the x plane that stacked props can be offset (for individual control)
local cvarMaxOffY = CreateConVar( "stacker_max_offsety", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the y plane that stacked props can be offset (for individual control)
local cvarMaxOffY = CreateConVar( "stacker_max_offsety", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the y plane that stacked props can be offset (for individual control)
local cvarMaxOffZ = CreateConVar( "stacker_max_offsetz", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the z plane that stacked props can be offset (for individual control)
local cvarMaxOffZ = CreateConVar( "stacker_max_offsetz", 500, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- defines the max distance on the z plane that stacked props can be offset (for individual control)
local cvarStayInWorld = CreateConVar( "stacker_stayinworld", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be restricted to spawning inside the world or not (addresses possible crashes)
local cvarStayInWorld = CreateConVar( "stacker_stayinworld", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be restricted to spawning inside the world or not (addresses possible crashes)
local cvarFreeze = CreateConVar( "stacker_force_freeze", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn frozen or not
local cvarFreeze = CreateConVar( "stacker_force_freeze", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn frozen or not
local cvarWeld = CreateConVar( "stacker_force_weld", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn welded or not
local cvarWeld = CreateConVar( "stacker_force_weld", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn welded or not
local cvarNoCollide = CreateConVar( "stacker_force_nocollide", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn nocollided or not
local cvarNoCollide = CreateConVar( "stacker_force_nocollide", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines whether props should be forced to spawn nocollided or not
local cvarDelay = CreateConVar( "stacker_delay", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines the amount of time that must pass before a player can use stacker again
local cvarDelay = CreateConVar( "stacker_delay", 0, bit.bor( FCVAR_NOTIFY, FCVAR_REPLICATED, FCVAR_SERVER_CAN_EXECUTE ) ) -- determines the amount of time that must pass before a player can use stacker again


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Console Commands
-- Console Commands
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


if ( CLIENT ) then
if ( CLIENT ) then
local function ResetOffsets( ply, command, arguments )
local function ResetOffsets( ply, command, arguments )
-- Reset all of the offset options to 0 and adv options to 1
-- Reset all of the offset options to 0 and adv options to 1
LocalPlayer():ConCommand( "stacker_offsetx 0" )
LocalPlayer():ConCommand( "stacker_offsetx 0" )
LocalPlayer():ConCommand( "stacker_offsety 0" )
LocalPlayer():ConCommand( "stacker_offsety 0" )
LocalPlayer():ConCommand( "stacker_offsetz 0" )
LocalPlayer():ConCommand( "stacker_offsetz 0" )
LocalPlayer():ConCommand( "stacker_rotp 0" )
LocalPlayer():ConCommand( "stacker_rotp 0" )
LocalPlayer():ConCommand( "stacker_roty 0" )
LocalPlayer():ConCommand( "stacker_roty 0" )
LocalPlayer():ConCommand( "stacker_rotr 0" )
LocalPlayer():ConCommand( "stacker_rotr 0" )
--LocalPlayer():ConCommand( "stacker_recalc 1" )
--LocalPlayer():ConCommand( "stacker_recalc 1" )
--LocalPlayer():ConCommand( "stacker_ghostall 1" )
--LocalPlayer():ConCommand( "stacker_ghostall 1" )
--LocalPlayer():ConCommand( "stacker_material 1" )
--LocalPlayer():ConCommand( "stacker_material 1" )
--LocalPlayer():ConCommand( "stacker_color 1" )
--LocalPlayer():ConCommand( "stacker_color 1" )
--LocalPlayer():ConCommand( "stacker_physprop 1" )
--LocalPlayer():ConCommand( "stacker_physprop 1" )
--LocalPlayer():ConCommand( "stacker_halo 1" )
--LocalPlayer():ConCommand( "stacker_halo 1" )
end
end
concommand.Add( "stacker_resetoffsets", ResetOffsets )
concommand.Add( "stacker_resetoffsets", ResetOffsets )
elseif ( SERVER ) then
elseif ( SERVER ) then


local function ValidateCommand( ply, arg )
local function ValidateCommand( ply, arg )
if ( IsValid( ply ) and !ply:IsAdmin() ) then ply:PrintMessage( HUD_PRINTTALK, "You must be in the 'admin' usergroup to change this cvar" ) return false end
if ( IsValid( ply ) and !ply:IsAdmin() ) then ply:PrintMessage( HUD_PRINTTALK, "You must be in the 'admin' usergroup to change this cvar" ) return false end
if ( !tonumber( arg ) ) then return false else return true end
if ( !tonumber( arg ) ) then return false else return true end
end
end
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxtotal", function( ply, cmd, args )
concommand.Add( "stacker_set_maxtotal", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end


RunConsoleCommand( "stacker_max_total", args[1] )
RunConsoleCommand( "stacker_max_total", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxcount", function( ply, cmd, args )
concommand.Add( "stacker_set_maxcount", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_max_count", args[1] )
RunConsoleCommand( "stacker_max_count", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxoffset", function( ply, cmd, args )
concommand.Add( "stacker_set_maxoffset", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_max_offsetx", args[1] )
RunConsoleCommand( "stacker_max_offsetx", args[1] )
RunConsoleCommand( "stacker_max_offsety", args[1] )
RunConsoleCommand( "stacker_max_offsety", args[1] )
RunConsoleCommand( "stacker_max_offsetz", args[1] )
RunConsoleCommand( "stacker_max_offsetz", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxoffsetx", function( ply, cmd, args )
concommand.Add( "stacker_set_maxoffsetx", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_max_offsetx", args[1] )
RunConsoleCommand( "stacker_max_offsetx", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxoffsety", function( ply, cmd, args )
concommand.Add( "stacker_set_maxoffsety", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_max_offsety", args[1] )
RunConsoleCommand( "stacker_max_offsety", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_maxoffsetz", function( ply, cmd, args )
concommand.Add( "stacker_set_maxoffsetz", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_max_offsetz", args[1] )
RunConsoleCommand( "stacker_max_offsetz", args[1] )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_stayinworld", function( ply, cmd, args )
concommand.Add( "stacker_set_stayinworld", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_stayinworld", ( tobool( args[1] ) and 1 ) or 0 )
RunConsoleCommand( "stacker_stayinworld", ( tobool( args[1] ) and 1 ) or 0 )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_freeze", function( ply, cmd, args )
concommand.Add( "stacker_set_freeze", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_force_freeze", ( tobool( args[1] ) and 1 ) or 0 )
RunConsoleCommand( "stacker_force_freeze", ( tobool( args[1] ) and 1 ) or 0 )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_weld", function( ply, cmd, args )
concommand.Add( "stacker_set_weld", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_force_weld", ( tobool( args[1] ) and 1 ) or 0 )
RunConsoleCommand( "stacker_force_weld", ( tobool( args[1] ) and 1 ) or 0 )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_nocollide", function( ply, cmd, args )
concommand.Add( "stacker_set_nocollide", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_force_nocollide", ( tobool( args[1] ) and 1 ) or 0 )
RunConsoleCommand( "stacker_force_nocollide", ( tobool( args[1] ) and 1 ) or 0 )
end )
end )
--[[-------------------------------------------------------------]]--
--[[-------------------------------------------------------------]]--
concommand.Add( "stacker_set_delay", function( ply, cmd, args )
concommand.Add( "stacker_set_delay", function( ply, cmd, args )
if ( !ValidateCommand( ply, args[1] ) ) then return false end
if ( !ValidateCommand( ply, args[1] ) ) then return false end
RunConsoleCommand( "stacker_delay", args[1] )
RunConsoleCommand( "stacker_delay", args[1] )
end )
end )
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Hooks
-- Hooks
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- GAMEMODE:PlayerInitialSpawn()
-- GAMEMODE:PlayerInitialSpawn()
--
--
-- Sets the newly connected player's total stacker ents to 0.
-- Sets the newly connected player's total stacker ents to 0.
-- See TOOL:IsExceedingMax() below for more details
-- See TOOL:IsExceedingMax() below for more details
--]]--
--]]--
hook.Add( "PlayerInitialSpawn", "StackerSetTotalEnts", function( ply )
hook.Add( "PlayerInitialSpawn", "StackerSetTotalEnts", function( ply )
ply.TotalStackerEnts = 0
ply.TotalStackerEnts = 0
end )
end )




--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Convenience Functions
-- Convenience Functions
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- GetGhostStack(), SetGhostStack( table )
-- GetGhostStack(), SetGhostStack( table )
--
--
-- Gets and sets the table of ghosted props in the stack.
-- Gets and sets the table of ghosted props in the stack.
--]]--
--]]--
local function GetGhostStack() return GhostStack end
local function GetGhostStack() return GhostStack end
local function SetGhostStack( tbl ) GhostStack = tbl end
local function SetGhostStack( tbl ) GhostStack = tbl end




--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:IsExceedingMax()
-- TOOL:IsExceedingMax()
--
--
-- Returns true if the player has exceeded the allowed maximum stacker prop count.
-- Returns true if the player has exceeded the allowed maximum stacker prop count.
--
--
-- The total number of props a player has spawned from the Stacker tool is recorded
-- The total number of props a player has spawned from the Stacker tool is recorded
-- on them via ply.TotalStackerEnts. When a player removes a prop that has been spawned
-- on them via ply.TotalStackerEnts. When a player removes a prop that has been spawned
-- from Stacker, the total count is decreased by 1.
-- from Stacker, the total count is decreased by 1.
--
--
-- In combination with the stacker_max_total cvar, this function can prevent players
-- In combination with the stacker_max_total cvar, this function can prevent players
-- from crashing the server by stacking dozens of welded props and unfreezing them.
-- from crashing the server by stacking dozens of welded props and unfreezing them.
--
--
-- By default, the number of stacker props is -1 (infinite). This is done to not interfere
-- By default, the number of stacker props is -1 (infinite). This is done to not interfere
-- with servers that don't want to limit the number of Stacker props a player can spawn directly.
-- with servers that don't want to limit the number of Stacker props a player can spawn directly.
-- They may still hit cvars like sbox_maxprops before ever hitting stacker_max_total.
-- They may still hit cvars like sbox_maxprops before ever hitting stacker_max_total.
--
--
-- As an example case, if players are crashing your servers by spawning 50 welded chairs
-- As an example case, if players are crashing your servers by spawning 50 welded chairs
-- and unfreezing them all at once, you can set stacker_max_total to 30 so that at any
-- and unfreezing them all at once, you can set stacker_max_total to 30 so that at any
-- given time they can only have 30 props created by Stacker. Trying to stack any more props
-- given time they can only have 30 props created by Stacker. Trying to stack any more props
-- would give the player an error message.
-- would give the player an error message.
--]]--
--]]--
function TOOL:IsExceedingMax()
function TOOL:IsExceedingMax()
return cvarMaxTotal:GetInt() >= 0 and self:GetTotalStackerEnts() >= cvarMaxTotal:GetInt()
return cvarMaxTotal:GetInt() >= 0 and self:GetTotalStackerEnts() >= cvarMaxTotal:GetInt()
end
end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:SetTotalStackerEnts()
-- TOOL:SetTotalStackerEnts()
--
--
-- Sets the total number of active stacker props spawned by the player.
-- Sets the total number of active stacker props spawned by the player.
--]]--
--]]--
function TOOL:SetTotalStackerEnts( num )
function TOOL:SetTotalStackerEnts( num )
self:GetOwner().TotalStackerEnts = num
self:GetOwner().TotalStackerEnts = num
end
end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetTotalStackerEnts()
-- TOOL:GetTotalStackerEnts()
--
--
-- Retrieves the total number of active stacker props spawned by the player.
-- Retrieves the total number of active stacker props spawned by the player.
--]]--
--]]--
function TOOL:GetTotalStackerEnts()
function TOOL:GetTotalStackerEnts()
return self:GetOwner().TotalStackerEnts or 0
return self:GetOwner().TotalStackerEnts or 0
end
end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:IncrementStackerEnts()
-- TOOL:IncrementStackerEnts()
--
--
-- Increases the number of active stacker props spawned by the player by 1.
-- Increases the number of active stacker props spawned by the player by 1.
--]]--
--]]--
function TOOL:IncrementStackerEnts()
function TOOL:IncrementStackerEnts()
self:SetTotalStackerEnts( self:GetTotalStackerEnts() + 1 )
self:SetTotalStackerEnts( self:GetTotalStackerEnts() + 1 )
end
end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:DecrementStackerEnts()
-- TOOL:DecrementStackerEnts()
--
--
-- Decreases the number of active stacked props spawned by the player by 1.
-- Decreases the number of active stacked props spawned by the player by 1.
--]]--
--]]--
function TOOL:DecrementStackerEnts()
function TOOL:DecrementStackerEnts()
self:SetTotalStackerEnts( self:GetTotalStackerEnts() - 1 )
self:SetTotalStackerEnts( self:GetTotalStackerEnts() - 1 )
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetCount()
-- TOOL:GetCount()
--
--
-- Gets the amount of props that the client wants to stack at once.
-- Gets the amount of props that the client wants to stack at once.
--]]--
--]]--
function TOOL:GetCount()
function TOOL:GetCount()
return self:GetClientNumber( "count" )
return self:GetClientNumber( "count" )
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetMaxCount()
-- TOOL:GetMaxCount()
--
--
-- Gets the maximum amount of props that can be stacked at a time.
-- Gets the maximum amount of props that can be stacked at a time.
--]]--
--]]--
function TOOL:GetMaxCount()
function TOOL:GetMaxCount()
return cvarMaxCount:GetInt()
return cvarMaxCount:GetInt()
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetDirection()
-- TOOL:GetDirection()
--
--
-- Gets the direction to stack the props.
-- Gets the direction to stack the props.
--]]--
--]]--
function TOOL:GetDirection() return self:GetClientNumber( "dir" ) end
function TOOL:GetDirection() return self:GetClientNumber( "dir" ) end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetStackerMode()
-- TOOL:GetStackerMode()
--
--
-- Gets the stacker mode (1 = MODE_WORLD, 2 = MODE_PROP).
-- Gets the stacker mode (1 = MODE_WORLD, 2 = MODE_PROP).
--]]--
--]]--
function TOOL:GetStackerMode() return self:GetClientNumber( "mode" ) end
function TOOL:GetStackerMode() return self:GetClientNumber( "mode" ) end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetOffsetX(), TOOL:GetOffsetY(), TOOL:GetOffsetZ(), TOOL:GetOffsetVector()
-- TOOL:GetOffsetX(), TOOL:GetOffsetY(), TOOL:GetOffsetZ(), TOOL:GetOffsetVector()
--
--
-- Gets the distance to offset the position of the stacked props.
-- Gets the distance to offset the position of the stacked props.
-- These values are clamped to prevent server crashes from players
-- These values are clamped to prevent server crashes from players
-- using very high offset values.
-- using very high offset values.
--]]--
--]]--
function TOOL:GetOffsetX() return math.Clamp( self:GetClientNumber( "offsetx" ), - cvarMaxOffX:GetInt(), cvarMaxOffX:GetInt() ) end
function TOOL:GetOffsetX() return math.Clamp( self:GetClientNumber( "offsetx" ), - cvarMaxOffX:GetInt(), cvarMaxOffX:GetInt() ) end
function TOOL:GetOffsetY() return math.Clamp( self:GetClientNumber( "offsety" ), - cvarMaxOffY:GetInt(), cvarMaxOffY:GetInt() ) end
function TOOL:GetOffsetY() return math.Clamp( self:GetClientNumber( "offsety" ), - cvarMaxOffY:GetInt(), cvarMaxOffY:GetInt() ) end
function TOOL:GetOffsetZ() return math.Clamp( self:GetClientNumber( "offsetz" ), - cvarMaxOffZ:GetInt(), cvarMaxOffZ:GetInt() ) end
function TOOL:GetOffsetZ() return math.Clamp( self:GetClientNumber( "offsetz" ), - cvarMaxOffZ:GetInt(), cvarMaxOffZ:GetInt() ) end


function TOOL:GetOffsetVector() return Vector( self:GetOffsetX(), self:GetOffsetY(), self:GetOffsetZ() ) end
function TOOL:GetOffsetVector() return Vector( self:GetOffsetX(), self:GetOffsetY(), self:GetOffsetZ() ) end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetRotateP(), TOOL:GetRotateY(), TOOL:GetRotateR(), TOOL:GetRotateAngle()
-- TOOL:GetRotateP(), TOOL:GetRotateY(), TOOL:GetRotateR(), TOOL:GetRotateAngle()
--
--
-- Gets the value to rotate the angle of the stacked props.
-- Gets the value to rotate the angle of the stacked props.
-- These values are clamped to prevent server crashes from players
-- These values are clamped to prevent server crashes from players
-- using very high rotation values.
-- using very high rotation values.
--]]--
--]]--
function TOOL:GetRotateP() return math.Clamp( self:GetClientNumber( "rotp" ), -360, 360 ) end
function TOOL:GetRotateP() return math.Clamp( self:GetClientNumber( "rotp" ), -360, 360 ) end
function TOOL:GetRotateY() return math.Clamp( self:GetClientNumber( "roty" ), -360, 360 ) end
function TOOL:GetRotateY() return math.Clamp( self:GetClientNumber( "roty" ), -360, 360 ) end
function TOOL:GetRotateR() return math.Clamp( self:GetClientNumber( "rotr" ), -360, 360 ) end
function TOOL:GetRotateR() return math.Clamp( self:GetClientNumber( "rotr" ), -360, 360 ) end


function TOOL:GetRotateAngle() return Angle( self:GetRotateP(), self:GetRotateY(), self:GetRotateR() ) end
function TOOL:GetRotateAngle() return Angle( self:GetRotateP(), self:GetRotateY(), self:GetRotateR() ) end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldFreeze()
-- TOOL:ShouldFreeze()
--
--
-- Returns true if the stacked props should be spawned frozen.
-- Returns true if the stacked props should be spawned frozen.
--]]--
--]]--
function TOOL:ShouldApplyFreeze() return self:GetClientNumber( "freeze" ) == 1 end
function TOOL:ShouldApplyFreeze() return self:GetClientNumber( "freeze" ) == 1 end
function TOOL:ShouldForceFreeze() return cvarFreeze:GetBool() end
function TOOL:ShouldForceFreeze() return cvarFreeze:GetBool() end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldWeld()
-- TOOL:ShouldWeld()
--
--
-- Returns true if the stacked props should be welded together.
-- Returns true if the stacked props should be welded together.
--]]--
--]]--
function TOOL:ShouldApplyWeld() return self:GetClientNumber( "weld" ) == 1 end
function TOOL:ShouldApplyWeld() return self:GetClientNumber( "weld" ) == 1 end
function TOOL:ShouldForceWeld() return cvarWeld:GetBool() end
function TOOL:ShouldForceWeld() return cvarWeld:GetBool() end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldNoCollide()
-- TOOL:ShouldNoCollide()
--
--
-- Returns true if the stacked props should be nocollided with each other.
-- Returns true if the stacked props should be nocollided with each other.
--]]--
--]]--
function TOOL:ShouldApplyNoCollide() return self:GetClientNumber( "nocollide" ) == 1 end
function TOOL:ShouldApplyNoCollide() return self:GetClientNumber( "nocollide" ) == 1 end
function TOOL:ShouldForceNoCollide() return cvarNoCollide:GetBool() end
function TOOL:ShouldForceNoCollide() return cvarNoCollide:GetBool() end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldStackRelative()
-- TOOL:ShouldStackRelative()
--
--
-- Returns true if the stacked props should be stacked relative to the new rotation.
-- Returns true if the stacked props should be stacked relative to the new rotation.
-- Using this setting will allow you to create curved structures out of props.
-- Using this setting will allow you to create curved structures out of props.
--]]--
--]]--
function TOOL:ShouldStackRelative() return self:GetClientNumber( "recalc" ) == 1 end
function TOOL:ShouldStackRelative() return self:GetClientNumber( "recalc" ) == 1 end
--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldGhostAll()
-- TOOL:ShouldGhostAll()
--
--
-- Returns true if the stacked props should all be ghosted or if only the
-- Returns true if the stacked props should all be ghosted or if only the
-- first stacked prop should be ghosted.
-- first stacked prop should be ghosted.
--]]--
--]]--
function TOOL:ShouldGhostAll() return self:GetClientNumber( "ghostall" ) == 1 end
function TOOL:ShouldGhostAll() return self:GetClientNumber( "ghostall" ) == 1 end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldAddHalos(), TOOL:GetHaloR(), TOOL:GetHaloG(), TOOL:GetHaloB() TOOL:GetHaloA() TOOL:GetHaloColor()
-- TOOL:ShouldAddHalos(), TOOL:GetHaloR(), TOOL:GetHaloG(), TOOL:GetHaloB() TOOL:GetHaloA() TOOL:GetHaloColor()
--
--
-- Returns true if the stacked props should have halos drawn on them for added visibility.
-- Returns true if the stacked props should have halos drawn on them for added visibility.
-- Gets the RGBA values of the halo color.
-- Gets the RGBA values of the halo color.
--]]--
--]]--
function TOOL:ShouldAddHalos() return self:GetClientNumber( "halo" ) == 1 end
function TOOL:ShouldAddHalos() return self:GetClientNumber( "halo" ) == 1 end


function TOOL:GetHaloR() return math.Clamp( self:GetClientNumber( "halo_r" ), 0, 255 ) end
function TOOL:GetHaloR() return math.Clamp( self:GetClientNumber( "halo_r" ), 0, 255 ) end
function TOOL:GetHaloG() return math.Clamp( self:GetClientNumber( "halo_g" ), 0, 255 ) end
function TOOL:GetHaloG() return math.Clamp( self:GetClientNumber( "halo_g" ), 0, 255 ) end
function TOOL:GetHaloB() return math.Clamp( self:GetClientNumber( "halo_b" ), 0, 255 ) end
function TOOL:GetHaloB() return math.Clamp( self:GetClientNumber( "halo_b" ), 0, 255 ) end
function TOOL:GetHaloA() return math.Clamp( self:GetClientNumber( "halo_a" ), 0, 255 ) end
function TOOL:GetHaloA() return math.Clamp( self:GetClientNumber( "halo_a" ), 0, 255 ) end


function TOOL:GetHaloColor()
function TOOL:GetHaloColor()
return Color( self:GetHaloR(), self:GetHaloG(), self:GetHaloB(), self:GetHaloA() )
return Color( self:GetHaloR(), self:GetHaloG(), self:GetHaloB(), self:GetHaloA() )
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldApplyMaterial()
-- TOOL:ShouldApplyMaterial()
--
--
-- Returns true if the stacked props should have the original prop's material applied.
-- Returns true if the stacked props should have the original prop's material applied.
--]]--
--]]--
function TOOL:ShouldApplyMaterial() return self:GetClientNumber( "material" ) == 1 end
function TOOL:ShouldApplyMaterial() return self:GetClientNumber( "material" ) == 1 end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldApplyColor()
-- TOOL:ShouldApplyColor()
--
--
-- Returns true if the stacked props should have the original prop's color applied.
-- Returns true if the stacked props should have the original prop's color applied.
--]]--
--]]--
function TOOL:ShouldApplyColor() return self:GetClientNumber( "color" ) == 1 end
function TOOL:ShouldApplyColor() return self:GetClientNumber( "color" ) == 1 end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:ShouldApplyPhysicalProperties()
-- TOOL:ShouldApplyPhysicalProperties()
--
--
-- Returns true if the stacked props should have the original prop's physicsl properties
-- Returns true if the stacked props should have the original prop's physicsl properties
-- applied, including gravity, physics material, and weight.
-- applied, including gravity, physics material, and weight.
--]]--
--]]--
function TOOL:ShouldApplyPhysicalProperties() return self:GetClientNumber( "physprop" ) == 1 end
function TOOL:ShouldApplyPhysicalProperties() return self:GetClientNumber( "physprop" ) == 1 end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- TOOL:GetDelay()
-- TOOL:GetDelay()
--
--
-- Returns the time in seconds that must pass before a player can use stacker again.
-- Returns the time in seconds that must pass before a player can use stacker again.
-- For example, if stacker_delay is set to 3, a player must wait 3 seconds in between each
-- For example, if stacker_delay is set to 3, a player must wait 3 seconds in between each
-- use of stacker's left click.
-- use of stacker's left click.
--]]--
--]]--
function TOOL:GetDelay() return cvarDelay:GetInt() end
function TOOL:GetDelay() return cvarDelay:GetInt() end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
-- Tool Functions
-- Tool Functions
--------------------------------------------------------------------------]]--
--------------------------------------------------------------------------]]--


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:Deploy()
-- TOOL:Deploy()
--
--
-- Called when the player brings out this tool.
-- Called when the player brings out this tool.
--]]--
--]]--
function TOOL:Deploy()
function TOOL:Deploy()
self:ReleaseGhostStack()
self:ReleaseGhostStack()
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:Holster()
-- TOOL:Holster()
--
--
-- Called when the player switches to a different tool.
-- Called when the player switches to a different tool.
--]]--
--]]--
function TOOL:Holster()
function TOOL:Holster()
self:ReleaseGhostStack()
self:ReleaseGhostStack()
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:OnRemove()
-- TOOL:OnRemove()
--
--
-- Should be called when the toolgun is somehow removed, but more than likely
-- Should be called when the toolgun is somehow removed, but more than likely
-- doesn't get called due to the way the gmod_tool was coded.
-- doesn't get called due to the way the gmod_tool was coded.
--]]--
--]]--
function TOOL:OnRemove()
function TOOL:OnRemove()
self:ReleaseGhostStack()
self:ReleaseGhostStack()
end
end


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:OnDrop()
-- TOOL:OnDrop()
--
--
-- Should be called when when the toolgun is dropped, but more than likely
-- Should be called when when the toolgun is dropped, but more than likely
-- doesn't get called due to the way to gmod_tool was coded.
-- doesn't get called due to the way to gmod_tool was coded.
--]]--
--]]--
function TOOL:OnDrop()
function TOOL:OnDrop()
self:ReleaseGhostStack()
self:ReleaseGhostStack()
end
end






--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:Init()
-- TOOL:Init()
--
--
-- Called when a player initializes in the server (probably InitPostEntity).
-- Called when a player initializes in the server (probably InitPostEntity).
-- This is called only once and only during that time, meaning reloading this
-- This is called only once and only during that time, meaning reloading this
-- file will not call TOOL:Init() again.
-- file will not call TOOL:Init() again.
--
--
-- Since using hooks in STools is rather awkward when the hook function must use
-- Since using hooks in STools is rather awkward when the hook function must use
-- this tool's function, loading hooked functions here ensures that we can use
-- this tool's function, loading hooked functions here ensures that we can use
-- 'self' to refer to this tool object even after the TOOL global table has been made nil.
-- 'self' to refer to this tool object even after the TOOL global table has been made nil.
--]]--
--]]--
--[[if ( CLIENT ) then
--[[if ( CLIENT ) then
function TOOL:Init()
function TOOL:Init()
self:AddHalos()
self:AddHalos()
end
end
end]]
end]]


--[[--------------------------------------------------------------------------
--[[--------------------------------------------------------------------------
--
--
-- TOOL:AddHalos()
-- TOOL:AddHalos()
--
--
-- Loads the hook that draws halos on the gh
-- Loads the hook that draws halos on the gh