diff --git a/mp/src/game/client/CMakeLists.txt b/mp/src/game/client/CMakeLists.txt index 3dd7f6322..b23feddc1 100644 --- a/mp/src/game/client/CMakeLists.txt +++ b/mp/src/game/client/CMakeLists.txt @@ -15,6 +15,7 @@ target_include_directories(client ${CMAKE_SOURCE_DIR}/game/shared ${CMAKE_SOURCE_DIR}/game/shared/hl2 ${CMAKE_SOURCE_DIR}/game/shared/hl2mp + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer ${CMAKE_SOURCE_DIR}/game/shared/neo ${CMAKE_SOURCE_DIR}/game/shared/neo/weapons ${CMAKE_SOURCE_DIR}/public @@ -1566,8 +1567,6 @@ target_sources_grouped( ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_shared.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_spawnpoint.cpp ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_spawnpoint.h - ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.cpp - ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.cpp ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp @@ -1653,6 +1652,14 @@ if(NEO_BUILD_WEAPON_PBK56S) ) endif() +target_sources_grouped( + TARGET client + NAME "Source Files\\Shared\\Multiplayer" + FILES + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer/multiplayer_animstate.cpp + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer/multiplayer_animstate.h +) + target_sources_grouped( TARGET client NAME "HL2MP" @@ -1661,6 +1668,8 @@ target_sources_grouped( ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_gamerules.h ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_player_shared.cpp ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_player_shared.h + ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_playeranimstate.cpp + ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_playeranimstate.h ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_weapon_parse.cpp ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_weapon_parse.h hl2mp/c_hl2mp_player.cpp diff --git a/mp/src/game/client/c_baseanimating.cpp b/mp/src/game/client/c_baseanimating.cpp index a91b6ff58..5f596033f 100644 --- a/mp/src/game/client/c_baseanimating.cpp +++ b/mp/src/game/client/c_baseanimating.cpp @@ -887,7 +887,11 @@ void C_BaseAnimating::UpdateRelevantInterpolatedVars() void C_BaseAnimating::AddBaseAnimatingInterpolatedVars() { +#ifdef NEO // NEO HACK (Adam) lean interpolation was messed up with change to multiplayer_animstate, NEOTODO workout if this is ok, or how to make the old version work + AddVar( m_flEncodedController, &m_iv_flEncodedController, LATCH_SIMULATION_VAR, true ); +#else AddVar( m_flEncodedController, &m_iv_flEncodedController, LATCH_ANIMATION_VAR, true ); +#endif AddVar( m_flPoseParameter, &m_iv_flPoseParameter, LATCH_ANIMATION_VAR, true ); int flags = LATCH_ANIMATION_VAR; diff --git a/mp/src/game/client/c_baseanimatingoverlay.cpp b/mp/src/game/client/c_baseanimatingoverlay.cpp index 7f2b2dd7e..eadc72f97 100644 --- a/mp/src/game/client/c_baseanimatingoverlay.cpp +++ b/mp/src/game/client/c_baseanimatingoverlay.cpp @@ -15,10 +15,6 @@ #include "dt_utlvector_recv.h" -#ifndef NEO -#include "neo_playeranimstate.h" -#endif - // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/mp/src/game/client/hl2mp/c_hl2mp_player.cpp b/mp/src/game/client/hl2mp/c_hl2mp_player.cpp index 41a90afaa..cc26820bc 100644 --- a/mp/src/game/client/hl2mp/c_hl2mp_player.cpp +++ b/mp/src/game/client/hl2mp/c_hl2mp_player.cpp @@ -14,6 +14,9 @@ #include "iviewrender_beams.h" // flashlight beam #include "r_efx.h" #include "dlight.h" +#include "c_basetempentity.h" +#include "prediction.h" +#include "bone_setup.h" #ifdef NEO #include "c_neo_player.h" @@ -29,12 +32,26 @@ LINK_ENTITY_TO_CLASS( player, C_HL2MP_Player ); #endif -IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player) +BEGIN_RECV_TABLE_NOBASE( C_HL2MP_Player, DT_HL2MPLocalPlayerExclusive ) + RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ), + RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ), +// RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ), +END_RECV_TABLE() + +BEGIN_RECV_TABLE_NOBASE( C_HL2MP_Player, DT_HL2MPNonLocalPlayerExclusive ) + RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ), RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ), RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ), #ifdef NEO RecvPropFloat( RECVINFO( m_angEyeAngles[2] ) ), #endif +END_RECV_TABLE() + +IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player) + + RecvPropDataTable( "hl2mplocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_HL2MPLocalPlayerExclusive) ), + RecvPropDataTable( "hl2mpnonlocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_HL2MPNonLocalPlayerExclusive) ), + RecvPropEHandle( RECVINFO( m_hRagdoll ) ), RecvPropInt( RECVINFO( m_iSpawnInterpCounter ) ), RecvPropInt( RECVINFO( m_iPlayerSoundType) ), @@ -43,7 +60,12 @@ IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player) END_RECV_TABLE() BEGIN_PREDICTION_DATA( C_HL2MP_Player ) + DEFINE_PRED_FIELD( m_flCycle, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ), DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nSequence, FIELD_INTEGER, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ), + DEFINE_PRED_FIELD( m_flPlaybackRate, FIELD_FLOAT, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ), + DEFINE_PRED_ARRAY_TOL( m_flEncodedController, FIELD_FLOAT, MAXSTUDIOBONECTRLS, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE, 0.02f ), + DEFINE_PRED_FIELD( m_nNewSequenceParity, FIELD_INTEGER, FTYPEDESC_OVERRIDE | FTYPEDESC_PRIVATE | FTYPEDESC_NOERRORCHECK ), END_PREDICTION_DATA() #ifdef NEO @@ -61,16 +83,16 @@ static ConVar cl_defaultweapon( "cl_defaultweapon", "weapon_physcannon", FCVAR_U void SpawnBlood (Vector vecSpot, const Vector &vecDir, int bloodColor, float flDamage); -C_HL2MP_Player::C_HL2MP_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles( "C_HL2MP_Player::m_iv_angEyeAngles" ) +C_HL2MP_Player::C_HL2MP_Player() : m_iv_angEyeAngles( "C_HL2MP_Player::m_iv_angEyeAngles" ) { m_iIDEntIndex = 0; m_iSpawnInterpCounterCache = 0; - m_angEyeAngles.Init(); - AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR ); - m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK; +// m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK; + m_PlayerAnimState = CreateHL2MPPlayerAnimState( this ); + m_blinkTimer.Invalidate(); m_pFlashlightBeam = NULL; @@ -79,6 +101,7 @@ C_HL2MP_Player::C_HL2MP_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles( C_HL2MP_Player::~C_HL2MP_Player( void ) { ReleaseFlashlight(); + m_PlayerAnimState->Release(); } int C_HL2MP_Player::GetIDTarget() const @@ -179,6 +202,12 @@ CStudioHdr *C_HL2MP_Player::OnNewModel( void ) Initialize( ); + // Reset the players animation states, gestures + if ( m_PlayerAnimState ) + { + m_PlayerAnimState->OnNewModel(); + } + return hdr; } @@ -321,24 +350,6 @@ void C_HL2MP_Player::DoImpactEffect( trace_t &tr, int nDamageType ) void C_HL2MP_Player::PreThink( void ) { - QAngle vTempAngles = GetLocalAngles(); - - if ( GetLocalPlayer() == this ) - { - vTempAngles[PITCH] = EyeAngles()[PITCH]; - } - else - { - vTempAngles[PITCH] = m_angEyeAngles[PITCH]; - } - - if ( vTempAngles[YAW] < 0.0f ) - { - vTempAngles[YAW] += 360.0f; - } - - SetLocalAngles( vTempAngles ); - BaseClass::PreThink(); HandleSpeedChanges(); @@ -371,13 +382,6 @@ void C_HL2MP_Player::AddEntity( void ) { BaseClass::AddEntity(); - QAngle vTempAngles = GetLocalAngles(); - vTempAngles[PITCH] = m_angEyeAngles[PITCH]; - - SetLocalAngles( vTempAngles ); - - m_PlayerAnimState.Update(); - // Zero out model pitch, blending takes care of all of it. SetLocalAnglesDim( X_INDEX, 0 ); @@ -473,7 +477,7 @@ const QAngle& C_HL2MP_Player::GetRenderAngles() } else { - return m_PlayerAnimState.GetRenderAngles(); + return m_PlayerAnimState->GetRenderAngles(); } } @@ -845,7 +849,7 @@ void C_HL2MPRagdoll::Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity ) VarMapping_t *pSrc = pSourceEntity->GetVarMapping(); VarMapping_t *pDest = GetVarMapping(); - + // Find all the VarMapEntry_t's that represent the same variable. for ( int i = 0; i < pDest->m_Entries.Count(); i++ ) { @@ -1041,10 +1045,140 @@ void C_HL2MPRagdoll::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWei } } -void C_HL2MP_Player::PostThink( void ) +void C_HL2MP_Player::UpdateClientSideAnimation() +{ + m_PlayerAnimState->Update( EyeAngles()[YAW], EyeAngles()[PITCH] ); + + BaseClass::UpdateClientSideAnimation(); +} + +// -------------------------------------------------------------------------------- // +// Player animation event. Sent to the client when a player fires, jumps, reloads, etc.. +// -------------------------------------------------------------------------------- // + +class C_TEPlayerAnimEvent : public C_BaseTempEntity +{ +public: + DECLARE_CLASS( C_TEPlayerAnimEvent, C_BaseTempEntity ); + DECLARE_CLIENTCLASS(); + + virtual void PostDataUpdate( DataUpdateType_t updateType ) + { + // Create the effect. + C_HL2MP_Player *pPlayer = dynamic_cast< C_HL2MP_Player* >( m_hPlayer.Get() ); + if ( pPlayer && !pPlayer->IsDormant() ) + { + pPlayer->DoAnimationEvent( (PlayerAnimEvent_t)m_iEvent.Get(), m_nData ); + } + } + +public: + CNetworkHandle( CBasePlayer, m_hPlayer ); + CNetworkVar( int, m_iEvent ); + CNetworkVar( int, m_nData ); +}; + +IMPLEMENT_CLIENTCLASS_EVENT( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent, CTEPlayerAnimEvent ); + +BEGIN_RECV_TABLE_NOBASE( C_TEPlayerAnimEvent, DT_TEPlayerAnimEvent ) + RecvPropEHandle( RECVINFO( m_hPlayer ) ), + RecvPropInt( RECVINFO( m_iEvent ) ), + RecvPropInt( RECVINFO( m_nData ) ) +END_RECV_TABLE() + +void C_HL2MP_Player::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) +{ + if ( IsLocalPlayer() ) + { + if ( ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) ) + return; + } + + MDLCACHE_CRITICAL_SECTION(); + m_PlayerAnimState->DoAnimationEvent( event, nData ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_HL2MP_Player::CalculateIKLocks( float currentTime ) { - BaseClass::PostThink(); + if (!m_pIk) + return; + + int targetCount = m_pIk->m_target.Count(); + if ( targetCount == 0 ) + return; + + // In TF, we might be attaching a player's view to a walking model that's using IK. If we are, it can + // get in here during the view setup code, and it's not normally supposed to be able to access the spatial + // partition that early in the rendering loop. So we allow access right here for that special case. + SpatialPartitionListMask_t curSuppressed = partition->GetSuppressedLists(); + partition->SuppressLists( PARTITION_ALL_CLIENT_EDICTS, false ); + CBaseEntity::PushEnableAbsRecomputations( false ); + + for (int i = 0; i < targetCount; i++) + { + trace_t trace; + CIKTarget *pTarget = &m_pIk->m_target[i]; + + if (!pTarget->IsActive()) + continue; + + switch( pTarget->type) + { + case IK_GROUND: + { + pTarget->SetPos( Vector( pTarget->est.pos.x, pTarget->est.pos.y, GetRenderOrigin().z )); + pTarget->SetAngles( GetRenderAngles() ); + } + break; + + case IK_ATTACHMENT: + { + C_BaseEntity *pEntity = NULL; + float flDist = pTarget->est.radius; + + // FIXME: make entity finding sticky! + // FIXME: what should the radius check be? + for ( CEntitySphereQuery sphere( pTarget->est.pos, 64 ); ( pEntity = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() ) + { + C_BaseAnimating *pAnim = pEntity->GetBaseAnimating( ); + if (!pAnim) + continue; + + int iAttachment = pAnim->LookupAttachment( pTarget->offset.pAttachmentName ); + if (iAttachment <= 0) + continue; + + Vector origin; + QAngle angles; + pAnim->GetAttachment( iAttachment, origin, angles ); + + // debugoverlay->AddBoxOverlay( origin, Vector( -1, -1, -1 ), Vector( 1, 1, 1 ), QAngle( 0, 0, 0 ), 255, 0, 0, 0, 0 ); + + float d = (pTarget->est.pos - origin).Length(); + + if ( d >= flDist) + continue; + + flDist = d; + pTarget->SetPos( origin ); + pTarget->SetAngles( angles ); + // debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 ); + } + + if (flDist >= pTarget->est.radius) + { + // debugoverlay->AddBoxOverlay( pTarget->est.pos, Vector( -pTarget->est.radius, -pTarget->est.radius, -pTarget->est.radius ), Vector( pTarget->est.radius, pTarget->est.radius, pTarget->est.radius), QAngle( 0, 0, 0 ), 0, 0, 255, 0, 0 ); + // no solution, disable ik rule + pTarget->IKFailed( ); + } + } + break; + } + } - // Store the eye angles pitch so the client can compute its animation state correctly. - m_angEyeAngles = EyeAngles(); + CBaseEntity::PopEnableAbsRecomputations(); + partition->SuppressLists( curSuppressed, true ); } \ No newline at end of file diff --git a/mp/src/game/client/hl2mp/c_hl2mp_player.h b/mp/src/game/client/hl2mp/c_hl2mp_player.h index 9bae444ec..a82ff4e01 100644 --- a/mp/src/game/client/hl2mp/c_hl2mp_player.h +++ b/mp/src/game/client/hl2mp/c_hl2mp_player.h @@ -9,7 +9,7 @@ #define HL2MP_PLAYER_H #pragma once -class C_HL2MP_Player; +#include "hl2mp_playeranimstate.h" #include "c_basehlplayer.h" #include "hl2mp_player_shared.h" #include "beamdraw.h" @@ -41,7 +41,6 @@ class C_HL2MP_Player : public C_BaseHLPlayer virtual int DrawModel( int flags ); virtual void AddEntity( void ); - QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles; } Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL ); @@ -98,13 +97,14 @@ class C_HL2MP_Player : public C_BaseHLPlayer HL2MPPlayerState State_Get() const; - virtual void PostThink( void ); + virtual void UpdateClientSideAnimation(); + void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 ); + virtual void CalculateIKLocks( float currentTime ); private: C_HL2MP_Player( const C_HL2MP_Player & ); - - CPlayerAnimState m_PlayerAnimState; + CHL2MPPlayerAnimState *m_PlayerAnimState; QAngle m_angEyeAngles; diff --git a/mp/src/game/client/neo/c_neo_player.cpp b/mp/src/game/client/neo/c_neo_player.cpp index 234d36e3f..c1545dc75 100644 --- a/mp/src/game/client/neo/c_neo_player.cpp +++ b/mp/src/game/client/neo/c_neo_player.cpp @@ -46,8 +46,6 @@ #include "model_types.h" -#include "neo_playeranimstate.h" - #include "c_user_message_register.h" // Don't alias here @@ -445,16 +443,12 @@ C_NEO_Player::C_NEO_Player() m_bLastTickInThermOpticCamo = false; m_bIsAllowedToToggleVision = false; - m_pPlayerAnimState = CreatePlayerAnimState(this, CreateAnimStateHelpers(this), - NEO_ANIMSTATE_LEGANIM_TYPE, NEO_ANIMSTATE_USES_AIMSEQUENCES); - memset(m_szNeoNameWDupeIdx, 0, sizeof(m_szNeoNameWDupeIdx)); m_szNameDupePos = 0; } C_NEO_Player::~C_NEO_Player() { - m_pPlayerAnimState->Release(); #ifdef GLOWS_ENABLE DestroyGlowEffect(); #endif // GLOWS_ENABLE @@ -1060,14 +1054,6 @@ void C_NEO_Player::PostThink(void) m_bPreviouslyReloading = pNeoWep->m_bInReload; } } - - Vector eyeForward; - this->EyeVectors(&eyeForward, NULL, NULL); - Assert(eyeForward.IsValid()); - - float flPitch = asin(-eyeForward[2]); - float flYaw = atan2(eyeForward[1], eyeForward[0]); - m_pPlayerAnimState->Update(RAD2DEG(flYaw), RAD2DEG(flPitch)); } void C_NEO_Player::CalcDeathCamView(Vector &eyeOrigin, QAngle &eyeAngles, float &fov) @@ -1579,19 +1565,6 @@ void C_NEO_Player::PreDataUpdate(DataUpdateType_t updateType) BaseClass::PreDataUpdate(updateType); } -void C_NEO_Player::SetAnimation(PLAYER_ANIM playerAnim) -{ - PlayerAnimEvent_t animEvent; - if (!PlayerAnimToPlayerAnimEvent(playerAnim, animEvent)) - { - DevWarning("CLI Tried to get unknown PLAYER_ANIM %d\n", playerAnim); - } - else - { - m_pPlayerAnimState->DoAnimationEvent(animEvent); - } -} - extern ConVar sv_neo_wep_dmg_modifier; // NEO NOTE (Rain): doesn't seem to be implemented at all clientside? diff --git a/mp/src/game/client/neo/c_neo_player.h b/mp/src/game/client/neo/c_neo_player.h index d0bf94f0b..2b1c1761f 100644 --- a/mp/src/game/client/neo/c_neo_player.h +++ b/mp/src/game/client/neo/c_neo_player.h @@ -107,8 +107,6 @@ class C_NEO_Player : public C_HL2MP_Player float GetWalkSpeed(void) const; float GetSprintSpeed(void) const; - virtual void SetAnimation(PLAYER_ANIM playerAnim) OVERRIDE; - private: float GetActiveWeaponSpeedScale() const; float GetBackwardsMovementPenaltyScale() const { return ((m_nButtons & IN_BACK) ? NEO_SLOW_MODIFIER : 1.0); } diff --git a/mp/src/game/server/CMakeLists.txt b/mp/src/game/server/CMakeLists.txt index 6ecc6a149..e2643b3e6 100644 --- a/mp/src/game/server/CMakeLists.txt +++ b/mp/src/game/server/CMakeLists.txt @@ -24,6 +24,7 @@ target_include_directories(server ${CMAKE_SOURCE_DIR}/game/shared/econ ${CMAKE_SOURCE_DIR}/game/shared/hl2 ${CMAKE_SOURCE_DIR}/game/shared/hl2mp + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer ${CMAKE_SOURCE_DIR}/game/shared/neo ${CMAKE_SOURCE_DIR}/game/shared/neo/weapons ${CMAKE_SOURCE_DIR}/utils/common @@ -1318,8 +1319,6 @@ target_sources_grouped( ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_shared.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_spawnpoint.cpp ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_player_spawnpoint.h - ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.cpp - ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.cpp ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.h ${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp @@ -1421,6 +1420,14 @@ if(NEO_BUILD_WEAPON_PBK56S) ) endif() +target_sources_grouped( + TARGET server + NAME "Source Files\\Shared\\Multiplayer" + FILES + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer/multiplayer_animstate.cpp + ${CMAKE_SOURCE_DIR}/game/shared/Multiplayer/multiplayer_animstate.h +) + target_sources_grouped( TARGET server NAME "HL2MP" @@ -1429,6 +1436,8 @@ target_sources_grouped( ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_gamerules.h ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_player_shared.cpp ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_player_shared.h + ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_playeranimstate.cpp + ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_playeranimstate.h ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_weapon_parse.cpp ${CMAKE_SOURCE_DIR}/game/shared/hl2mp/hl2mp_weapon_parse.h hl2mp/hl2mp_bot_temp.cpp diff --git a/mp/src/game/server/hl2mp/hl2mp_player.cpp b/mp/src/game/server/hl2mp/hl2mp_player.cpp index 1c5a5e63d..38ea9b390 100644 --- a/mp/src/game/server/hl2mp/hl2mp_player.cpp +++ b/mp/src/game/server/hl2mp/hl2mp_player.cpp @@ -20,6 +20,8 @@ #include "grenade_satchel.h" #include "eventqueue.h" #include "gamestats.h" +#include "tier0/vprof.h" +#include "bone_setup.h" #include "engine/IEngineSound.h" #include "SoundEmitterSystem/isoundemittersystembase.h" @@ -30,6 +32,9 @@ #include "neo_player.h" #endif +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + int g_iLastCitizenModel = 0; int g_iLastCombineModel = 0; @@ -48,22 +53,61 @@ LINK_ENTITY_TO_CLASS( player, CHL2MP_Player ); LINK_ENTITY_TO_CLASS( info_player_combine, CPointEntity ); LINK_ENTITY_TO_CLASS( info_player_rebel, CPointEntity ); -IMPLEMENT_SERVERCLASS_ST(CHL2MP_Player, DT_HL2MP_Player) - SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 11, SPROP_CHANGES_OFTEN ), - SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 11, SPROP_CHANGES_OFTEN ), +extern void SendProxy_Origin( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); + +//Tony; this should ideally be added to dt_send.cpp +void* SendProxy_SendNonLocalDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ) +{ + pRecipients->SetAllRecipients(); + pRecipients->ClearRecipient( objectID - 1 ); + return ( void * )pVarData; +} +REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendNonLocalDataTable ); + + +BEGIN_SEND_TABLE_NOBASE( CHL2MP_Player, DT_HL2MPLocalPlayerExclusive ) + // send a hi-res origin to the local player for use in prediction + SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_NOSCALE|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ), + SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ), +// SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 10, SPROP_CHANGES_OFTEN ), +END_SEND_TABLE() + +BEGIN_SEND_TABLE_NOBASE( CHL2MP_Player, DT_HL2MPNonLocalPlayerExclusive ) + // send a lo-res origin to other players + SendPropVector (SENDINFO(m_vecOrigin), -1, SPROP_COORD_MP_LOWPRECISION|SPROP_CHANGES_OFTEN, 0.0f, HIGH_DEFAULT, SendProxy_Origin ), + SendPropFloat( SENDINFO_VECTORELEM(m_angEyeAngles, 0), 8, SPROP_CHANGES_OFTEN, -90.0f, 90.0f ), + SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 1), 10, SPROP_CHANGES_OFTEN ), #ifdef NEO SendPropAngle( SENDINFO_VECTORELEM(m_angEyeAngles, 2), 11, SPROP_CHANGES_OFTEN ), #endif - SendPropEHandle( SENDINFO( m_hRagdoll ) ), - SendPropInt( SENDINFO( m_iSpawnInterpCounter), 4 ), - SendPropInt( SENDINFO( m_iPlayerSoundType), 3 ), - +END_SEND_TABLE() + +IMPLEMENT_SERVERCLASS_ST(CHL2MP_Player, DT_HL2MP_Player) SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ), + SendPropExclude( "DT_BaseAnimating", "m_flPlaybackRate" ), + SendPropExclude( "DT_BaseAnimating", "m_nSequence" ), + SendPropExclude( "DT_BaseEntity", "m_angRotation" ), + SendPropExclude( "DT_BaseAnimatingOverlay", "overlay_vars" ), + + SendPropExclude( "DT_BaseEntity", "m_vecOrigin" ), + + // playeranimstate and clientside animation takes care of these on the client + SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ), + SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ), + + SendPropExclude( "DT_BaseFlex", "m_flexWeight" ), + SendPropExclude( "DT_BaseFlex", "m_blinktoggle" ), SendPropExclude( "DT_BaseFlex", "m_viewtarget" ), -// SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ), -// SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ), - + // Data that only gets sent to the local player. + SendPropDataTable( "hl2mplocaldata", 0, &REFERENCE_SEND_TABLE(DT_HL2MPLocalPlayerExclusive), SendProxy_SendLocalDataTable ), + // Data that gets sent to all other players + SendPropDataTable( "hl2mpnonlocaldata", 0, &REFERENCE_SEND_TABLE(DT_HL2MPNonLocalPlayerExclusive), SendProxy_SendNonLocalDataTable ), + + SendPropEHandle( SENDINFO( m_hRagdoll ) ), + SendPropInt( SENDINFO( m_iSpawnInterpCounter), 4 ), + SendPropInt( SENDINFO( m_iPlayerSoundType), 3 ), + END_SEND_TABLE() BEGIN_DATADESC( CHL2MP_Player ) @@ -105,8 +149,12 @@ const char *g_ppszRandomCombineModels[] = #pragma warning( disable : 4355 ) -CHL2MP_Player::CHL2MP_Player() : m_PlayerAnimState( this ) +CHL2MP_Player::CHL2MP_Player() { + //Tony; create our player animation state. + m_PlayerAnimState = CreateHL2MPPlayerAnimState( this ); + UseClientSideAnimation(); + m_angEyeAngles.Init(); m_iLastWeaponFireUsercmd = 0; @@ -125,6 +173,7 @@ CHL2MP_Player::CHL2MP_Player() : m_PlayerAnimState( this ) CHL2MP_Player::~CHL2MP_Player( void ) { + m_PlayerAnimState->Release(); } @@ -312,8 +361,6 @@ void CHL2MP_Player::Spawn(void) GiveDefaultItems(); } - SetNumAnimOverlays(3); - ResetAnimation(); m_nRenderFX = kRenderNormal; @@ -339,6 +386,10 @@ void CHL2MP_Player::Spawn(void) SetPlayerUnderwater(false); m_bReady = false; + + //Tony; do the spawn animevent + DoAnimationEvent( PLAYERANIMEVENT_SPAWN ); + } void CHL2MP_Player::PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize ) @@ -513,55 +564,20 @@ void CHL2MP_Player::SetupPlayerSoundsByModel( const char *pModelName ) } } -void CHL2MP_Player::ResetAnimation( void ) -{ - if ( IsAlive() ) - { - SetSequence ( -1 ); - SetActivity( ACT_INVALID ); - - if (!GetAbsVelocity().x && !GetAbsVelocity().y) - SetAnimation( PLAYER_IDLE ); - else if ((GetAbsVelocity().x || GetAbsVelocity().y) && ( GetFlags() & FL_ONGROUND )) - SetAnimation( PLAYER_WALK ); - else if (GetWaterLevel() > 1) - SetAnimation( PLAYER_WALK ); - } -} - - bool CHL2MP_Player::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex ) { bool bRet = BaseClass::Weapon_Switch( pWeapon, viewmodelindex ); - if ( bRet == true ) - { - ResetAnimation(); - } - return bRet; } void CHL2MP_Player::PreThink( void ) { - QAngle vOldAngles = GetLocalAngles(); - QAngle vTempAngles = GetLocalAngles(); - - vTempAngles = EyeAngles(); - - if ( vTempAngles[PITCH] > 180.0f ) - { - vTempAngles[PITCH] -= 360.0f; - } - - SetLocalAngles( vTempAngles ); - BaseClass::PreThink(); State_PreThink(); //Reset bullet force accumulator, only lasts one frame m_vecTotalBulletForce = vec3_origin; - SetLocalAngles( vOldAngles ); } void CHL2MP_Player::PostThink( void ) @@ -578,14 +594,13 @@ void CHL2MP_Player::PostThink( void ) #endif } - m_PlayerAnimState.Update(); - - // Store the eye angles pitch so the client can compute its animation state correctly. - m_angEyeAngles = EyeAngles(); - QAngle angles = GetLocalAngles(); angles[PITCH] = 0; SetLocalAngles( angles ); + + // Store the eye angles pitch so the client can compute its animation state correctly. + m_angEyeAngles = EyeAngles(); + m_PlayerAnimState->Update( m_angEyeAngles[YAW], m_angEyeAngles[PITCH] ); } void CHL2MP_Player::PlayerDeathThink() @@ -696,175 +711,6 @@ Activity CHL2MP_Player::TranslateTeamActivity( Activity ActToTranslate ) extern ConVar hl2_normspeed; -// Set the activity based on an event or current state -void CHL2MP_Player::SetAnimation( PLAYER_ANIM playerAnim ) -{ -#ifdef NEO - Assert(false); // we don't want this implementation -#endif - - //BaseClass::SetAnimation(playerAnim); - int animDesired; - - float speed; - - speed = GetAbsVelocity().Length2D(); - - - // bool bRunning = true; - - //Revisit! -/* if ( ( m_nButtons & ( IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT ) ) ) - { - if ( speed > 1.0f && speed < hl2_normspeed.GetFloat() - 20.0f ) - { - bRunning = false; - } - }*/ - - if ( GetFlags() & ( FL_FROZEN | FL_ATCONTROLS ) ) - { - speed = 0; - playerAnim = PLAYER_IDLE; - } - - Activity idealActivity = ACT_HL2MP_RUN; - - // This could stand to be redone. Why is playerAnim abstracted from activity? (sjb) - if ( playerAnim == PLAYER_JUMP ) - { - idealActivity = ACT_HL2MP_JUMP; - } - else if ( playerAnim == PLAYER_DIE ) - { - if ( m_lifeState == LIFE_ALIVE ) - { - return; - } - } - else if ( playerAnim == PLAYER_ATTACK1 ) - { - if ( GetActivity( ) == ACT_HOVER || - GetActivity( ) == ACT_SWIM || - GetActivity( ) == ACT_HOP || - GetActivity( ) == ACT_LEAP || - GetActivity( ) == ACT_DIESIMPLE ) - { - idealActivity = GetActivity( ); - } - else - { - idealActivity = ACT_HL2MP_GESTURE_RANGE_ATTACK; - } - } - else if ( playerAnim == PLAYER_RELOAD ) - { - idealActivity = ACT_HL2MP_GESTURE_RELOAD; - } - else if ( playerAnim == PLAYER_IDLE || playerAnim == PLAYER_WALK ) - { - if ( !( GetFlags() & FL_ONGROUND ) && GetActivity( ) == ACT_HL2MP_JUMP ) // Still jumping - { - idealActivity = GetActivity( ); - } - /* - else if ( GetWaterLevel() > 1 ) - { - if ( speed == 0 ) - idealActivity = ACT_HOVER; - else - idealActivity = ACT_SWIM; - } - */ - else - { - if ( GetFlags() & FL_DUCKING ) - { - if ( speed > 0 ) - { - idealActivity = ACT_HL2MP_WALK_CROUCH; - } - else - { - idealActivity = ACT_HL2MP_IDLE_CROUCH; - } - } - else - { - if ( speed > 0 ) - { - /* - if ( bRunning == false ) - { - idealActivity = ACT_WALK; - } - else - */ - { - idealActivity = ACT_HL2MP_RUN; - } - } - else - { - idealActivity = ACT_HL2MP_IDLE; - } - } - } - - idealActivity = TranslateTeamActivity( idealActivity ); - } - - if ( idealActivity == ACT_HL2MP_GESTURE_RANGE_ATTACK ) - { - RestartGesture( Weapon_TranslateActivity( idealActivity ) ); - - // FIXME: this seems a bit wacked - Weapon_SetActivity( Weapon_TranslateActivity( ACT_RANGE_ATTACK1 ), 0 ); - - return; - } - else if ( idealActivity == ACT_HL2MP_GESTURE_RELOAD ) - { - RestartGesture( Weapon_TranslateActivity( idealActivity ) ); - return; - } - else - { - SetActivity( idealActivity ); - - animDesired = SelectWeightedSequence( Weapon_TranslateActivity ( idealActivity ) ); - - if (animDesired == -1) - { - animDesired = SelectWeightedSequence( idealActivity ); - - if ( animDesired == -1 ) - { - animDesired = 0; - } - } - - // Already using the desired animation? - if ( GetSequence() == animDesired ) - return; - - m_flPlaybackRate = 1.0; - ResetSequence( animDesired ); - SetCycle( 0 ); - return; - } - - // Already using the desired animation? - if ( GetSequence() == animDesired ) - return; - - //Msg( "Set animation to %d\n", animDesired ); - // Reset to first frame of desired animation - ResetSequence( animDesired ); - SetCycle( 0 ); -} - - extern int gEvilImpulse101; //----------------------------------------------------------------------------- // Purpose: Player reacts to bumping a weapon. @@ -1259,8 +1105,6 @@ void CHL2MP_Player::Event_Killed( const CTakeDamageInfo &info ) CTakeDamageInfo subinfo = info; subinfo.SetDamageForce( m_vecTotalBulletForce ); - SetNumAnimOverlays( 0 ); - // Note: since we're dead, it won't draw us on the client, but we don't set EF_NODRAW // because we still want to transmit to the clients in our PVS. CreateRagdollEntity(); @@ -1663,3 +1507,140 @@ bool CHL2MP_Player::CanHearAndReadChatFrom( CBasePlayer *pPlayer ) return true; } + +//----------------------------------------------------------------------------- +// Purpose: multiplayer does not do autoaiming. +//----------------------------------------------------------------------------- +Vector CHL2MP_Player::GetAutoaimVector( float flScale ) +{ + //No Autoaim + Vector forward; + AngleVectors( EyeAngles() + m_Local.m_vecPunchAngle, &forward ); + return forward; +} + +//----------------------------------------------------------------------------- +// Purpose: Do nothing multiplayer_animstate takes care of animation. +// Input : playerAnim - +//----------------------------------------------------------------------------- +void CHL2MP_Player::SetAnimation( PLAYER_ANIM playerAnim ) +{ + return; +} + +// -------------------------------------------------------------------------------- // +// Player animation event. Sent to the client when a player fires, jumps, reloads, etc.. +// -------------------------------------------------------------------------------- // +class CTEPlayerAnimEvent : public CBaseTempEntity +{ +public: + DECLARE_CLASS( CTEPlayerAnimEvent, CBaseTempEntity ); + DECLARE_SERVERCLASS(); + + CTEPlayerAnimEvent( const char *name ) : CBaseTempEntity( name ) + { + } + + CNetworkHandle( CBasePlayer, m_hPlayer ); + CNetworkVar( int, m_iEvent ); + CNetworkVar( int, m_nData ); +}; + +IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEPlayerAnimEvent, DT_TEPlayerAnimEvent ) + SendPropEHandle( SENDINFO( m_hPlayer ) ), + SendPropInt( SENDINFO( m_iEvent ), Q_log2( PLAYERANIMEVENT_COUNT ) + 1, SPROP_UNSIGNED ), + SendPropInt( SENDINFO( m_nData ), 32 ) +END_SEND_TABLE() + +static CTEPlayerAnimEvent g_TEPlayerAnimEvent( "PlayerAnimEvent" ); + +void TE_PlayerAnimEvent( CBasePlayer *pPlayer, PlayerAnimEvent_t event, int nData ) +{ + CPVSFilter filter( (const Vector&)pPlayer->EyePosition() ); + + //Tony; use prediction rules. + filter.UsePredictionRules(); + + g_TEPlayerAnimEvent.m_hPlayer = pPlayer; + g_TEPlayerAnimEvent.m_iEvent = event; + g_TEPlayerAnimEvent.m_nData = nData; + g_TEPlayerAnimEvent.Create( filter, 0 ); +} + + +void CHL2MP_Player::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) +{ + m_PlayerAnimState->DoAnimationEvent( event, nData ); + TE_PlayerAnimEvent( this, event, nData ); // Send to any clients who can see this guy. +} + +//----------------------------------------------------------------------------- +// Purpose: Override setup bones so that is uses the render angles from +// the HL2MP animation state to setup the hitboxes. +//----------------------------------------------------------------------------- +void CHL2MP_Player::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ) +{ + VPROF_BUDGET( "CHL2MP_Player::SetupBones", VPROF_BUDGETGROUP_SERVER_ANIM ); + + // Get the studio header. + Assert( GetModelPtr() ); + CStudioHdr *pStudioHdr = GetModelPtr( ); + if ( !pStudioHdr ) + return; + + Vector pos[MAXSTUDIOBONES]; + Quaternion q[MAXSTUDIOBONES]; + + // Adjust hit boxes based on IK driven offset. + Vector adjOrigin = GetAbsOrigin() + Vector( 0, 0, m_flEstIkOffset ); + + // FIXME: pass this into Studio_BuildMatrices to skip transforms + CBoneBitList boneComputed; + if ( m_pIk ) + { + m_iIKCounter++; + m_pIk->Init( pStudioHdr, GetAbsAngles(), adjOrigin, gpGlobals->curtime, m_iIKCounter, boneMask ); + GetSkeleton( pStudioHdr, pos, q, boneMask ); + + m_pIk->UpdateTargets( pos, q, pBoneToWorld, boneComputed ); + CalculateIKLocks( gpGlobals->curtime ); + m_pIk->SolveDependencies( pos, q, pBoneToWorld, boneComputed ); + } + else + { + GetSkeleton( pStudioHdr, pos, q, boneMask ); + } + + CBaseAnimating *pParent = dynamic_cast< CBaseAnimating* >( GetMoveParent() ); + if ( pParent ) + { + // We're doing bone merging, so do special stuff here. + CBoneCache *pParentCache = pParent->GetBoneCache(); + if ( pParentCache ) + { + BuildMatricesWithBoneMerge( + pStudioHdr, + m_PlayerAnimState->GetRenderAngles(), + adjOrigin, + pos, + q, + pBoneToWorld, + pParent, + pParentCache ); + + return; + } + } + + Studio_BuildMatrices( + pStudioHdr, + m_PlayerAnimState->GetRenderAngles(), + adjOrigin, + pos, + q, + -1, + GetModelScale(), // Scaling + pBoneToWorld, + boneMask ); +} + diff --git a/mp/src/game/server/hl2mp/hl2mp_player.h b/mp/src/game/server/hl2mp/hl2mp_player.h index e4895524d..ff7bfedd6 100644 --- a/mp/src/game/server/hl2mp/hl2mp_player.h +++ b/mp/src/game/server/hl2mp/hl2mp_player.h @@ -16,6 +16,7 @@ class CHL2MP_Player; #include "hl2_player.h" #include "simtimer.h" #include "soundenvelope.h" +#include "hl2mp_playeranimstate.h" #include "hl2mp_player_shared.h" #include "hl2mp_gamerules.h" #include "utldict.h" @@ -56,13 +57,17 @@ class CHL2MP_Player : public CHL2_Player DECLARE_SERVERCLASS(); DECLARE_DATADESC(); + DECLARE_PREDICTABLE(); + + // This passes the event to the client's and server's CHL2MPPlayerAnimState. + void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 ); + void SetupBones( matrix3x4_t *pBoneToWorld, int boneMask ); virtual void Precache( void ); virtual void Spawn( void ); virtual void PostThink( void ); virtual void PreThink( void ); virtual void PlayerDeathThink( void ); - virtual void SetAnimation( PLAYER_ANIM playerAnim ); virtual bool HandleCommand_JoinTeam( int team ); virtual bool ClientCommand( const CCommand &args ); virtual void CreateViewModel( int viewmodelindex = 0 ); @@ -88,9 +93,8 @@ class CHL2MP_Player : public CHL2_Player void PrecacheFootStepSounds( void ); bool ValidatePlayerModel( const char *pModel ); - QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles.Get(); } - Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL ); + virtual Vector GetAutoaimVector( float flDelta ); void CheatImpulseCommands( int iImpulse ); void CreateRagdollEntity( void ); @@ -104,7 +108,8 @@ class CHL2MP_Player : public CHL2_Player void NoteWeaponFired( void ); - void ResetAnimation( void ); + void SetAnimation( PLAYER_ANIM playerAnim ); + void SetPlayerModel( void ); void SetPlayerTeamModel( void ); Activity TranslateTeamActivity( Activity ActToTranslate ); @@ -157,8 +162,9 @@ class CHL2MP_Player : public CHL2_Player private: + CHL2MPPlayerAnimState *m_PlayerAnimState; + CNetworkQAngle( m_angEyeAngles ); - CPlayerAnimState m_PlayerAnimState; int m_iLastWeaponFireUsercmd; int m_iModelType; diff --git a/mp/src/game/server/neo/neo_player.cpp b/mp/src/game/server/neo/neo_player.cpp index 569a7b7d7..ea320d353 100644 --- a/mp/src/game/server/neo/neo_player.cpp +++ b/mp/src/game/server/neo/neo_player.cpp @@ -1,7 +1,6 @@ #include "cbase.h" #include "neo_player.h" -#include "neo_playeranimstate.h" #include "neo_predicted_viewmodel.h" #include "neo_predicted_viewmodel_muzzleflash.h" #include "in_buttons.h" @@ -412,9 +411,6 @@ CNEO_Player::CNEO_Player() m_NeoFlags = 0; - m_pPlayerAnimState = CreatePlayerAnimState(this, CreateAnimStateHelpers(this), - NEO_ANIMSTATE_LEGANIM_TYPE, NEO_ANIMSTATE_USES_AIMSEQUENCES); - memset(m_szNeoNameWDupeIdx, 0, sizeof(m_szNeoNameWDupeIdx)); m_szNeoNameWDupeIdxNeedUpdate = true; m_szNameDupePos = 0; @@ -425,7 +421,6 @@ CNEO_Player::CNEO_Player() CNEO_Player::~CNEO_Player( void ) { - m_pPlayerAnimState->Release(); } void CNEO_Player::ZeroFriendlyPlayerLocArray(void) @@ -504,9 +499,6 @@ void CNEO_Player::Spawn(void) BaseClass::Spawn(); - SetNumAnimOverlays(NUM_LAYERS_WANTED); - ResetAnimation(); - m_HL2Local.m_cloakPower = CloakPower_Cap(); m_bIsPendingSpawnForThisRound = false; @@ -1043,30 +1035,6 @@ void CNEO_Player::PostThink(void) Weapon_Drop(pNeoWep, NULL, &eyeForward); } } - -#if(0) - int iMoveX = LookupPoseParameter("move_x"); - int iMoveY = LookupPoseParameter("move_y"); - - if (iMoveX != -1 && iMoveY != -1) - { - float speedScaleX = clamp((GetAbsVelocity().x / NEO_ASSAULT_NORM_SPEED), 0, 1); - float speedScaleY = clamp((GetAbsVelocity().y / NEO_ASSAULT_NORM_SPEED), 0, 1); - - SetPoseParameter(iMoveX, speedScaleX); - SetPoseParameter(iMoveY, speedScaleY); - - //DevMsg("Setspeed %f , %f\n", speedScaleX, speedScaleY); - } -#endif - - Vector eyeForward; - this->EyeVectors(&eyeForward, NULL, NULL); - Assert(eyeForward.IsValid()); - - float flPitch = asin(-eyeForward[2]); - float flYaw = atan2(eyeForward[1], eyeForward[0]); - m_pPlayerAnimState->Update(RAD2DEG(flYaw), RAD2DEG(flPitch)); } void CNEO_Player::PlayerDeathThink() @@ -1167,232 +1135,7 @@ void CNEO_Player::Weapon_SetZoom(const bool bZoomIn) m_bInAim = bZoomIn; } -void CNEO_Player::SetAnimation( PLAYER_ANIM playerAnim ) -{ - PlayerAnimEvent_t animEvent; - if (!PlayerAnimToPlayerAnimEvent(playerAnim, animEvent)) - { - DevWarning("SRV Tried to get unknown PLAYER_ANIM %d\n", playerAnim); - } - else - { - m_pPlayerAnimState->DoAnimationEvent(animEvent); - } - // Stopping; animations are handled by m_pPlayerAnimState->Update. - // Should clean up this unused code later. - return; - - /* - - auto activeWep = GetActiveWeapon(); - - const char *pszAnimPrefix = (activeWep) ? activeWep->GetAnimPrefix() : ""; -#define MAX_WEAPON_PREFIX_LEN 18 // "Crouch_Walk_Upper_" == 18 -#define MAX_WEAPON_SUFFIX_LEN 6 // "pistol" == 6 -#define NONE_STR "" - char pszUpperAnim[MAX_WEAPON_PREFIX_LEN + MAX_WEAPON_SUFFIX_LEN + 1] = NONE_STR; - char pszReloadAnim[MAX_WEAPON_PREFIX_LEN + MAX_WEAPON_SUFFIX_LEN + 1] = NONE_STR; - - int iLowerSequence = -1; - int iUpperSequence = -1; - - if (idealActivity == ACT_NEO_JUMP) - { - iLowerSequence = LookupSequence("Jump"); - } - else if (idealActivity == ACT_NEO_MOVE_RUN) - { - iLowerSequence = LookupSequence("Run_lower"); - - const char *pszLayeredSequence = "Run_Upper_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else if (idealActivity == ACT_NEO_MOVE_WALK) - { - iLowerSequence = LookupSequence("walk_lower"); - - const char *pszLayeredSequence = "Walk_Upper_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else if (idealActivity == ACT_NEO_IDLE_STAND) - { - iLowerSequence = LookupSequence("Idle_lower"); - - const char *pszLayeredSequence = "Idle_Upper_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else if (idealActivity == ACT_NEO_IDLE_CROUCH) - { - iLowerSequence = LookupSequence("Crouch_Idle_Lower"); - - const char *pszLayeredSequence = "Crouch_Idle_Upper_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else if (idealActivity == ACT_NEO_MOVE_CROUCH) - { - iLowerSequence = LookupSequence("Crouch_walk_lower"); - - const char *pszLayeredSequence = "Crouch_Walk_Upper_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else if (idealActivity == ACT_NEO_ATTACK) - { - if (GetFlags() & FL_DUCKING) - { - if (speed > 0) - { - iLowerSequence = LookupSequence("Crouch_walk_lower"); - - const char *pszLayeredSequence = "Crouch_Walk_Shoot_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else - { - iLowerSequence = LookupSequence("Crouch_Idle_Lower"); - - const char *pszLayeredSequence = "Crouch_Idle_Shoot_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - } - else - { - if (speed > 0) - { - if (speed > GetWalkSpeed()) - { - iLowerSequence = LookupSequence("Run_lower"); - - const char *pszLayeredSequence = "Run_Shoot_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - else - { - iLowerSequence = LookupSequence("walk_lower"); - - const char *pszLayeredSequence = "Walk_Shoot_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - } - else - { - iLowerSequence = LookupSequence("Idle_lower"); - const char *pszLayeredSequence = "Idle_Shoot_%s"; - V_sprintf_safe(pszUpperAnim, pszLayeredSequence, pszAnimPrefix); - iUpperSequence = LookupSequence(pszUpperAnim); - } - } - } - - if (iLowerSequence == -1) - { - //Assert(false); - iLowerSequence = 0; - } - - const bool bReloadAnimPlayingNow = ((bStartedReloading) || (activeWep && activeWep->m_bInReload)); - - // Handle lower body animation - if (GetSequence() != iLowerSequence || !SequenceLoops()) - { - //DevMsg("Setting lower seq: %i\n", iLowerSequence); - SetSequence(iLowerSequence); - ResetSequence(iLowerSequence); - } - - // Handle upper body animation - if (iUpperSequence != -1) - { - if (!IsValidSequence(iUpperSequence)) - { - Assert(false); - Warning("CNEO_Player::SetAnimation: !IsValidSequence %i: (\"%s\")\n", - iUpperSequence, pszUpperAnim); - } - else - { - const int iAimLayer = AddGestureSequence(iUpperSequence, true); - SetLayerWeight(iAimLayer, 0.5f); -#if(0) - if (!pAnimOverlay_Fire->IsActive() || pAnimOverlay_Fire->IsAbandoned()) - { - pAnimOverlay_Fire->KillMe(); - } - pAnimOverlay_Fire->Init(this); - pAnimOverlay_Fire->m_nSequence = iUpperAimSequence; - pAnimOverlay_Fire->StudioFrameAdvance(0.1, this); - - int seq = AddGestureSequence(iUpperAimSequence, true); - if (IsValidSequence(seq)) - { - SetLayerBlendIn(seq, 0.1f); - SetLayerBlendOut(seq, 0.1f); - } -#endif - } - } - - if (bReloadAnimPlayingNow) - { - const char *pszLayeredSequence = "Reload_%s"; - V_sprintf_safe(pszReloadAnim, pszLayeredSequence, pszAnimPrefix); - Assert(!FStrEq(pszReloadAnim, NONE_STR)); - - const int iUpperReloadSequence = LookupSequence(pszReloadAnim); - - const int iReloadLayer = AddGestureSequence(iUpperReloadSequence, true); - SetLayerWeight(iReloadLayer, 0.5f); - -#if(0) - int seq = AddGestureSequence(iUpperReloadSequence, true); - if (IsValidSequence(seq)) - { - bool reloading = bReloadAnimPlayingNow; - float layerCycle = GetLayerCycle(RELOADSEQUENCE_LAYER); - int seq = iUpperReloadSequence; - UpdateLayerSequenceGeneric(this, GetModelPtr(), RELOADSEQUENCE_LAYER, reloading, layerCycle, seq, false); - } - - if (!IsValidSequence(iUpperReloadSequence)) - { - Assert(false); - Warning("CNEO_Player::SetAnimation: !IsValidSequence %i: (\"%s\")\n", - iUpperReloadSequence, pszReloadAnim); - } - else - { - - pAnimOverlay_Reload->Init(this); - pAnimOverlay_Reload->m_nSequence = iUpperReloadSequence; - pAnimOverlay_Reload->StudioFrameAdvance(0.1, this); - - int seq = AddGestureSequence(iUpperReloadSequence, true); - if (IsValidSequence(seq)) - { - SetLayerBlendIn(seq, 0.1f); - SetLayerBlendOut(seq, 0.1f); - } - } -#endif - } - -#if(0) - static CSequenceTransitioner transitioner; - transitioner->RemoveAll(); - transitioner->CheckForSequenceChange(GetModelPtr(), GetSequence(), false, true); - transitioner->UpdateCurrent(GetModelPtr(), GetSequence(), GetCycle(), 1.0f, gpGlobals->curtime); -#endif - */ -} // Purpose: Suicide, but cancel the point loss. void CNEO_Player::SoftSuicide(void) @@ -1893,7 +1636,6 @@ void CNEO_Player::SetPlayerCorpseModel(int type) SetModel(model); SetPlaybackRate(1.0f); - ResetAnimation(); } float CNEO_Player::GetReceivedDamageScale(CBaseEntity* pAttacker) @@ -2074,7 +1816,7 @@ void CNEO_Player::SetPlayerTeamModel( void ) SetModel(model); SetPlaybackRate(1.0f); - ResetAnimation(); + //ResetAnimation(); DevMsg("Set model: %s\n", model); diff --git a/mp/src/game/server/neo/neo_player.h b/mp/src/game/server/neo/neo_player.h index 92c43dc73..90e5c181c 100644 --- a/mp/src/game/server/neo/neo_player.h +++ b/mp/src/game/server/neo/neo_player.h @@ -41,7 +41,6 @@ class CNEO_Player : public CHL2MP_Player virtual void PostThink(void) OVERRIDE; virtual void PreThink(void) OVERRIDE; virtual void PlayerDeathThink(void) OVERRIDE; - virtual void SetAnimation(PLAYER_ANIM playerAnim) OVERRIDE; virtual bool HandleCommand_JoinTeam(int team) OVERRIDE; virtual bool ClientCommand(const CCommand &args) OVERRIDE; virtual void CreateViewModel(int viewmodelindex = 0) OVERRIDE; @@ -256,8 +255,6 @@ class CNEO_Player : public CHL2MP_Player int m_iDmgMenuCurPage; int m_iDmgMenuNextPage; - INEOPlayerAnimState* m_pPlayerAnimState; - private: CNEO_Player(const CNEO_Player&); }; diff --git a/mp/src/game/shared/Multiplayer/multiplayer_animstate.cpp b/mp/src/game/shared/Multiplayer/multiplayer_animstate.cpp index 2734eba02..3be01c841 100644 --- a/mp/src/game/shared/Multiplayer/multiplayer_animstate.cpp +++ b/mp/src/game/shared/Multiplayer/multiplayer_animstate.cpp @@ -26,6 +26,10 @@ ConVar anim_showmainactivity( "anim_showmainactivity", "0", FCVAR_CHEAT, "Show t #include "tf_gamerules.h" #endif +#ifdef NEO +#include "weapon_detpack.h" +#endif + #ifndef CALL_ATTRIB_HOOK_FLOAT_ON_OTHER #define CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( o, r, n ) #endif @@ -655,6 +659,82 @@ void CMultiPlayerAnimState::AddToGestureSlot( int iGestureSlot, Activity iGestur #endif } +#ifdef NEO +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMultiPlayerAnimState::AddToGestureSlot(int iGestureSlot, int iGestureSequence, bool bAutoKill) +{ + // Sanity Check + Assert(iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT); + + CBasePlayer* pPlayer = GetBasePlayer(); + if (!pPlayer) + return; + + // Make sure we have a valid animation layer to fill out. + if (!m_aGestureSlots[iGestureSlot].m_pAnimLayer) + return; + + if (!VerifyAnimLayerInSlot(iGestureSlot)) + return; + + if (iGestureSequence <= 0) + return; + +#ifdef CLIENT_DLL + + // Setup the gesture. + m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot; + m_aGestureSlots[iGestureSlot].m_iActivity = ACT_INVALID; + m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill; + m_aGestureSlots[iGestureSlot].m_bActive = true; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nSequence = iGestureSequence; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nOrder = iGestureSlot; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flWeight = 1.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPlaybackRate = 1.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flCycle = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPrevCycle = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerAnimtime = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLayerFadeOuttime = 0.0f; + + pPlayer->m_flOverlayPrevEventCycle[iGestureSlot] = -1.0; + +#else + + // Setup the gesture. + m_aGestureSlots[iGestureSlot].m_iGestureSlot = iGestureSlot; + m_aGestureSlots[iGestureSlot].m_iActivity = ACT_INVALID; + m_aGestureSlots[iGestureSlot].m_bAutoKill = bAutoKill; + m_aGestureSlots[iGestureSlot].m_bActive = true; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nActivity = ACT_INVALID; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nOrder = iGestureSlot; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nPriority = 0; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flCycle = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPrevCycle = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flPlaybackRate = 1.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_nSequence = iGestureSequence; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flWeight = 1.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendIn = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flBlendOut = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bSequenceFinished = false; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = 0.0f; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_flLastEventCheck = gpGlobals->curtime; + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_bLooping = false;//( ( GetSequenceFlags( GetModelPtr(), iGestureSequence ) & STUDIO_LOOPING ) != 0); + if (bAutoKill) + { + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_AUTOKILL; + } + else + { + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags &= ~ANIM_LAYER_AUTOKILL; + } + m_aGestureSlots[iGestureSlot].m_pAnimLayer->m_fFlags |= ANIM_LAYER_ACTIVE; + +#endif // CLIENT_DLL +} +#endif // NEO + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -844,8 +924,11 @@ bool CMultiPlayerAnimState::HandleSwimming( Activity &idealActivity ) RestartMainSequence(); m_bFirstSwimFrame = false; } - +#ifdef NEO + idealActivity = ACT_SWIM; +#else idealActivity = ACT_MP_SWIM; +#endif m_bInSwim = true; return true; } @@ -918,8 +1001,11 @@ bool CMultiPlayerAnimState::HandleMoving( Activity &idealActivity ) //----------------------------------------------------------------------------- Activity CMultiPlayerAnimState::CalcMainActivity() { +#ifdef NEO + Activity idealActivity = ACT_IDLE; +#else Activity idealActivity = ACT_MP_STAND_IDLE; - +#endif if ( HandleJumping( idealActivity ) || HandleDucking( idealActivity ) || HandleSwimming( idealActivity ) || @@ -1084,6 +1170,298 @@ void CMultiPlayerAnimState::ComputeSequences( CStudioHdr *pStudioHdr ) ComputeGestureSequence( pStudioHdr ); } +#ifdef NEO + +// NEO Activities +#define ACT_NEO_ATTACK ACT_RANGE_ATTACK1 +#define ACT_NEO_RELOAD ACT_RELOAD +#define ACT_NEO_IDLE_STAND ACT_IDLE +#define ACT_NEO_IDLE_CROUCH ACT_CROUCHIDLE +#define ACT_NEO_MOVE_RUN ACT_RUN +#define ACT_NEO_MOVE_WALK ACT_WALK +#define ACT_NEO_MOVE_CROUCH ACT_RUN_CROUCH +#define ACT_NEO_DIE ACT_DIESIMPLE +#define ACT_NEO_HOVER ACT_HOVER +#define ACT_NEO_JUMP ACT_HOP +#define ACT_NEO_SWIM ACT_SWIM + +#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_" + +int CMultiPlayerAnimState::CalcSequenceIndex(const char* pBaseName, ...) +{ + if (!m_pPlayer) + { + return 0; + } + + char szFullName[512]; + va_list marker; + va_start(marker, pBaseName); + Q_vsnprintf(szFullName, sizeof(szFullName), pBaseName, marker); + va_end(marker); + int iSequence = m_pPlayer->LookupSequence(szFullName); + + // Show warnings if we can't find anything here. + if (iSequence == -1) + { + static CUtlDict dict; + if (dict.Find(szFullName) == -1) + { + dict.Insert(szFullName, 0); + Warning("CalcSequenceIndex: can't find '%s'.\n", szFullName); + } + + iSequence = 0; + } + + //DevMsg("CalcSeqIdx: \"%s\": %d\n", szFullName, iSequence); + + return iSequence; +} + +void CMultiPlayerAnimState::UpdateAimSequenceLayers( + float flCycle, + int iFirstLayer, + bool bForceIdle, + CSequenceTransitioner* pTransitioner, + float flWeightScale +) +{ + float flAimSequenceWeight = 1; + int iAimSequence = CalcAimLayerSequence(m_eCurrentMainSequenceActivity, false); + if (iAimSequence == -1) + iAimSequence = 0; + + CBaseAnimatingOverlay* pPlayer = GetBasePlayer(); + + // Feed the current state of the animation parameters to the sequence transitioner. + // It will hand back either 1 or 2 animations in the queue to set, depending on whether + // it's transitioning or not. We just dump those into the animation layers. + pTransitioner->CheckForSequenceChange( + pPlayer->GetModelPtr(), + iAimSequence, + false, // don't force transitions on the same anim + true // yes, interpolate when transitioning + ); + + pTransitioner->UpdateCurrent( + pPlayer->GetModelPtr(), + iAimSequence, + flCycle, + pPlayer->GetPlaybackRate(), + gpGlobals->curtime + ); + + CAnimationLayer* pDest0 = m_aGestureSlots[iFirstLayer].m_pAnimLayer; + CAnimationLayer* pDest1 = m_aGestureSlots[iFirstLayer + 1].m_pAnimLayer; + + if (pTransitioner->m_animationQueue.Count() == 1) + { + // If only 1 animation, then blend it in fully. + CAnimationLayer* pSource0 = &pTransitioner->m_animationQueue[0]; + *pDest0 = *pSource0; + + pDest0->m_flWeight = 1; + pDest1->m_flWeight = 0; + pDest0->m_nOrder = iFirstLayer; + +#ifndef CLIENT_DLL + pDest0->m_fFlags |= ANIM_LAYER_ACTIVE; +#endif + } + else if (pTransitioner->m_animationQueue.Count() >= 2) + { + // The first one should be fading out. Fade in the new one inversely. + CAnimationLayer* pSource0 = &pTransitioner->m_animationQueue[0]; + CAnimationLayer* pSource1 = &pTransitioner->m_animationQueue[1]; + + *pDest0 = *pSource0; + *pDest1 = *pSource1; + Assert(pDest0->m_flWeight >= 0.0f && pDest0->m_flWeight <= 1.0f); + pDest1->m_flWeight = 1 - pDest0->m_flWeight; // This layer just mirrors the other layer's weight (one fades in while the other fades out). + + pDest0->m_nOrder = iFirstLayer; + pDest1->m_nOrder = iFirstLayer + 1; + +#ifndef CLIENT_DLL + pDest0->m_fFlags |= ANIM_LAYER_ACTIVE; + pDest1->m_fFlags |= ANIM_LAYER_ACTIVE; +#endif + } + + pDest0->m_flWeight *= flWeightScale * flAimSequenceWeight; + pDest0->m_flWeight = clamp((float)pDest0->m_flWeight, 0.0f, 1.0f); + + pDest1->m_flWeight *= flWeightScale * flAimSequenceWeight; + pDest1->m_flWeight = clamp((float)pDest1->m_flWeight, 0.0f, 1.0f); + + pDest0->m_flCycle = pDest1->m_flCycle = flCycle; +} + +int CMultiPlayerAnimState::CalcAimLayerSequence(Activity activity, bool bForceIdle) +{ + if (!m_pPlayer) + { + return 0; + } + + auto pWeapon = m_pPlayer->GetActiveWeapon(); + if (!pWeapon) + { + return 0; + } + + const char* pSuffix = pWeapon->GetWpnData().szAnimationPrefix; + if (!pSuffix) + { + return 0; + } + + if (!Q_strcmp(pWeapon->GetClassname(), "weapon_remotedet")) + { + pSuffix = "detpack"; + auto detpack = static_cast(pWeapon); + if (detpack && (detpack->m_bRemoteHasBeenTriggered || + (detpack->m_bThisDetpackHasBeenThrown && (gpGlobals->curtime > detpack->m_flNextPrimaryAttack)))) + { + pSuffix = "detremote"; + } + } + + if (bForceIdle) + { + switch (activity) + { + case ACT_NEO_IDLE_CROUCH: + return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix); + + default: + return CalcSequenceIndex("%s%s", DEFAULT_IDLE_NAME, pSuffix); + } + } + else + { + switch (activity) + { + case ACT_NEO_MOVE_RUN: + return CalcSequenceIndex("%s%s", DEFAULT_RUN_NAME, pSuffix); + + case ACT_RUNTOIDLE: + Assert(false); + case ACT_IDLETORUN: + Assert(false); + case ACT_NEO_MOVE_WALK: + return CalcSequenceIndex("%s%s", DEFAULT_WALK_NAME, pSuffix); + + case ACT_NEO_IDLE_CROUCH: + return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix); + + case ACT_NEO_MOVE_CROUCH: + return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_WALK_NAME, pSuffix); + + case ACT_NEO_IDLE_STAND: + default: + return CalcSequenceIndex("%s%s", DEFAULT_IDLE_NAME, pSuffix); + } + } +} + +int CMultiPlayerAnimState::CalcFireSequence() +{ + if (!m_pPlayer) + { + return 0; + } + + auto pWeapon = m_pPlayer->GetActiveWeapon(); + if (!pWeapon) + { + return 0; + } + + const char* pSuffix = pWeapon->GetWpnData().szAnimationPrefix; + if (!pSuffix) + { + return 0; + } + + if (!Q_strcmp(pSuffix, "Grenade")) + { + pSuffix = "Gren1"; + } + + if (!Q_strcmp(pWeapon->GetClassname(), "weapon_remotedet")) + { + pSuffix = "detpack"; + auto detpack = static_cast(pWeapon); + if (detpack && (detpack->m_bRemoteHasBeenTriggered || + (detpack->m_bThisDetpackHasBeenThrown && (gpGlobals->curtime > detpack->m_flNextPrimaryAttack + 0.005)))) + { + pSuffix = "detremote"; + } + } + + + { + switch (m_eCurrentMainSequenceActivity) + { + case ACT_NEO_MOVE_RUN: + return CalcSequenceIndex("%s%s", DEFAULT_FIRE_RUN_NAME, pSuffix); + + case ACT_RUNTOIDLE: + Assert(false); + case ACT_IDLETORUN: + Assert(false); + case ACT_NEO_MOVE_WALK: + return CalcSequenceIndex("%s%s", DEFAULT_FIRE_WALK_NAME, pSuffix); + + case ACT_NEO_IDLE_CROUCH: + return CalcSequenceIndex("%s%s", DEFAULT_FIRE_CROUCH_NAME, pSuffix); + + case ACT_NEO_MOVE_CROUCH: + return CalcSequenceIndex("%s%s", DEFAULT_FIRE_CROUCH_WALK_NAME, pSuffix); + + case ACT_NEO_IDLE_STAND: + default: + return CalcSequenceIndex("%s%s", DEFAULT_FIRE_IDLE_NAME, pSuffix); + } + } +} + +int CMultiPlayerAnimState::CalcReloadSequence() +{ + if (!m_pPlayer) + { + return 0; + } + + auto pWeapon = m_pPlayer->GetActiveWeapon(); + if (!pWeapon) + { + return 0; + } + + const char* pSuffix = pWeapon->GetWpnData().szAnimationPrefix; + if (!pSuffix) + { + return 0; + } + + return CalcSequenceIndex("Reload_%s", pSuffix); +} + +#endif // NEO + //----------------------------------------------------------------------------- // Purpose: // Input : - @@ -1096,14 +1474,24 @@ void CMultiPlayerAnimState::ComputeMainSequence() // Have our class or the mod-specific class determine what the current activity is. Activity idealActivity = CalcMainActivity(); - #ifdef CLIENT_DLL Activity oldActivity = m_eCurrentMainSequenceActivity; #endif - // Store our current activity so the aim and fire layers know what to do. m_eCurrentMainSequenceActivity = idealActivity; +#ifdef NEO + float flCycle = pPlayer->GetCycle(); + UpdateAimSequenceLayers(flCycle, GESTURE_SLOT_AIM, true, &m_IdleSequenceTransitioner, 1); + + auto activeWeapon = GetBasePlayer()->GetActiveWeapon(); + if (m_hActiveWeapon != activeWeapon) + { // If we switched weapons, clear out the firing / reload animations + ResetGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD); + } + m_hActiveWeapon = activeWeapon; +#endif // NEO + // Hook to force playback of a specific requested full-body sequence if ( m_nSpecificMainSequence >= 0 ) { @@ -1137,9 +1525,14 @@ void CMultiPlayerAnimState::ComputeMainSequence() #ifdef CLIENT_DLL // If we went from idle to walk, reset the interpolation history. // Kind of hacky putting this here.. it might belong outside the base class. - if ( (oldActivity == ACT_MP_CROUCH_IDLE || oldActivity == ACT_MP_STAND_IDLE || oldActivity == ACT_MP_DEPLOYED_IDLE || oldActivity == ACT_MP_CROUCH_DEPLOYED_IDLE ) && - (idealActivity == ACT_MP_WALK || idealActivity == ACT_MP_CROUCHWALK ) ) - { +#ifdef NEO + if ( (oldActivity == ACT_CROUCHIDLE || oldActivity == ACT_IDLE ) && + (idealActivity == ACT_WALK || idealActivity == ACT_RUN_CROUCH || idealActivity == ACT_RUN) ) +#else + if ((oldActivity == ACT_MP_CROUCH_IDLE || oldActivity == ACT_MP_STAND_IDLE || oldActivity == ACT_MP_DEPLOYED_IDLE || oldActivity == ACT_MP_CROUCH_DEPLOYED_IDLE) && + (idealActivity == ACT_MP_WALK || idealActivity == ACT_MP_CROUCHWALK)) +#endif + { ResetGroundSpeed(); } #endif @@ -1957,22 +2350,38 @@ void CMultiPlayerAnimState::DebugShowActivity( Activity activity ) switch( activity ) { +#ifdef NEO + case ACT_IDLE: +#else case ACT_MP_STAND_IDLE: +#endif { pszActivity = "idle"; break; } +#ifdef NEO + case ACT_SPRINT: +#else case ACT_MP_SPRINT: +#endif { pszActivity = "sprint"; break; } +#ifdef NEO + case ACT_WALK: +#else case ACT_MP_WALK: +#endif { pszActivity = "walk"; break; } +#ifdef NEO + case ACT_RUN: +#else case ACT_MP_RUN: +#endif { pszActivity = "run"; break; diff --git a/mp/src/game/shared/Multiplayer/multiplayer_animstate.h b/mp/src/game/shared/Multiplayer/multiplayer_animstate.h index a3c7937ae..80a32795e 100644 --- a/mp/src/game/shared/Multiplayer/multiplayer_animstate.h +++ b/mp/src/game/shared/Multiplayer/multiplayer_animstate.h @@ -12,6 +12,9 @@ #include "convar.h" #include "basecombatweapon_shared.h" #include "iplayeranimstate.h" +#ifdef NEO +#include "sequence_Transitioner.h" +#endif #if defined( CLIENT_DLL ) class C_BasePlayer; @@ -76,6 +79,10 @@ enum PlayerAnimEvent_t // Gesture Slots. enum { +#ifdef NEO + GESTURE_SLOT_AIM, + GESTURE_SLOT_AIM2, // For blending aim sequences +#endif GESTURE_SLOT_ATTACK_AND_RELOAD, GESTURE_SLOT_GRENADE, GESTURE_SLOT_JUMP, @@ -237,6 +244,14 @@ class CMultiPlayerAnimState void ShutdownGestureSlots( void ); bool IsGestureSlotPlaying( int iGestureSlot, Activity iGestureActivity ); void AddToGestureSlot( int iGestureSlot, Activity iGestureActivity, bool bAutoKill ); +#ifdef NEO + int CalcSequenceIndex(const char* pBaseName, ...); + void UpdateAimSequenceLayers(float flCycle, int iFirstLayer, bool bForceIdle, CSequenceTransitioner* pTransitioner, float flWeightScale); + int CalcAimLayerSequence(Activity activity, bool bForceIdle); + int CalcFireSequence(); + int CalcReloadSequence(); + void AddToGestureSlot(int iGestureSlot, int iGestureSequence, bool bAutoKill); +#endif // NEO virtual void RestartGesture( int iGestureSlot, Activity iGestureActivity, bool bAutoKill = true ); void ComputeGestureSequence( CStudioHdr *pStudioHdr ); void UpdateGestureLayer( CStudioHdr *pStudioHdr, GestureSlot_t *pGesture ); @@ -342,6 +357,10 @@ class CMultiPlayerAnimState // movement playback options int m_nMovementSequence; LegAnimType_t m_LegAnimType; +#ifdef NEO + // This gives us smooth transitions between aim anim sequences on the client. + CSequenceTransitioner m_IdleSequenceTransitioner; +#endif }; // If this is set, then the game code needs to make sure to send player animation events diff --git a/mp/src/game/shared/base_playeranimstate.cpp b/mp/src/game/shared/base_playeranimstate.cpp index 1b5e8e6d2..e9fe51508 100644 --- a/mp/src/game/shared/base_playeranimstate.cpp +++ b/mp/src/game/shared/base_playeranimstate.cpp @@ -13,10 +13,6 @@ #include "utldict.h" #include "filesystem.h" -#ifdef NEO -#include "neo_playeranimstate.h" -#endif - #ifdef CLIENT_DLL #include "c_baseplayer.h" #include "engine/ivdebugoverlay.h" diff --git a/mp/src/game/shared/basecombatweapon_shared.cpp b/mp/src/game/shared/basecombatweapon_shared.cpp index fba4dcf9b..e94afa1af 100644 --- a/mp/src/game/shared/basecombatweapon_shared.cpp +++ b/mp/src/game/shared/basecombatweapon_shared.cpp @@ -2432,14 +2432,14 @@ bool CBaseCombatWeapon::SetIdealActivity( Activity ideal ) { //Set our activity to the next transitional animation SetActivity( ACT_TRANSITION ); - SetSequence( nextSequence ); + SetSequence( nextSequence ); SendViewModelAnim( nextSequence ); } else { //Set our activity to the ideal SetActivity( m_IdealActivity ); - SetSequence( m_nIdealSequence ); + SetSequence( m_nIdealSequence ); SendViewModelAnim( m_nIdealSequence ); } diff --git a/mp/src/game/shared/gamemovement.cpp b/mp/src/game/shared/gamemovement.cpp index e2232ae8e..f20574b8c 100644 --- a/mp/src/game/shared/gamemovement.cpp +++ b/mp/src/game/shared/gamemovement.cpp @@ -2531,7 +2531,8 @@ bool CGameMovement::CheckJumpButton( void ) #ifdef DEBUG Assert(dynamic_cast(player)); #endif - switch (static_cast(player)->GetClass()) + auto neoPlayer = static_cast(player); + switch (neoPlayer->GetClass()) { case NEO_CLASS_RECON: flMul *= RECON_JUMP_MULTIPLIER; @@ -2543,6 +2544,7 @@ bool CGameMovement::CheckJumpButton( void ) flMul *= ASSAULT_JUMP_MULTIPLIER; break; } + neoPlayer->DoAnimationEvent(PLAYERANIMEVENT_JUMP); #endif // Acclerate upward diff --git a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp index 6f5dc9f6a..6c2a75267 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp @@ -31,6 +31,9 @@ #include "engine/IEngineSound.h" #include "SoundEmitterSystem/isoundemittersystembase.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + extern ConVar sv_footsteps; const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] = @@ -141,575 +144,3 @@ void CHL2MP_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, f EmitSound( filter, entindex(), ep ); } - - -//========================== -// ANIMATION CODE -//========================== - - -// Below this many degrees, slow down turning rate linearly -#define FADE_TURN_DEGREES 45.0f -// After this, need to start turning feet -#define MAX_TORSO_ANGLE 90.0f -// Below this amount, don't play a turning animation/perform IK -#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f - -static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." ); -extern ConVar sv_backspeed; -extern ConVar mp_feetyawrate; -extern ConVar mp_facefronttime; -extern ConVar mp_ik; - -CPlayerAnimState::CPlayerAnimState( CHL2MP_Player *outer ) - : m_pOuter( outer ) -{ - m_flGaitYaw = 0.0f; - m_flGoalFeetYaw = 0.0f; - m_flCurrentFeetYaw = 0.0f; - m_flCurrentTorsoYaw = 0.0f; - m_flLastYaw = 0.0f; - m_flLastTurnTime = 0.0f; - m_flTurnCorrectionTime = 0.0f; - -#ifdef NEO - if (outer) - { - //outer->UseClientSideAnimation(); - } - else - { - Assert(false); - } -#endif -}; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CPlayerAnimState::Update() -{ - m_angRender = GetOuter()->GetLocalAngles(); - m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; - - ComputePoseParam_BodyYaw(); - ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr()); - ComputePoseParam_BodyLookYaw(); - -#ifdef NEO - ComputePoseParam_BodyXY(); -#else - ComputePlaybackRate(); // We do this in ComputePoseParam_BodyXY, don't call me -#endif - -#ifdef CLIENT_DLL - GetOuter()->UpdateLookAt(); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CPlayerAnimState::ComputePlaybackRate() -{ -#ifdef NEO - Assert(false); // We do this in ComputePoseParam_BodyXY, don't call me - return; -#else - // Determine ideal playback rate - Vector vel; - GetOuterAbsVelocity( vel ); - - float speed = vel.Length2D(); - - bool isMoving = ( speed > 0.5f ) ? true : false; - - float maxspeed = GetOuter()->GetSequenceGroundSpeed( GetOuter()->GetSequence() ); - - if ( isMoving && ( maxspeed > 0.0f ) ) - { - float flFactor = 1.0f; - - // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below - GetOuter()->SetPlaybackRate( ( speed * flFactor ) / maxspeed ); - - // BUG BUG: - // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed - } - else - { - GetOuter()->SetPlaybackRate( 1.0f ); - } -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: -// Output : CBasePlayer -//----------------------------------------------------------------------------- -CHL2MP_Player *CPlayerAnimState::GetOuter() -{ - return m_pOuter; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : dt - -//----------------------------------------------------------------------------- -void CPlayerAnimState::EstimateYaw( void ) -{ - float dt = gpGlobals->frametime; - - if ( !dt ) - { - return; - } - - Vector est_velocity; - QAngle angles; - - GetOuterAbsVelocity( est_velocity ); - - angles = GetOuter()->GetLocalAngles(); - - if ( est_velocity[1] == 0 && est_velocity[0] == 0 ) - { - float flYawDiff = angles[YAW] - m_flGaitYaw; - flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; - if (flYawDiff > 180) - flYawDiff -= 360; - if (flYawDiff < -180) - flYawDiff += 360; - - if (dt < 0.25) - flYawDiff *= dt * 4; - else - flYawDiff *= dt; - - m_flGaitYaw += flYawDiff; - m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360; - } - else - { - m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); - - if (m_flGaitYaw > 180) - m_flGaitYaw = 180; - else if (m_flGaitYaw < -180) - m_flGaitYaw = -180; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Override for backpeddling -// Input : dt - -//----------------------------------------------------------------------------- -void CPlayerAnimState::ComputePoseParam_BodyYaw( void ) -{ - int iYaw = GetOuter()->LookupPoseParameter( "move_yaw" ); - if ( iYaw < 0 ) - return; - - // view direction relative to movement - float flYaw; - - EstimateYaw(); - - QAngle angles = GetOuter()->GetLocalAngles(); - float ang = angles[ YAW ]; - if ( ang > 180.0f ) - { - ang -= 360.0f; - } - else if ( ang < -180.0f ) - { - ang += 360.0f; - } - - // calc side to side turning - flYaw = ang - m_flGaitYaw; - // Invert for mapping into 8way blend - flYaw = -flYaw; - flYaw = flYaw - (int)(flYaw / 360) * 360; - - if (flYaw < -180) - { - flYaw = flYaw + 360; - } - else if (flYaw > 180) - { - flYaw = flYaw - 360; - } - - GetOuter()->SetPoseParameter( iYaw, flYaw ); - -#ifndef CLIENT_DLL - //Adrian: Make the model's angle match the legs so the hitboxes match on both sides. - GetOuter()->SetLocalAngles( QAngle( GetOuter()->GetAnimEyeAngles().x, m_flCurrentFeetYaw, 0 ) ); -#endif -} - -#ifdef NEO -ConVar sv_neo_animrate_scale("sv_neo_animrate_scale", "1.0", FCVAR_REPLICATED | FCVAR_ARCHIVE | FCVAR_CHEAT, "", true, 0.0, true, 10.0); -ConVar sv_neo_animrate_max("sv_neo_animrate_max", "1.25", FCVAR_REPLICATED | FCVAR_ARCHIVE | FCVAR_CHEAT, "", true, 0.0, true, 10.0); -#endif - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr ) -{ - // Get pitch from v_angle - float flPitch = GetOuter()->GetLocalAngles()[ PITCH ]; - - if ( flPitch > 180.0f ) - { - flPitch -= 360.0f; - } - flPitch = clamp( flPitch, -90, 90 ); - - QAngle absangles = GetOuter()->GetAbsAngles(); - absangles.x = 0.0f; - m_angRender = absangles; - m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; - - // See if we have a blender for pitch -#ifdef NEO - GetOuter()->SetPoseParameter(pStudioHdr, "body_pitch", flPitch); -#else - GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch ); -#endif -} - -// Grabbed from CBasePlayerAnimState. We should really inherit/override from there. -float CalcMovementPlaybackRate(const float speed, const float groundSpeed, bool *bIsMoving) -{ - bool isMoving = (speed > MOVING_MINIMUM_SPEED); - - *bIsMoving = false; - float flReturnValue = 1; - - if (isMoving) - { - if (groundSpeed < 0.001f) - { - flReturnValue = 0.01; - } - else - { - // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below - flReturnValue = speed / groundSpeed; - flReturnValue = clamp(flReturnValue, 0.01f, -#ifdef NEO - sv_neo_animrate_max.GetFloat()); // clamp crouch legs max anim rate -#else - 10.f); // don't go nuts here. -#endif - } - *bIsMoving = true; - } - - return flReturnValue; -} - -void CPlayerAnimState::ComputePoseParam_BodyXY(void) -{ -#ifdef GAME_DLL -#if(0) - DevMsg("%i has seq: %s (%i)\n", - GetOuter()->GetSequence(), - "body_x", - (GetOuter()->HasPoseParameter(GetOuter()->GetSequence(), "move_x"))); -#endif -#endif - - const int poseparam_move_x = GetOuter()->LookupPoseParameter("move_x"); - - if (poseparam_move_x == -1) - { - return; - } - - const float speed = GetOuter()->GetLocalVelocity().Length2D(); - - float speedScale = clamp( - ((speed / ((GetOuter()->GetFlags() & FL_DUCKING) ? NEO_RECON_CROUCH_SPEED : NEO_RECON_NORM_SPEED))), - 0, 1); - - Vector eyeForward; - GetOuter()->EyeVectors(&eyeForward, NULL, NULL); - Assert(eyeForward.IsValid()); - Vector velocity = GetOuter()->GetLocalVelocity(); - - Vector2D eyeForward2D = eyeForward.AsVector2D(); - Vector2D velocity2D = velocity.AsVector2D(); - - eyeForward2D.NormalizeInPlace(); - velocity2D.NormalizeInPlace(); - - float forwardDot = eyeForward2D[0] * velocity2D[0] + eyeForward2D[1] * velocity2D[1]; - Vector2D eyeRight2D = Vector2D(eyeForward2D[1], eyeForward2D[0] * -1); // eyeForward2D rotated by 90 degrees - float sideDot = eyeRight2D[0] * velocity2D[0] + eyeRight2D[1] * velocity2D[1]; - - float speed_x = speedScale * forwardDot; - float speed_y = speedScale * sideDot; - - GetOuter()->SetPoseParameter(poseparam_move_x, speed_x); - GetOuter()->SetPoseParameter("move_y", speed_y); - - bool bIsMoving; - const float flPlaybackRate = CalcMovementPlaybackRate(speed, GetOuter()->GetSequenceGroundSpeed(GetOuter()->GetSequence()), &bIsMoving) * sv_neo_animrate_scale.GetFloat(); - - if (bIsMoving) - { - GetOuter()->SetPlaybackRate(flPlaybackRate); - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : goal - -// maxrate - -// dt - -// current - -// Output : int -//----------------------------------------------------------------------------- -int CPlayerAnimState::ConvergeAngles( float goal,float maxrate, float dt, float& current ) -{ - int direction = TURN_NONE; - - float anglediff = goal - current; - float anglediffabs = fabs( anglediff ); - - anglediff = AngleNormalize( anglediff ); - - float scale = 1.0f; - if ( anglediffabs <= FADE_TURN_DEGREES ) - { - scale = anglediffabs / FADE_TURN_DEGREES; - // Always do at least a bit of the turn ( 1% ) - scale = clamp( scale, 0.01f, 1.0f ); - } - - float maxmove = maxrate * dt * scale; - - if ( fabs( anglediff ) < maxmove ) - { - current = goal; - } - else - { - if ( anglediff > 0 ) - { - current += maxmove; - direction = TURN_LEFT; - } - else - { - current -= maxmove; - direction = TURN_RIGHT; - } - } - - current = AngleNormalize( current ); - - return direction; -} - -void CPlayerAnimState::ComputePoseParam_BodyLookYaw( void ) -{ - QAngle absangles = GetOuter()->GetAbsAngles(); - absangles.y = AngleNormalize( absangles.y ); - m_angRender = absangles; - m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; - -#ifdef NEO - int upper_body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" ); -#else - int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" ); -#endif - // See if we even have a blender for yaw - if ( upper_body_yaw < 0 ) - { - return; - } - - // Assume upper and lower bodies are aligned and that we're not turning - float flGoalTorsoYaw = 0.0f; - int turning = TURN_NONE; - float turnrate = 360.0f; - - Vector vel; - - GetOuterAbsVelocity( vel ); - - bool isMoving = ( vel.Length() > 1.0f ) ? true : false; - - if ( !isMoving ) - { - // Just stopped moving, try and clamp feet - if ( m_flLastTurnTime <= 0.0f ) - { - m_flLastTurnTime = gpGlobals->curtime; - m_flLastYaw = GetOuter()->GetAnimEyeAngles().y; - // Snap feet to be perfectly aligned with torso/eyes - m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; - m_flCurrentFeetYaw = m_flGoalFeetYaw; - m_nTurningInPlace = TURN_NONE; - } - - // If rotating in place, update stasis timer - if ( m_flLastYaw != GetOuter()->GetAnimEyeAngles().y ) - { - m_flLastTurnTime = gpGlobals->curtime; - m_flLastYaw = GetOuter()->GetAnimEyeAngles().y; - } - - if ( m_flGoalFeetYaw != m_flCurrentFeetYaw ) - { - m_flLastTurnTime = gpGlobals->curtime; - } - - turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); - - QAngle eyeAngles = GetOuter()->GetAnimEyeAngles(); - QAngle vAngle = GetOuter()->GetLocalAngles(); - - // See how far off current feetyaw is from true yaw - float yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw; - yawdelta = AngleNormalize( yawdelta ); - - bool rotated_too_far = false; - - float yawmagnitude = fabs( yawdelta ); - - // If too far, then need to turn in place - if ( yawmagnitude > 45 ) - { - rotated_too_far = true; - } - - // Standing still for a while, rotate feet around to face forward - // Or rotated too far - // FIXME: Play an in place turning animation - if ( rotated_too_far || - ( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) ) - { - m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; - m_flLastTurnTime = gpGlobals->curtime; - - /* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw; - if ( yd > 0 ) - { - m_nTurningInPlace = TURN_RIGHT; - } - else if ( yd < 0 ) - { - m_nTurningInPlace = TURN_LEFT; - } - else - { - m_nTurningInPlace = TURN_NONE; - } - - turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw ); - yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;*/ - - } - - // Snap upper body into position since the delta is already smoothed for the feet - flGoalTorsoYaw = yawdelta; - m_flCurrentTorsoYaw = flGoalTorsoYaw; - } - else - { - m_flLastTurnTime = 0.0f; - m_nTurningInPlace = TURN_NONE; - m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y; - flGoalTorsoYaw = 0.0f; - m_flCurrentTorsoYaw = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw; - } - - - if ( turning == TURN_NONE ) - { - m_nTurningInPlace = turning; - } - - if ( m_nTurningInPlace != TURN_NONE ) - { - // If we're close to finishing the turn, then turn off the turning animation - if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION ) - { - m_nTurningInPlace = TURN_NONE; - } - } - - // Rotate entire body into position - absangles = GetOuter()->GetAbsAngles(); - absangles.y = m_flCurrentFeetYaw; - m_angRender = absangles; - m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; - - GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) ); - - /* - // FIXME: Adrian, what is this? - int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" ); - - if ( body_yaw >= 0 ) - { - GetOuter()->SetPoseParameter( body_yaw, 30 ); - } - */ - -} - - - -//----------------------------------------------------------------------------- -// Purpose: -// Input : activity - -// Output : Activity -//----------------------------------------------------------------------------- -Activity CPlayerAnimState::BodyYawTranslateActivity( Activity activity ) -{ - // Not even standing still, sigh - if ( activity != ACT_IDLE ) - return activity; - - // Not turning - switch ( m_nTurningInPlace ) - { - default: - case TURN_NONE: - return activity; - /* - case TURN_RIGHT: - return ACT_TURNRIGHT45; - case TURN_LEFT: - return ACT_TURNLEFT45; - */ - case TURN_RIGHT: - case TURN_LEFT: - return mp_ik.GetBool() ? ACT_TURN : activity; - } - - Assert( 0 ); - return activity; -} - -const QAngle& CPlayerAnimState::GetRenderAngles() -{ - return m_angRender; -} - - -void CPlayerAnimState::GetOuterAbsVelocity( Vector& vel ) -{ -#if defined( CLIENT_DLL ) - GetOuter()->EstimateAbsVelocity( vel ); -#else - vel = GetOuter()->GetAbsVelocity(); -#endif -} \ No newline at end of file diff --git a/mp/src/game/shared/hl2mp/hl2mp_player_shared.h b/mp/src/game/shared/hl2mp/hl2mp_player_shared.h index f4e84fde3..f79f1c1c1 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.h +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.h @@ -34,70 +34,5 @@ enum HL2MPPlayerState #define CHL2MP_Player C_HL2MP_Player #endif -class CHL2MP_Player; - -class CPlayerAnimState -{ -public: - enum - { - TURN_NONE = 0, - TURN_LEFT, - TURN_RIGHT - }; - - CPlayerAnimState( CHL2MP_Player *outer ); - - Activity BodyYawTranslateActivity( Activity activity ); - - void Update(); - - const QAngle& GetRenderAngles(); - - void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] ); - - CHL2MP_Player *GetOuter(); - -private: - void GetOuterAbsVelocity( Vector& vel ); - - int ConvergeAngles( float goal,float maxrate, float dt, float& current ); - - void EstimateYaw( void ); - void ComputePoseParam_BodyYaw( void ); - void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr ); - void ComputePoseParam_BodyLookYaw( void ); -#ifdef NEO - void ComputePoseParam_BodyXY(void); - void ComputePoseParam_MoveYaw(void); -#endif - - void ComputePlaybackRate(); - - CHL2MP_Player *m_pOuter; - - float m_flGaitYaw; - float m_flStoredCycle; - - // The following variables are used for tweaking the yaw of the upper body when standing still and - // making sure that it smoothly blends in and out once the player starts moving - // Direction feet were facing when we stopped moving - float m_flGoalFeetYaw; - float m_flCurrentFeetYaw; - - float m_flCurrentTorsoYaw; - - // To check if they are rotating in place - float m_flLastYaw; - // Time when we stopped moving - float m_flLastTurnTime; - - // One of the above enums - int m_nTurningInPlace; - - QAngle m_angRender; - - float m_flTurnCorrectionTime; -}; #endif //HL2MP_PLAYER_SHARED_h diff --git a/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.cpp b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.cpp new file mode 100644 index 000000000..d4f4c8439 --- /dev/null +++ b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.cpp @@ -0,0 +1,988 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include "cbase.h" +#include "tier0/vprof.h" +#include "animation.h" +#include "studio.h" +#include "apparent_velocity_helper.h" +#include "utldict.h" + +#include "hl2mp_playeranimstate.h" +#include "base_playeranimstate.h" +#include "datacache/imdlcache.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#ifdef NEO +#include "c_neo_player.h" +#endif +#else +#include "hl2mp_player.h" +#ifdef NEO +#include "neo_player.h" +#endif +#endif + +#ifdef NEO +#include "shareddefs.h" + +#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_" +#endif + +#include "filesystem.h" +#include "engine/ivdebugoverlay.h" + +#define HL2MP_RUN_SPEED 320.0f +#define HL2MP_WALK_SPEED 75.0f +#define HL2MP_CROUCHWALK_SPEED 110.0f + +extern ConVar sv_showanimstate; +extern ConVar showanimstate_log; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +// Output : CMultiPlayerAnimState* +//----------------------------------------------------------------------------- +CHL2MPPlayerAnimState* CreateHL2MPPlayerAnimState( CHL2MP_Player *pPlayer ) +{ + MDLCACHE_CRITICAL_SECTION(); + + // Setup the movement data. + MultiPlayerMovementData_t movementData; + movementData.m_flBodyYawRate = 720.0f; + movementData.m_flRunSpeed = HL2MP_RUN_SPEED; + movementData.m_flWalkSpeed = HL2MP_WALK_SPEED; + movementData.m_flSprintSpeed = -1.0f; + + // Create animation state for this player. + CHL2MPPlayerAnimState *pRet = new CHL2MPPlayerAnimState( pPlayer, movementData ); + + // Specific HL2MP player initialization. + pRet->InitHL2MPAnimState( pPlayer ); + + return pRet; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : - +//----------------------------------------------------------------------------- +CHL2MPPlayerAnimState::CHL2MPPlayerAnimState() +{ + m_pHL2MPPlayer = NULL; + + // Don't initialize HL2MP specific variables here. Init them in InitHL2MPAnimState() +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pPlayer - +// &movementData - +//----------------------------------------------------------------------------- +CHL2MPPlayerAnimState::CHL2MPPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData ) +: CMultiPlayerAnimState( pPlayer, movementData ) +{ + m_pHL2MPPlayer = NULL; + + // Don't initialize HL2MP specific variables here. Init them in InitHL2MPAnimState() +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : - +//----------------------------------------------------------------------------- +CHL2MPPlayerAnimState::~CHL2MPPlayerAnimState() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Initialize HL2MP specific animation state. +// Input : *pPlayer - +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::InitHL2MPAnimState( CHL2MP_Player *pPlayer ) +{ + m_pHL2MPPlayer = pPlayer; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::ClearAnimationState( void ) +{ + BaseClass::ClearAnimationState(); +} + +int CHL2MPPlayerAnimState::CalcSequenceIndex(const char* pBaseName, ...) +{ + char szFullName[512]; + va_list marker; + va_start(marker, pBaseName); + Q_vsnprintf(szFullName, sizeof(szFullName), pBaseName, marker); + va_end(marker); + CBaseAnimatingOverlay* pPlayer = GetBasePlayer(); + int iSequence = pPlayer->LookupSequence(szFullName); + + // Show warnings if we can't find anything here. + if (iSequence == -1) + { + static CUtlDict dict; + if (dict.Find(szFullName) == -1) + { + dict.Insert(szFullName, 0); + Warning("CalcSequenceIndex: can't find '%s'.\n", szFullName); + } + + iSequence = 0; + } + + //DevMsg("CalcSeqIdx: \"%s\": %d\n", szFullName, iSequence); + + return iSequence; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : actDesired - +// Output : Activity +//----------------------------------------------------------------------------- +Activity CHL2MPPlayerAnimState::TranslateActivity( Activity actDesired ) +{ + // Hook into baseclass when / if hl2mp player models get swim animations. + Activity translateActivity = actDesired; //BaseClass::TranslateActivity( actDesired ); + if ( GetHL2MPPlayer()->GetActiveWeapon() ) + { + bool required = false; + translateActivity = GetHL2MPPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, &required); + } + return translateActivity; +} + +#ifdef NEO +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pStudioHdr - +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::ComputeSequences(CStudioHdr* pStudioHdr) +{ + VPROF("CBasePlayerAnimState::ComputeSequences"); + + // Lower body (walk/run/idle). + ComputeMainSequence(); + + // The groundspeed interpolator uses the main sequence info. + UpdateInterpolators(); + ComputeGestureSequence(pStudioHdr); +} + +#endif //NEO +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::Update( float eyeYaw, float eyePitch ) +{ + // Profile the animation update. + VPROF( "CHL2MPPlayerAnimState::Update" ); + + // Get the HL2MP player. + CHL2MP_Player *pHL2MPPlayer = GetHL2MPPlayer(); + if ( !pHL2MPPlayer ) + return; + + // Get the studio header for the player. + CStudioHdr *pStudioHdr = pHL2MPPlayer->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 ) ) + { + // 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() ) + { + m_pHL2MPPlayer->SetPlaybackRate( 1.0f ); + } +#endif + +#ifdef CLIENT_DLL + if (cl_showanimstate.GetInt() == m_pHL2MPPlayer->entindex()) + { + DebugShowAnimStateFull(5); + } + else if (cl_showanimstate.GetInt() == -2) + { + C_BasePlayer* targetPlayer = C_BasePlayer::GetLocalPlayer(); + + if (targetPlayer && (targetPlayer->GetObserverMode() == OBS_MODE_IN_EYE || targetPlayer->GetObserverMode() == OBS_MODE_CHASE)) + { + C_BaseEntity* target = targetPlayer->GetObserverTarget(); + + if (target && target->IsPlayer()) + { + targetPlayer = ToBasePlayer(target); + } + } + + if (m_pHL2MPPlayer == targetPlayer) + { + DebugShowAnimStateFull(6); + } + } +#else + if (sv_showanimstate.GetInt() == m_pHL2MPPlayer->entindex()) + { + DebugShowAnimState(20); + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : event - +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) +{ + Activity iGestureActivity = ACT_INVALID; + + switch( event ) + { + case PLAYERANIMEVENT_ATTACK_PRIMARY: + { +#ifdef NEO + AddToGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD, CalcFireSequence(), true); +#else + // Weapon primary fire. + if ( m_pHL2MPPlayer->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; +#endif + 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: + { +#ifdef NEO + AddToGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD, CalcFireSequence(), true); +#else + // Weapon secondary fire. + if ( m_pHL2MPPlayer->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; +#endif + break; + } + case PLAYERANIMEVENT_ATTACK_PRE: + { + if ( m_pHL2MPPlayer->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, false ); + + break; + } + case PLAYERANIMEVENT_ATTACK_POST: + { + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_ATTACK_STAND_POSTFIRE ); + break; + } + + case PLAYERANIMEVENT_RELOAD: + { +#ifdef NEO + AddToGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD, CalcReloadSequence(), true); +#else + // Weapon reload. + if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH ); + else + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND ); +#endif + break; + } + case PLAYERANIMEVENT_RELOAD_LOOP: + { + // Weapon reload. + if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_LOOP ); + else + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_LOOP ); + break; + } + case PLAYERANIMEVENT_RELOAD_END: + { + // Weapon reload. + if ( GetBasePlayer()->GetFlags() & FL_DUCKING ) + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_CROUCH_END ); + else + RestartGesture( GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_MP_RELOAD_STAND_END ); + break; + } + default: + { + BaseClass::DoAnimationEvent( event, nData ); + break; + } + } + +#ifdef CLIENT_DLL + // Make the weapon play the animation as well + if ( iGestureActivity != ACT_INVALID ) + { + CBaseCombatWeapon *pWeapon = GetHL2MPPlayer()->GetActiveWeapon(); + if ( pWeapon ) + { +// pWeapon->EnsureCorrectRenderingModel(); + pWeapon->SendWeaponAnim( iGestureActivity ); +// // Force animation events! +// pWeapon->ResetEventsParity(); // reset event parity so the animation events will occur on the weapon. + pWeapon->DoAnimationEvents( pWeapon->GetModelPtr() ); + } + } +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *idealActivity - +//----------------------------------------------------------------------------- +bool CHL2MPPlayerAnimState::HandleSwimming( Activity &idealActivity ) +{ + bool bInWater = BaseClass::HandleSwimming( idealActivity ); + + return bInWater; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *idealActivity - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CHL2MPPlayerAnimState::HandleMoving( Activity &idealActivity ) +{ +#ifdef NEO + if (m_pHL2MPPlayer->IsWalking()) + { + idealActivity = ACT_WALK; + } + else + { + idealActivity = ACT_RUN; + } + + return true; +#else + return BaseClass::HandleMoving( idealActivity ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *idealActivity - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CHL2MPPlayerAnimState::HandleDucking( Activity &idealActivity ) +{ + if ( m_pHL2MPPlayer->GetFlags() & FL_DUCKING ) + { + if ( GetOuterXYSpeed() < MOVING_MINIMUM_SPEED ) + { +#ifdef NEO + idealActivity = ACT_CROUCHIDLE; +#else + idealActivity = ACT_MP_CROUCH_IDLE; +#endif + } + else + { +#ifdef NEO + idealActivity = ACT_RUN_CROUCH; +#else + idealActivity = ACT_MP_CROUCHWALK; +#endif + } + + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +bool CHL2MPPlayerAnimState::HandleJumping( Activity &idealActivity ) +{ + Vector vecVelocity; + GetOuterAbsVelocity( vecVelocity ); + + if ( m_bJumping ) + { + static bool bNewJump = false; //Tony; hl2mp players only have a 'hop' + + if ( m_bFirstJumpFrame ) + { + m_bFirstJumpFrame = false; + RestartMainSequence(); // Reset the animation. + } + + // Reset if we hit water and start swimming. + if ( m_pHL2MPPlayer->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 ( m_pHL2MPPlayer->GetFlags() & FL_ONGROUND ) + { + m_bJumping = false; + RestartMainSequence(); + + if ( bNewJump ) + { +#ifdef NEO + RestartGesture(GESTURE_SLOT_JUMP, ACT_HOP); +#else + RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND ); +#endif + } + } + } + + // if we're still jumping + if ( m_bJumping ) + { +#ifdef NEO + idealActivity = ACT_HOP; +#else + 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; + } +#endif + } + } + + if ( m_bJumping ) + return true; + + return false; +} + +bool CHL2MPPlayerAnimState::SetupPoseParameters( CStudioHdr *pStudioHdr ) +{ +#ifdef NEO + BaseClass::SetupPoseParameters(pStudioHdr); +#endif + // Check to see if this has already been done. + if ( m_bPoseParameterInit ) + return true; + + // Save off the pose parameter indices. + if ( !pStudioHdr ) + return false; + + // Tony; just set them both to the same for now. + m_PoseParameterData.m_iMoveX = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_yaw" ); + m_PoseParameterData.m_iMoveY = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "move_yaw" ); + if ( ( m_PoseParameterData.m_iMoveX < 0 ) || ( m_PoseParameterData.m_iMoveY < 0 ) ) + return false; + + // Look for the aim pitch blender. + m_PoseParameterData.m_iAimPitch = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "body_pitch" ); + if ( m_PoseParameterData.m_iAimPitch < 0 ) + return false; + + // Look for aim yaw blender. + m_PoseParameterData.m_iAimYaw = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "body_yaw" ); + if ( m_PoseParameterData.m_iAimYaw < 0 ) + return false; + + m_bPoseParameterInit = true; + + return true; +} +float SnapYawTo( float flValue ); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::EstimateYaw( void ) +{ + // Get the frame time. + float flDeltaTime = gpGlobals->frametime; + if ( flDeltaTime == 0.0f ) + return; + +#if 0 // 9way + // Get the player's velocity and angles. + Vector vecEstVelocity; + GetOuterAbsVelocity( vecEstVelocity ); + QAngle angles = GetBasePlayer()->GetLocalAngles(); + + // If we are not moving, sync up the feet and eyes slowly. + if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f ) + { + float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw; + flYawDelta = AngleNormalize( flYawDelta ); + + if ( flDeltaTime < 0.25f ) + { + flYawDelta *= ( flDeltaTime * 4.0f ); + } + else + { + flYawDelta *= flDeltaTime; + } + + m_PoseParameterData.m_flEstimateYaw += flYawDelta; + AngleNormalize( m_PoseParameterData.m_flEstimateYaw ); + } + else + { + m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI ); + m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f ); + } +#else + float dt = gpGlobals->frametime; + + // Get the player's velocity and angles. + Vector vecEstVelocity; + GetOuterAbsVelocity( vecEstVelocity ); + QAngle angles = GetBasePlayer()->GetLocalAngles(); + + if ( vecEstVelocity.y == 0 && vecEstVelocity.x == 0 ) + { + float flYawDiff = angles[YAW] - m_PoseParameterData.m_flEstimateYaw; + flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; + if (flYawDiff > 180) + flYawDiff -= 360; + if (flYawDiff < -180) + flYawDiff += 360; + + if (dt < 0.25) + flYawDiff *= dt * 4; + else + flYawDiff *= dt; + + m_PoseParameterData.m_flEstimateYaw += flYawDiff; + m_PoseParameterData.m_flEstimateYaw = m_PoseParameterData.m_flEstimateYaw - (int)(m_PoseParameterData.m_flEstimateYaw / 360) * 360; + } + else + { + m_PoseParameterData.m_flEstimateYaw = (atan2(vecEstVelocity.y, vecEstVelocity.x) * 180 / M_PI); + + if (m_PoseParameterData.m_flEstimateYaw > 180) + m_PoseParameterData.m_flEstimateYaw = 180; + else if (m_PoseParameterData.m_flEstimateYaw < -180) + m_PoseParameterData.m_flEstimateYaw = -180; + } +#endif +} +//----------------------------------------------------------------------------- +// Purpose: Override for backpeddling +// Input : dt - +//----------------------------------------------------------------------------- +float SnapYawTo( float flValue ); +void CHL2MPPlayerAnimState::ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr ) +{ +#ifdef NEO + BaseClass::ComputePoseParam_MoveYaw(pStudioHdr); +#endif + // Get the estimated movement yaw. + EstimateYaw(); + +#if 1 // 9way + ConVarRef mp_slammoveyaw("mp_slammoveyaw"); + + // Get the view yaw. + float flAngle = AngleNormalize( m_flEyeYaw ); + + // Calc side to side turning - the view vs. movement yaw. + float flYaw = flAngle - m_PoseParameterData.m_flEstimateYaw; + flYaw = AngleNormalize( -flYaw ); + + // Get the current speed the character is running. + bool bIsMoving; + float flPlaybackRate = CalcMovementPlaybackRate( &bIsMoving ); + + // Setup the 9-way blend parameters based on our speed and direction. + Vector2D vecCurrentMoveYaw( 0.0f, 0.0f ); + if ( bIsMoving ) + { + if ( mp_slammoveyaw.GetBool() ) + flYaw = SnapYawTo( flYaw ); + + vecCurrentMoveYaw.x = cos( DEG2RAD( flYaw ) ) * flPlaybackRate; + vecCurrentMoveYaw.y = -sin( DEG2RAD( flYaw ) ) * flPlaybackRate; + } + + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, vecCurrentMoveYaw.x ); + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, vecCurrentMoveYaw.y ); + + m_DebugAnimData.m_vecMoveYaw = vecCurrentMoveYaw; +#else + // view direction relative to movement + float flYaw; + + QAngle angles = GetBasePlayer()->GetLocalAngles(); + float ang = angles[ YAW ]; + if ( ang > 180.0f ) + { + ang -= 360.0f; + } + else if ( ang < -180.0f ) + { + ang += 360.0f; + } + + // calc side to side turning + flYaw = ang - m_PoseParameterData.m_flEstimateYaw; + // Invert for mapping into 8way blend + flYaw = -flYaw; + flYaw = flYaw - (int)(flYaw / 360) * 360; + + if (flYaw < -180) + { + flYaw = flYaw + 360; + } + else if (flYaw > 180) + { + flYaw = flYaw - 360; + } + + //Tony; oops, i inverted this previously above. + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, flYaw ); + +#endif + +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr ) +{ + // Get the view pitch. + float flAimPitch = m_flEyePitch; + + // Set the aim pitch pose parameter and save. + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimPitch, flAimPitch ); + m_DebugAnimData.m_flAimPitch = flAimPitch; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr ) +{ + // Get the movement velocity. + Vector vecVelocity; + GetOuterAbsVelocity( vecVelocity ); + + // Check to see if we are moving. + bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false; + + // If we are moving or are prone and undeployed. + if ( bMoving || m_bForceAimYaw ) + { + // The feet match the eye direction when moving - the move yaw takes care of the rest. + m_flGoalFeetYaw = m_flEyeYaw; + } + // Else if we are not moving. + else + { + // Initialize the feet. + if ( m_PoseParameterData.m_flLastAimTurnTime <= 0.0f ) + { + m_flGoalFeetYaw = m_flEyeYaw; + m_flCurrentFeetYaw = m_flEyeYaw; + m_PoseParameterData.m_flLastAimTurnTime = gpGlobals->curtime; + } + // Make sure the feet yaw isn't too far out of sync with the eye yaw. + // TODO: Do something better here! + else + { + float flYawDelta = AngleNormalize( m_flGoalFeetYaw - m_flEyeYaw ); + +#ifdef NEO + if (fabs(flYawDelta) > 90.f /*NEO_ANIMSTATE_MAX_BODY_YAW_DEGREES*/) +#else + if ( fabs( flYawDelta ) > 45.0f ) +#endif + { + float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f; + +#ifdef NEO + m_flGoalFeetYaw += (90.f/*NEO_ANIMSTATE_MAX_BODY_YAW_DEGREES*/ * flSide); +#else + m_flGoalFeetYaw += ( 45.0f * flSide ); +#endif + } + } + } + + // Fix up the feet yaw. + m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw ); + if ( m_flGoalFeetYaw != m_flCurrentFeetYaw ) + { + if ( m_bForceAimYaw ) + { + m_flCurrentFeetYaw = m_flGoalFeetYaw; + } + else + { + ConvergeYawAngles( m_flGoalFeetYaw, 720.0f, gpGlobals->frametime, m_flCurrentFeetYaw ); + m_flLastAimTurnTime = gpGlobals->curtime; + } + } + + // Rotate the body into position. + m_angRender[YAW] = m_flCurrentFeetYaw; + + // Find the aim(torso) yaw base on the eye and feet yaws. + float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw; + flAimYaw = AngleNormalize( flAimYaw ); + + // Set the aim yaw and save. + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, flAimYaw ); + m_DebugAnimData.m_flAimYaw = flAimYaw; + + // Turn off a force aim yaw - either we have already updated or we don't need to. + m_bForceAimYaw = false; + +#ifndef CLIENT_DLL + QAngle angle = GetBasePlayer()->GetAbsAngles(); + angle[YAW] = m_flCurrentFeetYaw; + + GetBasePlayer()->SetAbsAngles( angle ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Override the default, because hl2mp models don't use moveX +// Input : - +// Output : float +//----------------------------------------------------------------------------- +float CHL2MPPlayerAnimState::GetCurrentMaxGroundSpeed() +{ +#ifdef NEO + return BaseClass::GetCurrentMaxGroundSpeed(); +#endif + CStudioHdr *pStudioHdr = GetBasePlayer()->GetModelPtr(); + + if ( pStudioHdr == NULL ) + return 1.0f; + +// float prevX = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveX ); + float prevY = GetBasePlayer()->GetPoseParameter( m_PoseParameterData.m_iMoveY ); + + float d = sqrt( /*prevX * prevX + */prevY * prevY ); + float newY;//, newX; + if ( d == 0.0 ) + { +// newX = 1.0; + newY = 0.0; + } + else + { +// newX = prevX / d; + newY = prevY / d; + } + +// GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, newX ); + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, newY ); + + float speed = GetBasePlayer()->GetSequenceGroundSpeed( GetBasePlayer()->GetSequence() ); + +// GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveX, prevX ); + GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iMoveY, prevY ); + + return speed; +} + +// ----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::AnimStateLog(const char* pMsg, ...) +{ + // Format the string. + char str[4096]; + va_list marker; + va_start(marker, pMsg); + Q_vsnprintf(str, sizeof(str), pMsg, marker); + va_end(marker); + + // Log it? + if (showanimstate_log.GetInt() == 1 || showanimstate_log.GetInt() == 3) + { + Msg("%s", str); + } + + if (showanimstate_log.GetInt() > 1) + { +#ifdef CLIENT_DLL + const char* fname = "AnimStateClient.log"; +#else + const char* fname = "AnimStateServer.log"; +#endif + static FileHandle_t hFile = filesystem->Open(fname, "wt"); + filesystem->FPrintf(hFile, "%s", str); + filesystem->Flush(hFile); + } +} + +// ----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::AnimStatePrintf(int iLine, const char* pMsg, ...) +{ + // Format the string. + char str[4096]; + va_list marker; + va_start(marker, pMsg); + Q_vsnprintf(str, sizeof(str), pMsg, marker); + va_end(marker); + + // Show it with Con_NPrintf. + engine->Con_NPrintf(iLine, "%s", str); + + // Log it. + AnimStateLog("%s\n", str); +} + + +// ----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::DebugShowAnimState(int iStartLine) +{ + Vector vOuterVel; + GetOuterAbsVelocity(vOuterVel); + + int iLine = iStartLine; + AnimStatePrintf(iLine++, "main: %s(%d), cycle: %.2f cyclerate: %.2f playbackrate: %.2f\n", + GetSequenceName(m_pHL2MPPlayer->GetModelPtr(), m_pHL2MPPlayer->GetSequence()), + m_pHL2MPPlayer->GetSequence(), + m_pHL2MPPlayer->GetCycle(), + m_pHL2MPPlayer->GetSequenceCycleRate(m_pHL2MPPlayer->GetModelPtr(), m_pHL2MPPlayer->GetSequence()), + m_pHL2MPPlayer->GetPlaybackRate() + ); + + for (int i = 0; i < m_pHL2MPPlayer->GetNumAnimOverlays() - 1; i++) + { + CAnimationLayer* pLayer = m_pHL2MPPlayer->GetAnimOverlay(AIMSEQUENCE_LAYER + i); +#ifdef CLIENT_DLL + AnimStatePrintf(iLine++, "%s(%d), weight: %.2f, cycle: %.2f, order (%d), aim (%d)", + !pLayer->IsActive() ? "-- " : (pLayer->m_nSequence == 0 ? "-- " : GetSequenceName(m_pHL2MPPlayer->GetModelPtr(), pLayer->m_nSequence)), + !pLayer->IsActive() ? 0 : (int)pLayer->m_nSequence, + !pLayer->IsActive() ? 0 : (float)pLayer->m_flWeight, + !pLayer->IsActive() ? 0 : (float)pLayer->m_flCycle, + !pLayer->IsActive() ? 0 : (int)pLayer->m_nOrder, + i + ); +#else + AnimStatePrintf(iLine++, "%s(%d), flags (%d), weight: %.2f, cycle: %.2f, order (%d), aim (%d)", + !pLayer->IsActive() ? "-- " : (pLayer->m_nSequence == 0 ? "-- " : GetSequenceName(m_pHL2MPPlayer->GetModelPtr(), pLayer->m_nSequence)), + !pLayer->IsActive() ? 0 : (int)pLayer->m_nSequence, + !pLayer->IsActive() ? 0 : (int)pLayer->m_fFlags,// Doesn't exist on client + !pLayer->IsActive() ? 0 : (float)pLayer->m_flWeight, + !pLayer->IsActive() ? 0 : (float)pLayer->m_flCycle, + !pLayer->IsActive() ? 0 : (int)pLayer->m_nOrder, + i + ); +#endif + } + + AnimStatePrintf(iLine++, "vel: %.2f, time: %.2f, max: %.2f, animspeed: %.2f", + vOuterVel.Length2D(), gpGlobals->curtime, GetInterpolatedGroundSpeed(), m_pHL2MPPlayer->GetSequenceGroundSpeed(m_pHL2MPPlayer->GetSequence())); + + { + AnimStatePrintf(iLine++, "ent yaw: %.2f, body_yaw: %.2f, body_pitch: %.2f, move_x: %.2f, move_y: %.2f", + m_angRender[YAW], g_flLastBodyYaw, g_flLastBodyPitch, m_DebugAnimData.m_vecMoveYaw.x, m_DebugAnimData.m_vecMoveYaw.y); + } + + // Draw a red triangle on the ground for the eye yaw. + float flBaseSize = 10; + float flHeight = 80; + Vector vBasePos = m_pHL2MPPlayer->GetAbsOrigin() + Vector(0, 0, 3); + QAngle angles(0, 0, 0); + angles[YAW] = m_flEyeYaw; + Vector vForward, vRight, vUp; + AngleVectors(angles, &vForward, &vRight, &vUp); + debugoverlay->AddTriangleOverlay(vBasePos + vRight * flBaseSize / 2, vBasePos - vRight * flBaseSize / 2, vBasePos + vForward * flHeight, 255, 0, 0, 255, false, 0.01); + + // Draw a blue triangle on the ground for the body yaw. + angles[YAW] = m_angRender[YAW]; + AngleVectors(angles, &vForward, &vRight, &vUp); + debugoverlay->AddTriangleOverlay(vBasePos + vRight * flBaseSize / 2, vBasePos - vRight * flBaseSize / 2, vBasePos + vForward * flHeight, 0, 0, 255, 255, false, 0.01); + +} + +// ----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::DebugShowAnimStateFull(int iStartLine) +{ + AnimStateLog("----------------- frame %d -----------------\n", gpGlobals->framecount); + + DebugShowAnimState(iStartLine); + + AnimStateLog("--------------------------------------------\n\n"); +} diff --git a/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.h b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.h new file mode 100644 index 000000000..bea91c50b --- /dev/null +++ b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.h @@ -0,0 +1,74 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#ifndef HL2MP_PLAYERANIMSTATE_H +#define HL2MP_PLAYERANIMSTATE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "convar.h" +#include "multiplayer_animstate.h" + +#if defined( CLIENT_DLL ) +class C_HL2MP_Player; +#define CHL2MP_Player C_HL2MP_Player +#else +class CHL2MP_Player; +#endif + +// ------------------------------------------------------------------------------------------------ // +// CPlayerAnimState declaration. +// ------------------------------------------------------------------------------------------------ // +class CHL2MPPlayerAnimState : public CMultiPlayerAnimState +{ +public: + + DECLARE_CLASS( CHL2MPPlayerAnimState, CMultiPlayerAnimState ); + + CHL2MPPlayerAnimState(); + CHL2MPPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerMovementData_t &movementData ); + ~CHL2MPPlayerAnimState(); + + void InitHL2MPAnimState( CHL2MP_Player *pPlayer ); + CHL2MP_Player *GetHL2MPPlayer( void ) { return m_pHL2MPPlayer; } + + virtual void ClearAnimationState(); + int CalcSequenceIndex(const char* pBaseName, ...); + virtual Activity TranslateActivity( Activity actDesired ); + virtual void Update( float eyeYaw, float eyePitch ); + + void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 ); + + bool HandleMoving( Activity &idealActivity ); + bool HandleJumping( Activity &idealActivity ); + bool HandleDucking( Activity &idealActivity ); + bool HandleSwimming( Activity &idealActivity ); + + virtual float GetCurrentMaxGroundSpeed(); +#ifdef NEO + virtual void ComputeSequences(CStudioHdr* pStudioHdr); +#endif + + void DebugShowAnimStateFull(int iStartLine); + virtual void DebugShowAnimState(int iStartLine); + void AnimStatePrintf(int iLine, PRINTF_FORMAT_STRING const char* pMsg, ...); + void AnimStateLog(PRINTF_FORMAT_STRING const char* pMsg, ...); + +private: + + bool SetupPoseParameters( CStudioHdr *pStudioHdr ); + virtual void EstimateYaw( void ); + virtual void ComputePoseParam_MoveYaw( CStudioHdr *pStudioHdr ); + virtual void ComputePoseParam_AimPitch( CStudioHdr *pStudioHdr ); + virtual void ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr ); + + CHL2MP_Player *m_pHL2MPPlayer; + bool m_bInAirWalk; + float m_flHoldDeployedPoseUntilTime; +}; + +CHL2MPPlayerAnimState *CreateHL2MPPlayerAnimState( CHL2MP_Player *pPlayer ); + + + +#endif // HL2MP_PLAYERANIMSTATE_H diff --git a/mp/src/game/shared/hl2mp/weapon_357.cpp b/mp/src/game/shared/hl2mp/weapon_357.cpp index d943f2787..38fb8ad99 100644 --- a/mp/src/game/shared/hl2mp/weapon_357.cpp +++ b/mp/src/game/shared/hl2mp/weapon_357.cpp @@ -35,10 +35,7 @@ class CWeapon357 : public CBaseHL2MPCombatWeapon void PrimaryAttack( void ); DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif private: @@ -57,24 +54,24 @@ LINK_ENTITY_TO_CLASS( weapon_357, CWeapon357 ); PRECACHE_WEAPON_REGISTER( weapon_357 ); -#ifndef CLIENT_DLL acttable_t CWeapon357::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false }, -}; + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, -IMPLEMENT_ACTTABLE( CWeapon357 ); + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, -#endif + { ACT_MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, +}; + +IMPLEMENT_ACTTABLE( CWeapon357 ); //----------------------------------------------------------------------------- // Purpose: Constructor @@ -91,7 +88,7 @@ CWeapon357::CWeapon357( void ) void CWeapon357::PrimaryAttack( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if ( !pPlayer ) { @@ -117,7 +114,7 @@ void CWeapon357::PrimaryAttack( void ) pPlayer->DoMuzzleFlash(); SendWeaponAnim( ACT_VM_PRIMARYATTACK ); - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); m_flNextPrimaryAttack = gpGlobals->curtime + 0.75; m_flNextSecondaryAttack = gpGlobals->curtime + 0.75; @@ -125,7 +122,7 @@ void CWeapon357::PrimaryAttack( void ) m_iClip1--; Vector vecSrc = pPlayer->Weapon_ShootPosition(); - Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); + Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); FireBulletsInfo_t info( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType ); info.m_pAttacker = pPlayer; diff --git a/mp/src/game/shared/hl2mp/weapon_ar2.cpp b/mp/src/game/shared/hl2mp/weapon_ar2.cpp index 5086db1bc..ed2dea010 100644 --- a/mp/src/game/shared/hl2mp/weapon_ar2.cpp +++ b/mp/src/game/shared/hl2mp/weapon_ar2.cpp @@ -46,24 +46,25 @@ LINK_ENTITY_TO_CLASS( weapon_ar2, CWeaponAR2 ); PRECACHE_WEAPON_REGISTER(weapon_ar2); -#ifndef CLIENT_DLL - acttable_t CWeaponAR2::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR2, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_AR2, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_AR2, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_AR2, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_AR2, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_AR2, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_AR2, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_AR2, false }, }; IMPLEMENT_ACTTABLE(CWeaponAR2); -#endif - CWeaponAR2::CWeaponAR2( ) { m_fMinRange1 = 65; diff --git a/mp/src/game/shared/hl2mp/weapon_ar2.h b/mp/src/game/shared/hl2mp/weapon_ar2.h index 8aa8dde85..36723051d 100644 --- a/mp/src/game/shared/hl2mp/weapon_ar2.h +++ b/mp/src/game/shared/hl2mp/weapon_ar2.h @@ -75,9 +75,7 @@ class CWeaponAR2 : public CHL2MPMachineGun bool m_bShotDelayed; int m_nVentPose; -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif }; diff --git a/mp/src/game/shared/hl2mp/weapon_crossbow.cpp b/mp/src/game/shared/hl2mp/weapon_crossbow.cpp index 5d22003e8..a617418d8 100644 --- a/mp/src/game/shared/hl2mp/weapon_crossbow.cpp +++ b/mp/src/game/shared/hl2mp/weapon_crossbow.cpp @@ -433,9 +433,7 @@ class CWeaponCrossbow : public CBaseHL2MPCombatWeapon void SetChargerState( ChargerState_t state ); void DoLoadEffect( void ); -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif private: @@ -475,23 +473,25 @@ LINK_ENTITY_TO_CLASS( weapon_crossbow, CWeaponCrossbow ); PRECACHE_WEAPON_REGISTER( weapon_crossbow ); -#ifndef CLIENT_DLL - acttable_t CWeaponCrossbow::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false }, }; IMPLEMENT_ACTTABLE(CWeaponCrossbow); -#endif - //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- diff --git a/mp/src/game/shared/hl2mp/weapon_crowbar.cpp b/mp/src/game/shared/hl2mp/weapon_crowbar.cpp index 55a03d1d6..06b918cb5 100644 --- a/mp/src/game/shared/hl2mp/weapon_crowbar.cpp +++ b/mp/src/game/shared/hl2mp/weapon_crowbar.cpp @@ -45,24 +45,25 @@ END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar ); PRECACHE_WEAPON_REGISTER( weapon_crowbar ); -#ifndef CLIENT_DLL - acttable_t CWeaponCrowbar::m_acttable[] = { - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_MELEE, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_MELEE, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_MELEE, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, }; IMPLEMENT_ACTTABLE(CWeaponCrowbar); -#endif - //----------------------------------------------------------------------------- // Constructor //----------------------------------------------------------------------------- diff --git a/mp/src/game/shared/hl2mp/weapon_crowbar.h b/mp/src/game/shared/hl2mp/weapon_crowbar.h index 2cd10fb9c..57301cd41 100644 --- a/mp/src/game/shared/hl2mp/weapon_crowbar.h +++ b/mp/src/game/shared/hl2mp/weapon_crowbar.h @@ -35,10 +35,7 @@ class CWeaponCrowbar : public CBaseHL2MPBludgeonWeapon DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif CWeaponCrowbar(); diff --git a/mp/src/game/shared/hl2mp/weapon_frag.cpp b/mp/src/game/shared/hl2mp/weapon_frag.cpp index 9ddcb8133..d0543942f 100644 --- a/mp/src/game/shared/hl2mp/weapon_frag.cpp +++ b/mp/src/game/shared/hl2mp/weapon_frag.cpp @@ -82,29 +82,27 @@ class CWeaponFrag: public CBaseHL2MPCombatWeapon CNetworkVar( bool, m_fDrawbackFinished ); CWeaponFrag( const CWeaponFrag & ); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif }; - -#ifndef CLIENT_DLL - acttable_t CWeaponFrag::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_GRENADE, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_GRENADE, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_GRENADE, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_GRENADE, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false }, }; IMPLEMENT_ACTTABLE(CWeaponFrag); -#endif - IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFrag, DT_WeaponFrag ) BEGIN_NETWORK_TABLE( CWeaponFrag, DT_WeaponFrag ) @@ -341,7 +339,7 @@ void CWeaponFrag::ItemPostFrame( void ) { if( m_fDrawbackFinished ) { - CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); if (pOwner) { @@ -351,6 +349,7 @@ void CWeaponFrag::ItemPostFrame( void ) if( !(pOwner->m_nButtons & IN_ATTACK) ) { SendWeaponAnim( ACT_VM_THROW ); + pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); m_fDrawbackFinished = false; } break; @@ -369,6 +368,8 @@ void CWeaponFrag::ItemPostFrame( void ) //Send the weapon animation SendWeaponAnim( ACT_VM_HAULBACK ); } + //Tony; the grenade really should have a secondary anim. but it doesn't on the player. + pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); m_fDrawbackFinished = false; } diff --git a/mp/src/game/shared/hl2mp/weapon_hl2mpbase.cpp b/mp/src/game/shared/hl2mp/weapon_hl2mpbase.cpp index 15995a5be..a9269b960 100644 --- a/mp/src/game/shared/hl2mp/weapon_hl2mpbase.cpp +++ b/mp/src/game/shared/hl2mp/weapon_hl2mpbase.cpp @@ -105,7 +105,17 @@ bool CWeaponHL2MPBase::IsPredicted() const { return true; } - +//Tony; override for animation purposes. +bool CWeaponHL2MPBase::Reload( void ) +{ + bool fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD ); + if ( fRet ) + { +// WeaponSound( RELOAD ); + ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD ); + } + return fRet; +} void CWeaponHL2MPBase::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ ) { #ifdef CLIENT_DLL diff --git a/mp/src/game/shared/hl2mp/weapon_hl2mpbase.h b/mp/src/game/shared/hl2mp/weapon_hl2mpbase.h index 0f21044b1..c34166317 100644 --- a/mp/src/game/shared/hl2mp/weapon_hl2mpbase.h +++ b/mp/src/game/shared/hl2mp/weapon_hl2mpbase.h @@ -40,9 +40,6 @@ class CWeaponHL2MPBase : public CBaseCombatWeapon #ifdef GAME_DLL DECLARE_DATADESC(); - - void SendReloadSoundEvent( void ); - void Materialize( void ); virtual int ObjectCaps( void ); #endif @@ -60,6 +57,7 @@ class CWeaponHL2MPBase : public CBaseCombatWeapon virtual void FireBullets( const FireBulletsInfo_t &info ); virtual void FallInit( void ); + virtual bool Reload(); public: #if defined( CLIENT_DLL ) diff --git a/mp/src/game/shared/hl2mp/weapon_hl2mpbase_machinegun.cpp b/mp/src/game/shared/hl2mp/weapon_hl2mpbase_machinegun.cpp index b5a0040ef..04fbcb9db 100644 --- a/mp/src/game/shared/hl2mp/weapon_hl2mpbase_machinegun.cpp +++ b/mp/src/game/shared/hl2mp/weapon_hl2mpbase_machinegun.cpp @@ -114,7 +114,8 @@ void CHL2MPMachineGun::PrimaryAttack( void ) } SendWeaponAnim( GetPrimaryAttackActivity() ); - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + ToHL2MPPlayer(pPlayer)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + } //----------------------------------------------------------------------------- diff --git a/mp/src/game/shared/hl2mp/weapon_hl2mpbasebasebludgeon.cpp b/mp/src/game/shared/hl2mp/weapon_hl2mpbasebasebludgeon.cpp index 21373ca8d..a8698fbce 100644 --- a/mp/src/game/shared/hl2mp/weapon_hl2mpbasebasebludgeon.cpp +++ b/mp/src/game/shared/hl2mp/weapon_hl2mpbasebasebludgeon.cpp @@ -355,7 +355,7 @@ void CBaseHL2MPBludgeonWeapon::Swing( int bIsSecondary ) // Send the anim SendWeaponAnim( nHitActivity ); - pOwner->SetAnimation( PLAYER_ATTACK1 ); + ToHL2MPPlayer(pOwner)->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); //Setup our next attack times m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); diff --git a/mp/src/game/shared/hl2mp/weapon_physcannon.cpp b/mp/src/game/shared/hl2mp/weapon_physcannon.cpp index a5537a85a..a29133587 100644 --- a/mp/src/game/shared/hl2mp/weapon_physcannon.cpp +++ b/mp/src/game/shared/hl2mp/weapon_physcannon.cpp @@ -1251,10 +1251,7 @@ class CWeaponPhysCannon : public CBaseHL2MPCombatWeapon private: CWeaponPhysCannon( const CWeaponPhysCannon & ); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif }; IMPLEMENT_NETWORKCLASS_ALIASED( WeaponPhysCannon, DT_WeaponPhysCannon ) @@ -1291,23 +1288,24 @@ END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_physcannon, CWeaponPhysCannon ); PRECACHE_WEAPON_REGISTER( weapon_physcannon ); -#ifndef CLIENT_DLL - acttable_t CWeaponPhysCannon::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false }, -}; + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PHYSGUN, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PHYSGUN, false }, -IMPLEMENT_ACTTABLE(CWeaponPhysCannon); + { ACT_MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false }, -#endif + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PHYSGUN, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PHYSGUN, false }, + { ACT_MP_JUMP, ACT_HL2MP_JUMP_PHYSGUN, false }, +}; + +IMPLEMENT_ACTTABLE(CWeaponPhysCannon); enum { diff --git a/mp/src/game/shared/hl2mp/weapon_pistol.cpp b/mp/src/game/shared/hl2mp/weapon_pistol.cpp index 5a9533c43..83b251990 100644 --- a/mp/src/game/shared/hl2mp/weapon_pistol.cpp +++ b/mp/src/game/shared/hl2mp/weapon_pistol.cpp @@ -15,6 +15,7 @@ #endif #include "weapon_hl2mpbasehlmpcombatweapon.h" +#include "weapon_hl2mpbase_machinegun.h" #define PISTOL_FASTEST_REFIRE_TIME 0.1f #define PISTOL_FASTEST_DRY_REFIRE_TIME 0.2f @@ -30,10 +31,10 @@ // CWeaponPistol //----------------------------------------------------------------------------- -class CWeaponPistol : public CBaseHL2MPCombatWeapon +class CWeaponPistol : public CHL2MPMachineGun { public: - DECLARE_CLASS( CWeaponPistol, CBaseHL2MPCombatWeapon ); + DECLARE_CLASS( CWeaponPistol, CHL2MPMachineGun ); CWeaponPistol(void); @@ -84,10 +85,7 @@ class CWeaponPistol : public CBaseHL2MPCombatWeapon { return 0.5f; } - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif private: CNetworkVar( float, m_flSoonestPrimaryAttack ); @@ -127,23 +125,24 @@ END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_pistol, CWeaponPistol ); PRECACHE_WEAPON_REGISTER( weapon_pistol ); -#ifndef CLIENT_DLL acttable_t CWeaponPistol::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false }, -}; + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_PISTOL, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_PISTOL, false }, + { ACT_MP_RUN, ACT_HL2MP_RUN_PISTOL, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PISTOL, false }, -IMPLEMENT_ACTTABLE( CWeaponPistol ); + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, -#endif + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false }, +}; + +IMPLEMENT_ACTTABLE( CWeaponPistol ); //----------------------------------------------------------------------------- // Purpose: Constructor @@ -313,6 +312,7 @@ bool CWeaponPistol::Reload( void ) if ( fRet ) { WeaponSound( RELOAD ); + ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD ); m_flAccuracyPenalty = 0.0f; } return fRet; diff --git a/mp/src/game/shared/hl2mp/weapon_rpg.cpp b/mp/src/game/shared/hl2mp/weapon_rpg.cpp index 18785d861..1a0b3c239 100644 --- a/mp/src/game/shared/hl2mp/weapon_rpg.cpp +++ b/mp/src/game/shared/hl2mp/weapon_rpg.cpp @@ -1305,23 +1305,25 @@ END_PREDICTION_DATA() #endif -#ifndef CLIENT_DLL acttable_t CWeaponRPG::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_RPG, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_RPG, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_RPG, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_RPG, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_RPG, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_RPG, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_RPG, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_RPG, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_RPG, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_RPG, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_RPG, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_RPG, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_RPG, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_RPG, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_RPG, false }, }; IMPLEMENT_ACTTABLE(CWeaponRPG); -#endif - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -1424,7 +1426,7 @@ bool CWeaponRPG::WeaponShouldBeLowered( void ) void CWeaponRPG::PrimaryAttack( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if (!pPlayer) return; @@ -1479,7 +1481,8 @@ void CWeaponRPG::PrimaryAttack( void ) WeaponSound( SINGLE ); // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + } //----------------------------------------------------------------------------- @@ -2253,8 +2256,7 @@ int CLaserDot::DrawModel( int flags ) { // Take the eye position and direction vecAttachment = pOwner->EyePosition(); - - QAngle angles = pOwner->GetAnimEyeAngles(); + QAngle angles = pOwner->EyeAngles(); AngleVectors( angles, &vecDir ); } diff --git a/mp/src/game/shared/hl2mp/weapon_rpg.h b/mp/src/game/shared/hl2mp/weapon_rpg.h index 436433b50..af10575bc 100644 --- a/mp/src/game/shared/hl2mp/weapon_rpg.h +++ b/mp/src/game/shared/hl2mp/weapon_rpg.h @@ -245,9 +245,7 @@ class CWeaponRPG : public CBaseHL2MPCombatWeapon CBaseEntity *GetMissile( void ) { return m_hMissile; } -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif protected: diff --git a/mp/src/game/shared/hl2mp/weapon_shotgun.cpp b/mp/src/game/shared/hl2mp/weapon_shotgun.cpp index e5ff0f105..288816c79 100644 --- a/mp/src/game/shared/hl2mp/weapon_shotgun.cpp +++ b/mp/src/game/shared/hl2mp/weapon_shotgun.cpp @@ -61,9 +61,7 @@ class CWeaponShotgun : public CBaseHL2MPCombatWeapon void DryFire( void ); virtual float GetFireRate( void ) { return 0.7; }; -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif CWeaponShotgun(void); @@ -99,23 +97,25 @@ END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_shotgun, CWeaponShotgun ); PRECACHE_WEAPON_REGISTER(weapon_shotgun); -#ifndef CLIENT_DLL acttable_t CWeaponShotgun::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false }, }; IMPLEMENT_ACTTABLE(CWeaponShotgun); -#endif - //----------------------------------------------------------------------------- // Purpose: Override so only reload one shell at a time @@ -127,7 +127,7 @@ bool CWeaponShotgun::StartReload( void ) if ( m_bNeedPump ) return false; - CBaseCombatCharacter *pOwner = GetOwner(); + CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); if ( pOwner == NULL ) return false; @@ -146,6 +146,9 @@ bool CWeaponShotgun::StartReload( void ) SendWeaponAnim( ACT_SHOTGUN_RELOAD_START ); + //Tony; BUG BUG BUG!!! shotgun does one shell at a time!!! -- player model only has a single reload!!! so I'm just going to dispatch the singular for now. + pOwner->DoAnimationEvent( PLAYERANIMEVENT_RELOAD ); + // Make shotgun shell visible SetBodygroup(1,0); @@ -293,7 +296,7 @@ void CWeaponShotgun::DryFire( void ) void CWeaponShotgun::PrimaryAttack( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if (!pPlayer) { @@ -312,7 +315,8 @@ void CWeaponShotgun::PrimaryAttack( void ) m_iClip1 -= 1; // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); @@ -344,7 +348,7 @@ void CWeaponShotgun::PrimaryAttack( void ) void CWeaponShotgun::SecondaryAttack( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if (!pPlayer) { @@ -364,7 +368,8 @@ void CWeaponShotgun::SecondaryAttack( void ) m_iClip1 -= 2; // Shotgun uses same clip for primary and secondary attacks // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); //Tony; shotgun doesn't have a secondary anim, use primary. + Vector vecSrc = pPlayer->Weapon_ShootPosition(); Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); diff --git a/mp/src/game/shared/hl2mp/weapon_slam.cpp b/mp/src/game/shared/hl2mp/weapon_slam.cpp index 8cd94c8a4..30f566b9b 100644 --- a/mp/src/game/shared/hl2mp/weapon_slam.cpp +++ b/mp/src/game/shared/hl2mp/weapon_slam.cpp @@ -92,21 +92,26 @@ BEGIN_DATADESC( CWeapon_SLAM ) DEFINE_FUNCTION( SlamTouch ), END_DATADESC() +#endif acttable_t CWeapon_SLAM::m_acttable[] = { - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SLAM, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SLAM, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SLAM, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SLAM, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SLAM, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SLAM, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SLAM, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SLAM, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_SLAM, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SLAM, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SLAM, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SLAM, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SLAM, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_SLAM, false }, }; IMPLEMENT_ACTTABLE(CWeapon_SLAM); -#endif void CWeapon_SLAM::Spawn( ) @@ -395,7 +400,7 @@ void CWeapon_SLAM::TripmineAttach( void ) void CWeapon_SLAM::StartTripmineAttach( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if (!pPlayer) { return; @@ -422,7 +427,7 @@ void CWeapon_SLAM::StartTripmineAttach( void ) if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR)) { // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); // ----------------------------------------- // Play attach animation @@ -459,11 +464,12 @@ void CWeapon_SLAM::StartTripmineAttach( void ) //----------------------------------------------------------------------------- void CWeapon_SLAM::SatchelThrow( void ) { + // Only the player fires this way so we can cast + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); + #ifndef CLIENT_DLL m_bThrowSatchel = false; - // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); Vector vecSrc = pPlayer->WorldSpaceCenter(); Vector vecFacing = pPlayer->BodyDirection3D( ); @@ -495,10 +501,11 @@ void CWeapon_SLAM::SatchelThrow( void ) } pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType ); - pPlayer->SetAnimation( PLAYER_ATTACK1 ); - #endif + //Tony; is there a different anim in the player? must check.. + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + // Play throw sound EmitSound( "Weapon_SLAM.SatchelThrow" ); } @@ -589,7 +596,7 @@ void CWeapon_SLAM::SatchelAttach( void ) void CWeapon_SLAM::StartSatchelAttach( void ) { #ifndef CLIENT_DLL - CBaseCombatCharacter *pOwner = GetOwner(); + CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); if (!pOwner) { return; @@ -607,11 +614,8 @@ void CWeapon_SLAM::StartSatchelAttach( void ) CBaseEntity *pEntity = tr.m_pEnt; if (pEntity && !(pEntity->GetFlags() & FL_CONVEYOR)) { - // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( pOwner ); - // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pOwner->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); // ----------------------------------------- // Play attach animation diff --git a/mp/src/game/shared/hl2mp/weapon_slam.h b/mp/src/game/shared/hl2mp/weapon_slam.h index 0b59bed77..34b628c4e 100644 --- a/mp/src/game/shared/hl2mp/weapon_slam.h +++ b/mp/src/game/shared/hl2mp/weapon_slam.h @@ -78,8 +78,8 @@ class CWeapon_SLAM : public CBaseHL2MPCombatWeapon CWeapon_SLAM(); -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); +#ifndef CLIENT_DLL DECLARE_DATADESC(); #endif diff --git a/mp/src/game/shared/hl2mp/weapon_smg1.cpp b/mp/src/game/shared/hl2mp/weapon_smg1.cpp index bd6e1d429..ead647e2a 100644 --- a/mp/src/game/shared/hl2mp/weapon_smg1.cpp +++ b/mp/src/game/shared/hl2mp/weapon_smg1.cpp @@ -61,9 +61,7 @@ class CWeaponSMG1 : public CHL2MPMachineGun const WeaponProficiencyInfo_t *GetProficiencyValues(); -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif protected: @@ -85,21 +83,24 @@ END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_smg1, CWeaponSMG1 ); PRECACHE_WEAPON_REGISTER(weapon_smg1); -#ifndef CLIENT_DLL acttable_t CWeaponSMG1::m_acttable[] = { - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG1, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false }, - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_SMG1, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_SMG1, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_SMG1, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_SMG1, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_SMG1, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_SMG1, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_SMG1, false }, }; IMPLEMENT_ACTTABLE(CWeaponSMG1); -#endif //========================================================= CWeaponSMG1::CWeaponSMG1( ) @@ -164,6 +165,7 @@ bool CWeaponSMG1::Reload( void ) m_flNextSecondaryAttack = GetOwner()->m_flNextAttack = fCacheTime; WeaponSound( RELOAD ); + ToHL2MPPlayer(GetOwner())->DoAnimationEvent( PLAYERANIMEVENT_RELOAD ); } return fRet; @@ -193,7 +195,7 @@ void CWeaponSMG1::AddViewKick( void ) void CWeaponSMG1::SecondaryAttack( void ) { // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetOwner() ); if ( pPlayer == NULL ) return; @@ -234,7 +236,7 @@ void CWeaponSMG1::SecondaryAttack( void ) SendWeaponAnim( ACT_VM_SECONDARYATTACK ); // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); // Decrease ammo pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType ); diff --git a/mp/src/game/shared/hl2mp/weapon_stunstick.cpp b/mp/src/game/shared/hl2mp/weapon_stunstick.cpp index 70a852f68..8e96c9385 100644 --- a/mp/src/game/shared/hl2mp/weapon_stunstick.cpp +++ b/mp/src/game/shared/hl2mp/weapon_stunstick.cpp @@ -57,10 +57,7 @@ class CWeaponStunStick : public CBaseHL2MPBludgeonWeapon DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif #ifdef CLIENT_DLL virtual int DrawModel( int flags ); @@ -152,24 +149,25 @@ LINK_ENTITY_TO_CLASS( weapon_stunstick, CWeaponStunStick ); PRECACHE_WEAPON_REGISTER( weapon_stunstick ); -#ifndef CLIENT_DLL - acttable_t CWeaponStunStick::m_acttable[] = { - { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true }, - { ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false }, - { ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false }, - { ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, - { ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false }, - { ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, - { ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, - { ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, + { ACT_MP_STAND_IDLE, ACT_HL2MP_IDLE_MELEE, false }, + { ACT_MP_CROUCH_IDLE, ACT_HL2MP_IDLE_CROUCH_MELEE, false }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_MELEE, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_MELEE, false }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false }, + + { ACT_MP_RELOAD_STAND, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + { ACT_MP_RELOAD_CROUCH, ACT_HL2MP_GESTURE_RELOAD_MELEE, false }, + + { ACT_MP_JUMP, ACT_HL2MP_JUMP_MELEE, false }, }; IMPLEMENT_ACTTABLE(CWeaponStunStick); -#endif - //----------------------------------------------------------------------------- // Constructor diff --git a/mp/src/game/shared/neo/neo_player_shared.cpp b/mp/src/game/shared/neo/neo_player_shared.cpp index b2cbbf706..0e43d57b0 100644 --- a/mp/src/game/shared/neo/neo_player_shared.cpp +++ b/mp/src/game/shared/neo/neo_player_shared.cpp @@ -18,7 +18,6 @@ #include "neo_player.h" #endif -#include "neo_playeranimstate.h" #include "convar.h" #include "weapon_neobasecombatweapon.h" @@ -89,16 +88,6 @@ CBaseCombatWeapon* GetNeoWepWithBits(const CNEO_Player* player, const NEO_WEP_BI return NULL; } -bool PlayerAnimToPlayerAnimEvent(const PLAYER_ANIM playerAnim, PlayerAnimEvent_t& outAnimEvent) -{ - bool success = true; - if (playerAnim == PLAYER_ANIM::PLAYER_JUMP) { outAnimEvent = PlayerAnimEvent_t::PLAYERANIMEVENT_JUMP; } - else if (playerAnim == PLAYER_ANIM::PLAYER_RELOAD) { outAnimEvent = PlayerAnimEvent_t::PLAYERANIMEVENT_RELOAD; } - else if (playerAnim == PLAYER_ANIM::PLAYER_ATTACK1) { outAnimEvent = PlayerAnimEvent_t::PLAYERANIMEVENT_FIRE_GUN_PRIMARY; } - else { success = false; } - return success; -} - bool ClientWantsAimHold(const CNEO_Player* player) { #ifdef CLIENT_DLL diff --git a/mp/src/game/shared/neo/neo_player_shared.h b/mp/src/game/shared/neo/neo_player_shared.h index d0650c2dd..a2290e01e 100644 --- a/mp/src/game/shared/neo/neo_player_shared.h +++ b/mp/src/game/shared/neo/neo_player_shared.h @@ -200,7 +200,6 @@ enum NeoStar { class CNEO_Player; class CNEOBaseCombatWeapon; class C_BaseCombatWeapon; -enum PlayerAnimEvent_t : uint; extern bool IsThereRoomForLeanSlide(CNEO_Player *player, const Vector &targetViewOffset, bool &outStartInSolid); @@ -250,10 +249,6 @@ inline const char *GetRankName(int xp, bool shortened = false) CBaseCombatWeapon* GetNeoWepWithBits(const CNEO_Player* player, const NEO_WEP_BITS_UNDERLYING_TYPE& neoWepBits); -// Temporary helper for converting between these. Should refactor this to use the same structure for both. -// Returns true on success. If returns false, the out value will not be set. -bool PlayerAnimToPlayerAnimEvent(const PLAYER_ANIM playerAnim, PlayerAnimEvent_t& outAnimEvent); - enum NeoLeanDirectionE { NEO_LEAN_NONE = 0, NEO_LEAN_LEFT, diff --git a/mp/src/game/shared/neo/neo_playeranimstate.cpp b/mp/src/game/shared/neo/neo_playeranimstate.cpp deleted file mode 100644 index 0164da34b..000000000 --- a/mp/src/game/shared/neo/neo_playeranimstate.cpp +++ /dev/null @@ -1,970 +0,0 @@ -#include "cbase.h" -#include "base_playeranimstate.h" -#include "weapon_grenade.h" -#include "weapon_smokegrenade.h" -#include "weapon_detpack.h" - -#include "tier0/vprof.h" -#include "animation.h" -#include "studio.h" -#include "apparent_velocity_helper.h" -#include "utldict.h" - -#include "neo_playeranimstate.h" - -#include "weapon_neobasecombatweapon.h" - -#ifdef CLIENT_DLL -#include "c_neo_player.h" -#include "bone_setup.h" -#include "interpolatedvar.h" -#else -#include "neo_player.h" -#endif - -#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_" - -// ------------------------------------------------------------------------- // -// CSDKPlayerAnimState declaration. -// ------------------------------------------------------------------------- // -class CNEOPlayerAnimState : public CBasePlayerAnimState, public INEOPlayerAnimState -{ -public: - DECLARE_CLASS(CNEOPlayerAnimState, CBasePlayerAnimState); - friend INEOPlayerAnimState *CreatePlayerAnimState(CBaseAnimatingOverlay *pEntity, - INEOPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences); - - CNEOPlayerAnimState(); - ~CNEOPlayerAnimState(); - - virtual void DoAnimationEvent(PlayerAnimEvent_t event, int nData); - virtual bool IsThrowingGrenade(); - virtual int CalcAimLayerSequence(float *flCycle, float *flAimSequenceWeight, bool bForceIdle); - virtual void ClearAnimationState(); - virtual void ClearAnimationFlags(); - virtual void UpdateAnimationFlags(); - virtual void UpdateGrenadeAnimationFlags(CWeaponGrenade* grenadeWeapon); - virtual void UpdateSmokeGrenadeAnimationFlags(CWeaponSmokeGrenade* grenadeWeapon); - virtual void UpdateDetpackAnimationFlags(CWeaponDetpack* detpackWeapon); - virtual void UpdateBaseWeaponAnimationFlags(CBaseCombatWeapon* currentWeapon); - virtual bool CanThePlayerMove(); - virtual float GetCurrentMaxGroundSpeed(); - virtual Activity CalcMainActivity(); - virtual void DebugShowAnimState(int iStartLine); - virtual void ComputeSequences(CStudioHdr *pStudioHdr); - virtual void ClearAnimationLayers(); - - void InitNEO(CBaseAnimatingOverlay *pPlayer, INEOPlayerAnimStateHelpers *pHelpers, - LegAnimType_t legAnimType, bool bUseAimSequences); - - // If this returns true, then it will blend the current aim layer sequence with an idle aim layer - // sequence based on how fast the character is moving, so it doesn't play the upper-body run at - // full speed if he's moving really slowly. - // - // We return false on this for animations that don't have blends. - virtual bool ShouldBlendAimSequenceToIdle() OVERRIDE; - - virtual bool ShouldBlendReloadSequenceToIdle(); - -protected: - virtual void ComputeAimSequence() OVERRIDE; - - virtual bool ShouldResetMainSequence(int iCurrentSequence, int iNewSequence) OVERRIDE; - - 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(); - - void ComputeDetpackSequence(CStudioHdr* pStudioHdr); - - const char* GetWeaponSuffix(); - bool IsAirborne(); - - void UpdateLayerSequenceGeneric(CStudioHdr *pStudioHdr, int iLayer, bool &bEnabled, - float &flCurCycle, int &iSequence, bool bWaitAtEnd); - -private: - void UpdateReloadSequenceLayers(float flCycle, int iFirstLayer, bool bForceIdle, - CSequenceTransitioner* pTransitioner, float flWeightScale); - -private: - // Aim sequence plays reload while this is on. - bool m_bReloading; - float m_flReloadCycle; - int m_iReloadSequence; - - bool m_bFreshJump; - - // 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. - - // Detpack Animations - bool m_bThrowingDetpack; - bool m_bTriggeringDetpack; - float m_flDetpackCycle; - int m_iDetpackSequence; - - INEOPlayerAnimStateHelpers *m_pHelpers; - - CSequenceTransitioner m_ReloadSequenceTransitioner; -}; - -INEOPlayerAnimState *CreatePlayerAnimState(CBaseAnimatingOverlay *pEntity, - INEOPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences) -{ - CNEOPlayerAnimState *pRet = new CNEOPlayerAnimState; - pRet->InitNEO(pEntity, pHelpers, legAnimType, bUseAimSequences); - Assert(pRet); - return pRet; -} - -class CNEOPlayerAnimStateHelpers : public INEOPlayerAnimStateHelpers -{ -public: - CNEOPlayerAnimStateHelpers(CNEO_Player* player) : m_pPlayer(player) - { - Assert(m_pPlayer); - } - - virtual CBaseCombatWeapon* NEOAnim_GetActiveWeapon() - { - return m_pPlayer->GetActiveWeapon(); - } - - virtual bool NEOAnim_CanMove() - { - if ((m_pPlayer->GetNeoFlags() & FL_FROZEN) || (m_pPlayer->GetFlags() & FL_FROZEN)) - { - return false; - } - return true; - } - -private: - CNEO_Player* m_pPlayer; -}; - -INEOPlayerAnimStateHelpers* CreateAnimStateHelpers(CNEO_Player* pPlayer) -{ - CNEOPlayerAnimStateHelpers* pRet = new CNEOPlayerAnimStateHelpers(pPlayer); - Assert(pRet); - return pRet; -} - -// ------------------------------------------------------------------------- // -// CNEOPlayerAnimState implementation. -// ------------------------------------------------------------------------- // -CNEOPlayerAnimState::CNEOPlayerAnimState() -{ - // Base weapon reloading - m_bReloading = false; - m_flReloadCycle = 0; - m_iReloadSequence = 0; - - m_bFreshJump = false; - - // Base weapon firing - m_bFiring = false; - m_iFireSequence = 0; - m_flFireCycle = 0; - - // Grenade prime and firing - m_bPrimingGrenade = false; - m_bThrowingGrenade = false; - m_flGrenadeCycle = 0; - m_iGrenadeSequence = 0; - m_iLastThrowGrenadeCounter = 0; - - // Detpack throwing and triggering - m_bThrowingDetpack = false; - m_bTriggeringDetpack = false; - m_flDetpackCycle = 0; - m_iDetpackSequence = 0; - - m_pHelpers = NULL; -} - -CNEOPlayerAnimState::~CNEOPlayerAnimState() -{ - delete m_pHelpers; -} - -void CNEOPlayerAnimState::InitNEO(CBaseAnimatingOverlay *pPlayer, - INEOPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences) -{ - CModAnimConfig config; - config.m_flMaxBodyYawDegrees = NEO_ANIMSTATE_MAX_BODY_YAW_DEGREES; - config.m_LegAnimType = legAnimType; - config.m_bUseAimSequences = bUseAimSequences; - - m_pHelpers = pHelpers; - - BaseClass::Init(pPlayer, config); -} - -void CNEOPlayerAnimState::ClearAnimationState() -{ - ClearAnimationFlags(); - BaseClass::ClearAnimationState(); -} - -void CNEOPlayerAnimState::ClearAnimationFlags() -{ - m_bFiring = false; - m_bReloading = false; - - m_bPrimingGrenade = m_bThrowingGrenade = false; - m_bThrowingDetpack = m_bTriggeringDetpack = false; - m_iLastThrowGrenadeCounter = GetOuterGrenadeThrowCounter(); -} - - -void CNEOPlayerAnimState::UpdateAnimationFlags() -{ - CWeaponGrenade* grenadeWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); - if (grenadeWeapon != nullptr) - { // Current weapon is a grenade - UpdateGrenadeAnimationFlags(grenadeWeapon); - return; - } - - CWeaponSmokeGrenade* smokeGrenadeWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); - if (smokeGrenadeWeapon != nullptr) - { // Current weapon is a smoke grenade - UpdateSmokeGrenadeAnimationFlags(smokeGrenadeWeapon); - return; - } - - CWeaponDetpack* detpackWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); - if (detpackWeapon != nullptr) - { // Current weapon is a detpack - UpdateDetpackAnimationFlags(detpackWeapon); - return; - } - - CBaseCombatWeapon* currentWeapon = dynamic_cast(m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()); - if (currentWeapon != nullptr) - { // Current weapon is a firearm/melee weapon - UpdateBaseWeaponAnimationFlags(currentWeapon); - return; - } - // Character hands are empty? - ClearAnimationFlags(); - return; -} - -void CNEOPlayerAnimState::UpdateGrenadeAnimationFlags(CWeaponGrenade* grenadeWeapon) -{ - m_bFiring = false; - m_bReloading = false; - m_bThrowingGrenade = false; - - if (!m_bThrowingGrenade && m_flGrenadeCycle < 1) - { // Grenade was recently thrown, continue playing throw animation - return; - } - - if (m_bPrimingGrenade && !grenadeWeapon->IsPrimed()) - { // Play throw sequence if grenade was primed but now isn't, grenade was thrown (unless user switched to a different grenade after priming a grenade, need to keep track of grenade names? NEO FIXME) - m_bPrimingGrenade = false; - m_bThrowingGrenade = true; - m_iGrenadeSequence = CalcGrenadePrimeSequence(); // This should be ThrowSequence but ThrowSequence returns 0 NEO FIXME - m_flGrenadeCycle = 0; - return; - } - - if (m_bPrimingGrenade && grenadeWeapon->IsPrimed()) - {// Still priming grenade - return; - } - - m_bPrimingGrenade = grenadeWeapon->IsPrimed(); - if (m_bPrimingGrenade) - { // Begin prime sequence - //m_iGrenadeSequence = CalcGrenadePrimeSequence(); // Can add a grenade priming animation here, there is no such animation in the orignal game NEO TODO - m_flGrenadeCycle = 0; - return; - } -} - -void CNEOPlayerAnimState::UpdateSmokeGrenadeAnimationFlags(CWeaponSmokeGrenade* grenadeWeapon) -{ - m_bFiring = false; - m_bReloading = false; - m_bThrowingGrenade = false; - - if (!m_bThrowingGrenade && m_flGrenadeCycle < 1) - { // Grenade was recently thrown, continue playing throw animation - return; - } - - if (m_bPrimingGrenade && !grenadeWeapon->IsPrimed()) - { // Play throw sequence if grenade was primed but now isn't, grenade was thrown (unless user switched to a different grenade after priming a grenade, need to keep track of grenade names? NEO FIXME) - m_bPrimingGrenade = false; - m_bThrowingGrenade = true; - m_iGrenadeSequence = CalcGrenadePrimeSequence(); // This should be ThrowSequence but ThrowSequence returns 0 NEO FIXME - m_flGrenadeCycle = 0; - return; - } - - if (m_bPrimingGrenade && grenadeWeapon->IsPrimed()) - {// Still priming grenade - return; - } - - m_bPrimingGrenade = grenadeWeapon->IsPrimed(); - if (m_bPrimingGrenade) - { // Begin prime sequence - //m_iGrenadeSequence = CalcGrenadePrimeSequence(); // Can add a grenade priming animation here, there is no such animation in the orignal game NEO TODO - m_flGrenadeCycle = 0; - return; - } -} - -void CNEOPlayerAnimState::UpdateDetpackAnimationFlags(CWeaponDetpack* detpackWeapon) -{ - if (detpackWeapon->m_bRemoteHasBeenTriggered) - { // detpack triggering - if (!m_bTriggeringDetpack) - { - m_flDetpackCycle = 0; - m_iDetpackSequence = CalcSequenceIndex("Idle_Shoot_detremote"); - m_bTriggeringDetpack = true; - } - m_bThrowingDetpack = false; - return; - } - - if (detpackWeapon->m_bWantsToThrowThisDetpack && !detpackWeapon->m_fDrawbackFinished) - { // detpack throwing - if (!m_bThrowingDetpack) - { // first tick - m_flDetpackCycle = 0; - m_iDetpackSequence = CalcSequenceIndex("Idle_Shoot_detpack"); - m_bThrowingDetpack = true; - } - m_bTriggeringDetpack = false; - return; - } -} - -void CNEOPlayerAnimState::UpdateBaseWeaponAnimationFlags(CBaseCombatWeapon* currentWeapon) -{ - m_bFiring = !((gpGlobals->curtime - currentWeapon->m_flNextPrimaryAttack.Get()) > 0.5f); - m_bReloading = currentWeapon->m_bInReload.Get(); -} - -void CNEOPlayerAnimState::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 > 0); - } - else if (event == PLAYERANIMEVENT_JUMP) - { - m_bFreshJump = true; - } - else if (event == PLAYERANIMEVENT_RELOAD) - { - m_iReloadSequence = CalcReloadLayerSequence(); - if (m_iReloadSequence > 0) - { - m_bReloading = true; - m_flReloadCycle = 0; - } - } - else - { - Assert(!"CNEOPlayerAnimState::DoAnimationEvent"); - } -} - -float g_flThrowGrenadeFraction = 0.25; -bool CNEOPlayerAnimState::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 CNEOPlayerAnimState::CalcReloadLayerSequence() -{ - const char *pSuffix = GetWeaponSuffix(); - if (!pSuffix) - { - return 0; - } - - auto pWeapon = m_pHelpers->NEOAnim_GetActiveWeapon(); - if (!pWeapon) - { - return 0; - } - - // First, look for Reload_. - char szName[512]; - Q_snprintf(szName, sizeof(szName), "Reload_%s", pSuffix); - - int iReloadSequence = CalcSequenceIndex(szName);// m_pOuter->LookupSequence(szName); - Assert(iReloadSequence > 0); - if (iReloadSequence > 0) - { - return iReloadSequence; - } - - // Fall back to Reload_M4. - iReloadSequence = CalcSequenceIndex("Reload_M4"); - Assert(iReloadSequence > 0); - return iReloadSequence; -} - -void CNEOPlayerAnimState::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; - return; - } - else - { - // Not firing anymore. - bEnabled = false; - iSequence = 0; - return; - } - } - - // Now dump the state into its animation layer. - CAnimationLayer *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; -} - -// We don't have a concept of cooking grenades, so checking for the actual moment of tossing it. -bool CNEOPlayerAnimState::IsOuterGrenadePrimed() -{ - auto player = static_cast(m_pOuter->MyCombatCharacterPointer()); - if (player) - { - auto vm = player->GetViewModel(); - if (vm) - { - return (vm->GetSequenceActivity(vm->GetSequence()) == ACT_VM_THROW); - } - } - return false; -} - -void CNEOPlayerAnimState::ComputeGrenadeSequence(CStudioHdr *pStudioHdr) -{ - if (m_bThrowingGrenade) - { - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bThrowingGrenade, - m_flGrenadeCycle, m_iGrenadeSequence, false); - } - if (m_bPrimingGrenade) - { - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bPrimingGrenade, - m_flGrenadeCycle, m_iGrenadeSequence, true); - } - bool grenadeBeingThrown = m_flGrenadeCycle < 1; - if (!m_bThrowingGrenade && grenadeBeingThrown) - { - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, grenadeBeingThrown, - m_flGrenadeCycle, m_iGrenadeSequence, false); - } -} - -void CNEOPlayerAnimState::ComputeDetpackSequence(CStudioHdr* pStudioHdr) -{ - if (m_bThrowingDetpack) - { - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bThrowingDetpack, - m_flDetpackCycle, m_iDetpackSequence, false); - } - if (m_bTriggeringDetpack) - { - UpdateLayerSequenceGeneric(pStudioHdr, GRENADESEQUENCE_LAYER, m_bTriggeringDetpack, - m_flDetpackCycle, m_iDetpackSequence, false); - } -} - -int CNEOPlayerAnimState::CalcGrenadePrimeSequence() -{ - return CalcSequenceIndex("Idle_Shoot_Gren1"); -} - -int CNEOPlayerAnimState::CalcGrenadeThrowSequence() -{ - // We don't have a prime sequence, so we throw on the prime; - // don't need to return anything here. - return 0; -} - -int CNEOPlayerAnimState::GetOuterGrenadeThrowCounter() -{ - CNEO_Player *pPlayer = dynamic_cast(m_pOuter); - if (!pPlayer) - { - return 0; - } - - return 0; - //return pPlayer->m_iThrowGrenadeCounter; // NEO FIXME (Rain): unimplemented -} - -void CNEOPlayerAnimState::ComputeReloadSequence(CStudioHdr *pStudioHdr) -{ - UpdateLayerSequenceGeneric(pStudioHdr, RELOADSEQUENCE_LAYER, m_bReloading, - m_flReloadCycle, m_iReloadSequence, false); -} - -int CNEOPlayerAnimState::CalcAimLayerSequence(float *flCycle, - float *flAimSequenceWeight, bool bForceIdle) -{ - const char* pSuffix = GetWeaponSuffix(); - if (!pSuffix) - { - return 0; - } - - if (bForceIdle) - { - switch (GetCurrentMainSequenceActivity()) - { - case ACT_NEO_IDLE_CROUCH: - return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix); - - default: - return CalcSequenceIndex("%s%s", DEFAULT_IDLE_NAME, pSuffix); - } - } - else - { - switch (GetCurrentMainSequenceActivity()) - { - case ACT_NEO_MOVE_RUN: - return CalcSequenceIndex("%s%s", DEFAULT_RUN_NAME, pSuffix); - - case ACT_RUNTOIDLE: - Assert(false); - case ACT_IDLETORUN: - Assert(false); - case ACT_NEO_MOVE_WALK: - return CalcSequenceIndex("%s%s", DEFAULT_WALK_NAME, pSuffix); - - case ACT_NEO_IDLE_CROUCH: - return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_IDLE_NAME, pSuffix); - - case ACT_NEO_MOVE_CROUCH: - return CalcSequenceIndex("%s%s", DEFAULT_CROUCH_WALK_NAME, pSuffix); - - case ACT_NEO_IDLE_STAND: - default: - return CalcSequenceIndex("%s%s", DEFAULT_IDLE_NAME, pSuffix); - } - } -} - -// NEO TODO/FIXME (Rain): suffix/prefix confusion on naming. -// I *think* this is talking about the same value as the -// WeaponData.anim_prefix in weapon scripts. -// -// If that is not the case, we might have to implement -// GetWpnData.m_szAnimExtension on Neo base wep. -const char *CNEOPlayerAnimState::GetWeaponSuffix() -{ - // Figure out the weapon suffix. - auto pWeapon = m_pHelpers->NEOAnim_GetActiveWeapon(); - if (!pWeapon) - { - return "Pistol"; - } - - const char *pSuffix = pWeapon->GetWpnData().szAnimationPrefix; - - return pSuffix; -} - -int CNEOPlayerAnimState::CalcFireLayerSequence(PlayerAnimEvent_t event) -{ - // Figure out the weapon suffix. - auto pWeapon = m_pHelpers->NEOAnim_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"; - } - - // NEO TODO (Rain): cleanup once done with debug - int res; - - switch (GetCurrentMainSequenceActivity()) - { - case ACT_PLAYER_RUN_FIRE: - Assert(false); - case ACT_NEO_MOVE_RUN: - res = CalcSequenceIndex("%s%s", DEFAULT_FIRE_RUN_NAME, pSuffix); - break; - - case ACT_PLAYER_WALK_FIRE: - Assert(false); - case ACT_NEO_MOVE_WALK: - res = CalcSequenceIndex("%s%s", DEFAULT_FIRE_WALK_NAME, pSuffix); - break; - - case ACT_PLAYER_CROUCH_FIRE: - Assert(false); - case ACT_NEO_IDLE_CROUCH: - res = CalcSequenceIndex("%s%s", DEFAULT_FIRE_CROUCH_NAME, pSuffix); - break; - - case ACT_PLAYER_CROUCH_WALK_FIRE: - Assert(false); - case ACT_NEO_MOVE_CROUCH: - res = CalcSequenceIndex("%s%s", DEFAULT_FIRE_CROUCH_WALK_NAME, pSuffix); - break; - - default: - case ACT_PLAYER_IDLE_FIRE: - res = CalcSequenceIndex("%s%s", DEFAULT_FIRE_IDLE_NAME, pSuffix); - break; - } - - //DevMsg("Res: %d\n", res); - - return res; -} - -bool CNEOPlayerAnimState::CanThePlayerMove() -{ - return m_pHelpers->NEOAnim_CanMove(); -} - -float CNEOPlayerAnimState::GetCurrentMaxGroundSpeed() -{ - const Activity currentActivity = m_pOuter->GetSequenceActivity(m_pOuter->GetSequence()); - - Assert(dynamic_cast(m_pOuter)); - - if (currentActivity == ACT_NEO_MOVE_WALK || currentActivity == ACT_NEO_IDLE_STAND) - { - return static_cast(m_pOuter)->GetWalkSpeed_WithActiveWepEncumberment(); - } - else if (currentActivity == ACT_NEO_MOVE_RUN) - { - return static_cast(m_pOuter)->GetNormSpeed_WithActiveWepEncumberment(); - } - else if (currentActivity == ACT_SPRINT) - { - Assert(false); - return static_cast(m_pOuter)->GetSprintSpeed_WithActiveWepEncumberment(); - } - else if (currentActivity == ACT_NEO_MOVE_CROUCH) - { - return static_cast(m_pOuter)->GetCrouchSpeed_WithActiveWepEncumberment(); - } - else - { - return static_cast(m_pOuter)->GetNormSpeed(); - } -} - -bool CNEOPlayerAnimState::IsAirborne() -{ - Assert(m_pOuter); - Assert(m_pOuter->MyCombatCharacterPointer()); - return static_cast(m_pOuter->MyCombatCharacterPointer())->IsAirborne(); -} - -Activity CNEOPlayerAnimState::CalcMainActivity() -{ - if (IsAirborne()) - { - return ACT_NEO_JUMP; - } - - Activity idealActivity = ACT_NEO_IDLE_STAND; - - const float flOuterSpeed = GetOuterXYSpeed(); - - if (m_pOuter->GetFlags() & FL_DUCKING) - { - if (flOuterSpeed > MOVING_MINIMUM_SPEED) - { - idealActivity = ACT_NEO_MOVE_CROUCH; - } - else - { - idealActivity = ACT_NEO_IDLE_CROUCH; - } - } - else - { - Assert(dynamic_cast(m_pOuter)); - - if (flOuterSpeed > MOVING_MINIMUM_SPEED) - { - if (flOuterSpeed > static_cast(m_pOuter)->GetNormSpeed_WithActiveWepEncumberment()) - { - idealActivity = ACT_NEO_MOVE_RUN; - } - else if (flOuterSpeed > static_cast(m_pOuter)->GetWalkSpeed_WithActiveWepEncumberment()) - { - idealActivity = ACT_NEO_MOVE_RUN; - } - else - { - idealActivity = ACT_NEO_MOVE_WALK; - } - } - else - { - idealActivity = ACT_NEO_IDLE_STAND; - } - } - - return idealActivity; -} - -void CNEOPlayerAnimState::DebugShowAnimState(int iStartLine) -{ - 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); -} - -void CNEOPlayerAnimState::ComputeSequences(CStudioHdr *pStudioHdr) -{ - BaseClass::ComputeSequences(pStudioHdr); - UpdateAnimationFlags(); - - ComputeFireSequence(pStudioHdr); - ComputeReloadSequence(pStudioHdr); - ComputeGrenadeSequence(pStudioHdr); - ComputeDetpackSequence(pStudioHdr); -} - -void CNEOPlayerAnimState::ClearAnimationLayers() -{ - VPROF("CNEOPlayerAnimState::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); -#ifndef CLIENT_DLL - m_pOuter->GetAnimOverlay(i)->m_fFlags = 0; -#endif - } -} - -void CNEOPlayerAnimState::ComputeFireSequence(CStudioHdr *pStudioHdr) -{ - UpdateLayerSequenceGeneric(pStudioHdr, FIRESEQUENCE_LAYER, m_bFiring, - m_flFireCycle, m_iFireSequence, false); -} - -bool CNEOPlayerAnimState::ShouldBlendAimSequenceToIdle() -{ - const Activity act = GetCurrentMainSequenceActivity(); - return (act == ACT_NEO_MOVE_RUN || act == ACT_NEO_MOVE_WALK || act == ACT_NEO_MOVE_CROUCH || act == ACT_NEO_RELOAD); -} - -bool CNEOPlayerAnimState::ShouldBlendReloadSequenceToIdle() -{ - Assert(!m_pOuter || m_pOuter->MyCombatCharacterPointer()); - if (!m_pOuter || !m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()) - { -#ifdef DEBUG - DevWarning("Early return from ShouldBlendReloadSequenceToIdle\n"); -#endif - m_bReloading = false; - return false; - } - - if (m_bReloading) - { - m_bReloading = m_pOuter->MyCombatCharacterPointer()->GetActiveWeapon()->m_bInReload; - } - - return (m_bReloading && ((m_pOuter)->GetFlags() & FL_DUCKING)); -} - -void CNEOPlayerAnimState::ComputeAimSequence() -{ - if (ShouldBlendReloadSequenceToIdle()) - { - const float cycle = (m_pOuter->GetFlags() & FL_DUCKING) ? -#ifdef CLIENT_DLL - m_pOuter->GetAnimOverlay(RELOADSEQUENCE_LAYER)->m_flCycle.GetRaw() : m_pOuter->GetCycle(); -#else - m_pOuter->GetAnimOverlay(RELOADSEQUENCE_LAYER)->m_flCycle.Get() : m_pOuter->GetCycle(); -#endif - UpdateReloadSequenceLayers(cycle, RELOADSEQUENCE_LAYER, true, &m_ReloadSequenceTransitioner, 1.0f); - } - BaseClass::ComputeAimSequence(); -} - -void CNEOPlayerAnimState::UpdateReloadSequenceLayers(float flCycle, int iFirstLayer, - bool bForceIdle, CSequenceTransitioner* pTransitioner, float flWeightScale) -{ - float flReloadSequenceWeight = 1; - int iReloadSequence = CalcReloadLayerSequence(); - if (iReloadSequence == -1) - iReloadSequence = 0; - - // Feed the current state of the animation parameters to the sequence transitioner. - // It will hand back either 1 or 2 animations in the queue to set, depending on whether - // it's transitioning or not. We just dump those into the animation layers. - pTransitioner->CheckForSequenceChange( - m_pOuter->GetModelPtr(), - iReloadSequence, - true, // force transitions on the same anim - true // yes, interpolate when transitioning - ); - - pTransitioner->UpdateCurrent( - m_pOuter->GetModelPtr(), - iReloadSequence, - flCycle, - GetOuter()->GetPlaybackRate(), - gpGlobals->curtime - ); - - CAnimationLayer* pDest0 = m_pOuter->GetAnimOverlay(iFirstLayer); - CAnimationLayer* pDest1 = m_pOuter->GetAnimOverlay(iFirstLayer + 1); - - if (pTransitioner->m_animationQueue.Count() == 1) - { - // If only 1 animation, then blend it in fully. - CAnimationLayer* pSource0 = &pTransitioner->m_animationQueue[0]; - *pDest0 = *pSource0; - - pDest0->m_flWeight = 1; - pDest1->m_flWeight = 0; - pDest0->m_nOrder = iFirstLayer; - -#ifndef CLIENT_DLL - pDest0->m_fFlags |= ANIM_LAYER_ACTIVE; -#endif - } - else if (pTransitioner->m_animationQueue.Count() >= 2) - { - // The first one should be fading out. Fade in the new one inversely. - CAnimationLayer* pSource0 = &pTransitioner->m_animationQueue[0]; - CAnimationLayer* pSource1 = &pTransitioner->m_animationQueue[1]; - - *pDest0 = *pSource0; - *pDest1 = *pSource1; - Assert(pDest0->m_flWeight >= 0.0f && pDest0->m_flWeight <= 1.0f); - pDest1->m_flWeight = 1 - pDest0->m_flWeight; // This layer just mirrors the other layer's weight (one fades in while the other fades out). - - pDest0->m_nOrder = iFirstLayer; - pDest1->m_nOrder = iFirstLayer + 1; - -#ifndef CLIENT_DLL - pDest0->m_fFlags |= ANIM_LAYER_ACTIVE; - pDest1->m_fFlags |= ANIM_LAYER_ACTIVE; -#endif - } - - pDest0->m_flWeight *= flWeightScale * flReloadSequenceWeight; - pDest0->m_flWeight = clamp((float)pDest0->m_flWeight, 0.0f, 1.0f); - - pDest1->m_flWeight *= flWeightScale * flReloadSequenceWeight; - pDest1->m_flWeight = clamp((float)pDest1->m_flWeight, 0.0f, 1.0f); - - pDest0->m_flCycle = pDest1->m_flCycle = flCycle; -} - -bool CNEOPlayerAnimState::ShouldResetMainSequence(int iCurrentSequence, int iNewSequence) -{ - if (IsAirborne()) - { - if (!m_bFreshJump) - { - // Only reset active mid-air jump sequence if we're transitioning away from that animation - return iNewSequence != SelectWeightedSequence(TranslateActivity(ACT_NEO_JUMP)); - } - m_bFreshJump = false; - } - - return BaseClass::ShouldResetMainSequence(iCurrentSequence, iNewSequence); -} \ No newline at end of file diff --git a/mp/src/game/shared/neo/neo_playeranimstate.h b/mp/src/game/shared/neo/neo_playeranimstate.h deleted file mode 100644 index c985e109e..000000000 --- a/mp/src/game/shared/neo/neo_playeranimstate.h +++ /dev/null @@ -1,64 +0,0 @@ -// This animstate code is based off the SDK (CS:S) sdk_playeranimstate code. - -#ifndef NEO_PLAYERANIMSTATE_H -#define NEO_PLAYERANIMSTATE_H -#ifdef _WIN32 -#pragma once -#endif - -#include "convar.h" -#include "iplayeranimstate.h" -#include "base_playeranimstate.h" - -#define FIRESEQUENCE_LAYER (AIMSEQUENCE_LAYER+NUM_AIMSEQUENCE_LAYERS) -#define RELOADSEQUENCE_LAYER (FIRESEQUENCE_LAYER + 1) -#define GRENADESEQUENCE_LAYER (RELOADSEQUENCE_LAYER + 1) -#define NUM_LAYERS_WANTED 15//(GRENADESEQUENCE_LAYER + 1) - -class CBaseAnimatingOverlay; -class CBaseCombatWeapon; -class CNEO_Player; - -enum PlayerAnimEvent_t : uint -{ - PLAYERANIMEVENT_FIRE_GUN_PRIMARY = 0, - PLAYERANIMEVENT_FIRE_GUN_SECONDARY, - PLAYERANIMEVENT_THROW_GRENADE, - PLAYERANIMEVENT_JUMP, - PLAYERANIMEVENT_RELOAD, - - PLAYERANIMEVENT_COUNT -}; - -class INEOPlayerAnimState : virtual public IPlayerAnimState -{ -public: - // 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 = 0) = 0; - - // Returns true if we're playing the grenade prime or throw animation. - virtual bool IsThrowingGrenade() = 0; -}; - -// This abstracts the differences between SDK players and hostages. -// NEO TODO (Rain): porting this over from the SDK code for now, -// in case it becomes useful for VIPs or something. Should be cleaned up later. -class INEOPlayerAnimStateHelpers -{ -public: - virtual CBaseCombatWeapon* NEOAnim_GetActiveWeapon() = 0; - virtual bool NEOAnim_CanMove() = 0; - virtual ~INEOPlayerAnimStateHelpers() {} -}; - -INEOPlayerAnimState *CreatePlayerAnimState(CBaseAnimatingOverlay *pEntity, - INEOPlayerAnimStateHelpers *pHelpers, LegAnimType_t legAnimType, bool bUseAimSequences); - -INEOPlayerAnimStateHelpers* CreateAnimStateHelpers(CNEO_Player* pPlayer); - -// 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 // NEO_PLAYERANIMSTATE_H diff --git a/mp/src/game/shared/neo/weapons/weapon_aa13.cpp b/mp/src/game/shared/neo/weapons/weapon_aa13.cpp index 979164806..3264e902a 100644 --- a/mp/src/game/shared/neo/weapons/weapon_aa13.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_aa13.cpp @@ -79,7 +79,7 @@ void CWeaponAA13::PrimaryAttack(void) } // Only the player fires this way so we can cast - CBasePlayer *pPlayer = ToBasePlayer(GetOwner()); + auto* pPlayer = static_cast(GetOwner()); if (!pPlayer) { @@ -96,7 +96,7 @@ void CWeaponAA13::PrimaryAttack(void) m_iClip1 -= 1; // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); Vector vecSrc = pPlayer->Weapon_ShootPosition(); Vector vecAiming = pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES); diff --git a/mp/src/game/shared/neo/weapons/weapon_detpack.cpp b/mp/src/game/shared/neo/weapons/weapon_detpack.cpp index efa81bf80..566d68d10 100644 --- a/mp/src/game/shared/neo/weapons/weapon_detpack.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_detpack.cpp @@ -133,7 +133,8 @@ void CWeaponDetpack::PrimaryAttack(void) return; } - if (!GetOwner()) + auto* pPlayer = static_cast(GetOwner()); + if (!pPlayer) { Assert(false); return; @@ -150,6 +151,7 @@ void CWeaponDetpack::PrimaryAttack(void) DevMsg("Pulling remote trigger\n"); #endif SendWeaponAnim(ACT_VM_PRIMARYATTACK_DEPLOYED); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_flNextPrimaryAttack = gpGlobals->curtime + (SequenceDuration() / 3); m_flTimeWeaponIdle = FLT_MAX; } @@ -186,7 +188,7 @@ void CWeaponDetpack::ItemPostFrame(void) if (m_fDrawbackFinished) { - auto pOwner = GetOwner(); + auto pOwner = static_cast(GetOwner()); if ((m_bRemoteHasBeenTriggered) && (gpGlobals->curtime > m_flNextPrimaryAttack)) { @@ -224,6 +226,7 @@ void CWeaponDetpack::ItemPostFrame(void) { TossDetpack(ToBasePlayer(pOwner)); m_bThisDetpackHasBeenThrown = true; + pOwner->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); // SendWeaponAnim(ACT_VM_DRAW_DEPLOYED); // SendWeaponAnim(ACT_VM_THROW); m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); diff --git a/mp/src/game/shared/neo/weapons/weapon_grenade.cpp b/mp/src/game/shared/neo/weapons/weapon_grenade.cpp index 5283aa3aa..2dcb98370 100644 --- a/mp/src/game/shared/neo/weapons/weapon_grenade.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_grenade.cpp @@ -221,7 +221,7 @@ void CWeaponGrenade::ItemPostFrame(void) if (m_bDrawbackFinished) { - CBasePlayer *pOwner = ToBasePlayer(GetOwner()); + auto pOwner = static_cast(GetOwner()); if (pOwner) { @@ -256,6 +256,7 @@ void CWeaponGrenade::ItemPostFrame(void) SendWeaponAnim(ACT_VM_THROW); } + pOwner->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_flNextPrimaryAttack = m_flNextSecondaryAttack = m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration(); m_bDrawbackFinished = false; m_AttackPaused = GRENADE_PAUSED_NO; @@ -289,7 +290,7 @@ void CWeaponGrenade::CheckThrowPosition(CBasePlayer *pPlayer, const Vector &vecE } } -void CWeaponGrenade::ThrowGrenade(CBasePlayer *pPlayer, bool isAlive, CBaseEntity *pAttacker) +void CWeaponGrenade::ThrowGrenade(CNEO_Player *pPlayer, bool isAlive, CBaseEntity *pAttacker) { if (!sv_neo_infinite_frag_grenades.GetBool()) { @@ -344,12 +345,12 @@ void CWeaponGrenade::ThrowGrenade(CBasePlayer *pPlayer, bool isAlive, CBaseEntit WeaponSound(SINGLE); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } -void CWeaponGrenade::LobGrenade(CBasePlayer *pPlayer) +void CWeaponGrenade::LobGrenade(CNEO_Player *pPlayer) { // Binds hack: we want grenade secondary attack to trigger on aim, not the attack2 bind. if (pPlayer->m_afButtonPressed & IN_AIM) @@ -385,12 +386,12 @@ void CWeaponGrenade::LobGrenade(CBasePlayer *pPlayer) WeaponSound(WPN_DOUBLE); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } -void CWeaponGrenade::RollGrenade(CBasePlayer *pPlayer) +void CWeaponGrenade::RollGrenade(CNEO_Player *pPlayer) { // Binds hack: we want grenade secondary attack to trigger on aim, not the attack2 bind. if (pPlayer->m_afButtonPressed & IN_AIM) @@ -445,7 +446,7 @@ void CWeaponGrenade::RollGrenade(CBasePlayer *pPlayer) WeaponSound(SPECIAL1); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } @@ -464,7 +465,7 @@ void CWeaponGrenade::Drop(const Vector& vecVelocity) #ifndef CLIENT_DLL void CWeaponGrenade::Operator_HandleAnimEvent(animevent_t *pEvent, CBaseCombatCharacter *pOperator) { - CBasePlayer *pOwner = ToBasePlayer(GetOwner()); + auto pOwner = static_cast(GetOwner()); Assert(pOwner); bool fThrewGrenade = false; diff --git a/mp/src/game/shared/neo/weapons/weapon_grenade.h b/mp/src/game/shared/neo/weapons/weapon_grenade.h index 1bc111085..683c12122 100644 --- a/mp/src/game/shared/neo/weapons/weapon_grenade.h +++ b/mp/src/game/shared/neo/weapons/weapon_grenade.h @@ -62,12 +62,12 @@ class CWeaponGrenade : public CNEOBaseCombatWeapon void Operator_HandleAnimEvent(animevent_t *pEvent, CBaseCombatCharacter *pOperator); #endif - void ThrowGrenade(CBasePlayer *pPlayer, bool isAlive = true, CBaseEntity *pAttacker = NULL); - void LobGrenade(CBasePlayer *pPlayer); + void ThrowGrenade(CNEO_Player *pPlayer, bool isAlive = true, CBaseEntity *pAttacker = NULL); + void LobGrenade(CNEO_Player *pPlayer); bool IsPrimed() const { return (m_AttackPaused != 0); } private: - void RollGrenade(CBasePlayer *pPlayer); + void RollGrenade(CNEO_Player *pPlayer); // Check a throw from vecSrc. If not valid, move the position back along the line to vecEye void CheckThrowPosition(CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc); diff --git a/mp/src/game/shared/neo/weapons/weapon_knife.cpp b/mp/src/game/shared/neo/weapons/weapon_knife.cpp index 73887404d..42dd6c2b4 100644 --- a/mp/src/game/shared/neo/weapons/weapon_knife.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_knife.cpp @@ -131,7 +131,7 @@ bool CWeaponKnife::IsViewable() void CWeaponKnife::Swing(int bIsSecondary) { - CBasePlayer* pOwner = ToBasePlayer(GetOwner()); + auto pOwner = static_cast(GetOwner()); if (!pOwner) return; @@ -202,7 +202,7 @@ void CWeaponKnife::Swing(int bIsSecondary) // Send the anim SendWeaponAnim(nHitActivity); - pOwner->SetAnimation(PLAYER_ATTACK1); + pOwner->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); //Setup our next attack times m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); diff --git a/mp/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp b/mp/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp index 71334fe72..846248783 100644 --- a/mp/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp @@ -798,7 +798,7 @@ void CNEOBaseCombatWeapon::PrimaryAttack(void) } // Only the player fires this way so we can cast - CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + auto pPlayer = static_cast(GetOwner()); if (!pPlayer) { @@ -811,7 +811,7 @@ void CNEOBaseCombatWeapon::PrimaryAttack(void) SendWeaponAnim(GetPrimaryAttackActivity()); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); FireBulletsInfo_t info; info.m_vecSrc = pPlayer->Weapon_ShootPosition(); diff --git a/mp/src/game/shared/neo/weapons/weapon_smokegrenade.cpp b/mp/src/game/shared/neo/weapons/weapon_smokegrenade.cpp index 4531636c4..4a5ca9d19 100644 --- a/mp/src/game/shared/neo/weapons/weapon_smokegrenade.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_smokegrenade.cpp @@ -200,7 +200,7 @@ void CWeaponSmokeGrenade::ItemPostFrame(void) if (m_bDrawbackFinished) { - CBasePlayer* pOwner = ToBasePlayer(GetOwner()); + auto pOwner = static_cast(GetOwner()); if (pOwner) { @@ -268,7 +268,7 @@ void CWeaponSmokeGrenade::CheckThrowPosition(CBasePlayer* pPlayer, const Vector& } } -void CWeaponSmokeGrenade::ThrowGrenade(CBasePlayer* pPlayer, bool isAlive, CBaseEntity *pAttacker) +void CWeaponSmokeGrenade::ThrowGrenade(CNEO_Player* pPlayer, bool isAlive, CBaseEntity *pAttacker) { if (!sv_neo_infinite_smoke_grenades.GetBool()) { @@ -324,12 +324,12 @@ void CWeaponSmokeGrenade::ThrowGrenade(CBasePlayer* pPlayer, bool isAlive, CBase #endif // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } -void CWeaponSmokeGrenade::LobGrenade(CBasePlayer* pPlayer) +void CWeaponSmokeGrenade::LobGrenade(CNEO_Player* pPlayer) { // Binds hack: we want grenade secondary attack to trigger on aim, not the attack2 bind. if (pPlayer->m_afButtonPressed & IN_AIM) @@ -365,12 +365,12 @@ void CWeaponSmokeGrenade::LobGrenade(CBasePlayer* pPlayer) WeaponSound(WPN_DOUBLE); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } -void CWeaponSmokeGrenade::RollGrenade(CBasePlayer* pPlayer) +void CWeaponSmokeGrenade::RollGrenade(CNEO_Player* pPlayer) { // Binds hack: we want grenade secondary attack to trigger on aim, not the attack2 bind. if (pPlayer->m_afButtonPressed & IN_AIM) @@ -425,7 +425,7 @@ void CWeaponSmokeGrenade::RollGrenade(CBasePlayer* pPlayer) WeaponSound(SPECIAL1); // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); m_bRedraw = true; } @@ -444,7 +444,7 @@ void CWeaponSmokeGrenade::Drop(const Vector& vecVelocity) #ifndef CLIENT_DLL void CWeaponSmokeGrenade::Operator_HandleAnimEvent(animevent_t* pEvent, CBaseCombatCharacter* pOperator) { - CBasePlayer* pOwner = ToBasePlayer(GetOwner()); + auto pOwner = static_cast(GetOwner()); Assert(pOwner); bool fThrewGrenade = false; diff --git a/mp/src/game/shared/neo/weapons/weapon_smokegrenade.h b/mp/src/game/shared/neo/weapons/weapon_smokegrenade.h index 884cfdffc..54f13b086 100644 --- a/mp/src/game/shared/neo/weapons/weapon_smokegrenade.h +++ b/mp/src/game/shared/neo/weapons/weapon_smokegrenade.h @@ -60,12 +60,12 @@ class CWeaponSmokeGrenade : public CNEOBaseCombatWeapon void Operator_HandleAnimEvent(animevent_t* pEvent, CBaseCombatCharacter* pOperator); #endif - void ThrowGrenade(CBasePlayer* pPlayer, bool isAlive = true, CBaseEntity *pAttacker = NULL); - void LobGrenade(CBasePlayer* pPlayer); + void ThrowGrenade(CNEO_Player* pPlayer, bool isAlive = true, CBaseEntity *pAttacker = NULL); + void LobGrenade(CNEO_Player* pPlayer); bool IsPrimed() const { return (m_AttackPaused != 0); } private: - void RollGrenade(CBasePlayer* pPlayer); + void RollGrenade(CNEO_Player* pPlayer); // Check a throw from vecSrc. If not valid, move the position back along the line to vecEye void CheckThrowPosition(CBasePlayer* pPlayer, const Vector& vecEye, Vector& vecSrc); diff --git a/mp/src/game/shared/neo/weapons/weapon_supa7.cpp b/mp/src/game/shared/neo/weapons/weapon_supa7.cpp index dd5e5ea59..9d138c007 100644 --- a/mp/src/game/shared/neo/weapons/weapon_supa7.cpp +++ b/mp/src/game/shared/neo/weapons/weapon_supa7.cpp @@ -172,7 +172,7 @@ bool CWeaponSupa7::Reload(void) Warning("ERROR: Supa7 Reload called incorrectly!\n"); } - CBaseCombatCharacter* pOwner = GetOwner(); + auto pOwner = static_cast(GetOwner()); if (pOwner == NULL) return false; @@ -187,6 +187,7 @@ bool CWeaponSupa7::Reload(void) // Play reload on different channel as otherwise steals channel away from fire sound WeaponSound(SPECIAL1); SendWeaponAnim(ACT_VM_RELOAD); + pOwner->DoAnimationEvent(PLAYERANIMEVENT_RELOAD); pOwner->m_flNextAttack = gpGlobals->curtime; ProposeNextAttack(gpGlobals->curtime + SequenceDuration()); @@ -207,7 +208,7 @@ bool CWeaponSupa7::ReloadSlug(void) Warning("ERROR: Supa7 ReloadSlug called incorrectly!\n"); } - CBaseCombatCharacter* pOwner = GetOwner(); + auto pOwner = static_cast(GetOwner()); if (pOwner == NULL) return false; @@ -222,6 +223,7 @@ bool CWeaponSupa7::ReloadSlug(void) // Play reload on different channel as otherwise steals channel away from fire sound WeaponSound(SPECIAL1); SendWeaponAnim(ACT_VM_RELOAD); + pOwner->DoAnimationEvent(PLAYERANIMEVENT_RELOAD); pOwner->m_flNextAttack = gpGlobals->curtime; ProposeNextAttack(gpGlobals->curtime + SequenceDuration()); @@ -292,7 +294,7 @@ void CWeaponSupa7::PrimaryAttack(void) } // Only the player fires this way so we can cast - CBasePlayer* pPlayer = ToBasePlayer(GetOwner()); + auto pPlayer = static_cast(GetOwner()); if (!pPlayer) { @@ -333,7 +335,7 @@ void CWeaponSupa7::PrimaryAttack(void) m_iClip1 -= 1; // player "shoot" animation - pPlayer->SetAnimation(PLAYER_ATTACK1); + pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY); // Fire the bullets, and force the first shot to be perfectly accurate pPlayer->FireBullets(info);