diff --git a/assets b/assets index e4dc9529..9b4f9ab2 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e4dc9529f2178d373808ddf487165fa50a641a78 +Subproject commit 9b4f9ab2e67fc09863f35b33bb0a61ce75ef6aa8 diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index b9cc2589..5d57d5b6 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -20,6 +20,10 @@ #include "Sound/EStopSound.h" #include "Sound/ESetBGMGain.h" #include "Sound/ESetSFXGain.h" +#include "Core/EShoot.h" +#include "Core/EPlayerSpawned.h" +#include "Input/EInputCommand.h" +#include "Core/ECaptured.h" enum class SoundType { SFX, @@ -55,18 +59,24 @@ private: // Logic void initOpenAL(); - void updateEmitters(double dt); - void updateListener(double dt); - void deleteInactiveEmitters(); void addNewEmitters(double dt); - Source* createSource(std::string filePath); - void playSound(Source* source); - void stopSound(Source* source); + void updateEmitters(double dt); + void deleteInactiveEmitters(); void stopEmitters(); + void updateListener(double dt); + Source* createSource(std::string filePath); ALenum getSourceState(ALuint source); void setGain(Source* source, float gain); void setSoundProperties(ALuint source, ComponentWrapper* soundComponent); + // Specific logic + void playSound(Source* source); + void stopSound(Source* source); + void playerDamaged(); + void playerShot(); + void playerJumps(); + void playerStep(double dt); + // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; @@ -75,9 +85,14 @@ private: World* m_World = nullptr; EventBroker* m_EventBroker = nullptr; std::unordered_map m_Sources; - float m_BGMVolumeChannel = 1.0f; + float m_BGMVolumeChannel = 1.f; float m_SFXVolumeChannel = 1.f; bool m_EditorEnabled = false; + const double m_PlayerFootstepInterval = 0.5; + double m_TimeSinceLastFootstep = 0; + // TEMP + EntityID m_LocalPlayer = EntityID_Invalid; + bool m_LeftFoot = false; // Events EventRelay m_EPlaySoundOnEntity; @@ -96,6 +111,16 @@ private: bool OnSetBGMGain(const Events::SetBGMGain &e); // Not tested EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); // Not tested + + EventRelay m_EShoot; + bool OnShoot(const Events::Shoot &e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned &e); + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand &e); + EventRelay m_ECaptured; + bool OnCaptured(const Events::Captured &e); + }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/aim_rays.xml b/resources/Schema/Entities/aim_rays.xml new file mode 100644 index 00000000..c488ca51 --- /dev/null +++ b/resources/Schema/Entities/aim_rays.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + models/core/unitcube.mesh + + + + + + + + + + + diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index d0887c05..dbabb32d 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -20,6 +20,10 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::OnSetBGMGain); EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); + EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); } SoundSystem::~SoundSystem() @@ -48,19 +52,20 @@ void SoundSystem::stopEmitters() } void SoundSystem::Update(double dt) -{ +{ m_EventBroker->Process(); + playerStep(dt); addNewEmitters(dt); // can be optimized with "EEntityCreated" deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" - updateEmitters( dt); - updateListener( dt); + updateEmitters(dt); + updateListener(dt); } void SoundSystem::deleteInactiveEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { - if (m_World->ValidEntity(it->first) + if (m_World->ValidEntity(it->first) && m_World->HasComponent(it->first, "SoundEmitter")) { if (getSourceState(it->second->ALsource) != AL_STOPPED) { // Nothing to see here, move along @@ -70,6 +75,7 @@ void SoundSystem::deleteInactiveEmitters() // Sound has been stopped / finished playing. alDeleteBuffers(1, &it->second->ALsource); alDeleteSources(1, &it->second->ALsource); + m_World->DeleteEntity(it->first); delete it->second; it = m_Sources.erase(it); } @@ -174,6 +180,58 @@ void SoundSystem::stopSound(Source* source) alSourceStop(source->ALsource); } +void SoundSystem::playerDamaged() +{ + +} + +void SoundSystem::playerShot() +{ } + +void SoundSystem::playerJumps() +{ + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; + if (vel.y > 1) { + Source* source = createSource("Audio/jump/jump1.wav"); + auto emitterID = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(emitterID, "Transform"); + m_World->AttachComponent(emitterID, "SoundEmitter"); + source->Type = SoundType::SFX; + m_Sources[emitterID] = source; + playSound(source); + } +} + +void SoundSystem::playerStep(double dt) +{ + if (m_LocalPlayer == EntityID_Invalid) { + return; + } + m_TimeSinceLastFootstep += dt; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; + float playerSpeed = glm::length(vel); + bool isAirborne = vel.y != 0; + if (playerSpeed > 1 && !isAirborne) { + // Player is walking + if (m_TimeSinceLastFootstep > m_PlayerFootstepInterval) { + // Create footstep sound + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + Events::PlaySoundOnEntity e; + e.EmitterID = child; + if (m_LeftFoot) { + e.FilePath = "Audio/footstep/footstep2.wav"; + } else { + e.FilePath = "Audio/footstep/footstep3.wav"; + } + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_TimeSinceLastFootstep = 0; + } + } +} + bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); @@ -251,6 +309,69 @@ bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) return true; } +bool SoundSystem::OnShoot(const Events::Shoot & e) +{ + Source* source = createSource("Audio/laser/laser1.wav"); + auto emitterID = m_World->CreateEntity(e.Player.ID); + m_World->AttachComponent(emitterID, "Transform"); + auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + source->Type = SoundType::SFX; + m_Sources[emitterID] = source; + playSound(source); + return true; +} + +bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) +{ + if (e.PlayerID == -1) { // Local player + m_World->AttachComponent(e.Player.ID, "Listener"); + m_LocalPlayer = e.Player.ID; + EntityID child = m_World->CreateEntity(e.Player.ID); + m_World->AttachComponent(child, "SoundEmitter"); // Temp + m_World->AttachComponent(child, "Transform"); // Temp + Events::PlaySoundOnEntity event; + event.EmitterID = child; + event.FilePath = "Audio/announcer/go.wav"; + m_EventBroker->Publish(event); + } + return true; +} + +bool SoundSystem::OnInputCommand(const Events::InputCommand & e) +{ + if (e.Player.ID == EntityID_Invalid) { + //return false; + } + if (e.Command == "Jump" && e.Value > 0) { + if (e.PlayerID == -1) { // local player + //bool airBorne = ((glm::vec3)m_World->GetComponent(e.Player.ID, "Physics")["Velocity"]).y != 0; + //if (!airBorne) { + playerJumps(); + //} + return true; + } + } + return false; +} + +bool SoundSystem::OnCaptured(const Events::Captured & e) +{ + int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "CapturePoint")["HomePointForTeam"]; + int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; + Events::PlaySoundOnEntity ev; + if (team == homeTeam) { + ev.FilePath = "Audio/announcer/objective_achieved.wav"; + } else { + ev.FilePath = "Audio/announcer/objective_failed.wav"; + } + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + ev.EmitterID = child; + m_EventBroker->Publish(ev); + return false; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector.