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.

218 lines
6.4 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. //=============================================================================//
  4. #include "cbase.h"
  5. #include "paint_cleanser_manager.h"
  6. #include "igameevents.h"
  7. #ifdef CLIENT_DLL
  8. #include "c_trigger_paint_cleanser.h"
  9. #include "debugoverlay_shared.h"
  10. ConVar paint_cleanser_visibility_poll_frequency( "paint_cleanser_visibility_poll_rate", "0.5", FCVAR_CHEAT );
  11. ConVar paint_cleanser_visibility_checks_debug( "paint_cleanser_visibility_checks_debug", "0", FCVAR_DEVELOPMENTONLY );
  12. ConVar paint_cleanser_visibility_range( "paint_cleanser_visibility_range", "1000.0f", FCVAR_CHEAT );
  13. ConVar paint_cleanser_visibility_look_angle( "paint_cleanser_visibility_look_angle", "60.0f", FCVAR_CHEAT );
  14. #else
  15. #include "trigger_paint_cleanser.h"
  16. #endif
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. CPaintCleanserManager PaintCleanserManager( "PaintCleanserManager" );
  20. CPaintCleanserManager::CPaintCleanserManager( char const *name )
  21. #ifdef CLIENT_DLL
  22. : CAutoGameSystemPerFrame( name ),
  23. m_flNextPollTime( 0.0f )
  24. #else
  25. : CAutoGameSystem( name )
  26. #endif
  27. {
  28. #ifdef CLIENT_DLL
  29. memset( m_ppVisibleCleanser, 0, sizeof(m_ppVisibleCleanser) );
  30. #endif
  31. }
  32. CPaintCleanserManager::~CPaintCleanserManager( void )
  33. {
  34. }
  35. void CPaintCleanserManager::LevelInitPreEntity()
  36. {
  37. #ifdef CLIENT_DLL
  38. m_flNextPollTime = gpGlobals->curtime + paint_cleanser_visibility_poll_frequency.GetFloat();
  39. #endif
  40. }
  41. void CPaintCleanserManager::LevelShutdownPreEntity()
  42. {
  43. m_PaintCleansers.RemoveAll();
  44. }
  45. void CPaintCleanserManager::AddPaintCleanser( C_TriggerPaintCleanser *pCleanser )
  46. {
  47. m_PaintCleansers.AddToTail( pCleanser );
  48. }
  49. void CPaintCleanserManager::RemovePaintCleanser( C_TriggerPaintCleanser *pCleanser )
  50. {
  51. m_PaintCleansers.FindAndRemove( pCleanser );
  52. }
  53. void CPaintCleanserManager::GetPaintCleansers( PaintCleanserVector_t& paintCleansers )
  54. {
  55. paintCleansers = m_PaintCleansers;
  56. }
  57. #ifdef CLIENT_DLL
  58. void CPaintCleanserManager::Update( float frametime )
  59. {
  60. //Check if it is time to update the cleanser visibility
  61. if( gpGlobals->curtime < m_flNextPollTime )
  62. {
  63. return;
  64. }
  65. //Set the time for the next check
  66. m_flNextPollTime = gpGlobals->curtime + paint_cleanser_visibility_poll_frequency.GetFloat();
  67. UpdatePaintCleanserVisibility();
  68. }
  69. void CPaintCleanserManager::UpdatePaintCleanserVisibility( void )
  70. {
  71. FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh )
  72. {
  73. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer( hh );
  74. if( !pPlayer )
  75. continue;
  76. Vector vecPlayerForward;
  77. AngleVectors( pPlayer->EyeAngles(), &vecPlayerForward );
  78. VectorNormalize( vecPlayerForward );
  79. Vector vecPlayerEyePos = pPlayer->EyePosition();
  80. //Max distance to check for visibility
  81. float flVisibilityRange = paint_cleanser_visibility_range.GetFloat() * paint_cleanser_visibility_range.GetFloat();
  82. bool bDebugging = paint_cleanser_visibility_checks_debug.GetBool();
  83. float flClosestCleanserDist = FLT_MAX;
  84. C_TriggerPaintCleanser *pClosestCleanser = NULL;
  85. //If there is a cleanser visible before the check
  86. bool bCleanserWasVisible = m_ppVisibleCleanser[hh] ? true : false;
  87. for( int i = 0; i < m_PaintCleansers.Count(); ++i )
  88. {
  89. Vector vecCleanserPos = m_PaintCleansers[i]->WorldSpaceCenter();
  90. //Don't test the cleanser if the player is too far from it
  91. float flDistSqr = vecPlayerEyePos.DistToSqr( vecCleanserPos );
  92. if( flDistSqr > flVisibilityRange )
  93. {
  94. if( m_ppVisibleCleanser[hh] == m_PaintCleansers[i] )
  95. {
  96. m_ppVisibleCleanser[hh] = NULL;
  97. }
  98. continue;
  99. }
  100. //Don't test the cleanser if the player isn't looking in its direction
  101. Vector vecPlayerCleanserDir = vecCleanserPos - vecPlayerEyePos;
  102. VectorNormalize( vecPlayerCleanserDir );
  103. float flPlayerCleanserAngle = RAD2DEG( acos( DotProduct( vecPlayerForward, vecPlayerCleanserDir ) ) );
  104. if( flPlayerCleanserAngle >= paint_cleanser_visibility_look_angle.GetFloat() )
  105. {
  106. if( m_ppVisibleCleanser[hh] == m_PaintCleansers[i] )
  107. {
  108. m_ppVisibleCleanser[hh] = NULL;
  109. }
  110. continue;
  111. }
  112. //Trace from the player's eye to the paint cleanser
  113. Ray_t playerCleanserRay;
  114. playerCleanserRay.Init( vecPlayerEyePos, vecCleanserPos );
  115. trace_t tr;
  116. int mask = MASK_BLOCKLOS_AND_NPCS & ~CONTENTS_BLOCKLOS;
  117. UTIL_TraceRay( playerCleanserRay, mask, pPlayer, COLLISION_GROUP_NONE, &tr );
  118. //If there is nothing between the player and the cleanser
  119. if( tr.fraction == 1.0f || tr.m_pEnt == m_PaintCleansers[i] )
  120. {
  121. if( bDebugging )
  122. {
  123. NDebugOverlay::Line( pPlayer->WorldSpaceCenter(), vecCleanserPos, 0, 255, 255, false, paint_cleanser_visibility_poll_frequency.GetFloat() );
  124. }
  125. Color debugColor( 255, 0, 0 );
  126. //If this is the closest visible paint cleanser
  127. if( flDistSqr < flClosestCleanserDist )
  128. {
  129. flClosestCleanserDist = flDistSqr;
  130. pClosestCleanser = m_PaintCleansers[i];
  131. debugColor = Color( 0, 255, 0 );
  132. }
  133. if( bDebugging )
  134. {
  135. NDebugOverlay::Cross3D( vecCleanserPos, 16, debugColor.r(), debugColor.g(), debugColor.b(), false, paint_cleanser_visibility_poll_frequency.GetFloat() );
  136. }
  137. }
  138. else
  139. {
  140. if( bDebugging )
  141. {
  142. NDebugOverlay::Line( pPlayer->WorldSpaceCenter(), vecCleanserPos, 0, 0, 255, false, paint_cleanser_visibility_poll_frequency.GetFloat() );
  143. }
  144. }
  145. } //For all the paint cleansers
  146. //If the player can see a different cleanser
  147. if( pClosestCleanser && pClosestCleanser != m_ppVisibleCleanser[hh] )
  148. {
  149. m_ppVisibleCleanser[hh] = pClosestCleanser;
  150. if( pPlayer->Weapon_OwnsThisType( "weapon_paintgun" ) )
  151. {
  152. IGameEvent *event = gameeventmanager->CreateEvent( "paint_cleanser_visible" );
  153. if ( event )
  154. {
  155. event->SetInt( "userid", pPlayer->GetUserID() );
  156. event->SetInt( "subject", m_ppVisibleCleanser[hh]->entindex() );
  157. gameeventmanager->FireEventClientSide( event );
  158. }
  159. }
  160. }
  161. //If there is no visible cleanser
  162. else if( !m_ppVisibleCleanser[hh] && bCleanserWasVisible )
  163. {
  164. IGameEvent *event = gameeventmanager->CreateEvent( "paint_cleanser_not_visible" );
  165. if( event )
  166. {
  167. event->SetInt( "userid", pPlayer->GetUserID() );
  168. gameeventmanager->FireEventClientSide( event );
  169. }
  170. }
  171. } //for each pPlayer
  172. }
  173. #endif