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.

337 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TF's custom C_PlayerResource
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "c_tf_playerresource.h"
  9. #include <shareddefs.h>
  10. #include <tf_shareddefs.h>
  11. #include "hud.h"
  12. #include "tf_gamerules.h"
  13. #include "tf_gc_client.h"
  14. #include "tf_lobby_server.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. extern ConVar tf_mvm_respec_limit;
  18. extern ConVar tf_mvm_buybacks_method;
  19. C_TF_PlayerResource *g_TF_PR;
  20. IMPLEMENT_CLIENTCLASS_DT( C_TF_PlayerResource, DT_TFPlayerResource, CTFPlayerResource )
  21. RecvPropArray3( RECVINFO_ARRAY( m_iTotalScore ), RecvPropInt( RECVINFO( m_iTotalScore[0] ) ) ),
  22. RecvPropArray3( RECVINFO_ARRAY( m_iMaxHealth ), RecvPropInt( RECVINFO( m_iMaxHealth[0] ) ) ),
  23. RecvPropArray3( RECVINFO_ARRAY( m_iMaxBuffedHealth ), RecvPropInt( RECVINFO( m_iMaxBuffedHealth[0] ) ) ),
  24. RecvPropArray3( RECVINFO_ARRAY( m_iPlayerClass ), RecvPropInt( RECVINFO( m_iPlayerClass[0] ) ) ),
  25. RecvPropArray3( RECVINFO_ARRAY( m_bArenaSpectator ), RecvPropBool( RECVINFO( m_bArenaSpectator[0] ) ) ),
  26. RecvPropArray3( RECVINFO_ARRAY( m_iActiveDominations ), RecvPropInt( RECVINFO( m_iActiveDominations[0] ) ) ),
  27. RecvPropArray3( RECVINFO_ARRAY( m_flNextRespawnTime ), RecvPropTime( RECVINFO( m_flNextRespawnTime[0] ) ) ),
  28. RecvPropArray3( RECVINFO_ARRAY( m_iChargeLevel ), RecvPropInt( RECVINFO( m_iChargeLevel[0] ) ) ),
  29. RecvPropArray3( RECVINFO_ARRAY( m_iDamage ), RecvPropInt( RECVINFO( m_iDamage[0] ) ) ),
  30. RecvPropArray3( RECVINFO_ARRAY( m_iDamageAssist ), RecvPropInt( RECVINFO( m_iDamageAssist[0] ) ) ),
  31. RecvPropArray3( RECVINFO_ARRAY( m_iDamageBoss ), RecvPropInt( RECVINFO( m_iDamageBoss[0] ) ) ),
  32. RecvPropArray3( RECVINFO_ARRAY( m_iHealing ), RecvPropInt( RECVINFO( m_iHealing[0] ) ) ),
  33. RecvPropArray3( RECVINFO_ARRAY( m_iHealingAssist ), RecvPropInt( RECVINFO( m_iHealingAssist[0] ) ) ),
  34. RecvPropArray3( RECVINFO_ARRAY( m_iDamageBlocked ), RecvPropInt( RECVINFO( m_iDamageBlocked[0] ) ) ),
  35. RecvPropArray3( RECVINFO_ARRAY( m_iCurrencyCollected ), RecvPropInt( RECVINFO( m_iCurrencyCollected[0] ) ) ),
  36. RecvPropArray3( RECVINFO_ARRAY( m_iBonusPoints ), RecvPropInt( RECVINFO( m_iBonusPoints[0] ) ) ),
  37. RecvPropArray3( RECVINFO_ARRAY( m_iPlayerLevel ), RecvPropInt( RECVINFO( m_iPlayerLevel[0] ) ) ),
  38. RecvPropArray3( RECVINFO_ARRAY( m_iStreaks ), RecvPropInt( RECVINFO_ARRAY( m_iStreaks ) ) ),
  39. RecvPropArray3( RECVINFO_ARRAY( m_iUpgradeRefundCredits ), RecvPropInt( RECVINFO( m_iUpgradeRefundCredits[0] ) ) ),
  40. RecvPropArray3( RECVINFO_ARRAY( m_iBuybackCredits ), RecvPropInt( RECVINFO( m_iBuybackCredits[0] ) ) ),
  41. RecvPropInt( RECVINFO( m_iPartyLeaderRedTeamIndex ) ),
  42. RecvPropInt( RECVINFO( m_iPartyLeaderBlueTeamIndex ) ),
  43. RecvPropInt( RECVINFO( m_iEventTeamStatus ) ),
  44. RecvPropArray3( RECVINFO_ARRAY( m_iPlayerClassWhenKilled ), RecvPropInt( RECVINFO( m_iPlayerClassWhenKilled[0] ) ) ),
  45. RecvPropArray3( RECVINFO_ARRAY( m_iConnectionState ), RecvPropInt( RECVINFO( m_iConnectionState[0] ) ) ),
  46. END_RECV_TABLE()
  47. //-----------------------------------------------------------------------------
  48. // Purpose:
  49. //-----------------------------------------------------------------------------
  50. C_TF_PlayerResource::C_TF_PlayerResource()
  51. {
  52. m_Colors[TEAM_UNASSIGNED] = COLOR_TF_SPECTATOR;
  53. m_Colors[TEAM_SPECTATOR] = COLOR_TF_SPECTATOR;
  54. m_Colors[TF_TEAM_RED] = COLOR_RED;
  55. m_Colors[TF_TEAM_BLUE] = COLOR_BLUE;
  56. m_iPartyLeaderRedTeamIndex = 0;
  57. m_iPartyLeaderBlueTeamIndex = 0;
  58. m_iEventTeamStatus = 0;
  59. ResetPlayerScoreStats();
  60. g_TF_PR = this;
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. C_TF_PlayerResource::~C_TF_PlayerResource()
  66. {
  67. g_TF_PR = NULL;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose:
  71. //-----------------------------------------------------------------------------
  72. int C_TF_PlayerResource::GetTeam( int iIndex )
  73. {
  74. bool bValid = ( iIndex >= 1 && iIndex <= MAX_PLAYERS );
  75. if ( !bValid )
  76. {
  77. Assert( bValid );
  78. return TEAM_UNASSIGNED;
  79. }
  80. int iTeam = BaseClass::GetTeam( iIndex );
  81. if ( iTeam == TEAM_UNASSIGNED )
  82. {
  83. // In MvM, force everybody to show as being on the defending team,
  84. // even if they have not picked a team yet
  85. if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
  86. {
  87. iTeam = TF_TEAM_PVE_DEFENDERS;
  88. }
  89. }
  90. return iTeam;
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose:
  94. //-----------------------------------------------------------------------------
  95. MM_PlayerConnectionState_t C_TF_PlayerResource::GetPlayerConnectionState( int iIndex ) const
  96. {
  97. if ( !iIndex || ( iIndex > MAX_PLAYERS ) )
  98. return MM_DISCONNECTED;
  99. return m_iConnectionState[iIndex];
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose: Gets a value from an array member
  103. //-----------------------------------------------------------------------------
  104. int C_TF_PlayerResource::GetArrayValue( int iIndex, int *pArray, int iDefaultVal )
  105. {
  106. if ( !IsConnected( iIndex ) && !IsValid( iIndex ) )
  107. return iDefaultVal;
  108. return pArray[iIndex];
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Purpose: Gets a streak value
  112. //-----------------------------------------------------------------------------
  113. int C_TF_PlayerResource::GetStreak( unsigned int iIndex, CTFPlayerShared::ETFStreak streak_type )
  114. {
  115. if ( !IsConnected( iIndex ) && !IsValid( iIndex ) )
  116. return 0;
  117. return m_iStreaks[ iIndex * CTFPlayerShared::kTFStreak_COUNT + streak_type ];
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. //-----------------------------------------------------------------------------
  122. int C_TF_PlayerResource::GetNumRespecCredits( uint32 unIndex )
  123. {
  124. if ( !unIndex || unIndex > MAX_PLAYERS )
  125. return 0;
  126. if ( !tf_mvm_respec_limit.GetBool() )
  127. return 1;
  128. return GetArrayValue( unIndex, m_iUpgradeRefundCredits, 0 );
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose:
  132. //-----------------------------------------------------------------------------
  133. int C_TF_PlayerResource::GetNumBuybackCredits( uint32 unIndex )
  134. {
  135. if ( !unIndex || unIndex > MAX_PLAYERS )
  136. return 0;
  137. if ( !tf_mvm_buybacks_method.GetBool() )
  138. return 0;
  139. return GetArrayValue( unIndex, m_iBuybackCredits, 0 );
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose:
  143. //-----------------------------------------------------------------------------
  144. int C_TF_PlayerResource::GetCountForPlayerClass( int iTeam, int iClass, bool bExcludeLocalPlayer /*=false*/ )
  145. {
  146. int count = 0;
  147. int iLocalPlayerIndex = GetLocalPlayerIndex();
  148. for ( int i = 1 ; i <= MAX_PLAYERS ; i++ )
  149. {
  150. if ( bExcludeLocalPlayer && ( i == iLocalPlayerIndex ) )
  151. {
  152. continue;
  153. }
  154. if ( ( GetTeam( i ) == iTeam ) && ( GetPlayerClass( i ) == iClass ) )
  155. {
  156. count++;
  157. }
  158. }
  159. return count;
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Purpose:
  163. //-----------------------------------------------------------------------------
  164. int C_TF_PlayerResource::GetNumPlayersForTeam( int iTeam, bool bAliveOnly )
  165. {
  166. int count = 0;
  167. for ( int playerIndex = 1 ; playerIndex <= MAX_PLAYERS; playerIndex++ )
  168. {
  169. if ( IsConnected( playerIndex ) )
  170. {
  171. if ( GetTeam( playerIndex ) == iTeam )
  172. {
  173. if ( bAliveOnly && !IsAlive( playerIndex ) )
  174. continue;
  175. count++;
  176. }
  177. }
  178. }
  179. return count;
  180. }
  181. //-----------------------------------------------------------------------------
  182. // Purpose:
  183. //-----------------------------------------------------------------------------
  184. int C_TF_PlayerResource::GetDamage( unsigned int nIndex )
  185. {
  186. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  187. return GetArrayValue( nIndex, m_iDamage, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamage;
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose:
  191. //-----------------------------------------------------------------------------
  192. int C_TF_PlayerResource::GetDamageAssist( unsigned int nIndex )
  193. {
  194. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  195. return GetArrayValue( nIndex, m_iDamageAssist, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageAssist;
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Purpose:
  199. //-----------------------------------------------------------------------------
  200. int C_TF_PlayerResource::GetDamageBoss( unsigned int nIndex )
  201. {
  202. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  203. return GetArrayValue( nIndex, m_iDamageBoss, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageBoss;
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Purpose:
  207. //-----------------------------------------------------------------------------
  208. int C_TF_PlayerResource::GetHealing( unsigned int nIndex )
  209. {
  210. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  211. return GetArrayValue( nIndex, m_iHealing, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevHealing;
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. int C_TF_PlayerResource::GetHealingAssist( unsigned int nIndex )
  217. {
  218. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  219. return GetArrayValue( nIndex, m_iHealingAssist, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevHealingAssist;
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose:
  223. //-----------------------------------------------------------------------------
  224. int C_TF_PlayerResource::GetDamageBlocked( unsigned int nIndex )
  225. {
  226. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  227. return GetArrayValue( nIndex, m_iDamageBlocked, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageBlocked;
  228. }
  229. //-----------------------------------------------------------------------------
  230. // Purpose:
  231. //-----------------------------------------------------------------------------
  232. int C_TF_PlayerResource::GetCurrencyCollected( unsigned int nIndex )
  233. {
  234. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  235. return GetArrayValue( nIndex, m_iCurrencyCollected, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevCurrencyCollected;
  236. }
  237. //-----------------------------------------------------------------------------
  238. // Purpose:
  239. //-----------------------------------------------------------------------------
  240. int C_TF_PlayerResource::GetBonusPoints( unsigned int nIndex )
  241. {
  242. Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  243. return GetArrayValue( nIndex, m_iBonusPoints, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevBonusPoints;
  244. }
  245. //-----------------------------------------------------------------------------
  246. // Purpose:
  247. //-----------------------------------------------------------------------------
  248. void C_TF_PlayerResource::UpdatePlayerScoreStats( void )
  249. {
  250. for ( int playerIndex = 0; playerIndex < ARRAYSIZE( m_aPlayerScoreStats ); playerIndex++ )
  251. {
  252. // Add current round stats to the accumulator
  253. m_aPlayerScoreStats[playerIndex].m_iPrevDamage += GetArrayValue( playerIndex, m_iDamage, 0 );
  254. m_aPlayerScoreStats[playerIndex].m_iPrevDamageAssist += GetArrayValue( playerIndex, m_iDamageAssist, 0 );
  255. m_aPlayerScoreStats[playerIndex].m_iPrevDamageBoss += GetArrayValue( playerIndex, m_iDamageBoss, 0 );
  256. m_aPlayerScoreStats[playerIndex].m_iPrevHealing += GetArrayValue( playerIndex, m_iHealing, 0 );
  257. m_aPlayerScoreStats[playerIndex].m_iPrevHealingAssist += GetArrayValue( playerIndex, m_iHealingAssist, 0 );
  258. m_aPlayerScoreStats[playerIndex].m_iPrevDamageBlocked += GetArrayValue( playerIndex, m_iDamageBlocked, 0 );
  259. m_aPlayerScoreStats[playerIndex].m_iPrevCurrencyCollected += GetArrayValue( playerIndex, m_iCurrencyCollected, 0 );
  260. m_aPlayerScoreStats[playerIndex].m_iPrevBonusPoints += GetArrayValue( playerIndex, m_iBonusPoints, 0 );
  261. }
  262. }
  263. //-----------------------------------------------------------------------------
  264. // Purpose:
  265. //-----------------------------------------------------------------------------
  266. void C_TF_PlayerResource::ResetPlayerScoreStats( int playerIndex /*= -1*/ )
  267. {
  268. if ( playerIndex == -1 )
  269. {
  270. Q_memset( m_aPlayerScoreStats, 0, sizeof( m_aPlayerScoreStats ) );
  271. }
  272. else
  273. {
  274. // valid playerIndex should be 1-33 (32 players)
  275. Assert( playerIndex > 0 && playerIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
  276. m_aPlayerScoreStats[playerIndex].m_iPrevDamage = 0;
  277. m_aPlayerScoreStats[playerIndex].m_iPrevDamageAssist = 0;
  278. m_aPlayerScoreStats[playerIndex].m_iPrevDamageBoss = 0;
  279. m_aPlayerScoreStats[playerIndex].m_iPrevHealing = 0;
  280. m_aPlayerScoreStats[playerIndex].m_iPrevHealingAssist = 0;
  281. m_aPlayerScoreStats[playerIndex].m_iPrevDamageBlocked = 0;
  282. m_aPlayerScoreStats[playerIndex].m_iPrevCurrencyCollected = 0;
  283. m_aPlayerScoreStats[playerIndex].m_iPrevBonusPoints = 0;
  284. }
  285. }