source-engine/game/shared/Multiplayer/multiplayer_animstate.h
2022-03-01 23:00:42 +03:00

343 lines
9.1 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef MULTIPLAYERANIMSTATE_H
#define MULTIPLAYERANIMSTATE_H
#ifdef _WIN32
#pragma once
#endif
#include "convar.h"
#include "basecombatweapon_shared.h"
#include "iplayeranimstate.h"
#if defined( CLIENT_DLL )
class C_BasePlayer;
#define CPlayer C_BasePlayer
#else
class CBasePlayer;
#endif
enum PlayerAnimEvent_t
{
PLAYERANIMEVENT_ATTACK_PRIMARY,
PLAYERANIMEVENT_ATTACK_SECONDARY,
PLAYERANIMEVENT_ATTACK_GRENADE,
PLAYERANIMEVENT_RELOAD,
PLAYERANIMEVENT_RELOAD_LOOP,
PLAYERANIMEVENT_RELOAD_END,
PLAYERANIMEVENT_JUMP,
PLAYERANIMEVENT_SWIM,
PLAYERANIMEVENT_DIE,
PLAYERANIMEVENT_FLINCH_CHEST,
PLAYERANIMEVENT_FLINCH_HEAD,
PLAYERANIMEVENT_FLINCH_LEFTARM,
PLAYERANIMEVENT_FLINCH_RIGHTARM,
PLAYERANIMEVENT_FLINCH_LEFTLEG,
PLAYERANIMEVENT_FLINCH_RIGHTLEG,
PLAYERANIMEVENT_DOUBLEJUMP,
// Cancel.
PLAYERANIMEVENT_CANCEL,
PLAYERANIMEVENT_SPAWN,
// Snap to current yaw exactly
PLAYERANIMEVENT_SNAP_YAW,
PLAYERANIMEVENT_CUSTOM, // Used to play specific activities
PLAYERANIMEVENT_CUSTOM_GESTURE,
PLAYERANIMEVENT_CUSTOM_SEQUENCE, // Used to play specific sequences
PLAYERANIMEVENT_CUSTOM_GESTURE_SEQUENCE,
// TF Specific. Here until there's a derived game solution to this.
PLAYERANIMEVENT_ATTACK_PRE,
PLAYERANIMEVENT_ATTACK_POST,
PLAYERANIMEVENT_GRENADE1_DRAW,
PLAYERANIMEVENT_GRENADE2_DRAW,
PLAYERANIMEVENT_GRENADE1_THROW,
PLAYERANIMEVENT_GRENADE2_THROW,
PLAYERANIMEVENT_VOICE_COMMAND_GESTURE,
PLAYERANIMEVENT_DOUBLEJUMP_CROUCH,
PLAYERANIMEVENT_STUN_BEGIN,
PLAYERANIMEVENT_STUN_MIDDLE,
PLAYERANIMEVENT_STUN_END,
PLAYERANIMEVENT_ATTACK_PRIMARY_SUPER,
PLAYERANIMEVENT_COUNT
};
// Gesture Slots.
enum
{
GESTURE_SLOT_ATTACK_AND_RELOAD,
GESTURE_SLOT_GRENADE,
GESTURE_SLOT_JUMP,
GESTURE_SLOT_SWIM,
GESTURE_SLOT_FLINCH,
GESTURE_SLOT_VCD,
GESTURE_SLOT_CUSTOM,
GESTURE_SLOT_COUNT,
};
#define GESTURE_SLOT_INVALID -1
struct GestureSlot_t
{
int m_iGestureSlot;
Activity m_iActivity;
bool m_bAutoKill;
bool m_bActive;
CAnimationLayer *m_pAnimLayer;
};
inline bool IsCustomPlayerAnimEvent( PlayerAnimEvent_t event )
{
return ( event == PLAYERANIMEVENT_CUSTOM ) || ( event == PLAYERANIMEVENT_CUSTOM_GESTURE ) ||
( event == PLAYERANIMEVENT_CUSTOM_SEQUENCE ) || ( event == PLAYERANIMEVENT_CUSTOM_GESTURE_SEQUENCE );
}
struct MultiPlayerPoseData_t
{
int m_iMoveX;
int m_iMoveY;
int m_iAimYaw;
int m_iAimPitch;
int m_iBodyHeight;
int m_iMoveYaw;
int m_iMoveScale;
float m_flEstimateYaw;
float m_flLastAimTurnTime;
void Init()
{
m_iMoveX = 0;
m_iMoveY = 0;
m_iAimYaw = 0;
m_iAimPitch = 0;
m_iBodyHeight = 0;
m_iMoveYaw = 0;
m_iMoveScale = 0;
m_flEstimateYaw = 0.0f;
m_flLastAimTurnTime = 0.0f;
}
};
struct DebugPlayerAnimData_t
{
float m_flSpeed;
float m_flAimPitch;
float m_flAimYaw;
float m_flBodyHeight;
Vector2D m_vecMoveYaw;
void Init()
{
m_flSpeed = 0.0f;
m_flAimPitch = 0.0f;
m_flAimYaw = 0.0f;
m_flBodyHeight = 0.0f;
m_vecMoveYaw.Init();
}
};
struct MultiPlayerMovementData_t
{
// Set speeds to -1 if they are not used.
float m_flWalkSpeed;
float m_flRunSpeed;
float m_flSprintSpeed;
float m_flBodyYawRate;
};
//=============================================================================
//
// Multi-Player Animation State
//
class CMultiPlayerAnimState
{
public:
DECLARE_CLASS_NOBASE( CMultiPlayerAnimState );
// Creation/Destruction
CMultiPlayerAnimState() {}
CMultiPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData );
virtual ~CMultiPlayerAnimState();
// 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 ClearAnimationState();
virtual void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
virtual Activity CalcMainActivity();
virtual void Update( float eyeYaw, float eyePitch );
virtual void Release( void );
const QAngle &GetRenderAngles();
virtual Activity TranslateActivity( Activity actDesired );
virtual void SetRunSpeed( float flSpeed ) { m_MovementData.m_flRunSpeed = flSpeed; }
virtual void SetWalkSpeed( float flSpeed ) { m_MovementData.m_flWalkSpeed = flSpeed; }
virtual void SetSprintSpeed( float flSpeed ) { m_MovementData.m_flSprintSpeed = flSpeed; }
// Debug
virtual void ShowDebugInfo( void );
virtual void DebugShowAnimState( int iStartLine );
Activity GetCurrentMainActivity( void ) { return m_eCurrentMainSequenceActivity; }
void OnNewModel( void );
// Gestures.
void ResetGestureSlots( void );
void ResetGestureSlot( int iGestureSlot );
void AddVCDSequenceToGestureSlot( int iGestureSlot, int iGestureSequence, float flCycle = 0.0f, bool bAutoKill = true );
CAnimationLayer* GetGestureSlotLayer( int iGestureSlot );
bool IsGestureSlotActive( int iGestureSlot );
bool VerifyAnimLayerInSlot( int iGestureSlot );
// Feet.
bool m_bForceAimYaw;
protected:
virtual void Init( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData );
CBasePlayer *GetBasePlayer( void ) { return m_pPlayer; }
// Allow inheriting classes to override SelectWeightedSequence
virtual int SelectWeightedSequence( Activity activity ) { return GetBasePlayer()->SelectWeightedSequence( activity ); }
virtual void RestartMainSequence();
virtual void GetOuterAbsVelocity( Vector& vel );
float GetOuterXYSpeed();
virtual bool HandleJumping( Activity &idealActivity );
virtual bool HandleDucking( Activity &idealActivity );
virtual bool HandleMoving( Activity &idealActivity );
virtual bool HandleSwimming( Activity &idealActivity );
virtual bool HandleDying( Activity &idealActivity );
// Gesture Slots
CUtlVector<GestureSlot_t> m_aGestureSlots;
bool InitGestureSlots( void );
void ShutdownGestureSlots( void );
bool IsGestureSlotPlaying( int iGestureSlot, Activity iGestureActivity );
void AddToGestureSlot( int iGestureSlot, Activity iGestureActivity, bool bAutoKill );
virtual void RestartGesture( int iGestureSlot, Activity iGestureActivity, bool bAutoKill = true );
void ComputeGestureSequence( CStudioHdr *pStudioHdr );
void UpdateGestureLayer( CStudioHdr *pStudioHdr, GestureSlot_t *pGesture );
void DebugGestureInfo( void );
virtual float GetGesturePlaybackRate( void ) { return 1.0f; }
#ifdef CLIENT_DLL
void RunGestureSlotAnimEventsToCompletion( GestureSlot_t *pGesture );
#endif
virtual void PlayFlinchGesture( Activity iActivity );
virtual float CalcMovementSpeed( bool *bIsMoving );
virtual float CalcMovementPlaybackRate( bool *bIsMoving );
void DoMovementTest( CStudioHdr *pStudioHdr, float flX, float flY );
void DoMovementTest( CStudioHdr *pStudioHdr );
void GetMovementFlags( CStudioHdr *pStudioHdr );
// Pose parameters.
bool SetupPoseParameters( CStudioHdr *pStudioHdr );
virtual void ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr );
virtual void ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr );
virtual void ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr );
void ComputePoseParam_BodyHeight( CStudioHdr *pStudioHdr );
virtual void EstimateYaw( void );
void ConvergeYawAngles( float flGoalYaw, float flYawRate, float flDeltaTime, float &flCurrentYaw );
virtual float GetCurrentMaxGroundSpeed();
virtual void ComputeSequences( CStudioHdr *pStudioHdr );
void ComputeMainSequence();
void UpdateInterpolators();
void ResetGroundSpeed( void );
float GetInterpolatedGroundSpeed( void );
void ComputeFireSequence();
void ComputeDeployedSequence();
virtual bool ShouldUpdateAnimState();
void DebugShowAnimStateForPlayer( bool bIsServer );
void DebugShowEyeYaw( void );
// Client specific.
#ifdef CLIENT_DLL
// Debug.
void DebugShowActivity( Activity activity );
#endif
protected:
CBasePlayer *m_pPlayer;
QAngle m_angRender;
// Pose parameters.
bool m_bPoseParameterInit;
MultiPlayerPoseData_t m_PoseParameterData;
DebugPlayerAnimData_t m_DebugAnimData;
bool m_bCurrentFeetYawInitialized;
float m_flLastAnimationStateClearTime;
float m_flEyeYaw;
float m_flEyePitch;
float m_flGoalFeetYaw;
float m_flCurrentFeetYaw;
float m_flLastAimTurnTime;
MultiPlayerMovementData_t m_MovementData;
// Jumping.
bool m_bJumping;
float m_flJumpStartTime;
bool m_bFirstJumpFrame;
// Swimming.
bool m_bInSwim;
bool m_bFirstSwimFrame;
// Dying
bool m_bDying;
bool m_bFirstDyingFrame;
// Last activity we've used on the lower body. Used to determine if animations should restart.
Activity m_eCurrentMainSequenceActivity;
// Specific full-body sequence to play
int m_nSpecificMainSequence;
// Weapon data.
CHandle<CBaseCombatWeapon> m_hActiveWeapon;
// Ground speed interpolators.
#ifdef CLIENT_DLL
float m_flLastGroundSpeedUpdateTime;
CInterpolatedVar<float> m_iv_flMaxGroundSpeed;
#endif
float m_flMaxGroundSpeed;
// movement playback options
int m_nMovementSequence;
LegAnimType_t m_LegAnimType;
};
// If this is set, then the game code needs to make sure to send player animation events
// to the local player if he's the one being watched.
extern ConVar cl_showanimstate;
#endif // DOD_PLAYERANIMSTATE_H