mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-04 18:09:53 +03:00
1
This commit is contained in:
373
game/shared/hl1/hl1_player_shared.cpp
Normal file
373
game/shared/hl1/hl1_player_shared.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
#include "hl1_player_shared.h"
|
||||
#include "hl1/c_hl1mp_player.h"
|
||||
//#define CRecipientFilter C_RecipientFilter
|
||||
#else
|
||||
#include "hl1mp_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 CPlayerAnimState : public IHL1MPPlayerAnimState, public CBasePlayerAnimState
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CPlayerAnimState, CBasePlayerAnimState );
|
||||
|
||||
CPlayerAnimState();
|
||||
void Init( CHL1MP_Player *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, bool bForceIdle );
|
||||
virtual float SetOuterBodyYaw( float flValue );
|
||||
virtual Activity CalcMainActivity();
|
||||
virtual float GetCurrentMaxGroundSpeed();
|
||||
virtual void ClearAnimationState();
|
||||
virtual bool ShouldUpdateAnimState();
|
||||
virtual int SelectWeightedSequence( Activity activity ) ;
|
||||
|
||||
float CalcMovementPlaybackRate( bool *bIsMoving );
|
||||
|
||||
virtual void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const char* GetWeaponSuffix();
|
||||
bool HandleJumping();
|
||||
bool HandleDeath( Activity *deathActivity );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CHL1MP_Player *m_pOuter;
|
||||
|
||||
bool m_bJumping;
|
||||
bool m_bFirstJumpFrame;
|
||||
float m_flJumpStartTime;
|
||||
|
||||
bool m_bFiring;
|
||||
float m_flFireStartTime;
|
||||
|
||||
bool m_bDying;
|
||||
Activity m_DeathActivity;
|
||||
};
|
||||
|
||||
|
||||
IHL1MPPlayerAnimState* CreatePlayerAnimState( CHL1MP_Player *pPlayer )
|
||||
{
|
||||
CPlayerAnimState *pRet = new CPlayerAnimState;
|
||||
pRet->Init( pPlayer );
|
||||
return pRet;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- //
|
||||
// CPlayerAnimState implementation.
|
||||
// ----------------------------------------------------------------------------- //
|
||||
|
||||
CPlayerAnimState::CPlayerAnimState()
|
||||
{
|
||||
m_pOuter = NULL;
|
||||
m_bJumping = false;
|
||||
m_bFirstJumpFrame = false;
|
||||
m_bFiring = false;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::Init( CHL1MP_Player *pPlayer )
|
||||
{
|
||||
m_pOuter = pPlayer;
|
||||
|
||||
CModAnimConfig config;
|
||||
config.m_flMaxBodyYawDegrees = 90;
|
||||
config.m_LegAnimType = LEGANIM_GOLDSRC;
|
||||
config.m_bUseAimSequences = true;
|
||||
|
||||
BaseClass::Init( pPlayer, config );
|
||||
}
|
||||
|
||||
|
||||
const char* CPlayerAnimState::GetWeaponSuffix()
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = m_pOuter->GetActiveWeapon();
|
||||
if ( pWeapon )
|
||||
return pWeapon->GetWpnData().szAnimationPrefix;
|
||||
else
|
||||
return "shotgun";
|
||||
}
|
||||
|
||||
|
||||
int CPlayerAnimState::CalcAimLayerSequence( float *flCycle, float *flAimSequenceWeight, bool bForceIdle )
|
||||
{
|
||||
const char *pWeaponSuffix = GetWeaponSuffix();
|
||||
if ( !pWeaponSuffix )
|
||||
return 0;
|
||||
|
||||
if ( strcmp( pWeaponSuffix, "glock" ) == 0 )
|
||||
pWeaponSuffix = "onehanded";
|
||||
|
||||
// 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_pOuter->SequenceDuration( iSequence );
|
||||
*flCycle = (gpGlobals->curtime - m_flFireStartTime) / dur;
|
||||
if ( *flCycle >= 1 )
|
||||
{
|
||||
*flCycle = 1;
|
||||
m_bFiring = false;
|
||||
}
|
||||
}
|
||||
|
||||
return iSequence;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float CPlayerAnimState::SetOuterBodyYaw( float flValue )
|
||||
{
|
||||
// m_pOuter->SetBoneController( 0, flValue );
|
||||
|
||||
float fAcc = flValue / 4;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
m_pOuter->SetBoneController( i, fAcc );
|
||||
}
|
||||
|
||||
return flValue;
|
||||
}
|
||||
|
||||
|
||||
bool CPlayerAnimState::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;
|
||||
}
|
||||
|
||||
int CPlayerAnimState::SelectWeightedSequence( Activity activity )
|
||||
{
|
||||
return m_pOuter->m_iRealSequence;
|
||||
}
|
||||
|
||||
bool CPlayerAnimState::HandleDeath( Activity *deathActivity )
|
||||
{
|
||||
if ( m_bDying )
|
||||
{
|
||||
if ( m_pOuter->IsAlive() )
|
||||
{
|
||||
m_bDying = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*deathActivity = m_DeathActivity;
|
||||
}
|
||||
}
|
||||
return m_bDying;
|
||||
}
|
||||
|
||||
|
||||
Activity CPlayerAnimState::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_pOuter->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 CPlayerAnimState::GetCurrentMaxGroundSpeed()
|
||||
{
|
||||
Activity act = GetCurrentMainSequenceActivity();
|
||||
if ( act == ACT_CROUCHIDLE || act == ACT_RUN_CROUCH )
|
||||
return MAX_CROUCHED_RUN_SPEED;
|
||||
else
|
||||
return MAX_STANDING_RUN_SPEED;
|
||||
}
|
||||
|
||||
|
||||
void CPlayerAnimState::ClearAnimationState()
|
||||
{
|
||||
m_bJumping = false;
|
||||
m_bFiring = false;
|
||||
m_bDying = false;
|
||||
|
||||
BaseClass::ClearAnimationState();
|
||||
}
|
||||
|
||||
|
||||
bool CPlayerAnimState::ShouldUpdateAnimState()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float CPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
|
||||
{
|
||||
// Determine ideal playback rate
|
||||
Vector vel;
|
||||
GetOuterAbsVelocity( vel );
|
||||
|
||||
float flReturnValue = BaseClass::CalcMovementPlaybackRate( bIsMoving );
|
||||
|
||||
Activity eActivity = GetOuter()->GetSequenceActivity( GetOuter()->GetSequence() ) ;
|
||||
|
||||
if ( eActivity == ACT_RUN || eActivity == ACT_WALK || eActivity == ACT_CROUCH )
|
||||
{
|
||||
VectorNormalize( vel );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( GetOuter()->EyeAngles(), &vForward );
|
||||
|
||||
float flDot = DotProduct( vel, vForward );
|
||||
|
||||
if ( flDot < 0 )
|
||||
{
|
||||
flReturnValue *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
return flReturnValue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
|
||||
{
|
||||
VPROF( "CBasePlayerAnimState::ComputePoseParam_BodyPitch" );
|
||||
|
||||
// Get pitch from v_angle
|
||||
float flPitch = -m_flEyePitch;
|
||||
if ( flPitch > 180.0f )
|
||||
{
|
||||
flPitch -= 360.0f;
|
||||
}
|
||||
flPitch = clamp( flPitch, -50, 45 );
|
||||
|
||||
// See if we have a blender for pitch
|
||||
int pitch = GetOuter()->LookupPoseParameter( pStudioHdr, "XR" );
|
||||
if ( pitch < 0 )
|
||||
return;
|
||||
|
||||
GetOuter()->SetPoseParameter( pStudioHdr, pitch, flPitch );
|
||||
g_flLastBodyPitch = flPitch;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user