Nic0Nic0Nii 10 months ago
commit b32ebb3b63
  1. 26
      Adventures in Lestoria/Audio.cpp
  2. 6
      Adventures in Lestoria/Audio.h
  3. 2
      Adventures in Lestoria/MonsterAttribute.h
  4. 40
      Adventures in Lestoria/SettingsWindow.cpp
  5. 40
      Adventures in Lestoria/Slider.h
  6. 4
      Adventures in Lestoria/SoundEffect.cpp
  7. 4
      Adventures in Lestoria/TODO.txt
  8. 2
      Adventures in Lestoria/Version.h
  9. 5
      Adventures in Lestoria/assets/config/audio/events.txt
  10. 2
      Adventures in Lestoria/assets/config/story/Chapter 1.txt
  11. BIN
      Adventures in Lestoria/assets/sounds/changevolume.ogg
  12. BIN
      x64/Release/Adventures in Lestoria.exe

@ -43,7 +43,9 @@ All rights reserved.
INCLUDE_game INCLUDE_game
INCLUDE_DATA INCLUDE_DATA
float Audio::defaultFadeTime; float Audio::defaultFadeTime=0.f;
float Audio::sfxVol=1.f;
float Audio::bgmVol=1.f;
void Audio::Initialize(){ void Audio::Initialize(){
Engine().SetBackgroundPlay(true); Engine().SetBackgroundPlay(true);
@ -265,7 +267,7 @@ void Audio::Update(){
float channelVol=track.GetVolume(Self().currentAudioEvent,channelListIndex); float channelVol=track.GetVolume(Self().currentAudioEvent,channelListIndex);
Self().prevVolumes.push_back(channelVol); Self().prevVolumes.push_back(channelVol);
Self().targetVolumes.push_back(channelVol); Self().targetVolumes.push_back(channelVol);
Engine().SetVolume(trackID,channelVol); Engine().SetVolume(trackID,channelVol*GetBGMVolume());
Engine().Play(trackID,Self().playParams.loop); Engine().Play(trackID,Self().playParams.loop);
channelListIndex++; channelListIndex++;
} }
@ -277,7 +279,7 @@ void Audio::Update(){
Self().fadeToTargetVolumeTime=std::max(0.f,Self().fadeToTargetVolumeTime-game->GetElapsedTime()); Self().fadeToTargetVolumeTime=std::max(0.f,Self().fadeToTargetVolumeTime-game->GetElapsedTime());
for(int counter=0;float&vol:Self().prevVolumes){ for(int counter=0;float&vol:Self().prevVolumes){
const BGM&currentBgm=Self().bgm[Self().currentBGM]; const BGM&currentBgm=Self().bgm[Self().currentBGM];
Engine().SetVolume(currentBgm.GetChannelIDs()[counter],util::lerp(vol,Self().targetVolumes[counter],1-(Self().fadeToTargetVolumeTime/currentBgm.GetFadeTime()))); Engine().SetVolume(currentBgm.GetChannelIDs()[counter],util::lerp(vol,Self().targetVolumes[counter],1-(Self().fadeToTargetVolumeTime/currentBgm.GetFadeTime()))*GetBGMVolume());
counter++; counter++;
} }
} }
@ -290,3 +292,21 @@ const bool Audio::BGMFullyLoaded(){
const float&Audio::BGM::GetFadeTime()const{ const float&Audio::BGM::GetFadeTime()const{
return fadeTime; return fadeTime;
} }
void Audio::SetBGMVolume(float vol){
bgmVol=vol;
BGM&track=Self().bgm[Self().playParams.sound];
for(int channelListIndex=0;int trackID:track.GetChannelIDs()){
float channelVol=track.GetVolume(Self().currentAudioEvent,channelListIndex);
Engine().SetVolume(trackID,channelVol*GetBGMVolume());
}
}
void Audio::SetSFXVolume(float vol){
sfxVol=vol;
}
float&Audio::GetBGMVolume(){
return bgmVol;
}
float&Audio::GetSFXVolume(){
return sfxVol;
}

@ -67,6 +67,10 @@ public:
static void SetAudioEvent(const Event&eventName); static void SetAudioEvent(const Event&eventName);
static const bool BGMIsPlaying(); static const bool BGMIsPlaying();
static const bool BGMFullyLoaded(); //Fully loaded means when the audio buffer has finished filling up, which means sound is now playing. static const bool BGMFullyLoaded(); //Fully loaded means when the audio buffer has finished filling up, which means sound is now playing.
static void SetBGMVolume(float vol);
static void SetSFXVolume(float vol);
static float&GetBGMVolume();
static float&GetSFXVolume();
private: private:
struct BGMPlayParams{ struct BGMPlayParams{
std::string sound; std::string sound;
@ -79,6 +83,8 @@ private:
private: private:
std::map<Event,VolumeList>eventInfo; std::map<Event,VolumeList>eventInfo;
}; };
static float bgmVol;
static float sfxVol;
class BGM{ class BGM{
public: public:
void Load(); void Load();

@ -93,4 +93,6 @@ enum class Attribute{
BEAR_STOMP_COUNT, BEAR_STOMP_COUNT,
PREVIOUS_PHASE, PREVIOUS_PHASE,
COLLIDED_WITH_PLAYER, //A boolean flag that is set to true when an enemy makes contact with the player. COLLIDED_WITH_PLAYER, //A boolean flag that is set to true when an enemy makes contact with the player.
LAST_BGM_VOLUME,
LAST_SFX_VOLUME,
}; };

@ -44,23 +44,59 @@ All rights reserved.
#include "olcUTIL_DataFile.h" #include "olcUTIL_DataFile.h"
#include "Unlock.h" #include "Unlock.h"
#include "State_OverworldMap.h" #include "State_OverworldMap.h"
#include "MenuLabel.h"
#include "Slider.h"
#include "Checkbox.h"
INCLUDE_DATA INCLUDE_DATA
INCLUDE_game INCLUDE_game
INCLUDE_WINDOW_SIZE INCLUDE_WINDOW_SIZE
using A=Attribute;
void Menu::InitializeSettingsWindow(){ void Menu::InitializeSettingsWindow(){
vf2d windowSize=WINDOW_SIZE-vf2d{28,28}; vf2d windowSize=WINDOW_SIZE-vf2d{28,28};
Menu*settingsWindow=CreateMenu(SETTINGS,CENTERED,windowSize); Menu*settingsWindow=CreateMenu(SETTINGS,CENTERED,windowSize);
settingsWindow->ADD("Unlock All Button",MenuComponent)(geom2d::rect<float>{{4,4},{72,12}},"Unlock All",[](MenuFuncData data){ settingsWindow->ADD("Unlock All Button",MenuComponent)(geom2d::rect<float>{{4,windowSize.y-12},{72,12}},"Unlock All",[](MenuFuncData data){
for(auto&cp:State_OverworldMap::connections){ for(auto&cp:State_OverworldMap::connections){
Unlock::UnlockArea(cp.map); Unlock::UnlockArea(cp.map);
} }
SoundEffect::PlaySFX("Buy Item",SoundEffect::CENTERED); SoundEffect::PlaySFX("Buy Item",SoundEffect::CENTERED);
return true; return true;
})END; })END;
settingsWindow->ADD("Go Back",MenuComponent)(geom2d::rect<float>{windowSize/2-vf2d{36,16},{72,12}},"Go Back",[](MenuFuncData data){
settingsWindow->ADD("Settings Label",MenuLabel)(geom2d::rect<float>{{4,4},vf2d{windowSize.x-8,24}},"Game Settings",2.f,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
settingsWindow->F(A::LAST_BGM_VOLUME)=1.f;
settingsWindow->F(A::LAST_SFX_VOLUME)=1.f;
settingsWindow->ADD("BGM Slider",Slider)(geom2d::rect<float>{vf2d{windowSize.x/2-64,44},{172,16}},"BGM Volume:",Audio::GetBGMVolume(),[](float val){
if(abs(Menu::menus[SETTINGS]->F(A::LAST_BGM_VOLUME)-val)>=0.04f){
SoundEffect::PlaySFX("Change Volume",SoundEffect::CENTERED);
Menu::menus[SETTINGS]->F(A::LAST_BGM_VOLUME)=val;
}
Audio::SetBGMVolume(val);
})END;
settingsWindow->ADD("SFX Slider",Slider)(geom2d::rect<float>{vf2d{windowSize.x/2-64,64},{172,16}},"SFX Volume:",Audio::GetSFXVolume(),[](float val){
if(abs(Menu::menus[SETTINGS]->F(A::LAST_SFX_VOLUME)-val)>=0.04f){
SoundEffect::PlaySFX("Change Volume",SoundEffect::CENTERED);
Menu::menus[SETTINGS]->F(A::LAST_SFX_VOLUME)=val;
}
})END;
settingsWindow->ADD("Terrain Collision Boxes Checkbox",Checkbox)(geom2d::rect<float>{{windowSize.x/2-88.f,84},{16.f,16.f}},[](ToggleFuncData data){
return true;
},true)END;
settingsWindow->ADD("Terrain Collision Boxes Label",MenuLabel)(geom2d::rect<float>{{windowSize.x/2-68.f,84},{windowSize.x/2+54.f,16.f}},"Terrain Collision Boxes",1.f,ComponentAttr::SHADOW)END;
settingsWindow->ADD("Keyboard Play Auto-Aim Checkbox",Checkbox)(geom2d::rect<float>{{windowSize.x/2-88.f,104},{16.f,16.f}},[](ToggleFuncData data){
return true;
},false)END;
settingsWindow->ADD("Keyboard Play Auto-Aim Label",MenuLabel)(geom2d::rect<float>{{windowSize.x/2-68.f,104},{windowSize.x/2+54.f,16.f}},"Keyboard Aim Assist\n (For Keyboard Only Players)",1.f,ComponentAttr::SHADOW)END;
settingsWindow->ADD("Keyboard Bindings Label",MenuComponent)(geom2d::rect<float>{{28,132.f},vf2d{windowSize.x-32,24}},"Keyboard Bindings",MenuType::ENUM_END,DO_NOTHING,vf2d{1.5f,2.f})END;
settingsWindow->ADD("Controller Bindings Label",MenuComponent)(geom2d::rect<float>{{28,160.f},vf2d{windowSize.x-32,24}},"Controller Bindings",MenuType::ENUM_END,DO_NOTHING,vf2d{1.5f,2.f})END;
settingsWindow->ADD("Go Back",MenuComponent)(geom2d::rect<float>{vf2d{windowSize.x/2.f,windowSize.y}-vf2d{36,16},{72,12}},"Go Back",[](MenuFuncData data){
Menu::CloseMenu(); Menu::CloseMenu();
return true; return true;
})END; })END;

@ -47,23 +47,27 @@ INCLUDE_GFX
class Slider:public MenuComponent{ class Slider:public MenuComponent{
bool dragging=false; bool dragging=false;
float&val; //0.f-1.f float&val; //0.f-1.f
float prevVal=0.f;
std::pair<int,int>minMaxDisplayValues; std::pair<int,int>minMaxDisplayValues;
std::function<void(float)>onValChange;
public:
//A slider component with a right-aligned label to the left, and a value display on the right-hand side. //A slider component with a right-aligned label to the left, and a value display on the right-hand side.
//valRef is between 0-1. //valRef is between 0-1.
//minMaxDisplayValues are visual only. //minMaxDisplayValues are visual only.
inline Slider(const geom2d::rect<float>&rect,const std::string&label,float&valRef,const std::pair<int,int>&minMaxDisplayValues={0,100},const ButtonAttr&attributes=ButtonAttr::NONE) inline Slider(const geom2d::rect<float>&rect,const std::string&label,float&valRef,const std::pair<int,int>&minMaxDisplayValues={0,100},const ButtonAttr&attributes=ButtonAttr::NONE)
:MenuComponent(rect,label,DO_NOTHING,attributes),val(valRef),minMaxDisplayValues(minMaxDisplayValues){ :Slider(rect,label,valRef,[](float val){},minMaxDisplayValues,attributes){}
inline Slider(const geom2d::rect<float>&rect,const std::string&label,float&valRef,std::function<void(float)>onValChange,const std::pair<int,int>&minMaxDisplayValues={0,100},const ButtonAttr&attributes=ButtonAttr::NONE)
:MenuComponent(rect,label,DO_NOTHING,attributes),val(valRef),minMaxDisplayValues(minMaxDisplayValues),prevVal(valRef),onValChange(onValChange){
if(minMaxDisplayValues.first>minMaxDisplayValues.second)ERR(std::format("WARNING! The first value provided for component {} is greater than the second! {} > {}",name,minMaxDisplayValues.first,minMaxDisplayValues.second)); if(minMaxDisplayValues.first>minMaxDisplayValues.second)ERR(std::format("WARNING! The first value provided for component {} is greater than the second! {} > {}",name,minMaxDisplayValues.first,minMaxDisplayValues.second));
} }
//Gets the absolute X position of the slider. //Gets the absolute X position of the slider.
float GetSliderX(){ float GetSliderX(){
return rect.pos.x+rect.size.x*val; return rect.pos.x+4+(rect.size.x-8)*val;
} }
float GetSliderVal(float x){ float GetSliderVal(float x){
return (x-rect.pos.x)/rect.size.x; return (x-rect.pos.x+4)/(rect.size.x-8);
} }
int GetValueDisplay(){ int GetValueDisplay(){
@ -81,7 +85,7 @@ class Slider:public MenuComponent{
if(dragging){ if(dragging){
if(Menu::UsingMouseNavigation()){ if(Menu::UsingMouseNavigation()){
val=GetSliderVal(game->GetMouseX()); val=GetSliderVal(game->GetMouseX()-Menu::menus[parentMenu]->pos.x-8);
}else{ }else{
if(game->KEY_LEFT.Held()){ if(game->KEY_LEFT.Held()){
val-=1.f*game->GetElapsedTime(); val-=1.f*game->GetElapsedTime();
@ -91,6 +95,10 @@ class Slider:public MenuComponent{
} }
} }
val=std::clamp(val,0.f,1.f); val=std::clamp(val,0.f,1.f);
if(abs(prevVal-val)>=0.01f){
onValChange(int(val*100)/100.f);
prevVal=val;
}
if(game->KEY_CONFIRM.Released()||game->GetMouse(Mouse::LEFT).bReleased){ if(game->KEY_CONFIRM.Released()||game->GetMouse(Mouse::LEFT).bReleased){
dragging=false; dragging=false;
@ -105,16 +113,24 @@ class Slider:public MenuComponent{
} }
vf2d labelSize=game->GetTextSizeProp(label); vf2d labelSize=game->GetTextSizeProp(label);
window.DrawShadowStringPropDecal({rect.pos.x-2-labelSize.x,rect.pos.y+rect.size.y/2-labelSize.y/2},label); window.DrawShadowStringPropDecal(vf2d{rect.pos.x-8-labelSize.x,rect.pos.y+rect.size.y/2-labelSize.y/2},label);
window.FillRectDecal({rect.pos.x,rect.pos.y+rect.size.y/2-1},{rect.size.x,2}); window.FillRectDecal(vf2d{rect.pos.x+4,rect.pos.y+rect.size.y/2-1}+vf2d{0.f,1.f},{rect.size.x-8,2},BLACK);
window.FillRectDecal(vf2d{rect.pos.x+4,rect.pos.y+rect.size.y/2-1},{rect.size.x-8,2});
window.DrawRotatedDecal({GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{2.f,2.f},backCol); window.DrawRotatedDecal(vf2d{GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{5.f,5.f},BLACK);
window.DrawRotatedDecal(vf2d{GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{4.f,4.f},backCol);
std::string valDisplayText=std::to_string(GetValueDisplay()); vf2d valDisplayTextSize=game->GetTextSize(std::to_string(minMaxDisplayValues.second));
vf2d valDisplayTextSize=game->GetTextSize(valDisplayText);
vf2d valDisplayOutlinePos={rect.pos.x+rect.size.x+2,rect.pos.y}; vf2d valDisplayOutlinePos={rect.pos.x+rect.size.x+2,rect.pos.y};
window.DrawRectDecal(valDisplayOutlinePos,valDisplayTextSize+vf2d{4,4}); Pixel valueBackCol=Menu::themes[Menu::themeSelection].GetButtonCol();
window.DrawShadowStringDecal(valDisplayOutlinePos+vf2d{2,2},valDisplayText); Pixel valueTextCol=WHITE;
if(grayedOut){
valueBackCol=GREY;
valueTextCol=VERY_DARK_GREY;
}
window.FillRectDecal(valDisplayOutlinePos+vf2d{7.f,1.f},valDisplayTextSize+vf2d{4,4},valueBackCol);
window.DrawShadowStringDecal(valDisplayOutlinePos+vf2d{9.f,3.f},std::format("{:03}",GetValueDisplay()),valueTextCol);
} }
}; };

@ -88,7 +88,7 @@ void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){
float pitch=util::random(pitchDiff)+sfx.minPitch; float pitch=util::random(pitchDiff)+sfx.minPitch;
if(pos==CENTERED){ if(pos==CENTERED){
Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),sfx.vol,0.0f,pitch); Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),sfx.vol*Audio::GetSFXVolume(),0.0f,pitch);
}else{ }else{
const float soundActivationRange="Audio.Environmental Audio Activation Range"_F; const float soundActivationRange="Audio.Environmental Audio Activation Range"_F;
@ -97,7 +97,7 @@ void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){
float distRatio=1-distanceFromPlayer/soundActivationRange; //0-1 where 1 is full volume. 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 xDistRatio=(pos.x-game->GetPlayer()->GetX())/soundActivationRange; //0-1 where 1 is full volume.
float vol=distRatio*sfx.vol; float vol=distRatio*sfx.vol*Audio::GetSFXVolume();
float pan=xDistRatio; float pan=xDistRatio;
Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),vol,pan,pitch); Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),vol,pan,pitch);
} }

@ -3,13 +3,15 @@ January 1st
Settings Menu Settings Menu
- Any settings should be saved to the save file! - Any settings should be saved to the save file!
- Volume Controls - Volume Controls
- Play Sound in Background - Play Sound in Background (Sound while Focused)
- Keyboard aim assist (When playing w/keyboard, have the game auto fire for players that don't want to use mouse or cannot) - Keyboard aim assist (When playing w/keyboard, have the game auto fire for players that don't want to use mouse or cannot)
- Terrain Collision Boxes
- Key Configuration - Key Configuration
-Upon pressing a key, check if the key is bound to another option, if so, -Upon pressing a key, check if the key is bound to another option, if so,
remove that bind from the list. Up to two keys may be binded per action. remove that bind from the list. Up to two keys may be binded per action.
-We have to save keybinds to the save file. -We have to save keybinds to the save file.
- XP Bar - XP Bar
- Implement escape menu during gameplay. - Implement escape menu during gameplay.

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 3 #define VERSION_MINOR 3
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 6718 #define VERSION_BUILD 6753
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -17,6 +17,11 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = button_click2.ogg, 40% File[0] = button_click2.ogg, 40%
} }
Change Volume
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = changevolume.ogg, 50%, 60%, 60%
}
Consume Potion Consume Potion
{ {
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)

@ -308,7 +308,7 @@ In the middle of the room is some kind of #F2FF00Pillar#FFFFFF which is the same
{RIGHT You} {RIGHT You}
On Top of that Pillar lies a red-coloured #FFBF00Stone Cube#FFFFFF. On Top of that Pillar lies a red-coloured #FFBF00Stone Cube#FFFFFF.
The Stone Cube seems be emitting light. The Stone Cube seems to be emitting light.
Behind the Cube is a Wall engraved with runes. Behind the Cube is a Wall engraved with runes.

Loading…
Cancel
Save