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