5858#ifdef MAPBASE
5959#include " triggers.h"
6060#include " mapbase/variant_tools.h"
61+ #include " mapbase/protagonist_system.h"
6162#endif
6263
6364// memdbgon must be the last include file in a .cpp file!!!
@@ -593,6 +594,8 @@ BEGIN_DATADESC( CHL2_Player )
593594 DEFINE_INPUTFUNC( FIELD_VOID , " DisableGeigerCounter" , InputDisableGeigerCounter ),
594595 DEFINE_INPUTFUNC( FIELD_VOID , " ShowSquadHUD" , InputShowSquadHUD ),
595596 DEFINE_INPUTFUNC( FIELD_VOID , " HideSquadHUD" , InputHideSquadHUD ),
597+
598+ DEFINE_INPUTFUNC( FIELD_STRING , " SetProtagonist" , InputSetProtagonist ),
596599#endif
597600
598601 DEFINE_SOUNDPATCH ( m_sndLeeches ),
@@ -607,6 +610,10 @@ BEGIN_DATADESC( CHL2_Player )
607610
608611 DEFINE_FIELD( m_flTimeNextLadderHint, FIELD_TIME ),
609612
613+ #ifdef MAPBASE
614+ DEFINE_KEYFIELD ( m_iszProtagonistName, FIELD_STRING , " ProtagonistName" ),
615+ #endif
616+
610617 // DEFINE_FIELD( m_hPlayerProxy, FIELD_EHANDLE ), //Shut up class check!
611618
612619END_DATADESC ()
@@ -625,6 +632,9 @@ BEGIN_ENT_SCRIPTDESC( CHL2_Player, CBasePlayer, "The HL2 player entity." )
625632 DEFINE_SCRIPTFUNC( RemoveCustomSuitDevice, " Removes a custom suit device ID. (1-3)" )
626633 DEFINE_SCRIPTFUNC( IsCustomSuitDeviceActive, " Checks if a custom suit device is active." )
627634
635+ DEFINE_SCRIPTFUNC( GetProtagonistName, " Gets the player's protagonist name." )
636+ DEFINE_SCRIPTFUNC( SetProtagonist, " Sets the player's protagonist entry." )
637+
628638#ifdef SP_ANIM_STATE
629639 DEFINE_SCRIPTFUNC ( AddAnimStateLayer, " Adds a custom sequence index as a misc. layer for the singleplayer anim state, wtih parameters for blending in/out, setting the playback rate, holding the animation at the end, and only playing when the player is still." )
630640#endif
@@ -640,6 +650,10 @@ CHL2_Player::CHL2_Player()
640650
641651 m_flArmorReductionTime = 0 .0f ;
642652 m_iArmorReductionFrom = 0 ;
653+
654+ #ifdef MAPBASE
655+ m_nProtagonistIndex = -1 ;
656+ #endif
643657}
644658
645659//
@@ -674,6 +688,9 @@ CSuitPowerDevice SuitDeviceCustom[] =
674688IMPLEMENT_SERVERCLASS_ST (CHL2_Player, DT_HL2_Player)
675689 SendPropDataTable (SENDINFO_DT (m_HL2Local), &REFERENCE_SEND_TABLE(DT_HL2Local), SendProxy_SendLocalDataTable),
676690 SendPropBool( SENDINFO (m_fIsSprinting) ),
691+ #ifdef MAPBASE
692+ SendPropInt ( SENDINFO ( m_nProtagonistIndex ), 8, SPROP_UNSIGNED ),
693+ #endif
677694#ifdef SP_ANIM_STATE
678695 SendPropFloat ( SENDINFO (m_flAnimRenderYaw), 0, SPROP_NOSCALE ),
679696 SendPropFloat( SENDINFO (m_flAnimRenderZ), 0, SPROP_NOSCALE ),
@@ -1259,6 +1276,11 @@ void CHL2_Player::Activate( void )
12591276#endif
12601277
12611278 GetPlayerProxy ();
1279+
1280+ #ifdef MAPBASE
1281+ if (m_iszProtagonistName != NULL_STRING )
1282+ SetProtagonist ( STRING ( m_iszProtagonistName ) );
1283+ #endif
12621284}
12631285
12641286// ------------------------------------------------------------------------------
@@ -1500,6 +1522,8 @@ CStudioHdr *CHL2_Player::OnNewModel()
15001522extern char g_szDefaultPlayerModel[MAX_PATH ];
15011523extern bool g_bDefaultPlayerLegs;
15021524extern bool g_bDefaultPlayerDrawExternally;
1525+
1526+ extern char g_szDefaultProtagonist[MAX_PROTAGONIST_NAME ];
15031527#endif
15041528
15051529// -----------------------------------------------------------------------------
@@ -1533,6 +1557,9 @@ void CHL2_Player::Spawn(void)
15331557
15341558 SetDrawPlayerLegs ( g_bDefaultPlayerLegs );
15351559 SetDrawPlayerModelExternally ( g_bDefaultPlayerDrawExternally );
1560+
1561+ if (m_iszProtagonistName == NULL_STRING && *g_szDefaultProtagonist)
1562+ m_iszProtagonistName = MAKE_STRING ( g_szDefaultProtagonist );
15361563#endif
15371564
15381565 //
@@ -4087,6 +4114,10 @@ bool CHL2_Player::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex
40874114 StopZooming ();
40884115 }
40894116
4117+ #ifdef MAPBASE
4118+ RefreshProtagonistWeaponData ( pWeapon );
4119+ #endif
4120+
40904121 return BaseClass::Weapon_Switch ( pWeapon, viewmodelindex );
40914122}
40924123
@@ -4482,6 +4513,144 @@ bool CHL2_Player::IsCustomSuitDeviceActive( int iDeviceID )
44824513
44834514 return SuitPower_IsDeviceActive ( SuitDeviceCustom[iDeviceID] );
44844515}
4516+
4517+ // -----------------------------------------------------------------------------
4518+ // Purpose: Gets our protagonist name, if we have one
4519+ // -----------------------------------------------------------------------------
4520+ const char *CHL2_Player::GetProtagonistName () const
4521+ {
4522+ return STRING ( m_iszProtagonistName );
4523+ }
4524+
4525+ // -----------------------------------------------------------------------------
4526+ // Purpose: Gets our protagonist index, if we have one
4527+ // -----------------------------------------------------------------------------
4528+ int CHL2_Player::GetProtagonistIndex () const
4529+ {
4530+ return m_nProtagonistIndex;
4531+ }
4532+
4533+ // -----------------------------------------------------------------------------
4534+ // Purpose: Sets our protagonist to the specified entry
4535+ // -----------------------------------------------------------------------------
4536+ void CHL2_Player::InputSetProtagonist ( inputdata_t &inputdata )
4537+ {
4538+ SetProtagonist ( inputdata.value .String () );
4539+ }
4540+
4541+ // -----------------------------------------------------------------------------
4542+ // Purpose: Sets our protagonist to the specified entry
4543+ // -----------------------------------------------------------------------------
4544+ void CHL2_Player::SetProtagonist ( const char *pszProtagonist )
4545+ {
4546+ if (!pszProtagonist || !*pszProtagonist)
4547+ {
4548+ ResetProtagonist ();
4549+ return ;
4550+ }
4551+
4552+ int nIndex = g_ProtagonistSystem.FindProtagonistIndex ( pszProtagonist );
4553+ if (nIndex == -1 )
4554+ {
4555+ Warning ( " \" %s\" is not a valid protagonist\n " , pszProtagonist );
4556+ return ;
4557+ }
4558+
4559+ if (m_nProtagonistIndex != -1 )
4560+ {
4561+ // Flush any pre-existing data
4562+ ResetProtagonist ();
4563+ }
4564+
4565+ m_nProtagonistIndex = nIndex;
4566+ m_iszProtagonistName = AllocPooledString ( pszProtagonist );
4567+
4568+ RefreshProtagonistData ();
4569+ }
4570+
4571+ // -----------------------------------------------------------------------------
4572+ // Purpose: Resets protagonist data
4573+ // -----------------------------------------------------------------------------
4574+ void CHL2_Player::ResetProtagonist ()
4575+ {
4576+ SetModel ( g_szDefaultPlayerModel );
4577+ m_nSkin = 0 ;
4578+ m_nBody = 0 ;
4579+
4580+ CBaseViewModel *vm = GetViewModel ( 1 );
4581+ if (vm)
4582+ {
4583+ extern char g_szDefaultHandsModel[MAX_PATH ];
4584+ vm->SetWeaponModel ( g_szDefaultHandsModel, NULL );
4585+
4586+ vm->m_nSkin = 0 ;
4587+ vm->m_nBody = 0 ;
4588+ }
4589+
4590+ // RemoveContext will automatically remove contexts by name, regardless of how values are specified
4591+ char szContexts[128 ] = { 0 };
4592+ g_ProtagonistSystem.GetProtagonist_ResponseContexts ( this , szContexts, sizeof ( szContexts ) );
4593+ if (szContexts[0 ])
4594+ RemoveContext ( szContexts );
4595+
4596+ m_iszProtagonistName = NULL_STRING ;
4597+ m_nProtagonistIndex = -1 ;
4598+ }
4599+
4600+ // -----------------------------------------------------------------------------
4601+ // Purpose: Refreshes protagonist data
4602+ // -----------------------------------------------------------------------------
4603+ void CHL2_Player::RefreshProtagonistData ()
4604+ {
4605+ if (m_nProtagonistIndex == -1 )
4606+ return ;
4607+
4608+ g_ProtagonistSystem.PrecacheProtagonist ( this , m_nProtagonistIndex );
4609+
4610+ const char *pszProtagModel = g_ProtagonistSystem.GetProtagonist_PlayerModel ( this );
4611+ if (pszProtagModel)
4612+ SetModel ( pszProtagModel );
4613+
4614+ m_nSkin = g_ProtagonistSystem.GetProtagonist_PlayerModelSkin ( this );
4615+ m_nBody = g_ProtagonistSystem.GetProtagonist_PlayerModelBody ( this );
4616+
4617+ char szContexts[128 ] = { 0 };
4618+ g_ProtagonistSystem.GetProtagonist_ResponseContexts ( this , szContexts, sizeof ( szContexts ) );
4619+ if (szContexts[0 ])
4620+ AddContext ( szContexts );
4621+
4622+ RefreshProtagonistWeaponData ( GetActiveWeapon () );
4623+ }
4624+
4625+ // -----------------------------------------------------------------------------
4626+ // Purpose: Refreshes protagonist data
4627+ // -----------------------------------------------------------------------------
4628+ void CHL2_Player::RefreshProtagonistWeaponData ( CBaseCombatWeapon *pWeapon )
4629+ {
4630+ if (m_nProtagonistIndex == -1 )
4631+ return ;
4632+
4633+ CBaseViewModel *vm = GetViewModel ( 1 );
4634+ if (vm)
4635+ {
4636+ const char *pszHandModel = g_ProtagonistSystem.GetProtagonist_HandModel ( this , pWeapon );
4637+ if (pszHandModel)
4638+ {
4639+ vm->SetWeaponModel ( pszHandModel, NULL );
4640+
4641+ vm->m_nSkin = g_ProtagonistSystem.GetProtagonist_HandModelSkin ( this , pWeapon );
4642+ vm->m_nBody = g_ProtagonistSystem.GetProtagonist_HandModelBody ( this , pWeapon );
4643+ }
4644+ else
4645+ {
4646+ extern char g_szDefaultHandsModel[MAX_PATH ];
4647+ vm->SetWeaponModel ( g_szDefaultHandsModel, NULL );
4648+
4649+ vm->m_nSkin = 0 ;
4650+ vm->m_nBody = 0 ;
4651+ }
4652+ }
4653+ }
44854654#endif
44864655
44874656// -----------------------------------------------------------------------------
0 commit comments