From dbb0ed6f469c95c4d541a9f076eafffe8cbd9d16 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Tue, 8 Mar 2022 19:25:55 -0600 Subject: [PATCH] Added gameinfo keyvalues for default hands models + code to hide custom hands on weapons which don't support them --- sp/src/game/server/player.cpp | 13 ++++ sp/src/game/shared/baseviewmodel_shared.cpp | 66 ++++++++++++++++--- sp/src/game/shared/mapbase/mapbase_shared.cpp | 8 +++ 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/sp/src/game/server/player.cpp b/sp/src/game/server/player.cpp index d713a8c3..6c78a3b5 100644 --- a/sp/src/game/server/player.cpp +++ b/sp/src/game/server/player.cpp @@ -632,6 +632,10 @@ void CBasePlayer::DestroyViewModels( void ) } #ifdef MAPBASE +extern char g_szDefaultHandsModel[MAX_PATH]; +extern int g_iDefaultHandsSkin; +extern int g_iDefaultHandsBody; + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -648,6 +652,11 @@ void CBasePlayer::CreateHandModel(int index, int iOtherVm) vm->SetAbsOrigin(GetAbsOrigin()); vm->SetOwner(this); vm->SetIndex(index); + + vm->SetModel( g_szDefaultHandsModel ); + vm->m_nSkin = g_iDefaultHandsSkin; + vm->m_nBody = g_iDefaultHandsBody; + DispatchSpawn(vm); vm->FollowEntity(GetViewModel(iOtherVm), true); m_hViewModel.Set(index, vm); @@ -5418,6 +5427,10 @@ void CBasePlayer::Precache( void ) m_iTrain = TRAIN_NEW; #endif +#ifdef MAPBASE + PrecacheModel( g_szDefaultHandsModel ); +#endif + m_iClientBattery = -1; m_iUpdateTime = 5; // won't update for 1/2 a second diff --git a/sp/src/game/shared/baseviewmodel_shared.cpp b/sp/src/game/shared/baseviewmodel_shared.cpp index 7c4a4013..aa8ddbae 100644 --- a/sp/src/game/shared/baseviewmodel_shared.cpp +++ b/sp/src/game/shared/baseviewmodel_shared.cpp @@ -290,12 +290,15 @@ void CBaseViewModel::AddEffects( int nEffects ) } #ifdef MAPBASE - // Apply effect changes to any viewmodel children as well - // (fixes hand models) - for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + if (GetOwningWeapon() && GetOwningWeapon()->UsesHands()) { - if (pChild->GetClassname()[0] == 'h') - pChild->AddEffects( nEffects ); + // If using hands, apply effect changes to any viewmodel children as well + // (fixes hand models) + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + pChild->AddEffects( nEffects ); + } } #endif @@ -313,12 +316,15 @@ void CBaseViewModel::RemoveEffects( int nEffects ) } #ifdef MAPBASE - // Apply effect changes to any viewmodel children as well - // (fixes hand models) - for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + if (GetOwningWeapon() && GetOwningWeapon()->UsesHands()) { - if (pChild->GetClassname()[0] == 'h') - pChild->RemoveEffects( nEffects ); + // If using hands, apply effect changes to any viewmodel children as well + // (fixes hand models) + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + pChild->RemoveEffects( nEffects ); + } } #endif @@ -359,6 +365,18 @@ void CBaseViewModel::SetWeaponModel( const char *modelname, CBaseCombatWeapon *w SetControlPanelsActive( showControlPanels ); } #endif + +#ifdef MAPBASE + // If our owning weapon doesn't support hands, disable the hands viewmodel(s) + bool bSupportsHands = weapon->UsesHands(); + for (CBaseEntity *pChild = FirstMoveChild(); pChild != NULL; pChild = pChild->NextMovePeer()) + { + if (pChild->GetClassname()[0] == 'h') + { + bSupportsHands ? pChild->RemoveEffects( EF_NODRAW ) : pChild->AddEffects( EF_NODRAW ); + } + } +#endif } //----------------------------------------------------------------------------- @@ -754,7 +772,13 @@ class CHandViewModel : public CBaseViewModel DECLARE_CLASS( CHandViewModel, CBaseViewModel ); public: DECLARE_NETWORKCLASS(); + + CBaseViewModel *GetVMOwner(); + + CBaseCombatWeapon *GetOwningWeapon( void ); + private: + CHandle m_hVMOwner; }; LINK_ENTITY_TO_CLASS(hand_viewmodel, CHandViewModel); @@ -770,4 +794,26 @@ BEGIN_NETWORK_TABLE(CHandViewModel, DT_HandViewModel) RecvPropInt(RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent), #endif END_NETWORK_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseViewModel *CHandViewModel::GetVMOwner() +{ + if (!m_hVMOwner) + m_hVMOwner = assert_cast(GetMoveParent()); + return m_hVMOwner; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBaseCombatWeapon *CHandViewModel::GetOwningWeapon() +{ + CBaseViewModel *pVM = GetVMOwner(); + if (pVM) + return pVM->GetOwningWeapon(); + else + return NULL; +} #endif diff --git a/sp/src/game/shared/mapbase/mapbase_shared.cpp b/sp/src/game/shared/mapbase/mapbase_shared.cpp index 8550b6dc..fd4825de 100644 --- a/sp/src/game/shared/mapbase/mapbase_shared.cpp +++ b/sp/src/game/shared/mapbase/mapbase_shared.cpp @@ -86,6 +86,10 @@ char g_iszGameName[128]; // Default player configuration char g_szDefaultPlayerModel[MAX_PATH]; bool g_bDefaultPlayerDrawExternally; + +char g_szDefaultHandsModel[MAX_PATH]; +int g_iDefaultHandsSkin; +int g_iDefaultHandsBody; #endif enum @@ -226,6 +230,10 @@ public: #ifdef GAME_DLL Q_strncpy( g_szDefaultPlayerModel, gameinfo->GetString( "player_default_model", "models/player.mdl" ), sizeof( g_szDefaultPlayerModel ) ); g_bDefaultPlayerDrawExternally = gameinfo->GetBool( "player_default_draw_externally", false ); + + Q_strncpy( g_szDefaultHandsModel, gameinfo->GetString( "player_default_hands", "models/weapons/v_hands.mdl" ), sizeof( g_szDefaultHandsModel ) ); + g_iDefaultHandsSkin = gameinfo->GetInt( "player_default_hands_skin", 0 ); + g_iDefaultHandsBody = gameinfo->GetInt( "player_default_hands_body", 0 ); #endif } gameinfo->deleteThis();