diff --git a/mp/src/game/client/c_baseplayer.cpp b/mp/src/game/client/c_baseplayer.cpp index 942f7a375..d6bc27612 100644 --- a/mp/src/game/client/c_baseplayer.cpp +++ b/mp/src/game/client/c_baseplayer.cpp @@ -228,9 +228,9 @@ END_RECV_TABLE() RecvPropEHandle ( RECVINFO( m_hLastWeapon ) ), RecvPropEHandle ( RECVINFO( m_hGroundEntity ) ), - RecvPropFloat ( RECVINFO(m_vecVelocity[0]), 0, RecvProxy_LocalVelocityX ), - RecvPropFloat ( RECVINFO(m_vecVelocity[1]), 0, RecvProxy_LocalVelocityY ), - RecvPropFloat ( RECVINFO(m_vecVelocity[2]), 0, RecvProxy_LocalVelocityZ ), + RecvPropFloat ( RECVINFO(m_vecVelocity[0]), 0, RecvProxy_LocalVelocityX ), + RecvPropFloat ( RECVINFO(m_vecVelocity[1]), 0, RecvProxy_LocalVelocityY ), + RecvPropFloat ( RECVINFO(m_vecVelocity[2]), 0, RecvProxy_LocalVelocityZ ), RecvPropVector ( RECVINFO( m_vecBaseVelocity ) ), @@ -469,7 +469,7 @@ void C_BasePlayer::Spawn( void ) m_iFOV = 0; // init field of view. - SetModel( "models/player.mdl" ); + SetModel( "models/player.mdl" ); Precache(); @@ -1854,6 +1854,13 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson ) } } } + + //Notify weapon. + CBaseCombatWeapon *pWeapon = GetActiveWeapon(); + if ( pWeapon ) + { + pWeapon->ThirdPersonSwitch( bThirdperson ); + } } } diff --git a/mp/src/game/client/c_te_effect_dispatch.cpp b/mp/src/game/client/c_te_effect_dispatch.cpp index 160e11b7c..2e7ce73a4 100644 --- a/mp/src/game/client/c_te_effect_dispatch.cpp +++ b/mp/src/game/client/c_te_effect_dispatch.cpp @@ -103,8 +103,8 @@ static void RecordEffect( const char *pEffectName, const CEffectData &data ) char pName[1024]; Q_snprintf( pName, sizeof(pName), "TE_DispatchEffect %s %s", pEffectName, pSurfacePropName ); - msg->SetInt( "te", TE_DISPATCH_EFFECT ); - msg->SetString( "name", pName ); + msg->SetInt( "te", TE_DISPATCH_EFFECT ); + msg->SetString( "name", pName ); msg->SetFloat( "time", gpGlobals->curtime ); msg->SetFloat( "originx", data.m_vOrigin.x ); msg->SetFloat( "originy", data.m_vOrigin.y ); @@ -126,10 +126,10 @@ static void RecordEffect( const char *pEffectName, const CEffectData &data ) msg->SetInt( "color", data.m_nColor ); msg->SetInt( "damagetype", data.m_nDamageType ); msg->SetInt( "hitbox", data.m_nHitBox ); - msg->SetString( "effectname", pEffectName ); + msg->SetString( "effectname", pEffectName ); // FIXME: Need to write the attachment name here - msg->SetInt( "attachmentindex", data.m_nAttachmentIndex ); + msg->SetInt( "attachmentindex", data.m_nAttachmentIndex ); // NOTE: Ptrs are our way of indicating it's an entindex msg->SetPtr( "entindex", (void*)data.entindex() ); @@ -178,7 +178,10 @@ void DispatchEffect( const char *pName, const CEffectData &data ) CPASFilter filter( data.m_vOrigin ); te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); } - +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ) +{ + te->DispatchEffect( filter, 0.0, data.m_vOrigin, pName, data ); +} //----------------------------------------------------------------------------- // Playback diff --git a/mp/src/game/client/c_te_effect_dispatch.h b/mp/src/game/client/c_te_effect_dispatch.h index 63fa61730..8abaaeab3 100644 --- a/mp/src/game/client/c_te_effect_dispatch.h +++ b/mp/src/game/client/c_te_effect_dispatch.h @@ -42,5 +42,6 @@ public: void DispatchEffectToCallback( const char *pEffectName, const CEffectData &m_EffectData ); void DispatchEffect( const char *pName, const CEffectData &data ); +void DispatchEffect( const char *pName, const CEffectData &data, IRecipientFilter &filter ); #endif // C_TE_EFFECT_DISPATCH_H diff --git a/mp/src/game/client/client_hl2mp.vpc b/mp/src/game/client/client_hl2mp.vpc index 88e18a8ec..5ffa12076 100644 --- a/mp/src/game/client/client_hl2mp.vpc +++ b/mp/src/game/client/client_hl2mp.vpc @@ -14,7 +14,7 @@ $Configuration { $Compiler { - $AdditionalIncludeDirectories "$BASE;hl2mp\ui,.\hl2mp,$SRCDIR\game\shared\hl2mp,.\hl2,.\hl2\elements,$SRCDIR\game\shared\hl2" + $AdditionalIncludeDirectories "$BASE;hl2mp\ui,.\hl2mp,$SRCDIR\game\shared\hl2mp,.\hl2,.\hl2\elements,$SRCDIR\game\shared\hl2,$SRCDIR\game\shared\Multiplayer" $PreprocessorDefinitions "$BASE;HL2MP;HL2_CLIENT_DLL" } } @@ -127,6 +127,10 @@ $Project "Client (HL2MP)" $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h" $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp" $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h" + $File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.h" + $File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.cpp" + $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h" + $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.cpp" $Folder "Weapons" { diff --git a/mp/src/game/client/hl2/c_basehlplayer.cpp b/mp/src/game/client/hl2/c_basehlplayer.cpp index fbc40eb2f..4849773c0 100644 --- a/mp/src/game/client/hl2/c_basehlplayer.cpp +++ b/mp/src/game/client/hl2/c_basehlplayer.cpp @@ -53,6 +53,11 @@ void CC_DropPrimary( void ) static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player."); +// link to the correct class. +#if !defined ( HL2MP ) +LINK_ENTITY_TO_CLASS( player, C_BaseHLPlayer ); +#endif + //----------------------------------------------------------------------------- // Constructor //----------------------------------------------------------------------------- diff --git a/mp/src/game/client/hl2mp/c_hl2mp_player.cpp b/mp/src/game/client/hl2mp/c_hl2mp_player.cpp index 49e55e293..60e3936d4 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" // Don't alias here #if defined( CHL2MP_Player ) @@ -22,9 +25,23 @@ LINK_ENTITY_TO_CLASS( player, C_HL2MP_Player ); -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] ) ), +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) ), @@ -33,7 +50,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() #define HL2_WALK_SPEED 150 @@ -45,16 +67,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; @@ -63,6 +85,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 @@ -163,6 +186,12 @@ CStudioHdr *C_HL2MP_Player::OnNewModel( void ) Initialize( ); + // Reset the players animation states, gestures + if ( m_PlayerAnimState ) + { + m_PlayerAnimState->OnNewModel(); + } + return hdr; } @@ -271,7 +300,7 @@ int C_HL2MP_Player::DrawModel( int flags ) if ( !m_bReadyToDraw ) return 0; - return BaseClass::DrawModel(flags); + return BaseClass::DrawModel(flags); } //----------------------------------------------------------------------------- @@ -305,24 +334,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(); @@ -355,13 +366,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 ); @@ -457,7 +461,7 @@ const QAngle& C_HL2MP_Player::GetRenderAngles() } else { - return m_PlayerAnimState.GetRenderAngles(); + return m_PlayerAnimState->GetRenderAngles(); } } @@ -780,7 +784,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++ ) { @@ -976,10 +980,140 @@ void C_HL2MPRagdoll::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWei } } -void C_HL2MP_Player::PostThink( void ) +void C_HL2MP_Player::UpdateClientSideAnimation() { - BaseClass::PostThink(); + m_PlayerAnimState->Update( EyeAngles()[YAW], EyeAngles()[PITCH] ); - // Store the eye angles pitch so the client can compute its animation state correctly. - m_angEyeAngles = EyeAngles(); + 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 ) +{ + 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; + } + } + + 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 bac41977d..d0560b9a2 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" @@ -37,7 +37,6 @@ public: virtual int DrawModel( int flags ); virtual void AddEntity( void ); - QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles; } Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL ); @@ -84,13 +83,14 @@ public: void StopWalking( void ); bool IsWalking( void ) { return m_fIsWalking; } - 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/server/baseentity.cpp b/mp/src/game/server/baseentity.cpp index 7a7a7e6cc..c5f0ea1a0 100644 --- a/mp/src/game/server/baseentity.cpp +++ b/mp/src/game/server/baseentity.cpp @@ -1575,7 +1575,28 @@ int CBaseEntity::VPhysicsTakeDamage( const CTakeDamageInfo &info ) if ( gameFlags & FVPHYSICS_PLAYER_HELD ) { // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); + + CBasePlayer *pPlayer = NULL; + + if ( gpGlobals->maxClients == 1 ) + { + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && (tempPlayer->GetHeldObject() == this ) ) + { + pPlayer = tempPlayer; + break; + } + } + } + if ( pPlayer ) { float mass = pPlayer->GetHeldObjectMass( VPhysicsGetObject() ); diff --git a/mp/src/game/server/filters.cpp b/mp/src/game/server/filters.cpp index 6179254dd..221a344a0 100644 --- a/mp/src/game/server/filters.cpp +++ b/mp/src/game/server/filters.cpp @@ -372,7 +372,8 @@ protected: bool PassesDamageFilterImpl(const CTakeDamageInfo &info) { - return info.GetDamageType() == m_iDamageType; + //Tony; these are bitflags. check them as so. + return ((info.GetDamageType() & m_iDamageType) == m_iDamageType); } int m_iDamageType; diff --git a/mp/src/game/server/hl2/hl2_player.cpp b/mp/src/game/server/hl2/hl2_player.cpp index e7583f5a2..e866fa162 100644 --- a/mp/src/game/server/hl2/hl2_player.cpp +++ b/mp/src/game/server/hl2/hl2_player.cpp @@ -2083,7 +2083,7 @@ bool CHL2_Player::IsIlluminatedByFlashlight( CBaseEntity *pEntity, float *flRetu } // Within 50 feet? - float flDistSqr = GetAbsOrigin().DistToSqr(pEntity->GetAbsOrigin()); + float flDistSqr = GetAbsOrigin().DistToSqr(pEntity->GetAbsOrigin()); if( flDistSqr > FLASHLIGHT_RANGE ) return false; @@ -2159,7 +2159,7 @@ void CHL2_Player::SetPlayerUnderwater( bool state ) } else { - SuitPower_RemoveDevice( SuitDeviceBreather ); + SuitPower_RemoveDevice( SuitDeviceBreather ); } BaseClass::SetPlayerUnderwater( state ); @@ -3154,6 +3154,10 @@ float CHL2_Player::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return mass; } +CBaseEntity *CHL2_Player::GetHeldObject( void ) +{ + return PhysCannonGetHeldEntity( GetActiveWeapon() ); +} //----------------------------------------------------------------------------- // Purpose: Force the player to drop any physics objects he's carrying //----------------------------------------------------------------------------- diff --git a/mp/src/game/server/hl2/hl2_player.h b/mp/src/game/server/hl2/hl2_player.h index 6e72bb9e2..3ec2d40dc 100644 --- a/mp/src/game/server/hl2/hl2_player.h +++ b/mp/src/game/server/hl2/hl2_player.h @@ -15,6 +15,14 @@ #include "simtimer.h" #include "soundenvelope.h" +// In HL2MP we need to inherit from BaseMultiplayerPlayer! +#if defined ( HL2MP ) +#include "basemultiplayerplayer.h" +#define BASEPLAYERCLASS CBaseMultiplayerPlayer +#else +#define BASEPLAYERCLASS CBasePlayer +#endif + class CAI_Squad; class CPropCombineBall; @@ -75,10 +83,10 @@ public: //============================================================================= // >> HL2_PLAYER //============================================================================= -class CHL2_Player : public CBasePlayer +class CHL2_Player : public BASEPLAYERCLASS { public: - DECLARE_CLASS( CHL2_Player, CBasePlayer ); + DECLARE_CLASS( CHL2_Player, BASEPLAYERCLASS ); CHL2_Player(); ~CHL2_Player( void ); @@ -241,6 +249,7 @@ public: virtual bool IsHoldingEntity( CBaseEntity *pEnt ); virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis ); virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *GetHeldObject( void ); virtual bool IsFollowingPhysics( void ) { return (m_afPhysicsFlags & PFLAG_ONBARNACLE) > 0; } void InputForceDropPhysObjects( inputdata_t &data ); diff --git a/mp/src/game/server/hl2mp/grenade_tripmine.cpp b/mp/src/game/server/hl2mp/grenade_tripmine.cpp index e14a929d8..b0e8d3b1b 100644 --- a/mp/src/game/server/hl2mp/grenade_tripmine.cpp +++ b/mp/src/game/server/hl2mp/grenade_tripmine.cpp @@ -8,7 +8,7 @@ #include "cbase.h" #include "beam_shared.h" #include "shake.h" -#include "grenade_tripmine.h" +#include "hl2mp/grenade_tripmine.h" // Load the hl2mp header!! #include "vstdlib/random.h" #include "engine/IEngineSound.h" #include "explode.h" @@ -49,8 +49,23 @@ CTripmineGrenade::CTripmineGrenade() m_vecEnd.Init(); m_posOwner.Init(); m_angleOwner.Init(); + + m_pConstraint = NULL; + m_bAttached = false; + m_hAttachEntity = NULL; } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTripmineGrenade::~CTripmineGrenade( void ) +{ + if (m_pConstraint) + { + physenv->DestroyConstraint(m_pConstraint); + m_pConstraint = NULL; + } +} void CTripmineGrenade::Spawn( void ) { Precache( ); @@ -59,7 +74,7 @@ void CTripmineGrenade::Spawn( void ) SetSolid( SOLID_BBOX ); SetModel( "models/Weapons/w_slam.mdl" ); - IPhysicsObject *pObject = VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, true ); + IPhysicsObject *pObject = VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, true ); pObject->EnableMotion( false ); SetCollisionGroup( COLLISION_GROUP_WEAPON ); @@ -117,10 +132,16 @@ void CTripmineGrenade::PowerupThink( void ) { if (gpGlobals->curtime > m_flPowerUp) { + m_flPowerUp = 0; MakeBeam( ); RemoveSolidFlags( FSOLID_NOT_SOLID ); m_bIsLive = true; + // The moment it's live, then do this - incase the attach entity moves between placing it, and activation + // use the absorigin of what we're attaching to for the check, if it moves - we blow up. + if ( m_bAttached && m_hAttachEntity.Get() != NULL ) + m_vAttachedPosition = m_hAttachEntity.Get()->GetAbsOrigin(); + // play enabled sound EmitSound( "TripmineGrenade.Activate" ); } @@ -146,8 +167,6 @@ void CTripmineGrenade::MakeBeam( void ) m_flBeamLength = tr.fraction; - - // If I hit a living thing, send the beam through me so it turns on briefly // and then blows the living thing up CBaseEntity *pEntity = tr.m_pEnt; @@ -219,31 +238,42 @@ void CTripmineGrenade::BeamBreakThink( void ) CBaseEntity *pEntity = tr.m_pEnt; CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity ); - if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001) + bool bAttachMoved = false; + if ( m_bAttached && m_hAttachEntity.Get() != NULL ) + { + if ( m_hAttachEntity.Get()->GetAbsOrigin() != m_vAttachedPosition ) + bAttachMoved = true; + } + + // Also blow up if the attached entity goes away, ie: a crate + if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001 || ( m_bAttached && m_hAttachEntity.Get() == NULL) || bAttachMoved ) { m_iHealth = 0; + if (m_pConstraint) + m_pConstraint->Deactivate(); + Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) ); return; } SetNextThink( gpGlobals->curtime + 0.05f ); } - -#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating -int CTripmineGrenade::OnTakeDamage_Alive( const CTakeDamageInfo &info ) +int CTripmineGrenade::OnTakeDamage( const CTakeDamageInfo &info ) { - if (gpGlobals->curtime < m_flPowerUp && info.GetDamage() < m_iHealth) + if ( m_iHealth < 0 ) + return 0; //already dead. + + if ( gpGlobals->curtime > m_flPowerUp ) { - // disable - // Create( "weapon_tripmine", GetLocalOrigin() + m_vecDir * 24, GetAngles() ); - SetThink( &CTripmineGrenade::SUB_Remove ); - SetNextThink( gpGlobals->curtime + 0.1f ); - KillBeam(); - return FALSE; + m_iHealth -= info.GetDamage(); + + if ( m_iHealth <= 0 ) + Event_Killed( info ); + + return info.GetDamage(); } - return BaseClass::OnTakeDamage_Alive( info ); + return 0; } -#endif //----------------------------------------------------------------------------- // Purpose: @@ -254,6 +284,9 @@ void CTripmineGrenade::Event_Killed( const CTakeDamageInfo &info ) { m_takedamage = DAMAGE_NO; + if (m_pConstraint) + m_pConstraint->Deactivate(); + SetThink( &CTripmineGrenade::DelayDeathThink ); SetNextThink( gpGlobals->curtime + 0.25 ); @@ -274,3 +307,60 @@ void CTripmineGrenade::DelayDeathThink( void ) UTIL_Remove( this ); } +bool CTripmineGrenade::MakeConstraint( CBaseEntity *pObject ) +{ + IPhysicsObject *cMinePhysics = VPhysicsGetObject(); + + Assert( cMinePhysics ); + + IPhysicsObject *pAttached = pObject->VPhysicsGetObject(); + if ( !cMinePhysics || !pAttached ) + return false; + + // constraining to the world means object 1 is fixed + if ( pAttached == g_PhysWorldObject ) + PhysSetGameFlags( cMinePhysics, FVPHYSICS_CONSTRAINT_STATIC ); + + IPhysicsConstraintGroup *pGroup = NULL; + + constraint_fixedparams_t fixed; + fixed.Defaults(); + fixed.InitWithCurrentObjectState( cMinePhysics, pAttached ); + fixed.constraint.Defaults(); + + m_pConstraint = physenv->CreateFixedConstraint( cMinePhysics, pAttached, pGroup, fixed ); + + if (!m_pConstraint) + return false; + + m_pConstraint->SetGameData( (void *)this ); + + return true; +} + +void CTripmineGrenade::AttachToEntity(CBaseEntity *pOther) +{ + if (!pOther) + return; + + if ( !VPhysicsGetObject() ) + return; + + m_bAttached = true; + m_hAttachEntity = pOther; + + SetMoveType ( MOVETYPE_NONE ); + + if (pOther->GetSolid() == SOLID_VPHYSICS && pOther->VPhysicsGetObject() != NULL ) + { + SetSolid(SOLID_BBOX); //Tony; switch to bbox solid instead of vphysics, because we've made the physics object non-solid + MakeConstraint(pOther); + SetMoveType ( MOVETYPE_VPHYSICS ); // use vphysics while constrained!! + } + //if it isnt vphysics or bsp, use SetParent to follow it. + else if (pOther->GetSolid() != SOLID_BSP) + { + SetSolid(SOLID_BBOX); //Tony; switch to bbox solid instead of vphysics, because we've made the physics object non-solid + SetParent( m_hAttachEntity.Get() ); + } +} diff --git a/mp/src/game/server/hl2mp/grenade_tripmine.h b/mp/src/game/server/hl2mp/grenade_tripmine.h index e18870960..f6f979688 100644 --- a/mp/src/game/server/hl2mp/grenade_tripmine.h +++ b/mp/src/game/server/hl2mp/grenade_tripmine.h @@ -15,6 +15,8 @@ class CBeam; +// for constraints +#include "vphysics/constraints.h" class CTripmineGrenade : public CBaseGrenade { @@ -22,12 +24,12 @@ public: DECLARE_CLASS( CTripmineGrenade, CBaseGrenade ); CTripmineGrenade(); + ~CTripmineGrenade(); + void Spawn( void ); void Precache( void ); -#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating - int OnTakeDamage_Alive( const CTakeDamageInfo &info ); -#endif + virtual int OnTakeDamage( const CTakeDamageInfo &info ); void WarningThink( void ); void PowerupThink( void ); void BeamBreakThink( void ); @@ -37,8 +39,14 @@ public: void MakeBeam( void ); void KillBeam( void ); + // Added to create a constraint + void AttachToEntity( CBaseEntity *pOther ); + bool MakeConstraint( CBaseEntity *pOther ); + public: EHANDLE m_hOwner; + // Added for following + EHANDLE m_hAttachEntity; private: float m_flPowerUp; @@ -50,6 +58,11 @@ private: Vector m_posOwner; Vector m_angleOwner; + // signifies if we're attached to something, and need to update slightly differently. + bool m_bAttached; + IPhysicsConstraint *m_pConstraint; + Vector m_vAttachedPosition; // if the attached position changes, we need to detonate + DECLARE_DATADESC(); }; diff --git a/mp/src/game/server/hl2mp/hl2mp_player.cpp b/mp/src/game/server/hl2mp/hl2mp_player.cpp index 1469d8420..f271f2c25 100644 --- a/mp/src/game/server/hl2mp/hl2mp_player.cpp +++ b/mp/src/game/server/hl2mp/hl2mp_player.cpp @@ -20,12 +20,17 @@ #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" #include "ilagcompensationmanager.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + int g_iLastCitizenModel = 0; int g_iLastCombineModel = 0; @@ -42,19 +47,58 @@ LINK_ENTITY_TO_CLASS( player, CHL2MP_Player ); LINK_ENTITY_TO_CLASS( info_player_combine, CPointEntity ); LINK_ENTITY_TO_CLASS( info_player_rebel, CPointEntity ); +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 ), +END_SEND_TABLE() + 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 ), + 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" ), + + // 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 ), - - SendPropExclude( "DT_BaseAnimating", "m_flPoseParameter" ), - SendPropExclude( "DT_BaseFlex", "m_viewtarget" ), - -// SendPropExclude( "DT_ServerAnimationData" , "m_flCycle" ), -// SendPropExclude( "DT_AnimTimeMustBeFirst" , "m_flAnimTime" ), - + END_SEND_TABLE() BEGIN_DATADESC( CHL2MP_Player ) @@ -96,8 +140,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; @@ -107,16 +155,16 @@ CHL2MP_Player::CHL2MP_Player() : m_PlayerAnimState( this ) m_iSpawnInterpCounter = 0; - m_bEnterObserver = false; + m_bEnterObserver = false; m_bReady = false; BaseClass::ChangeTeam( 0 ); -// UseClientSideAnimation(); } CHL2MP_Player::~CHL2MP_Player( void ) { + m_PlayerAnimState->Release(); } @@ -142,13 +190,13 @@ void CHL2MP_Player::Precache( void ) int i; for ( i = 0; i < nHeads; ++i ) - PrecacheModel( g_ppszRandomCitizenModels[i] ); + PrecacheModel( g_ppszRandomCitizenModels[i] ); //Precache Combine Models nHeads = ARRAYSIZE( g_ppszRandomCombineModels ); for ( i = 0; i < nHeads; ++i ) - PrecacheModel( g_ppszRandomCombineModels[i] ); + PrecacheModel( g_ppszRandomCombineModels[i] ); PrecacheFootStepSounds(); @@ -304,8 +352,6 @@ void CHL2MP_Player::Spawn(void) GiveDefaultItems(); } - SetNumAnimOverlays( 3 ); - ResetAnimation(); m_nRenderFX = kRenderNormal; @@ -331,6 +377,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 ) @@ -355,7 +405,7 @@ bool CHL2MP_Player::ValidatePlayerModel( const char *pModel ) for ( i = 0; i < iModels; ++i ) { - if ( !Q_stricmp( g_ppszRandomCombineModels[i], pModel ) ) + if ( !Q_stricmp( g_ppszRandomCombineModels[i], pModel ) ) { return true; } @@ -505,55 +555,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 ) @@ -565,14 +580,13 @@ void CHL2MP_Player::PostThink( void ) SetCollisionBounds( VEC_CROUCH_TRACE_MIN, VEC_CROUCH_TRACE_MAX ); } - 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() @@ -671,170 +685,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 ) -{ - 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. @@ -1225,8 +1075,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(); @@ -1415,7 +1263,7 @@ CON_COMMAND( timeleft, "prints the time remaining in the match" ) CHL2MP_Player *pPlayer = ToHL2MPPlayer( UTIL_GetCommandClient() ); int iTimeRemaining = (int)HL2MPRules()->GetMapRemainingTime(); - + if ( iTimeRemaining == 0 ) { if ( pPlayer ) @@ -1627,3 +1475,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 f91513c73..032e029a1 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" @@ -51,13 +52,17 @@ public: 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 ); @@ -82,9 +87,8 @@ public: 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 ); @@ -93,7 +97,8 @@ public: void NoteWeaponFired( void ); - void ResetAnimation( void ); + void SetAnimation( PLAYER_ANIM playerAnim ); + void SetPlayerModel( void ); void SetPlayerTeamModel( void ); Activity TranslateTeamActivity( Activity ActToTranslate ); @@ -140,8 +145,9 @@ public: private: + CHL2MPPlayerAnimState *m_PlayerAnimState; + CNetworkQAngle( m_angEyeAngles ); - CPlayerAnimState m_PlayerAnimState; int m_iLastWeaponFireUsercmd; int m_iModelType; @@ -161,7 +167,7 @@ private: // This lets us rate limit the commands the players can execute so they don't overflow things like reliable buffers. CUtlDict m_RateLimitLastCommandTimes; - bool m_bEnterObserver; + bool m_bEnterObserver; bool m_bReady; }; diff --git a/mp/src/game/server/physics_impact_damage.cpp b/mp/src/game/server/physics_impact_damage.cpp index 164568e23..feb7d966f 100644 --- a/mp/src/game/server/physics_impact_damage.cpp +++ b/mp/src/game/server/physics_impact_damage.cpp @@ -335,15 +335,33 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co if ( pEvent->pObjects[otherIndex]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { + // if the player is holding the object, use its real mass (player holding reduced the mass) + + CBasePlayer *pPlayer = NULL; + if ( gpGlobals->maxClients == 1 ) { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) + { + pPlayer = tempPlayer; + break; + } } } + + if ( pPlayer ) + { + otherMass = pPlayer->GetHeldObjectMass( pEvent->pObjects[otherIndex] ); + } } // NOTE: sum the mass of each object in this system for the purpose of damage @@ -438,19 +456,36 @@ float CalculatePhysicsImpactDamage( int index, gamevcollisionevent_t *pEvent, co } else if ( pEvent->pObjects[index]->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { + // if the player is holding the object, use it's real mass (player holding reduced the mass) + + CBasePlayer *pPlayer = NULL; if ( gpGlobals->maxClients == 1 ) { - // if the player is holding the object, use it's real mass (player holding reduced the mass) - CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); - if ( pPlayer ) + pPlayer = UTIL_GetLocalPlayer(); + } + else + { + // See which MP player is holding the physics object and then use that player to get the real mass of the object. + // This is ugly but better than having linkage between an object and its "holding" player. + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { - float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] ); - if ( mass > 0 ) + CBasePlayer *tempPlayer = UTIL_PlayerByIndex( i ); + if ( tempPlayer && pEvent->pEntities[index] == tempPlayer->GetHeldObject() ) { - invMass = 1.0f / mass; + pPlayer = tempPlayer; + break; } } } + + if ( pPlayer ) + { + float mass = pPlayer->GetHeldObjectMass( pEvent->pObjects[index] ); + if ( mass > 0 ) + { + invMass = 1.0f / mass; + } + } } eliminatedEnergy *= invMass * energyScale; diff --git a/mp/src/game/server/player.cpp b/mp/src/game/server/player.cpp index a44ee5515..75ec3aa5d 100644 --- a/mp/src/game/server/player.cpp +++ b/mp/src/game/server/player.cpp @@ -1079,7 +1079,7 @@ int CBasePlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo ) return 0; } - if ( IsInCommentaryMode() ) + if ( IsInCommentaryMode() ) { if( !ShouldTakeDamageInCommentaryMode( info ) ) return 0; @@ -1466,7 +1466,7 @@ void CBasePlayer::PackDeadPlayerItems( void ) // get the game rules iWeaponRules = g_pGameRules->DeadPlayerWeapons( this ); - iAmmoRules = g_pGameRules->DeadPlayerAmmo( this ); + iAmmoRules = g_pGameRules->DeadPlayerAmmo( this ); if ( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO ) { @@ -1552,7 +1552,7 @@ void CBasePlayer::RemoveAllItems( bool removeSuit ) Weapon_SetLast( NULL ); RemoveAllWeapons(); - RemoveAllAmmo(); + RemoveAllAmmo(); if ( removeSuit ) { @@ -1636,7 +1636,7 @@ int CBasePlayer::OnTakeDamage_Alive( const CTakeDamageInfo &info ) event->SetInt("attacker", 0 ); // hurt by "world" } - gameeventmanager->FireEvent( event ); + gameeventmanager->FireEvent( event ); } // Insert a combat sound so that nearby NPCs hear battle @@ -2255,17 +2255,17 @@ bool CBasePlayer::StartObserverMode(int mode) m_afPhysicsFlags |= PFLAG_OBSERVER; // Holster weapon immediately, to allow it to cleanup - if ( GetActiveWeapon() ) + if ( GetActiveWeapon() ) GetActiveWeapon()->Holster(); // clear out the suit message cache so we don't keep chattering - SetSuitUpdate(NULL, FALSE, 0); + SetSuitUpdate(NULL, FALSE, 0); SetGroundEntity( (CBaseEntity *)NULL ); RemoveFlag( FL_DUCKING ); - AddSolidFlags( FSOLID_NOT_SOLID ); + AddSolidFlags( FSOLID_NOT_SOLID ); SetObserverMode( mode ); @@ -2275,7 +2275,7 @@ bool CBasePlayer::StartObserverMode(int mode) } // Setup flags - m_Local.m_iHideHUD = HIDEHUD_HEALTH; + m_Local.m_iHideHUD = HIDEHUD_HEALTH; m_takedamage = DAMAGE_NO; // Become invisible @@ -2662,7 +2662,7 @@ bool CBasePlayer::IsValidObserverTarget(CBaseEntity * target) CBasePlayer * player = ToBasePlayer( target ); /* Don't spec observers or players who haven't picked a class yet - if ( player->IsObserver() ) + if ( player->IsObserver() ) return false; */ if( player == this ) @@ -2754,10 +2754,10 @@ CBaseEntity * CBasePlayer::FindNextObserverTarget(bool bReverse) currentIndex += iDir; // Loop through the clients - if (currentIndex > gpGlobals->maxClients) - currentIndex = 1; + if (currentIndex > gpGlobals->maxClients) + currentIndex = 1; else if (currentIndex < 1) - currentIndex = gpGlobals->maxClients; + currentIndex = gpGlobals->maxClients; } while ( currentIndex != startIndex ); @@ -2867,6 +2867,10 @@ float CBasePlayer::GetHeldObjectMass( IPhysicsObject *pHeldObject ) return 0; } +CBaseEntity *CBasePlayer::GetHeldObject( void ) +{ + return NULL; +} //----------------------------------------------------------------------------- // Purpose: Server side of jumping rules. Most jumping logic is already @@ -4955,7 +4959,7 @@ void CBasePlayer::Spawn( void ) m_Local.m_bDucked = false;// This will persist over round restart if you hold duck otherwise. m_Local.m_bDucking = false; - SetViewOffset( VEC_VIEW_SCALED( this ) ); + SetViewOffset( VEC_VIEW_SCALED( this ) ); Precache(); m_bitsDamageType = 0; @@ -5599,7 +5603,7 @@ void CSprayCan::Think( void ) CBasePlayer *pPlayer = ToBasePlayer( GetOwnerEntity() ); if ( pPlayer ) { - int playernum = pPlayer->entindex(); + int playernum = pPlayer->entindex(); Vector forward; trace_t tr; @@ -5877,12 +5881,12 @@ void CBasePlayer::ImpulseCommands( ) switch (iImpulse) { case 100: - // temporary flashlight for level designers - if ( FlashlightIsOn() ) + // temporary flashlight for level designers + if ( FlashlightIsOn() ) { FlashlightTurnOff(); } - else + else { FlashlightTurnOn(); } @@ -6413,7 +6417,7 @@ bool CBasePlayer::ClientCommand( const CCommand &args ) else { // switch to next spec mode if no parameter given - mode = GetObserverMode() + 1; + mode = GetObserverMode() + 1; if ( mode > LAST_PLAYER_OBSERVERMODE ) { @@ -8369,7 +8373,7 @@ void CBasePlayer::SetVCollisionState( const Vector &vecAbsOrigin, const Vector & switch( collisionState ) { case VPHYS_WALK: - m_pShadowStand->SetPosition( vecAbsOrigin, vec3_angle, true ); + m_pShadowStand->SetPosition( vecAbsOrigin, vec3_angle, true ); m_pShadowStand->SetVelocity( &vecAbsVelocity, NULL ); m_pShadowCrouch->EnableCollisions( false ); m_pPhysicsController->SetObject( m_pShadowStand ); diff --git a/mp/src/game/server/player.h b/mp/src/game/server/player.h index 8edefff37..a10bcac86 100644 --- a/mp/src/game/server/player.h +++ b/mp/src/game/server/player.h @@ -550,6 +550,7 @@ public: virtual void PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {} virtual void ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {} virtual float GetHeldObjectMass( IPhysicsObject *pHeldObject ); + virtual CBaseEntity *GetHeldObject( void ); void CheckSuitUpdate(); void SetSuitUpdate(const char *name, int fgroup, int iNoRepeat); @@ -922,7 +923,7 @@ protected: int m_iTrain; // Train control position float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn - unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden + unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden // Vehicles CNetworkHandle( CBaseEntity, m_hVehicle ); diff --git a/mp/src/game/server/server_hl2mp.vpc b/mp/src/game/server/server_hl2mp.vpc index 46d039db6..96c7a5598 100644 --- a/mp/src/game/server/server_hl2mp.vpc +++ b/mp/src/game/server/server_hl2mp.vpc @@ -15,7 +15,7 @@ $Configuration { $Compiler { - $AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2,.\hl2,.\hl2mp,$SRCDIR\game\shared\hl2mp" + $AdditionalIncludeDirectories "$BASE;$SRCDIR\game\shared\hl2,.\hl2,.\hl2mp,$SRCDIR\game\shared\hl2mp,$SRCDIR\game\shared\Multiplayer" $PreprocessorDefinitions "$BASE;HL2MP;HL2_DLL" } } @@ -258,6 +258,10 @@ $Project "Server (HL2MP)" $File "$SRCDIR\game\shared\hl2mp\hl2mp_player_shared.h" $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.cpp" $File "$SRCDIR\game\shared\hl2mp\hl2mp_weapon_parse.h" + $File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.h" + $File "$SRCDIR\game\shared\hl2mp\hl2mp_playeranimstate.cpp" + $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.h" + $File "$SRCDIR\game\shared\Multiplayer\multiplayer_animstate.cpp" $Folder "Weapons" { diff --git a/mp/src/game/shared/basecombatweapon_shared.h b/mp/src/game/shared/basecombatweapon_shared.h index 2c712923b..27feda8be 100644 --- a/mp/src/game/shared/basecombatweapon_shared.h +++ b/mp/src/game/shared/basecombatweapon_shared.h @@ -513,6 +513,9 @@ public: bool WantsToOverrideViewmodelAttachments( void ) { return false; } #endif + //Tony; notifications of any third person switches. + virtual void ThirdPersonSwitch( bool bThirdPerson ) {}; + #endif // End client-only methods virtual bool CanLower( void ) { return false; } diff --git a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp index 503d498c2..001257dc8 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.cpp @@ -18,6 +18,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] = @@ -120,458 +123,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; -}; - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CPlayerAnimState::Update() -{ - m_angRender = GetOuter()->GetLocalAngles(); - m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f; - - ComputePoseParam_BodyYaw(); - ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr()); - ComputePoseParam_BodyLookYaw(); - - ComputePlaybackRate(); - -#ifdef CLIENT_DLL - GetOuter()->UpdateLookAt(); -#endif - -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CPlayerAnimState::ComputePlaybackRate() -{ - // 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 ); - } -} - -//----------------------------------------------------------------------------- -// 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 -} - -//----------------------------------------------------------------------------- -// 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 - GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch ); -} - -//----------------------------------------------------------------------------- -// 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; - - // See if we even have a blender for pitch - int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_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 3aee9237c..f79f1c1c1 100644 --- a/mp/src/game/shared/hl2mp/hl2mp_player_shared.h +++ b/mp/src/game/shared/hl2mp/hl2mp_player_shared.h @@ -34,64 +34,5 @@ enum HL2MPPlayerState #define CHL2MP_Player C_HL2MP_Player #endif -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 ); - - 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..d18330f82 --- /dev/null +++ b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.cpp @@ -0,0 +1,703 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +#include "cbase.h" +#include "base_playeranimstate.h" +#include "tier0/vprof.h" +#include "animation.h" +#include "studio.h" +#include "apparent_velocity_helper.h" +#include "utldict.h" + +#include "hl2mp_playeranimstate.h" +#include "base_playeranimstate.h" +#include "datacache/imdlcache.h" + +#ifdef CLIENT_DLL +#include "c_hl2mp_player.h" +#else +#include "hl2mp_player.h" +#endif + +#define HL2MP_RUN_SPEED 320.0f +#define HL2MP_WALK_SPEED 75.0f +#define HL2MP_CROUCHWALK_SPEED 110.0f + +//----------------------------------------------------------------------------- +// 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(); +} + +//----------------------------------------------------------------------------- +// 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() ) + { + translateActivity = GetHL2MPPlayer()->GetActiveWeapon()->ActivityOverride( translateActivity, false ); + } + + return translateActivity; +} +//----------------------------------------------------------------------------- +// 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 +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : event - +//----------------------------------------------------------------------------- +void CHL2MPPlayerAnimState::DoAnimationEvent( PlayerAnimEvent_t event, int nData ) +{ + Activity iGestureActivity = ACT_INVALID; + + switch( event ) + { + case PLAYERANIMEVENT_ATTACK_PRIMARY: + { + // 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; + 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: + { + // 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; + 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: + { + // 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 ); + 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 ) +{ + return BaseClass::HandleMoving( idealActivity ); +} + +//----------------------------------------------------------------------------- +// 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 ) + { + idealActivity = ACT_MP_CROUCH_IDLE; + } + else + { + idealActivity = ACT_MP_CROUCHWALK; + } + + 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 ) + { + RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND ); + } + } + } + + // if we're still jumping + if ( m_bJumping ) + { + 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; + } + } + } + + if ( m_bJumping ) + return true; + + return false; +} + +bool CHL2MPPlayerAnimState::SetupPoseParameters( CStudioHdr *pStudioHdr ) +{ + // 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, "aim_pitch" ); + if ( m_PoseParameterData.m_iAimPitch < 0 ) + return false; + + // Look for aim yaw blender. + m_PoseParameterData.m_iAimYaw = GetBasePlayer()->LookupPoseParameter( pStudioHdr, "aim_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 ) +{ + // Get the estimated movement yaw. + EstimateYaw(); + +#if 0 // 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 ); + + if ( fabs( flYawDelta ) > 45.0f ) + { + float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f; + m_flGoalFeetYaw += ( 45.0f * flSide ); + } + } + } + + // 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() +{ + 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; +} \ No newline at end of file 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..0ff852613 --- /dev/null +++ b/mp/src/game/shared/hl2mp/hl2mp_playeranimstate.h @@ -0,0 +1,65 @@ +//========= 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(); + 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(); + +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 @@ public: void PrimaryAttack( void ); DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif private: @@ -57,25 +54,25 @@ 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 }, + + { 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( CWeapon357 ); -#endif - //----------------------------------------------------------------------------- // 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 @@ protected: 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 5bada600f..a617418d8 100644 --- a/mp/src/game/shared/hl2mp/weapon_crossbow.cpp +++ b/mp/src/game/shared/hl2mp/weapon_crossbow.cpp @@ -433,9 +433,7 @@ private: 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 //----------------------------------------------------------------------------- @@ -792,29 +792,34 @@ void CWeaponCrossbow::DoLoadEffect( void ) if ( pOwner == NULL ) return; - CBaseViewModel *pViewModel = pOwner->GetViewModel(); - - if ( pViewModel == NULL ) - return; - + //Tony; change this up a bit; on the server, dispatch an effect but don't send it to the client who fires + //on the client, create an effect either in the view model, or on the world model if first person. CEffectData data; -#ifdef CLIENT_DLL - data.m_hEntity = pViewModel->GetRefEHandle(); -#else - data.m_nEntIndex = pViewModel->entindex(); -#endif data.m_nAttachmentIndex = 1; + data.m_vOrigin = pOwner->GetAbsOrigin(); - DispatchEffect( "CrossbowLoad", data ); + CPASFilter filter( data.m_vOrigin ); + +#ifdef GAME_DLL + filter.RemoveRecipient( pOwner ); + data.m_nEntIndex = entindex(); +#else + CBaseViewModel *pViewModel = pOwner->GetViewModel(); + if ( ShouldDrawUsingViewModel() && pViewModel != NULL ) + data.m_hEntity = pViewModel->GetRefEHandle(); + else + data.m_hEntity = GetRefEHandle(); +#endif + + DispatchEffect( "CrossbowLoad", data, filter ); #ifndef CLIENT_DLL - CSprite *pBlast = CSprite::SpriteCreate( CROSSBOW_GLOW_SPRITE2, GetAbsOrigin(), false ); if ( pBlast ) { - pBlast->SetAttachment( pOwner->GetViewModel(), 1 ); + pBlast->SetAttachment( this, 1 ); pBlast->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone ); pBlast->SetBrightness( 128 ); pBlast->SetScale( 0.2f ); 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 @@ public: 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 @@ private: 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 @@ public: #ifdef GAME_DLL DECLARE_DATADESC(); - - void SendReloadSoundEvent( void ); - void Materialize( void ); virtual int ObjectCaps( void ); #endif @@ -60,6 +57,7 @@ public: 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 4972a1ed6..a29133587 100644 --- a/mp/src/game/shared/hl2mp/weapon_physcannon.cpp +++ b/mp/src/game/shared/hl2mp/weapon_physcannon.cpp @@ -1224,7 +1224,9 @@ protected: bool m_bOldOpen; // Used for parity checks void NotifyShouldTransmit( ShouldTransmitState_t state ); - +private: + virtual void ThirdPersonSwitch( bool bThirdPerson ); +protected: #endif // CLIENT_DLL int m_nChangeState; // For delayed state change of elements @@ -1249,10 +1251,7 @@ protected: private: CWeaponPhysCannon( const CWeaponPhysCannon & ); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif }; IMPLEMENT_NETWORKCLASS_ALIASED( WeaponPhysCannon, DT_WeaponPhysCannon ) @@ -1289,24 +1288,25 @@ 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 }, + + { ACT_MP_RUN, ACT_HL2MP_RUN_PHYSGUN, false }, + { ACT_MP_CROUCHWALK, ACT_HL2MP_WALK_CROUCH_PHYSGUN, false }, + + { 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); -#endif - - enum { ELEMENT_STATE_NONE = -1, @@ -2601,56 +2601,26 @@ void CWeaponPhysCannon::DoEffectIdle( void ) StartEffects(); - //if ( ShouldDrawUsingViewModel() ) + // Turn on the glow sprites + for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ ) { - // Turn on the glow sprites - for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ ) - { - m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE ); - m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) ); - } - - // Turn on the glow sprites - for ( int i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) - { - m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) ); - m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) ); - } - - if ( m_EffectState != EFFECT_HOLDING ) - { - // Turn beams off - m_Beams[0].SetVisible( false ); - m_Beams[1].SetVisible( false ); - m_Beams[2].SetVisible( false ); - } + m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE ); + m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) ); } - /* - else + + // Turn on the glow sprites + for ( int i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) { - // Turn on the glow sprites - for ( int i = PHYSCANNON_GLOW1; i < (PHYSCANNON_GLOW1+NUM_GLOW_SPRITES); i++ ) - { - m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 0.075f, 0.05f ) * SPRITE_SCALE ); - m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 24, 32 ) ); - } - - // Turn on the glow sprites - for ( i = PHYSCANNON_ENDCAP1; i < (PHYSCANNON_ENDCAP1+NUM_ENDCAP_SPRITES); i++ ) - { - m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) ); - m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) ); - } - - if ( m_EffectState != EFFECT_HOLDING ) - { - // Turn beams off - m_Beams[0].SetVisible( false ); - m_Beams[1].SetVisible( false ); - m_Beams[2].SetVisible( false ); - } + m_Parameters[i].GetScale().SetAbsolute( random->RandomFloat( 3, 5 ) ); + m_Parameters[i].GetAlpha().SetAbsolute( random->RandomInt( 200, 255 ) ); + } + if ( m_EffectState != EFFECT_HOLDING ) + { + // Turn beams off + m_Beams[0].SetVisible( false ); + m_Beams[1].SetVisible( false ); + m_Beams[2].SetVisible( false ); } - */ #endif } @@ -2957,6 +2927,15 @@ void CWeaponPhysCannon::StopEffects( bool stopSound ) #endif // !CLIENT_DLL } +#ifdef CLIENT_DLL +void CWeaponPhysCannon::ThirdPersonSwitch( bool bThirdPerson ) +{ + //Tony; if we switch to first or third person or whatever, destroy and recreate the effects. + //Note: the sound only ever gets shut off on the server, so it's okay - as this is entirely client side. + DestroyEffects(); + StartEffects(); +} +#endif //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- 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 @@ public: { return 0.5f; } - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif private: CNetworkVar( float, m_flSoonestPrimaryAttack ); @@ -127,24 +125,25 @@ 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 }, + + { ACT_MP_ATTACK_STAND_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + { ACT_MP_ATTACK_CROUCH_PRIMARYFIRE, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false }, + + { 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 ); -#endif - //----------------------------------------------------------------------------- // 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 aa3cc8fd0..1a0b3c239 100644 --- a/mp/src/game/shared/hl2mp/weapon_rpg.cpp +++ b/mp/src/game/shared/hl2mp/weapon_rpg.cpp @@ -453,7 +453,7 @@ void CMissile::IgniteThink( void ) SetMoveType( MOVETYPE_FLY ); SetModel("models/weapons/w_missile.mdl"); UTIL_SetSize( this, vec3_origin, vec3_origin ); - RemoveSolidFlags( FSOLID_NOT_SOLID ); + RemoveSolidFlags( FSOLID_NOT_SOLID ); //TODO: Play opening sound @@ -983,7 +983,7 @@ void CAPCMissile::ExplodeDelay( float flDelay ) void CAPCMissile::BeginSeekThink( void ) { - RemoveSolidFlags( FSOLID_NOT_SOLID ); + RemoveSolidFlags( FSOLID_NOT_SOLID ); SetThink( &CAPCMissile::SeekThink ); SetNextThink( gpGlobals->curtime ); } @@ -1248,7 +1248,7 @@ void CAPCMissile::ComputeActualDotPosition( CLaserDot *pLaserDot, Vector *pActua #define RPG_BEAM_SPRITE "effects/laser1.vmt" #define RPG_BEAM_SPRITE_NOZ "effects/laser1_noz.vmt" -#define RPG_LASER_SPRITE "sprites/redglow1" +#define RPG_LASER_SPRITE "sprites/redglow1.vmt" //============================================================================= // RPG @@ -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: //----------------------------------------------------------------------------- @@ -1361,7 +1363,6 @@ void CWeaponRPG::Precache( void ) PrecacheScriptSound( "Missile.Accelerate" ); // Laser dot... - PrecacheModel( "sprites/redglow1.vmt" ); PrecacheModel( RPG_LASER_SPRITE ); PrecacheModel( RPG_BEAM_SPRITE ); PrecacheModel( RPG_BEAM_SPRITE_NOZ ); @@ -1425,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; @@ -1480,7 +1481,8 @@ void CWeaponRPG::PrimaryAttack( void ) WeaponSound( SINGLE ); // player "shoot" animation - pPlayer->SetAnimation( PLAYER_ATTACK1 ); + pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY ); + } //----------------------------------------------------------------------------- @@ -1883,6 +1885,19 @@ void CWeaponRPG::GetWeaponAttachment( int attachmentId, Vector &outVector, Vecto } } +//Tony; added so when the rpg switches to third person, the beam etc is re-created. +void CWeaponRPG::ThirdPersonSwitch( bool bThirdPerson ) +{ + if ( m_pBeam != NULL ) + { + //Tell it to die right away and let the beam code free it. + m_pBeam->brightness = 0.0f; + m_pBeam->flags &= ~FBEAM_FOREVER; + m_pBeam->die = gpGlobals->curtime - 0.1; + m_pBeam = NULL; + } +} + //----------------------------------------------------------------------------- // Purpose: Setup our laser beam //----------------------------------------------------------------------------- @@ -2231,7 +2246,7 @@ int CLaserDot::DrawModel( int flags ) if ( pOwner != NULL && pOwner->IsDormant() == false ) { // Always draw the dot in front of our faces when in first-person - if ( pOwner->IsLocalPlayer() ) + if ( pOwner->IsLocalPlayer() && C_BasePlayer::LocalPlayerInFirstPersonView() ) //Tony; !!! { // Take our view position and orientation vecAttachment = CurrentViewOrigin(); @@ -2241,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 bbd6f2dd2..af10575bc 100644 --- a/mp/src/game/shared/hl2mp/weapon_rpg.h +++ b/mp/src/game/shared/hl2mp/weapon_rpg.h @@ -238,13 +238,14 @@ public: CMaterialReference m_hBeamMaterial; // Used for the laser beam Beam_t *m_pBeam; // Laser beam temp entity + //Tony; third person check thing, to destroy/reinitialize the beam ( swapping first -> third or back, etc ) + virtual void ThirdPersonSwitch( bool bThirdPerson ); + #endif //CLIENT_DLL 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 da370b539..288816c79 100644 --- a/mp/src/game/shared/hl2mp/weapon_shotgun.cpp +++ b/mp/src/game/shared/hl2mp/weapon_shotgun.cpp @@ -61,9 +61,7 @@ public: 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,10 +368,11 @@ 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 ); + + Vector vecSrc = pPlayer->Weapon_ShootPosition(); + Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); FireBulletsInfo_t info( 12, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType ); info.m_pAttacker = pPlayer; diff --git a/mp/src/game/shared/hl2mp/weapon_slam.cpp b/mp/src/game/shared/hl2mp/weapon_slam.cpp index bcdec40cd..30f566b9b 100644 --- a/mp/src/game/shared/hl2mp/weapon_slam.cpp +++ b/mp/src/game/shared/hl2mp/weapon_slam.cpp @@ -14,7 +14,7 @@ #include "c_hl2mp_player.h" #else #include "hl2mp_player.h" - #include "grenade_tripmine.h" + #include "hl2mp/grenade_tripmine.h" // Load the hl2mp version! #include "grenade_satchel.h" #include "entitylist.h" #include "eventqueue.h" @@ -26,6 +26,7 @@ #include "tier0/memdbgon.h" #define SLAM_PRIMARY_VOLUME 450 +#define SLAM_REFIRE_DELAY 0.05f IMPLEMENT_NETWORKCLASS_ALIASED( Weapon_SLAM, DT_Weapon_SLAM ) @@ -91,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( ) @@ -327,8 +333,8 @@ void CWeapon_SLAM::StartSatchelDetonate() } SatchelDetonate(); - m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); - m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); + // needs a higher delay on all of these, a minimum time really - to elimiate refires. + m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration(); } @@ -376,6 +382,8 @@ void CWeapon_SLAM::TripmineAttach( void ) CTripmineGrenade *pMine = (CTripmineGrenade *)pEnt; pMine->m_hOwner = GetOwner(); + // Attempt to attach to entity, or just sit still in place. + pMine->AttachToEntity( pEntity ); #endif @@ -392,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; @@ -419,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 @@ -444,8 +452,8 @@ void CWeapon_SLAM::StartTripmineAttach( void ) } } - m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); - m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); + // needs a higher delay on all of these, a minimum time really - to elimiate refires. + m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration(); // SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration() ); } @@ -456,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( ); @@ -492,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" ); } @@ -527,8 +537,7 @@ void CWeapon_SLAM::StartSatchelThrow( void ) m_bNeedReload = true; m_bThrowSatchel = true; - m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); - m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration(); + m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration(); } //----------------------------------------------------------------------------- @@ -587,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; @@ -605,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 @@ -631,7 +637,8 @@ void CWeapon_SLAM::StartSatchelAttach( void ) m_bNeedReload = true; m_bAttachSatchel = true; - m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); + m_flNextPrimaryAttack = m_flNextSecondaryAttack = SLAM_REFIRE_DELAY + gpGlobals->curtime + SequenceDuration(); + } } #endif @@ -813,7 +820,7 @@ void CWeapon_SLAM::Weapon_Switch( void ) void CWeapon_SLAM::WeaponIdle( void ) { // Ready to switch animations? - if ( HasWeaponIdleTimeElapsed() ) + if ( HasWeaponIdleTimeElapsed() ) { // Don't allow throw to attach switch unless in idle if (m_bClearReload) 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 @@ public: 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 @@ public: 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 9f7069833..436fae0d6 100644 --- a/mp/src/game/shared/hl2mp/weapon_stunstick.cpp +++ b/mp/src/game/shared/hl2mp/weapon_stunstick.cpp @@ -57,10 +57,7 @@ public: DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); - -#ifndef CLIENT_DLL DECLARE_ACTTABLE(); -#endif #ifdef CLIENT_DLL virtual int DrawModel( int flags ); @@ -68,7 +65,7 @@ public: virtual void OnDataChanged( DataUpdateType_t updateType ); virtual RenderGroup_t GetRenderGroup( void ); virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel ); - + virtual bool IsTransparent( void ); #endif virtual void Precache(); @@ -123,6 +120,9 @@ private: float m_flFadeTime; + //Tony; third person check thing, this has to be done for the local player if third person switches, so we can re-calc attachment points. + virtual void ThirdPersonSwitch( bool bThirdPerson ); + #endif CNetworkVar( bool, m_bActive ); @@ -149,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 @@ -447,6 +448,10 @@ void CWeaponStunStick::SetStunState( bool state ) bool CWeaponStunStick::Deploy( void ) { SetStunState( true ); +#ifdef CLIENT_DLL + //Tony; we need to just do this + SetupAttachmentPoints(); +#endif return BaseClass::Deploy(); } @@ -842,6 +847,10 @@ void C_WeaponStunStick::DrawFirstPersonEffects( void ) } } +void C_WeaponStunStick::ThirdPersonSwitch( bool bThirdPerson ) +{ + SetupAttachmentPoints(); +} //----------------------------------------------------------------------------- // Purpose: Draw our special effects //----------------------------------------------------------------------------- @@ -872,6 +881,13 @@ void C_WeaponStunStick::ViewModelDrawn( C_BaseViewModel *pBaseViewModel ) BaseClass::ViewModelDrawn( pBaseViewModel ); } +//----------------------------------------------------------------------------- +// Purpose: We are always considered transparent +//----------------------------------------------------------------------------- +bool C_WeaponStunStick::IsTransparent( void ) +{ + return true; +} //----------------------------------------------------------------------------- // Purpose: Draw a cheap glow quad at our impact point (with sparks) //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/filters.cpp b/sp/src/game/server/filters.cpp index 6179254dd..221a344a0 100644 --- a/sp/src/game/server/filters.cpp +++ b/sp/src/game/server/filters.cpp @@ -372,7 +372,8 @@ protected: bool PassesDamageFilterImpl(const CTakeDamageInfo &info) { - return info.GetDamageType() == m_iDamageType; + //Tony; these are bitflags. check them as so. + return ((info.GetDamageType() & m_iDamageType) == m_iDamageType); } int m_iDamageType;