Counter Strike : Global Offensive Source Code
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.

210 lines
5.2 KiB

  1. //============ Copyright (c) Valve Corporation, All rights reserved. ============
  2. #include "cbase.h"
  3. #include "game_timescale_shared.h"
  4. #include "usermessages.h"
  5. #ifdef CLIENT_DLL
  6. #include "c_user_message_register.h"
  7. #endif
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. CGameTimescale g_GameTimescale;
  11. CGameTimescale* GameTimescale() { return &g_GameTimescale; }
  12. CGameTimescale::CGameTimescale( void ) : CAutoGameSystemPerFrame( "CGameTimescale" )
  13. {
  14. m_flStartBlendRealtime = 0.0f;
  15. }
  16. CGameTimescale::~CGameTimescale()
  17. {
  18. }
  19. bool CGameTimescale::Init()
  20. {
  21. ResetTimescale();
  22. return true;
  23. }
  24. void CGameTimescale::Shutdown()
  25. {
  26. ResetTimescale();
  27. }
  28. #ifdef CLIENT_DLL
  29. void CGameTimescale::Update( float frametime )
  30. {
  31. UpdateTimescale();
  32. }
  33. #else
  34. void CGameTimescale::FrameUpdatePostEntityThink()
  35. {
  36. UpdateTimescale();
  37. }
  38. #endif
  39. void CGameTimescale::LevelInitPostEntity()
  40. {
  41. ResetTimescale();
  42. }
  43. void CGameTimescale::LevelShutdownPostEntity()
  44. {
  45. ResetTimescale();
  46. }
  47. void CGameTimescale::SetCurrentTimescale( float flTimescale )
  48. {
  49. if ( m_flCurrentTimescale == flTimescale && m_flCurrentTimescale == engine->GetTimescale() )
  50. return;
  51. // No ramp in/out, just set it!
  52. m_flDesiredTimescale = flTimescale;
  53. m_flCurrentTimescale = m_flDesiredTimescale;
  54. m_flDurationRealTimeSeconds = 0.0f;
  55. m_nInterpolatorType = INTERPOLATOR_LINEAR;
  56. m_flStartBlendTime = 0.0f;
  57. m_flStartBlendRealtime = 0.0f;
  58. #ifndef CLIENT_DLL
  59. engine->SetTimescale( m_flCurrentTimescale );
  60. // Pass the change info to the client so it can do prediction
  61. CReliableBroadcastRecipientFilter filter;
  62. CCSUsrMsg_CurrentTimescale msg;
  63. msg.set_cur_timescale( m_flCurrentTimescale );
  64. SendUserMessage( filter, CS_UM_CurrentTimescale, msg );
  65. #endif
  66. }
  67. void CGameTimescale::SetDesiredTimescaleAtTime( float flDesiredTimescale, float flDurationRealTimeSeconds /*= 0.0f*/, Interpolators_e nInterpolatorType /*= INTERPOLATOR_LINEAR*/, float flStartBlendTime /*= 0.0f*/ )
  68. {
  69. SetDesiredTimescale( flDesiredTimescale, flDurationRealTimeSeconds, nInterpolatorType, MAX( 0.0f, flStartBlendTime - gpGlobals->curtime ) );
  70. }
  71. void CGameTimescale::SetDesiredTimescale( float flDesiredTimescale, float flDurationRealTimeSeconds /*= 0.0f*/, Interpolators_e nInterpolatorType /*= INTERPOLATOR_LINEAR*/, float flDelayRealtime /*= 0.0f*/ )
  72. {
  73. if ( m_flDesiredTimescale == flDesiredTimescale )
  74. return;
  75. m_flDesiredTimescale = flDesiredTimescale;
  76. m_flDurationRealTimeSeconds = flDurationRealTimeSeconds;
  77. m_nInterpolatorType = nInterpolatorType;
  78. m_flStartBlendTime = gpGlobals->curtime + flDelayRealtime * m_flCurrentTimescale;
  79. if ( gpGlobals->curtime >= m_flStartBlendTime )
  80. {
  81. m_flStartBlendRealtime = gpGlobals->realtime;
  82. }
  83. else
  84. {
  85. m_flStartBlendRealtime = 0.0f;
  86. }
  87. m_flStartTimescale = m_flCurrentTimescale;
  88. #ifndef CLIENT_DLL
  89. // Pass the change info to the client so it can do prediction
  90. CReliableBroadcastRecipientFilter filter;
  91. CCSUsrMsg_DesiredTimescale msg;
  92. msg.set_desired_timescale( m_flDesiredTimescale );
  93. msg.set_duration_realtime_sec( m_flDurationRealTimeSeconds );
  94. msg.set_interpolator_type( m_nInterpolatorType );
  95. msg.set_start_blend_time( m_flStartBlendTime );
  96. SendUserMessage( filter, CS_UM_DesiredTimescale, msg );
  97. #endif
  98. }
  99. void CGameTimescale::UpdateTimescale( void )
  100. {
  101. if ( engine->IsPaused() )
  102. return;
  103. if ( m_flCurrentTimescale != m_flDesiredTimescale )
  104. {
  105. if ( gpGlobals->curtime >= m_flStartBlendTime )
  106. {
  107. if ( m_flStartBlendRealtime == 0.0f )
  108. {
  109. m_flStartBlendRealtime = gpGlobals->realtime;
  110. }
  111. float flInterp = 1.0f;
  112. if ( m_flDurationRealTimeSeconds > 0.0f )
  113. {
  114. flInterp = MIN( 1.0f, ( gpGlobals->realtime - m_flStartBlendRealtime ) / m_flDurationRealTimeSeconds );
  115. }
  116. switch ( m_nInterpolatorType )
  117. {
  118. case INTERPOLATOR_ACCEL:
  119. flInterp = Bias( flInterp, 0.25f );
  120. break;
  121. case INTERPOLATOR_DEACCEL:
  122. flInterp = Bias( flInterp, 0.75f );
  123. break;
  124. case INTERPOLATOR_EASE_IN_OUT:
  125. flInterp = Gain( flInterp, 0.75f );
  126. break;
  127. }
  128. m_flCurrentTimescale = m_flStartTimescale * ( 1.0f - flInterp ) + m_flDesiredTimescale * flInterp;
  129. }
  130. }
  131. if ( m_flCurrentTimescale != engine->GetTimescale() )
  132. {
  133. engine->SetTimescale( m_flCurrentTimescale );
  134. }
  135. }
  136. void CGameTimescale::ResetTimescale( void )
  137. {
  138. m_flDesiredTimescale = 1.0f;
  139. m_flCurrentTimescale = 1.0f;
  140. m_flDurationRealTimeSeconds = 0.0f;
  141. m_nInterpolatorType = INTERPOLATOR_LINEAR;
  142. m_flStartBlendTime = 0.0f;
  143. m_flStartBlendRealtime = 0.0f;
  144. engine->SetTimescale( 1.0f );
  145. }
  146. #ifdef CLIENT_DLL
  147. bool __MsgFunc_CurrentTimescale( const CCSUsrMsg_CurrentTimescale &msg )
  148. {
  149. GameTimescale()->SetCurrentTimescale( msg.cur_timescale() );
  150. return true;
  151. }
  152. USER_MESSAGE_REGISTER( CurrentTimescale );
  153. bool __MsgFunc_DesiredTimescale( const CCSUsrMsg_DesiredTimescale &msg )
  154. {
  155. float flDesiredTimescale = msg.desired_timescale();
  156. float flDurationRealTimeSeconds = msg.duration_realtime_sec();
  157. CGameTimescale::Interpolators_e nInterpolatorType = static_cast< CGameTimescale::Interpolators_e >( msg.interpolator_type() );
  158. float flStartBlendTime = msg.start_blend_time();
  159. GameTimescale()->SetDesiredTimescaleAtTime( flDesiredTimescale, flDurationRealTimeSeconds, nInterpolatorType, flStartBlendTime );
  160. return true;
  161. }
  162. USER_MESSAGE_REGISTER( DesiredTimescale );
  163. #endif //#ifdef CLIENT_DLL