Files
wnsrc/gamemodes/base/gamemode/animations.lua
lifestorm 9c918c46e5 Upload
2024-08-04 23:12:27 +03:00

407 lines
11 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/
--]]
function GM:HandlePlayerJumping( ply, velocity, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
if ( ply:GetMoveType() == MOVETYPE_NOCLIP ) then
plyTable.m_bJumping = false
return
end
-- airwalk more like hl2mp, we airwalk until we have 0 velocity, then it's the jump animation
-- underwater we're alright we airwalking
if ( !plyTable.m_bJumping && !ply:OnGround() && ply:WaterLevel() <= 0 ) then
if ( !plyTable.m_fGroundTime ) then
plyTable.m_fGroundTime = CurTime()
elseif ( ( CurTime() - plyTable.m_fGroundTime ) > 0 && velocity:Length2DSqr() < 0.25 ) then
plyTable.m_bJumping = true
plyTable.m_bFirstJumpFrame = false
plyTable.m_flJumpStartTime = 0
end
end
if ( plyTable.m_bJumping ) then
if ( plyTable.m_bFirstJumpFrame ) then
plyTable.m_bFirstJumpFrame = false
ply:AnimRestartMainSequence()
end
if ( ( ply:WaterLevel() >= 2 ) || ( ( CurTime() - plyTable.m_flJumpStartTime ) > 0.2 && ply:OnGround() ) ) then
plyTable.m_bJumping = false
plyTable.m_fGroundTime = nil
ply:AnimRestartMainSequence()
end
if ( plyTable.m_bJumping ) then
plyTable.CalcIdeal = ACT_MP_JUMP
return true
end
end
return false
end
function GM:HandlePlayerDucking( ply, velocity, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
if ( !ply:IsFlagSet( FL_ANIMDUCKING ) ) then return false end
if ( velocity:Length2DSqr() > 0.25 ) then
plyTable.CalcIdeal = ACT_MP_CROUCHWALK
else
plyTable.CalcIdeal = ACT_MP_CROUCH_IDLE
end
return true
end
function GM:HandlePlayerNoClipping( ply, velocity, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
if ( ply:GetMoveType() != MOVETYPE_NOCLIP || ply:InVehicle() ) then
if ( plyTable.m_bWasNoclipping ) then
plyTable.m_bWasNoclipping = nil
ply:AnimResetGestureSlot( GESTURE_SLOT_CUSTOM )
if ( CLIENT ) then ply:SetIK( true ) end
end
return
end
if ( !plyTable.m_bWasNoclipping ) then
ply:AnimRestartGesture( GESTURE_SLOT_CUSTOM, ACT_GMOD_NOCLIP_LAYER, false )
if ( CLIENT ) then ply:SetIK( false ) end
end
return true
end
function GM:HandlePlayerVaulting( ply, velocity, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
if ( velocity:LengthSqr() < 1000000 ) then return end
if ( ply:IsOnGround() ) then return end
plyTable.CalcIdeal = ACT_MP_SWIM
return true
end
function GM:HandlePlayerSwimming( ply, velocity, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
if ( ply:WaterLevel() < 2 || ply:IsOnGround() ) then
plyTable.m_bInSwim = false
return false
end
plyTable.CalcIdeal = ACT_MP_SWIM
plyTable.m_bInSwim = true
return true
end
function GM:HandlePlayerLanding( ply, velocity, WasOnGround )
if ( ply:GetMoveType() == MOVETYPE_NOCLIP ) then return end
if ( ply:IsOnGround() && !WasOnGround ) then
ply:AnimRestartGesture( GESTURE_SLOT_JUMP, ACT_LAND, true )
end
end
function GM:HandlePlayerDriving( ply, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
-- The player must have a parent to be in a vehicle. If there's no parent, we are in the exit anim, so don't do sitting in 3rd person anymore
if ( !ply:InVehicle() || !IsValid( ply:GetParent() ) ) then return false end
local pVehicle = ply:GetVehicle()
if ( !pVehicle.HandleAnimation && pVehicle.GetVehicleClass ) then
local c = pVehicle:GetVehicleClass()
local t = list.Get( "Vehicles" )[ c ]
if ( t && t.Members && t.Members.HandleAnimation ) then
pVehicle.HandleAnimation = t.Members.HandleAnimation
else
pVehicle.HandleAnimation = true -- Prevent this if block from trying to assign HandleAnimation again.
end
end
if ( isfunction( pVehicle.HandleAnimation ) ) then
local seq = pVehicle:HandleAnimation( ply )
if ( seq != nil ) then
plyTable.CalcSeqOverride = seq
end
end
if ( plyTable.CalcSeqOverride == -1 ) then -- pVehicle.HandleAnimation did not give us an animation
local class = pVehicle:GetClass()
if ( class == "prop_vehicle_jeep" ) then
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_jeep" )
elseif ( class == "prop_vehicle_airboat" ) then
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_airboat" )
elseif ( class == "prop_vehicle_prisoner_pod" && pVehicle:GetModel() == "models/vehicles/prisoner_pod_inner.mdl" ) then
-- HACK!!
plyTable.CalcSeqOverride = ply:LookupSequence( "drive_pd" )
else
plyTable.CalcSeqOverride = ply:LookupSequence( "sit_rollercoaster" )
end
end
local use_anims = ( plyTable.CalcSeqOverride == ply:LookupSequence( "sit_rollercoaster" ) || plyTable.CalcSeqOverride == ply:LookupSequence( "sit" ) )
if ( use_anims && ply:GetAllowWeaponsInVehicle() && IsValid( ply:GetActiveWeapon() ) ) then
local holdtype = ply:GetActiveWeapon():GetHoldType()
if ( holdtype == "smg" ) then holdtype = "smg1" end
local seqid = ply:LookupSequence( "sit_" .. holdtype )
if ( seqid != -1 ) then
plyTable.CalcSeqOverride = seqid
end
end
return true
end
--[[---------------------------------------------------------
Name: gamemode:UpdateAnimation()
Desc: Animation updates (pose params etc) should be done here
-----------------------------------------------------------]]
function GM:UpdateAnimation( ply, velocity, maxseqgroundspeed )
local len = velocity:Length()
local movement = 1.0
if ( len > 0.2 ) then
movement = ( len / maxseqgroundspeed )
end
local rate = math.min( movement, 2 )
-- if we're under water we want to constantly be swimming..
if ( ply:WaterLevel() >= 2 ) then
rate = math.max( rate, 0.5 )
elseif ( !ply:IsOnGround() && len >= 1000 ) then
rate = 0.1
end
ply:SetPlaybackRate( rate )
-- We only need to do this clientside..
if ( CLIENT ) then
if ( ply:InVehicle() ) then
--
-- This is used for the 'rollercoaster' arms
--
local Vehicle = ply:GetVehicle()
local Velocity = Vehicle:GetVelocity()
local fwd = Vehicle:GetUp()
local dp = fwd:Dot( Vector( 0, 0, 1 ) )
ply:SetPoseParameter( "vertical_velocity", ( dp < 0 && dp || 0 ) + fwd:Dot( Velocity ) * 0.005 )
-- Pass the vehicles steer param down to the player
local steer = Vehicle:GetPoseParameter( "vehicle_steer" )
steer = steer * 2 - 1 -- convert from 0..1 to -1..1
if ( Vehicle:GetClass() == "prop_vehicle_prisoner_pod" ) then steer = 0 ply:SetPoseParameter( "aim_yaw", math.NormalizeAngle( ply:GetAimVector():Angle().y - Vehicle:GetAngles().y - 90 ) ) end
ply:SetPoseParameter( "vehicle_steer", steer )
end
GAMEMODE:GrabEarAnimation( ply )
GAMEMODE:MouthMoveAnimation( ply )
end
end
--
-- If you don't want the player to grab his ear in your gamemode then
-- just override this.
--
function GM:GrabEarAnimation( ply, plyTable )
if ( !plyTable ) then plyTable = ply:GetTable() end
plyTable.ChatGestureWeight = plyTable.ChatGestureWeight || 0
-- Don't show this when we're playing a taunt!
if ( ply:IsPlayingTaunt() ) then return end
if ( ply:IsTyping() ) then
plyTable.ChatGestureWeight = math.Approach( plyTable.ChatGestureWeight, 1, FrameTime() * 5.0 )
else
plyTable.ChatGestureWeight = math.Approach( plyTable.ChatGestureWeight, 0, FrameTime() * 5.0 )
end
if ( plyTable.ChatGestureWeight > 0 ) then
ply:AnimRestartGesture( GESTURE_SLOT_VCD, ACT_GMOD_IN_CHAT, true )
ply:AnimSetGestureWeight( GESTURE_SLOT_VCD, plyTable.ChatGestureWeight )
end
end
--
-- Moves the mouth when talking on voicecom
--
function GM:MouthMoveAnimation( ply )
local flexes = {
ply:GetFlexIDByName( "jaw_drop" ),
ply:GetFlexIDByName( "left_part" ),
ply:GetFlexIDByName( "right_part" ),
ply:GetFlexIDByName( "left_mouth_drop" ),
ply:GetFlexIDByName( "right_mouth_drop" )
}
local weight = ply:IsSpeaking() && math.Clamp( ply:VoiceVolume() * 2, 0, 2 ) || 0
for k, v in ipairs( flexes ) do
ply:SetFlexWeight( v, weight )
end
end
function GM:CalcMainActivity( ply, velocity )
local plyTable = ply:GetTable()
plyTable.CalcIdeal = ACT_MP_STAND_IDLE
plyTable.CalcSeqOverride = -1
self:HandlePlayerLanding( ply, velocity, plyTable.m_bWasOnGround )
if !( self:HandlePlayerNoClipping( ply, velocity, plyTable ) ||
self:HandlePlayerDriving( ply, plyTable ) ||
self:HandlePlayerVaulting( ply, velocity, plyTable ) ||
self:HandlePlayerJumping( ply, velocity, plyTable ) ||
self:HandlePlayerSwimming( ply, velocity, plyTable ) ||
self:HandlePlayerDucking( ply, velocity, plyTable ) ) then
local len2d = velocity:Length2DSqr()
if ( len2d > 22500 ) then plyTable.CalcIdeal = ACT_MP_RUN elseif ( len2d > 0.25 ) then plyTable.CalcIdeal = ACT_MP_WALK end
end
plyTable.m_bWasOnGround = ply:IsOnGround()
plyTable.m_bWasNoclipping = ( ply:GetMoveType() == MOVETYPE_NOCLIP && !ply:InVehicle() )
return plyTable.CalcIdeal, plyTable.CalcSeqOverride
end
local IdleActivity = ACT_HL2MP_IDLE
local IdleActivityTranslate = {}
IdleActivityTranslate[ ACT_MP_STAND_IDLE ] = IdleActivity
IdleActivityTranslate[ ACT_MP_WALK ] = IdleActivity + 1
IdleActivityTranslate[ ACT_MP_RUN ] = IdleActivity + 2
IdleActivityTranslate[ ACT_MP_CROUCH_IDLE ] = IdleActivity + 3
IdleActivityTranslate[ ACT_MP_CROUCHWALK ] = IdleActivity + 4
IdleActivityTranslate[ ACT_MP_ATTACK_STAND_PRIMARYFIRE ] = IdleActivity + 5
IdleActivityTranslate[ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ] = IdleActivity + 5
IdleActivityTranslate[ ACT_MP_RELOAD_STAND ] = IdleActivity + 6
IdleActivityTranslate[ ACT_MP_RELOAD_CROUCH ] = IdleActivity + 6
IdleActivityTranslate[ ACT_MP_JUMP ] = ACT_HL2MP_JUMP_SLAM
IdleActivityTranslate[ ACT_MP_SWIM ] = IdleActivity + 9
IdleActivityTranslate[ ACT_LAND ] = ACT_LAND
-- it is preferred you return ACT_MP_* in CalcMainActivity, and if you have a specific need to not translate through the weapon do it here
function GM:TranslateActivity( ply, act )
local newact = ply:TranslateWeaponActivity( act )
-- select idle anims if the weapon didn't decide
if ( act == newact ) then
return IdleActivityTranslate[ act ]
end
return newact
end
function GM:DoAnimationEvent( ply, event, data )
if ( event == PLAYERANIMEVENT_ATTACK_PRIMARY ) then
if ply:IsFlagSet( FL_ANIMDUCKING ) then
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, true )
else
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE, true )
end
return ACT_VM_PRIMARYATTACK
elseif ( event == PLAYERANIMEVENT_ATTACK_SECONDARY ) then
-- there is no gesture, so just fire off the VM event
return ACT_VM_SECONDARYATTACK
elseif ( event == PLAYERANIMEVENT_RELOAD ) then
if ply:IsFlagSet( FL_ANIMDUCKING ) then
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH, true )
else
ply:AnimRestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND, true )
end
return ACT_INVALID
elseif ( event == PLAYERANIMEVENT_JUMP ) then
ply.m_bJumping = true
ply.m_bFirstJumpFrame = true
ply.m_flJumpStartTime = CurTime()
ply:AnimRestartMainSequence()
return ACT_INVALID
elseif ( event == PLAYERANIMEVENT_CANCEL_RELOAD ) then
ply:AnimResetGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD )
return ACT_INVALID
end
end