mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tfc_playeranimstate.h"
|
||||
#include "base_playeranimstate.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "animation.h"
|
||||
#include "studio.h"
|
||||
#include "apparent_velocity_helper.h"
|
||||
#include "utldict.h"
|
||||
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "c_tfc_player.h"
|
||||
#else
|
||||
#include "tfc_player.h"
|
||||
#endif
|
||||
|
||||
|
||||
// When moving this fast, he plays run anim.
|
||||
#define ARBITRARY_RUN_SPEED 175.0f
|
||||
|
||||
#define MAX_STANDING_RUN_SPEED 320
|
||||
#define MAX_CROUCHED_RUN_SPEED 110
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// CPlayerAnimState declaration.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class CTFCPlayerAnimState : public ITFCPlayerAnimState, public CBasePlayerAnimState
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CTFCPlayerAnimState, CBasePlayerAnimState );
|
||||
|
||||
CTFCPlayerAnimState();
|
||||
void InitTFC( CTFCPlayer *pPlayer );
|
||||
|
||||
// This is called by both the client and the server in the same way to trigger events for
|
||||
// players firing, jumping, throwing grenades, etc.
|
||||
virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData );
|
||||
virtual int CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight );
|
||||
virtual float SetOuterBodyYaw( float flValue );
|
||||
virtual Activity CalcMainActivity();
|
||||
virtual float GetCurrentMaxGroundSpeed();
|
||||
virtual void ClearAnimationState();
|
||||
virtual bool ShouldUpdateAnimState();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const char* GetWeaponSuffix();
|
||||
bool HandleJumping();
|
||||
bool HandleDeath( Activity *deathActivity );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CTFCPlayer *m_pOuterTFC;
|
||||
|
||||
bool m_bJumping;
|
||||
bool m_bFirstJumpFrame;
|
||||
float m_flJumpStartTime;
|
||||
|
||||
bool m_bFiring;
|
||||
float m_flFireStartTime;
|
||||
|
||||
bool m_bDying;
|
||||
Activity m_DeathActivity;
|
||||
};
|
||||
|
||||
|
||||
ITFCPlayerAnimState* CreatePlayerAnimState( CTFCPlayer *pPlayer )
|
||||
{
|
||||
CTFCPlayerAnimState *pRet = new CTFCPlayerAnimState;
|
||||
pRet->InitTFC( pPlayer );
|
||||
return pRet;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// CTFCPlayerAnimState implementation.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
CTFCPlayerAnimState::CTFCPlayerAnimState()
|
||||
{
|
||||
m_pOuterTFC = NULL;
|
||||
m_bJumping = false;
|
||||
m_bFirstJumpFrame = false;
|
||||
m_bFiring = false;
|
||||
}
|
||||
|
||||
|
||||
void CTFCPlayerAnimState::InitTFC( CTFCPlayer *pPlayer )
|
||||
{
|
||||
m_pOuterTFC = pPlayer;
|
||||
|
||||
CModAnimConfig config;
|
||||
config.m_flMaxBodyYawDegrees = 30;
|
||||
config.m_LegAnimType = LEGANIM_GOLDSRC;
|
||||
config.m_bUseAimSequences = true;
|
||||
|
||||
BaseClass::Init( pPlayer, config );
|
||||
}
|
||||
|
||||
|
||||
const char* CTFCPlayerAnimState::GetWeaponSuffix()
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = m_pOuterTFC->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
return pWeapon->GetWpnData().szAnimationPrefix;
|
||||
else
|
||||
return "shotgun";
|
||||
}
|
||||
|
||||
|
||||
int CTFCPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight )
|
||||
{
|
||||
const char *pWeaponSuffix = GetWeaponSuffix();
|
||||
if ( !pWeaponSuffix )
|
||||
return 0;
|
||||
|
||||
// Are we aiming or firing?
|
||||
const char *pAimOrShoot = "aim";
|
||||
if ( m_bFiring )
|
||||
pAimOrShoot = "shoot";
|
||||
|
||||
// Are we standing or crouching?
|
||||
int iSequence = 0;
|
||||
const char *pPrefix = "ref";
|
||||
if ( m_bDying )
|
||||
{
|
||||
// While dying, only play the main sequence.. don't layer this one on top.
|
||||
*flAimSequenceWeight = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( GetCurrentMainSequenceActivity() )
|
||||
{
|
||||
case ACT_CROUCHIDLE:
|
||||
case ACT_RUN_CROUCH:
|
||||
pPrefix = "crouch";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iSequence = CalcSequenceIndex( "%s_%s_%s", pPrefix, pAimOrShoot, pWeaponSuffix );
|
||||
|
||||
// Check if we're done firing.
|
||||
if ( m_bFiring )
|
||||
{
|
||||
float dur = m_pOuterTFC->SequenceDuration( iSequence );
|
||||
*flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
|
||||
if ( *flCycle >= 1 )
|
||||
{
|
||||
*flCycle = 1;
|
||||
m_bFiring = false;
|
||||
}
|
||||
}
|
||||
|
||||
return iSequence;
|
||||
}
|
||||
|
||||
|
||||
void CTFCPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData )
|
||||
{
|
||||
if ( event == PLAYERANIMEVENT_JUMP )
|
||||
{
|
||||
// Main animation goes to ACT_HOP.
|
||||
m_bJumping = true;
|
||||
m_bFirstJumpFrame = true;
|
||||
m_flJumpStartTime = gpGlobals->curtime;
|
||||
}
|
||||
else if ( event == PLAYERANIMEVENT_FIRE_GUN )
|
||||
{
|
||||
// The middle part of the aim layer sequence becomes "shoot" until that animation is complete.
|
||||
m_bFiring = true;
|
||||
m_flFireStartTime = gpGlobals->curtime;
|
||||
}
|
||||
else if ( event == PLAYERANIMEVENT_DIE )
|
||||
{
|
||||
m_bFiring = m_bJumping = false;
|
||||
m_bDying = true;
|
||||
|
||||
Activity acts[] =
|
||||
{
|
||||
ACT_DIESIMPLE,
|
||||
ACT_DIEBACKWARD,
|
||||
ACT_DIEFORWARD,
|
||||
ACT_DIE_HEADSHOT,
|
||||
ACT_DIE_GUTSHOT
|
||||
};
|
||||
|
||||
m_DeathActivity = acts[ RandomInt( 0, ARRAYSIZE( acts ) - 1 ) ];
|
||||
RestartMainSequence(); // Play a death animation.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float CTFCPlayerAnimState::SetOuterBodyYaw( float flValue )
|
||||
{
|
||||
m_pOuterTFC->SetBoneController( 0, flValue );
|
||||
return flValue;
|
||||
}
|
||||
|
||||
|
||||
bool CTFCPlayerAnimState::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_pOuterTFC->GetFlags() & FL_ONGROUND )
|
||||
{
|
||||
m_bJumping = false;
|
||||
RestartMainSequence(); // Reset the animation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Are we still jumping? If so, keep playing the jump animation.
|
||||
return m_bJumping;
|
||||
}
|
||||
|
||||
|
||||
bool CTFCPlayerAnimState::HandleDeath( Activity *deathActivity )
|
||||
{
|
||||
if ( m_bDying )
|
||||
{
|
||||
if ( m_pOuterTFC->IsAlive() )
|
||||
{
|
||||
m_bDying = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*deathActivity = m_DeathActivity;
|
||||
}
|
||||
}
|
||||
return m_bDying;
|
||||
}
|
||||
|
||||
|
||||
Activity CTFCPlayerAnimState::CalcMainActivity()
|
||||
{
|
||||
Activity deathActivity = ACT_IDLE;
|
||||
if ( HandleDeath( &deathActivity ) )
|
||||
{
|
||||
return deathActivity;
|
||||
}
|
||||
else if ( HandleJumping() )
|
||||
{
|
||||
return ACT_HOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Activity idealActivity = ACT_IDLE;
|
||||
float flOuterSpeed = GetOuterXYSpeed();
|
||||
|
||||
if ( m_pOuterTFC->GetFlags() & FL_DUCKING )
|
||||
{
|
||||
if ( flOuterSpeed > 0.1f )
|
||||
idealActivity = ACT_RUN_CROUCH;
|
||||
else
|
||||
idealActivity = ACT_CROUCHIDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flOuterSpeed > 0.1f )
|
||||
{
|
||||
if ( flOuterSpeed > ARBITRARY_RUN_SPEED )
|
||||
idealActivity = ACT_RUN;
|
||||
else
|
||||
idealActivity = ACT_WALK;
|
||||
}
|
||||
else
|
||||
{
|
||||
idealActivity = ACT_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
return idealActivity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float CTFCPlayerAnimState::GetCurrentMaxGroundSpeed()
|
||||
{
|
||||
Activity act = GetCurrentMainSequenceActivity();
|
||||
if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
|
||||
return MAX_CROUCHED_RUN_SPEED;
|
||||
else
|
||||
return MAX_STANDING_RUN_SPEED;
|
||||
}
|
||||
|
||||
|
||||
void CTFCPlayerAnimState::ClearAnimationState()
|
||||
{
|
||||
m_bJumping = false;
|
||||
m_bFiring = false;
|
||||
m_bDying = false;
|
||||
|
||||
BaseClass::ClearAnimationState();
|
||||
}
|
||||
|
||||
|
||||
bool CTFCPlayerAnimState::ShouldUpdateAnimState()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user