AudioEventHandler.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "AudioEventHandler.h"
  2. #include "../core/component.h"
  3. #include "../core/entity.h"
  4. #include "../core/world.h"
  5. #include "AudioSystem.h"
  6. #include "core/event_manager.h"
  7. #include "units/spawn_type.h"
  8. #include <chrono>
  9. #include <string>
  10. namespace Game::Audio {
  11. AudioEventHandler::AudioEventHandler(Engine::Core::World *world)
  12. : m_world(world) {}
  13. AudioEventHandler::~AudioEventHandler() { shutdown(); }
  14. auto AudioEventHandler::initialize() -> bool {
  15. if (m_initialized) {
  16. return true;
  17. }
  18. m_unitSelectedSub =
  19. Engine::Core::ScopedEventSubscription<Engine::Core::UnitSelectedEvent>(
  20. [this](const Engine::Core::UnitSelectedEvent &event) {
  21. onUnitSelected(event);
  22. });
  23. m_ambientChangedSub = Engine::Core::ScopedEventSubscription<
  24. Engine::Core::AmbientStateChangedEvent>(
  25. [this](const Engine::Core::AmbientStateChangedEvent &event) {
  26. onAmbientStateChanged(event);
  27. });
  28. m_audioTriggerSub =
  29. Engine::Core::ScopedEventSubscription<Engine::Core::AudioTriggerEvent>(
  30. [this](const Engine::Core::AudioTriggerEvent &event) {
  31. onAudioTrigger(event);
  32. });
  33. m_musicTriggerSub =
  34. Engine::Core::ScopedEventSubscription<Engine::Core::MusicTriggerEvent>(
  35. [this](const Engine::Core::MusicTriggerEvent &event) {
  36. onMusicTrigger(event);
  37. });
  38. m_initialized = true;
  39. return true;
  40. }
  41. void AudioEventHandler::shutdown() {
  42. if (!m_initialized) {
  43. return;
  44. }
  45. m_unitSelectedSub.unsubscribe();
  46. m_ambientChangedSub.unsubscribe();
  47. m_audioTriggerSub.unsubscribe();
  48. m_musicTriggerSub.unsubscribe();
  49. m_unitVoiceMap.clear();
  50. m_ambientMusicMap.clear();
  51. m_initialized = false;
  52. }
  53. void AudioEventHandler::loadUnitVoiceMapping(const std::string &unit_type,
  54. const std::string &soundId) {
  55. m_unitVoiceMap[unit_type] = soundId;
  56. }
  57. void AudioEventHandler::loadAmbientMusic(Engine::Core::AmbientState state,
  58. const std::string &musicId) {
  59. m_ambientMusicMap[state] = musicId;
  60. }
  61. void AudioEventHandler::setVoiceSoundCategory(bool useVoiceCategory) {
  62. m_useVoiceCategory = useVoiceCategory;
  63. }
  64. void AudioEventHandler::onUnitSelected(
  65. const Engine::Core::UnitSelectedEvent &event) {
  66. if (m_world == nullptr) {
  67. return;
  68. }
  69. auto *entity = m_world->getEntity(event.unit_id);
  70. if (entity == nullptr) {
  71. return;
  72. }
  73. auto *unit_component = entity->getComponent<Engine::Core::UnitComponent>();
  74. if (unit_component == nullptr) {
  75. return;
  76. }
  77. std::string const unit_type_str =
  78. Game::Units::spawn_typeToString(unit_component->spawn_type);
  79. auto it = m_unitVoiceMap.find(unit_type_str);
  80. if (it != m_unitVoiceMap.end()) {
  81. auto now = std::chrono::steady_clock::now();
  82. auto time_since_last_sound =
  83. std::chrono::duration_cast<std::chrono::milliseconds>(
  84. now - m_lastSelectionSoundTime)
  85. .count();
  86. bool const should_play =
  87. (time_since_last_sound >= SELECTION_SOUND_COOLDOWN_MS) ||
  88. (unit_type_str != m_lastSelectionUnitType);
  89. if (should_play) {
  90. AudioCategory const category =
  91. m_useVoiceCategory ? AudioCategory::VOICE : AudioCategory::SFX;
  92. AudioSystem::getInstance().playSound(it->second, 1.0F, false, 5,
  93. category);
  94. m_lastSelectionSoundTime = now;
  95. m_lastSelectionUnitType = unit_type_str;
  96. }
  97. }
  98. }
  99. void AudioEventHandler::onAmbientStateChanged(
  100. const Engine::Core::AmbientStateChangedEvent &event) {
  101. auto it = m_ambientMusicMap.find(event.new_state);
  102. if (it != m_ambientMusicMap.end()) {
  103. AudioSystem::getInstance().playMusic(it->second);
  104. }
  105. }
  106. void AudioEventHandler::onAudioTrigger(
  107. const Engine::Core::AudioTriggerEvent &event) {
  108. AudioSystem::getInstance().playSound(event.soundId, event.volume, event.loop,
  109. event.priority);
  110. }
  111. void AudioEventHandler::onMusicTrigger(
  112. const Engine::Core::MusicTriggerEvent &event) {
  113. AudioSystem::getInstance().playMusic(event.musicId, event.volume,
  114. event.crossfade);
  115. }
  116. } // namespace Game::Audio