mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
271
lua/entities/prop_animatable.lua
Normal file
271
lua/entities/prop_animatable.lua
Normal file
@@ -0,0 +1,271 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
|
||||
AddCSLuaFile()
|
||||
|
||||
ENT.Base = "base_entity"
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.WantsTranslucency = true -- For the outline
|
||||
ENT.AutomaticFrameAdvance = true
|
||||
|
||||
function ENT:SetupDataTables()
|
||||
|
||||
self:NetworkVar( "Bool", 0, "IsRagdoll" )
|
||||
self:NetworkVar( "Bool", 1, "AnimateBodyXY" )
|
||||
self:NetworkVar( "Bool", 2, "BecomeRagdoll" )
|
||||
self:NetworkVar( "Bool", 3, "HideBBox" )
|
||||
|
||||
if ( CLIENT ) then return end
|
||||
|
||||
self:SetIsRagdoll( false )
|
||||
self:SetAnimateBodyXY( false )
|
||||
self:SetBecomeRagdoll( false )
|
||||
|
||||
end
|
||||
|
||||
if ( SERVER ) then
|
||||
|
||||
function ENT:SetPlayer( ply )
|
||||
|
||||
-- Name compatible with base Sandbox function of the same name
|
||||
self.Founder = ply
|
||||
|
||||
end
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- This is a silly way to check if the model has a physics mesh or not
|
||||
self:PhysicsInit( SOLID_VPHYSICS )
|
||||
|
||||
-- We got no physics? Do some fake shit
|
||||
if ( !IsValid( self:GetPhysicsObject() ) ) then
|
||||
local mins, maxs = self:OBBMins(), self:OBBMaxs()
|
||||
self:SetCollisionBounds( mins, maxs )
|
||||
self:SetSolid( SOLID_BBOX )
|
||||
end
|
||||
|
||||
self:PhysicsDestroy()
|
||||
self:SetMoveType( MOVETYPE_NONE )
|
||||
|
||||
end
|
||||
|
||||
function ENT:FixRagdoll()
|
||||
|
||||
local mins, maxs = self:OBBMins(), self:OBBMaxs()
|
||||
|
||||
-- Just in case
|
||||
self.OriginalCollisions = mins
|
||||
self.OriginalCollisionsMax = maxs
|
||||
|
||||
-- Fix some NPC ragdolls flying above ground
|
||||
mins.z = 0
|
||||
|
||||
self:SetCollisionBounds( mins, maxs )
|
||||
self:SetSolid( SOLID_BBOX )
|
||||
|
||||
-- Used to determine if this animatable prop should have the "Turn into Ragdoll" option.
|
||||
self:SetIsRagdoll( true )
|
||||
|
||||
end
|
||||
|
||||
function ENT:PreEntityCopy()
|
||||
|
||||
self.DuplicatorSavedSequence = self:GetSequence()
|
||||
self.DuplicatorSavedSequenceName = self:GetSequenceName( self:GetSequence() )
|
||||
self.DuplicatorSavedCycle = self:GetCycle()
|
||||
self.DuplicatorSavedPlaybackRate = self:GetPlaybackRate()
|
||||
|
||||
self.PoseParameters = {}
|
||||
for k = 0, self:GetNumPoseParameters() - 1 do
|
||||
local name = self:GetPoseParameterName( k )
|
||||
self.PoseParameters[ name ] = self:GetPoseParameter( name )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:PostEntityPaste()
|
||||
|
||||
if ( self:GetIsRagdoll() ) then self:FixRagdoll() end
|
||||
|
||||
if ( !self.DuplicatorSavedSequence ) then return end
|
||||
|
||||
if ( self.DuplicatorSavedSequence != self:LookupSequence( self.DuplicatorSavedSequenceName ) ) then
|
||||
print( "Something went wrong with restoring sequence for animatable prop!" )
|
||||
self.DuplicatorSavedSequence = self:LookupSequence( self.DuplicatorSavedSequenceName )
|
||||
end
|
||||
|
||||
self:ResetSequence( self.DuplicatorSavedSequence )
|
||||
self:SetCycle( self.DuplicatorSavedCycle )
|
||||
self:SetPlaybackRate( self.DuplicatorSavedPlaybackRate )
|
||||
|
||||
if ( self.PoseParameters ) then
|
||||
for name, value in pairs( self.PoseParameters ) do
|
||||
self:SetPoseParameter( name, value )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnTakeDamage( dmg )
|
||||
|
||||
if ( !self:GetBecomeRagdoll() ) then return end
|
||||
|
||||
if ( util.IsValidRagdoll( self:GetModel() ) ) then
|
||||
self:BecomeRagdollLua( dmg:GetDamageForce(), dmg:GetDamagePosition() )
|
||||
else
|
||||
self:GibBreakClient( dmg:GetDamageForce() )
|
||||
self:Remove()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:BecomeRagdollLua( force, forcePos )
|
||||
local ent = self
|
||||
|
||||
local ragdoll = ents.Create( "prop_ragdoll" )
|
||||
ragdoll:SetModel( ent:GetModel() )
|
||||
ragdoll:SetPos( ent:GetPos() )
|
||||
ragdoll:SetAngles( ent:GetAngles() )
|
||||
|
||||
ragdoll:SetSkin( ent:GetSkin() )
|
||||
ragdoll:SetFlexScale( ent:GetFlexScale() )
|
||||
for i = 0, ent:GetNumBodyGroups() - 1 do ragdoll:SetBodygroup( i, ent:GetBodygroup( i ) ) end
|
||||
for i = 0, ent:GetFlexNum() - 1 do ragdoll:SetFlexWeight( i, ent:GetFlexWeight( i ) ) end
|
||||
for i = 0, ent:GetBoneCount() do
|
||||
ragdoll:ManipulateBoneScale( i, ent:GetManipulateBoneScale( i ) )
|
||||
ragdoll:ManipulateBoneAngles( i, ent:GetManipulateBoneAngles( i ) )
|
||||
ragdoll:ManipulateBonePosition( i, ent:GetManipulateBonePosition( i ) )
|
||||
ragdoll:ManipulateBoneJiggle( i, ent:GetManipulateBoneJiggle( i ) ) -- Even though we don't know what this does, I am still putting this here.
|
||||
end
|
||||
|
||||
ragdoll:Spawn()
|
||||
ragdoll:Activate()
|
||||
|
||||
if ( IsValid( self.Founder ) ) then
|
||||
--self.Founder:AddCount( "ragdolls", ragdoll
|
||||
gamemode.Call( "PlayerSpawnedRagdoll", self.Founder, ragdoll:GetModel(), ragdoll )
|
||||
self.Founder:AddCleanup( "ragdolls", ragdoll )
|
||||
end
|
||||
|
||||
ragdoll.EntityMods = ent.EntityMods
|
||||
ragdoll.BoneMods = ent.BoneMods
|
||||
duplicator.ApplyEntityModifiers( nil, ragdoll )
|
||||
duplicator.ApplyBoneModifiers( nil, ragdoll )
|
||||
|
||||
for i = 0, ragdoll:GetPhysicsObjectCount() - 1 do
|
||||
local bone = ragdoll:GetPhysicsObjectNum( i )
|
||||
if ( IsValid( bone ) ) then
|
||||
local pos, ang = ent:GetBonePosition( ragdoll:TranslatePhysBoneToBone( i ) )
|
||||
if ( pos ) then bone:SetPos( pos ) end
|
||||
if ( ang ) then bone:SetAngles( ang ) end
|
||||
|
||||
if ( !force ) then
|
||||
bone:EnableMotion( false )
|
||||
else
|
||||
bone:ApplyForceOffset( force / ragdoll:GetPhysicsObjectCount(), forcePos )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
undo.ReplaceEntity( ent, ragdoll )
|
||||
cleanup.ReplaceEntity( ent, ragdoll )
|
||||
|
||||
constraint.RemoveAll( ent ) -- Remove all constraints ( this stops ropes from hanging around )
|
||||
ent:Remove()
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
|
||||
-- Clientside only because Velocity is 0 on server
|
||||
if ( self:GetAnimateBodyXY() and CLIENT ) then
|
||||
|
||||
local velocity = self:GetVelocity()
|
||||
velocity.z = 0
|
||||
|
||||
local vecCurrentMoveYaw = Vector( velocity:GetNormalized():Dot( self:GetForward() ), velocity:GetNormalized():Dot( self:GetRight() ) )
|
||||
local flInvScale = math.max( math.abs( vecCurrentMoveYaw.x ), math.abs( vecCurrentMoveYaw.y ) );
|
||||
if ( flInvScale != 0.0 ) then
|
||||
vecCurrentMoveYaw.x = vecCurrentMoveYaw.x / flInvScale;
|
||||
vecCurrentMoveYaw.y = vecCurrentMoveYaw.y / flInvScale;
|
||||
end
|
||||
|
||||
self:SetPoseParameter( "move_x", vecCurrentMoveYaw.x )
|
||||
self:SetPoseParameter( "move_y", vecCurrentMoveYaw.y )
|
||||
|
||||
local maxSpeed = self:GetSequenceGroundSpeed( self:GetSequence() )
|
||||
|
||||
if ( maxSpeed > velocity:Length() ) then
|
||||
vecCurrentMoveYaw.x = vecCurrentMoveYaw.x * ( velocity:Length() / maxSpeed )
|
||||
vecCurrentMoveYaw.y = vecCurrentMoveYaw.y * ( velocity:Length() / maxSpeed )
|
||||
end
|
||||
self:SetPoseParameter( "move_x", vecCurrentMoveYaw.x )
|
||||
self:SetPoseParameter( "move_y", vecCurrentMoveYaw.y )
|
||||
|
||||
-- This has to be on server to function :(
|
||||
--[[local scale = velocity:Length() / maxSpeed
|
||||
if ( maxSpeed != 0 ) then
|
||||
self:SetPlaybackRate( scale )
|
||||
end]]
|
||||
|
||||
end
|
||||
|
||||
if ( SERVER ) then
|
||||
-- Ugly hack because no replicated cvars for Lua :(
|
||||
self:SetHideBBox( GetConVarNumber( "rb655_easy_animation_nobbox_sv" ) > 0 )
|
||||
end
|
||||
|
||||
-- Ensure the animation plays smoothly
|
||||
self:NextThink( CurTime() )
|
||||
return true
|
||||
|
||||
end
|
||||
|
||||
if ( SERVER ) then return end
|
||||
|
||||
function ENT:DrawBBox()
|
||||
|
||||
if ( GetConVarNumber( "rb655_easy_animation_noglow" ) != 0 or self:GetHideBBox() ) then return end
|
||||
|
||||
local wep = LocalPlayer():GetActiveWeapon()
|
||||
if ( !IsValid( wep ) or wep:GetClass() != "gmod_tool" and wep:GetClass() != "weapon_physgun" ) then
|
||||
return
|
||||
end
|
||||
|
||||
local mins = self:OBBMins()
|
||||
local maxs = self:OBBMaxs()
|
||||
|
||||
if ( self:GetSolid() == SOLID_BBOX ) then
|
||||
render.DrawWireframeBox( self:GetPos(), angle_zero, mins, maxs )
|
||||
else
|
||||
render.DrawWireframeBox( self:GetPos(), self:GetAngles(), mins, maxs )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function ENT:Draw( flags )
|
||||
|
||||
self:DrawBBox()
|
||||
|
||||
-- This probably shouldn't run every frame..
|
||||
self:SetRenderBounds( self:GetModelBounds() )
|
||||
|
||||
self:DrawModel( flags )
|
||||
|
||||
end
|
||||
|
||||
function ENT:DrawTranslucent( flags )
|
||||
|
||||
self:Draw( flags )
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user