Added Sound effect configuration and implementation.

pull/29/head
sigonasr2 1 year ago
parent 6539bbdb50
commit 0643393b9c
  1. 5
      Adventures in Lestoria/Adventures in Lestoria.vcxproj
  2. 6
      Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
  3. 5
      Adventures in Lestoria/AdventuresInLestoria.cpp
  4. 15
      Adventures in Lestoria/Audio.cpp
  5. 12
      Adventures in Lestoria/Item.cpp
  6. 4
      Adventures in Lestoria/Item.h
  7. 77
      Adventures in Lestoria/SoundEffect.cpp
  8. 55
      Adventures in Lestoria/SoundEffect.h
  9. 2
      Adventures in Lestoria/Version.h
  10. 3
      Adventures in Lestoria/assets/config/audio/bgm.txt
  11. 125
      Adventures in Lestoria/assets/config/audio/events.txt
  12. 6
      Adventures in Lestoria/assets/config/items/ItemDatabase.txt
  13. 1
      Adventures in Lestoria/olcUTIL_DataFile.h

@ -463,6 +463,7 @@
</ClInclude> </ClInclude>
<ClInclude Include="ScrollableWindowComponent.h" /> <ClInclude Include="ScrollableWindowComponent.h" />
<ClInclude Include="InventoryScrollableWindowComponent.h" /> <ClInclude Include="InventoryScrollableWindowComponent.h" />
<ClInclude Include="SoundEffect.h" />
<ClInclude Include="SpawnEncounterLabel.h" /> <ClInclude Include="SpawnEncounterLabel.h" />
<ClInclude Include="State.h" /> <ClInclude Include="State.h" />
<ClInclude Include="State_GameRun.h" /> <ClInclude Include="State_GameRun.h" />
@ -631,6 +632,10 @@
</ClCompile> </ClCompile>
<ClCompile Include="ShootAfar.cpp" /> <ClCompile Include="ShootAfar.cpp" />
<ClCompile Include="SlimeKing.cpp" /> <ClCompile Include="SlimeKing.cpp" />
<ClCompile Include="SoundEffect.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="State_GameRun.cpp" /> <ClCompile Include="State_GameRun.cpp" />
<ClCompile Include="State_LevelComplete.cpp"> <ClCompile Include="State_LevelComplete.cpp">
<SubType> <SubType>

@ -423,6 +423,9 @@
<ClInclude Include="stb_vorbis.h"> <ClInclude Include="stb_vorbis.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="SoundEffect.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Player.cpp"> <ClCompile Include="Player.cpp">
@ -710,6 +713,9 @@
<ClCompile Include="stb_vorbis.cpp"> <ClCompile Include="stb_vorbis.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="SoundEffect.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -69,6 +69,7 @@ All rights reserved.
#include "Merchant.h" #include "Merchant.h"
#include "SaveFile.h" #include "SaveFile.h"
#include "TitleScreen.h" #include "TitleScreen.h"
#include "SoundEffect.h"
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
#include "discord.h" #include "discord.h"
#endif #endif
@ -237,6 +238,7 @@ bool AiL::OnUserCreate(){
Audio::Initialize(); Audio::Initialize();
EnvironmentalAudio::Initialize(); EnvironmentalAudio::Initialize();
SoundEffect::Initialize();
LoadLevel(LEVEL_NAMES["starting_map"_S]); LoadLevel(LEVEL_NAMES["starting_map"_S]);
ChangePlayerClass(WARRIOR); ChangePlayerClass(WARRIOR);
@ -2467,6 +2469,9 @@ bool AiL::UseLoadoutItem(int slot){
if(GetLoadoutItem(slot).lock()->Amt()>0){ if(GetLoadoutItem(slot).lock()->Amt()>0){
Inventory::UseItem(GetLoadoutItem(slot).lock()->ActualName()); Inventory::UseItem(GetLoadoutItem(slot).lock()->ActualName());
GetLoadoutItem(slot).lock()->amt--; GetLoadoutItem(slot).lock()->amt--;
if(GetLoadoutItem(slot).lock()->UseSound().length()>0){
SoundEffect::PlaySFX(GetLoadoutItem(slot).lock()->UseSound());
}
return true; return true;
} }
return false; return false;

@ -48,7 +48,9 @@ void Audio::Initialize(){
Engine().SetBackgroundPlay(true); Engine().SetBackgroundPlay(true);
Self().events.insert("Default Volume"); Self().events.insert("Default Volume");
for(auto&[key,data]:DATA["Events"]){ 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"]){ for(auto&[songFileName,size]:DATA["BGM"]){
auto&data=DATA["BGM"][songFileName]; auto&data=DATA["BGM"][songFileName];
@ -67,14 +69,7 @@ void Audio::Initialize(){
channelCounter++; channelCounter++;
} }
if(!data.HasProperty("Default Volume"))ERR(std::format("WARNING! Track {} does not have a Default Volume parameter!",bgm.GetName())); if(!data["Events"].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;i<data["Default Volume"].GetValueCount();i++){
volumes.push_back(data["Default Volume"].GetInt(i)/100.f);
}
bgm.AddEventVolumes("Default Volume",volumes);
if(data.HasProperty("Fade Time")){ if(data.HasProperty("Fade Time")){
bgm.SetFadeTime(data["Fade Time"].GetReal()); bgm.SetFadeTime(data["Fade Time"].GetReal());
@ -84,7 +79,7 @@ void Audio::Initialize(){
if(data.HasProperty("Events")){ if(data.HasProperty("Events")){
for(auto&[eventName,size]:DATA["Events"]){ for(auto&eventName:Self().events){
auto&eventData=data["Events"][eventName]; auto&eventData=data["Events"][eventName];
if(eventData.GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! {} parameters do not match channel count. {} != {}",eventName,eventData.GetValueCount(),bgm.GetChannelCount())); if(eventData.GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! {} parameters do not match channel count. {} != {}",eventName,eventData.GetValueCount(),bgm.GetChannelCount()));
VolumeList volumes; VolumeList volumes;

@ -110,6 +110,7 @@ void ItemInfo::InitializeItems(){
Stats minStats; Stats minStats;
Stats maxStats; Stats maxStats;
bool useDuringCast=false; bool useDuringCast=false;
EventName useSound;
for(auto&[itemKey,itemValue]:data[key].GetKeys()){ for(auto&[itemKey,itemValue]:data[key].GetKeys()){
std::string keyName=itemKey; std::string keyName=itemKey;
if(keyName=="Description"){ if(keyName=="Description"){
@ -145,6 +146,9 @@ void ItemInfo::InitializeItems(){
}else }else
if(keyName=="SellValue"){ if(keyName=="SellValue"){
sellValue=data[key][keyName].GetInt(); sellValue=data[key][keyName].GetInt();
}else
if(keyName=="UseSound"){
useSound=data[key][keyName].GetString();
}else{ //THis is a custom override modifier for a script. NO-OP }else{ //THis is a custom override modifier for a script. NO-OP
} }
} }
@ -230,6 +234,7 @@ void ItemInfo::InitializeItems(){
it.buyValue=buyValue; it.buyValue=buyValue;
it.sellValue=sellValue; it.sellValue=sellValue;
it.useDuringCast=useDuringCast; it.useDuringCast=useDuringCast;
it.useSound=useSound;
if(slot.size()>0){ if(slot.size()>0){
for(std::string&s:slot){ for(std::string&s:slot){
if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!"); if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!");
@ -1097,4 +1102,11 @@ Stats ItemInfo::RandomizeStats(){
const bool Item::HasRandomizedStats()const{ const bool Item::HasRandomizedStats()const{
return randomizedStats.size()>0; return randomizedStats.size()>0;
}
const EventName&ItemInfo::UseSound()const{
return useSound;
}
const EventName&Item::UseSound()const{
return it->UseSound();
} }

@ -54,6 +54,7 @@ class ItemProps;
using IT=std::string; using IT=std::string;
using ITCategory=std::string; using ITCategory=std::string;
using EventName=std::string;
using ItemScript=std::function<bool(AiL*,ItemProps)>; using ItemScript=std::function<bool(AiL*,ItemProps)>;
@ -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. //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 DisplayName()const;
const std::string Description(CompactText compact=COMPACT)const; const std::string Description(CompactText compact=COMPACT)const;
const EventName&UseSound()const;
const ITCategory Category()const; const ITCategory Category()const;
const EquipSlot GetEquipSlot()const; const EquipSlot GetEquipSlot()const;
const::Decal*const Decal()const; const::Decal*const Decal()const;
@ -286,6 +288,7 @@ class ItemInfo{
EquipSlot slot; EquipSlot slot;
EnhancementInfo enhancement; EnhancementInfo enhancement;
::Decal*img; ::Decal*img;
EventName useSound="";
std::string set=""; std::string set="";
//Returns true if the item can be used, false otherwise //Returns true if the item can be used, false otherwise
std::string useFunc=""; std::string useFunc="";
@ -313,6 +316,7 @@ public:
/* /*
For the useFunc, return true if the item can be used, false otherwise. For the useFunc, return true if the item can be used, false otherwise.
*/ */
const EventName&UseSound()const;
const ItemScript&OnUseAction()const; const ItemScript&OnUseAction()const;
const Stats GetStats(int enhancementLevel)const; const Stats GetStats(int enhancementLevel)const;
const float CastTime()const; const float CastTime()const;

@ -0,0 +1,77 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
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::multimap<EventName,SoundEffect>SoundEffect::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);
}

@ -0,0 +1,55 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
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 <string>
#include <map>
#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::multimap<EventName,SoundEffect>SOUND_EFFECTS;
std::string filename;
float vol;
};

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 5466 #define VERSION_BUILD 5476
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -18,13 +18,12 @@ BGM
channel[8]=foresty1_1_strings.ogg channel[8]=foresty1_1_strings.ogg
channel[9]=foresty1_1_xtra perc.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. # Transition time between one phase to the next.
Fade Time = 2.0 Fade Time = 2.0
Events Events
{ {
Default Volume = 70%,70%,70%,70%,70%,70%,70%,70%,70%,70%
LowHealth = 100%,100%,100%,20%,20%,20%,100%,100%,20%,100% LowHealth = 100%,100%,100%,20%,20%,20%,100%,100%,20%,100%
InCombat = 100%,100%,100%,100%,100%,100%,100%,100%,100%,100% InCombat = 100%,100%,100%,100%,100%,100%,100%,100%,100%,100%
Underwater = 10%,10%,10%,60%,80%,80%,10%,10%,70%,10% Underwater = 10%,10%,10%,60%,80%,80%,10%,10%,70%,10%

@ -8,158 +8,195 @@ Events
{ {
Consume Potion Consume Potion
{ {
File[0] = consume_potion.ogg # Specify file names, followed by volume %
File[0] = consume_potion.ogg, 70%
} }
Consume Item Consume Item
{ {
File[0] = consume_item.ogg # Specify file names, followed by volume %
File[0] = consume_item.ogg, 60%
} }
Equip Armor Equip Armor
{ {
File[0] = equip.ogg # Specify file names, followed by volume %
File[1] = equip2.ogg File[0] = equip.ogg, 100%
File[1] = equip2.ogg, 100%
} }
Equip Accessory Equip Accessory
{ {
File[0] = equip_ring.ogg # Specify file names, followed by volume %
File[0] = equip_ring.ogg, 100%
} }
Footstep Footstep
{ {
File[0] = footsteps.ogg # Specify file names, followed by volume %
File[0] = footsteps.ogg, 100%
} }
Footstep - Wet Footstep - Wet
{ {
File[0] = footsteps_wet.ogg # Specify file names, followed by volume %
File[0] = footsteps_wet.ogg, 100%
} }
Buy Item Buy Item
{ {
File[0] = item_buy.ogg # Specify file names, followed by volume %
File[0] = item_buy.ogg, 100%
} }
Sell Item Sell Item
{ {
File[0] = item_sell.ogg # Specify file names, followed by volume %
File[0] = item_sell.ogg, 100%
} }
Craft Item Craft Item
{ {
File[0] = item_craft.ogg # Specify file names, followed by volume %
File[0] = item_craft.ogg, 100%
} }
Enhance Item Enhance Item
{ {
File[0] = item_enhance.ogg # Specify file names, followed by volume %
File[0] = item_enhance.ogg, 100%
} }
Monster Hurt Monster Hurt
{ {
File[0] = monster_hurt.ogg # Specify file names, followed by volume %
File[0] = monster_hurt.ogg, 100%
} }
Ranger Auto Attack Ranger Auto Attack
{ {
File[0] = ranger_auto1.ogg # Specify file names, followed by volume %
File[1] = ranger_auto2.ogg File[0] = ranger_auto1.ogg, 100%
File[1] = ranger_auto2.ogg, 100%
} }
Ranger Backstep Ranger Backstep
{ {
File[0] = ranger_backstep.ogg # Specify file names, followed by volume %
File[0] = ranger_backstep.ogg, 100%
} }
Ranger Multishot Ranger Multishot
{ {
File[0] = ranger_multishot.ogg # Specify file names, followed by volume %
File[0] = ranger_multishot.ogg, 100%
} }
Ranger Rapid Fire 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 Ranger Charged Shot
{ {
File[0] = ranger_charged_shot.ogg # Specify file names, followed by volume %
File[0] = ranger_charged_shot.ogg, 100%
} }
Ranger Multishot Ranger Multishot
{ {
File[0] = ranger_multishot.ogg # Specify file names, followed by volume %
File[0] = ranger_multishot.ogg, 100%
} }
Slime Dead Slime Dead
{ {
File[0] = slime_dead.ogg # Specify file names, followed by volume %
File[0] = slime_dead.ogg, 100%
} }
Monster Dead Monster Dead
{ {
File[0] = slime_dead2.ogg # Specify file names, followed by volume %
File[0] = slime_dead2.ogg, 100%
} }
Slime King Land 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 Slime King Shoot
{ {
File[0] = slime_king_shoot.ogg # Specify file names, followed by volume %
File[0] = slime_king_shoot.ogg, 100%
} }
Slime Shoot Slime Shoot
{ {
File[0] = slime_shoot.ogg # Specify file names, followed by volume %
File[1] = slime_shoot2.ogg File[0] = slime_shoot.ogg, 100%
File[1] = slime_shoot2.ogg, 100%
} }
Slime Walk Slime Walk
{ {
File[0] = slime_walk.ogg # Specify file names, followed by volume %
File[1] = slime_walk2.ogg File[0] = slime_walk.ogg, 100%
File[2] = slime_walk3.ogg File[1] = slime_walk2.ogg, 100%
File[2] = slime_walk3.ogg, 100%
} }
Spell Cast Spell Cast
{ {
File[0] = spell_cast.ogg # Specify file names, followed by volume %
File[0] = spell_cast.ogg, 100%
} }
Warrior Auto Attack Warrior Auto Attack
{ {
File[0] = warrior_auto1.ogg # Specify file names, followed by volume %
File[0] = warrior_auto1.ogg, 100%
} }
Warrior Battlecry Warrior Battlecry
{ {
File[0] = warrior_battlecry.ogg # Specify file names, followed by volume %
File[0] = warrior_battlecry.ogg, 100%
} }
Warrior Block Hit Warrior Block Hit
{ {
File[0] = warrior_blockhit1.ogg # Specify file names, followed by volume %
File[1] = warrior_blockhit2.ogg File[0] = warrior_blockhit1.ogg, 100%
File[1] = warrior_blockhit2.ogg, 100%
} }
Warrior Ground Slam Warrior Ground Slam
{ {
File[0] = warrior_groundslam.ogg # Specify file names, followed by volume %
File[0] = warrior_groundslam.ogg, 100%
} }
Warrior Sonic Slash Warrior Sonic Slash
{ {
File[0] = warrior_sonicslash.ogg # Specify file names, followed by volume %
File[0] = warrior_sonicslash.ogg, 100%
} }
Wizard Auto Attack Wizard Auto Attack
{ {
File[0] = wizard_auto1.ogg # Specify file names, followed by volume %
File[1] = wizard_auto2.ogg File[0] = wizard_auto1.ogg, 100%
File[1] = wizard_auto2.ogg, 100%
} }
Wizard Fire Bolt Wizard Fire Bolt
{ {
File[0] = wizard_firebolt.ogg # Specify file names, followed by volume %
File[0] = wizard_firebolt.ogg, 100%
} }
Wizard Fire Bolt Hit 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 Wizard Lightning Bolt
{ {
File[0] = wizard_lightningbolt.ogg # Specify file names, followed by volume %
File[0] = wizard_lightningbolt.ogg, 100%
} }
Wizard Lightning Bolt Hit 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 Wizard Meteor
{ {
File[0] = wizard_meteor.ogg # Specify file names, followed by volume %
File[0] = wizard_meteor.ogg, 100%
} }
Wizard Meteor Flames Wizard Meteor Flames
{ {
File[0] = wizard_meteor_lingering.ogg # Specify file names, followed by volume %
File[0] = wizard_meteor_lingering.ogg, 100%
} }
Wizard Teleport Wizard Teleport
{ {
File[0] = wizard_teleport.ogg # Specify file names, followed by volume %
File[0] = wizard_teleport.ogg, 100%
} }
} }
} }

@ -10,6 +10,7 @@ ItemDatabase
Cooldown Time = 5.0 Cooldown Time = 5.0
Cast Time = 0.0 Cast Time = 0.0
SellValue = 8 SellValue = 8
UseSound = Consume Item
} }
Minor Health Potion Minor Health Potion
{ {
@ -21,6 +22,7 @@ ItemDatabase
Cast Time = 0.0 Cast Time = 0.0
SellValue = 16 SellValue = 16
BuyValue = 23 BuyValue = 23
UseSound = Consume Potion
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
@ -42,6 +44,7 @@ ItemDatabase
Cast Time = 0.0 Cast Time = 0.0
SellValue = 21 SellValue = 21
BuyValue = 30 BuyValue = 30
UseSound = Consume Potion
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
@ -62,6 +65,7 @@ ItemDatabase
Cooldown Time = 5.0 Cooldown Time = 5.0
Cast Time = 0.0 Cast Time = 0.0
SellValue = 15 SellValue = 15
UseSound = Consume Potion
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
@ -83,6 +87,7 @@ ItemDatabase
Cooldown Time = 5.0 Cooldown Time = 5.0
Cast Time = 0.0 Cast Time = 0.0
SellValue = 30 SellValue = 30
UseSound = Consume Potion
Crafting Crafting
{ {
# When this crafting recipe is available. # When this crafting recipe is available.
@ -104,6 +109,7 @@ ItemDatabase
ItemCategory = Consumables ItemCategory = Consumables
SellValue = 7 SellValue = 7
BuyValue = 10 BuyValue = 10
UseSound = Consume Item
} }
Green Slime Remains Green Slime Remains
{ {

@ -63,6 +63,7 @@ David Barr, aka javidx9, <EFBFBD>OneLoneCoder 2019, 2020, 2021, 2022
#include <sstream> #include <sstream>
#include <numeric> #include <numeric>
#include "Error.h" #include "Error.h"
#include "olcPixelGameEngine.h"
using namespace std::literals; using namespace std::literals;

Loading…
Cancel
Save