Skip to content

Commit 51afe93

Browse files
authored
Merge pull request #377 from Blixibon/mapbase/feature/protagonist-system
HL2 player character switching system
2 parents af66f2b + 940745c commit 51afe93

16 files changed

Lines changed: 1226 additions & 3 deletions

sp/src/game/client/client_mapbase.vpc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ $Project
4949
$File "$SRCDIR\game\shared\mapbase\matchers.h"
5050
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.cpp"
5151
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.h"
52+
$File "$SRCDIR\game\shared\mapbase\protagonist_system.cpp"
53+
$File "$SRCDIR\game\shared\mapbase\protagonist_system.h"
5254
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
5355
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
5456
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]

sp/src/game/client/hl2/c_basehlplayer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDL
3131
IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
3232
RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
3333
RecvPropBool( RECVINFO( m_fIsSprinting ) ),
34+
#ifdef MAPBASE
35+
RecvPropInt( RECVINFO( m_nProtagonistIndex ) ),
36+
#endif
3437
#ifdef SP_ANIM_STATE
3538
RecvPropFloat( RECVINFO( m_flAnimRenderYaw ) ),
3639
RecvPropFloat( RECVINFO( m_flAnimRenderZ ) ),
@@ -79,6 +82,8 @@ C_BaseHLPlayer::C_BaseHLPlayer()
7982
#ifdef MAPBASE
8083
ConVarRef scissor("r_flashlightscissor");
8184
scissor.SetValue("0");
85+
86+
m_nProtagonistIndex = -1;
8287
#endif
8388
}
8489

sp/src/game/client/hl2/c_basehlplayer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class C_BaseHLPlayer : public C_BasePlayer
6363

6464
bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; }
6565

66+
#ifdef MAPBASE
67+
int GetProtagonistIndex() const { return m_nProtagonistIndex; }
68+
#endif
69+
6670
#ifdef SP_ANIM_STATE
6771
virtual const Vector& GetRenderOrigin();
6872
virtual const QAngle& GetRenderAngles( void );
@@ -89,6 +93,10 @@ class C_BaseHLPlayer : public C_BasePlayer
8993
bool m_bPlayUseDenySound; // Signaled by PlayerUse, but can be unset by HL2 ladder code...
9094
float m_flSpeedMod;
9195
float m_flExitSpeedMod;
96+
97+
#ifdef MAPBASE
98+
int m_nProtagonistIndex;
99+
#endif
92100

93101
#ifdef MAPBASE_MP
94102
CSinglePlayerAnimState *m_pPlayerAnimState;

sp/src/game/server/hl2/hl2_player.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
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

612619
END_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[] =
674688
IMPLEMENT_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()
15001522
extern char g_szDefaultPlayerModel[MAX_PATH];
15011523
extern bool g_bDefaultPlayerLegs;
15021524
extern 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
//-----------------------------------------------------------------------------

sp/src/game/server/hl2/hl2_player.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,15 @@ class CHL2_Player : public CBasePlayer
358358
void AddCustomSuitDevice( int iDeviceID );
359359
void RemoveCustomSuitDevice( int iDeviceID );
360360
bool IsCustomSuitDeviceActive( int iDeviceID );
361+
362+
// Protagonist system
363+
const char *GetProtagonistName() const;
364+
int GetProtagonistIndex() const;
365+
void InputSetProtagonist( inputdata_t &inputdata );
366+
void SetProtagonist( const char *pszProtagonist );
367+
void ResetProtagonist();
368+
void RefreshProtagonistData();
369+
void RefreshProtagonistWeaponData( CBaseCombatWeapon *pWeapon );
361370
#endif
362371

363372
CSoundPatch *m_sndLeeches;
@@ -442,6 +451,12 @@ class CHL2_Player : public CBasePlayer
442451

443452
friend class CHL2GameMovement;
444453

454+
#ifdef MAPBASE
455+
// Protagonist used by protagonist_system.h
456+
string_t m_iszProtagonistName;
457+
CNetworkVar( int, m_nProtagonistIndex );
458+
#endif
459+
445460
#ifdef SP_ANIM_STATE
446461
CMapbasePlayerAnimState* m_pPlayerAnimState;
447462

sp/src/game/server/player.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4475,6 +4475,11 @@ void CBasePlayer::SetSuitUpdate(const char *name, int fgroup, int iNoRepeatTime)
44754475
return;
44764476
}
44774477

4478+
#ifdef MAPBASE
4479+
if ( HasContext("silent_suit", "1") )
4480+
return;
4481+
#endif
4482+
44784483
// if name == NULL, then clear out the queue
44794484

44804485
if (!name)

sp/src/game/server/server_mapbase.vpc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ $Project
4848
$File "$SRCDIR\game\shared\mapbase\matchers.h"
4949
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.cpp"
5050
$File "$SRCDIR\game\shared\mapbase\mapbase_playeranimstate.h"
51+
$File "$SRCDIR\game\shared\mapbase\protagonist_system.cpp"
52+
$File "$SRCDIR\game\shared\mapbase\protagonist_system.h"
5153
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.cpp" [$MAPBASE_VSCRIPT]
5254
$File "$SRCDIR\game\shared\mapbase\vscript_funcs_shared.h" [$MAPBASE_VSCRIPT]
5355
$File "$SRCDIR\game\shared\mapbase\vscript_singletons.cpp" [$MAPBASE_VSCRIPT]

sp/src/game/shared/basecombatweapon_shared.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,11 @@ bool CBaseCombatWeapon::UsesHands() const
507507
{
508508
return GetWpnData().m_bUsesHands;
509509
}
510+
511+
int CBaseCombatWeapon::GetHandRig() const
512+
{
513+
return GetWpnData().m_nHandRig;
514+
}
510515
#endif
511516

512517
//-----------------------------------------------------------------------------
@@ -3127,6 +3132,9 @@ BEGIN_ENT_SCRIPTDESC( CBaseCombatWeapon, CBaseAnimating, "The base class for all
31273132
DEFINE_SCRIPTFUNC( GetViewModel, "Get the weapon's view model." )
31283133
DEFINE_SCRIPTFUNC( GetDroppedModel, "Get the weapon's unique dropped model if it has one." )
31293134

3135+
DEFINE_SCRIPTFUNC( UsesHands, "" )
3136+
DEFINE_SCRIPTFUNC( GetHandRig, "" )
3137+
31303138
DEFINE_SCRIPTFUNC( GetWeight, "Get the weapon's weight." )
31313139
DEFINE_SCRIPTFUNC( GetPrintName, "" )
31323140

sp/src/game/shared/basecombatweapon_shared.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,13 @@ class CBaseCombatWeapon : public BASECOMBATWEAPON_DERIVED_FROM
423423
virtual bool UsesClipsForAmmo2( void ) const;
424424
bool IsMeleeWeapon() const;
425425
#ifdef MAPBASE
426-
float GetViewmodelFOVOverride() const;
426+
virtual float GetViewmodelFOVOverride() const;
427427
float GetBobScale() const;
428428
float GetSwayScale() const;
429429
float GetSwaySpeedScale() const;
430430
virtual const char *GetDroppedModel( void ) const;
431-
bool UsesHands( void ) const;
431+
virtual bool UsesHands( void ) const;
432+
virtual int GetHandRig( void ) const;
432433
#endif
433434

434435
// derive this function if you mod uses encrypted weapon info files

0 commit comments

Comments
 (0)