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.

537 lines
17 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The TF Game rules object
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #ifndef CS_GAMERULES_H
  10. #define CS_GAMERULES_H
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. #include "teamplay_gamerules.h"
  15. #include "convar.h"
  16. #include "cs_shareddefs.h"
  17. #include "gamevars_shared.h"
  18. #ifdef CLIENT_DLL
  19. #include "c_cs_player.h"
  20. #include "networkstringtable_clientdll.h"
  21. #else
  22. #include "cs_player.h"
  23. #include "funfactmgr_cs.h"
  24. #endif
  25. #include "cs_urlretrieveprices.h"
  26. //extern ConVar mp_dynamicpricing;
  27. #define CS_GAMERULES_BLACKMARKET_TABLE_NAME "BlackMarketTable"
  28. #define WINNER_NONE 0
  29. #define WINNER_DRAW 1
  30. #define WINNER_TER TEAM_TERRORIST
  31. #define WINNER_CT TEAM_CT
  32. //=============================================================================
  33. // HPE_BEGIN:
  34. // [tj] Forward declaration so we can track bot suicides in the game rules.
  35. //=============================================================================
  36. class CCSBot;
  37. //=============================================================================
  38. // HPE_END
  39. //=============================================================================
  40. extern ConVar mp_startmoney;
  41. extern ConVar mp_tkpunish;
  42. extern ConVar mp_c4timer;
  43. extern ConVar mp_buytime;
  44. extern ConVar mp_freezetime;
  45. extern ConVar mp_playerid;
  46. #ifndef CLIENT_DLL
  47. extern ConVar mp_autoteambalance;
  48. #endif // !CLIENT_DLL
  49. #ifdef CLIENT_DLL
  50. #define CCSGameRules C_CSGameRules
  51. #define CCSGameRulesProxy C_CSGameRulesProxy
  52. #endif
  53. #ifndef CLIENT_DLL
  54. struct playerscore_t
  55. {
  56. int iPlayerIndex;
  57. int iScore;
  58. };
  59. #endif
  60. class CCSGameRulesProxy : public CGameRulesProxy
  61. {
  62. public:
  63. DECLARE_CLASS( CCSGameRulesProxy, CGameRulesProxy );
  64. DECLARE_NETWORKCLASS();
  65. };
  66. class CCSGameRules : public CTeamplayRules
  67. {
  68. public:
  69. DECLARE_CLASS( CCSGameRules, CTeamplayRules );
  70. // Stuff that is shared between client and server.
  71. bool IsFreezePeriod();
  72. virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
  73. float GetMapRemainingTime(); // time till end of map, -1 if timelimit is disabled
  74. float GetMapElapsedTime(); // How much time has elapsed since the map started.
  75. float GetRoundRemainingTime(); // time till end of round
  76. float GetRoundStartTime(); // When this round started.
  77. float GetRoundElapsedTime(); // How much time has elapsed since the round started.
  78. float GetBuyTimeLength() const;
  79. int GetRoundLength() const { return m_iRoundTime; }
  80. int SelectDefaultTeam( bool ignoreBots = false );
  81. int GetHumanTeam(); // TEAM_UNASSIGNED if no restrictions
  82. bool IsVIPMap() const;
  83. bool IsBombDefuseMap() const;
  84. bool IsHostageRescueMap() const;
  85. bool IsIntermission() const;
  86. bool IsLogoMap() const;
  87. bool IsSpawnPointValid( CBaseEntity *pSpot, CBasePlayer *pPlayer );
  88. bool IsBuyTimeElapsed();
  89. virtual int DefaultFOV();
  90. // Get the view vectors for this mod.
  91. virtual const CViewVectors* GetViewVectors() const;
  92. void UploadGameStats( void );
  93. int GetStartMoney( void );
  94. virtual bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer );
  95. private:
  96. float GetExplosionDamageAdjustment(Vector & vecSrc, Vector & vecEnd, CBaseEntity *pEntityToIgnore); // returns multiplier between 0.0 and 1.0 that is the percentage of any damage done from vecSrc to vecEnd that actually makes it.
  97. float GetAmountOfEntityVisible(Vector & src, CBaseEntity *player); // returns a value from 0 to 1 that is the percentage of player visible from src.
  98. CNetworkVar( bool, m_bFreezePeriod ); // TRUE at beginning of round, set to FALSE when the period expires
  99. CNetworkVar( int, m_iRoundTime ); // (From mp_roundtime) - How many seconds long this round is.
  100. CNetworkVar( float, m_fRoundStartTime ); // time round has started
  101. CNetworkVar( float, m_flGameStartTime );
  102. CNetworkVar( int, m_iHostagesRemaining );
  103. CNetworkVar( bool, m_bMapHasBombTarget );
  104. CNetworkVar( bool, m_bMapHasRescueZone );
  105. CNetworkVar( bool, m_bLogoMap ); // If there's an info_player_logo entity, then it's a logo map.
  106. CNetworkVar( bool, m_bBlackMarket );
  107. bool m_bDontUploadStats;
  108. public:
  109. bool IsBlackMarket( void ) { return m_bBlackMarket; }
  110. int GetNumHostagesRemaining( void ) { return m_iHostagesRemaining; }
  111. virtual CBaseCombatWeapon *GetNextBestWeapon( CBaseCombatCharacter *pPlayer, CBaseCombatWeapon *pCurrentWeapon );
  112. virtual const unsigned char *GetEncryptionKey( void ) { return (unsigned char *)"d7NSuLq2"; } // both the client and server need this key
  113. #ifdef CLIENT_DLL
  114. DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
  115. CCSGameRules();
  116. #else
  117. DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
  118. CCSGameRules();
  119. virtual ~CCSGameRules();
  120. void DumpTimers( void ) const; // debugging to help track down a stuck server (rare?)
  121. CBaseEntity *GetPlayerSpawnSpot( CBasePlayer *pPlayer );
  122. static void EndRound();
  123. virtual void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );
  124. virtual void Think();
  125. // Called at the end of GameFrame (i.e. after all game logic has run this frame)
  126. virtual void EndGameFrame( void );
  127. // Called when game rules are destroyed by CWorld
  128. virtual void LevelShutdown( void );
  129. virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
  130. virtual void PlayerSpawn( CBasePlayer *pPlayer );
  131. void ShowSpawnPoints();
  132. virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues );
  133. //=============================================================================
  134. // HPE_BEGIN:
  135. // [menglish] Set up anything for all players that changes based on new players spawning mid-game
  136. // Find and return fun fact data
  137. // [pfreese] Tracking of "pistol" round
  138. //=============================================================================
  139. virtual void SpawningLatePlayer(CCSPlayer* pLatePlayer);
  140. bool IsPistolRound();
  141. void HostageKilled() { m_hostageWasKilled = true; }
  142. void HostageInjured() { m_hostageWasInjured = true; }
  143. bool WasHostageKilled() { return m_hostageWasKilled; }
  144. bool WasHostageInjured() { return m_hostageWasInjured; }
  145. //=============================================================================
  146. // HPE_END
  147. //=============================================================================
  148. //=============================================================================
  149. // HPE_BEGIN:
  150. // [tj] So game rules can react to damage taken
  151. //=============================================================================
  152. void PlayerTookDamage(CCSPlayer* player, const CTakeDamageInfo &damageInfo);
  153. //=============================================================================
  154. // HPE_END
  155. //=============================================================================
  156. virtual bool PlayTextureSounds( void ) { return true; }
  157. // Let the game rules specify if fall death should fade screen to black
  158. virtual bool FlPlayerFallDeathDoesScreenFade( CBasePlayer *pl ) { return FALSE; }
  159. virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
  160. void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld );
  161. virtual void UpdateClientData( CBasePlayer *pl );
  162. // Death notices
  163. virtual void DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info );
  164. virtual void InitDefaultAIRelationships( void );
  165. virtual const char *GetGameDescription( void ) { return "Counter-Strike: Source"; } // this is the game name that gets seen in the server browser
  166. virtual const char *AIClassText(int classType);
  167. virtual bool FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );
  168. virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer );
  169. // Called before entities are created
  170. virtual void LevelInitPreEntity();
  171. // Called after the map has finished loading.
  172. virtual void LevelInitPostEntity();
  173. virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
  174. virtual void ClientDisconnected( edict_t *pClient );
  175. // Recreate all the map entities from the map data (preserving their indices),
  176. // then remove everything else except the players.
  177. // Also get rid of all world decals.
  178. void CleanUpMap();
  179. void CheckFreezePeriodExpired();
  180. void CheckRoundTimeExpired();
  181. // check if the scenario has been won/lost
  182. // return true if the scenario is over, false if the scenario is still in progress
  183. bool CheckWinConditions( void );
  184. void TerminateRound( float tmDelay, int reason );
  185. //=============================================================================
  186. // HPE_BEGIN:
  187. // [tj] A place to check achievements that occur at the end of the round
  188. //=============================================================================
  189. void ProcessEndOfRoundAchievements(int iWinnerTeam, int iReason);
  190. //=============================================================================
  191. // HPE_END
  192. //=============================================================================
  193. void RestartRound( void );
  194. void BalanceTeams( void );
  195. void MoveHumansToHumanTeam( void );
  196. bool TeamFull( int team_id );
  197. bool TeamStacked( int newTeam_id, int curTeam_id );
  198. bool FPlayerCanRespawn( CBasePlayer *pPlayer );
  199. void UpdateTeamScores();
  200. void CheckMapConditions();
  201. void MarkLivingPlayersOnTeamAsNotReceivingMoneyNextRound(int team);
  202. // Check various conditions to end the map.
  203. bool CheckGameOver();
  204. bool CheckMaxRounds();
  205. bool CheckWinLimit();
  206. bool CheckFragLimit();
  207. void CheckLevelInitialized();
  208. void CheckRestartRound();
  209. // Checks if it still needs players to start a round, or if it has enough players to start rounds.
  210. // Starts a round and returns true if there are enough players.
  211. bool NeededPlayersCheck( bool &bNeededPlayers );
  212. // Setup counts for m_iNumTerrorist, m_iNumCT, m_iNumSpawnableTerrorist, m_iNumSpawnableCT, etc.
  213. void InitializePlayerCounts(
  214. int &NumAliveTerrorist,
  215. int &NumAliveCT,
  216. int &NumDeadTerrorist,
  217. int &NumDeadCT
  218. );
  219. // Check to see if the round is over for the various game types. Terminates the round
  220. // and returns true if the round should end.
  221. bool PrisonRoundEndCheck();
  222. bool BombRoundEndCheck( bool bNeededPlayers );
  223. bool HostageRescueRoundEndCheck( bool bNeededPlayers );
  224. // Check to see if the teams exterminated each other. Ends the round and returns true if so.
  225. bool TeamExterminationCheck(
  226. int NumAliveTerrorist,
  227. int NumAliveCT,
  228. int NumDeadTerrorist,
  229. int NumDeadCT,
  230. bool bNeededPlayers
  231. );
  232. void ReadMultiplayCvars();
  233. void SwapAllPlayers();
  234. void BroadcastSound( const char *sound, int team = -1 );
  235. // VIP FUNCTIONS
  236. bool VIPRoundEndCheck( bool bNeededPlayers );
  237. void PickNextVIP();
  238. // BOMB MAP FUNCTIONS
  239. void GiveC4();
  240. bool IsThereABomber();
  241. bool IsThereABomb();
  242. // HOSTAGE MAP FUNCTIONS
  243. void HostageTouched();
  244. // Sets up g_pPlayerResource.
  245. virtual void CreateStandardEntities();
  246. virtual const char *GetChatPrefix( bool bTeamOnly, CBasePlayer *pPlayer );
  247. virtual const char *GetChatLocation( bool bTeamOnly, CBasePlayer *pPlayer );
  248. virtual const char *GetChatFormat( bool bTeamOnly, CBasePlayer *pPlayer );
  249. void ClientSettingsChanged( CBasePlayer *pPlayer );
  250. bool IsCareer( void ) const { return false; } // returns true if this is a CZ "career" game
  251. virtual bool FAllowNPCs( void );
  252. protected:
  253. virtual void GoToIntermission( void );
  254. public:
  255. bool IsFriendlyFireOn();
  256. virtual void SetAllowWeaponSwitch( bool allow );
  257. virtual bool GetAllowWeaponSwitch( void );
  258. // VARIABLES FOR ALL TYPES OF MAPS
  259. bool m_bLevelInitialized;
  260. int m_iRoundWinStatus; // 1 == CT's won last round, 2 == Terrorists did, 3 == Draw, no winner
  261. int m_iTotalRoundsPlayed;
  262. int m_iUnBalancedRounds; // keeps track of the # of consecutive rounds that have gone by where one team outnumbers the other team by more than 2
  263. // GAME TIMES
  264. int m_iFreezeTime; // (From mp_freezetime) - How many seconds long the intro round (when players are frozen) is.
  265. float m_flRestartRoundTime; // the global time when the round is supposed to end, if this is not 0
  266. int m_iNumTerrorist; // The number of terrorists on the team (this is generated at the end of a round)
  267. int m_iNumCT; // The number of CTs on the team (this is generated at the end of a round)
  268. int m_iNumSpawnableTerrorist;
  269. int m_iNumSpawnableCT;
  270. bool m_bFirstConnected;
  271. bool m_bCompleteReset; // Set to TRUE to have the scores reset next time round restarts
  272. int m_iAccountTerrorist;
  273. int m_iAccountCT;
  274. short m_iNumCTWins;
  275. short m_iNumTerroristWins;
  276. int m_iNumConsecutiveCTLoses; //SupraFiend: the number of rounds the CTs have lost in a row.
  277. int m_iNumConsecutiveTerroristLoses;//SupraFiend: the number of rounds the Terrorists have lost in a row.
  278. int m_iSpawnPointCount_Terrorist; // Number of Terrorist spawn points
  279. int m_iSpawnPointCount_CT; // Number of CT spawn points
  280. bool m_bTCantBuy; // Who can and can't buy.
  281. bool m_bCTCantBuy;
  282. bool m_bMapHasBuyZone;
  283. int m_iLoserBonus; // SupraFiend: the amount of money the losing team gets. This scales up as they lose more rounds in a row
  284. float m_tmNextPeriodicThink;
  285. // HOSTAGE RESCUE VARIABLES
  286. int m_iHostagesRescued;
  287. int m_iHostagesTouched;
  288. float m_flNextHostageAnnouncement;
  289. //=============================================================================
  290. // HPE_BEGIN
  291. //=============================================================================
  292. // [tj] Accessor for weapons donation ability
  293. bool GetCanDonateWeapon() { return m_bCanDonateWeapons; }
  294. // [tj] flawless and lossless round related flags
  295. bool m_bNoTerroristsKilled;
  296. bool m_bNoCTsKilled;
  297. bool m_bNoTerroristsDamaged;
  298. bool m_bNoCTsDamaged;
  299. // [tj] Find out if dropped weapons count as donations
  300. bool m_bCanDonateWeapons;
  301. // [tj] Keep track of first kill
  302. CHandle<CCSPlayer> m_pFirstKill;
  303. float m_firstKillTime;
  304. // [menglish] Keep track of first blood
  305. CHandle<CCSPlayer> m_pFirstBlood;
  306. float m_firstBloodTime;
  307. // [dwenger] Rescue-related achievement values
  308. CHandle<CCSPlayer> m_pLastRescuer;
  309. int m_iNumRescuers;
  310. bool m_hostageWasInjured;
  311. bool m_hostageWasKilled;
  312. // [menglish] Fun Fact Manager
  313. CCSFunFactMgr *m_pFunFactManager;
  314. // [tj] To avoid rewriting the same piece of code, we can get all the information
  315. // we want from one call that fills in an array of structures.
  316. struct TeamPlayerCounts
  317. {
  318. int totalPlayers;
  319. int totalAlivePlayers;
  320. int totalDeadPlayers; //sum of killedPlayers + suicidedPlayers + unenteredPlayers
  321. int killedPlayers;
  322. int suicidedPlayers;
  323. int unenteredPlayers;
  324. };
  325. void GetPlayerCounts(TeamPlayerCounts teamCounts[TEAM_MAXCOUNT]);
  326. //=============================================================================
  327. // HPE_END
  328. //=============================================================================
  329. // PRISON ESCAPE VARIABLES
  330. int m_iHaveEscaped;
  331. bool m_bMapHasEscapeZone;
  332. int m_iNumEscapers;
  333. int m_iNumEscapeRounds; // keeps track of the # of consecutive rounds of escape played.. Teams will be swapped after 8 rounds
  334. // VIP VARIABLES
  335. int m_iMapHasVIPSafetyZone; // 0 = uninitialized; 1 = has VIP safety zone; 2 = DOES not have VIP safetyzone
  336. CHandle<CCSPlayer> m_pVIP;
  337. int m_iConsecutiveVIP;
  338. // BOMB MAP VARIABLES
  339. bool m_bTargetBombed; // whether or not the bomb has been bombed
  340. bool m_bBombDefused; // whether or not the bomb has been defused
  341. bool m_bMapHasBombZone;
  342. bool m_bBombDropped;
  343. bool m_bBombPlanted;
  344. EHANDLE m_pLastBombGuy;
  345. private:
  346. // Don't allow switching weapons while gaining new technologies
  347. bool m_bAllowWeaponSwitch;
  348. public:
  349. void AddPricesToTable( weeklyprice_t prices );
  350. virtual void CreateCustomNetworkStringTables( void );
  351. #endif
  352. #ifdef GAME_DLL
  353. public:
  354. virtual void GetTaggedConVarList( KeyValues *pCvarTagList );
  355. #endif
  356. public:
  357. const weeklyprice_t *GetBlackMarketPriceList( void );
  358. int GetBlackMarketPriceForWeapon( int iWeaponID );
  359. int GetBlackMarketPreviousPriceForWeapon( int iWeaponID );
  360. void SetBlackMarketPrices( bool bSetDefaults );
  361. // Black market
  362. INetworkStringTable *m_StringTableBlackMarket;
  363. const weeklyprice_t *m_pPrices;
  364. };
  365. //-----------------------------------------------------------------------------
  366. // Gets us at the team fortress game rules
  367. //-----------------------------------------------------------------------------
  368. inline CCSGameRules* CSGameRules()
  369. {
  370. return static_cast<CCSGameRules*>(g_pGameRules);
  371. }
  372. #define IGNORE_SPECTATORS true
  373. int UTIL_HumansInGame( bool ignoreSpectators = false );
  374. //-----------------------------------------------------------------------------
  375. // Purpose: Useful utility functions
  376. //-----------------------------------------------------------------------------
  377. #ifdef CLIENT_DLL
  378. #else
  379. class CTFTeam;
  380. CTFTeam *GetOpposingTeam( CTeam *pTeam );
  381. bool EntityPlacementTest( CBaseEntity *pMainEnt, const Vector &vOrigin, Vector &outPos, bool bDropToGround );
  382. #endif
  383. #endif // TF_GAMERULES_H