Add team value, MP fixes, and consolidated macros for protagonist system

This commit is contained in:
ALLEN-PC\acj30 2025-02-12 16:04:12 -06:00
parent ee756087f5
commit 2c189199fe
4 changed files with 180 additions and 138 deletions

View File

@ -81,6 +81,8 @@ C_BaseHLPlayer::C_BaseHLPlayer()
#ifdef MAPBASE #ifdef MAPBASE
ConVarRef scissor("r_flashlightscissor"); ConVarRef scissor("r_flashlightscissor");
scissor.SetValue("0"); scissor.SetValue("0");
m_nProtagonistIndex = -1;
#endif #endif
} }

View File

@ -4541,9 +4541,10 @@ void CHL2_Player::ResetProtagonist()
} }
// RemoveContext will automatically remove contexts by name, regardless of how values are specified // RemoveContext will automatically remove contexts by name, regardless of how values are specified
const char *pszProtagContexts = g_ProtagonistSystem.GetProtagonist_ResponseContexts( this ); char szContexts[128] = { 0 };
if (pszProtagContexts) g_ProtagonistSystem.GetProtagonist_ResponseContexts( this, szContexts, sizeof( szContexts ) );
RemoveContext( pszProtagContexts ); if (szContexts[0])
RemoveContext( szContexts );
m_iszProtagonistName = NULL_STRING; m_iszProtagonistName = NULL_STRING;
m_nProtagonistIndex = -1; m_nProtagonistIndex = -1;
@ -4566,9 +4567,10 @@ void CHL2_Player::RefreshProtagonistData()
m_nSkin = g_ProtagonistSystem.GetProtagonist_PlayerModelSkin( this ); m_nSkin = g_ProtagonistSystem.GetProtagonist_PlayerModelSkin( this );
m_nBody = g_ProtagonistSystem.GetProtagonist_PlayerModelBody( this ); m_nBody = g_ProtagonistSystem.GetProtagonist_PlayerModelBody( this );
const char *pszProtagContexts = g_ProtagonistSystem.GetProtagonist_ResponseContexts( this ); char szContexts[128] = { 0 };
if (pszProtagContexts) g_ProtagonistSystem.GetProtagonist_ResponseContexts( this, szContexts, sizeof( szContexts ) );
AddContext( pszProtagContexts ); if (szContexts[0])
AddContext( szContexts );
RefreshProtagonistWeaponData( GetActiveWeapon() ); RefreshProtagonistWeaponData( GetActiveWeapon() );
} }

View File

@ -11,6 +11,9 @@
#include "weapon_parse.h" #include "weapon_parse.h"
#include "filesystem.h" #include "filesystem.h"
#include "hl2_player_shared.h" #include "hl2_player_shared.h"
#ifdef HL2MP
#include "hl2mp_gamerules.h"
#endif
CProtagonistSystem g_ProtagonistSystem; CProtagonistSystem g_ProtagonistSystem;
@ -166,6 +169,28 @@ void CProtagonistSystem::LoadProtagonistFile( const char *pszFile )
{ {
pProtag->pszResponseContexts = AllocateString( pSubKey->GetString() ); pProtag->pszResponseContexts = AllocateString( pSubKey->GetString() );
} }
//----------------------------------------------------------------------------
// Multiplayer
//----------------------------------------------------------------------------
else if (FStrEq( pszSubKeyName, "team" ))
{
#ifdef HL2MP
if (FStrEq( pszSubKeyName, "combine" ))
{
pProtag->nTeam = TEAM_COMBINE;
}
else if (FStrEq( pszSubKeyName, "rebels" ))
{
pProtag->nTeam = TEAM_REBELS;
}
else
#endif
{
// Try to get a direct integer
pProtag->nTeam = atoi( pszSubKeyName );
}
}
#endif #endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Weapon Data // Weapon Data
@ -245,7 +270,7 @@ CProtagonistSystem::ProtagonistData_t *CProtagonistSystem::GetPlayerProtagonist(
return NULL; return NULL;
int i = pHL2Player->GetProtagonistIndex(); int i = pHL2Player->GetProtagonistIndex();
if (i >= 0) if (i >= 0 && i < m_Protagonists.Count())
{ {
return &g_ProtagonistSystem.m_Protagonists[i]; return &g_ProtagonistSystem.m_Protagonists[i];
} }
@ -287,6 +312,21 @@ int CProtagonistSystem::FindProtagonistIndex( const char *pszName )
return -1; return -1;
} }
const char *CProtagonistSystem::FindProtagonistByModel( const char *pszModelName )
{
#ifndef CLIENT_DLL
FOR_EACH_VEC( m_Protagonists, i )
{
if (m_Protagonists[i].pszPlayerModel && FStrEq( pszModelName, m_Protagonists[i].pszPlayerModel ))
{
return m_Protagonists[i].szName;
}
}
#endif
return NULL;
}
void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx ) void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx )
{ {
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
@ -323,85 +363,71 @@ void CProtagonistSystem::PrecacheProtagonist( CBaseEntity *pSource, int nIdx )
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#define GetProtagonistParam( funcName, ... ) \ #define GetProtagParamInner( name, ... ) DoGetProtagonist_##name( *pProtag, ##__VA_ARGS__ )
#define GetProtagParam( name, type, invoke, ... ) \
type CProtagonistSystem::GetProtagonist_##name( const CBasePlayer *pPlayer, ##__VA_ARGS__ ) \
{ \
ProtagonistData_t *pProtag = GetPlayerProtagonist( pPlayer ); \ ProtagonistData_t *pProtag = GetPlayerProtagonist( pPlayer ); \
if (!pProtag) \ if (!pProtag) \
return NULL; \ return NULL; \
return funcName( *pProtag, ##__VA_ARGS__ ); \ return invoke; \
} \
type CProtagonistSystem::GetProtagonist_##name( const int nProtagonistIndex, ##__VA_ARGS__ ) \
{ \
ProtagonistData_t *pProtag = FindProtagonist( nProtagonistIndex ); \
if (!pProtag) \
return NULL; \
return invoke; \
} \
#define GetProtagParamBody( name, type, invoke, body, ... ) \
type CProtagonistSystem::GetProtagonist_##name( const CBasePlayer *pPlayer, ##__VA_ARGS__ ) \
{ \
ProtagonistData_t *pProtag = GetPlayerProtagonist( pPlayer ); \
if (!pProtag) \
return NULL; \
type returnVal = invoke; \
body \
return returnVal; \
} \
type CProtagonistSystem::GetProtagonist_##name( const int nProtagonistIndex, ##__VA_ARGS__ ) \
{ \
ProtagonistData_t *pProtag = FindProtagonist( nProtagonistIndex ); \
if (!pProtag) \
return NULL; \
type returnVal = invoke; \
body \
return returnVal; \
} \
#ifdef CLIENT_DLL #ifdef CLIENT_DLL
#else #else
const char *CProtagonistSystem::GetProtagonist_PlayerModel( const CBasePlayer *pPlayer ) GetProtagParam( PlayerModel, const char*, GetProtagParamInner( PlayerModel ) )
{ GetProtagParam( PlayerModelSkin, int, GetProtagParamInner( PlayerModelSkin ) )
GetProtagonistParam( DoGetProtagonist_PlayerModel ) GetProtagParam( PlayerModelBody, int, GetProtagParamInner( PlayerModelBody ) )
} GetProtagParam( HandModel, const char*, GetProtagParamInner( HandModel, pWeapon ), const CBaseCombatWeapon *pWeapon )
GetProtagParam( HandModelSkin, int, GetProtagParamInner( HandModelSkin, pWeapon ), const CBaseCombatWeapon *pWeapon )
int CProtagonistSystem::GetProtagonist_PlayerModelSkin( const CBasePlayer *pPlayer ) GetProtagParam( HandModelBody, int, GetProtagParamInner( HandModelBody, pWeapon ), const CBaseCombatWeapon *pWeapon )
{ GetProtagParamBody( ResponseContexts, bool, GetProtagParamInner( ResponseContexts, pszContexts, nContextsSize ), {
GetProtagonistParam( DoGetProtagonist_PlayerModelSkin ) if (pszContexts[0] != '\0')
} {
int CProtagonistSystem::GetProtagonist_PlayerModelBody( const CBasePlayer *pPlayer )
{
GetProtagonistParam( DoGetProtagonist_PlayerModelBody )
}
const char *CProtagonistSystem::GetProtagonist_HandModel( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_HandModel, pWeapon )
}
int CProtagonistSystem::GetProtagonist_HandModelSkin( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_HandModelSkin, pWeapon )
}
int CProtagonistSystem::GetProtagonist_HandModelBody( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_HandModelBody, pWeapon )
}
const char *CProtagonistSystem::GetProtagonist_ResponseContexts( const CBasePlayer *pPlayer )
{
ProtagonistData_t *pProtag = g_ProtagonistSystem.GetPlayerProtagonist( pPlayer );
if (!pProtag)
return NULL;
// Collect contexts from base as well as parents
char szContexts[128] = { 0 };
g_ProtagonistSystem.DoGetProtagonist_ResponseContexts( *pProtag, szContexts, sizeof( szContexts ) );
// Replace trailing comma // Replace trailing comma
int nLast = V_strlen( szContexts )-1; int nLast = V_strlen( pszContexts )-1;
if (szContexts[nLast] == ',') if (pszContexts[nLast] == ',')
szContexts[nLast] = '\0'; {
Msg( "Removing trailing comma from \"%s\"\n", pszContexts );
if (!szContexts[0]) pszContexts[nLast] = '\0';
return NULL; }
}
return AllocateString( szContexts ); }, char *pszContexts, int nContextsSize )
} GetProtagParam( Team, int, GetProtagParamInner( Team ) )
#endif #endif
const char *CProtagonistSystem::GetProtagonist_ViewModel( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon ) GetProtagParam( ViewModel, const char*, GetProtagParamInner( ViewModel, pWeapon ), const CBaseCombatWeapon *pWeapon )
{ GetProtagParam( ViewModelFOV, float*, GetProtagParamInner( ViewModelFOV, pWeapon ), const CBaseCombatWeapon *pWeapon )
GetProtagonistParam( DoGetProtagonist_ViewModel, pWeapon ) GetProtagParam( UsesHands, bool*, GetProtagParamInner( UsesHands, pWeapon ), const CBaseCombatWeapon *pWeapon )
} GetProtagParam( HandRig, int*, GetProtagParamInner( HandRig, pWeapon ), const CBaseCombatWeapon *pWeapon )
float *CProtagonistSystem::GetProtagonist_ViewModelFOV( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_ViewModelFOV, pWeapon )
}
bool *CProtagonistSystem::GetProtagonist_UsesHands( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_UsesHands, pWeapon )
}
int *CProtagonistSystem::GetProtagonist_HandRig( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon )
{
GetProtagonistParam( DoGetProtagonist_HandRig, pWeapon )
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -494,7 +520,7 @@ int CProtagonistSystem::DoGetProtagonist_HandModelBody( ProtagonistData_t &pProt
return NULL; return NULL;
} }
void CProtagonistSystem::DoGetProtagonist_ResponseContexts( ProtagonistData_t &pProtag, char *pszContexts, int nContextsSize ) bool CProtagonistSystem::DoGetProtagonist_ResponseContexts( ProtagonistData_t &pProtag, char *pszContexts, int nContextsSize )
{ {
if (pProtag.pszResponseContexts) if (pProtag.pszResponseContexts)
{ {
@ -504,6 +530,19 @@ void CProtagonistSystem::DoGetProtagonist_ResponseContexts( ProtagonistData_t &p
// Recursively search parent protagonists // Recursively search parent protagonists
GetProtagonistRecurseNoReturn( DoGetProtagonist_ResponseContexts, pszContexts, nContextsSize ) GetProtagonistRecurseNoReturn( DoGetProtagonist_ResponseContexts, pszContexts, nContextsSize )
return pszContexts[0] != '\0';
}
int CProtagonistSystem::DoGetProtagonist_Team( ProtagonistData_t &pProtag )
{
if (pProtag.nTeam >= -1)
return pProtag.nTeam;
// Recursively search parent protagonists
GetProtagonistRecurse( DoGetProtagonist_Team )
return TEAM_ANY;
} }
#endif #endif

View File

@ -28,47 +28,6 @@ public:
CProtagonistSystem() : m_Strings( 256, 0, &StringLessThan ) { } CProtagonistSystem() : m_Strings( 256, 0, &StringLessThan ) { }
~CProtagonistSystem() { PurgeProtagonists(); } ~CProtagonistSystem() { PurgeProtagonists(); }
bool Init();
void Shutdown();
void LevelInitPreEntity();
void LevelShutdownPostEntity();
//----------------------------------------------------------------------------
void LoadProtagonistManifest( const char *pszFile );
void LoadProtagonistFile( const char *pszFile );
//----------------------------------------------------------------------------
int FindProtagonistIndex( const char *pszName );
void PrecacheProtagonist( CBaseEntity *pSource, int nIdx );
//----------------------------------------------------------------------------
#ifdef CLIENT_DLL
#else
const char *GetProtagonist_PlayerModel( const CBasePlayer *pPlayer );
int GetProtagonist_PlayerModelSkin( const CBasePlayer *pPlayer );
int GetProtagonist_PlayerModelBody( const CBasePlayer *pPlayer );
const char *GetProtagonist_HandModel( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
int GetProtagonist_HandModelSkin( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
int GetProtagonist_HandModelBody( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
const char *GetProtagonist_ResponseContexts( const CBasePlayer *pPlayer );
#endif
const char *GetProtagonist_ViewModel( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
float *GetProtagonist_ViewModelFOV( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
bool *GetProtagonist_UsesHands( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
int *GetProtagonist_HandRig( const CBasePlayer *pPlayer, const CBaseCombatWeapon *pWeapon );
//----------------------------------------------------------------------------
void PurgeProtagonists();
void PrintProtagonistData();
//----------------------------------------------------------------------------
private: private:
struct ProtagonistData_t struct ProtagonistData_t
@ -96,6 +55,9 @@ private:
// Responses // Responses
const char *pszResponseContexts = NULL; const char *pszResponseContexts = NULL;
// Multiplayer
int nTeam = TEAM_ANY;
#endif #endif
// Weapon Data // Weapon Data
@ -110,27 +72,64 @@ private:
CUtlDict<WeaponDataOverride_t> dictWpnData; CUtlDict<WeaponDataOverride_t> dictWpnData;
}; };
public:
bool Init();
void Shutdown();
void LevelInitPreEntity();
void LevelShutdownPostEntity();
//----------------------------------------------------------------------------
void LoadProtagonistManifest( const char *pszFile );
void LoadProtagonistFile( const char *pszFile );
//----------------------------------------------------------------------------
int FindProtagonistIndex( const char *pszName );
const char *FindProtagonistByModel( const char *pszModelName );
void PrecacheProtagonist( CBaseEntity *pSource, int nIdx );
//----------------------------------------------------------------------------
#define DeclareProtagonistFunc(type, name, ...) \
type GetProtagonist_##name( const CBasePlayer *pPlayer, ##__VA_ARGS__ ); \
type GetProtagonist_##name( const int nProtagonistIndex, ##__VA_ARGS__ ); \
private: \
type DoGetProtagonist_##name( ProtagonistData_t &pProtag, ##__VA_ARGS__ ); \
public: \
#ifdef CLIENT_DLL
#else
DeclareProtagonistFunc( const char*, PlayerModel )
DeclareProtagonistFunc( int, PlayerModelSkin )
DeclareProtagonistFunc( int, PlayerModelBody )
DeclareProtagonistFunc( const char*, HandModel, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( int, HandModelSkin, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( int, HandModelBody, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( bool, ResponseContexts, char *pszContexts, int nContextsSize )
DeclareProtagonistFunc( int, Team )
#endif
DeclareProtagonistFunc( const char*, ViewModel, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( float*, ViewModelFOV, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( bool*, UsesHands, const CBaseCombatWeapon *pWeapon )
DeclareProtagonistFunc( int*, HandRig, const CBaseCombatWeapon *pWeapon )
//----------------------------------------------------------------------------
void PurgeProtagonists();
void PrintProtagonistData();
//----------------------------------------------------------------------------
private:
ProtagonistData_t *GetPlayerProtagonist( const CBasePlayer *pPlayer ); ProtagonistData_t *GetPlayerProtagonist( const CBasePlayer *pPlayer );
ProtagonistData_t *FindProtagonist( const char *pszName ); ProtagonistData_t *FindProtagonist( const char *pszName );
ProtagonistData_t *FindProtagonist( int nIndex ); ProtagonistData_t *FindProtagonist( int nIndex );
// For recursion
#ifdef CLIENT_DLL
#else
const char *DoGetProtagonist_PlayerModel( ProtagonistData_t &pProtag );
int DoGetProtagonist_PlayerModelSkin( ProtagonistData_t &pProtag );
int DoGetProtagonist_PlayerModelBody( ProtagonistData_t &pProtag );
const char *DoGetProtagonist_HandModel( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
int DoGetProtagonist_HandModelSkin( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
int DoGetProtagonist_HandModelBody( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
void DoGetProtagonist_ResponseContexts( ProtagonistData_t &pProtag, char *pszContexts, int nContextsSize );
#endif
const char *DoGetProtagonist_ViewModel( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
float *DoGetProtagonist_ViewModelFOV( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
bool *DoGetProtagonist_UsesHands( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
int *DoGetProtagonist_HandRig( ProtagonistData_t &pProtag, const CBaseCombatWeapon *pWeapon );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const char *FindString( const char *string ); const char *FindString( const char *string );