diff --git a/assets/game_assets/assets_audio.map b/assets/game_assets/assets_audio.map index d1178361778670e1e10cc101c20269773705127b..572a158bda8d86be819bed8f88992b85f61ffd2a 100644 --- a/assets/game_assets/assets_audio.map +++ b/assets/game_assets/assets_audio.map @@ -1,2 +1,2 @@ -audio: = audio/*.ogg -music: = music/*.ogg +audio: = audio/*.opus +music: = music/*.opus diff --git a/assets/game_assets/audio/Finish_01.opus b/assets/game_assets/audio/Finish_01.opus new file mode 100644 index 0000000000000000000000000000000000000000..a611d875b00429363d99c5d75a71af8abb7f7cf0 --- /dev/null +++ b/assets/game_assets/audio/Finish_01.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4b081c18b8fd488aae71fc5a04af82c93ab0fb2bf554ad0d74605d11b64aac8 +size 92030 diff --git a/assets/game_assets/audio/beat.ogg b/assets/game_assets/audio/beat.ogg deleted file mode 100644 index 8cdf08aee7f2f1762ce771992551b5af9619043e..0000000000000000000000000000000000000000 Binary files a/assets/game_assets/audio/beat.ogg and /dev/null differ diff --git a/assets/game_assets/audio/beat.opus b/assets/game_assets/audio/beat.opus new file mode 100644 index 0000000000000000000000000000000000000000..969b98db0591c9edb8b06f89f92351726af71097 --- /dev/null +++ b/assets/game_assets/audio/beat.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b615bd2935ccefe3fa5f61110bbe037fb1ed29448c296161d6d936a6e89ae36 +size 12568 diff --git a/assets/game_assets/audio/dash1.opus b/assets/game_assets/audio/dash1.opus new file mode 100644 index 0000000000000000000000000000000000000000..fa1423cdb710f86bc76c97399022a185cb5535ae --- /dev/null +++ b/assets/game_assets/audio/dash1.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfd31bbccf613feeb2cb4ab7724ad446774067d6ba69bb07411bd4c28604f62e +size 12155 diff --git a/assets/game_assets/audio/dash2.opus b/assets/game_assets/audio/dash2.opus new file mode 100644 index 0000000000000000000000000000000000000000..89ea1f12662c778967173cb522a6aff8161509fe --- /dev/null +++ b/assets/game_assets/audio/dash2.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:108aab6f480242432cd0b329e85a7bdee50bc153cbd40fb9313f9fd6ae77a098 +size 9072 diff --git a/assets/game_assets/audio/dash3.opus b/assets/game_assets/audio/dash3.opus new file mode 100644 index 0000000000000000000000000000000000000000..6f520b08888572df6133d14d558eb6cdd7d418f2 --- /dev/null +++ b/assets/game_assets/audio/dash3.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e2cd3125a99d12851c1369f7121ee0a3e51ad22158f341207e4e1107484e7c4 +size 7396 diff --git a/assets/game_assets/audio/empty b/assets/game_assets/audio/empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/assets/game_assets/audio/enemy_attack_heavy.opus b/assets/game_assets/audio/enemy_attack_heavy.opus new file mode 100644 index 0000000000000000000000000000000000000000..8ac2d48ba82baca455b4fc707bd76df9f8ada82f --- /dev/null +++ b/assets/game_assets/audio/enemy_attack_heavy.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85980c3502091535aa09ca48f25b1f8e6378b6dc84027031ccc0cec1a475742e +size 20063 diff --git a/assets/game_assets/audio/enemy_attack_small.opus b/assets/game_assets/audio/enemy_attack_small.opus new file mode 100644 index 0000000000000000000000000000000000000000..f853247f59e3df99610bd9796ed6049eeba5509f --- /dev/null +++ b/assets/game_assets/audio/enemy_attack_small.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e1753ca86cb3c49eb22cb302b6dd5e704157990649975dd8ca03766cb12ec95 +size 9105 diff --git a/assets/game_assets/audio/enemy_hit_1.opus b/assets/game_assets/audio/enemy_hit_1.opus new file mode 100644 index 0000000000000000000000000000000000000000..9cb1da047ce53ba05d2da5ba57be9b70a2cda745 --- /dev/null +++ b/assets/game_assets/audio/enemy_hit_1.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c312022846703b6fad2c930fb373c47fd102a947d1d32c8b014d90e805fd98d +size 17203 diff --git a/assets/game_assets/audio/enemy_hit_2.opus b/assets/game_assets/audio/enemy_hit_2.opus new file mode 100644 index 0000000000000000000000000000000000000000..3f6d6e829db9b364e601c3692fcec7b08ee77b75 --- /dev/null +++ b/assets/game_assets/audio/enemy_hit_2.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22278cd985a9f8dee85807e20b587f3ae74e9de0f6a1000f2c3cc136f973db88 +size 14701 diff --git a/assets/game_assets/audio/enemy_hit_3.opus b/assets/game_assets/audio/enemy_hit_3.opus new file mode 100644 index 0000000000000000000000000000000000000000..2a69dab56db3501475314c09fd306d4c00facd47 --- /dev/null +++ b/assets/game_assets/audio/enemy_hit_3.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:889ce08a1ee277dd596226ed715a00a936060f73591f486fda1a4fbe5ecbf4c5 +size 9736 diff --git a/assets/game_assets/audio/enemy_hit_4.opus b/assets/game_assets/audio/enemy_hit_4.opus new file mode 100644 index 0000000000000000000000000000000000000000..7914af3533c46eb8e678bcafb54f693a873abaeb --- /dev/null +++ b/assets/game_assets/audio/enemy_hit_4.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:916663ea14bd4be556af7c543e2e48ac12a456f84f72bf39cde5bc9003512d3f +size 26871 diff --git a/assets/game_assets/audio/enemy_hit_5.opus b/assets/game_assets/audio/enemy_hit_5.opus new file mode 100644 index 0000000000000000000000000000000000000000..d7e4e7565bd8b02de9ac07761e59b5515336dd5f --- /dev/null +++ b/assets/game_assets/audio/enemy_hit_5.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c477b2bb3be41fdf5f207be2e378dd228f8d9d8bc140c3ffb329c704a3550a1 +size 24700 diff --git a/assets/game_assets/audio/gameover.opus b/assets/game_assets/audio/gameover.opus new file mode 100644 index 0000000000000000000000000000000000000000..b6c29b2ebb8490b5e41f47ab06eec1739a9e4ff2 --- /dev/null +++ b/assets/game_assets/audio/gameover.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f6afc736a2ba540ea0a56ba3f46bfce85dc127015e4d0bd9a253c4e7d3af91d +size 41793 diff --git a/assets/game_assets/audio/player_damaged.opus b/assets/game_assets/audio/player_damaged.opus new file mode 100644 index 0000000000000000000000000000000000000000..464c5a0a7b1d72591016973db8dece4fd68ae457 --- /dev/null +++ b/assets/game_assets/audio/player_damaged.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87085464b4af7e4be422e23fc16cf096872216da50afcfbbbfd83a3f41c28f3f +size 12600 diff --git a/assets/game_assets/audio/player_damaged__.opus b/assets/game_assets/audio/player_damaged__.opus new file mode 100644 index 0000000000000000000000000000000000000000..c48ed69a4141793d423ed77d469b572707d4ed36 --- /dev/null +++ b/assets/game_assets/audio/player_damaged__.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea2b06c95463ccb841e17168783cf0af078d050a77677ecd07c6f58c1d5e7f22 +size 13069 diff --git a/assets/game_assets/audio/stationary_attack.opus b/assets/game_assets/audio/stationary_attack.opus new file mode 100644 index 0000000000000000000000000000000000000000..21b251fb3f084ee08d3cb123bae7e3496a498be3 --- /dev/null +++ b/assets/game_assets/audio/stationary_attack.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8645962b7f1ee30c2e915968f9557c91578f89979ed6b7a901b40430f5e2a96 +size 77771 diff --git a/assets/game_assets/audio/win.opus b/assets/game_assets/audio/win.opus new file mode 100644 index 0000000000000000000000000000000000000000..5b8d4e30051f14d1c8fa162e7d11b8a2117296d7 --- /dev/null +++ b/assets/game_assets/audio/win.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1264274eb81cb34b37f7b2ed3c2b247247600acb6f2bf8f0d10ee63f595a3ae +size 39289 diff --git a/assets/game_assets/audio/win2.opus b/assets/game_assets/audio/win2.opus new file mode 100644 index 0000000000000000000000000000000000000000..27547297fab37dc9d3e0facd4ed53fc2ff424691 --- /dev/null +++ b/assets/game_assets/audio/win2.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd95be9c0938ce279961230d2a40282a8314c77051e31f7076cecb0f867aa5ea +size 25910 diff --git a/assets/game_assets/level/proto.lvl b/assets/game_assets/level/proto.lvl new file mode 100644 index 0000000000000000000000000000000000000000..1156fd90154309e73d7b7e56b79a9a6434e2503e --- /dev/null +++ b/assets/game_assets/level/proto.lvl @@ -0,0 +1,17 @@ +dummy +################################ +#|------------------|#|-------|# +#| - h h h|#| G |# +#| p h hhh h|#| |# +#| h h h|#| -- |# +#|-------------| |#| --h-- |# +####|----------|h |#| h -- |# +####| b b |#| h |# +####| b b h|#| -- |# +####|b |-------| |#| -- |# +####| |-------|h |-| h |# +####| h h h |# +####| h h h h h - |# +####| h h h h |# +####|-------------------------|# +################################ \ No newline at end of file diff --git a/assets/game_assets/music/pulse.ogg b/assets/game_assets/music/pulse.ogg deleted file mode 100644 index 5f5b6b7ab0b39092fc26a729867c49a1c11ecf92..0000000000000000000000000000000000000000 Binary files a/assets/game_assets/music/pulse.ogg and /dev/null differ diff --git a/assets/game_assets/music/pulse.opus b/assets/game_assets/music/pulse.opus new file mode 100644 index 0000000000000000000000000000000000000000..8dba48b62e753ac0aa93a11288ec68efd68c0c17 --- /dev/null +++ b/assets/game_assets/music/pulse.opus @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdf9d010bcf91fa165cbd3b5d07d415eeeb8957255ea5362b8472da4fbc13559 +size 2087114 diff --git a/assets/game_assets/settings/sound_effects.json b/assets/game_assets/settings/sound_effects.json new file mode 100644 index 0000000000000000000000000000000000000000..50dbb894520709b72122d1a48f2fe3614493e9b8 --- /dev/null +++ b/assets/game_assets/settings/sound_effects.json @@ -0,0 +1,12 @@ +{ + "effects": { + "dash": ["dash3"], + "attack": ["stationary_attack"], + "e_att_h": ["enemy_attack_heavy"], + "e_att_s": ["enemy_attack_small"], + "enemy_hit": ["enemy_hit_1", "enemy_hit_2", "enemy_hit_3", "enemy_hit_4", "enemy_hit_5"], + "gameover": ["gameover"], + "damaged": ["player_damaged"], + "win": ["win", "win2"] + } +} diff --git a/src/audio/sound_manager.cpp b/src/audio/sound_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..528aa066f533925c0ac98a89463ffd01daf6da4d --- /dev/null +++ b/src/audio/sound_manager.cpp @@ -0,0 +1,75 @@ +#include "sound_manager.hpp" + +#include "audio_asset.hpp" + +#include "../messages.hpp" + +#include + +#include + +namespace phase_shifter::audio { + + struct Effect_file { + std::unordered_map> effects; + }; + sf2_structDef(Effect_file, effects); + + Sound_manager::Sound_manager(eam::audio& audio, + mirrage::util::Message_bus& bus, + mirrage::asset::Asset_manager& assets) + : _audio(audio), _mailbox(bus), _assets(assets), _random_gen(mirrage::util::construct_random_engine()) + { + _mailbox.subscribe_to([&](Play_sound_msg& e) { play_effect(e.id); }); + } + + void Sound_manager::load_effects_file(const mirrage::asset::AID& aid) + { + auto file = _assets.load(aid, false); + + for(auto&& [id, paths] : file.get_blocking().effects) { + for(auto&& path : paths) + register_effect(Sound_effect_id(id), mirrage::asset::AID("audio"_strid, path)); + } + } + + void Sound_manager::effect_volume(float v) { _effect_volume = v; } + + void Sound_manager::pause() + { + // TODO + } + void Sound_manager::resume() + { + // TODO + } + + void Sound_manager::update(mirrage::util::Time dt) { _mailbox.update_subscriptions(); } + + void Sound_manager::register_effect(Sound_effect_id id, const mirrage::asset::AID& aid) + { + LOG(plog::info) << "Loading sound " << aid.str(); + auto effect = _assets.load>(aid).get_blocking(); + + auto entry = _sound_effects.find(id); + if(entry != _sound_effects.end()) + entry->second.raw_vector().emplace_back(std::move(effect)); + else { + auto effects = Sound_effect_set(); + effects.raw_vector().emplace_back(std::move(effect)); + _sound_effects.emplace(id, std::move(effects)); + } + } + void Sound_manager::unregister_effect(Sound_effect_id id) { _sound_effects.erase(id); } + void Sound_manager::play_effect(Sound_effect_id id) + { + auto effect = _sound_effects.find(id); + if(effect != _sound_effects.end()) { + auto ctx = _audio.generate_context(effect->second.get_random(_random_gen)); + ctx.get_object()->set_loops(0); + ctx.get_object()->set_volume(_effect_volume * 100); + ctx.play(); + } + } + +} // namespace phase_shifter::audio diff --git a/src/audio/sound_manager.hpp b/src/audio/sound_manager.hpp new file mode 100644 index 0000000000000000000000000000000000000000..35c70dbe86a041719a42963b1424537a9e3f1855 --- /dev/null +++ b/src/audio/sound_manager.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "../util/random_vector.hpp" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +namespace phase_shifter::audio { + + using Sound_effect_id = mirrage::util::Str_id; + + class Sound_manager { + public: + Sound_manager(eam::audio& audio, mirrage::util::Message_bus&, mirrage::asset::Asset_manager&); + + void load_effects_file(const mirrage::asset::AID& aid); + + void effect_volume(float); + auto effect_volume() const -> float { return _effect_volume; } + + void pause(); + void resume(); + + void update(mirrage::util::Time dt); + + void register_effect(Sound_effect_id id, const mirrage::asset::AID& aid); + void unregister_effect(Sound_effect_id id); + + void play_effect(Sound_effect_id id); + + private: + using Sound_effect = std::shared_ptr; + using Sound_effect_set = utils::Random_vector; + + eam::audio& _audio; + mirrage::util::Mailbox_collection _mailbox; + mirrage::asset::Asset_manager& _assets; + float _effect_volume = 1.f; + std::mt19937_64 _random_gen; + + std::unordered_map _sound_effects; + }; + +} // namespace phase_shifter::audio diff --git a/src/gameplay/movement_system.cpp b/src/gameplay/movement_system.cpp index 52bb85878b6566b75fb6d6a6a132e372b8a3965d..4cbc51fb40940185652fc6edf2601556eb668255 100644 --- a/src/gameplay/movement_system.cpp +++ b/src/gameplay/movement_system.cpp @@ -3,6 +3,7 @@ #include "beat_system.hpp" #include "combat_system.hpp" #include "movement_comp.hpp" +#include "player_comp.hpp" #include "rigid_body_comp.hpp" #include "../level/level_system.hpp" @@ -67,12 +68,20 @@ namespace phase_shifter::gameplay { if(aim_len < 0.0001f) { // TODO: attack move.attack = true; + + if(entity.has()) { + _bus.send("attack"_strid); + } } else { // start movement move.step_time_left = beat.avg_beat_time * move.step_time_percentage; move.step_time = move.step_time_left; move.last_step = (aim_len > 1.f ? move.aim / aim_len : move.aim) * move.distance_per_step; + + if(entity.has()) { + _bus.send("dash"_strid); + } } } else { diff --git a/src/messages.hpp b/src/messages.hpp index c1d721db9a563581cb3683f14f6cec6de012b757..3d89bff0698eb8cd848da7de4270e48a0a5467e9 100644 --- a/src/messages.hpp +++ b/src/messages.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include @@ -20,4 +21,8 @@ namespace phase_shifter { glm::vec3 attack_direction; }; + struct Play_sound_msg { + mirrage::util::Str_id id; + }; + } // namespace phase_shifter diff --git a/src/meta_system.cpp b/src/meta_system.cpp index 9409d0f052a4f4f0163436e3ab1dc893c8d514db..706b442b606f2641bf914a86719b23c21513d881 100644 --- a/src/meta_system.cpp +++ b/src/meta_system.cpp @@ -1,6 +1,7 @@ #include "meta_system.hpp" #include "audio/audio_asset.hpp" +#include "audio/sound_manager.hpp" #include "game_engine.hpp" #include "gameplay/beat_system.hpp" #include "gameplay/camera_system.hpp" @@ -33,6 +34,7 @@ namespace phase_shifter { : _entities(engine.assets(), this) , _renderer(engine.renderer_factory().create_renderer(_entities, engine.render_pass_mask())) , _model_loading(std::make_unique(_entities, engine.assets())) + , _sound_manager(std::make_unique(engine.audio(), engine.bus(), engine.assets())) , _beat_system(std::make_unique(engine.bus(), engine.assets())) , _level_system(std::make_unique(_entities, engine.assets())) , _movement_system(std::make_unique( @@ -48,6 +50,8 @@ namespace phase_shifter { std::make_unique(engine.bus(), _entities)) , _effect_system(std::make_unique(engine.bus(), _entities)) { + _sound_manager->load_effects_file("cfg:sound_effects"_aid); + _entities.register_component_type(); //auto s = _renderer->settings(); @@ -130,6 +134,7 @@ namespace phase_shifter { _model_loading->update(dt); _renderer->update(dt * _beat_system->graphic_time_scale()); + _sound_manager->update(dt); } void Meta_system::draw() { @@ -138,8 +143,16 @@ namespace phase_shifter { } - void Meta_system::pause() { _input_system->disable(); } - void Meta_system::resume() { _input_system->enable(); } + void Meta_system::pause() + { + _input_system->disable(); + _sound_manager->pause(); + } + void Meta_system::resume() + { + _input_system->enable(); + _sound_manager->resume(); + } void Meta_system::shrink_to_fit() { _renderer->shrink_to_fit(); } diff --git a/src/meta_system.hpp b/src/meta_system.hpp index ab22dd93a21630e8bfa49e242c7fcf41a5d4f606..cbf157f05f66d140cd33446ed111329e5ab02f3e 100644 --- a/src/meta_system.hpp +++ b/src/meta_system.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace mirrage { namespace renderer { @@ -19,6 +20,9 @@ namespace mirrage { namespace phase_shifter { class Game_engine; + namespace audio { + class Sound_manager; + } namespace gameplay { class Beat_system; class Movement_system; @@ -63,6 +67,7 @@ namespace phase_shifter { mirrage::ecs::Entity_manager _entities; std::unique_ptr _renderer; std::unique_ptr _model_loading; + std::unique_ptr _sound_manager; std::unique_ptr _beat_system; std::unique_ptr _level_system; diff --git a/src/ui/effect_system.cpp b/src/ui/effect_system.cpp index 3f33c80fd82c5246ec4f101e07f176eb1dfe3b29..3498ea06c4fbe0c13f4af31eccfc9b4cef6421ff 100644 --- a/src/ui/effect_system.cpp +++ b/src/ui/effect_system.cpp @@ -1,5 +1,7 @@ #include "effect_system.hpp" +#include "../gameplay/combat_system.hpp" +#include "../gameplay/player_comp.hpp" #include "../messages.hpp" #include @@ -13,6 +15,8 @@ namespace phase_shifter::ui { : _bus(bus), _mailbox(bus), _ecs(ecs) { _mailbox.subscribe_to([&](Enemy_killed_msg& e) { + _bus.send("enemy_hit"_strid); + auto entity = _ecs.entity_builder("enemy_tombstone") .rotation(glm::rotation( glm::vec3{1.f, 0.f, 0.f}, @@ -20,17 +24,22 @@ namespace phase_shifter::ui { .position(e.position) .create(); - _actions.defer(5_s, [&, entity] { - _ecs.erase(entity); - LOG(plog::debug) << "erased"; + _actions.defer(5_s, [&, entity] { _ecs.erase(entity); }); + }); + + _mailbox.subscribe_to([&](gameplay::Damaged_msg& e) { + _ecs.get(e.entity).process([&](auto& entity) { + entity.process([&](gameplay::Player_comp&) { _bus.send("damaged"_strid); }); }); }); _mailbox.subscribe_to([&](Win_msg& e) { + _bus.send("win"_strid); // TODO }); _mailbox.subscribe_to([&](Lose_msg& e) { + _bus.send("gameover"_strid); // TODO }); } diff --git a/src/util/random_vector.hpp b/src/util/random_vector.hpp new file mode 100644 index 0000000000000000000000000000000000000000..800907b55b453371bb720429abd7755c4715c28d --- /dev/null +++ b/src/util/random_vector.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include + + +namespace phase_shifter::utils { + + template + class Random_vector { + public: + Random_vector(std::vector data = {}) : _data(std::move(data)) {} + + auto raw_vector() -> std::vector& { return _data; } + + auto empty() const { return _data.empty(); } + + template + auto get_random(RNG& gen) -> T& + { + if(_data.size() <= 1) + return _data.front(); + + if(_next_index < _data.size()) + return _data[_next_index++]; + + if(_data.size() > 2) { + auto low = static_cast(std::ceil(_data.size() / 4.f)); + auto high = static_cast(std::floor(_data.size() / 4.f * 3.f)); + std::shuffle(_data.begin(), _data.begin() + high, gen); + std::shuffle(_data.begin() + low, _data.end(), gen); + } + + _next_index = 1; + return _data[0]; + } + + private: + std::vector _data; + std::size_t _next_index = 0; + }; + +} // namespace phase_shifter::utils