--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local meta = FindMetaTable( "Player" ) if ( !meta ) then return end -- In this file we're adding functions to the player meta table. -- This means you'll be able to call functions here straight from the player object -- You can even override already existing functions. --[[--------------------------------------------------------- Name: AddFrozenPhysicsObject Desc: For the Physgun, adds a frozen object to the player's list -----------------------------------------------------------]] function meta:AddFrozenPhysicsObject( ent, phys ) -- Get the player's table local tab = self:GetTable() -- Make sure the physics objects table exists tab.FrozenPhysicsObjects = tab.FrozenPhysicsObjects or {} -- Make a new table that contains the info local entry = {} entry.ent = ent entry.phys = phys table.insert( tab.FrozenPhysicsObjects, entry ) gamemode.Call( "PlayerFrozeObject", self, ent, phys ) end local function PlayerUnfreezeObject( ply, ent, object ) -- Not frozen! if ( object:IsMoveable() ) then return 0 end -- Unfreezable means it can't be frozen or unfrozen. -- This prevents the player unfreezing the gmod_anchor entity. if ( ent:GetUnFreezable() ) then return 0 end -- NOTE: IF YOU'RE MAKING SOME KIND OF PROP PROTECTOR THEN HOOK "CanPlayerUnfreeze" if ( !gamemode.Call( "CanPlayerUnfreeze", ply, ent, object ) ) then return 0 end object:EnableMotion( true ) object:Wake() gamemode.Call( "PlayerUnfrozeObject", ply, ent, object ) return 1 end --[[--------------------------------------------------------- Name: UnfreezePhysicsObjects Desc: For the Physgun, unfreezes all frozen physics objects -----------------------------------------------------------]] function meta:PhysgunUnfreeze() -- Get the player's table local tab = self:GetTable() if ( !tab.FrozenPhysicsObjects ) then return 0 end -- Detect double click. Unfreeze all objects on double click. if ( tab.LastPhysUnfreeze && CurTime() - tab.LastPhysUnfreeze < 0.25 ) then return self:UnfreezePhysicsObjects() end local tr = self:GetEyeTrace() if ( tr.HitNonWorld && IsValid( tr.Entity ) ) then local Ents = constraint.GetAllConstrainedEntities( tr.Entity ) local UnfrozenObjects = 0 for k, ent in pairs( Ents ) do local objects = ent:GetPhysicsObjectCount() for i = 1, objects do local physobject = ent:GetPhysicsObjectNum( i - 1 ) UnfrozenObjects = UnfrozenObjects + PlayerUnfreezeObject( self, ent, physobject ) end end return UnfrozenObjects end tab.LastPhysUnfreeze = CurTime() return 0 end --[[--------------------------------------------------------- Name: UnfreezePhysicsObjects Desc: For the Physgun, unfreezes all frozen physics objects -----------------------------------------------------------]] function meta:UnfreezePhysicsObjects() -- Get the player's table local tab = self:GetTable() -- If the table doesn't exist then quit here if ( !tab.FrozenPhysicsObjects ) then return 0 end local Count = 0 -- Loop through each table in our table for k, v in pairs( tab.FrozenPhysicsObjects ) do -- Make sure the entity to which the physics object -- is attached is still valid (still exists) if ( isentity( v.ent ) && IsValid( v.ent ) ) then -- We can't directly test to see if EnableMotion is false right now -- but IsMovable seems to do the job just fine. -- We only test so the count isn't wrong if ( IsValid( v.phys ) && !v.phys:IsMoveable() ) then -- We need to freeze/unfreeze all physobj's in jeeps to stop it spazzing if ( v.ent:GetClass() == "prop_vehicle_jeep" ) then -- How many physics objects we have local objects = v.ent:GetPhysicsObjectCount() -- Loop through each one for i = 0, objects - 1 do local physobject = v.ent:GetPhysicsObjectNum( i ) PlayerUnfreezeObject( self, v.ent, physobject ) end end Count = Count + PlayerUnfreezeObject( self, v.ent, v.phys ) end end end -- Remove the table tab.FrozenPhysicsObjects = nil return Count end local g_UniqueIDTable = {} --[[--------------------------------------------------------- This table will persist between client deaths and reconnects -----------------------------------------------------------]] function meta:UniqueIDTable( key ) local id = 0 if ( SERVER ) then id = self:SteamID64() end g_UniqueIDTable[ id ] = g_UniqueIDTable[ id ] or {} g_UniqueIDTable[ id ][ key ] = g_UniqueIDTable[ id ][ key ] or {} return g_UniqueIDTable[ id ][ key ] end --[[--------------------------------------------------------- Player Eye Trace -----------------------------------------------------------]] function meta:GetEyeTrace() if ( CLIENT ) then local framenum = FrameNumber() -- Cache the trace results for the current frame, unless we're serverside -- in which case it wouldn't play well with lag compensation at all if ( self.LastPlayerTrace == framenum ) then return self.PlayerTrace end self.LastPlayerTrace = framenum end local tr = util.TraceLine( util.GetPlayerTrace( self ) ) self.PlayerTrace = tr return tr end --[[--------------------------------------------------------- GetEyeTraceIgnoreCursor Like GetEyeTrace but doesn't use the cursor aim vector.. -----------------------------------------------------------]] function meta:GetEyeTraceNoCursor() if ( CLIENT ) then local framenum = FrameNumber() if ( self.LastPlayerAimTrace == framenum ) then return self.PlayerAimTrace end self.LastPlayerAimTrace = framenum end local tr = util.TraceLine( util.GetPlayerTrace( self, self:EyeAngles():Forward() ) ) self.PlayerAimTrace = tr return tr end