Created
April 14, 2015 20:43
-
-
Save SunRed/da1b02efa7c167804e65 to your computer and use it in GitHub Desktop.
A simple unstuck script in gmod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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 ) |
Where do i put this script?
I put it in ...\Steam\steamapps\common\GarrysMod\garrysmod\lua\autorun
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
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.