local PLUGIN = {} PLUGIN.Name = "Ghost" PLUGIN.Author = "RabidToaster" PLUGIN.Date = "1st August 2008" PLUGIN.Filename = PLUGIN_FILENAME PLUGIN.ClientSide = true PLUGIN.ServerSide = true PLUGIN.APIVersion = 2 PLUGIN.Gamemodes = {} // This is the default access level needed. PLUGIN.LevelNeeded = "Admin" // Speed + jump height for ghosts. PLUGIN.MoveSpeed = 1000 PLUGIN.JumpHeight = 300 // Levels possible to set to. PLUGIN.Levels = { "Owner", "Super Admin", "Admin", "Temp Admin", "Respected", "Guest", "Banned" } if ( SERVER ) then ASS_NewLogLevel( "ASS_ACL_GHOST" ) function PLUGIN.HasLevelNeeded( ply, level ) local levelTest = ply[ "Is" .. ( level or PLUGIN.LevelNeeded ) ] if ( levelTest ) then return levelTest( ply ) else return ply:IsAdmin() end end function PLUGIN.SetMinimum( PLAYER, CMD, ARGS ) local level = ARGS[ 1 ] if ( !level || !table.HasValue( PLUGIN.Levels, level ) ) then return end if ( PLAYER:IsTempAdmin() ) then PLUGIN.LevelNeeded = level ASS_MessagePlayer( PLAYER, "Minimum level set to \"" .. level .. "\".\n" ) else ASS_MessagePlayer( PLAYER, "You do not have a sufficent access level!\n") end end concommand.Add( "ASS_SetGhostLevel", PLUGIN.SetMinimum ) function PLUGIN.IsGhosting( ply ) return ply.Ghost != nil end function PLUGIN.GetGhostEntity( ply ) return ply.Ghost end function PLUGIN.SetGhosting( ply, bool ) // Turn off ghosting. if ( !bool && PLUGIN.IsGhosting( ply ) ) then local pos = ply:GetPos() ply:UnSpectate() ply:Spawn() ply:SetPos( pos ) ply.Ghost = nil ASS_MessagePlayer( ply, "Stopped ghosting!\n") // Turn on ghosting. elseif ( bool && !PLUGIN.IsGhosting( ply ) ) then local trace = util.TraceLine( util.GetPlayerTrace( ply ) ) local ent = trace.Entity if ( ValidEntity( ent ) && ent:GetClass() == "prop_physics" ) then ply:StripWeapons() ply:Spectate( OBS_MODE_CHASE ) ply:SpectateEntity( ent ) ply.Ghost = ent ASS_MessagePlayer( ply, "Ghosting!\n") end end end function PLUGIN.PlayerSay( ply, text ) if ( string.Left( string.lower( text ), 6 ) != "!ghost" ) then return end local ghosting = PLUGIN.IsGhosting( ply ) // Check if the player is the right level. if ( ghosting || PLUGIN.HasLevelNeeded( ply ) ) then PLUGIN.SetGhosting( ply, !ghosting ) else ASS_MessagePlayer( ply, "You do not have a sufficent access level!\n") end return "" end function PLUGIN.PlayerDeath( ply ) PLUGIN.SetGhosting( ply, false ) end function PLUGIN.IsOnGround( ent ) local a, b = ent:WorldSpaceAABB() local c = ent:LocalToWorld( ent:OBBCenter() ) c.z = b.z return util.QuickTrace( c, Vector( 0, 0, -50 ), ent ).Hit end function PLUGIN.ControlProp( ply, phys, time, ent ) local dir = ply:EyeAngles() local fd, up, rt = dir:Forward(), dir:Up(), dir:Right() local vel = Vector( 0, 0, 0 ) local speed = PLUGIN.MoveSpeed * time // Forward/back. if ( ply:KeyDown( IN_FORWARD ) ) then vel = vel + ( fd * speed ) end if ( ply:KeyDown( IN_BACK ) ) then vel = vel + ( fd * speed * -1 ) end // Left/right. if ( ply:KeyDown( IN_MOVERIGHT ) ) then vel = vel + ( rt * speed ) end if ( ply:KeyDown( IN_MOVELEFT ) ) then vel = vel + ( rt * speed * -1 ) end // Jump. if ( ply:KeyPressed( IN_JUMP ) && PLUGIN.IsOnGround( ent ) ) then vel = vel + Vector( 0, 0, PLUGIN.JumpHeight ) end // Brake! if ( ply:KeyDown( IN_DUCK ) ) then local cur = phys:GetVelocity() local brake = cur:GetNormal() * math.min( cur:Length(), speed ) * -1 brake.z = 0 vel = vel + brake end phys:AddVelocity( vel ) end function PLUGIN.Think() local time = FrameTime() for _, ply in pairs( player.GetAll() ) do if ( PLUGIN.IsGhosting( ply ) ) then local ent = PLUGIN.GetGhostEntity( ply ) if ( ValidEntity( ent ) ) then local phys = ent:GetPhysicsObject() if ( phys:IsValid() ) then PLUGIN.ControlProp( ply, phys, time, ent ) end end end end end function PLUGIN.Registered() hook.Add( "PlayerSay", "PlayerSay_" .. PLUGIN.Filename, PLUGIN.PlayerSay ) hook.Add( "PlayerDeath", "PlayerDeath_" .. PLUGIN.Filename, PLUGIN.PlayerDeath ) hook.Add( "Think", "Think_" .. PLUGIN.Filename, PLUGIN.Think ) end end if ( CLIENT ) then function PLUGIN.AddMenu( DMENU ) DMENU:AddSubMenu( "Ghost", nil, function( NEWMENU ) for _, level in pairs( PLUGIN.Levels ) do NEWMENU:AddOption( level, function() RunConsoleCommand( "ASS_SetGhostLevel", level ) end ) end end ) end end ASS_RegisterPlugin( PLUGIN )