Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_SoundManagerEntity.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameScripted/Sound", description: "")]
2 class SCR_SoundManagerEntityClass : GenericEntityClass
3 {
4 };
5 
6 //------------------------------------------------------------------------------------------------
18 {
20  private ref array<ref SCR_AudioSource> m_aAudioSource = {};
22  private SoundWorld m_SoundWorld;
23 
25  static const string G_INTERIOR_SIGNAL_NAME = "GInterior";
26  static const string G_CURR_VEHICLE_COVERAGE_SIGNAL_NAME = "GCurrVehicleCoverage";
27  static const string G_IS_THIRD_PERSON_CAM_SIGNAL_NAME = "GIsThirdPersonCam";
28  static const string G_ROOM_SIZE = "GRoomSize";
29  static const string DYNAMIC_RANGE_SIGNAL_NAME = "DynamicRange";
30  static const string G_TINNITUS_SIGNAL_NAME = "GTinnitus";
31  static const string IN_EDITOR_SIGNAL_NAME = "InEditor";
32 
34  private static int s_iGInteriorIdx;
35  private static int s_iGCurrVehicleCoverageIdx;
36  private static int s_iGIsThirdPersonCamIdx;
37  private static int s_iGRoomSizeIdx;
38  private static int s_iDynamicRangeIdx;
39  private static int s_iGTinnitusIdx;
40  private static int s_iInEditorIdx;
41 
42  #ifdef ENABLE_DIAG
43  private static int s_iCreatedAudioSources;
44  private static int s_iMaxActiveAudioSources;
45  private static int s_iPlayedAudioSources;
46  private static int s_iInvalidAudioSources;
47  private static int s_iInaudibleAudioSources;
48  private static int s_iTerminateAudioSourceCalls;
49  private static int s_iCalculateInterirorAtCount;
50  #endif
51 
52  //------------------------------------------------------------------------------------------------
59  SCR_AudioSource CreateAudioSource(IEntity owner, string eventName)
60  {
61  #ifdef ENABLE_DIAG
62  s_iCreatedAudioSources++;
63  #endif
64 
65  // Get SCR_AudioSourceConfiguration prefab data
66  SCR_SoundDataComponent soundDataComponent = SCR_SoundDataComponent.Cast(owner.FindComponent(SCR_SoundDataComponent));
67  if (!soundDataComponent)
68  return null;
69 
70  SCR_AudioSourceConfiguration audioSourceConfiguration = soundDataComponent.GetAudioSourceConfiguration(eventName);
71  if (!audioSourceConfiguration)
72  return null;
73 
74  // Is sound source in audible range?
75  float distance = AudioSystem.IsAudible(audioSourceConfiguration.m_sSoundProject, eventName, owner.GetOrigin());
76  if (distance < 0)
77  {
78  #ifdef ENABLE_DIAG
79  s_iInaudibleAudioSources++;
80  #endif
81 
82  return null;
83  }
84 
85  return new SCR_AudioSource(owner, audioSourceConfiguration, distance);
86  }
87 
88  //------------------------------------------------------------------------------------------------
95  SCR_AudioSource CreateAudioSource(IEntity owner, SCR_AudioSourceConfiguration audioSourceConfiguration)
96  {
97  #ifdef ENABLE_DIAG
98  s_iCreatedAudioSources++;
99  #endif
100 
101  // Is sound source in audible range?
102  float distance = AudioSystem.IsAudible(audioSourceConfiguration.m_sSoundProject, audioSourceConfiguration.m_sSoundEventName, owner.GetOrigin());
103  if (distance < 0)
104  {
105  #ifdef ENABLE_DIAG
106  s_iInaudibleAudioSources++;
107  #endif
108 
109  return null;
110  }
111 
112  return new SCR_AudioSource(owner, audioSourceConfiguration, distance);
113  }
114 
115  //------------------------------------------------------------------------------------------------
122  void CreateAndPlayAudioSource(IEntity owner, string eventName)
123  {
124  SCR_AudioSource audioSource = CreateAudioSource(owner, eventName);
125 
126  if (!audioSource)
127  return;
128 
129  PlayAudioSource(audioSource);
130  }
131 
132  //------------------------------------------------------------------------------------------------
139  void CreateAndPlayAudioSource(IEntity owner, SCR_AudioSourceConfiguration audioSourceConfiguration)
140  {
141  SCR_AudioSource audioSource = CreateAudioSource(owner, audioSourceConfiguration);
142 
143  if (!audioSource)
144  return;
145 
146  PlayAudioSource(audioSource);
147  }
148 
149  //------------------------------------------------------------------------------------------------
158  void CreateAndPlayAudioSource(IEntity owner, SCR_AudioSourceConfiguration audioSourceConfiguration, vector mat[4])
159  {
160  SCR_AudioSource audioSource = CreateAudioSource(owner, audioSourceConfiguration);
161 
162  if (!audioSource)
163  return;
164 
165  PlayAudioSource(audioSource, mat);
166  }
167 
168  //------------------------------------------------------------------------------------------------
175  void PlayAudioSource(SCR_AudioSource audioSource)
176  {
177  // Update global occlusion signals
178  audioSource.SetGlobalOcclusionSignals();
179 
180  // Get owner transformation
181  vector mat[4];
182  audioSource.m_Owner.GetTransform(mat);
183 
184  // Play event
185  PlaySoundEvent(audioSource, mat);
186  }
187 
188  //------------------------------------------------------------------------------------------------
196  void PlayAudioSource(SCR_AudioSource audioSource, vector mat[4])
197  {
198  // Update global occlusion signals
199  audioSource.SetGlobalOcclusionSignals();
200 
201  // Play event
202  PlaySoundEvent(audioSource, mat);
203  }
204 
205  //------------------------------------------------------------------------------------------------
211  private void PlaySoundEvent(SCR_AudioSource audioSource, vector mat[4])
212  {
213  if (m_SoundWorld)
214  {
215  audioSource.m_InteriorRequestCallback = new SCR_InteriorRequestCallback(audioSource);
216  audioSource.SetTransformation(mat);
217  m_SoundWorld.CalculateInterirorAt(mat[3], audioSource.m_InteriorRequestCallback);
218 
219  #ifdef ENABLE_DIAG
220  s_iCalculateInterirorAtCount++;
221  #endif
222 
223  // Inset audio source to audio source pool
224  m_aAudioSource.Insert(audioSource);
225  }
226  else
227  {
228  audioSource.SetTransformation(mat);
229 
230  // Inset audio source to audio source pool
231  if (audioSource.Play())
232  m_aAudioSource.Insert(audioSource);
233  }
234  }
235 
236  //------------------------------------------------------------------------------------------------
241  void TerminateAudioSource(IEntity entity)
242  {
243  #ifdef ENABLE_DIAG
244  s_iTerminateAudioSourceCalls++;
245  #endif
246 
247  for (int i = m_aAudioSource.Count() - 1; i >= 0; i--)
248  {
249  SCR_AudioSource audioSource = m_aAudioSource[i];
250 
251  if (audioSource.m_Owner == entity)
252  audioSource.Ternimate();
253  }
254  }
255 
256  //------------------------------------------------------------------------------------------------
261  void TerminateAudioSource(SCR_AudioSource audioSource)
262  {
263  // AudioSource was already played and removed
264  if (!audioSource)
265  return;
266 
267  // Terminate sound
268  audioSource.Ternimate();
269  }
270 
271  //------------------------------------------------------------------------------------------------
275  void TerminateAll()
276  {
277  foreach (SCR_AudioSource audioSource : m_aAudioSource)
278  {
279  audioSource.Ternimate();
280  }
281  }
282 
283  //------------------------------------------------------------------------------------------------
287  private void HandleAudioSources()
288  {
289  for (int i = m_aAudioSource.Count() - 1; i >= 0; i--)
290  {
291  SCR_AudioSource audioSource = m_aAudioSource[i];
292 
293  // Remove audio source if sound finished playing
294  if (AudioSystem.IsSoundPlayed(audioSource.m_AudioHandle) && !audioSource.m_InteriorRequestCallback)
295  {
296  m_aAudioSource.Remove(i);
297  continue;
298  }
299 
300  if (m_aAudioSource[i].m_Owner)
301  {
302  // Update audio source position
303  if (!SCR_Enum.HasFlag(audioSource.m_AudioSourceConfiguration.m_eFlags, EAudioSourceConfigurationFlag.Static))
304  audioSource.UpdateTransformation();
305  }
306  else
307  {
308  // Remove audio source if parent entity was deleted
309  if (!SCR_Enum.HasFlag(audioSource.m_AudioSourceConfiguration.m_eFlags, EAudioSourceConfigurationFlag.FinishWhenEntityDestroyed) && !audioSource.m_InteriorRequestCallback)
310  {
311  audioSource.Ternimate();
312  m_aAudioSource.Remove(i);
313  }
314  }
315  }
316 
317  #ifdef ENABLE_DIAG
318  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SOUNDS_SOUND_MANAGER))
319  {
320  int count = m_aAudioSource.Count();
321  DbgUI.Begin("Sound Manager");
322  DbgUI.Text("Active Audio Sources :" + count);
323  if (count > s_iMaxActiveAudioSources)
324  s_iMaxActiveAudioSources = count;
325  DbgUI.Text("Maximum Active Audio Sources :" + s_iMaxActiveAudioSources);
326  DbgUI.Text("Created Audio Sources :" + s_iCreatedAudioSources);
327  DbgUI.Text("Played Audio Sources :" + s_iPlayedAudioSources);
328  DbgUI.Text("Invalid Audio Sources :" + s_iInvalidAudioSources);
329  DbgUI.Text("Inaudible Audio Sources :" + s_iInaudibleAudioSources);
330  DbgUI.Text("TerminateAudioSource() Calls :" + s_iTerminateAudioSourceCalls);
331  DbgUI.Text("CalculateInterirorAt() Count :" + s_iCalculateInterirorAtCount);
332  DbgUI.End();
333 
334  // Print events for active audio sources
335  if (m_aAudioSource.Count() != 0)
336  {
337  Print("--- " + m_aAudioSource.Count().ToString() + " playing sound events ---");
338  foreach (SCR_AudioSource audioSource : m_aAudioSource)
339  {
340  Print(audioSource.m_AudioSourceConfiguration.m_sSoundEventName);
341  }
342  }
343  }
344 
345  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SOUNDS_GLOBAL_VARIABLES))
346  {
347  Resource holder = BaseContainerTools.LoadContainer("{A60F08955792B575}Sounds/_SharedData/Variables/GlobalVariables.conf");
348  if (!holder)
349  return;
350 
351  BaseContainer baseContainer = holder.GetResource().ToBaseContainer();
352  if (!baseContainer)
353  return;
354 
355  BaseContainerList list = baseContainer.GetObjectArray("Variables");
356  if (!list)
357  return;
358 
359  DbgUI.Begin("Global Variables");
360  for (int i = 0; i < list.Count(); i++)
361  {
362  string name = list[i].GetName();
363  DbgUI.Text(name + ": " + AudioSystem.GetVariableValue(name, "{A60F08955792B575}Sounds/_SharedData/Variables/GlobalVariables.conf").ToString(-1,2));
364  }
365  DbgUI.End();
366  }
367  #endif
368  }
369 
370  //------------------------------------------------------------------------------------------------
374  int GetGInteriorSignalIdx()
375  {
376  return s_iGInteriorIdx;
377  }
378 
379  //------------------------------------------------------------------------------------------------
383  int GetGCurrVehicleCoverageSignalIdx()
384  {
385  return s_iGCurrVehicleCoverageIdx;
386  }
387 
388  //------------------------------------------------------------------------------------------------
392  int GetGIsThirdPersonCamSignalIdx()
393  {
394  return s_iGIsThirdPersonCamIdx;
395  }
396 
397  //------------------------------------------------------------------------------------------------
401  int GetRoomSizeIdx()
402  {
403  return s_iGRoomSizeIdx;
404  }
405 
406  //------------------------------------------------------------------------------------------------
410  protected void SetDynamicRangeSignalValue()
411  {
412  BaseContainer settings = GetGame().GetGameUserSettings().GetModule("SCR_AudioSettings");
413  if (!settings)
414  return;
415 
416  float value;
417  settings.Get("m_fDynamicRange", value);
418 
419  // DynamicRange has range <-1, 1>
420  GetGame().GetSignalsManager().SetSignalValue(s_iDynamicRangeIdx, value * 0.01 - 1);
421  }
422 
423  //------------------------------------------------------------------------------------------------
427  protected void SetTinnitusSignalValue()
428  {
429  BaseContainer settings = GetGame().GetGameUserSettings().GetModule("SCR_AudioSettings");
430  if (!settings)
431  return;
432 
433  bool value;
434  settings.Get("m_bGTinnitus", value);
435 
436  GetGame().GetSignalsManager().SetSignalValue(s_iGTinnitusIdx, value);
437  }
438 
439  //------------------------------------------------------------------------------------------------
443  protected void OnEditorOpen()
444  {
445  GetGame().GetSignalsManager().SetSignalValue(s_iInEditorIdx, 1);
446  }
447  //------------------------------------------------------------------------------------------------
451  protected void OnEditorClose()
452  {
453  GetGame().GetSignalsManager().SetSignalValue(s_iInEditorIdx, 0);
454  }
455  //------------------------------------------------------------------------------------------------
459  protected void OnEditorManagerInit(SCR_EditorManagerEntity editorManager)
460  {
461  editorManager.GetOnOpened().Insert(OnEditorOpen);
462  editorManager.GetOnClosed().Insert(OnEditorClose);
463  }
464  //------------------------------------------------------------------------------------------------
468  protected void OnEditorManagerExit(SCR_EditorManagerEntity editorManager)
469  {
470  editorManager.GetOnOpened().Remove(OnEditorOpen);
471  editorManager.GetOnClosed().Remove(OnEditorClose);
472  }
473 
474  //------------------------------------------------------------------------------------------------
478  protected void EditorManagerEventsInit()
479  {
480  SCR_EditorManagerEntity editorManager = SCR_EditorManagerEntity.GetInstance();
481  if (editorManager)
482  OnEditorManagerInit(editorManager);
483  else
484  {
486  if (editorManagerCore)
487  editorManagerCore.Event_OnEditorManagerInitOwner.Insert(OnEditorManagerInit);
488  }
489  }
490 
491  //------------------------------------------------------------------------------------------------
495  protected void EditorManagerEventsExit()
496  {
497  SCR_EditorManagerEntity editorManager = SCR_EditorManagerEntity.GetInstance();
498  if (editorManager)
499  OnEditorManagerExit(editorManager);
500 
502  if (editorManagerCore)
503  editorManagerCore.Event_OnEditorManagerInitOwner.Remove(OnEditorManagerInit);
504  }
505 
506  //------------------------------------------------------------------------------------------------
507  override void EOnPostFrame(IEntity owner, float timeSlice)
508  {
509  HandleAudioSources();
510  }
511 
512  //------------------------------------------------------------------------------------------------
513  override void EOnInit(IEntity owner)
514  {
515  // Register SCR_SoundManagerEntity
516  GetGame().RegisterSoundManagerEntity(this);
517 
518  // Get global signals indexes
519  GameSignalsManager gameSignalsManager = GetGame().GetSignalsManager();
520 
521  s_iGInteriorIdx = gameSignalsManager.AddOrFindSignal(G_INTERIOR_SIGNAL_NAME);
522  s_iGCurrVehicleCoverageIdx = gameSignalsManager.AddOrFindSignal(G_CURR_VEHICLE_COVERAGE_SIGNAL_NAME);
523  s_iGIsThirdPersonCamIdx = gameSignalsManager.AddOrFindSignal(G_IS_THIRD_PERSON_CAM_SIGNAL_NAME);
524  s_iGRoomSizeIdx = gameSignalsManager.AddOrFindSignal(G_ROOM_SIZE);
525  s_iDynamicRangeIdx = gameSignalsManager.AddOrFindSignal(DYNAMIC_RANGE_SIGNAL_NAME);
526  s_iGTinnitusIdx = gameSignalsManager.AddOrFindSignal(G_TINNITUS_SIGNAL_NAME);
527  s_iInEditorIdx = gameSignalsManager.AddOrFindSignal(IN_EDITOR_SIGNAL_NAME);
528 
529  // Event listeners for audio game settings
530  GetGame().OnUserSettingsChangedInvoker().Insert(SetDynamicRangeSignalValue);
531  GetGame().OnUserSettingsChangedInvoker().Insert(SetTinnitusSignalValue);
532  // Update DynamicRange signal
533  SetDynamicRangeSignalValue();
534  // Update EnableTinnitus signal
535  SetTinnitusSignalValue();
536 
537  //Event listeners for editor manager
538  EditorManagerEventsInit();
539 
540  // GetSoundWorld
541  ChimeraWorld chimeraWorld = ChimeraWorld.CastFrom(GetGame().GetWorld());
542  if (chimeraWorld)
543  m_SoundWorld = chimeraWorld.GetSoundWorld();
544 
545  #ifdef ENABLE_DIAG
546  s_iCreatedAudioSources = 0;
547  s_iMaxActiveAudioSources = 0;
548  s_iPlayedAudioSources = 0;
549  s_iInvalidAudioSources = 0;
550  s_iInaudibleAudioSources = 0;
551  s_iTerminateAudioSourceCalls = 0;
552  s_iCalculateInterirorAtCount = 0;
553  #endif
554  }
555 
556  //------------------------------------------------------------------------------------------------
557  void SCR_SoundManagerEntity(IEntitySource src, IEntity parent)
558  {
559  SetEventMask(EntityEvent.POSTFRAME | EntityEvent.INIT);
560  SetFlags(EntityFlags.NO_TREE | EntityFlags.NO_LINK);
561 
562  #ifdef ENABLE_DIAG
563  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SOUNDS_SOUND_MANAGER, "", "Sound Manager", "Sounds");
564  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SOUNDS_GLOBAL_VARIABLES, "", "Global Variables", "Sounds");
565  #endif
566  }
567 
568  //------------------------------------------------------------------------------------------------
569  void ~SCR_SoundManagerEntity()
570  {
571  // Terminate all playing sounds
572  TerminateAll();
573 
574  // Remove from audio game settings event
575  GetGame().OnUserSettingsChangedInvoker().Remove(SetDynamicRangeSignalValue);
576 
577  // Remove from editor manager events
578  EditorManagerEventsExit();
579 
580  #ifdef ENABLE_DIAG
581  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SOUNDS_SOUND_MANAGER);
582  DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_SOUNDS_GLOBAL_VARIABLES);
583  #endif
584  }
585 };
ChimeraWorld
Definition: ChimeraWorld.c:12
SCR_AudioSource
Definition: SCR_AudioSource.c:1
SCR_Enum
Definition: SCR_Enum.c:1
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
EAudioSourceConfigurationFlag
EAudioSourceConfigurationFlag
Definition: SCR_AudioSourceConfiguration.c:1
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
SCR_SoundManagerEntity
Definition: SCR_SoundManagerEntity.c:17
SCR_InteriorRequestCallback
Definition: SCR_InteriorRequestCallback.c:1
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
SCR_EditorManagerCore
Core component to manage SCR_EditorManagerEntity.
Definition: SCR_EditorManagerCore.c:5
SCR_SoundManagerEntityClass
Definition: SCR_SoundManagerEntity.c:2
GameSignalsManager
Definition: GameSignalsManager.c:7
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
m_Owner
SCR_AIGroupUtilityComponentClass m_Owner
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180
SCR_EditorManagerEntity
Definition: SCR_EditorManagerEntity.c:26