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.

1099 lines
34 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Shared util code between client and server.
  4. //
  5. //=============================================================================//
  6. #ifndef UTIL_SHARED_H
  7. #define UTIL_SHARED_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "mathlib/vector.h"
  12. #include "cmodel.h"
  13. #include "utlvector.h"
  14. #include "networkvar.h"
  15. #include "engine/IEngineTrace.h"
  16. #include "engine/IStaticPropMgr.h"
  17. #include "shared_classnames.h"
  18. #ifdef CLIENT_DLL
  19. #include "cdll_client_int.h"
  20. #endif
  21. #ifdef PORTAL
  22. #include "portal_util_shared.h"
  23. #endif
  24. //-----------------------------------------------------------------------------
  25. // Forward declarations
  26. //-----------------------------------------------------------------------------
  27. class CGameTrace;
  28. class CBasePlayer;
  29. typedef CGameTrace trace_t;
  30. extern ConVar developer; // developer mode
  31. //-----------------------------------------------------------------------------
  32. // Language IDs.
  33. //-----------------------------------------------------------------------------
  34. #define LANGUAGE_ENGLISH 0
  35. #define LANGUAGE_GERMAN 1
  36. #define LANGUAGE_FRENCH 2
  37. #define LANGUAGE_BRITISH 3
  38. //-----------------------------------------------------------------------------
  39. // Pitch + yaw
  40. //-----------------------------------------------------------------------------
  41. float UTIL_VecToYaw (const Vector &vec);
  42. float UTIL_VecToPitch (const Vector &vec);
  43. float UTIL_VecToYaw (const matrix3x4_t& matrix, const Vector &vec);
  44. float UTIL_VecToPitch (const matrix3x4_t& matrix, const Vector &vec);
  45. Vector UTIL_YawToVector ( float yaw );
  46. //-----------------------------------------------------------------------------
  47. // Shared random number generators for shared/predicted code:
  48. // whenever generating random numbers in shared/predicted code, these functions
  49. // have to be used. Each call should specify a unique "sharedname" string that
  50. // seeds the random number generator. In loops make sure the "additionalSeed"
  51. // is increased with the loop counter, otherwise it will always return the
  52. // same random number
  53. //-----------------------------------------------------------------------------
  54. float SharedRandomFloat( const char *sharedname, float flMinVal, float flMaxVal, int additionalSeed = 0 );
  55. int SharedRandomInt( const char *sharedname, int iMinVal, int iMaxVal, int additionalSeed = 0 );
  56. Vector SharedRandomVector( const char *sharedname, float minVal, float maxVal, int additionalSeed = 0 );
  57. QAngle SharedRandomAngle( const char *sharedname, float minVal, float maxVal, int additionalSeed = 0 );
  58. //-----------------------------------------------------------------------------
  59. // Standard collision filters...
  60. //-----------------------------------------------------------------------------
  61. bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *pPass );
  62. bool StandardFilterRules( IHandleEntity *pHandleEntity, int fContentsMask );
  63. // "weapon_"
  64. #define WEAPON_CLASSNAME_PREFIX_LENGTH 7
  65. bool IsWeaponClassname( const char *pszClassName );
  66. //-----------------------------------------------------------------------------
  67. // Converts an IHandleEntity to an CBaseEntity
  68. //-----------------------------------------------------------------------------
  69. inline const CBaseEntity *EntityFromEntityHandle( const IHandleEntity *pConstHandleEntity )
  70. {
  71. IHandleEntity *pHandleEntity = const_cast<IHandleEntity*>(pConstHandleEntity);
  72. #ifdef CLIENT_DLL
  73. IClientUnknown *pUnk = (IClientUnknown*)pHandleEntity;
  74. return pUnk->GetBaseEntity();
  75. #else
  76. if ( staticpropmgr->IsStaticProp( pHandleEntity ) )
  77. return NULL;
  78. IServerUnknown *pUnk = (IServerUnknown*)pHandleEntity;
  79. return pUnk->GetBaseEntity();
  80. #endif
  81. }
  82. inline CBaseEntity *EntityFromEntityHandle( IHandleEntity *pHandleEntity )
  83. {
  84. #ifdef CLIENT_DLL
  85. IClientUnknown *pUnk = (IClientUnknown*)pHandleEntity;
  86. return pUnk->GetBaseEntity();
  87. #else
  88. #ifndef _GAMECONSOLE
  89. if ( staticpropmgr->IsStaticProp( pHandleEntity ) )
  90. return NULL;
  91. #else
  92. if ( !pHandleEntity || pHandleEntity->m_bIsStaticProp )
  93. return NULL;
  94. #endif
  95. IServerUnknown *pUnk = (IServerUnknown*)pHandleEntity;
  96. Assert( !pUnk || pUnk->GetBaseEntity() );
  97. return pUnk->GetBaseEntity();
  98. #endif
  99. }
  100. typedef bool (*ShouldHitFunc_t)( IHandleEntity *pHandleEntity, int contentsMask );
  101. //-----------------------------------------------------------------------------
  102. // traceline methods
  103. //-----------------------------------------------------------------------------
  104. class CTraceFilterSimple : public CTraceFilter
  105. {
  106. public:
  107. // It does have a base, but we'll never network anything below here..
  108. DECLARE_CLASS_NOBASE( CTraceFilterSimple );
  109. CTraceFilterSimple( const IHandleEntity *passentity, int collisionGroup, ShouldHitFunc_t pExtraShouldHitCheckFn = NULL );
  110. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  111. virtual void SetPassEntity( const IHandleEntity *pPassEntity ) { m_pPassEnt = pPassEntity; }
  112. virtual void SetCollisionGroup( int iCollisionGroup ) { m_collisionGroup = iCollisionGroup; }
  113. const IHandleEntity *GetPassEntity( void ){ return m_pPassEnt;}
  114. int GetCollisionGroup( void ) const { return m_collisionGroup; }
  115. private:
  116. const IHandleEntity *m_pPassEnt;
  117. int m_collisionGroup;
  118. ShouldHitFunc_t m_pExtraShouldHitCheckFunction;
  119. };
  120. class CTraceFilterSkipTwoEntities : public CTraceFilterSimple
  121. {
  122. public:
  123. // It does have a base, but we'll never network anything below here..
  124. DECLARE_CLASS( CTraceFilterSkipTwoEntities, CTraceFilterSimple );
  125. CTraceFilterSkipTwoEntities( const IHandleEntity *passentity = NULL, const IHandleEntity *passentity2 = NULL, int collisionGroup = COLLISION_GROUP_NONE );
  126. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  127. virtual void SetPassEntity2( const IHandleEntity *pPassEntity2 ) { m_pPassEnt2 = pPassEntity2; }
  128. private:
  129. const IHandleEntity *m_pPassEnt2;
  130. };
  131. class CTraceFilterSimpleList : public CTraceFilterSimple
  132. {
  133. public:
  134. CTraceFilterSimpleList( int collisionGroup );
  135. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  136. void AddEntityToIgnore( IHandleEntity *pEntity );
  137. void AddEntitiesToIgnore( int nCount, IHandleEntity **ppEntities );
  138. protected:
  139. CUtlVector<IHandleEntity*> m_PassEntities;
  140. };
  141. class CTraceFilterOnlyHitThis : public CTraceFilterEntitiesOnly
  142. {
  143. public:
  144. // It does have a base, but we'll never network anything below here..
  145. DECLARE_CLASS_NOBASE( CTraceFilterOnlyHitThis );
  146. CTraceFilterOnlyHitThis( const IHandleEntity *hitentity );
  147. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  148. private:
  149. const IHandleEntity *m_pHitEnt;
  150. };
  151. class CTraceFilterOnlyNPCsAndPlayer : public CTraceFilterSimple
  152. {
  153. public:
  154. CTraceFilterOnlyNPCsAndPlayer( const IHandleEntity *passentity, int collisionGroup )
  155. : CTraceFilterSimple( passentity, collisionGroup )
  156. {
  157. }
  158. virtual TraceType_t GetTraceType() const
  159. {
  160. return TRACE_ENTITIES_ONLY;
  161. }
  162. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  163. };
  164. class CTraceFilterNoNPCsOrPlayer : public CTraceFilterSimple
  165. {
  166. public:
  167. CTraceFilterNoNPCsOrPlayer( const IHandleEntity *passentity = NULL, int collisionGroup = COLLISION_GROUP_NONE )
  168. : CTraceFilterSimple( passentity, collisionGroup )
  169. {
  170. }
  171. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  172. };
  173. class CTraceFilterNoPlayers : public CTraceFilterSimple
  174. {
  175. public:
  176. CTraceFilterNoPlayers( const IHandleEntity *passentity = NULL, int collisionGroup = COLLISION_GROUP_NONE )
  177. : CTraceFilterSimple( passentity, collisionGroup )
  178. {
  179. }
  180. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  181. };
  182. //-----------------------------------------------------------------------------
  183. // Purpose: Custom trace filter used for NPC LOS traces
  184. //-----------------------------------------------------------------------------
  185. class CTraceFilterLOS : public CTraceFilterSkipTwoEntities
  186. {
  187. public:
  188. CTraceFilterLOS( IHandleEntity *pHandleEntity, int collisionGroup, IHandleEntity *pHandleEntity2 = NULL );
  189. bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  190. };
  191. class CTraceFilterSkipClassname : public CTraceFilterSimple
  192. {
  193. public:
  194. CTraceFilterSkipClassname( const IHandleEntity *passentity, const char *pchClassname, int collisionGroup );
  195. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  196. private:
  197. const char *m_pchClassname;
  198. };
  199. class CTraceFilterSkipTwoClassnames : public CTraceFilterSkipClassname
  200. {
  201. public:
  202. // It does have a base, but we'll never network anything below here..
  203. DECLARE_CLASS( CTraceFilterSkipTwoClassnames, CTraceFilterSkipClassname );
  204. CTraceFilterSkipTwoClassnames( const IHandleEntity *passentity, const char *pchClassname, const char *pchClassname2, int collisionGroup );
  205. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  206. private:
  207. const char *m_pchClassname2;
  208. };
  209. class CTraceFilterSimpleClassnameList : public CTraceFilterSimple
  210. {
  211. public:
  212. CTraceFilterSimpleClassnameList( const IHandleEntity *passentity, int collisionGroup );
  213. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  214. void AddClassnameToIgnore( const char *pchClassname );
  215. private:
  216. CUtlVector<const char*> m_PassClassnames;
  217. };
  218. class CTraceFilterChain : public CTraceFilter
  219. {
  220. public:
  221. CTraceFilterChain( ITraceFilter *pTraceFilter1, ITraceFilter *pTraceFilter2 );
  222. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  223. private:
  224. ITraceFilter *m_pTraceFilter1;
  225. ITraceFilter *m_pTraceFilter2;
  226. };
  227. // helper
  228. void DebugDrawLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, int r, int g, int b, bool test, float duration );
  229. extern ConVar r_visualizetraces;
  230. #ifdef DETECT_TRACE_SPIKES
  231. #define BeginDetectTraceSpike() \
  232. extern void DoReportExpensiveTrace( bool repeat, float time ); \
  233. extern float g_TraceSpikeTolerance; \
  234. CFastTimer spikeTimer; \
  235. spikeTimer.Start()
  236. #define EndDetectTraceSpike() \
  237. spikeTimer.End()
  238. #define DidTraceSpike() \
  239. ( spikeTimer.GetDuration().GetMillisecondsF() > g_TraceSpikeTolerance )
  240. #define ReportExpensiveTrace( repeat ) if ( DidTraceSpike() ) DoReportExpensiveTrace( repeat, spikeTimer.GetDuration().GetMillisecondsF() )
  241. #else
  242. #define BeginDetectTraceSpike() ((void)0)
  243. #define EndDetectTraceSpike() ((void)0)
  244. #define DidTraceSpike() false
  245. #define ReportExpensiveTrace( repeat ) ((void)0)
  246. #endif
  247. inline void UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
  248. const IHandleEntity *ignore, int collisionGroup, trace_t *ptr )
  249. {
  250. BeginDetectTraceSpike();
  251. Ray_t ray;
  252. ray.Init( vecAbsStart, vecAbsEnd );
  253. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  254. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  255. EndDetectTraceSpike();
  256. if( r_visualizetraces.GetBool() || DidTraceSpike() )
  257. {
  258. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, ( r_visualizetraces.GetBool() ) ? -1.0f : .5 );
  259. ReportExpensiveTrace( false );
  260. if ( DidTraceSpike() ) // Opimizer will remove this block
  261. {
  262. ReportExpensiveTrace( false );
  263. BeginDetectTraceSpike();
  264. Ray_t ray;
  265. ray.Init( vecAbsStart, vecAbsEnd );
  266. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  267. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  268. EndDetectTraceSpike();
  269. if ( DidTraceSpike() )
  270. {
  271. ReportExpensiveTrace( true );
  272. }
  273. }
  274. }
  275. }
  276. inline void UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
  277. ITraceFilter *pFilter, trace_t *ptr )
  278. {
  279. BeginDetectTraceSpike();
  280. Ray_t ray;
  281. ray.Init( vecAbsStart, vecAbsEnd );
  282. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  283. EndDetectTraceSpike();
  284. if( r_visualizetraces.GetBool() || DidTraceSpike() )
  285. {
  286. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, ( r_visualizetraces.GetBool() ) ? -1.0f : .5 );
  287. ReportExpensiveTrace( false );
  288. if ( DidTraceSpike() ) // Opimizer will remove this block
  289. {
  290. BeginDetectTraceSpike();
  291. Ray_t ray;
  292. ray.Init( vecAbsStart, vecAbsEnd );
  293. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  294. EndDetectTraceSpike();
  295. if ( DidTraceSpike() )
  296. {
  297. ReportExpensiveTrace( true );
  298. }
  299. }
  300. }
  301. }
  302. inline void UTIL_TraceHull( const Vector &vecAbsStart, const Vector &vecAbsEnd, const Vector &hullMin,
  303. const Vector &hullMax, unsigned int mask, const IHandleEntity *ignore,
  304. int collisionGroup, trace_t *ptr )
  305. {
  306. BeginDetectTraceSpike();
  307. Ray_t ray;
  308. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  309. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  310. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  311. EndDetectTraceSpike();
  312. if( r_visualizetraces.GetBool() || DidTraceSpike() )
  313. {
  314. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 255, 0, true, ( r_visualizetraces.GetBool() ) ? -1.0f : .5 );
  315. ReportExpensiveTrace( false );
  316. if ( DidTraceSpike() ) // Opimizer will remove this block
  317. {
  318. BeginDetectTraceSpike();
  319. Ray_t ray;
  320. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  321. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  322. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  323. EndDetectTraceSpike();
  324. if ( DidTraceSpike() )
  325. {
  326. ReportExpensiveTrace( true );
  327. }
  328. }
  329. }
  330. }
  331. inline void UTIL_TraceHull( const Vector &vecAbsStart, const Vector &vecAbsEnd, const Vector &hullMin,
  332. const Vector &hullMax, unsigned int mask, ITraceFilter *pFilter, trace_t *ptr )
  333. {
  334. BeginDetectTraceSpike();
  335. Ray_t ray;
  336. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  337. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  338. EndDetectTraceSpike();
  339. if( r_visualizetraces.GetBool() || DidTraceSpike() )
  340. {
  341. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 255, 0, true, ( r_visualizetraces.GetBool() ) ? -1.0f : .5 );
  342. ReportExpensiveTrace( false );
  343. if ( DidTraceSpike() ) // Opimizer will remove this block
  344. {
  345. BeginDetectTraceSpike();
  346. Ray_t ray;
  347. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  348. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  349. EndDetectTraceSpike();
  350. if( DidTraceSpike() )
  351. {
  352. ReportExpensiveTrace( true );
  353. }
  354. }
  355. }
  356. }
  357. inline void UTIL_TraceRay( const Ray_t &ray, unsigned int mask,
  358. const IHandleEntity *ignore, int collisionGroup, trace_t *ptr )
  359. {
  360. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  361. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  362. if( r_visualizetraces.GetBool() )
  363. {
  364. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f );
  365. }
  366. }
  367. inline void UTIL_TraceRay( const Ray_t &ray, unsigned int mask,
  368. ITraceFilter *pFilter, trace_t *ptr )
  369. {
  370. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  371. if( r_visualizetraces.GetBool() )
  372. {
  373. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f );
  374. }
  375. }
  376. // Sweeps a particular entity through the world
  377. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd, unsigned int mask, trace_t *ptr );
  378. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd,
  379. unsigned int mask, ITraceFilter *pFilter, trace_t *ptr );
  380. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd,
  381. unsigned int mask, const IHandleEntity *ignore, int collisionGroup, trace_t *ptr );
  382. bool UTIL_EntityHasMatchingRootParent( CBaseEntity *pRootParent, CBaseEntity *pEntity );
  383. inline int UTIL_PointContents( const Vector &vec, int contentsMask )
  384. {
  385. return enginetrace->GetPointContents( vec, contentsMask );
  386. }
  387. // Sweeps against a particular model, using collision rules
  388. void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin,
  389. const Vector &hullMax, CBaseEntity *pentModel, int collisionGroup, trace_t *ptr );
  390. void UTIL_ClipTraceToPlayers( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr );
  391. // Particle effect tracer
  392. void UTIL_ParticleTracer( const char *pszTracerEffectName, const Vector &vecStart, const Vector &vecEnd, int iEntIndex = 0, int iAttachment = 0, bool bWhiz = false );
  393. // Old style, non-particle system, tracers
  394. void UTIL_Tracer( const Vector &vecStart, const Vector &vecEnd, int iEntIndex = 0, int iAttachment = TRACER_DONT_USE_ATTACHMENT, float flVelocity = 0, bool bWhiz = false, const char *pCustomTracerName = NULL, int iParticleID = 0 );
  395. bool UTIL_IsLowViolence( void );
  396. bool UTIL_ShouldShowBlood( int bloodColor );
  397. void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount );
  398. void UTIL_BloodImpact( const Vector &pos, const Vector &dir, int color, int amount );
  399. void UTIL_BloodDecalTrace( trace_t *pTrace, int bloodColor );
  400. void UTIL_DecalTrace( trace_t *pTrace, char const *decalName );
  401. bool UTIL_IsSpaceEmpty( CBaseEntity *pMainEnt, const Vector &vMin, const Vector &vMax );
  402. bool UTIL_IsSpaceEmpty( CBaseEntity *pMainEnt, const Vector &vMin, const Vector &vMax, unsigned int mask, ITraceFilter *pFilter );
  403. // Search for water transition along a vertical line
  404. float UTIL_WaterLevel( const Vector &position, float minz, float maxz );
  405. // Like UTIL_WaterLevel, but *way* less expensive.
  406. // I didn't replace UTIL_WaterLevel everywhere to avoid breaking anything.
  407. float UTIL_FindWaterSurface( const Vector &position, float minz, float maxz );
  408. void UTIL_StringToVector( float *pVector, const char *pString );
  409. void UTIL_StringToFloatArray( float *pVector, int count, const char *pString );
  410. CBasePlayer *UTIL_PlayerByIndex( int entindex );
  411. // decodes/encodes a buffer using a 64bit ICE key (inplace)
  412. void UTIL_DecodeICE( unsigned char * buffer, int size, const unsigned char *key );
  413. void UTIL_EncodeICE( unsigned char * buffer, unsigned int size, const unsigned char *key );
  414. unsigned short UTIL_GetAchievementEventMask( void );
  415. //assumes the object is already in a mostly passable space
  416. #define FL_AXIS_DIRECTION_NONE ( 0 )
  417. #define FL_AXIS_DIRECTION_X ( 1 << 0 )
  418. #define FL_AXIS_DIRECTION_NX ( 1 << 1 )
  419. #define FL_AXIS_DIRECTION_Y ( 1 << 2 )
  420. #define FL_AXIS_DIRECTION_NY ( 1 << 3 )
  421. #define FL_AXIS_DIRECTION_Z ( 1 << 4 )
  422. #define FL_AXIS_DIRECTION_NZ ( 1 << 5 )
  423. struct FindClosestPassableSpace_TraceAdapter_t;
  424. typedef void (*FN_RayTraceAdapterFunc)( const Ray_t &ray, trace_t *pResult, FindClosestPassableSpace_TraceAdapter_t *pTraceAdapter );
  425. typedef bool (*FN_PointIsOutsideWorld)( const Vector &vTest, FindClosestPassableSpace_TraceAdapter_t *pTraceAdapter );
  426. //derive from this to tack on additional data to your adapted functions
  427. struct FindClosestPassableSpace_TraceAdapter_t
  428. {
  429. FN_RayTraceAdapterFunc pTraceFunc;
  430. FN_PointIsOutsideWorld pPointOutsideWorldFunc;
  431. ITraceFilter *pTraceFilter;
  432. unsigned int fMask;
  433. };
  434. bool UTIL_FindClosestPassableSpace( const Vector &vCenter, const Vector &vExtents, const Vector &vIndecisivePush, unsigned int iIterations, Vector &vCenterOut, int nAxisRestrictionFlags, FindClosestPassableSpace_TraceAdapter_t *pTraceAdapter );
  435. bool UTIL_FindClosestPassableSpace( const Vector &vCenter, const Vector &vExtents, const Vector &vIndecisivePush, ITraceFilter *pTraceFilter, unsigned int fMask, unsigned int iIterations, Vector &vCenterOut, int nAxisRestrictionFlags = FL_AXIS_DIRECTION_NONE );
  436. bool UTIL_FindClosestPassableSpace( CBaseEntity *pEntity, const Vector &vIndecisivePush, unsigned int fMask, unsigned int iIterations, Vector &vOriginOut, Vector *pStartingPosition = NULL, int nAxisRestrictionFlags = FL_AXIS_DIRECTION_NONE );
  437. bool UTIL_FindClosestPassableSpace( CBaseEntity *pEntity, const Vector &vIndecisivePush, unsigned int fMask, Vector *pStartingPosition = NULL, int nAxisRestrictionFlags = FL_AXIS_DIRECTION_NONE );
  438. //--------------------------------------------------------------------------------------------------------------
  439. /**
  440. * Given a position and a ray, return the shortest distance between the two.
  441. * If 'pos' is beyond either end of the ray, the returned distance is negated.
  442. */
  443. inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vector &rayEnd, float *along = NULL, Vector *pointOnRay = NULL )
  444. {
  445. Vector to = pos - rayStart;
  446. Vector dir = rayEnd - rayStart;
  447. float length = dir.NormalizeInPlace();
  448. float rangeAlong = DotProduct( dir, to );
  449. if (along)
  450. {
  451. *along = rangeAlong;
  452. }
  453. float range;
  454. if (rangeAlong < 0.0f)
  455. {
  456. // off start point
  457. range = -(pos - rayStart).Length();
  458. if (pointOnRay)
  459. {
  460. *pointOnRay = rayStart;
  461. }
  462. }
  463. else if (rangeAlong > length)
  464. {
  465. // off end point
  466. range = -(pos - rayEnd).Length();
  467. if (pointOnRay)
  468. {
  469. *pointOnRay = rayEnd;
  470. }
  471. }
  472. else // within ray bounds
  473. {
  474. Vector onRay = rayStart + rangeAlong * dir;
  475. range = (pos - onRay).Length();
  476. if (pointOnRay)
  477. {
  478. *pointOnRay = onRay;
  479. }
  480. }
  481. return range;
  482. }
  483. //--------------------------------------------------------------------------------------------------------------
  484. /**
  485. * Macro for creating an interface that when inherited from automatically maintains a list of instances
  486. * that inherit from that interface.
  487. */
  488. // interface for entities that want to a auto maintained global list
  489. #define DECLARE_AUTO_LIST( interfaceName ) \
  490. class interfaceName; \
  491. abstract_class interfaceName \
  492. { \
  493. public: \
  494. interfaceName( bool bAutoAdd = true ); \
  495. virtual ~interfaceName(); \
  496. virtual CBaseEntity* GetEntity( void ) = 0; \
  497. static void Add( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \
  498. static void Remove( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \
  499. static const CUtlVector< interfaceName* >& AutoList( void ) { return m_##interfaceName##AutoList; } \
  500. private: \
  501. static CUtlVector< interfaceName* > m_##interfaceName##AutoList; \
  502. };
  503. // Creates a simple function for accessing the higher level entity
  504. #define IMPLEMENT_AUTO_LIST_GET() \
  505. virtual CBaseEntity* GetEntity( void ) { return this; }
  506. // Creates the auto add/remove constructor/destructor...
  507. // Pass false to the constructor to not auto add
  508. #define IMPLEMENT_AUTO_LIST( interfaceName ) \
  509. CUtlVector< class interfaceName* > interfaceName::m_##interfaceName##AutoList; \
  510. interfaceName::interfaceName( bool bAutoAdd ) \
  511. { \
  512. if ( bAutoAdd ) \
  513. { \
  514. Add( this ); \
  515. } \
  516. } \
  517. interfaceName::~interfaceName() \
  518. { \
  519. Remove( this ); \
  520. }
  521. //--------------------------------------------------------------------------------------------------------------
  522. /**
  523. * Simple class for tracking intervals of game time.
  524. * Upon creation, the timer is invalidated. To measure time intervals, start the timer via Start().
  525. */
  526. class IntervalTimer
  527. {
  528. public:
  529. #ifdef CLIENT_DLL
  530. DECLARE_PREDICTABLE();
  531. #endif
  532. DECLARE_DATADESC();
  533. DECLARE_CLASS_NOBASE( IntervalTimer );
  534. DECLARE_EMBEDDED_NETWORKVAR();
  535. IntervalTimer( void ) : m_timestamp( -1.0f )
  536. {
  537. }
  538. void Reset( void )
  539. {
  540. m_timestamp = Now();
  541. }
  542. void Start( void )
  543. {
  544. m_timestamp = Now();
  545. }
  546. void StartFromTime( float startTime )
  547. {
  548. m_timestamp = startTime;
  549. }
  550. void Invalidate( void )
  551. {
  552. m_timestamp = -1.0f;
  553. }
  554. bool HasStarted( void ) const
  555. {
  556. return (m_timestamp > 0.0f);
  557. }
  558. /// if not started, elapsed time is very large
  559. float GetElapsedTime( void ) const
  560. {
  561. return (HasStarted()) ? (Now() - m_timestamp) : 99999.9f;
  562. }
  563. bool IsLessThen( float duration ) const
  564. {
  565. return (Now() - m_timestamp < duration) ? true : false;
  566. }
  567. bool IsGreaterThen( float duration ) const
  568. {
  569. return (Now() - m_timestamp > duration) ? true : false;
  570. }
  571. float GetStartTime( void ) const
  572. {
  573. return m_timestamp;
  574. }
  575. protected:
  576. CNetworkVar( float, m_timestamp );
  577. float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
  578. };
  579. #ifdef CLIENT_DLL
  580. EXTERN_RECV_TABLE(DT_IntervalTimer);
  581. #else
  582. EXTERN_SEND_TABLE(DT_IntervalTimer);
  583. #endif
  584. //--------------------------------------------------------------------------------------------------------------
  585. /**
  586. * Simple class for counting down a short interval of time.
  587. * Upon creation, the timer is invalidated. Invalidated countdown timers are considered to have elapsed.
  588. */
  589. class CountdownTimer
  590. {
  591. public:
  592. #ifdef CLIENT_DLL
  593. DECLARE_PREDICTABLE();
  594. #endif
  595. DECLARE_CLASS_NOBASE( CountdownTimer );
  596. DECLARE_EMBEDDED_NETWORKVAR();
  597. CountdownTimer( void ) :
  598. m_timestamp( -1.0f), m_duration( 0.0f )
  599. {
  600. }
  601. void Reset( void )
  602. {
  603. m_timestamp = Now() + m_duration;
  604. }
  605. void Start( float duration )
  606. {
  607. m_timestamp = Now() + duration;
  608. m_duration = duration;
  609. }
  610. void StartFromTime( float startTime, float duration )
  611. {
  612. m_timestamp = startTime + duration;
  613. m_duration = duration;
  614. }
  615. void Invalidate( void )
  616. {
  617. m_timestamp = -1.0f;
  618. }
  619. bool HasStarted( void ) const
  620. {
  621. return (m_timestamp > 0.0f);
  622. }
  623. bool IsElapsed( void ) const
  624. {
  625. return (Now() > m_timestamp);
  626. }
  627. float GetElapsedTime( void ) const
  628. {
  629. return Now() - m_timestamp + m_duration;
  630. }
  631. float GetRemainingTime( void ) const
  632. {
  633. return (m_timestamp - Now());
  634. }
  635. float GetTargetTime() const
  636. {
  637. return m_timestamp;
  638. }
  639. /// return original countdown time
  640. float GetCountdownDuration( void ) const
  641. {
  642. return (m_timestamp > 0.0f) ? m_duration : 0.0f;
  643. }
  644. /// 1.0 for newly started, 0.0 for elapsed
  645. float GetRemainingRatio( void ) const
  646. {
  647. if ( HasStarted() )
  648. {
  649. float left = GetRemainingTime() / m_duration;
  650. if ( left < 0.0f )
  651. return 0.0f;
  652. if ( left > 1.0f )
  653. return 1.0f;
  654. return left;
  655. }
  656. return 0.0f;
  657. }
  658. float GetElapsedRatio() const
  659. {
  660. if ( HasStarted() )
  661. {
  662. float elapsed = GetElapsedTime() / m_duration;
  663. if ( elapsed < 0.0f )
  664. return 0.0f;
  665. if ( elapsed > 1.0f )
  666. return 1.0f;
  667. return elapsed;
  668. }
  669. return 1.0f;
  670. }
  671. // Usage:
  672. // Declaration: CountdownTimer mTimer;
  673. // Think function:
  674. // while(mTimer.RunEvery( timerInterval ))
  675. // {
  676. // do fixed-rate stuff
  677. // }
  678. //
  679. // nextThinkTime = min(nextThinkTime, mTimer.GetTargetTime());
  680. //
  681. // This avoids 'losing' ticks on a repeating timer when
  682. // the think rate is not a multiple of the timer duration,
  683. // especially since SetNextThink rounds ticks up/down, causing
  684. // even a timer that is running exactly at the think rate of
  685. // the underlying class to not elapse correctly.
  686. //
  687. // It also makes sure that ticks are never lost
  688. bool RunEvery( float amount = -1.0f )
  689. {
  690. // First call starts the timer
  691. if(!HasStarted())
  692. {
  693. if(amount > 0.0f)
  694. Start( amount );
  695. return false;
  696. }
  697. if( IsElapsed() )
  698. {
  699. if ( amount > 0.0f )
  700. m_duration = amount;
  701. m_timestamp += m_duration;
  702. return true;
  703. }
  704. return false;
  705. }
  706. // Same as RunEvery() but only returns true once per 'tick', then guarantees being non-elapsed.
  707. // Useful when "do fixed rate stuff" is idempotent, like updating something to match
  708. // the current time.
  709. bool Interval( float amount = -1.0f )
  710. {
  711. // First call starts the timer
  712. if ( !HasStarted() )
  713. {
  714. if ( amount > 0.0f )
  715. Start( amount );
  716. return false;
  717. }
  718. if ( IsElapsed() )
  719. {
  720. if ( amount > 0.0f )
  721. m_duration = amount;
  722. m_timestamp += m_duration;
  723. // If we are still expired, add a multiple of the interval
  724. // until we become non-elapsed
  725. float remaining = GetRemainingTime();
  726. if ( remaining < 0.0f)
  727. {
  728. float numIntervalsRequired = -floorf( remaining / m_duration );
  729. m_timestamp += m_duration * numIntervalsRequired;
  730. }
  731. // We should no longer be elapsed
  732. Assert( !IsElapsed() );
  733. return true;
  734. }
  735. return false;
  736. }
  737. private:
  738. CNetworkVar( float, m_duration );
  739. CNetworkVar( float, m_timestamp );
  740. float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
  741. };
  742. #ifdef CLIENT_DLL
  743. EXTERN_RECV_TABLE(DT_CountdownTimer);
  744. #else
  745. EXTERN_SEND_TABLE(DT_CountdownTimer);
  746. #endif
  747. //--------------------------------------------------------------------------------------------------------------
  748. /**
  749. * Simple class for tracking change in values over time.
  750. */
  751. #define TIMELINE_ARRAY_SIZE 64
  752. #define TIMELINE_INTERVAL_START 0.25f
  753. enum TimelineCompression_t
  754. {
  755. TIMELINE_COMPRESSION_SUM,
  756. TIMELINE_COMPRESSION_COUNT_PER_INTERVAL,
  757. TIMELINE_COMPRESSION_AVERAGE,
  758. TIMELINE_COMPRESSION_AVERAGE_BLEND,
  759. TIMELINE_COMPRESSION_TOTAL
  760. };
  761. class CTimeline : public IntervalTimer
  762. {
  763. public:
  764. DECLARE_DATADESC();
  765. DECLARE_CLASS( CTimeline, IntervalTimer );
  766. DECLARE_EMBEDDED_NETWORKVAR();
  767. CTimeline( void )
  768. {
  769. ClearValues();
  770. }
  771. void ClearValues( void );
  772. void ClearAndStart( void ) { ClearValues(); Start(); }
  773. void StopRecording( void ) { m_bStopped = true; }
  774. void RecordValue( float flValue );
  775. void RecordFinalValue( float flValue ) { RecordValue( flValue ); StopRecording(); }
  776. int Count( void ) const
  777. {
  778. return m_nBucketCount;
  779. }
  780. float GetValue( int i ) const;
  781. float GetValueAtInterp( float fInterp ) const;
  782. float GetValueTime( int i ) const
  783. {
  784. Assert( i >= 0 && i < m_nBucketCount );
  785. return static_cast<float>( i ) * m_flInterval;
  786. }
  787. float GetInterval( void ) const
  788. {
  789. return m_flInterval;
  790. }
  791. void SetCompressionType( TimelineCompression_t nCompressionType )
  792. {
  793. m_nCompressionType = nCompressionType;
  794. }
  795. TimelineCompression_t GetCompressionType( void ) const
  796. {
  797. return m_nCompressionType;
  798. }
  799. private:
  800. int GetCurrentBucket( void )
  801. {
  802. return static_cast<float>( Now() - m_timestamp ) / m_flInterval;
  803. }
  804. void Compress( void );
  805. CNetworkArray( float, m_flValues, TIMELINE_ARRAY_SIZE );
  806. CNetworkArray( int, m_nValueCounts, TIMELINE_ARRAY_SIZE );
  807. CNetworkVar( int, m_nBucketCount );
  808. CNetworkVar( float, m_flInterval );
  809. CNetworkVar( float, m_flFinalValue );
  810. CNetworkVar( TimelineCompression_t, m_nCompressionType );
  811. CNetworkVar( bool, m_bStopped );
  812. };
  813. #ifdef CLIENT_DLL
  814. EXTERN_RECV_TABLE(DT_Timeline);
  815. #else
  816. EXTERN_SEND_TABLE(DT_Timeline);
  817. #endif
  818. char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename = NULL );
  819. int UTIL_StringFieldToInt( const char *szValue, const char **pValueStrings, int iNumStrings );
  820. int UTIL_CountNumBitsSet( unsigned int nVar );
  821. int UTIL_CountNumBitsSet( uint64 nVar );
  822. bool UTIL_GetModDir( char *lpszTextOut, unsigned int nSize );
  823. /*UTIL_CalcFrustumThroughPolygon - Given a frustum and a polygon, calculate how the current frustum would clip the polygon, then generate a new frustum that runs along the edge of the clipped polygon.
  824. -returns number of planes in the output frustum, 0 if the polygon was completely clipped by the input frustum
  825. -vFrustumOrigin can be thought of as the camera origin if your frustum is a view frustum
  826. -planes should face inward
  827. -iPreserveCount will preserve N planes at the end of your input frustum and ensure they're at the end of your output frustum. Assuming your input frustum is of type "Frustum", a value of 2 would preserve your near and far planes
  828. -to ensure that your output frustum can hold the entire complex frustum we generate. Make it of size (iPolyVertCount + iCurrentFrustumPlanes + iPreserveCount). Otherwise the output frustum will be simplified to fit your maximum output by eliminating bounding planes with the clipped area.
  829. -a lack of input frustum is considered valid input*/
  830. int UTIL_CalcFrustumThroughConvexPolygon( const Vector *pPolyVertices, int iPolyVertCount, const Vector &vFrustumOrigin, const VPlane *pInputFrustumPlanes, int iInputFrustumPlanes, VPlane *pOutputFrustumPlanes, int iMaxOutputPlanes, int iPreserveCount );
  831. //-----------------------------------------------------------------------------
  832. // class CFlaggedEntitiesEnum
  833. //-----------------------------------------------------------------------------
  834. // enumerate entities that match a set of edict flags into a static array
  835. class CFlaggedEntitiesEnum : public IPartitionEnumerator
  836. {
  837. public:
  838. CFlaggedEntitiesEnum( CBaseEntity **pList, int listMax, int flagMask );
  839. // This gets called by the enumeration methods with each element
  840. // that passes the test.
  841. virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity );
  842. int GetCount() { return m_count; }
  843. bool AddToList( CBaseEntity *pEntity );
  844. private:
  845. CBaseEntity **m_pList;
  846. int m_listMax;
  847. int m_flagMask;
  848. int m_count;
  849. };
  850. class CHurtableEntitiesEnum : public IPartitionEnumerator
  851. {
  852. public:
  853. CHurtableEntitiesEnum( CBaseEntity **pList, int listMax );
  854. // This gets called by the enumeration methods with each element
  855. // that passes the test.
  856. virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity );
  857. int GetCount() { return m_count; }
  858. bool AddToList( CBaseEntity *pEntity );
  859. private:
  860. CBaseEntity **m_pList;
  861. int m_listMax;
  862. int m_count;
  863. };
  864. int UTIL_EntitiesAlongRay( const Ray_t &ray, CFlaggedEntitiesEnum *pEnum );
  865. inline int UTIL_EntitiesAlongRay( CBaseEntity **pList, int listMax, const Ray_t &ray, int flagMask )
  866. {
  867. CFlaggedEntitiesEnum rayEnum( pList, listMax, flagMask );
  868. return UTIL_EntitiesAlongRay( ray, &rayEnum );
  869. }
  870. #include "shareddefs.h"
  871. #if (PREDICTION_ERROR_CHECK_LEVEL > 0)
  872. extern void _Easy_DiffPrint( CBaseEntity *pEntity, PRINTF_FORMAT_STRING const char *szFormatSTring, ... );
  873. #if defined( CLIENT_DLL )
  874. extern bool _Easy_DiffPrint_InternalConditions( C_BaseEntity *pEntity );
  875. #define _EASY_DIFFPRINT_INTERNALCONDITIONS(entity) _Easy_DiffPrint_InternalConditions( entity )
  876. #else
  877. #define _EASY_DIFFPRINT_INTERNALCONDITIONS(entity) true
  878. #endif
  879. #define EASY_DIFFPRINT_CONDITIONAL( conditions, entity, szFormatString, ... ) if( (conditions) && _EASY_DIFFPRINT_INTERNALCONDITIONS( entity ) ) { _Easy_DiffPrint( entity, szFormatString, __VA_ARGS__ ); }
  880. #define EASY_DIFFPRINT( entity, szFormatString, ... ) EASY_DIFFPRINT_CONDITIONAL( true, entity, szFormatString, __VA_ARGS__ )
  881. #else //#if (PREDICTION_ERROR_CHECK_LEVEL > 0)
  882. #define EASY_DIFFPRINT_CONDITIONAL( conditions, entity, szFormatString, ... )
  883. #define EASY_DIFFPRINT( entity, szFormatString, ... )
  884. #endif //#if (PREDICTION_ERROR_CHECK_LEVEL > 0)
  885. void UTIL_GetNextCommandLength( const char *pText, int nMaxLen, int *pCommandLength, int *pNextCommandOffset );
  886. //--------------------------------------------------------------------------------------------------------------
  887. /**
  888. * remove double spaces and empty bold/italic HTML tags from a string
  889. */
  890. void UTIL_TrimEmptyWhitespaceFromHTML( OUT_Z_BYTECAP( descWriterByteSize ) wchar_t* pszDescWriter, size_t descWriterByteSize, const wchar_t* pszDescReader );
  891. void UTIL_TrimEmptyWhitespaceFromHTML( OUT_Z_BYTECAP( descWriterByteSize ) char* pszDescWriter, size_t descWriterByteSize, const char* pszDescReader );
  892. #endif // UTIL_SHARED_H