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.

264 lines
8.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // Soundent.h - the entity that spawns when the world
  9. // spawns, and handles the world's active and free sound
  10. // lists.
  11. #ifndef SOUNDENT_H
  12. #define SOUNDENT_H
  13. #ifdef _WIN32
  14. #pragma once
  15. #endif
  16. enum
  17. {
  18. MAX_WORLD_SOUNDS_SP = 64, // Maximum number of sounds handled by the world at one time in single player.
  19. // This is also the number of entries saved in a savegame file (for b/w compatibility).
  20. MAX_WORLD_SOUNDS_MP = 128 // The sound array size is set this large but we'll only use gpGlobals->maxPlayers+32 entries in mp.
  21. };
  22. enum
  23. {
  24. SOUND_NONE = 0,
  25. SOUND_COMBAT = 0x00000001,
  26. SOUND_WORLD = 0x00000002,
  27. SOUND_PLAYER = 0x00000004,
  28. SOUND_DANGER = 0x00000008,
  29. SOUND_BULLET_IMPACT = 0x00000010,
  30. SOUND_CARCASS = 0x00000020,
  31. SOUND_MEAT = 0x00000040,
  32. SOUND_GARBAGE = 0x00000080,
  33. SOUND_THUMPER = 0x00000100, // keeps certain creatures at bay
  34. SOUND_BUGBAIT = 0x00000200, // gets the antlion's attention
  35. SOUND_PHYSICS_DANGER = 0x00000400,
  36. SOUND_DANGER_SNIPERONLY = 0x00000800, // only scares the sniper NPC.
  37. SOUND_MOVE_AWAY = 0x00001000,
  38. SOUND_PLAYER_VEHICLE = 0x00002000,
  39. SOUND_READINESS_LOW = 0x00004000, // Changes listener's readiness (Player Companion only)
  40. SOUND_READINESS_MEDIUM = 0x00008000,
  41. SOUND_READINESS_HIGH = 0x00010000,
  42. // Contexts begin here.
  43. SOUND_CONTEXT_FROM_SNIPER = 0x00100000, // additional context for SOUND_DANGER
  44. SOUND_CONTEXT_GUNFIRE = 0x00200000, // Added to SOUND_COMBAT
  45. SOUND_CONTEXT_MORTAR = 0x00400000, // Explosion going to happen here.
  46. SOUND_CONTEXT_COMBINE_ONLY = 0x00800000, // Only combine can hear sounds marked this way
  47. SOUND_CONTEXT_REACT_TO_SOURCE = 0x01000000, // React to sound source's origin, not sound's location
  48. SOUND_CONTEXT_EXPLOSION = 0x02000000, // Context added to SOUND_COMBAT, usually.
  49. SOUND_CONTEXT_EXCLUDE_COMBINE = 0x04000000, // Combine do NOT hear this
  50. SOUND_CONTEXT_DANGER_APPROACH = 0x08000000, // Treat as a normal danger sound if you see the source, otherwise turn to face source.
  51. SOUND_CONTEXT_ALLIES_ONLY = 0x10000000, // Only player allies can hear this sound
  52. SOUND_CONTEXT_PLAYER_VEHICLE = 0x20000000, // HACK: need this because we're not treating the SOUND_xxx values as true bit values! See switch in OnListened.
  53. ALL_CONTEXTS = 0xFFF00000,
  54. ALL_SCENTS = SOUND_CARCASS | SOUND_MEAT | SOUND_GARBAGE,
  55. ALL_SOUNDS = 0x000FFFFF & ~ALL_SCENTS,
  56. };
  57. // Make as many of these as you want.
  58. enum
  59. {
  60. SOUNDENT_CHANNEL_UNSPECIFIED = 0,
  61. SOUNDENT_CHANNEL_REPEATING,
  62. SOUNDENT_CHANNEL_REPEATED_DANGER, // for things that make danger sounds frequently.
  63. SOUNDENT_CHANNEL_REPEATED_PHYSICS_DANGER,
  64. SOUNDENT_CHANNEL_WEAPON,
  65. SOUNDENT_CHANNEL_INJURY,
  66. SOUNDENT_CHANNEL_BULLET_IMPACT,
  67. SOUNDENT_CHANNEL_NPC_FOOTSTEP,
  68. SOUNDENT_CHANNEL_SPOOKY_NOISE, // made by zombies in darkness
  69. SOUNDENT_CHANNEL_ZOMBINE_GRENADE,
  70. };
  71. enum
  72. {
  73. SOUNDLIST_EMPTY = -1
  74. };
  75. #define SOUNDENT_VOLUME_MACHINEGUN 1500.0
  76. #define SOUNDENT_VOLUME_SHOTGUN 1500.0
  77. #define SOUNDENT_VOLUME_PISTOL 1500.0
  78. #define SOUNDENT_VOLUME_EMPTY 500.0 // volume of the "CLICK" when you have no bullets
  79. enum
  80. {
  81. SOUND_PRIORITY_VERY_LOW = -2,
  82. SOUND_PRIORITY_LOW,
  83. SOUND_PRIORITY_NORMAL = 0,
  84. SOUND_PRIORITY_HIGH,
  85. SOUND_PRIORITY_VERY_HIGH,
  86. SOUND_PRIORITY_HIGHEST,
  87. };
  88. //=========================================================
  89. // CSound - an instance of a sound in the world.
  90. //=========================================================
  91. class CSound
  92. {
  93. DECLARE_SIMPLE_DATADESC();
  94. public:
  95. bool DoesSoundExpire() const;
  96. float SoundExpirationTime() const;
  97. void SetSoundOrigin( const Vector &vecOrigin ) { m_vecOrigin = vecOrigin; }
  98. const Vector& GetSoundOrigin( void ) { return m_vecOrigin; }
  99. const Vector& GetSoundReactOrigin( void );
  100. bool FIsSound( void );
  101. bool FIsScent( void );
  102. bool IsSoundType( int nSoundFlags ) const;
  103. int SoundType( ) const;
  104. int SoundContext() const;
  105. int SoundTypeNoContext( ) const;
  106. int Volume( ) const;
  107. float OccludedVolume() { return m_iVolume * m_flOcclusionScale; }
  108. int NextSound() const;
  109. void Reset ( void );
  110. int SoundChannel( void ) const;
  111. bool ValidateOwner() const;
  112. EHANDLE m_hOwner; // sound's owner
  113. EHANDLE m_hTarget; // Sounds's target - an odd concept. For a gunfire sound, the target is the entity being fired at
  114. int m_iVolume; // how loud the sound is
  115. float m_flOcclusionScale; // How loud the sound is when occluded by the world. (volume * occlusionscale)
  116. int m_iType; // what type of sound this is
  117. int m_iNextAudible; // temporary link that NPCs use to build a list of audible sounds
  118. private:
  119. void Clear ( void );
  120. float m_flExpireTime; // when the sound should be purged from the list
  121. short m_iNext; // index of next sound in this list ( Active or Free )
  122. bool m_bNoExpirationTime;
  123. int m_ownerChannelIndex;
  124. Vector m_vecOrigin; // sound's location in space
  125. bool m_bHasOwner; // Lets us know if this sound was created with an owner. In case the owner goes null.
  126. #ifdef DEBUG
  127. int m_iMyIndex; // debugging
  128. #endif
  129. friend class CSoundEnt;
  130. };
  131. inline bool CSound::DoesSoundExpire() const
  132. {
  133. return m_bNoExpirationTime == false;
  134. }
  135. inline float CSound::SoundExpirationTime() const
  136. {
  137. return m_bNoExpirationTime ? FLT_MAX : m_flExpireTime;
  138. }
  139. inline bool CSound::IsSoundType( int nSoundFlags ) const
  140. {
  141. return (m_iType & nSoundFlags) != 0;
  142. }
  143. inline int CSound::SoundType( ) const
  144. {
  145. return m_iType;
  146. }
  147. inline int CSound::SoundContext( ) const
  148. {
  149. return m_iType & ALL_CONTEXTS;
  150. }
  151. inline int CSound::SoundTypeNoContext( ) const
  152. {
  153. return m_iType & ~ALL_CONTEXTS;
  154. }
  155. inline int CSound::Volume( ) const
  156. {
  157. return m_iVolume;
  158. }
  159. inline int CSound::NextSound() const
  160. {
  161. return m_iNext;
  162. }
  163. inline int CSound::SoundChannel( void ) const
  164. {
  165. return m_ownerChannelIndex;
  166. }
  167. // The owner is considered valid if:
  168. // -The sound never had an assigned owner (quite common)
  169. // -The sound was assigned an owner and that owner still exists
  170. inline bool CSound::ValidateOwner( void ) const
  171. {
  172. return ( !m_bHasOwner || (m_hOwner.Get() != NULL) );
  173. }
  174. //=========================================================
  175. // CSoundEnt - a single instance of this entity spawns when
  176. // the world spawns. The SoundEnt's job is to update the
  177. // world's Free and Active sound lists.
  178. //=========================================================
  179. class CSoundEnt : public CPointEntity
  180. {
  181. DECLARE_DATADESC();
  182. public:
  183. DECLARE_CLASS( CSoundEnt, CPointEntity );
  184. // Construction, destruction
  185. static bool InitSoundEnt();
  186. static void ShutdownSoundEnt();
  187. CSoundEnt();
  188. virtual ~CSoundEnt();
  189. virtual void OnRestore();
  190. void Precache ( void );
  191. void Spawn( void );
  192. void Think( void );
  193. void Initialize ( void );
  194. int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
  195. static void InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration, CBaseEntity *pOwner = NULL, int soundChannelIndex = SOUNDENT_CHANNEL_UNSPECIFIED, CBaseEntity *pSoundTarget = NULL );
  196. static void FreeSound ( int iSound, int iPrevious );
  197. static int ActiveList( void );// return the head of the active list
  198. static int FreeList( void );// return the head of the free list
  199. static CSound* SoundPointerForIndex( int iIndex );// return a pointer for this index in the sound list
  200. static CSound* GetLoudestSoundOfType( int iType, const Vector &vecEarPosition );
  201. static int ClientSoundIndex ( edict_t *pClient );
  202. bool IsEmpty( void );
  203. int ISoundsInList ( int iListType );
  204. int IAllocSound ( void );
  205. int FindOrAllocateSound( CBaseEntity *pOwner, int soundChannelIndex );
  206. private:
  207. int m_iFreeSound; // index of the first sound in the free sound list
  208. int m_iActiveSound; // indes of the first sound in the active sound list
  209. int m_cLastActiveSounds; // keeps track of the number of active sounds at the last update. (for diagnostic work)
  210. CSound m_SoundPool[ MAX_WORLD_SOUNDS_MP ];
  211. };
  212. //-----------------------------------------------------------------------------
  213. // Inline methods
  214. //-----------------------------------------------------------------------------
  215. inline bool CSoundEnt::IsEmpty( void )
  216. {
  217. return m_iActiveSound == SOUNDLIST_EMPTY;
  218. }
  219. #endif //SOUNDENT_H