diff --git a/sp/src/game/server/hl2/hl2_player.cpp b/sp/src/game/server/hl2/hl2_player.cpp index 1c5ed71d17d..298ff09dd2f 100644 --- a/sp/src/game/server/hl2/hl2_player.cpp +++ b/sp/src/game/server/hl2/hl2_player.cpp @@ -634,6 +634,8 @@ BEGIN_DATADESC( CHL2_Player ) DEFINE_FIELD( m_flNextKickAttack , FIELD_TIME ), DEFINE_FIELD( m_bKickWeaponLowered, FIELD_BOOLEAN ), DEFINE_FIELD( m_LegModelName, FIELD_STRING ), + DEFINE_FIELD( m_nLegSkin, FIELD_INTEGER ), + DEFINE_FIELD( m_nLegBody, FIELD_INTEGER ), #endif DEFINE_FIELD( m_flTimeIgnoreFallDamage, FIELD_TIME ), @@ -5057,6 +5059,8 @@ void CHL2_Player::StartKickAnimation( void ) if ( vm ) { vm->SetWeaponModel( STRING( m_LegModelName ), NULL ); + vm->m_nSkin = m_nLegSkin; + vm->m_nBody = m_nLegBody; int idealSequence = vm->SelectWeightedSequence( ACT_VM_PRIMARYATTACK ); @@ -5379,6 +5383,12 @@ void CHL2_Player::ResetProtagonist() vm->m_nBody = 0; } +#ifdef EZ2 + m_LegModelName = AllocPooledString( sv_player_kick_default_modelname.GetString() ); + m_nLegSkin = 0; + m_nLegBody = 0; +#endif + // RemoveContext will automatically remove contexts by name, regardless of how values are specified char szContexts[128] = { 0 }; g_ProtagonistSystem.GetProtagonist_ResponseContexts( this, szContexts, sizeof( szContexts ) ); @@ -5406,6 +5416,15 @@ void CHL2_Player::RefreshProtagonistData() m_nSkin = g_ProtagonistSystem.GetProtagonist_PlayerModelSkin( this ); m_nBody = g_ProtagonistSystem.GetProtagonist_PlayerModelBody( this ); +#ifdef EZ2 + const char *pszLegModel = g_ProtagonistSystem.GetProtagonist_LegModel( this ); + if (pszLegModel) + m_LegModelName = MAKE_STRING( pszLegModel ); + + m_nLegSkin = g_ProtagonistSystem.GetProtagonist_LegModelSkin( this ); + m_nLegBody = g_ProtagonistSystem.GetProtagonist_LegModelBody( this ); +#endif + char szContexts[128] = { 0 }; g_ProtagonistSystem.GetProtagonist_ResponseContexts( this, szContexts, sizeof( szContexts ) ); if (szContexts[0]) diff --git a/sp/src/game/server/hl2/hl2_player.h b/sp/src/game/server/hl2/hl2_player.h index 6138ad8365d..8d24f527b5e 100644 --- a/sp/src/game/server/hl2/hl2_player.h +++ b/sp/src/game/server/hl2/hl2_player.h @@ -493,6 +493,8 @@ class CHL2_Player : public CBasePlayer bool m_bKickWeaponLowered; string_t m_LegModelName; + int m_nLegSkin; + int m_nLegBody; #endif // Aiming heuristics code diff --git a/sp/src/game/shared/mapbase/protagonist_system.cpp b/sp/src/game/shared/mapbase/protagonist_system.cpp index b4eb1313578..c4089cf0029 100644 --- a/sp/src/game/shared/mapbase/protagonist_system.cpp +++ b/sp/src/game/shared/mapbase/protagonist_system.cpp @@ -14,6 +14,9 @@ #ifdef HL2MP #include "hl2mp_gamerules.h" #endif +#ifdef EZ2 +#include "basehlcombatweapon_shared.h" +#endif CProtagonistSystem g_ProtagonistSystem; @@ -162,6 +165,31 @@ void CProtagonistSystem::LoadProtagonistFile( const char *pszFile ) } } +#ifdef EZ2 + //---------------------------------------------------------------------------- + // Leg + //---------------------------------------------------------------------------- + else if (V_strnicmp( pszSubKeyName, "leg", 3 ) == 0) + { + pszSubKeyName += 3; + if (!pszSubKeyName[0] || pszSubKeyName[0] == 's') + { + // Model + pProtag->pszLegModel = AllocateString( pSubKey->GetString() ); + } + else if (FStrEq( pszSubKeyName, "_skin" )) + { + // Skin + pProtag->nLegSkin = pSubKey->GetInt(); + } + else if (FStrEq( pszSubKeyName, "_body" )) + { + // Bodygroup + pProtag->nLegBody = pSubKey->GetInt(); + } + } +#endif + //---------------------------------------------------------------------------- // Responses //---------------------------------------------------------------------------- @@ -222,6 +250,12 @@ void CProtagonistSystem::LoadProtagonistFile( const char *pszFile ) if (pszVM) pProtag->dictWpnData[i].pszVM = AllocateString( pszVM ); +#ifdef EZ2 + pszVM = pWeaponKey->GetString( "viewmodel_dual", NULL ); + if (pszVM) + pProtag->dictWpnData[i].pszDualVM = AllocateString( pszVM ); +#endif + const char *pszHandRig = pWeaponKey->GetString( "hand_rig", NULL ); if (pszHandRig) { @@ -356,6 +390,14 @@ void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx ) } } +#ifdef EZ2 + // Legs + if (pProtag.pszLegModel) + { + pSource->PrecacheModel( pProtag.pszLegModel ); + } +#endif + // Weapon Data FOR_EACH_DICT_FAST( pProtag.dictWpnData, i ) { @@ -363,6 +405,13 @@ void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx ) { pSource->PrecacheModel( pProtag.dictWpnData[i].pszVM ); } + +#ifdef EZ2 + if (pProtag.dictWpnData[i].pszDualVM) + { + pSource->PrecacheModel( pProtag.dictWpnData[i].pszDualVM ); + } +#endif } CBaseEntity::SetAllowPrecache( false ); @@ -425,6 +474,11 @@ GetProtagParam( PlayerModelBody, int, GetProtagParamInner( PlayerModelBody ) GetProtagParam( HandModel, const char*, GetProtagParamInner( HandModel, pWeapon ), const CBaseCombatWeapon *pWeapon ) GetProtagParam( HandModelSkin, int, GetProtagParamInner( HandModelSkin, pWeapon ), const CBaseCombatWeapon *pWeapon ) GetProtagParam( HandModelBody, int, GetProtagParamInner( HandModelBody, pWeapon ), const CBaseCombatWeapon *pWeapon ) +#ifdef EZ2 +GetProtagParam( LegModel, const char*, GetProtagParamInner( LegModel ) ) +GetProtagParam( LegModelSkin, int, GetProtagParamInner( LegModelSkin ) ) +GetProtagParam( LegModelBody, int, GetProtagParamInner( LegModelBody ) ) +#endif GetProtagParamBody( ResponseContexts, bool, GetProtagParamInner( ResponseContexts, pszContexts, nContextsSize ), { if (pszContexts[0] != '\0') { @@ -535,6 +589,41 @@ int CProtagonistSystem::DoGetProtagonist_HandModelBody( ProtagonistData_t &pProt return NULL; } +#ifdef EZ2 +const char *CProtagonistSystem::DoGetProtagonist_LegModel( ProtagonistData_t &pProtag ) +{ + if (pProtag.pszLegModel != NULL) + return pProtag.pszLegModel; + + // Recursively search parent protagonists + GetProtagonistRecurse( DoGetProtagonist_LegModel ) + + return NULL; +} + +int CProtagonistSystem::DoGetProtagonist_LegModelSkin( ProtagonistData_t &pProtag ) +{ + if (pProtag.nLegSkin >= 0) + return pProtag.nLegSkin; + + // Recursively search parent protagonists + GetProtagonistRecurse( DoGetProtagonist_LegModelSkin ) + + return NULL; +} + +int CProtagonistSystem::DoGetProtagonist_LegModelBody( ProtagonistData_t &pProtag ) +{ + if (pProtag.nLegBody >= 0) + return pProtag.nLegBody; + + // Recursively search parent protagonists + GetProtagonistRecurse( DoGetProtagonist_LegModelBody ) + + return NULL; +} +#endif + bool CProtagonistSystem::DoGetProtagonist_ResponseContexts( ProtagonistData_t &pProtag, char *pszContexts, int nContextsSize ) { if (pProtag.pszResponseContexts) @@ -569,6 +658,14 @@ const char *CProtagonistSystem::DoGetProtagonist_ViewModel( ProtagonistData_t &p if (!FStrEq( pProtag.dictWpnData.GetElementName( i ), const_cast(pWeapon)->GetClassname() )) continue; +#ifdef EZ2 + // Protagonist override code is currently handled in CBaseHLCombatWeapon, so a static cast is safe. + // Please change this if protagonist overrides are extended to other classes. + const CBaseHLCombatWeapon *pHLWeapon = assert_cast(pWeapon); + if (pHLWeapon && pHLWeapon->GetLeftHandGun() && pProtag.dictWpnData[i].pszDualVM) + return pProtag.dictWpnData[i].pszDualVM; +#endif + if (pProtag.dictWpnData[i].pszVM) return pProtag.dictWpnData[i].pszVM; break; @@ -708,6 +805,11 @@ void CProtagonistSystem::PrintProtagonistData() Msg( "\t\tHand %s model: \"%s\" (%i, %i)\n", pHandRigs[j], pProtag.pszHandModels[j], pProtag.nPlayerSkin, pProtag.nPlayerBody ); } +#ifdef EZ2 + if (pProtag.pszLegModel) + Msg( "\t\t\t\tLeg model: \"%s\" (%i, %i)\n", pProtag.pszLegModel, pProtag.nLegSkin, pProtag.nLegBody ); +#endif + // Weapon Data Msg( "\t\tWeapon Data: %i\n", pProtag.dictWpnData.Count() ); FOR_EACH_DICT_FAST( pProtag.dictWpnData, j ) @@ -716,6 +818,11 @@ void CProtagonistSystem::PrintProtagonistData() if (pProtag.dictWpnData[j].pszVM) Msg( "\t\t\t\tViewmodel: \"%s\"\n", pProtag.dictWpnData[j].pszVM ); +#ifdef EZ2 + if (pProtag.dictWpnData[j].pszDualVM) + Msg( "\t\t\t\tDual Viewmodel: \"%s\"\n", pProtag.dictWpnData[j].pszDualVM ); +#endif + Msg( "\t\t\t\tUses hands: %d, hand rig: %i\n", pProtag.dictWpnData[j].bUsesHands, pProtag.dictWpnData[j].nHandRig ); } #endif diff --git a/sp/src/game/shared/mapbase/protagonist_system.h b/sp/src/game/shared/mapbase/protagonist_system.h index e678bc90baf..e5b46c92716 100644 --- a/sp/src/game/shared/mapbase/protagonist_system.h +++ b/sp/src/game/shared/mapbase/protagonist_system.h @@ -56,6 +56,13 @@ class CProtagonistSystem : public CAutoGameSystem int nHandSkin = -1; int nHandBody = -1; +#ifdef EZ2 + // Leg + const char *pszLegModel = NULL; + int nLegSkin = -1; + int nLegBody = -1; +#endif + // Responses const char *pszResponseContexts = NULL; @@ -70,6 +77,9 @@ class CProtagonistSystem : public CAutoGameSystem struct WeaponDataOverride_t { const char *pszVM = NULL; +#ifdef EZ2 + const char *pszDualVM = NULL; +#endif bool bUsesHands = false; int nHandRig = 0; float flVMFOV = 0.0f; @@ -114,6 +124,11 @@ class CProtagonistSystem : public CAutoGameSystem DeclareProtagonistFunc( const char*, HandModel, const CBaseCombatWeapon *pWeapon ) DeclareProtagonistFunc( int, HandModelSkin, const CBaseCombatWeapon *pWeapon ) DeclareProtagonistFunc( int, HandModelBody, const CBaseCombatWeapon *pWeapon ) +#ifdef EZ2 + DeclareProtagonistFunc( const char*, LegModel ) + DeclareProtagonistFunc( int, LegModelSkin ) + DeclareProtagonistFunc( int, LegModelBody ) +#endif DeclareProtagonistFunc( bool, ResponseContexts, char *pszContexts, int nContextsSize ) DeclareProtagonistFunc( int, Team ) #endif