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.

662 lines
21 KiB

  1. //========= Copyright 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. #include "steam/steamuniverse.h"
  19. #ifdef CLIENT_DLL
  20. #include "cdll_client_int.h"
  21. #endif
  22. #ifdef PORTAL
  23. #include "portal_util_shared.h"
  24. #endif
  25. //-----------------------------------------------------------------------------
  26. // Forward declarations
  27. //-----------------------------------------------------------------------------
  28. class CGameTrace;
  29. class CBasePlayer;
  30. typedef CGameTrace trace_t;
  31. extern ConVar developer; // developer mode
  32. //-----------------------------------------------------------------------------
  33. // Language IDs.
  34. //-----------------------------------------------------------------------------
  35. #define LANGUAGE_ENGLISH 0
  36. #define LANGUAGE_GERMAN 1
  37. #define LANGUAGE_FRENCH 2
  38. #define LANGUAGE_BRITISH 3
  39. //-----------------------------------------------------------------------------
  40. // Pitch + yaw
  41. //-----------------------------------------------------------------------------
  42. float UTIL_VecToYaw (const Vector &vec);
  43. float UTIL_VecToPitch (const Vector &vec);
  44. float UTIL_VecToYaw (const matrix3x4_t& matrix, const Vector &vec);
  45. float UTIL_VecToPitch (const matrix3x4_t& matrix, const Vector &vec);
  46. Vector UTIL_YawToVector ( float yaw );
  47. //-----------------------------------------------------------------------------
  48. // Shared random number generators for shared/predicted code:
  49. // whenever generating random numbers in shared/predicted code, these functions
  50. // have to be used. Each call should specify a unique "sharedname" string that
  51. // seeds the random number generator. In loops make sure the "additionalSeed"
  52. // is increased with the loop counter, otherwise it will always return the
  53. // same random number
  54. //-----------------------------------------------------------------------------
  55. float SharedRandomFloat( const char *sharedname, float flMinVal, float flMaxVal, int additionalSeed = 0 );
  56. int SharedRandomInt( const char *sharedname, int iMinVal, int iMaxVal, int additionalSeed = 0 );
  57. Vector SharedRandomVector( const char *sharedname, float minVal, float maxVal, int additionalSeed = 0 );
  58. QAngle SharedRandomAngle( const char *sharedname, float minVal, float maxVal, int additionalSeed = 0 );
  59. //-----------------------------------------------------------------------------
  60. // Standard collision filters...
  61. //-----------------------------------------------------------------------------
  62. bool PassServerEntityFilter( const IHandleEntity *pTouch, const IHandleEntity *pPass );
  63. bool StandardFilterRules( IHandleEntity *pHandleEntity, int fContentsMask );
  64. //-----------------------------------------------------------------------------
  65. // Converts an IHandleEntity to an CBaseEntity
  66. //-----------------------------------------------------------------------------
  67. inline const CBaseEntity *EntityFromEntityHandle( const IHandleEntity *pConstHandleEntity )
  68. {
  69. IHandleEntity *pHandleEntity = const_cast<IHandleEntity*>(pConstHandleEntity);
  70. #ifdef CLIENT_DLL
  71. IClientUnknown *pUnk = (IClientUnknown*)pHandleEntity;
  72. return pUnk->GetBaseEntity();
  73. #else
  74. if ( staticpropmgr->IsStaticProp( pHandleEntity ) )
  75. return NULL;
  76. IServerUnknown *pUnk = (IServerUnknown*)pHandleEntity;
  77. return pUnk->GetBaseEntity();
  78. #endif
  79. }
  80. inline CBaseEntity *EntityFromEntityHandle( IHandleEntity *pHandleEntity )
  81. {
  82. #ifdef CLIENT_DLL
  83. IClientUnknown *pUnk = (IClientUnknown*)pHandleEntity;
  84. return pUnk->GetBaseEntity();
  85. #else
  86. if ( staticpropmgr->IsStaticProp( pHandleEntity ) )
  87. return NULL;
  88. IServerUnknown *pUnk = (IServerUnknown*)pHandleEntity;
  89. return pUnk->GetBaseEntity();
  90. #endif
  91. }
  92. typedef bool (*ShouldHitFunc_t)( IHandleEntity *pHandleEntity, int contentsMask );
  93. //-----------------------------------------------------------------------------
  94. // traceline methods
  95. //-----------------------------------------------------------------------------
  96. class CTraceFilterSimple : public CTraceFilter
  97. {
  98. public:
  99. // It does have a base, but we'll never network anything below here..
  100. DECLARE_CLASS_NOBASE( CTraceFilterSimple );
  101. CTraceFilterSimple( const IHandleEntity *passentity, int collisionGroup, ShouldHitFunc_t pExtraShouldHitCheckFn = NULL );
  102. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  103. virtual void SetPassEntity( const IHandleEntity *pPassEntity ) { m_pPassEnt = pPassEntity; }
  104. virtual void SetCollisionGroup( int iCollisionGroup ) { m_collisionGroup = iCollisionGroup; }
  105. const IHandleEntity *GetPassEntity( void ){ return m_pPassEnt;}
  106. private:
  107. const IHandleEntity *m_pPassEnt;
  108. int m_collisionGroup;
  109. ShouldHitFunc_t m_pExtraShouldHitCheckFunction;
  110. };
  111. class CTraceFilterSkipTwoEntities : public CTraceFilterSimple
  112. {
  113. public:
  114. // It does have a base, but we'll never network anything below here..
  115. DECLARE_CLASS( CTraceFilterSkipTwoEntities, CTraceFilterSimple );
  116. CTraceFilterSkipTwoEntities( const IHandleEntity *passentity, const IHandleEntity *passentity2, int collisionGroup );
  117. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  118. virtual void SetPassEntity2( const IHandleEntity *pPassEntity2 ) { m_pPassEnt2 = pPassEntity2; }
  119. private:
  120. const IHandleEntity *m_pPassEnt2;
  121. };
  122. class CTraceFilterSimpleList : public CTraceFilterSimple
  123. {
  124. public:
  125. CTraceFilterSimpleList( int collisionGroup );
  126. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  127. void AddEntityToIgnore( IHandleEntity *pEntity );
  128. protected:
  129. CUtlVector<IHandleEntity*> m_PassEntities;
  130. };
  131. class CTraceFilterOnlyNPCsAndPlayer : public CTraceFilterSimple
  132. {
  133. public:
  134. CTraceFilterOnlyNPCsAndPlayer( const IHandleEntity *passentity, int collisionGroup )
  135. : CTraceFilterSimple( passentity, collisionGroup )
  136. {
  137. }
  138. virtual TraceType_t GetTraceType() const
  139. {
  140. return TRACE_ENTITIES_ONLY;
  141. }
  142. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  143. };
  144. class CTraceFilterNoNPCsOrPlayer : public CTraceFilterSimple
  145. {
  146. public:
  147. CTraceFilterNoNPCsOrPlayer( const IHandleEntity *passentity, int collisionGroup )
  148. : CTraceFilterSimple( passentity, collisionGroup )
  149. {
  150. }
  151. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  152. };
  153. //-----------------------------------------------------------------------------
  154. // Purpose: Custom trace filter used for NPC LOS traces
  155. //-----------------------------------------------------------------------------
  156. class CTraceFilterLOS : public CTraceFilterSkipTwoEntities
  157. {
  158. public:
  159. CTraceFilterLOS( IHandleEntity *pHandleEntity, int collisionGroup, IHandleEntity *pHandleEntity2 = NULL );
  160. bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  161. };
  162. class CTraceFilterSkipClassname : public CTraceFilterSimple
  163. {
  164. public:
  165. CTraceFilterSkipClassname( const IHandleEntity *passentity, const char *pchClassname, int collisionGroup );
  166. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  167. private:
  168. const char *m_pchClassname;
  169. };
  170. class CTraceFilterSkipTwoClassnames : public CTraceFilterSkipClassname
  171. {
  172. public:
  173. // It does have a base, but we'll never network anything below here..
  174. DECLARE_CLASS( CTraceFilterSkipTwoClassnames, CTraceFilterSkipClassname );
  175. CTraceFilterSkipTwoClassnames( const IHandleEntity *passentity, const char *pchClassname, const char *pchClassname2, int collisionGroup );
  176. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  177. private:
  178. const char *m_pchClassname2;
  179. };
  180. class CTraceFilterSimpleClassnameList : public CTraceFilterSimple
  181. {
  182. public:
  183. CTraceFilterSimpleClassnameList( const IHandleEntity *passentity, int collisionGroup );
  184. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  185. void AddClassnameToIgnore( const char *pchClassname );
  186. private:
  187. CUtlVector<const char*> m_PassClassnames;
  188. };
  189. class CTraceFilterChain : public CTraceFilter
  190. {
  191. public:
  192. CTraceFilterChain( ITraceFilter *pTraceFilter1, ITraceFilter *pTraceFilter2 );
  193. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  194. private:
  195. ITraceFilter *m_pTraceFilter1;
  196. ITraceFilter *m_pTraceFilter2;
  197. };
  198. // helper
  199. void DebugDrawLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, int r, int g, int b, bool test, float duration );
  200. extern ConVar r_visualizetraces;
  201. inline void UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
  202. const IHandleEntity *ignore, int collisionGroup, trace_t *ptr )
  203. {
  204. Ray_t ray;
  205. ray.Init( vecAbsStart, vecAbsEnd );
  206. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  207. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  208. if( r_visualizetraces.GetBool() )
  209. {
  210. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f );
  211. }
  212. }
  213. inline void UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
  214. ITraceFilter *pFilter, trace_t *ptr )
  215. {
  216. Ray_t ray;
  217. ray.Init( vecAbsStart, vecAbsEnd );
  218. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  219. if( r_visualizetraces.GetBool() )
  220. {
  221. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f );
  222. }
  223. }
  224. inline void UTIL_TraceHull( const Vector &vecAbsStart, const Vector &vecAbsEnd, const Vector &hullMin,
  225. const Vector &hullMax, unsigned int mask, const IHandleEntity *ignore,
  226. int collisionGroup, trace_t *ptr )
  227. {
  228. Ray_t ray;
  229. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  230. CTraceFilterSimple traceFilter( ignore, collisionGroup );
  231. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  232. if( r_visualizetraces.GetBool() )
  233. {
  234. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 255, 0, true, -1.0f );
  235. }
  236. }
  237. inline void UTIL_TraceHull( const Vector &vecAbsStart, const Vector &vecAbsEnd, const Vector &hullMin,
  238. const Vector &hullMax, unsigned int mask, ITraceFilter *pFilter, trace_t *ptr )
  239. {
  240. Ray_t ray;
  241. ray.Init( vecAbsStart, vecAbsEnd, hullMin, hullMax );
  242. enginetrace->TraceRay( ray, mask, pFilter, ptr );
  243. if( r_visualizetraces.GetBool() )
  244. {
  245. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 255, 0, true, -1.0f );
  246. }
  247. }
  248. inline void UTIL_TraceRay( const Ray_t &ray, unsigned int mask,
  249. const IHandleEntity *ignore, int collisionGroup, trace_t *ptr, ShouldHitFunc_t pExtraShouldHitCheckFn = NULL )
  250. {
  251. CTraceFilterSimple traceFilter( ignore, collisionGroup, pExtraShouldHitCheckFn );
  252. enginetrace->TraceRay( ray, mask, &traceFilter, ptr );
  253. if( r_visualizetraces.GetBool() )
  254. {
  255. DebugDrawLine( ptr->startpos, ptr->endpos, 255, 0, 0, true, -1.0f );
  256. }
  257. }
  258. // Sweeps a particular entity through the world
  259. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd, unsigned int mask, trace_t *ptr );
  260. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd,
  261. unsigned int mask, ITraceFilter *pFilter, trace_t *ptr );
  262. void UTIL_TraceEntity( CBaseEntity *pEntity, const Vector &vecAbsStart, const Vector &vecAbsEnd,
  263. unsigned int mask, const IHandleEntity *ignore, int collisionGroup, trace_t *ptr );
  264. bool UTIL_EntityHasMatchingRootParent( CBaseEntity *pRootParent, CBaseEntity *pEntity );
  265. inline int UTIL_PointContents( const Vector &vec )
  266. {
  267. return enginetrace->GetPointContents( vec );
  268. }
  269. // Sweeps against a particular model, using collision rules
  270. void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin,
  271. const Vector &hullMax, CBaseEntity *pentModel, int collisionGroup, trace_t *ptr );
  272. void UTIL_ClipTraceToPlayers( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter *filter, trace_t *tr );
  273. // Particle effect tracer
  274. void UTIL_ParticleTracer( const char *pszTracerEffectName, const Vector &vecStart, const Vector &vecEnd, int iEntIndex = 0, int iAttachment = 0, bool bWhiz = false );
  275. // Old style, non-particle system, tracers
  276. 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 );
  277. bool UTIL_IsLowViolence( void );
  278. bool UTIL_ShouldShowBlood( int bloodColor );
  279. void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount );
  280. void UTIL_BloodImpact( const Vector &pos, const Vector &dir, int color, int amount );
  281. void UTIL_BloodDecalTrace( trace_t *pTrace, int bloodColor );
  282. void UTIL_DecalTrace( trace_t *pTrace, char const *decalName );
  283. bool UTIL_IsSpaceEmpty( CBaseEntity *pMainEnt, const Vector &vMin, const Vector &vMax );
  284. void UTIL_StringToVector( float *pVector, const char *pString );
  285. void UTIL_StringToIntArray( int *pVector, int count, const char *pString );
  286. void UTIL_StringToFloatArray( float *pVector, int count, const char *pString );
  287. void UTIL_StringToColor32( color32 *color, const char *pString );
  288. CBasePlayer *UTIL_PlayerByIndex( int entindex );
  289. // Helper for use with console commands and the like.
  290. // Returns NULL if not found or if the provided arg would match multiple players.
  291. // Currently accepts, in descending priority:
  292. // - Formatted SteamID ([U:1:1234])
  293. // - SteamID64 (76561197989728462)
  294. // - Legacy SteamID (STEAM_0:1:1234)
  295. // - UserID preceded by a pound (#4)
  296. // - Partial name match (if unique)
  297. // - UserID not preceded by a pound*
  298. //
  299. // *Does not count as ambiguous with higher priority items
  300. CBasePlayer* UTIL_PlayerByCommandArg( const char *arg );
  301. CBasePlayer* UTIL_PlayerByUserId( int userID );
  302. CBasePlayer* UTIL_PlayerByName( const char *name ); // not case sensitive
  303. // Finds a player who has this non-ambiguous substring. Also not case sensitive.
  304. CBasePlayer* UTIL_PlayerByPartialName( const char *name );
  305. // decodes a buffer using a 64bit ICE key (inplace)
  306. void UTIL_DecodeICE( unsigned char * buffer, int size, const unsigned char *key);
  307. //--------------------------------------------------------------------------------------------------------------
  308. /**
  309. * Given a position and a ray, return the shortest distance between the two.
  310. * If 'pos' is beyond either end of the ray, the returned distance is negated.
  311. */
  312. inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vector &rayEnd, float *along = NULL, Vector *pointOnRay = NULL )
  313. {
  314. Vector to = pos - rayStart;
  315. Vector dir = rayEnd - rayStart;
  316. float length = dir.NormalizeInPlace();
  317. float rangeAlong = DotProduct( dir, to );
  318. if (along)
  319. {
  320. *along = rangeAlong;
  321. }
  322. float range;
  323. if (rangeAlong < 0.0f)
  324. {
  325. // off start point
  326. range = -(pos - rayStart).Length();
  327. if (pointOnRay)
  328. {
  329. *pointOnRay = rayStart;
  330. }
  331. }
  332. else if (rangeAlong > length)
  333. {
  334. // off end point
  335. range = -(pos - rayEnd).Length();
  336. if (pointOnRay)
  337. {
  338. *pointOnRay = rayEnd;
  339. }
  340. }
  341. else // within ray bounds
  342. {
  343. Vector onRay = rayStart + rangeAlong * dir;
  344. range = (pos - onRay).Length();
  345. if (pointOnRay)
  346. {
  347. *pointOnRay = onRay;
  348. }
  349. }
  350. return range;
  351. }
  352. //--------------------------------------------------------------------------------------------------------------
  353. /**
  354. * Macro for creating an interface that when inherited from automatically maintains a list of instances
  355. * that inherit from that interface.
  356. */
  357. // interface for entities that want to a auto maintained global list
  358. #define DECLARE_AUTO_LIST( interfaceName ) \
  359. class interfaceName; \
  360. abstract_class interfaceName \
  361. { \
  362. public: \
  363. interfaceName( bool bAutoAdd = true ); \
  364. virtual ~interfaceName(); \
  365. static void AddToAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \
  366. static void RemoveFromAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \
  367. static const CUtlVector< interfaceName* >& AutoList( void ) { return m_##interfaceName##AutoList; } \
  368. private: \
  369. static CUtlVector< interfaceName* > m_##interfaceName##AutoList; \
  370. };
  371. // Creates the auto add/remove constructor/destructor...
  372. // Pass false to the constructor to not auto add
  373. #define IMPLEMENT_AUTO_LIST( interfaceName ) \
  374. CUtlVector< class interfaceName* > interfaceName::m_##interfaceName##AutoList; \
  375. interfaceName::interfaceName( bool bAutoAdd ) \
  376. { \
  377. if ( bAutoAdd ) \
  378. { \
  379. AddToAutoList( this ); \
  380. } \
  381. } \
  382. interfaceName::~interfaceName() \
  383. { \
  384. RemoveFromAutoList( this ); \
  385. }
  386. //--------------------------------------------------------------------------------------------------------------
  387. // You can use this if you need an autolist without an extra interface type involved.
  388. // To use this, just inherit (class Mine : public TAutoList<Mine> {)
  389. template< class T >
  390. class TAutoList
  391. {
  392. public:
  393. typedef CUtlVector< T* > AutoListType;
  394. static AutoListType &GetAutoList()
  395. {
  396. return m_autolist;
  397. }
  398. protected:
  399. TAutoList()
  400. {
  401. m_autolist.AddToTail( static_cast< T* >( this ) );
  402. }
  403. virtual ~TAutoList()
  404. {
  405. m_autolist.FindAndFastRemove( static_cast< T* >( this ) );
  406. }
  407. private:
  408. static AutoListType m_autolist;
  409. };
  410. template< class T >
  411. CUtlVector< T* > TAutoList< T >::m_autolist;
  412. //--------------------------------------------------------------------------------------------------------------
  413. /**
  414. * Simple class for tracking intervals of game time.
  415. * Upon creation, the timer is invalidated. To measure time intervals, start the timer via Start().
  416. */
  417. class IntervalTimer
  418. {
  419. public:
  420. IntervalTimer( void )
  421. {
  422. m_timestamp = -1.0f;
  423. }
  424. void Reset( void )
  425. {
  426. m_timestamp = Now();
  427. }
  428. void Start( void )
  429. {
  430. m_timestamp = Now();
  431. }
  432. void Invalidate( void )
  433. {
  434. m_timestamp = -1.0f;
  435. }
  436. bool HasStarted( void ) const
  437. {
  438. return (m_timestamp > 0.0f);
  439. }
  440. /// if not started, elapsed time is very large
  441. float GetElapsedTime( void ) const
  442. {
  443. return (HasStarted()) ? (Now() - m_timestamp) : 99999.9f;
  444. }
  445. bool IsLessThen( float duration ) const
  446. {
  447. return (Now() - m_timestamp < duration) ? true : false;
  448. }
  449. bool IsGreaterThen( float duration ) const
  450. {
  451. return (Now() - m_timestamp > duration) ? true : false;
  452. }
  453. private:
  454. float m_timestamp;
  455. float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
  456. };
  457. //--------------------------------------------------------------------------------------------------------------
  458. /**
  459. * Simple class for counting down a short interval of time.
  460. * Upon creation, the timer is invalidated. Invalidated countdown timers are considered to have elapsed.
  461. */
  462. class CountdownTimer
  463. {
  464. public:
  465. CountdownTimer( void )
  466. {
  467. m_timestamp = -1.0f;
  468. m_duration = 0.0f;
  469. }
  470. void Reset( void )
  471. {
  472. m_timestamp = Now() + m_duration;
  473. }
  474. void Start( float duration )
  475. {
  476. m_timestamp = Now() + duration;
  477. m_duration = duration;
  478. }
  479. void Invalidate( void )
  480. {
  481. m_timestamp = -1.0f;
  482. }
  483. bool HasStarted( void ) const
  484. {
  485. return (m_timestamp > 0.0f);
  486. }
  487. bool IsElapsed( void ) const
  488. {
  489. return (Now() > m_timestamp);
  490. }
  491. float GetElapsedTime( void ) const
  492. {
  493. return Now() - m_timestamp + m_duration;
  494. }
  495. float GetRemainingTime( void ) const
  496. {
  497. return (m_timestamp - Now());
  498. }
  499. /// return original countdown time
  500. float GetCountdownDuration( void ) const
  501. {
  502. return (m_timestamp > 0.0f) ? m_duration : 0.0f;
  503. }
  504. private:
  505. float m_duration;
  506. float m_timestamp;
  507. virtual float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
  508. };
  509. class RealTimeCountdownTimer : public CountdownTimer
  510. {
  511. virtual float Now( void ) const OVERRIDE
  512. {
  513. return Plat_FloatTime();
  514. }
  515. };
  516. char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename = NULL );
  517. int UTIL_StringFieldToInt( const char *szValue, const char **pValueStrings, int iNumStrings );
  518. //-----------------------------------------------------------------------------
  519. // Holidays
  520. //-----------------------------------------------------------------------------
  521. // Used at level change and round start to re-calculate which holiday is active
  522. void UTIL_CalculateHolidays();
  523. bool UTIL_IsHolidayActive( /*EHoliday*/ int eHoliday );
  524. /*EHoliday*/ int UTIL_GetHolidayForString( const char* pszHolidayName );
  525. // This will return the first active holiday string it can find. In the case of multiple
  526. // holidays overlapping, the list order will act as priority.
  527. const char *UTIL_GetActiveHolidayString();
  528. const char *UTIL_GetRandomSoundFromEntry( const char* pszEntryName );
  529. /// Clamp and round float vals to int. The values are in the 0...255 range.
  530. Color FloatRGBAToColor( float r, float g, float b, float a );
  531. float LerpFloat( float x0, float x1, float t );
  532. Color LerpColor( const Color &c0, const Color &c1, float t );
  533. // Global econ-level helper functionality.
  534. EUniverse GetUniverse();
  535. #endif // UTIL_SHARED_H