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.

232 lines
5.6 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. //=============================================================================//
  4. #include "cbase.h"
  5. #include "paint_stream_shared.h"
  6. #include "paint_stream_manager.h"
  7. #include <functional>
  8. #include <algorithm>
  9. #include "paint_power_user.h"
  10. #include "vstdlib/jobthread.h"
  11. #ifdef CLIENT_DLL
  12. #include "collisionutils.h"
  13. #include "c_paint_stream.h"
  14. #include "c_paintblob.h"
  15. #else
  16. #include "paint_stream.h"
  17. #include "cpaintblob.h"
  18. #endif
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. #define VPROF_BUDGETGROUP_PAINTBLOB _T("Paintblob")
  22. ConVar max_sound_channels_per_paint_stream("max_sound_channels_per_paint_stream", "7", FCVAR_REPLICATED | FCVAR_CHEAT);
  23. IMPLEMENT_SHAREDCLASS_DT( CPaintStream )
  24. SharedProp( m_sharedBlobData )
  25. SharedProp( m_sharedBlobDataMutex )
  26. END_SHARED_TABLE()
  27. void CPaintStream::UpdateOnRemove()
  28. {
  29. RemoveAllPaintBlobs();
  30. BaseClass::UpdateOnRemove();
  31. }
  32. void CPaintStream::RemoveAllPaintBlobs( void )
  33. {
  34. #ifdef CLIENT_DLL
  35. RemoveFromLeafSystem();
  36. #endif
  37. }
  38. unsigned int CPaintStream::GetBlobsCount() const
  39. {
  40. return m_blobs.Count();
  41. }
  42. CPaintBlob* CPaintStream::GetBlob( int id )
  43. {
  44. return m_blobs[id];
  45. }
  46. struct ShouldNotDeleteBlob_t : std::unary_function< CPaintBlob*, bool >
  47. {
  48. inline bool operator()( const CPaintBlob* pBlob ) const
  49. {
  50. return !pBlob->ShouldDeleteThis();
  51. }
  52. };
  53. void CPaintStream::RemoveDeadBlobs()
  54. {
  55. CPaintBlob** begin = GetBegin( m_blobs );
  56. CPaintBlob** end = GetEnd( m_blobs );
  57. CPaintBlob** middle = std::partition( begin, end, ShouldNotDeleteBlob_t() );
  58. for( CPaintBlob** i = middle; i != end; ++i )
  59. {
  60. PaintStreamManager.FreeBlob( *i );
  61. }
  62. int numRemoved = end - middle;
  63. m_blobs.RemoveMultipleFromTail( numRemoved );
  64. }
  65. struct TimeElapsed : public std::unary_function<TimeStamp, bool>
  66. {
  67. TimeStamp m_CurrentTime;
  68. TimeElapsed( TimeStamp currentTime ) : m_CurrentTime( currentTime ) {}
  69. inline bool operator()( TimeStamp time ) const
  70. {
  71. return time <= m_CurrentTime;
  72. }
  73. };
  74. void CPaintStream::QueuePaintEffect()
  75. {
  76. #ifdef GAME_DLL
  77. // if not listen server, don't do anything
  78. if ( engine->IsDedicatedServer() )
  79. return;
  80. #else
  81. // if we are listen server, don't do anything on client
  82. if ( engine->IsClientLocalToActiveServer() )
  83. return;
  84. #endif
  85. // Update how many channels are in use
  86. TimeElapsed timeElapsedPred( gpGlobals->curtime );
  87. TimeStamp* begin = m_UsedChannelTimestamps.Base();
  88. TimeStamp* end = begin + m_UsedChannelTimestamps.Count();
  89. TimeStamp* newEnd = std::remove_if( begin, end, timeElapsedPred );
  90. m_UsedChannelTimestamps.RemoveMultipleFromTail( end - newEnd );
  91. // Try to queue up effects for each impact that occurred
  92. PaintImpactEffect const impactEffect = (m_nRenderMode == BLOB_RENDER_BLOBULATOR) ? PAINT_STREAM_IMPACT_EFFECT : PAINT_DRIP_IMPACT_EFFECT;
  93. int const maxChannels = max_sound_channels_per_paint_stream.GetInt();
  94. CUtlVectorFixedGrowable<Vector, 32> soundPositions;
  95. for ( int i = 0; i < m_blobs.Count(); ++i )
  96. {
  97. CPaintBlob *pBlob = m_blobs[i];
  98. if ( pBlob->ShouldPlayEffect() && !pBlob->IsSilent() )
  99. {
  100. PaintStreamManager.CreatePaintImpactParticles( pBlob->GetPosition(), pBlob->GetContactNormal(), m_nPaintType );
  101. if( pBlob->ShouldPlaySound() )
  102. soundPositions.AddToTail( pBlob->GetPosition() );
  103. }
  104. }
  105. if( soundPositions.Count() != 0 )
  106. PaintStreamManager.PlayMultiplePaintImpactSounds( m_UsedChannelTimestamps, maxChannels, soundPositions, impactEffect );
  107. }
  108. void CPaintStream::PreUpdateBlobs()
  109. {
  110. RemoveDeadBlobs();
  111. DebugDrawBlobs();
  112. }
  113. void CPaintStream::PostUpdateBlobs()
  114. {
  115. RemoveTeleportedThisFrameBlobs();
  116. UpdateRenderBoundsAndOriginWorldspace();
  117. QueuePaintEffect();
  118. #ifdef GAME_DLL
  119. AddPaintToDatabase();
  120. UpdateBlobSharedData();
  121. #endif
  122. // reset blobs teleported this frame flag
  123. ResetBlobsTeleportedThisFrame();
  124. }
  125. const Vector& CPaintStream::WorldAlignMins() const
  126. {
  127. return m_vCachedWorldMins;
  128. }
  129. const Vector& CPaintStream::WorldAlignMaxs() const
  130. {
  131. return m_vCachedWorldMaxs;
  132. }
  133. struct TeleportedThisFrameBlob_t : std::unary_function< CPaintBlob*, bool >
  134. {
  135. TeleportedThisFrameBlob_t( int nMaxTeleportationCount ) : m_nMaxTeleportationCount( nMaxTeleportationCount )
  136. {
  137. }
  138. inline bool operator()( const CPaintBlob* pBlob ) const
  139. {
  140. return pBlob->HasBlobTeleportedThisFrame() && ( pBlob->GetTeleportationCount() >= m_nMaxTeleportationCount );
  141. }
  142. int m_nMaxTeleportationCount;
  143. };
  144. //-----------------------------------------------------------------------------------------------
  145. // Purpose: Remove blobs that have teleported this frame if the stream reaches max blob count
  146. //-----------------------------------------------------------------------------------------------
  147. void CPaintStream::RemoveTeleportedThisFrameBlobs()
  148. {
  149. if ( m_nRenderMode == BLOB_RENDER_FAST_SPHERE )
  150. {
  151. Assert( m_blobs.Count() <= m_nMaxBlobCount );
  152. if ( m_blobs.Count() == m_nMaxBlobCount )
  153. {
  154. CPaintBlob** begin = GetBegin( m_blobs );
  155. CPaintBlob** end = GetEnd( m_blobs );
  156. CPaintBlob** middle = std::partition( begin, end, TeleportedThisFrameBlob_t( 4 ) );
  157. for( CPaintBlob** i = begin; i != middle; ++i )
  158. {
  159. PaintStreamManager.FreeBlob( *i );
  160. }
  161. int numRemoved = middle - begin;
  162. m_blobs.RemoveMultipleFromHead( numRemoved );
  163. }
  164. }
  165. }
  166. void CPaintStream::ResetBlobsTeleportedThisFrame()
  167. {
  168. for ( int i=0; i<m_blobs.Count(); ++i )
  169. {
  170. m_blobs[i]->SetBlobTeleportedThisFrame( false );
  171. }
  172. }