mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 13:23:46 +03:00
272 lines
7.3 KiB
Lua
272 lines
7.3 KiB
Lua
--[[
|
|
| 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
|