diff --git a/src/game/client/c_baseviewmodel.cpp b/src/game/client/c_baseviewmodel.cpp index 07a1e71c6..40651cd85 100644 --- a/src/game/client/c_baseviewmodel.cpp +++ b/src/game/client/c_baseviewmodel.cpp @@ -19,6 +19,7 @@ #include #include "hltvcamera.h" #ifdef TF_CLIENT_DLL + #include "c_tf_player.h" #include "tf_weaponbase.h" #endif @@ -91,6 +92,24 @@ void FormatViewModelAttachment( Vector &vOrigin, bool bInverse ) vOrigin = pViewSetup->origin + vOut; } +#ifdef TF_CLIENT_DLL +bool TeamFortress_ShouldFlipClientViewModel( void ) +{ + bool bFlipViewModels = cl_flipviewmodels.GetBool(); + + if ( IsLocalPlayerSpectator() ) + { + // Use spectated client's handedness preference + C_TFPlayer *pSpecTarget = ToTFPlayer( UTIL_PlayerByIndex( GetSpectatorTarget() ) ); + if ( pSpecTarget ) + { + bFlipViewModels = pSpecTarget->m_bFlipViewModels; + } + } + + return bFlipViewModels; +} +#endif //TF_CLIENT_DLL void C_BaseViewModel::FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld ) { @@ -211,7 +230,7 @@ bool C_BaseViewModel::ShouldFlipViewModel() CBaseCombatWeapon *pWeapon = m_hWeapon.Get(); if ( pWeapon ) { - return pWeapon->m_bFlipViewModel != cl_flipviewmodels.GetBool(); + return pWeapon->m_bFlipViewModel != TeamFortress_ShouldFlipClientViewModel(); } #endif diff --git a/src/game/client/c_baseviewmodel.h b/src/game/client/c_baseviewmodel.h index fa59176da..2bc02945a 100644 --- a/src/game/client/c_baseviewmodel.h +++ b/src/game/client/c_baseviewmodel.h @@ -16,4 +16,8 @@ #include "utlvector.h" #include "baseviewmodel_shared.h" +#ifdef TF_CLIENT_DLL +bool TeamFortress_ShouldFlipClientViewModel( void ); +#endif //TF_CLIENT_DLL + #endif // C_BASEVIEWMODEL_H diff --git a/src/game/client/tf/c_tf_player.cpp b/src/game/client/tf/c_tf_player.cpp index 0c26a824a..7ad116699 100644 --- a/src/game/client/tf/c_tf_player.cpp +++ b/src/game/client/tf/c_tf_player.cpp @@ -3727,6 +3727,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_TFPlayer, DT_TFPlayer, CTFPlayer ) RecvPropFloat( RECVINFO( m_flMvMLastDamageTime ) ), RecvPropFloat( RECVINFO_NAME( m_flMvMLastDamageTime, "m_flLastDamageTime" ) ), // Renamed RecvPropInt( RECVINFO( m_iSpawnCounter ) ), + RecvPropBool( RECVINFO( m_bFlipViewModels ) ), RecvPropBool( RECVINFO( m_bArenaSpectator ) ), RecvPropDataTable( RECVINFO_DT( m_AttributeManager ), 0, &REFERENCE_RECV_TABLE(DT_AttributeManager) ), diff --git a/src/game/client/tf/c_tf_player.h b/src/game/client/tf/c_tf_player.h index 0fcee3730..e7e789007 100644 --- a/src/game/client/tf/c_tf_player.h +++ b/src/game/client/tf/c_tf_player.h @@ -662,6 +662,8 @@ public: int m_iSpawnCounter; bool m_bArenaSpectator; + bool m_bFlipViewModels; + bool m_bIsMiniBoss; bool m_bIsABot; int m_nBotSkill; diff --git a/src/game/server/tf/tf_player.cpp b/src/game/server/tf/tf_player.cpp index c0b4ddee1..c3f0a8dde 100644 --- a/src/game/server/tf/tf_player.cpp +++ b/src/game/server/tf/tf_player.cpp @@ -815,6 +815,7 @@ IMPLEMENT_SERVERCLASS_ST( CTFPlayer, DT_TFPlayer ) SendPropFloat( SENDINFO( m_flMvMLastDamageTime ), 16, SPROP_ROUNDUP ), SendPropInt( SENDINFO( m_iSpawnCounter ) ), + SendPropBool( SENDINFO( m_bFlipViewModels ) ), SendPropBool( SENDINFO( m_bArenaSpectator ) ), SendPropFloat( SENDINFO( m_flHeadScale ) ), SendPropFloat( SENDINFO( m_flTorsoScale ) ), diff --git a/src/game/server/tf/tf_player.h b/src/game/server/tf/tf_player.h index 224ddbeb0..67d4dabe0 100644 --- a/src/game/server/tf/tf_player.h +++ b/src/game/server/tf/tf_player.h @@ -982,7 +982,7 @@ public: int m_iOldStunFlags; - bool m_bFlipViewModels; + CNetworkVar( bool, m_bFlipViewModels ); int m_iBlastJumpState; float m_flBlastJumpLandTime; bool m_bTakenBlastDamageSinceLastMovement; diff --git a/src/game/shared/econ/econ_entity.cpp b/src/game/shared/econ/econ_entity.cpp index dd48f4c41..133a808be 100644 --- a/src/game/shared/econ/econ_entity.cpp +++ b/src/game/shared/econ/econ_entity.cpp @@ -20,6 +20,7 @@ #if defined(TF_CLIENT_DLL) #include "c_tf_player.h" +#include "c_baseviewmodel.h" #include "tf_gamerules.h" #include "c_playerresource.h" #include "tf_shareddefs.h" @@ -91,9 +92,6 @@ BEGIN_ENT_SCRIPTDESC( CEconEntity, CBaseAnimating, "Econ Entity" ) END_SCRIPTDESC(); #endif -#ifdef TF_CLIENT_DLL -extern ConVar cl_flipviewmodels; -#endif #ifdef CLIENT_DLL @@ -857,7 +855,7 @@ int C_ViewmodelAttachmentModel::InternalDrawModel( int flags ) { #ifdef TF_CLIENT_DLL CMatRenderContextPtr pRenderContext( materials ); - if ( cl_flipviewmodels.GetBool() != m_bAlwaysFlip ) + if ( TeamFortress_ShouldFlipClientViewModel() != m_bAlwaysFlip ) { pRenderContext->CullMode( MATERIAL_CULLMODE_CW ); } diff --git a/src/game/shared/tf/tf_weaponbase.cpp b/src/game/shared/tf/tf_weaponbase.cpp index 91741d7ad..d1a40dc67 100644 --- a/src/game/shared/tf/tf_weaponbase.cpp +++ b/src/game/shared/tf/tf_weaponbase.cpp @@ -48,6 +48,7 @@ // Client specific. #else #include "c_tf_player.h" +#include "c_baseviewmodel.h" #include "tf_viewmodel.h" #include "hud_crosshair.h" #include "c_tf_playerresource.h" @@ -91,7 +92,6 @@ extern ConVar tf_weapon_criticals_bucket_bottom; #ifdef CLIENT_DLL extern ConVar cl_crosshair_file; -extern ConVar cl_flipviewmodels; #endif //============================================================================= @@ -5594,7 +5594,7 @@ bool CTFWeaponBase::IsViewModelFlipped( void ) return true; } #else - if ( m_bFlipViewModel != cl_flipviewmodels.GetBool() ) + if ( m_bFlipViewModel != TeamFortress_ShouldFlipClientViewModel() ) { return true; } @@ -6775,7 +6775,7 @@ void CTFWeaponBase::AddStatTrakModel( CEconItemView *pItem, int nStatTrakType, A pStatTrakEnt->m_nSkin = nSkin; m_viewmodelStatTrakAddon = pStatTrakEnt; - if ( cl_flipviewmodels.GetBool() ) + if ( IsViewModelFlipped() ) { pStatTrakEnt->SetBodygroup( 1, 1 ); // use a special mirror-image stattrak module that appears correct for lefties flScale *= -1.0f; // flip scale