mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-04-04 07:35:25 +00:00
633 lines
16 KiB
C++
633 lines
16 KiB
C++
//====== Copyright © 1996-2003, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "cbase.h"
|
|
#include "tier0/vprof.h"
|
|
#include "animation.h"
|
|
#include "studio.h"
|
|
#include "apparent_velocity_helper.h"
|
|
#include "utldict.h"
|
|
#include "tf_playeranimstate.h"
|
|
#include "base_playeranimstate.h"
|
|
#include "datacache/imdlcache.h"
|
|
|
|
#ifdef CLIENT_DLL
|
|
#include "c_tf_player.h"
|
|
#else
|
|
#include "tf_player.h"
|
|
#endif
|
|
|
|
#define TF_RUN_SPEED 320.0f
|
|
#define TF_WALK_SPEED 75.0f
|
|
#define TF_CROUCHWALK_SPEED 110.0f
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pPlayer -
|
|
// Output : CMultiPlayerAnimState*
|
|
//-----------------------------------------------------------------------------
|
|
CTFPlayerAnimState* CreateTFPlayerAnimState( CTFPlayer *pPlayer )
|
|
{
|
|
MDLCACHE_CRITICAL_SECTION();
|
|
|
|
// Setup the movement data.
|
|
MultiPlayerMovementData_t movementData;
|
|
movementData.m_flBodyYawRate = 720.0f;
|
|
movementData.m_flRunSpeed = TF_RUN_SPEED;
|
|
movementData.m_flWalkSpeed = TF_WALK_SPEED;
|
|
movementData.m_flSprintSpeed = -1.0f;
|
|
|
|
// Create animation state for this player.
|
|
CTFPlayerAnimState *pRet = new CTFPlayerAnimState( pPlayer, movementData );
|
|
|
|
// Specific TF player initialization.
|
|
pRet->InitTF( pPlayer );
|
|
|
|
return pRet;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : -
|
|
//-----------------------------------------------------------------------------
|
|
CTFPlayerAnimState::CTFPlayerAnimState()
|
|
{
|
|
m_pTFPlayer = NULL;
|
|
|
|
// Don't initialize TF specific variables here. Init them in InitTF()
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *pPlayer -
|
|
// &movementData -
|
|
//-----------------------------------------------------------------------------
|
|
CTFPlayerAnimState::CTFPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData )
|
|
: CMultiPlayerAnimState( pPlayer, movementData )
|
|
{
|
|
m_pTFPlayer = NULL;
|
|
|
|
// Don't initialize TF specific variables here. Init them in InitTF()
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : -
|
|
//-----------------------------------------------------------------------------
|
|
CTFPlayerAnimState::~CTFPlayerAnimState()
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Initialize Team Fortress specific animation state.
|
|
// Input : *pPlayer -
|
|
//-----------------------------------------------------------------------------
|
|
void CTFPlayerAnimState::InitTF( CTFPlayer *pPlayer )
|
|
{
|
|
m_pTFPlayer = pPlayer;
|
|
m_bInAirWalk = false;
|
|
m_flHoldDeployedPoseUntilTime = 0.0f;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFPlayerAnimState::ClearAnimationState( void )
|
|
{
|
|
m_bInAirWalk = false;
|
|
|
|
BaseClass::ClearAnimationState();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : actDesired -
|
|
// Output : Activity
|
|
//-----------------------------------------------------------------------------
|
|
Activity CTFPlayerAnimState::TranslateActivity( Activity actDesired )
|
|
{
|
|
Activity translateActivity = BaseClass::TranslateActivity( actDesired );
|
|
|
|
if ( GetTFPlayer()->GetActiveWeapon() )
|
|
{
|
|
translateActivity = GetTFPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, NULL );
|
|
}
|
|
|
|
return translateActivity;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTFPlayerAnimState::Update( float eyeYaw, float eyePitch )
|
|
{
|
|
// Profile the animation update.
|
|
VPROF( "CMultiPlayerAnimState::Update" );
|
|
|
|
// Get the TF player.
|
|
CTFPlayer *pTFPlayer = GetTFPlayer();
|
|
if ( !pTFPlayer )
|
|
return;
|
|
|
|
// Get the studio header for the player.
|
|
CStudioHdr *pStudioHdr = pTFPlayer->GetModelPtr();
|
|
if ( !pStudioHdr )
|
|
return;
|
|
|
|
// Check to see if we should be updating the animation state - dead, ragdolled?
|
|
if ( !ShouldUpdateAnimState() )
|
|
{
|
|
ClearAnimationState();
|
|
return;
|
|
}
|
|
|
|
// Store the eye angles.
|
|
m_flEyeYaw = AngleNormalize( eyeYaw );
|
|
m_flEyePitch = AngleNormalize( eyePitch );
|
|
|
|
// Compute the player sequences.
|
|
ComputeSequences( pStudioHdr );
|
|
|
|
if ( SetupPoseParameters( pStudioHdr ) && !pTFPlayer->m_Shared.InCond( TF_COND_TAUNTING ) )
|
|
{
|
|
// Pose parameter - what direction are the player's legs running in.
|
|
ComputePoseParam_MoveYaw( pStudioHdr );
|
|
|
|
// Pose parameter - Torso aiming (up/down).
|
|
ComputePoseParam_AimPitch( pStudioHdr );
|
|
|
|
// Pose parameter - Torso aiming (rotation).
|
|
ComputePoseParam_AimYaw( pStudioHdr );
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
if ( C_BasePlayer::ShouldDrawLocalPlayer() )
|
|
{
|
|
GetBasePlayer()->SetPlaybackRate( 1.0f );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : event -
|
|
//-----------------------------------------------------------------------------
|
|
void CTFPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
|
|
{
|
|
Activity iGestureActivity = ACT_INVALID;
|
|
|
|
switch( event )
|
|
{
|
|
case PLAYERANIMEVENT_ATTACK_PRIMARY:
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayer();
|
|
if ( !pPlayer )
|
|
return;
|
|
|
|
CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
|
|
bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );
|
|
bool bIsSniperRifle = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE );
|
|
|
|
// Heavy weapons primary fire.
|
|
if ( bIsMinigun )
|
|
{
|
|
// Play standing primary fire.
|
|
iGestureActivity = ACT_MP_ATTACK_STAND_PRIMARYFIRE;
|
|
|
|
if ( m_bInSwim )
|
|
{
|
|
// Play swimming primary fire.
|
|
iGestureActivity = ACT_MP_ATTACK_SWIM_PRIMARYFIRE;
|
|
}
|
|
else if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
// Play crouching primary fire.
|
|
iGestureActivity = ACT_MP_ATTACK_CROUCH_PRIMARYFIRE;
|
|
}
|
|
|
|
if ( !IsGestureSlotPlaying( GESTURE_SLOT_ATTACK_AND_RELOAD, TranslateActivity(iGestureActivity) ) )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity );
|
|
}
|
|
}
|
|
else if ( bIsSniperRifle && pPlayer->m_Shared.InCond( TF_COND_ZOOMED ) )
|
|
{
|
|
// Weapon primary fire, zoomed in
|
|
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE_DEPLOYED );
|
|
}
|
|
else
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE_DEPLOYED );
|
|
}
|
|
|
|
iGestureActivity = ACT_VM_PRIMARYATTACK;
|
|
|
|
// Hold our deployed pose for a few seconds
|
|
m_flHoldDeployedPoseUntilTime = gpGlobals->curtime + 2.0;
|
|
}
|
|
else
|
|
{
|
|
// Weapon primary fire.
|
|
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_PRIMARYFIRE );
|
|
}
|
|
else
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_PRIMARYFIRE );
|
|
}
|
|
|
|
iGestureActivity = ACT_VM_PRIMARYATTACK;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case PLAYERANIMEVENT_VOICE_COMMAND_GESTURE:
|
|
{
|
|
if ( !IsGestureSlotActive( GESTURE_SLOT_ATTACK_AND_RELOAD ) )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, (Activity)nData );
|
|
}
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_ATTACK_SECONDARY:
|
|
{
|
|
// Weapon secondary fire.
|
|
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_CROUCH_SECONDARYFIRE );
|
|
}
|
|
else
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_SECONDARYFIRE );
|
|
}
|
|
|
|
iGestureActivity = ACT_VM_PRIMARYATTACK;
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_ATTACK_PRE:
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayer();
|
|
if ( !pPlayer )
|
|
return;
|
|
|
|
CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
|
|
bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );
|
|
|
|
bool bAutoKillPreFire = false;
|
|
if ( bIsMinigun )
|
|
{
|
|
bAutoKillPreFire = true;
|
|
}
|
|
|
|
if ( m_bInSwim && bIsMinigun )
|
|
{
|
|
// Weapon pre-fire. Used for minigun windup while swimming
|
|
iGestureActivity = ACT_MP_ATTACK_SWIM_PREFIRE;
|
|
}
|
|
else if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc in crouch.
|
|
iGestureActivity = ACT_MP_ATTACK_CROUCH_PREFIRE;
|
|
}
|
|
else
|
|
{
|
|
// Weapon pre-fire. Used for minigun windup, sniper aiming start, etc.
|
|
iGestureActivity = ACT_MP_ATTACK_STAND_PREFIRE;
|
|
}
|
|
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity, bAutoKillPreFire );
|
|
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_ATTACK_POST:
|
|
{
|
|
CTFPlayer *pPlayer = GetTFPlayer();
|
|
if ( !pPlayer )
|
|
return;
|
|
|
|
CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
|
|
bool bIsMinigun = ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN );
|
|
|
|
if ( m_bInSwim && bIsMinigun )
|
|
{
|
|
// Weapon pre-fire. Used for minigun winddown while swimming
|
|
iGestureActivity = ACT_MP_ATTACK_SWIM_POSTFIRE;
|
|
}
|
|
else if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
// Weapon post-fire. Used for minigun winddown in crouch.
|
|
iGestureActivity = ACT_MP_ATTACK_CROUCH_POSTFIRE;
|
|
}
|
|
else
|
|
{
|
|
// Weapon post-fire. Used for minigun winddown.
|
|
iGestureActivity = ACT_MP_ATTACK_STAND_POSTFIRE;
|
|
}
|
|
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, iGestureActivity );
|
|
|
|
break;
|
|
}
|
|
|
|
case PLAYERANIMEVENT_RELOAD:
|
|
{
|
|
// Weapon reload.
|
|
if ( m_bInAirWalk )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK );
|
|
}
|
|
else
|
|
{
|
|
BaseClass::DoAnimationEvent( event, nData );
|
|
}
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_RELOAD_LOOP:
|
|
{
|
|
// Weapon reload.
|
|
if ( m_bInAirWalk )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_LOOP );
|
|
}
|
|
else
|
|
{
|
|
BaseClass::DoAnimationEvent( event, nData );
|
|
}
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_RELOAD_END:
|
|
{
|
|
// Weapon reload.
|
|
if ( m_bInAirWalk )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_AIRWALK_END );
|
|
}
|
|
else
|
|
{
|
|
BaseClass::DoAnimationEvent( event, nData );
|
|
}
|
|
break;
|
|
}
|
|
case PLAYERANIMEVENT_DOUBLEJUMP:
|
|
{
|
|
// Check to see if we are jumping!
|
|
if ( !m_bJumping )
|
|
{
|
|
m_bJumping = true;
|
|
m_bFirstJumpFrame = true;
|
|
m_flJumpStartTime = gpGlobals->curtime;
|
|
RestartMainSequence();
|
|
}
|
|
|
|
// Force the air walk off.
|
|
m_bInAirWalk = false;
|
|
|
|
// Player the air dash gesture.
|
|
RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_DOUBLEJUMP );
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
BaseClass::DoAnimationEvent( event, nData );
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
// Make the weapon play the animation as well
|
|
if ( iGestureActivity != ACT_INVALID )
|
|
{
|
|
CBaseCombatWeapon *pWeapon = GetTFPlayer()->GetActiveWeapon();
|
|
if ( pWeapon )
|
|
{
|
|
pWeapon->SendWeaponAnim( iGestureActivity );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *idealActivity -
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFPlayerAnimState::HandleSwimming( Activity &idealActivity )
|
|
{
|
|
bool bInWater = BaseClass::HandleSwimming( idealActivity );
|
|
|
|
if ( bInWater )
|
|
{
|
|
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
|
|
{
|
|
CTFWeaponBase *pWpn = m_pTFPlayer->GetActiveTFWeapon();
|
|
if ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_MINIGUN )
|
|
{
|
|
idealActivity = ACT_MP_SWIM_DEPLOYED;
|
|
}
|
|
// Check for sniper deployed underwater - should only be when standing on something
|
|
else if ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE )
|
|
{
|
|
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_ZOOMED ) )
|
|
{
|
|
idealActivity = ACT_MP_SWIM_DEPLOYED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bInWater;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *idealActivity -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFPlayerAnimState::HandleMoving( Activity &idealActivity )
|
|
{
|
|
float flSpeed = GetOuterXYSpeed();
|
|
|
|
// If we move, cancel the deployed anim hold
|
|
if ( flSpeed > MOVING_MINIMUM_SPEED )
|
|
{
|
|
m_flHoldDeployedPoseUntilTime = 0.0;
|
|
}
|
|
|
|
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
|
|
{
|
|
if ( flSpeed > MOVING_MINIMUM_SPEED )
|
|
{
|
|
idealActivity = ACT_MP_DEPLOYED;
|
|
}
|
|
else
|
|
{
|
|
idealActivity = ACT_MP_DEPLOYED_IDLE;
|
|
}
|
|
}
|
|
else if ( m_flHoldDeployedPoseUntilTime > gpGlobals->curtime )
|
|
{
|
|
// Unless we move, hold the deployed pose for a number of seconds after being deployed
|
|
idealActivity = ACT_MP_DEPLOYED_IDLE;
|
|
}
|
|
else
|
|
{
|
|
return BaseClass::HandleMoving( idealActivity );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : *idealActivity -
|
|
// Output : Returns true on success, false on failure.
|
|
//-----------------------------------------------------------------------------
|
|
bool CTFPlayerAnimState::HandleDucking( Activity &idealActivity )
|
|
{
|
|
if ( GetBasePlayer()->GetFlags() & FL_DUCKING )
|
|
{
|
|
if ( GetOuterXYSpeed() < MOVING_MINIMUM_SPEED )
|
|
{
|
|
idealActivity = ACT_MP_CROUCH_IDLE;
|
|
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) || m_flHoldDeployedPoseUntilTime > gpGlobals->curtime )
|
|
{
|
|
idealActivity = ACT_MP_CROUCH_DEPLOYED_IDLE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
idealActivity = ACT_MP_CROUCHWALK;
|
|
|
|
if ( m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
|
|
{
|
|
// Don't do this for the heavy! we don't usually let him deployed crouch walk
|
|
bool bIsMinigun = false;
|
|
|
|
CTFPlayer *pPlayer = GetTFPlayer();
|
|
if ( pPlayer && pPlayer->GetActiveTFWeapon() )
|
|
{
|
|
bIsMinigun = ( pPlayer->GetActiveTFWeapon()->GetWeaponID() == TF_WEAPON_MINIGUN );
|
|
}
|
|
|
|
if ( !bIsMinigun )
|
|
{
|
|
idealActivity = ACT_MP_CROUCH_DEPLOYED;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
bool CTFPlayerAnimState::HandleJumping( Activity &idealActivity )
|
|
{
|
|
Vector vecVelocity;
|
|
GetOuterAbsVelocity( vecVelocity );
|
|
|
|
// Don't allow a firing heavy to jump or air walk.
|
|
if ( m_pTFPlayer->GetPlayerClass()->IsClass( TF_CLASS_HEAVYWEAPONS ) && m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
|
|
return false;
|
|
|
|
// Handle air walking before handling jumping - air walking supersedes jump
|
|
TFPlayerClassData_t *pData = m_pTFPlayer->GetPlayerClass()->GetData();
|
|
bool bValidAirWalkClass = ( pData && pData->m_bDontDoAirwalk == false );
|
|
|
|
if ( bValidAirWalkClass && ( vecVelocity.z > 300.0f || m_bInAirWalk ) )
|
|
{
|
|
// Check to see if we were in an airwalk and now we are basically on the ground.
|
|
if ( ( GetBasePlayer()->GetFlags() & FL_ONGROUND ) && m_bInAirWalk )
|
|
{
|
|
m_bInAirWalk = false;
|
|
RestartMainSequence();
|
|
RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );
|
|
}
|
|
else if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
|
|
{
|
|
// Turn off air walking and reset the animation.
|
|
m_bInAirWalk = false;
|
|
RestartMainSequence();
|
|
}
|
|
else if ( ( GetBasePlayer()->GetFlags() & FL_ONGROUND ) == 0 )
|
|
{
|
|
// In an air walk.
|
|
idealActivity = ACT_MP_AIRWALK;
|
|
m_bInAirWalk = true;
|
|
}
|
|
}
|
|
// Jumping.
|
|
else
|
|
{
|
|
if ( m_bJumping )
|
|
{
|
|
// Remove me once all classes are doing the new jump
|
|
TFPlayerClassData_t *pData = m_pTFPlayer->GetPlayerClass()->GetData();
|
|
bool bNewJump = ( pData && pData->m_bDontDoNewJump == false );
|
|
|
|
if ( m_bFirstJumpFrame )
|
|
{
|
|
m_bFirstJumpFrame = false;
|
|
RestartMainSequence(); // Reset the animation.
|
|
}
|
|
|
|
// Reset if we hit water and start swimming.
|
|
if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
|
|
{
|
|
m_bJumping = false;
|
|
RestartMainSequence();
|
|
}
|
|
// Don't check if he's on the ground for a sec.. sometimes the client still has the
|
|
// on-ground flag set right when the message comes in.
|
|
else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
|
|
{
|
|
if ( GetBasePlayer()->GetFlags() & FL_ONGROUND )
|
|
{
|
|
m_bJumping = false;
|
|
RestartMainSequence();
|
|
|
|
if ( bNewJump )
|
|
{
|
|
RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we're still jumping
|
|
if ( m_bJumping )
|
|
{
|
|
if ( bNewJump )
|
|
{
|
|
if ( gpGlobals->curtime - m_flJumpStartTime > 0.5 )
|
|
{
|
|
idealActivity = ACT_MP_JUMP_FLOAT;
|
|
}
|
|
else
|
|
{
|
|
idealActivity = ACT_MP_JUMP_START;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
idealActivity = ACT_MP_JUMP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( m_bJumping || m_bInAirWalk )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|