@@ -42,6 +42,10 @@ ConVar hl2mp_spawn_frag_fallback_radius( "hl2mp_spawn_frag_fallback_radius", "48
4242
4343#define HL2MP_COMMAND_MAX_RATE 0.3
4444
45+ #ifdef MAPBASE
46+ ConVar sv_hl2mp_protagonist_select ( " sv_hl2mp_protagonist_select" , " 0" , FCVAR_NONE, " Allows players to select any valid protagonist, rather than being limited to default HL2:DM models." );
47+ #endif
48+
4549void DropPrimedFragGrenade ( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade );
4650
4751LINK_ENTITY_TO_CLASS ( player, CHL2MP_Player );
@@ -403,6 +407,23 @@ void CHL2MP_Player::Spawn(void)
403407
404408bool CHL2MP_Player::ValidatePlayerModel ( const char *pModel )
405409{
410+ #ifdef MAPBASE
411+ if (pModel[0 ] == ' #' )
412+ {
413+ if (!sv_hl2mp_protagonist_select.GetBool ())
414+ {
415+ ClientPrint ( this , HUD_PRINTTALK, " Server does not allow direct protagonist selection" );
416+ return false ;
417+ }
418+
419+ int nProtagonist = g_ProtagonistSystem.FindProtagonistIndex ( pModel + 1 );
420+ if (nProtagonist != -1 )
421+ {
422+ return true ;
423+ }
424+ }
425+ #endif
426+
406427 int iModels = ARRAYSIZE ( g_ppszRandomCitizenModels );
407428 int i;
408429
@@ -444,7 +465,11 @@ void CHL2MP_Player::SetPlayerTeamModel( void )
444465
445466 int modelIndex = modelinfo->GetModelIndex ( szModelName );
446467
468+ #ifdef MAPBASE
469+ if ( (modelIndex == -1 && szModelName[0 ] != ' #' ) || ValidatePlayerModel (szModelName) == false )
470+ #else
447471 if ( modelIndex == -1 || ValidatePlayerModel ( szModelName ) == false )
472+ #endif
448473 {
449474 szModelName = " models/Combine_Soldier.mdl" ;
450475 m_iModelType = TEAM_COMBINE;
@@ -479,8 +504,34 @@ void CHL2MP_Player::SetPlayerTeamModel( void )
479504
480505 m_iModelType = TEAM_REBELS;
481506 }
482-
507+
508+ #ifdef MAPBASE
509+ if ( szModelName[0 ] == ' #' )
510+ {
511+ // Protagonist name. Was already validated above
512+ SetProtagonist ( szModelName + 1 );
513+ }
514+ else
515+ {
516+ // Find out if we have a protagonist for this model
517+ const char *pszProtagonistName = g_ProtagonistSystem.FindProtagonistByModel ( szModelName );
518+ if (pszProtagonistName)
519+ {
520+ SetProtagonist ( pszProtagonistName );
521+
522+ // Fall back if not accepted
523+ if ( GetProtagonistIndex () == -1 )
524+ SetModel ( szModelName );
525+ }
526+ else
527+ {
528+ SetModel ( szModelName );
529+ }
530+ }
531+ #else
483532 SetModel ( szModelName );
533+ #endif
534+
484535 SetupPlayerSoundsByModel ( szModelName );
485536
486537 m_flNextModelChangeTime = gpGlobals->curtime + MODEL_CHANGE_INTERVAL;
@@ -543,6 +594,18 @@ void CHL2MP_Player::SetPlayerModel( void )
543594 }
544595 }
545596
597+ #ifdef MAPBASE
598+ if (szModelName[0 ] == ' #' )
599+ {
600+ // Protagonist name. Was already validated above
601+ SetProtagonist ( szModelName + 1 );
602+ }
603+ else
604+ {
605+ ResetProtagonist ();
606+ }
607+ #endif
608+
546609 int modelIndex = modelinfo->GetModelIndex ( szModelName );
547610
548611 if ( modelIndex == -1 )
@@ -556,7 +619,28 @@ void CHL2MP_Player::SetPlayerModel( void )
556619 engine->ClientCommand ( edict (), szReturnString );
557620 }
558621
622+ #ifdef MAPBASE
623+ if (GetProtagonistIndex () == -1 )
624+ {
625+ // Find out if we have a protagonist for this model
626+ const char *pszProtagonistName = g_ProtagonistSystem.FindProtagonistByModel ( szModelName );
627+ if (pszProtagonistName)
628+ {
629+ SetProtagonist ( pszProtagonistName );
630+
631+ // Fall back if not accepted
632+ if ( GetProtagonistIndex () <= -1 )
633+ SetModel ( szModelName );
634+ }
635+ else
636+ {
637+ SetModel ( szModelName );
638+ }
639+ }
640+ #else
559641 SetModel ( szModelName );
642+ #endif
643+
560644 SetupPlayerSoundsByModel ( szModelName );
561645
562646 m_flNextModelChangeTime = gpGlobals->curtime + MODEL_CHANGE_INTERVAL;
0 commit comments