diff --git a/Adventures in Lestoria/Adventures in Lestoria.tiled-project b/Adventures in Lestoria/Adventures in Lestoria.tiled-project index 4c77688e..8cec3afb 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.tiled-project +++ b/Adventures in Lestoria/Adventures in Lestoria.tiled-project @@ -29,6 +29,24 @@ "object" ] }, + { + "id": 43, + "name": "AudioEvent", + "storageType": "string", + "type": "enum", + "values": [ + "LowHealth", + "TitleScreenLoaded", + "BlacksmithUnlock", + "Chapter2Unlock", + "Chapter3Unlock", + "BossFanfare", + "BossDefeated", + "PreBossPhase", + "Default Volume" + ], + "valuesAsFlags": false + }, { "id": 30, "name": "Backdrop", @@ -335,6 +353,12 @@ "drawFill": true, "id": 19, "members": [ + { + "name": "Audio Event", + "propertyType": "AudioEvent", + "type": "string", + "value": "Default Volume" + }, { "name": "Backdrop", "propertyType": "Backdrop", diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 030a271e..f71ba4fd 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -2714,7 +2714,7 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){ #pragma region Setup Pathfinding (Loading Phase 9) LoadingScreen::AddPhase([&](){ - Audio::SetAudioEvent("Default Volume"); + Audio::SetAudioEvent(GetCurrentMap().GetDefaultAudioEvent()); #ifdef __EMSCRIPTEN__ Audio::muted=false; Audio::UpdateBGMVolume(); diff --git a/Adventures in Lestoria/Audio.cpp b/Adventures in Lestoria/Audio.cpp index 4b432be2..09fa021b 100644 --- a/Adventures in Lestoria/Audio.cpp +++ b/Adventures in Lestoria/Audio.cpp @@ -41,6 +41,7 @@ All rights reserved. #include "util.h" #include "LoadingScreen.h" #include "Menu.h" +#include "SoundEffect.h" INCLUDE_game INCLUDE_DATA @@ -416,8 +417,11 @@ float Audio::GetCalculatedBGMVolume(const float channelVol){ } return channelVol*GetBGMVolume()*GetMuteMult()*pauseMult; } -float Audio::GetCalculatedSFXVolume(const float vol){ - return vol*GetSFXVolume()*GetMuteMult(); +float Audio::GetCalculatedSFXVolume(const SoundEffect&sfx){ + return sfx.TreatAsBPM()?Audio::GetCalculatedBGMVolume(sfx.GetVolume()):sfx.GetVolume()*GetSFXVolume()*GetMuteMult(); +} +float Audio::GetCalculatedSFXVolume(const float sfxVol){ + return sfxVol*GetSFXVolume()*GetMuteMult(); } float Audio::GetMuteMult(){ if(muted)return 0.f; diff --git a/Adventures in Lestoria/Audio.h b/Adventures in Lestoria/Audio.h index 973fde8d..9c25dbc5 100644 --- a/Adventures in Lestoria/Audio.h +++ b/Adventures in Lestoria/Audio.h @@ -49,6 +49,8 @@ using ChannelIDList=std::vector; using Volume=float; using VolumeList=std::vector; +class SoundEffect; + class Audio{ friend class AiL; public: @@ -80,7 +82,8 @@ public: //This will get a prepared BGM loop iteration count which is useful for loading stages. static int GetPrepareBGMLoopIterations(std::string_view sound); static float GetCalculatedBGMVolume(const float channelVol); - static float GetCalculatedSFXVolume(const float vol); + static float GetCalculatedSFXVolume(const SoundEffect&sfx); + static float GetCalculatedSFXVolume(const float sfxVol); //NOTE: This is a more manually invoked function! If you are trying to play a specific sound effect from an event, use the SoundEffect version instead!! This accounts for any additional flags related to volume. private: bool trackLoadStarted=false; bool trackLoadComplete=false; diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index 9b11f790..d475399b 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -1058,6 +1058,15 @@ void Monster::OnDeath(){ exitRing.zone.pos.y=std::clamp(exitRing.zone.pos.y,clampedArena.pos.y-"boss_spawn_ring_radius"_I,clampedArena.pos.y-"boss_spawn_ring_radius"_I+clampedArena.size.y); game->AddZone("EndZone",exitRing); //Create a 144x144 ring around the dead boss. + + Audio::SetAudioEvent("BossFanfare"); + + game->GetPlayer()->AddTimer(PlayerTimerType::FANFARE_WAIT_TIMER,Timer{"Fanfare Wait Timer",1.f,[](){ + SoundEffect::PlaySFX("Fanfare",SoundEffect::CENTERED); + game->GetPlayer()->AddTimer(PlayerTimerType::FANFARE_WAIT_TIMER,Timer{"Fanfare Wait Timer",5.f,[](){ + Audio::SetAudioEvent("BossDefeated"); + }}); + }}); } } } diff --git a/Adventures in Lestoria/PlayerTimerType.h b/Adventures in Lestoria/PlayerTimerType.h index f461917f..51756b5d 100644 --- a/Adventures in Lestoria/PlayerTimerType.h +++ b/Adventures in Lestoria/PlayerTimerType.h @@ -45,4 +45,5 @@ enum class PlayerTimerType{ ADVANCE_SHIELD_TIMER, CAT_FORM_ALREADY_ACTIVE, BLINK_PORTAL_SECOND_CAST, + FANFARE_WAIT_TIMER, }; \ No newline at end of file diff --git a/Adventures in Lestoria/SoundEffect.cpp b/Adventures in Lestoria/SoundEffect.cpp index 34363ecc..b44532fa 100644 --- a/Adventures in Lestoria/SoundEffect.cpp +++ b/Adventures in Lestoria/SoundEffect.cpp @@ -58,8 +58,8 @@ void RepeatingSoundEffect::StopAllSounds(){ playingSoundEffects.clear(); } -SoundEffect::SoundEffect(const std::string_view filename,const float&vol,const float&minPitch,const float&maxPitch,const bool combatSound) - :filename(filename),vol(vol),minPitch(minPitch),maxPitch(maxPitch),combatSound(combatSound){ +SoundEffect::SoundEffect(const std::string_view filename,const float&vol,const float&minPitch,const float&maxPitch,const bool combatSound,const bool treatAsBGM) + :filename(filename),vol(vol),minPitch(minPitch),maxPitch(maxPitch),combatSound(combatSound),treatAsBGM(treatAsBGM){ if(vol<0.f||vol>1.f)ERR(std::format("WARNING! Volume must be between 0.0f ~ 1.0f! Provided value {}",vol)); } @@ -67,16 +67,20 @@ void SoundEffect::Initialize(){ for(auto&[key,size]:DATA["Events"]["SFX"]){ int counter=0; bool combatSound=false; + bool treatAsBGM{false}; if(DATA["Events"]["SFX"][key].HasProperty("CombatSound")){ combatSound=DATA["Events"]["SFX"][key]["CombatSound"].GetBool(); } + if(DATA["Events"]["SFX"][key].HasProperty("Treat as BGM")){ + treatAsBGM=DATA["Events"]["SFX"][key]["Treat as BGM"].GetBool(); + } while(DATA["Events"]["SFX"][key].HasProperty(std::format("File[{}]",counter))){ utils::datafile&data=DATA["Events"]["SFX"][key][std::format("File[{}]",counter)]; float minPitch=0.9f; float maxPitch=1.1f; if(data.GetValueCount()>=3){minPitch=data.GetInt(2)/100.f;} if(data.GetValueCount()>=4){maxPitch=data.GetInt(3)/100.f;} - SOUND_EFFECTS.insert({key,SoundEffect{data.GetString(0),data.GetInt(1)/100.f,minPitch,maxPitch,combatSound}}); + SOUND_EFFECTS.insert({key,SoundEffect{data.GetString(0),data.GetInt(1)/100.f,minPitch,maxPitch,combatSound,treatAsBGM}}); counter++; } auto itr=SOUND_EFFECTS.equal_range(key); @@ -96,7 +100,8 @@ void SoundEffect::PlaySFX(const std::string&eventName,const vf2d&pos){ float pitch=util::random(pitchDiff)+sfx.minPitch; if(pos==CENTERED){ - Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),Audio::GetCalculatedSFXVolume(sfx.vol*Audio::GetSFXVolume()),0.0f,pitch); + float vol{Audio::GetCalculatedSFXVolume(sfx)}; + Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),vol,0.0f,pitch); }else{ const float soundActivationRange="Audio.Environmental Audio Activation Range"_F; @@ -105,7 +110,7 @@ void SoundEffect::PlaySFX(const std::string&eventName,const vf2d&pos){ float distRatio=1-distanceFromPlayer/soundActivationRange; //0-1 where 1 is full volume. float xDistRatio=(pos.x-game->GetPlayer()->GetX())/soundActivationRange; //0-1 where 1 is full volume. - float vol=distRatio*sfx.vol*Audio::GetSFXVolume()*Audio::GetMuteMult(); + float vol=distRatio*Audio::GetCalculatedSFXVolume(sfx); float pan=xDistRatio; Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),vol,pan,pitch); } @@ -142,4 +147,11 @@ SoundEffect&SoundEffect::GetRandomSFXFromFile(const std::string&eventName){ } return (*it).second; +} + +const float&SoundEffect::GetVolume()const{ + return vol; +} +const bool&SoundEffect::TreatAsBPM()const{ + return treatAsBGM; } \ No newline at end of file diff --git a/Adventures in Lestoria/SoundEffect.h b/Adventures in Lestoria/SoundEffect.h index 316d366d..2d1569e3 100644 --- a/Adventures in Lestoria/SoundEffect.h +++ b/Adventures in Lestoria/SoundEffect.h @@ -53,18 +53,21 @@ private: class SoundEffect{ public: - SoundEffect(const std::string_view filename,const float&vol,const float&minPitch=0.9f,const float&maxPitch=1.1f,const bool combatSound=false); + SoundEffect(const std::string_view filename,const float&vol,const float&minPitch=0.9f,const float&maxPitch=1.1f,const bool combatSound=false,const bool treatAsBGM=false); static void PlaySFX(const std::string&eventName,const vf2d&pos); //Sets up a sound to be looped continuously. static size_t PlayLoopingSFX(const std::string&eventName,const vf2d&pos); static void StopLoopingSFX(const int id); static void Initialize(); static const vf2d CENTERED; + const float&GetVolume()const; + const bool&TreatAsBPM()const; private: static SoundEffect&GetRandomSFXFromFile(const std::string&eventName); static std::multimapSOUND_EFFECTS; std::string filename; float vol; + bool treatAsBGM{false}; bool combatSound=false; float minPitch=0.9f; float maxPitch=1.1f; diff --git a/Adventures in Lestoria/TMXParser.h b/Adventures in Lestoria/TMXParser.h index 59988d84..8e648a1d 100644 --- a/Adventures in Lestoria/TMXParser.h +++ b/Adventures in Lestoria/TMXParser.h @@ -144,6 +144,7 @@ private: std::vectornpcs; MapType mapType{}; std::string bgmSongName=""; + std::string audioEvent{"Default Volume"}; std::unordered_mapdevCompletionTrialTime; BackdropName backdrop=""; std::setspawns; @@ -166,6 +167,7 @@ public: const int Spawn_pop(); //Grabs the next spawn controller ID and removes it from the stack. const Renderable*const GetOptimizedMap()const; const std::map>&GetZones()const; + const std::string&GetDefaultAudioEvent()const; std::string FormatLayerData(std::ostream& os, std::vectortiles); std::string FormatSpawnerData(std::ostream& os, std::maptiles); friend std::ostream& operator << (std::ostream& os, Map& rhs); @@ -352,6 +354,9 @@ class TMXParser{ const Renderable*const Map::GetOptimizedMap()const{ return optimizedTile; } + const std::string&Map::GetDefaultAudioEvent()const{ + return audioEvent; + } NPCData::NPCData(){} NPCData::NPCData(XMLTag npcTag){ const std::arraytags={"Function","NPC Name","Roaming Range","Unlock Condition","Spritesheet","x","y"}; @@ -539,6 +544,9 @@ class TMXParser{ parsedMapInfo.backdrop=newTag.data["value"]; } }else + if(newTag.tag=="property"&&newTag.data["name"]=="Audio Event"){ + parsedMapInfo.audioEvent=newTag.data["value"]; + }else if (newTag.tag=="object"&&newTag.data["type"]=="AudioEnvironmentalSound") { parsedMapInfo.environmentalAudioData.emplace_back(); prevAudioData=&parsedMapInfo.environmentalAudioData.back(); diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 1219b117..0fcdee2c 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 11570 +#define VERSION_BUILD 11576 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/Zephy.cpp b/Adventures in Lestoria/Zephy.cpp index 5b7c6032..4b260b36 100644 --- a/Adventures in Lestoria/Zephy.cpp +++ b/Adventures in Lestoria/Zephy.cpp @@ -92,6 +92,8 @@ void Monster::STRATEGY::ZEPHY(Monster&m,float fElapsedTime,std::string strategy) game->SetOverlay(ConfigString("Wind Attack.Wind Overlay Sprite"),ConfigPixel("Wind Attack.Wind Overlay Color")); game->GetOverlay().Disable(); + Audio::SetAudioEvent("Default Volume"); //Begin playing regular music. + m.SetStrategyDeathFunction([&](GameEvent&ev,Monster&m,const std::string&strategy){ game->SetWindSpeed({}); game->GetOverlay().Disable(); diff --git a/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx b/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx index 82abda9c..1657571a 100644 --- a/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx +++ b/Adventures in Lestoria/assets/Campaigns/Boss_2_B.tmx @@ -1,6 +1,7 @@ + diff --git a/Adventures in Lestoria/assets/config/audio/bgm.txt b/Adventures in Lestoria/assets/config/audio/bgm.txt index 90605cd9..dd2a8784 100644 --- a/Adventures in Lestoria/assets/config/audio/bgm.txt +++ b/Adventures in Lestoria/assets/config/audio/bgm.txt @@ -44,6 +44,7 @@ BGM Track Name = Foresty Boss channel[0]=commercial_assets/foresty_boss.ogg + channel[1]=commercial_assets/AiL_forest_postBoss.ogg # Transition time between one phase to the next. Fade Time = 2.0 @@ -52,7 +53,9 @@ BGM Events { - Default Volume = 70% + Default Volume = 70%, 0% + BossFanfare = 0%, 0% + BossDefeated = 0%, 70% } } @@ -151,6 +154,8 @@ BGM Track Name = Mountain Boss channel[0]=commercial_assets/AiL_mountain_boss.ogg + channel[1]=commercial_assets/AiL_mountain_postBoss.ogg + channel[2]=commercial_assets/AiL_mountain_boss_halfTrack.ogg # Transition time between one phase to the next. Fade Time = 2.0 @@ -159,7 +164,10 @@ BGM Events { - Default Volume = 70% + Default Volume = 70%, 0%, 0% + BossFanfare = 0%, 0%, 0% + BossDefeated = 0%, 70%, 0% + PreBossPhase = 0%, 0%, 70% } } } \ No newline at end of file diff --git a/Adventures in Lestoria/assets/config/audio/events.txt b/Adventures in Lestoria/assets/config/audio/events.txt index cb88387e..7af7cd9e 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -5,6 +5,9 @@ Events BlacksmithUnlock = "Blacksmith appears in the camp." Chapter2Unlock = "Chapter 2 is unlocked (beat the demo)" Chapter3Unlock = "Chapter 3 is unlocked (After beating the Stone Golem)" + BossFanfare = "Fanfare is playing, music should be muted." + BossDefeated = "After a boss has been wiped out the event will transition over." + PreBossPhase = "A pre-boss phase to a boss fight." SFX { @@ -164,6 +167,14 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) File[0] = explosion.ogg, 80% } + Fanfare + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = AiL_fanfare.ogg, 100%, 100%, 100% + + # If set to true, then this sound will use the volume controls from the BGM volume setting instead. + Treat as BGM = true + } Footstep { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 2dbe361d..4e9e870a 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/assets/sounds/AiL_fanfare.ogg b/Adventures in Lestoria/assets/sounds/AiL_fanfare.ogg new file mode 100644 index 00000000..87ae7529 Binary files /dev/null and b/Adventures in Lestoria/assets/sounds/AiL_fanfare.ogg differ diff --git a/Adventures in Lestoria/promo/enchant1.png b/Adventures in Lestoria/promo/enchant1.png new file mode 100644 index 00000000..65f91668 Binary files /dev/null and b/Adventures in Lestoria/promo/enchant1.png differ diff --git a/Adventures in Lestoria/promo/enchant2.png b/Adventures in Lestoria/promo/enchant2.png new file mode 100644 index 00000000..c5123c57 Binary files /dev/null and b/Adventures in Lestoria/promo/enchant2.png differ diff --git a/Adventures in Lestoria/promo/newclasses.png b/Adventures in Lestoria/promo/newclasses.png new file mode 100644 index 00000000..1674aaea Binary files /dev/null and b/Adventures in Lestoria/promo/newclasses.png differ diff --git a/Adventures in Lestoria/promo/thief1.png b/Adventures in Lestoria/promo/thief1.png new file mode 100644 index 00000000..ec073998 Binary files /dev/null and b/Adventures in Lestoria/promo/thief1.png differ diff --git a/Adventures in Lestoria/promo/thief2.png b/Adventures in Lestoria/promo/thief2.png new file mode 100644 index 00000000..73f2b0c9 Binary files /dev/null and b/Adventures in Lestoria/promo/thief2.png differ diff --git a/Adventures in Lestoria/promo/trapper1.png b/Adventures in Lestoria/promo/trapper1.png new file mode 100644 index 00000000..39bf3bf5 Binary files /dev/null and b/Adventures in Lestoria/promo/trapper1.png differ diff --git a/Adventures in Lestoria/promo/trapper2.png b/Adventures in Lestoria/promo/trapper2.png new file mode 100644 index 00000000..f5f6b1a8 Binary files /dev/null and b/Adventures in Lestoria/promo/trapper2.png differ diff --git a/Adventures in Lestoria/promo/witch1.png b/Adventures in Lestoria/promo/witch1.png new file mode 100644 index 00000000..686a964f Binary files /dev/null and b/Adventures in Lestoria/promo/witch1.png differ diff --git a/Adventures in Lestoria/promo/witch2.png b/Adventures in Lestoria/promo/witch2.png new file mode 100644 index 00000000..6b2d5c19 Binary files /dev/null and b/Adventures in Lestoria/promo/witch2.png differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 11d6c6c9..08b2493d 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ