AudioEventHandler.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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, UNIT_SELECTION_VOLUME,
  93. false, UNIT_SELECTION_PRIORITY,
  94. category);
  95. m_lastSelectionSoundTime = now;
  96. m_lastSelectionUnitType = unit_type_str;
  97. }
  98. }
  99. }
  100. void AudioEventHandler::onAmbientStateChanged(
  101. const Engine::Core::AmbientStateChangedEvent &event) {
  102. auto it = m_ambientMusicMap.find(event.new_state);
  103. if (it != m_ambientMusicMap.end()) {
  104. AudioSystem::getInstance().playMusic(it->second);
  105. }
  106. }
  107. void AudioEventHandler::onAudioTrigger(
  108. const Engine::Core::AudioTriggerEvent &event) {
  109. AudioSystem::getInstance().playSound(event.soundId, event.volume, event.loop,
  110. event.priority);
  111. }
  112. void AudioEventHandler::onMusicTrigger(
  113. const Engine::Core::MusicTriggerEvent &event) {
  114. AudioSystem::getInstance().playMusic(event.musicId, event.volume,
  115. event.crossfade);
  116. }
  117. } // namespace Game::Audio