Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
6.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include "cbase.h"
  3. #ifdef HL2_EPISODIC
  4. #include "hl2_gamerules.h"
  5. #include "ammodef.h"
  6. #include "hl2_shareddefs.h"
  7. #include "filesystem.h"
  8. #include <KeyValues.h>
  9. #ifdef CLIENT_DLL
  10. #else
  11. #include "player.h"
  12. #include "game.h"
  13. #include "gamerules.h"
  14. #include "teamplay_gamerules.h"
  15. #include "hl2_player.h"
  16. #include "voice_gamemgr.h"
  17. #include "globalstate.h"
  18. #include "ai_basenpc.h"
  19. #include "weapon_physcannon.h"
  20. #include "ammodef.h"
  21. #endif
  22. #ifdef CLIENT_DLL
  23. #define CHalfLife2Survival C_HalfLife2Survival
  24. #define CHalfLife2SurvivalProxy C_HalfLife2SurvivalProxy
  25. #endif
  26. ConVar gamerules_survival( "gamerules_survival", "0", FCVAR_REPLICATED );
  27. class CHalfLife2SurvivalProxy : public CGameRulesProxy
  28. {
  29. public:
  30. DECLARE_CLASS( CHalfLife2SurvivalProxy, CGameRulesProxy );
  31. DECLARE_NETWORKCLASS();
  32. };
  33. class CSurvivalAmmo
  34. {
  35. public:
  36. char m_szAmmoName[256];
  37. int m_iAmount;
  38. };
  39. class CSurvivalSettings
  40. {
  41. public:
  42. CSurvivalSettings();
  43. CUtlVector<char*, CUtlMemory<char*> > m_Loadout;
  44. int m_iSpawnHealth;
  45. string_t m_szPickups;
  46. CUtlVector<CSurvivalAmmo> m_Ammo;
  47. };
  48. CSurvivalSettings::CSurvivalSettings()
  49. {
  50. m_iSpawnHealth = 100;
  51. }
  52. class CHalfLife2Survival : public CHalfLife2
  53. {
  54. public:
  55. DECLARE_CLASS( CHalfLife2Survival, CHalfLife2 );
  56. #ifdef CLIENT_DLL
  57. DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
  58. #else
  59. DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
  60. CHalfLife2Survival();
  61. virtual ~CHalfLife2Survival() {}
  62. virtual void Think( void );
  63. virtual void PlayerSpawn( CBasePlayer *pPlayer );
  64. virtual bool IsAllowedToSpawn( CBaseEntity *pEntity );
  65. virtual void CreateStandardEntities();
  66. void ReadSurvivalScriptFile( void );
  67. void ParseSurvivalSettings( KeyValues *pSubKey );
  68. void ParseSurvivalAmmo( KeyValues *pSubKey );
  69. private:
  70. bool m_bActive;
  71. CSurvivalSettings m_SurvivalSettings;
  72. #endif
  73. };
  74. //-----------------------------------------------------------------------------
  75. // Gets us at the Half-Life 2 game rules
  76. //-----------------------------------------------------------------------------
  77. inline CHalfLife2Survival* HL2SurvivalGameRules()
  78. {
  79. return static_cast<CHalfLife2Survival*>(g_pGameRules);
  80. }
  81. REGISTER_GAMERULES_CLASS( CHalfLife2Survival );
  82. BEGIN_NETWORK_TABLE_NOBASE( CHalfLife2Survival, DT_HL2SurvivalGameRules )
  83. END_NETWORK_TABLE()
  84. LINK_ENTITY_TO_CLASS( hl2_survival_gamerules, CHalfLife2SurvivalProxy );
  85. IMPLEMENT_NETWORKCLASS_ALIASED( HalfLife2SurvivalProxy, DT_HalfLife2SurvivalProxy )
  86. #ifdef CLIENT_DLL
  87. void RecvProxy_HL2SurvivalGameRules( const RecvProp *pProp, void **pOut, void *pData, int objectID )
  88. {
  89. CHalfLife2Survival *pRules = HL2SurvivalGameRules();
  90. Assert( pRules );
  91. *pOut = pRules;
  92. }
  93. BEGIN_RECV_TABLE( CHalfLife2SurvivalProxy, DT_HalfLife2SurvivalProxy )
  94. RecvPropDataTable( "hl2_survival_gamerules_data", 0, 0, &REFERENCE_RECV_TABLE( DT_HL2SurvivalGameRules ), RecvProxy_HL2SurvivalGameRules )
  95. END_RECV_TABLE()
  96. #else
  97. void* SendProxy_HL2SurvivalGameRules( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID )
  98. {
  99. CHalfLife2Survival *pRules = HL2SurvivalGameRules();
  100. Assert( pRules );
  101. pRecipients->SetAllRecipients();
  102. return pRules;
  103. }
  104. BEGIN_SEND_TABLE( CHalfLife2SurvivalProxy, DT_HalfLife2SurvivalProxy )
  105. SendPropDataTable( "hl2_survival_gamerules_data", 0, &REFERENCE_SEND_TABLE( DT_HL2SurvivalGameRules ), SendProxy_HL2SurvivalGameRules )
  106. END_SEND_TABLE()
  107. #endif
  108. #ifndef CLIENT_DLL
  109. CHalfLife2Survival::CHalfLife2Survival()
  110. {
  111. m_bActive = false;
  112. }
  113. void CHalfLife2Survival::Think( void )
  114. {
  115. }
  116. bool CHalfLife2Survival::IsAllowedToSpawn( CBaseEntity *pEntity )
  117. {
  118. if ( !m_bActive )
  119. return BaseClass::IsAllowedToSpawn( pEntity );
  120. const char *pPickups = STRING( m_SurvivalSettings.m_szPickups );
  121. if ( !pPickups )
  122. return false;
  123. if ( Q_stristr( pPickups, "everything" ) )
  124. return true;
  125. if ( Q_stristr( pPickups, pEntity->GetClassname() ) || Q_stristr( pPickups, STRING( pEntity->GetEntityName() ) ) )
  126. return true;
  127. return false;
  128. }
  129. void CHalfLife2Survival::PlayerSpawn( CBasePlayer *pPlayer )
  130. {
  131. BaseClass::PlayerSpawn( pPlayer );
  132. if ( !m_bActive )
  133. return;
  134. pPlayer->EquipSuit();
  135. pPlayer->SetHealth( m_SurvivalSettings.m_iSpawnHealth );
  136. for ( int i = 0; i < m_SurvivalSettings.m_Loadout.Count(); ++i )
  137. {
  138. pPlayer->GiveNamedItem( m_SurvivalSettings.m_Loadout[i] );
  139. }
  140. for ( int i = 0; i < m_SurvivalSettings.m_Ammo.Count(); ++i )
  141. {
  142. pPlayer->CBasePlayer::GiveAmmo( m_SurvivalSettings.m_Ammo[i].m_iAmount , m_SurvivalSettings.m_Ammo[i].m_szAmmoName );
  143. }
  144. }
  145. void CHalfLife2Survival::ParseSurvivalSettings( KeyValues *pSubKey )
  146. {
  147. if ( pSubKey == NULL )
  148. return;
  149. m_SurvivalSettings.m_szPickups = NULL_STRING;
  150. m_SurvivalSettings.m_iSpawnHealth = 100;
  151. KeyValues *pTestKey = pSubKey->GetFirstSubKey();
  152. while ( pTestKey )
  153. {
  154. if ( !stricmp( pTestKey->GetName(), "weapons" ) )
  155. {
  156. const char *pLoadout = pTestKey->GetString();
  157. Q_SplitString( pLoadout, ";", m_SurvivalSettings.m_Loadout );
  158. }
  159. else if ( !stricmp( pTestKey->GetName(), "spawnhealth" ) )
  160. {
  161. m_SurvivalSettings.m_iSpawnHealth = pTestKey->GetInt( NULL, 100 );
  162. }
  163. else if ( !stricmp( pTestKey->GetName(), "allowedpickups" ) )
  164. {
  165. m_SurvivalSettings.m_szPickups = MAKE_STRING( pTestKey->GetString() );
  166. }
  167. pTestKey = pTestKey->GetNextKey();
  168. }
  169. }
  170. void CHalfLife2Survival::ParseSurvivalAmmo( KeyValues *pSubKey )
  171. {
  172. if ( pSubKey )
  173. {
  174. KeyValues *pAmmoKey = pSubKey->GetFirstSubKey();
  175. while ( pAmmoKey )
  176. {
  177. CSurvivalAmmo ammo;
  178. Q_strcpy( ammo.m_szAmmoName, pAmmoKey->GetName() );
  179. ammo.m_iAmount = pAmmoKey->GetInt();
  180. m_SurvivalSettings.m_Ammo.AddToTail( ammo );
  181. pAmmoKey = pAmmoKey->GetNextKey();
  182. }
  183. }
  184. }
  185. void CHalfLife2Survival::ReadSurvivalScriptFile( void )
  186. {
  187. char szFullName[512];
  188. Q_snprintf( szFullName, sizeof( szFullName ), "maps/%s_survival.txt", STRING(gpGlobals->mapname) );
  189. KeyValues *pkvFile = new KeyValues( "Survival" );
  190. if ( pkvFile->LoadFromFile( filesystem, szFullName, "MOD" ) )
  191. {
  192. ParseSurvivalSettings( pkvFile->FindKey( "settings" ) );
  193. ParseSurvivalAmmo( pkvFile->FindKey( "ammo" ) );
  194. CUtlVector <CBaseEntity*> entities;
  195. UTIL_LoadAndSpawnEntitiesFromScript( entities, szFullName, "Survival", true );
  196. // It's important to turn on survival mode after we create all the entities
  197. // in the script, so that we don't remove them if they violate survival rules.
  198. // i.e. we want the player to start with a shotgun, but prevent all future shotguns from spawning.
  199. m_bActive = true;
  200. }
  201. else
  202. {
  203. m_bActive = false;
  204. }
  205. }
  206. void CHalfLife2Survival::CreateStandardEntities( void )
  207. {
  208. ReadSurvivalScriptFile();
  209. }
  210. #endif
  211. #endif