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.

226 lines
5.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //=======================================================================================//
  4. #include "cbase.h"
  5. #if defined( REPLAY_ENABLED )
  6. #include "cs_replay.h"
  7. #include "c_cs_player.h"
  8. #include "cs_gamestats_shared.h"
  9. #include "cs_client_gamestats.h"
  10. #include "clientmode_shared.h"
  11. #include "replay/ireplaymoviemanager.h"
  12. #include "replay/ireplayfactory.h"
  13. #include "replay/ireplayscreenshotmanager.h"
  14. #include "replay/screenshot.h"
  15. #include <time.h>
  16. //----------------------------------------------------------------------------------------
  17. extern IReplayScreenshotManager *g_pReplayScreenshotManager;
  18. //----------------------------------------------------------------------------------------
  19. CCSReplay::CCSReplay()
  20. {
  21. }
  22. CCSReplay::~CCSReplay()
  23. {
  24. }
  25. void CCSReplay::OnBeginRecording()
  26. {
  27. BaseClass::OnBeginRecording();
  28. // Setup the newly created replay
  29. C_CSPlayer* pPlayer = C_CSPlayer::GetLocalCSPlayer();
  30. if ( pPlayer )
  31. {
  32. SetPlayerClass( pPlayer->PlayerClass() );
  33. SetPlayerTeam( pPlayer->GetTeamNumber() );
  34. }
  35. }
  36. void CCSReplay::OnEndRecording()
  37. {
  38. if ( gameeventmanager )
  39. {
  40. gameeventmanager->RemoveListener( this );
  41. }
  42. BaseClass::OnEndRecording();
  43. }
  44. void CCSReplay::OnComplete()
  45. {
  46. BaseClass::OnComplete();
  47. }
  48. void CCSReplay::Update()
  49. {
  50. BaseClass::Update();
  51. }
  52. float CCSReplay::GetSentryKillScreenshotDelay()
  53. {
  54. ConVarRef replay_screenshotsentrykilldelay( "replay_screenshotsentrykilldelay" );
  55. return replay_screenshotsentrykilldelay.IsValid() ? replay_screenshotsentrykilldelay.GetFloat() : 0.5f;
  56. }
  57. void CCSReplay::FireGameEvent( IGameEvent *pEvent )
  58. {
  59. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  60. if ( !pLocalPlayer )
  61. return;
  62. CaptureScreenshotParams_t params;
  63. V_memset( &params, 0, sizeof( params ) );
  64. if ( FStrEq( pEvent->GetName(), "player_death" ) )
  65. {
  66. ConVarRef replay_debug( "replay_debug" );
  67. if ( replay_debug.IsValid() && replay_debug.GetBool() )
  68. {
  69. DevMsg( "%i: CCSReplay::FireGameEvent(): player_death\n", gpGlobals->tickcount );
  70. }
  71. int nKillerID = pEvent->GetInt( "attacker" );
  72. int nVictimID = pEvent->GetInt( "userid" );
  73. int nDeathFlags = pEvent->GetInt( "death_flags" );
  74. const char *pWeaponName = pEvent->GetString( "weapon" );
  75. // Suicide?
  76. bool bSuicide = nKillerID == nVictimID;
  77. // Try to get killer
  78. C_CSPlayer *pKiller = ToCSPlayer( USERID2PLAYER( nKillerID ) );
  79. // Try to get victim
  80. C_CSPlayer *pVictim = ToCSPlayer( USERID2PLAYER( nVictimID ) );
  81. // Inflictor was a sentry gun?
  82. bool bSentry = V_strnicmp( pWeaponName, "obj_sentrygun", 13 ) == 0;
  83. // Is the killer the local player?
  84. if ( nKillerID == pLocalPlayer->GetUserID() &&
  85. !bSuicide &&
  86. !bSentry )
  87. {
  88. // Domination?
  89. if ( nDeathFlags & REPLAY_DEATH_DOMINATION )
  90. {
  91. AddDomination( nVictimID );
  92. }
  93. // Revenge?
  94. if ( pEvent->GetInt( "death_flags" ) & REPLAY_DEATH_REVENGE )
  95. {
  96. AddRevenge( nVictimID );
  97. }
  98. // Add victim info to kill list
  99. if ( pVictim )
  100. {
  101. AddKill( pVictim->GetPlayerName(), pVictim->PlayerClass() );
  102. }
  103. // Take a quick screenshot with some delay
  104. ConVarRef replay_screenshotkilldelay( "replay_screenshotkilldelay" );
  105. if ( replay_screenshotkilldelay.IsValid() )
  106. {
  107. params.m_flDelay = GetKillScreenshotDelay();
  108. g_pReplayScreenshotManager->CaptureScreenshot( params );
  109. }
  110. }
  111. // Player death?
  112. else if ( pKiller &&
  113. nVictimID == pLocalPlayer->GetUserID() )
  114. {
  115. // Record who killed the player if not a suicide
  116. if ( !bSuicide )
  117. {
  118. RecordPlayerDeath( pKiller->GetPlayerName(), pKiller->PlayerClass() );
  119. }
  120. // Take screenshot - taking a screenshot during feign death is cool, too.
  121. ConVarRef replay_deathcammaxverticaloffset( "replay_deathcammaxverticaloffset" );
  122. ConVarRef replay_playerdeathscreenshotdelay( "replay_playerdeathscreenshotdelay" );
  123. params.m_flDelay = replay_playerdeathscreenshotdelay.IsValid() ? replay_playerdeathscreenshotdelay.GetFloat() : 0.0f;
  124. params.m_nEntity = pLocalPlayer->entindex();
  125. params.m_posCamera.Init( 0,0, replay_deathcammaxverticaloffset.IsValid() ? replay_deathcammaxverticaloffset.GetFloat() : 150 );
  126. params.m_angCamera.Init( 90, 0, 0 ); // Look straight down
  127. params.m_bUseCameraAngles = true;
  128. params.m_bIgnoreMinTimeBetweenScreenshots = true;
  129. g_pReplayScreenshotManager->CaptureScreenshot( params );
  130. }
  131. }
  132. }
  133. bool CCSReplay::IsValidClass( int iClass ) const
  134. {
  135. return ( iClass >= CS_CLASS_NONE && iClass < CS_NUM_CLASSES );
  136. }
  137. bool CCSReplay::IsValidTeam( int iTeam ) const
  138. {
  139. return ( iTeam == TEAM_TERRORIST || iTeam == TEAM_CT );
  140. }
  141. bool CCSReplay::GetCurrentStats( RoundStats_t &out )
  142. {
  143. out = g_CSClientGameStats.GetLifetimeStats();
  144. return true;
  145. }
  146. const char *CCSReplay::GetStatString( int iStat ) const
  147. {
  148. return CSStatProperty_Table[ iStat ].szSteamName;
  149. }
  150. const char *CCSReplay::GetPlayerClass( int iClass ) const
  151. {
  152. Assert( iClass >= CS_CLASS_NONE && iClass < CS_NUM_CLASSES );
  153. return GetCSClassInfo( iClass )->m_pClassName;
  154. }
  155. bool CCSReplay::Read( KeyValues *pIn )
  156. {
  157. return BaseClass::Read( pIn );
  158. }
  159. void CCSReplay::Write( KeyValues *pOut )
  160. {
  161. BaseClass::Write( pOut );
  162. }
  163. const char *CCSReplay::GetMaterialFriendlyPlayerClass() const
  164. {
  165. return BaseClass::GetMaterialFriendlyPlayerClass();
  166. }
  167. void CCSReplay::DumpGameSpecificData() const
  168. {
  169. BaseClass::DumpGameSpecificData();
  170. }
  171. //----------------------------------------------------------------------------------------
  172. class CCSReplayFactory : public IReplayFactory
  173. {
  174. public:
  175. virtual CReplay *Create()
  176. {
  177. return new CCSReplay();
  178. }
  179. };
  180. static CCSReplayFactory s_ReplayManager;
  181. IReplayFactory *g_pReplayFactory = &s_ReplayManager;
  182. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CCSReplayFactory, IReplayFactory, INTERFACE_VERSION_REPLAY_FACTORY, s_ReplayManager );
  183. #endif