You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
622 lines
16 KiB
622 lines
16 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "base_playeranimstate.h"
|
||
|
#include "tier0/vprof.h"
|
||
|
#include "animation.h"
|
||
|
#include "studio.h"
|
||
|
#include "apparent_velocity_helper.h"
|
||
|
#include "utldict.h"
|
||
|
|
||
|
#include "sdk_playeranimstate.h"
|
||
|
#include "weapon_sdkbase.h"
|
||
|
#include "weapon_basesdkgrenade.h"
|
||
|
|
||
|
#ifdef CLIENT_DLL
|
||
|
#include "c_sdk_player.h"
|
||
|
#include "bone_setup.h"
|
||
|
#include "interpolatedvar.h"
|
||
|
#else
|
||
|
#include "sdk_player.h"
|
||
|
#endif
|
||
|
|
||
|
#define ANIM_TOPSPEED_WALK 100
|
||
|
#define ANIM_TOPSPEED_RUN 250
|
||
|
#define ANIM_TOPSPEED_RUN_CROUCH 85
|
||
|
|
||
|
#define DEFAULT_IDLE_NAME "idle_upper_"
|
||
|
#define DEFAULT_CROUCH_IDLE_NAME "crouch_idle_upper_"
|
||
|
#define DEFAULT_CROUCH_WALK_NAME "crouch_walk_upper_"
|
||
|
#define DEFAULT_WALK_NAME "walk_upper_"
|
||
|
#define DEFAULT_RUN_NAME "run_upper_"
|
||
|
|
||
|
#define DEFAULT_FIRE_IDLE_NAME "idle_shoot_"
|
||
|
#define DEFAULT_FIRE_CROUCH_NAME "crouch_idle_shoot_"
|
||
|
#define DEFAULT_FIRE_CROUCH_WALK_NAME "crouch_walk_shoot_"
|
||
|
#define DEFAULT_FIRE_WALK_NAME "walk_shoot_"
|
||
|
#define DEFAULT_FIRE_RUN_NAME "run_shoot_"
|
||
|
|
||
|
|
||
|
#define FIRESEQUENCE_LAYER (AIMSEQUENCE_LAYER+NUM_AIMSEQUENCE_LAYERS)
|
||
|
#define RELOADSEQUENCE_LAYER (FIRESEQUENCE_LAYER + 1)
|
||
|
#define GRENADESEQUENCE_LAYER (RELOADSEQUENCE_LAYER + 1)
|
||
|
#define NUM_LAYERS_WANTED (GRENADESEQUENCE_LAYER + 1)
|
||
|
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------------------------------------ //
|
||
|
// CSDKPlayerAnimState declaration.
|
||
|
// ------------------------------------------------------------------------------------------------ //
|
||
|
|
||
|
class CSDKPlayerAnimState : public CBasePlayerAnimState, public ISDKPlayerAnimState
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_CLASS( CSDKPlayerAnimState, CBasePlayerAnimState );
|
||
|
friend ISDKPlayerAnimState* CreatePlayerAnimState( CBaseAnimatingOverlay *pEntity, ISDKPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences );
|
||
|
|
||
|
CSDKPlayerAnimState();
|
||
|
|
||
|
virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
|
||
|
virtual bool IsThrowingGrenade();
|
||
|
virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle );
|
||
|
virtual void ClearAnimationState();
|
||
|
virtual bool CanThePlayerMove();
|
||
|
virtual float GetCurrentMaxGroundSpeed();
|
||
|
virtual Activity CalcMainActivity();
|
||
|
virtual void DebugShowAnimState( int iStartLine );
|
||
|
virtual void ComputeSequences( CStudioHdr *pStudioHdr );
|
||
|
virtual void ClearAnimationLayers();
|
||
|
|
||
|
|
||
|
void InitSDK( CBaseAnimatingOverlay *pPlayer, ISDKPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences );
|
||
|
|
||
|
protected:
|
||
|
|
||
|
int CalcFireLayerSequence(PlayerAnimEvent_t event);
|
||
|
void ComputeFireSequence(CStudioHdr *pStudioHdr);
|
||
|
|
||
|
void ComputeReloadSequence(CStudioHdr *pStudioHdr);
|
||
|
int CalcReloadLayerSequence();
|
||
|
|
||
|
bool IsOuterGrenadePrimed();
|
||
|
void ComputeGrenadeSequence( CStudioHdr *pStudioHdr );
|
||
|
int CalcGrenadePrimeSequence();
|
||
|
int CalcGrenadeThrowSequence();
|
||
|
int GetOuterGrenadeThrowCounter();
|
||
|
|
||
|
const char* GetWeaponSuffix();
|
||
|
bool HandleJumping();
|
||
|
|
||
|
void UpdateLayerSequenceGeneric( CStudioHdr *pStudioHdr, int iLayer, bool &bEnabled, float &flCurCycle, int &iSequence, bool bWaitAtEnd );
|
||
|
|
||
|
private:
|
||
|
|
||
|
// Current state variables.
|
||
|
bool m_bJumping; // Set on a jump event.
|
||
|
float m_flJumpStartTime;
|
||
|
bool m_bFirstJumpFrame;
|
||
|
|
||
|
// Aim sequence plays reload while this is on.
|
||
|
bool m_bReloading;
|
||
|
float m_flReloadCycle;
|
||
|
int m_iReloadSequence;
|
||
|
|
||
|
// This is set to true if ANY animation is being played in the fire layer.
|
||
|
bool m_bFiring; // If this is on, then it'll continue the fire animation in the fire layer
|
||
|
// until it completes.
|
||
|
int m_iFireSequence; // (For any sequences in the fire layer, including grenade throw).
|
||
|
float m_flFireCycle;
|
||
|
|
||
|
// These control grenade animations.
|
||
|
bool m_bThrowingGrenade;
|
||
|
bool m_bPrimingGrenade;
|
||
|
float m_flGrenadeCycle;
|
||
|
int m_iGrenadeSequence;
|
||
|
int m_iLastThrowGrenadeCounter; // used to detect when the guy threw the grenade.
|
||
|
|
||
|
ISDKPlayerAnimStateHelpers *m_pHelpers;
|
||
|
};
|
||
|
|
||
|
|
||
|
ISDKPlayerAnimState* CreatePlayerAnimState( CBaseAnimatingOverlay *pEntity, ISDKPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences )
|
||
|
{
|
||
|
CSDKPlayerAnimState *pRet = new CSDKPlayerAnimState;
|
||
|
pRet->InitSDK( pEntity, pHelpers, legAnimType, bUseAimSequences );
|
||
|
return pRet;
|
||
|
}
|
||
|
|
||
|
// ------------------------------------------------------------------------------------------------ //
|
||
|
// CSDKPlayerAnimState implementation.
|
||
|
// ------------------------------------------------------------------------------------------------ //
|
||
|
|
||
|
CSDKPlayerAnimState::CSDKPlayerAnimState()
|
||
|
{
|
||
|
m_pOuter = NULL;
|
||
|
m_bReloading = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::InitSDK( CBaseAnimatingOverlay *pEntity, ISDKPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences )
|
||
|
{
|
||
|
CModAnimConfig config;
|
||
|
config.m_flMaxBodyYawDegrees = 90;
|
||
|
config.m_LegAnimType = legAnimType;
|
||
|
config.m_bUseAimSequences = bUseAimSequences;
|
||
|
|
||
|
m_pHelpers = pHelpers;
|
||
|
|
||
|
BaseClass::Init( pEntity, config );
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ClearAnimationState()
|
||
|
{
|
||
|
m_bJumping = false;
|
||
|
m_bFiring = false;
|
||
|
m_bReloading = false;
|
||
|
m_bThrowingGrenade = m_bPrimingGrenade = false;
|
||
|
m_iLastThrowGrenadeCounter = GetOuterGrenadeThrowCounter();
|
||
|
|
||
|
BaseClass::ClearAnimationState();
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
|
||
|
{
|
||
|
Assert( event != PLAYERANIMEVENT_THROW_GRENADE );
|
||
|
|
||
|
if ( event == PLAYERANIMEVENT_FIRE_GUN_PRIMARY ||
|
||
|
event == PLAYERANIMEVENT_FIRE_GUN_SECONDARY )
|
||
|
{
|
||
|
// Regardless of what we're doing in the fire layer, restart it.
|
||
|
m_flFireCycle = 0;
|
||
|
m_iFireSequence = CalcFireLayerSequence( event );
|
||
|
m_bFiring = m_iFireSequence != -1;
|
||
|
}
|
||
|
else if ( event == PLAYERANIMEVENT_JUMP )
|
||
|
{
|
||
|
// Play the jump animation.
|
||
|
m_bJumping = true;
|
||
|
m_bFirstJumpFrame = true;
|
||
|
m_flJumpStartTime = gpGlobals->curtime;
|
||
|
}
|
||
|
else if ( event == PLAYERANIMEVENT_RELOAD )
|
||
|
{
|
||
|
m_iReloadSequence = CalcReloadLayerSequence();
|
||
|
if ( m_iReloadSequence != -1 )
|
||
|
{
|
||
|
m_bReloading = true;
|
||
|
m_flReloadCycle = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Assert( !"CSDKPlayerAnimState::DoAnimationEvent" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
float g_flThrowGrenadeFraction = 0.25;
|
||
|
bool CSDKPlayerAnimState::IsThrowingGrenade()
|
||
|
{
|
||
|
if ( m_bThrowingGrenade )
|
||
|
{
|
||
|
// An animation event would be more appropriate here.
|
||
|
return m_flGrenadeCycle < g_flThrowGrenadeFraction;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool bThrowPending = (m_iLastThrowGrenadeCounter != GetOuterGrenadeThrowCounter());
|
||
|
return bThrowPending || IsOuterGrenadePrimed();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::CalcReloadLayerSequence()
|
||
|
{
|
||
|
const char *pSuffix = GetWeaponSuffix();
|
||
|
if ( !pSuffix )
|
||
|
return -1;
|
||
|
|
||
|
CWeaponSDKBase *pWeapon = m_pHelpers->SDKAnim_GetActiveWeapon();
|
||
|
if ( !pWeapon )
|
||
|
return -1;
|
||
|
|
||
|
// First, look for reload_<weapon name>.
|
||
|
char szName[512];
|
||
|
Q_snprintf( szName, sizeof( szName ), "reload_%s", pSuffix );
|
||
|
int iReloadSequence = m_pOuter->LookupSequence( szName );
|
||
|
if ( iReloadSequence != -1 )
|
||
|
return iReloadSequence;
|
||
|
|
||
|
//SDKTODO
|
||
|
/*
|
||
|
// Ok, look for generic categories.. pistol, shotgun, rifle, etc.
|
||
|
if ( pWeapon->GetSDKWpnData().m_WeaponType == WEAPONTYPE_PISTOL )
|
||
|
{
|
||
|
Q_snprintf( szName, sizeof( szName ), "reload_pistol" );
|
||
|
iReloadSequence = m_pOuter->LookupSequence( szName );
|
||
|
if ( iReloadSequence != -1 )
|
||
|
return iReloadSequence;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// Fall back to reload_m4.
|
||
|
iReloadSequence = CalcSequenceIndex( "reload_m4" );
|
||
|
if ( iReloadSequence > 0 )
|
||
|
return iReloadSequence;
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifdef CLIENT_DLL
|
||
|
void CSDKPlayerAnimState::UpdateLayerSequenceGeneric( CStudioHdr *pStudioHdr, int iLayer, bool &bEnabled, float &flCurCycle, int &iSequence, bool bWaitAtEnd )
|
||
|
{
|
||
|
if ( !bEnabled )
|
||
|
return;
|
||
|
|
||
|
// Increment the fire sequence's cycle.
|
||
|
flCurCycle += m_pOuter->GetSequenceCycleRate( pStudioHdr, iSequence ) * gpGlobals->frametime;
|
||
|
if ( flCurCycle > 1 )
|
||
|
{
|
||
|
if ( bWaitAtEnd )
|
||
|
{
|
||
|
flCurCycle = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Not firing anymore.
|
||
|
bEnabled = false;
|
||
|
iSequence = 0;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now dump the state into its animation layer.
|
||
|
C_AnimationLayer *pLayer = m_pOuter->GetAnimOverlay( iLayer );
|
||
|
|
||
|
pLayer->m_flCycle = flCurCycle;
|
||
|
pLayer->m_nSequence = iSequence;
|
||
|
|
||
|
pLayer->m_flPlaybackRate = 1.0;
|
||
|
pLayer->m_flWeight = 1.0f;
|
||
|
pLayer->m_nOrder = iLayer;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
bool CSDKPlayerAnimState::IsOuterGrenadePrimed()
|
||
|
{
|
||
|
CBaseCombatCharacter *pChar = m_pOuter->MyCombatCharacterPointer();
|
||
|
if ( pChar )
|
||
|
{
|
||
|
CBaseSDKGrenade *pGren = dynamic_cast<CBaseSDKGrenade*>( pChar->GetActiveWeapon() );
|
||
|
return pGren && pGren->IsPinPulled();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ComputeGrenadeSequence( CStudioHdr *pStudioHdr )
|
||
|
{
|
||
|
#ifdef CLIENT_DLL
|
||
|
if ( m_bThrowingGrenade )
|
||
|
{
|
||
|
UpdateLayerSequenceGeneric( pStudioHdr, GRENADESEQUENCE_LAYER, m_bThrowingGrenade, m_flGrenadeCycle, m_iGrenadeSequence, false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Priming the grenade isn't an event.. we just watch the player for it.
|
||
|
// Also play the prime animation first if he wants to throw the grenade.
|
||
|
bool bThrowPending = (m_iLastThrowGrenadeCounter != GetOuterGrenadeThrowCounter());
|
||
|
if ( IsOuterGrenadePrimed() || bThrowPending )
|
||
|
{
|
||
|
if ( !m_bPrimingGrenade )
|
||
|
{
|
||
|
// If this guy just popped into our PVS, and he's got his grenade primed, then
|
||
|
// let's assume that it's all the way primed rather than playing the prime
|
||
|
// animation from the start.
|
||
|
if ( TimeSinceLastAnimationStateClear() < 0.4f )
|
||
|
m_flGrenadeCycle = 1;
|
||
|
else
|
||
|
m_flGrenadeCycle = 0;
|
||
|
|
||
|
m_iGrenadeSequence = CalcGrenadePrimeSequence();
|
||
|
}
|
||
|
|
||
|
m_bPrimingGrenade = true;
|
||
|
UpdateLayerSequenceGeneric( pStudioHdr, GRENADESEQUENCE_LAYER, m_bPrimingGrenade, m_flGrenadeCycle, m_iGrenadeSequence, true );
|
||
|
|
||
|
// If we're waiting to throw and we're done playing the prime animation...
|
||
|
if ( bThrowPending && m_flGrenadeCycle == 1 )
|
||
|
{
|
||
|
m_iLastThrowGrenadeCounter = GetOuterGrenadeThrowCounter();
|
||
|
|
||
|
// Now play the throw animation.
|
||
|
m_iGrenadeSequence = CalcGrenadeThrowSequence();
|
||
|
if ( m_iGrenadeSequence != -1 )
|
||
|
{
|
||
|
// Configure to start playing
|
||
|
m_bThrowingGrenade = true;
|
||
|
m_bPrimingGrenade = false;
|
||
|
m_flGrenadeCycle = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_bPrimingGrenade = false;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::CalcGrenadePrimeSequence()
|
||
|
{
|
||
|
return CalcSequenceIndex( "idle_shoot_gren1" );
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::CalcGrenadeThrowSequence()
|
||
|
{
|
||
|
return CalcSequenceIndex( "idle_shoot_gren2" );
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::GetOuterGrenadeThrowCounter()
|
||
|
{
|
||
|
CSDKPlayer *pPlayer = dynamic_cast<CSDKPlayer*>( m_pOuter );
|
||
|
if ( pPlayer )
|
||
|
return pPlayer->m_iThrowGrenadeCounter;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ComputeReloadSequence( CStudioHdr *pStudioHdr )
|
||
|
{
|
||
|
#ifdef CLIENT_DLL
|
||
|
UpdateLayerSequenceGeneric( pStudioHdr, RELOADSEQUENCE_LAYER, m_bReloading, m_flReloadCycle, m_iReloadSequence, false );
|
||
|
#else
|
||
|
// Server doesn't bother with different fire sequences.
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
|
||
|
{
|
||
|
const char *pSuffix = GetWeaponSuffix();
|
||
|
if ( !pSuffix )
|
||
|
return 0;
|
||
|
|
||
|
if ( bForceIdle )
|
||
|
{
|
||
|
switch ( GetCurrentMainSequenceActivity() )
|
||
|
{
|
||
|
case ACT_CROUCHIDLE:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix );
|
||
|
|
||
|
default:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_IDLE_NAME, pSuffix );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch ( GetCurrentMainSequenceActivity() )
|
||
|
{
|
||
|
case ACT_RUN:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_RUN_NAME, pSuffix );
|
||
|
|
||
|
case ACT_WALK:
|
||
|
case ACT_RUNTOIDLE:
|
||
|
case ACT_IDLETORUN:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_WALK_NAME, pSuffix );
|
||
|
|
||
|
case ACT_CROUCHIDLE:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix );
|
||
|
|
||
|
case ACT_RUN_CROUCH:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_CROUCH_WALK_NAME, pSuffix );
|
||
|
|
||
|
case ACT_IDLE:
|
||
|
default:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_IDLE_NAME, pSuffix );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
const char* CSDKPlayerAnimState::GetWeaponSuffix()
|
||
|
{
|
||
|
// Figure out the weapon suffix.
|
||
|
CWeaponSDKBase *pWeapon = m_pHelpers->SDKAnim_GetActiveWeapon();
|
||
|
if ( !pWeapon )
|
||
|
return "Pistol";
|
||
|
|
||
|
const char *pSuffix = pWeapon->GetSDKWpnData().m_szAnimExtension;
|
||
|
|
||
|
return pSuffix;
|
||
|
}
|
||
|
|
||
|
|
||
|
int CSDKPlayerAnimState::CalcFireLayerSequence(PlayerAnimEvent_t event)
|
||
|
{
|
||
|
// Figure out the weapon suffix.
|
||
|
CWeaponSDKBase *pWeapon = m_pHelpers->SDKAnim_GetActiveWeapon();
|
||
|
if ( !pWeapon )
|
||
|
return 0;
|
||
|
|
||
|
const char *pSuffix = GetWeaponSuffix();
|
||
|
if ( !pSuffix )
|
||
|
return 0;
|
||
|
|
||
|
// Don't rely on their weapon here because the player has usually switched to their
|
||
|
// pistol or rifle by the time the PLAYERANIMEVENT_THROW_GRENADE message gets to the client.
|
||
|
if ( event == PLAYERANIMEVENT_THROW_GRENADE )
|
||
|
{
|
||
|
pSuffix = "Gren";
|
||
|
}
|
||
|
|
||
|
switch ( GetCurrentMainSequenceActivity() )
|
||
|
{
|
||
|
case ACT_PLAYER_RUN_FIRE:
|
||
|
case ACT_RUN:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_FIRE_RUN_NAME, pSuffix );
|
||
|
|
||
|
case ACT_PLAYER_WALK_FIRE:
|
||
|
case ACT_WALK:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_FIRE_WALK_NAME, pSuffix );
|
||
|
|
||
|
case ACT_PLAYER_CROUCH_FIRE:
|
||
|
case ACT_CROUCHIDLE:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_FIRE_CROUCH_NAME, pSuffix );
|
||
|
|
||
|
case ACT_PLAYER_CROUCH_WALK_FIRE:
|
||
|
case ACT_RUN_CROUCH:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_FIRE_CROUCH_WALK_NAME, pSuffix );
|
||
|
|
||
|
default:
|
||
|
case ACT_PLAYER_IDLE_FIRE:
|
||
|
return CalcSequenceIndex( "%s%s", DEFAULT_FIRE_IDLE_NAME, pSuffix );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CSDKPlayerAnimState::CanThePlayerMove()
|
||
|
{
|
||
|
return m_pHelpers->SDKAnim_CanMove();
|
||
|
}
|
||
|
|
||
|
|
||
|
float CSDKPlayerAnimState::GetCurrentMaxGroundSpeed()
|
||
|
{
|
||
|
Activity currentActivity = m_pOuter->GetSequenceActivity( m_pOuter->GetSequence() );
|
||
|
if ( currentActivity == ACT_WALK || currentActivity == ACT_IDLE )
|
||
|
return ANIM_TOPSPEED_WALK;
|
||
|
else if ( currentActivity == ACT_RUN )
|
||
|
return ANIM_TOPSPEED_RUN;
|
||
|
else if ( currentActivity == ACT_RUN_CROUCH )
|
||
|
return ANIM_TOPSPEED_RUN_CROUCH;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CSDKPlayerAnimState::HandleJumping()
|
||
|
{
|
||
|
if ( m_bJumping )
|
||
|
{
|
||
|
if ( m_bFirstJumpFrame )
|
||
|
{
|
||
|
m_bFirstJumpFrame = false;
|
||
|
RestartMainSequence(); // Reset the animation.
|
||
|
}
|
||
|
|
||
|
// 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.
|
||
|
if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
|
||
|
{
|
||
|
if ( m_pOuter->GetFlags() & FL_ONGROUND )
|
||
|
{
|
||
|
m_bJumping = false;
|
||
|
RestartMainSequence(); // Reset the animation.
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Are we still jumping? If so, keep playing the jump animation.
|
||
|
return m_bJumping;
|
||
|
}
|
||
|
|
||
|
|
||
|
Activity CSDKPlayerAnimState::CalcMainActivity()
|
||
|
{
|
||
|
float flOuterSpeed = GetOuterXYSpeed();
|
||
|
|
||
|
if ( HandleJumping() )
|
||
|
{
|
||
|
return ACT_HOP;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Activity idealActivity = ACT_IDLE;
|
||
|
|
||
|
if ( m_pOuter->GetFlags() & FL_DUCKING )
|
||
|
{
|
||
|
if ( flOuterSpeed > MOVING_MINIMUM_SPEED )
|
||
|
idealActivity = ACT_RUN_CROUCH;
|
||
|
else
|
||
|
idealActivity = ACT_CROUCHIDLE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( flOuterSpeed > MOVING_MINIMUM_SPEED )
|
||
|
{
|
||
|
if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
|
||
|
idealActivity = ACT_RUN;
|
||
|
else
|
||
|
idealActivity = ACT_WALK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
idealActivity = ACT_IDLE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return idealActivity;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::DebugShowAnimState( int iStartLine )
|
||
|
{
|
||
|
#ifdef CLIENT_DLL
|
||
|
engine->Con_NPrintf( iStartLine++, "fire : %s, cycle: %.2f\n", m_bFiring ? GetSequenceName( m_pOuter->GetModelPtr(), m_iFireSequence ) : "[not firing]", m_flFireCycle );
|
||
|
engine->Con_NPrintf( iStartLine++, "reload: %s, cycle: %.2f\n", m_bReloading ? GetSequenceName( m_pOuter->GetModelPtr(), m_iReloadSequence ) : "[not reloading]", m_flReloadCycle );
|
||
|
BaseClass::DebugShowAnimState( iStartLine );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr )
|
||
|
{
|
||
|
BaseClass::ComputeSequences( pStudioHdr );
|
||
|
|
||
|
ComputeFireSequence( pStudioHdr );
|
||
|
ComputeReloadSequence( pStudioHdr );
|
||
|
ComputeGrenadeSequence( pStudioHdr );
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ClearAnimationLayers()
|
||
|
{
|
||
|
if ( !m_pOuter )
|
||
|
return;
|
||
|
|
||
|
m_pOuter->SetNumAnimOverlays( NUM_LAYERS_WANTED );
|
||
|
for ( int i=0; i < m_pOuter->GetNumAnimOverlays(); i++ )
|
||
|
{
|
||
|
m_pOuter->GetAnimOverlay( i )->SetOrder( CBaseAnimatingOverlay::MAX_OVERLAYS );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CSDKPlayerAnimState::ComputeFireSequence( CStudioHdr *pStudioHdr )
|
||
|
{
|
||
|
#ifdef CLIENT_DLL
|
||
|
UpdateLayerSequenceGeneric( pStudioHdr, FIRESEQUENCE_LAYER, m_bFiring, m_flFireCycle, m_iFireSequence, false );
|
||
|
#else
|
||
|
// Server doesn't bother with different fire sequences.
|
||
|
#endif
|
||
|
}
|