Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple unstuck script in gmod
-- TODO: Nocollided props still trigger even with MASK_PLAYERSOLID!
---------------------------------------------------------------
local ply = nil
-- WeHateGarbage
local t = {start=nil,endpos=nil,mask=MASK_PLAYERSOLID,filter=nil}
local function PlayerNotStuck()
t.start = ply:GetPos()
t.endpos = t.start
t.filter = ply
return util.TraceEntity(t,ply).StartSolid == false
end
local NewPos = nil
local function FindPassableSpace( direction, step )
local i = 0
while ( i < 100 ) do
local origin = ply:GetPos()
--origin = VectorMA( origin, step, direction )
origin = origin + step * direction
ply:SetPos( origin )
if PlayerNotStuck( ply ) then
NewPos = ply:GetPos()
return true
end
i = i + 1
end
return false
end
--
-- Purpose: Unstucks player
-- Note: Very expensive to call, you have been warned!
--
local function UnstuckPlayer( pl )
ply = pl
NewPos = ply:GetPos()
local OldPos = NewPos
if not PlayerNotStuck( ply ) then
local angle = ply:GetAngles()
local forward = angle:Forward()
local right = angle:Right()
local up = angle:Up()
local SearchScale = 1 -- Increase and it will unstuck you from even harder places but with lost accuracy. Please, don't try higher values than 12
if not FindPassableSpace( forward, SearchScale ) and -- forward
not FindPassableSpace( right, SearchScale ) and -- right
not FindPassableSpace( right, -SearchScale ) and -- left
not FindPassableSpace( up, SearchScale ) and -- up
not FindPassableSpace( up, -SearchScale ) and -- down
not FindPassableSpace( forward, -SearchScale ) -- back
then
--Msg( "Can't find the world for player "..tostring(ply).."\n" )
return false
end
if OldPos == NewPos then
return true -- Not stuck?
else
ply:SetPos( NewPos )
if SERVER and ply and ply:IsValid() and ply:GetPhysicsObject():IsValid() then
if ply:IsPlayer() then
ply:SetVelocity(vector_origin)
end
ply:GetPhysicsObject():SetVelocity(vector_origin) -- prevents bugs :s
end
return true
end
end
end
---------------------------------------------------------------
local meta = FindMetaTable( "Player" )
if not meta then return end
-- Unstucks a player
-- returns:
-- true: Unstucked
-- false: Could not UnStuck
-- else: Not stuck
--
function meta:UnStuck()
return UnstuckPlayer(self)
end
---------------------------------------------------------------
-- CONFIG -----------------------------------------------------
---------------------------------------------------------------
local config = {} -- ignore
-- Available chat commands for us_unstuck console command
config.ChatCommands = {
"!unstuck",
"!stuck",
"/unstuck",
"/stuck"
}
-- Players of these teams are not allowed to use the unstuck command
config.ExcludedTeams = {
"TEAM_PROPS"
}
-- Number of seconds a player has to wait until (s)he can use the unstuck command again
config.Wait = 10
---------------------------------------------------------------
concommand.Add( "us_unstuck", function( pl )
if not IsValid( pl ) then return end
if not pl:Alive() then
pl:ChatPrint( "You ain't alive." )
return
end
for _,team in pairs( config.ExcludedTeams ) do
if _G[team] ~= nil and _G[team] == pl:Team() then
pl:ChatPrint( "Sorry! You aren't allowed to do this in your team!" )
return
end
end
local CurrentTime = CurTime()
if pl.lastUnStuckTime then
if pl.lastUnStuckTime + config.Wait > CurrentTime then
local waittime, s = config.Wait - math.floor( CurrentTime - pl.lastUnStuckTime ), ""
if waittime ~= 1 then s = "s" end
pl:ChatPrint( "You might want to wait another " .. tostring( waittime ) .. " second" .. s .. "." )
return
end
end
local unstuck = pl:UnStuck()
if unstuck == true then
pl:ChatPrint( "Unstuck successful!" )
elseif unstuck == false then
pl:ChatPrint( "Unstuck not possible (No free space found)." )
else
pl:ChatPrint( "You are not stuck." )
end
pl.lastUnStuckTime = CurTime()
end )
hook.Add( "PlayerSay", "Unstuck Command", function( pl, text )
if table.HasValue( config.ChatCommands, string.lower(text) ) then
pl:ConCommand( "us_unstuck" )
--return false
end
end )
@tetra-fox

This comment has been minimized.

Copy link

commented Dec 12, 2015

Not working anymore. Chat returns Unstuck not possible (No free space found). and player is never unstuck.

@SunRed

This comment has been minimized.

Copy link
Owner Author

commented Feb 23, 2016

Sorry for the late answer, according to my experiences this script still works even though there are better solutions.
You may not experience this problem anymore if you change SearchScale to 2 or 3.

@eleggameplayer

This comment has been minimized.

Copy link

commented Nov 24, 2016

Where do i put this script?

@Mibo5354

This comment has been minimized.

Copy link

commented Apr 8, 2017

I put it in ...\Steam\steamapps\common\GarrysMod\garrysmod\lua\autorun

@zwagbagbacon

This comment has been minimized.

Copy link

commented Aug 8, 2017

I agree with tetra-fox, this command doesn't work on my prop hunt server. It just says the same thing, Unstuck not possible (No free space found).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.