From 0643393b9c4d38bd8317041b985ee7408689e0d3 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Mon, 8 Jan 2024 05:26:20 -0600 Subject: [PATCH] Added Sound effect configuration and implementation. --- .../Adventures in Lestoria.vcxproj | 5 + .../Adventures in Lestoria.vcxproj.filters | 6 + .../AdventuresInLestoria.cpp | 5 + Adventures in Lestoria/Audio.cpp | 15 +-- Adventures in Lestoria/Item.cpp | 12 ++ Adventures in Lestoria/Item.h | 4 + Adventures in Lestoria/SoundEffect.cpp | 77 +++++++++++ Adventures in Lestoria/SoundEffect.h | 55 ++++++++ Adventures in Lestoria/Version.h | 2 +- .../assets/config/audio/bgm.txt | 3 +- .../assets/config/audio/events.txt | 125 ++++++++++++------ .../assets/config/items/ItemDatabase.txt | 6 + Adventures in Lestoria/olcUTIL_DataFile.h | 1 + 13 files changed, 259 insertions(+), 57 deletions(-) create mode 100644 Adventures in Lestoria/SoundEffect.cpp create mode 100644 Adventures in Lestoria/SoundEffect.h diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 99641940..5183118a 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -463,6 +463,7 @@ + @@ -631,6 +632,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index f3726ac5..e6106801 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -423,6 +423,9 @@ Header Files + + Header Files + @@ -710,6 +713,9 @@ Source Files + + Source Files + diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index ea2b6071..b633cfa4 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -69,6 +69,7 @@ All rights reserved. #include "Merchant.h" #include "SaveFile.h" #include "TitleScreen.h" +#include "SoundEffect.h" #ifndef __EMSCRIPTEN__ #include "discord.h" #endif @@ -237,6 +238,7 @@ bool AiL::OnUserCreate(){ Audio::Initialize(); EnvironmentalAudio::Initialize(); + SoundEffect::Initialize(); LoadLevel(LEVEL_NAMES["starting_map"_S]); ChangePlayerClass(WARRIOR); @@ -2467,6 +2469,9 @@ bool AiL::UseLoadoutItem(int slot){ if(GetLoadoutItem(slot).lock()->Amt()>0){ Inventory::UseItem(GetLoadoutItem(slot).lock()->ActualName()); GetLoadoutItem(slot).lock()->amt--; + if(GetLoadoutItem(slot).lock()->UseSound().length()>0){ + SoundEffect::PlaySFX(GetLoadoutItem(slot).lock()->UseSound()); + } return true; } return false; diff --git a/Adventures in Lestoria/Audio.cpp b/Adventures in Lestoria/Audio.cpp index 6544c1eb..f106057c 100644 --- a/Adventures in Lestoria/Audio.cpp +++ b/Adventures in Lestoria/Audio.cpp @@ -48,7 +48,9 @@ void Audio::Initialize(){ Engine().SetBackgroundPlay(true); Self().events.insert("Default Volume"); for(auto&[key,data]:DATA["Events"]){ - Self().events.insert(key); + if(key!="SFX"){ //HACK ALERT! We are specifically excluding the SFX key because it's used to specify the sound effects in-game. + Self().events.insert(key); + } } for(auto&[songFileName,size]:DATA["BGM"]){ auto&data=DATA["BGM"][songFileName]; @@ -67,14 +69,7 @@ void Audio::Initialize(){ channelCounter++; } - if(!data.HasProperty("Default Volume"))ERR(std::format("WARNING! Track {} does not have a Default Volume parameter!",bgm.GetName())); - if(data["Default Volume"].GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! Default Volume parameters do not match channel count. {} != {}",data["Default Volume"].GetValueCount(),bgm.GetChannelCount())); - - VolumeList volumes; - for(int i=0;i0){ for(std::string&s:slot){ if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<0; +} + +const EventName&ItemInfo::UseSound()const{ + return useSound; +} +const EventName&Item::UseSound()const{ + return it->UseSound(); } \ No newline at end of file diff --git a/Adventures in Lestoria/Item.h b/Adventures in Lestoria/Item.h index ae9eb521..38868199 100644 --- a/Adventures in Lestoria/Item.h +++ b/Adventures in Lestoria/Item.h @@ -54,6 +54,7 @@ class ItemProps; using IT=std::string; using ITCategory=std::string; +using EventName=std::string; using ItemScript=std::function; @@ -180,6 +181,7 @@ public: //Use for places where the item name is actually displayed. Provides modified text that shows additional information like enhancement levels. const std::string DisplayName()const; const std::string Description(CompactText compact=COMPACT)const; + const EventName&UseSound()const; const ITCategory Category()const; const EquipSlot GetEquipSlot()const; const::Decal*const Decal()const; @@ -286,6 +288,7 @@ class ItemInfo{ EquipSlot slot; EnhancementInfo enhancement; ::Decal*img; + EventName useSound=""; std::string set=""; //Returns true if the item can be used, false otherwise std::string useFunc=""; @@ -313,6 +316,7 @@ public: /* For the useFunc, return true if the item can be used, false otherwise. */ + const EventName&UseSound()const; const ItemScript&OnUseAction()const; const Stats GetStats(int enhancementLevel)const; const float CastTime()const; diff --git a/Adventures in Lestoria/SoundEffect.cpp b/Adventures in Lestoria/SoundEffect.cpp new file mode 100644 index 00000000..d6c45a39 --- /dev/null +++ b/Adventures in Lestoria/SoundEffect.cpp @@ -0,0 +1,77 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2023 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion + +#include "olcUTIL_DataFile.h" +#include "SoundEffect.h" +#include "Audio.h" +#include "util.h" +#include "DEFINES.h" + +INCLUDE_DATA + +std::multimapSoundEffect::SOUND_EFFECTS; + +SoundEffect::SoundEffect(const std::string_view filename,const float&vol) + :filename(filename),vol(vol){ + if(vol<0.f||vol>1.f)ERR(std::format("WARNING! Volume must be between 0.0f ~ 1.0f! Provided value {}",vol)); +} + +void SoundEffect::Initialize(){ + for(auto&[key,size]:DATA["Events"]["SFX"]){ + int counter=0; + while(DATA["Events"]["SFX"][key].HasProperty(std::format("File[{}]",counter))){ + utils::datafile&data=DATA["Events"]["SFX"][key][std::format("File[{}]",counter)]; + SOUND_EFFECTS.insert({key,SoundEffect{data.GetString(0),data.GetInt(1)/100.f}}); + counter++; + } + } +} + +void SoundEffect::PlaySFX(const std::string_view eventName){ + auto itr=SOUND_EFFECTS.equal_range(std::string(eventName)); + size_t soundCount=std::distance(itr.first,itr.second); + size_t soundEffectChoice=util::random()%soundCount; + int counter=0; + auto it=itr.first; + while(counter!=soundEffectChoice){ + ++counter; + ++it; + } + const SoundEffect&sfx=(*it).second; + Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),sfx.vol); +} \ No newline at end of file diff --git a/Adventures in Lestoria/SoundEffect.h b/Adventures in Lestoria/SoundEffect.h new file mode 100644 index 00000000..d3e06fab --- /dev/null +++ b/Adventures in Lestoria/SoundEffect.h @@ -0,0 +1,55 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2023 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once + +#include +#include +#include "Error.h" + +using EventName=std::string; + +class SoundEffect{ +public: + SoundEffect(const std::string_view filename,const float&vol); + static void PlaySFX(const std::string_view eventName); + static void Initialize(); +private: + static std::multimapSOUND_EFFECTS; + std::string filename; + float vol; +}; \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 8851bd00..69e930d5 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 5466 +#define VERSION_BUILD 5476 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/config/audio/bgm.txt b/Adventures in Lestoria/assets/config/audio/bgm.txt index 05565a77..67b888a1 100644 --- a/Adventures in Lestoria/assets/config/audio/bgm.txt +++ b/Adventures in Lestoria/assets/config/audio/bgm.txt @@ -18,13 +18,12 @@ BGM channel[8]=foresty1_1_strings.ogg channel[9]=foresty1_1_xtra perc.ogg - Default Volume = 70%,70%,70%,70%,70%,70%,70%,70%,70%,70% - # Transition time between one phase to the next. Fade Time = 2.0 Events { + Default Volume = 70%,70%,70%,70%,70%,70%,70%,70%,70%,70% LowHealth = 100%,100%,100%,20%,20%,20%,100%,100%,20%,100% InCombat = 100%,100%,100%,100%,100%,100%,100%,100%,100%,100% Underwater = 10%,10%,10%,60%,80%,80%,10%,10%,70%,10% diff --git a/Adventures in Lestoria/assets/config/audio/events.txt b/Adventures in Lestoria/assets/config/audio/events.txt index 5e8277dd..cc71fc36 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -8,158 +8,195 @@ Events { Consume Potion { - File[0] = consume_potion.ogg + # Specify file names, followed by volume % + File[0] = consume_potion.ogg, 70% } Consume Item { - File[0] = consume_item.ogg + # Specify file names, followed by volume % + File[0] = consume_item.ogg, 60% } Equip Armor { - File[0] = equip.ogg - File[1] = equip2.ogg + # Specify file names, followed by volume % + File[0] = equip.ogg, 100% + File[1] = equip2.ogg, 100% } Equip Accessory { - File[0] = equip_ring.ogg + # Specify file names, followed by volume % + File[0] = equip_ring.ogg, 100% } Footstep { - File[0] = footsteps.ogg + # Specify file names, followed by volume % + File[0] = footsteps.ogg, 100% } Footstep - Wet { - File[0] = footsteps_wet.ogg + # Specify file names, followed by volume % + File[0] = footsteps_wet.ogg, 100% } Buy Item { - File[0] = item_buy.ogg + # Specify file names, followed by volume % + File[0] = item_buy.ogg, 100% } Sell Item { - File[0] = item_sell.ogg + # Specify file names, followed by volume % + File[0] = item_sell.ogg, 100% } Craft Item { - File[0] = item_craft.ogg + # Specify file names, followed by volume % + File[0] = item_craft.ogg, 100% } Enhance Item { - File[0] = item_enhance.ogg + # Specify file names, followed by volume % + File[0] = item_enhance.ogg, 100% } Monster Hurt { - File[0] = monster_hurt.ogg + # Specify file names, followed by volume % + File[0] = monster_hurt.ogg, 100% } Ranger Auto Attack { - File[0] = ranger_auto1.ogg - File[1] = ranger_auto2.ogg + # Specify file names, followed by volume % + File[0] = ranger_auto1.ogg, 100% + File[1] = ranger_auto2.ogg, 100% } Ranger Backstep { - File[0] = ranger_backstep.ogg + # Specify file names, followed by volume % + File[0] = ranger_backstep.ogg, 100% } Ranger Multishot { - File[0] = ranger_multishot.ogg + # Specify file names, followed by volume % + File[0] = ranger_multishot.ogg, 100% } Ranger Rapid Fire { - File[0] = ranger_rapid_fire.ogg + # Specify file names, followed by volume % + File[0] = ranger_rapid_fire.ogg, 100% } Ranger Charged Shot { - File[0] = ranger_charged_shot.ogg + # Specify file names, followed by volume % + File[0] = ranger_charged_shot.ogg, 100% } Ranger Multishot { - File[0] = ranger_multishot.ogg + # Specify file names, followed by volume % + File[0] = ranger_multishot.ogg, 100% } Slime Dead { - File[0] = slime_dead.ogg + # Specify file names, followed by volume % + File[0] = slime_dead.ogg, 100% } Monster Dead { - File[0] = slime_dead2.ogg + # Specify file names, followed by volume % + File[0] = slime_dead2.ogg, 100% } Slime King Land { - File[0] = slime_king_landing.ogg + # Specify file names, followed by volume % + File[0] = slime_king_landing.ogg, 100% } Slime King Shoot { - File[0] = slime_king_shoot.ogg + # Specify file names, followed by volume % + File[0] = slime_king_shoot.ogg, 100% } Slime Shoot { - File[0] = slime_shoot.ogg - File[1] = slime_shoot2.ogg + # Specify file names, followed by volume % + File[0] = slime_shoot.ogg, 100% + File[1] = slime_shoot2.ogg, 100% } Slime Walk { - File[0] = slime_walk.ogg - File[1] = slime_walk2.ogg - File[2] = slime_walk3.ogg + # Specify file names, followed by volume % + File[0] = slime_walk.ogg, 100% + File[1] = slime_walk2.ogg, 100% + File[2] = slime_walk3.ogg, 100% } Spell Cast { - File[0] = spell_cast.ogg + # Specify file names, followed by volume % + File[0] = spell_cast.ogg, 100% } Warrior Auto Attack { - File[0] = warrior_auto1.ogg + # Specify file names, followed by volume % + File[0] = warrior_auto1.ogg, 100% } Warrior Battlecry { - File[0] = warrior_battlecry.ogg + # Specify file names, followed by volume % + File[0] = warrior_battlecry.ogg, 100% } Warrior Block Hit { - File[0] = warrior_blockhit1.ogg - File[1] = warrior_blockhit2.ogg + # Specify file names, followed by volume % + File[0] = warrior_blockhit1.ogg, 100% + File[1] = warrior_blockhit2.ogg, 100% } Warrior Ground Slam { - File[0] = warrior_groundslam.ogg + # Specify file names, followed by volume % + File[0] = warrior_groundslam.ogg, 100% } Warrior Sonic Slash { - File[0] = warrior_sonicslash.ogg + # Specify file names, followed by volume % + File[0] = warrior_sonicslash.ogg, 100% } Wizard Auto Attack { - File[0] = wizard_auto1.ogg - File[1] = wizard_auto2.ogg + # Specify file names, followed by volume % + File[0] = wizard_auto1.ogg, 100% + File[1] = wizard_auto2.ogg, 100% } Wizard Fire Bolt { - File[0] = wizard_firebolt.ogg + # Specify file names, followed by volume % + File[0] = wizard_firebolt.ogg, 100% } Wizard Fire Bolt Hit { - File[0] = wizard_firebolt_hit.ogg + # Specify file names, followed by volume % + File[0] = wizard_firebolt_hit.ogg, 100% } Wizard Lightning Bolt { - File[0] = wizard_lightningbolt.ogg + # Specify file names, followed by volume % + File[0] = wizard_lightningbolt.ogg, 100% } Wizard Lightning Bolt Hit { - File[0] = wizard_firebolt_hit.ogg + # Specify file names, followed by volume % + File[0] = wizard_firebolt_hit.ogg, 100% } Wizard Meteor { - File[0] = wizard_meteor.ogg + # Specify file names, followed by volume % + File[0] = wizard_meteor.ogg, 100% } Wizard Meteor Flames { - File[0] = wizard_meteor_lingering.ogg + # Specify file names, followed by volume % + File[0] = wizard_meteor_lingering.ogg, 100% } Wizard Teleport { - File[0] = wizard_teleport.ogg + # Specify file names, followed by volume % + File[0] = wizard_teleport.ogg, 100% } } } \ No newline at end of file diff --git a/Adventures in Lestoria/assets/config/items/ItemDatabase.txt b/Adventures in Lestoria/assets/config/items/ItemDatabase.txt index 828f40cb..a54a2d35 100644 --- a/Adventures in Lestoria/assets/config/items/ItemDatabase.txt +++ b/Adventures in Lestoria/assets/config/items/ItemDatabase.txt @@ -10,6 +10,7 @@ ItemDatabase Cooldown Time = 5.0 Cast Time = 0.0 SellValue = 8 + UseSound = Consume Item } Minor Health Potion { @@ -21,6 +22,7 @@ ItemDatabase Cast Time = 0.0 SellValue = 16 BuyValue = 23 + UseSound = Consume Potion Crafting { # When this crafting recipe is available. @@ -42,6 +44,7 @@ ItemDatabase Cast Time = 0.0 SellValue = 21 BuyValue = 30 + UseSound = Consume Potion Crafting { # When this crafting recipe is available. @@ -62,6 +65,7 @@ ItemDatabase Cooldown Time = 5.0 Cast Time = 0.0 SellValue = 15 + UseSound = Consume Potion Crafting { # When this crafting recipe is available. @@ -83,6 +87,7 @@ ItemDatabase Cooldown Time = 5.0 Cast Time = 0.0 SellValue = 30 + UseSound = Consume Potion Crafting { # When this crafting recipe is available. @@ -104,6 +109,7 @@ ItemDatabase ItemCategory = Consumables SellValue = 7 BuyValue = 10 + UseSound = Consume Item } Green Slime Remains { diff --git a/Adventures in Lestoria/olcUTIL_DataFile.h b/Adventures in Lestoria/olcUTIL_DataFile.h index ffcd8df8..b58fc9d5 100644 --- a/Adventures in Lestoria/olcUTIL_DataFile.h +++ b/Adventures in Lestoria/olcUTIL_DataFile.h @@ -63,6 +63,7 @@ David Barr, aka javidx9, �OneLoneCoder 2019, 2020, 2021, 2022 #include #include #include "Error.h" +#include "olcPixelGameEngine.h" using namespace std::literals;