Skip to content

Instantly share code, notes, and snippets.

@OmegaExtern
Last active September 7, 2021 11:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save OmegaExtern/e481e0d5034a91363475 to your computer and use it in GitHub Desktop.
Save OmegaExtern/e481e0d5034a91363475 to your computer and use it in GitHub Desktop.
Garry's Mod. Stop players from going into skybox area/space on gm_flatgrass & gm_construct.
--[[-------------------------------------------------
Author: OmegaExtern <omegaextern@live.com>
License: MIT <https://opensource.org/licenses/MIT>
-----------------------------------------------------
To install, save this file in the following folder (create a folder if it does not exist, it is case-sensitive):
(Steam installation directory)\steamapps\common\GarrysMod\garrysmod\addons\protect-skybox-area\lua\autorun\server
Supported maps:
gm_construct
gm_flatgrass
---------------------------------------------------]]
local SupportedMaps, ActiveMap = {
--[[---------------------------------------------
local abs = math.abs
local Size = Vector( abs( Min.x - Max.x ), abs( Min.y - Max.y ), abs( Min.z - Max.z ) )
local Extents = Vector( Size.x / 2, Size.y / 2, Size.z / 2 )
local Center = Vector( Min.x + Extents.x, Min.y + Extents.y, Min.z + Extents.z )
-----------------------------------------------]]
gm_construct = { max = Vector( 15615.968750, 15103.968750, 15231.169922 ), min = Vector( -15103.968750, -15103.968750, 10367.232422 ) },
gm_flatgrass = { max = Vector( 8191.96875, 8191.96875, -13312.03125 ), min = Vector( -8191.96875, -8191.96875, -15871.96875 ) }
-- Feel free to add more maps...
}, game.GetMap()
if ( !SERVER || !SupportedMaps[ ActiveMap ] ) then
ErrorNoHalt( "Not serverside or unsupported map.\n" )
return
end
do
local PlayerMeta = FindMetaTable( "Player" )
if ( !PlayerMeta ) then
ErrorNoHalt( "Could not find Player metatable.\n" )
return
end
--[[---------------------------------------------
! DO NOT EDIT ABOVE /!\ DO NOT EDIT ABOVE !
-----------------------------------------------]]
local AllowAdmins = false -- Boolean. Set to true to allow (super)admins to go into skybox; otherwise false.
local PrintNotification = true -- Boolean. Set to true to print a notification message that indicates whether a skybox is protected or not; otherwise false.
--[[---------------------------------------------
! DO NOT EDIT BELOW /!\ DO NOT EDIT BELOW !
-----------------------------------------------]]
local getlocal, getinfo, ActiveMapSkyboxBounds = debug.getlocal, debug.getinfo, SupportedMaps[ ActiveMap ]
function PlayerMeta.IntersectsWithSkybox( self )
assert( IsValid( self ) && isfunction( self.IsPlayer ) && self:IsPlayer(), Format( "bad argument #%i (%s) to '%s' (Player expected, got %s)", 1, getlocal( 1, 1 ), getinfo( 1, "n" ).name, type( self ) ) )
local plyMin, plyMax = self:LocalToWorld( self:OBBMins() ), self:LocalToWorld( self:OBBMaxs() )
return ( ( ( ( ( ActiveMapSkyboxBounds.min.x <= plyMax.x ) && ( ActiveMapSkyboxBounds.max.x >= plyMin.x ) ) && ( ( ActiveMapSkyboxBounds.min.y <= plyMax.y ) && ( ActiveMapSkyboxBounds.max.y >= plyMin.y ) ) ) && ( ActiveMapSkyboxBounds.min.z <= plyMax.z ) ) && ( ActiveMapSkyboxBounds.max.z >= plyMin.z ) )
end
local CreateTwoStateServerConVar = function( name, default, flags, helpText, funcOff, funcOn, notify, persist, forceExecution )
if ( !SERVER ) then
return
end
local funcName = getinfo( 1, 'n' ).name
assert( isstring( name ) && name:len() > 1, Format( "bad argument %d# to '%s' (string expected, got %s)", 1, funcName, type( name ) ) )
if ( !default || type( default ) == "nil" ) then
default = 0
elseif ( isstring( default ) ) then
default = tonumber( default ) || 0
elseif ( isfunction( default ) ) then
default = default()
end
assert( isnumber( default ), Format( "bad argument %d# to '%s' (number expected, got %s)", 2, funcName, type( default ) ) )
default = math.Clamp( math.floor( default ), 0, 1 )
assert( isnumber( flags ) || istable( flags ), Format( "bad argument %d# to '%s' (number or table expected, got %s)", 3, funcName, type( flags ) ) )
assert( isstring( helpText ), Format( "bad argument %d# to '%s' (number or table expected, got %s)", 4, funcName, type( helpText ) ) )
local cvar = CreateConVar( name, default, flags, helpText )
cvars.RemoveChangeCallback( cvar:GetName(), cvar:GetName() )
table.Empty( cvars.GetConVarCallbacks( cvar:GetName(), false ) )
cvars.AddChangeCallback( cvar:GetName(), function( convar_name, value_old, value_new )
value_old = math.floor( tonumber( value_old ) || default )
value_new = math.floor( tonumber( value_new ) || default )
if ( ( value_old < 0 && value_new < 0 ) || ( value_old < 0 && value_new == 0 ) || ( value_old == 0 && value_new < 0 ) || ( value_old == 0 && value_new == 0 ) ) then
RunConsoleCommand( convar_name, '0' )
return
end
if ( ( value_old > 1 && value_new > 1 ) || ( value_old > 1 && value_new == 1 ) || ( value_old == 1 && value_new > 1 ) || ( value_old == 1 && value_new == 1 ) ) then
RunConsoleCommand( convar_name, '1' )
return
end
if ( ( value_old < 0 && value_new > 1 ) || ( value_old < 0 && value_new == 1 ) || ( value_old == 0 && value_new > 1 ) || ( value_old == 0 && value_new == 1 ) ) then
if ( isfunction( funcOn ) ) then
funcOn( cvar, convar_name, value_old, value_new )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 1.", convar_name ) )
end
RunConsoleCommand( convar_name, '1' )
return
end
if ( ( value_old > 1 && value_new < 0 ) || ( value_old == 1 && value_new < 0 ) || ( value_old > 1 && value_new == 0 ) || ( value_old == 1 && value_new == 0 ) ) then
if ( isfunction( funcOff ) ) then
funcOff( cvar, convar_name, value_old, value_new )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 0.", convar_name ) )
end
RunConsoleCommand( convar_name, '0' )
return
end
RunConsoleCommand( convar_name, tostring( math.Clamp( value_new, 0, 1 ) ) )
end, cvar:GetName() )
if ( isbool( persist ) && persist ) then
local value = math.Clamp( cvar:GetInt(), 0, 1 )
if ( forceExecution ) then
if ( value == 1 ) then
if ( isfunction( funcOn ) ) then
funcOn( cvar, cvar:GetName(), value, 1 )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 1.", cvar:GetName() ) )
end
else
if ( isfunction( funcOff ) ) then
funcOff( cvar, cvar:GetName(), value, 0 )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 0.", cvar:GetName() ) )
end
end
end
RunConsoleCommand( cvar:GetName(), tostring( value ) )
else
if ( forceExecution ) then
if ( default == 1 ) then
if ( isfunction( funcOn ) ) then
funcOn( cvar, cvar:GetName(), cvar:GetInt(), 1 )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 1.", cvar:GetName() ) )
end
else
if ( isfunction( funcOff ) ) then
funcOff( cvar, cvar:GetName(), cvar:GetInt(), 0 )
end
if ( isbool( notify ) && notify ) then
print( Format( "Server cvar \"%s\" changed to 0.", cvar:GetName() ) )
end
end
end
RunConsoleCommand( cvar:GetName(), tostring( default ) )
end
return cvar
end
local OnChangePrintNotification = function( sv_protectskybox )
if ( !PrintNotification ) then
return
end
if ( sv_protectskybox:GetBool() ) then
MsgC( Color( 0, 128, 64 ), "Skybox is protected!\n" )
else
MsgC( Color( 128, 32, 32 ), "Skybox is not protected!\n" )
end
end
local sv_protectskybox_allowadmins = CreateTwoStateServerConVar( "sv_protectskybox_allowadmins", ( AllowAdmins && 1 ) || 0, FCVAR_ARCHIVE, "Allow or disallow (super)admins to enter the skybox.", nil, nil, true, false, false )
local sv_protectskybox = CreateTwoStateServerConVar( "sv_protectskybox", 1, FCVAR_ARCHIVE, "Enable or disable protection for the skybox area.", function( cvar )
hook.Remove( "SkyboxIntersection", "FooBarSkyboxIntersections" )
hook.Remove( "Think", "FooBarThinks" )
OnChangePrintNotification( cvar )
end, function( cvar )
--
-- Stop players from going into skybox area/space.
--
hook.Add( "SkyboxIntersection", "FooBarSkyboxIntersections", function( ply )
-- Allow admins and super-admins to go into skybox.
if ( sv_protectskybox_allowadmins:GetBool() && ( ply:IsAdmin() || ply:IsSuperAdmin() ) ) then
return
end
-- Called when a player intersects with skybox.
-- If non-admin player enters the skybox:
ply:ChatPrint( "Sorry, you are not allowed to enter the skybox!" )
ply:KillSilent() -- Kills a player, silently.
-- If I just wanted to prevent, how can I find intersection vector?
--ply:SetPos( ? IntersectionVector ? )
end )
hook.Add( "Think", "FooBarThinks", function()
for _, ply in pairs( player.GetAll() ) do
-- Skip over dead players. I am not sure about vehicles.
if ( !ply:Alive() ) then
continue
end
if ( ply:IntersectsWithSkybox() ) then
hook.Call( "SkyboxIntersection", nil, ply )
end
end
end )
OnChangePrintNotification( cvar )
end, true, true, true )
--OnChangePrintNotification( sv_protectskybox )
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment