Files
wnsrc/gamemodes/sandbox/entities/weapons/gmod_tool/ghostentity.lua

136 lines
4.1 KiB
Lua
Raw Normal View History

2024-08-04 23:54:45 +03:00
--[[
| 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/
--]]
--[[---------------------------------------------------------
Starts up the ghost entity
The most important part of this is making sure it gets deleted properly
-----------------------------------------------------------]]
function ToolObj:MakeGhostEntity( model, pos, angle )
util.PrecacheModel( model )
-- We do ghosting serverside in single player
-- It's done clientside in multiplayer
if ( SERVER && !game.SinglePlayer() ) then return end
if ( CLIENT && game.SinglePlayer() ) then return end
-- The reason we need this is because in multiplayer, when you holster a tool serverside,
-- either by using the spawnnmenu's Weapons tab or by simply entering a vehicle,
-- the Think hook is called once after Holster is called on the client, recreating the ghost entity right after it was removed.
if ( !IsFirstTimePredicted() ) then return end
-- Release the old ghost entity
self:ReleaseGhostEntity()
-- Don't allow ragdolls/effects to be ghosts
if ( !util.IsValidProp( model ) ) then return end
if ( CLIENT ) then
self.GhostEntity = ents.CreateClientProp( model )
else
self.GhostEntity = ents.Create( "prop_physics" )
end
-- If there's too many entities we might not spawn..
if ( !IsValid( self.GhostEntity ) ) then
self.GhostEntity = nil
return
end
self.GhostEntity:SetModel( model )
self.GhostEntity:SetPos( pos )
self.GhostEntity:SetAngles( angle )
self.GhostEntity:Spawn()
-- We do not want physics at all
self.GhostEntity:PhysicsDestroy()
-- SOLID_NONE causes issues with Entity.NearestPoint used by Wheel tool
--self.GhostEntity:SetSolid( SOLID_NONE )
self.GhostEntity:SetMoveType( MOVETYPE_NONE )
self.GhostEntity:SetNotSolid( true )
self.GhostEntity:SetRenderMode( RENDERMODE_TRANSCOLOR )
self.GhostEntity:SetColor( Color( 255, 255, 255, 150 ) )
end
--[[---------------------------------------------------------
Starts up the ghost entity
The most important part of this is making sure it gets deleted properly
-----------------------------------------------------------]]
function ToolObj:StartGhostEntity( ent )
-- We do ghosting serverside in single player
-- It's done clientside in multiplayer
if ( SERVER && !game.SinglePlayer() ) then return end
if ( CLIENT && game.SinglePlayer() ) then return end
self:MakeGhostEntity( ent:GetModel(), ent:GetPos(), ent:GetAngles() )
end
--[[---------------------------------------------------------
Releases up the ghost entity
-----------------------------------------------------------]]
function ToolObj:ReleaseGhostEntity()
if ( self.GhostEntity ) then
if ( !IsValid( self.GhostEntity ) ) then self.GhostEntity = nil return end
self.GhostEntity:Remove()
self.GhostEntity = nil
end
-- This is unused!
if ( self.GhostEntities ) then
for k, v in pairs( self.GhostEntities ) do
if ( IsValid( v ) ) then v:Remove() end
self.GhostEntities[ k ] = nil
end
self.GhostEntities = nil
end
-- This is unused!
if ( self.GhostOffset ) then
for k, v in pairs( self.GhostOffset ) do
self.GhostOffset[ k ] = nil
end
end
end
--[[---------------------------------------------------------
Update the ghost entity
-----------------------------------------------------------]]
function ToolObj:UpdateGhostEntity()
if ( self.GhostEntity == nil ) then return end
if ( !IsValid( self.GhostEntity ) ) then self.GhostEntity = nil return end
local trace = self:GetOwner():GetEyeTrace()
if ( !trace.Hit ) then return end
local Ang1, Ang2 = self:GetNormal( 1 ):Angle(), ( trace.HitNormal * -1 ):Angle()
local TargetAngle = self:GetEnt( 1 ):AlignAngles( Ang1, Ang2 )
self.GhostEntity:SetPos( self:GetEnt( 1 ):GetPos() )
self.GhostEntity:SetAngles( TargetAngle )
local TranslatedPos = self.GhostEntity:LocalToWorld( self:GetLocalPos( 1 ) )
local TargetPos = trace.HitPos + ( self:GetEnt( 1 ):GetPos() - TranslatedPos ) + trace.HitNormal
self.GhostEntity:SetPos( TargetPos )
end