diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj b/Adventures in Lestoria/Adventures in Lestoria.vcxproj index 96f73d9a..8d832915 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj @@ -379,6 +379,7 @@ + @@ -635,6 +636,10 @@ + + + + diff --git a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters index bdb58ff7..39983308 100644 --- a/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters +++ b/Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters @@ -456,6 +456,9 @@ Header Files\Interface + + Header Files + @@ -797,6 +800,9 @@ Source Files\Interface + + Source Files + diff --git a/Adventures in Lestoria/InputHelper.cpp b/Adventures in Lestoria/InputHelper.cpp index 779e2fbd..65258d42 100644 --- a/Adventures in Lestoria/InputHelper.cpp +++ b/Adventures in Lestoria/InputHelper.cpp @@ -38,6 +38,7 @@ All rights reserved. #include "InputHelper.h" #include "AdventuresInLestoria.h" #include "Menu.h" +#include "MenuComponent.h" INCLUDE_game INCLUDE_GFX @@ -70,8 +71,22 @@ void InputHelper::Draw(){ std::vector>buttonImgs; //Store decals for buttons that actually have images, and strings for buttons that have labels. std::vectorbuttonDescriptions; #pragma region Populate all buttons to display - for(auto&[group,displayName]:inputGroups){ + for(auto&[group,display]:inputGroups){ auto&primaryKey=group.GetPrimaryKey(mode); + + std::string displayName; + + if(std::holds_alternative(display))displayName=std::get(display); + else + if(std::holds_alternative>(display)){ + std::weak_ptrparentComponent; + if(!Menu::stack.back()->GetSelection().expired()){ + parentComponent=Menu::stack.back()->GetSelection().lock()->parentComponent; + } + displayName=std::get>(display)(MenuFuncData{*Menu::stack.back(),game,Menu::stack.back()->GetSelection(),parentComponent}); + } + else ERR("WARNING! display contains a variant alternative that does not exist. THIS SHOULD NOT BE HAPPENING!"); + if(displayName.length()>0&&primaryKey.has_value()){ if(primaryKey.value().HasIcon()){ buttonImgWidth+=primaryKey.value().GetIcon().Sprite()->width+"Interface.InputHelperSpacing"_I; diff --git a/Adventures in Lestoria/InputHelper.h b/Adventures in Lestoria/InputHelper.h index b18b998e..d355fdd6 100644 --- a/Adventures in Lestoria/InputHelper.h +++ b/Adventures in Lestoria/InputHelper.h @@ -41,10 +41,7 @@ All rights reserved. #include #include "Key.h" #include "MenuType.h" - -using InputGroupActionDisplayName=std::string; -using ButtonName=std::string; -using MenuInputGroups=std::map>>>; +#include "MenuDefinitions.h" class InputHelper{ std::mapinputGroups; diff --git a/Adventures in Lestoria/LevelCompleteWindow.cpp b/Adventures in Lestoria/LevelCompleteWindow.cpp index aa6a2e0e..4da30775 100644 --- a/Adventures in Lestoria/LevelCompleteWindow.cpp +++ b/Adventures in Lestoria/LevelCompleteWindow.cpp @@ -43,6 +43,7 @@ All rights reserved. #include "Unlock.h" #include "State_OverworldMap.h" #include "ProgressBar.h" +#include "SoundEffect.h" INCLUDE_game @@ -97,22 +98,56 @@ void Menu::InitializeLevelCompleteWindow(){ } }, { //Button Key - {{game->KEY_SHOULDER,Pressed},{"Scroll",[](MenuType type){}}}, - {{game->KEY_FASTSCROLLDOWN,PressedDAS,InputEngageGroup::NOT_VISIBLE},{"Scroll",[](MenuType type){ - auto selection=Menu::menus[type]->GetSelection(); + {{game->KEY_SHOULDER,Pressed},{[](MenuFuncData data){ + auto monsterLoot=Component(data.menu.GetType(),"Monster Loot Window"); + auto stageLoot=Component(data.menu.GetType(),"Stage Loot Window"); + if(!data.parentComponent.expired()){ + if(data.parentComponent.lock()->GetName()=="Monster Loot Window"&&monsterLoot->GetComponents().size()>0){ + return "Stage Loot"; + }else + if(monsterLoot->GetComponents().size()>0){ + return "Monster Loot"; + } + } + return ""; + },[](MenuType type){}}}, + {{game->KEY_FASTSCROLLUP,Pressed},{"",[](MenuType type){ + auto monsterLoot=Component(type,"Monster Loot Window"); + auto stageLoot=Component(type,"Stage Loot Window"); + auto selection=Menu::stack.back()->GetSelection(); if(!selection.expired()){ - auto parentComponent=DYNAMIC_POINTER_CAST(selection.lock()->parentComponent); - int invWidth=int((parentComponent->rect.size.x-12)/(float(parentComponent->options.size.x)+parentComponent->options.padding)); - parentComponent->IncreaseSelectionIndex(invWidth*3.f); + auto parent=selection.lock()->parentComponent; + if(!parent.expired()){ + if(parent.lock()->GetName()=="Monster Loot Window"&&stageLoot->GetComponents().size()>0){ + Menu::stack.back()->SetSelection(stageLoot->GetComponents()[0]); + SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); + }else + if(monsterLoot->GetComponents().size()>0){ + Menu::stack.back()->SetSelection(monsterLoot->GetComponents()[0]); + SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); + } + } } + return ""; }}}, - {{game->KEY_FASTSCROLLUP,PressedDAS,InputEngageGroup::NOT_VISIBLE},{"Scroll",[](MenuType type){ - auto selection=Menu::menus[type]->GetSelection(); + {{game->KEY_FASTSCROLLDOWN,Pressed},{"",[](MenuType type){ + auto monsterLoot=Component(type,"Monster Loot Window"); + auto stageLoot=Component(type,"Stage Loot Window"); + auto selection=Menu::stack.back()->GetSelection(); if(!selection.expired()){ - auto parentComponent=DYNAMIC_POINTER_CAST(selection.lock()->parentComponent); - int invWidth=int((parentComponent->rect.size.x-12)/(float(parentComponent->options.size.x)+parentComponent->options.padding)); - parentComponent->IncreaseSelectionIndex(invWidth*-3.f); + auto parent=selection.lock()->parentComponent; + if(!parent.expired()){ + if(parent.lock()->GetName()=="Monster Loot Window"&&stageLoot->GetComponents().size()>0){ + Menu::stack.back()->SetSelection(stageLoot->GetComponents()[0]); + SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); + }else + if(monsterLoot->GetComponents().size()>0){ + Menu::stack.back()->SetSelection(monsterLoot->GetComponents()[0]); + SoundEffect::PlaySFX("Button Click",SoundEffect::CENTERED); + } + } } + return ""; }}}, {game->KEY_SCROLL,{"View Items",[](MenuType type){}}}, {game->KEY_START,{"Continue",[](MenuType type){ @@ -154,7 +189,7 @@ void Menu::InitializeLevelCompleteWindow(){ DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window") { //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory. //By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping. - int colIndex=selectedButton.lock()->inventoryIndex; //Negative index, so we have to loop around. + int colIndex=selectedButton.lock()->inventoryIndex%invWidth; //Negative index, so we have to loop around. //Get the base row index of the new inventory. auto stageLootWindow=Component(type,"Stage Loot Window"); if(stageLootWindow->GetComponents().size()>0){ @@ -207,7 +242,7 @@ void Menu::InitializeLevelCompleteWindow(){ DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window") { //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory. //By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping. - int colIndex=selectedButton.lock()->inventoryIndex; + int colIndex=selectedButton.lock()->inventoryIndex%invWidth; //Get the base row index of the new inventory. auto stageLootWindow=Component(type,"Stage Loot Window"); if(stageLootWindow->GetComponents().size()>0){ @@ -278,7 +313,7 @@ void Menu::InitializeLevelCompleteWindow(){ int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \ int newRowIndex=selectedButton.lock()->inventoryIndex+1; \ int newRowBaseIndex = (newRowIndex / invWidth) * invWidth; \ - if(rowBaseIndex!=newRowBaseIndex) + if(rowBaseIndex!=newRowBaseIndex||newRowIndex>=itemsList.size()) #define DefaultBehavior \ newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \ newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \ @@ -338,7 +373,7 @@ void Menu::InitializeLevelCompleteWindow(){ DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window") { //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory. //By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping. - int colIndex=selectedButton.lock()->inventoryIndex; + int colIndex=selectedButton.lock()->inventoryIndex%invWidth; //Get the base row index of the new inventory. auto stageLootWindow=Component(type,"Monster Loot Window"); if(stageLootWindow->GetComponents().size()>0){ @@ -391,7 +426,7 @@ void Menu::InitializeLevelCompleteWindow(){ DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window") { //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory. //By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping. - int colIndex=selectedButton.lock()->inventoryIndex; + int colIndex=selectedButton.lock()->inventoryIndex%invWidth; //Get the base row index of the new inventory. auto stageLootWindow=Component(type,"Monster Loot Window"); if(stageLootWindow->GetComponents().size()>0){ diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index 7f953fc4..39b7cb9f 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -656,10 +656,6 @@ void Menu::AddChapterListener(std::weak_ptrcomponent){ chapterListeners.push_back(component); } - -MenuFuncData::MenuFuncData(Menu&menu,AiL*const game,std::weak_ptrcomponent,std::weak_ptrparentComponent) - :menu(menu),game(game),component(component),parentComponent(parentComponent){} - ToggleFuncData::ToggleFuncData(Menu&menu,AiL*const game,std::weak_ptrcomponent,std::weak_ptrparentComponent,bool checked) :MenuFuncData(menu,game,component,parentComponent),checked(checked){} diff --git a/Adventures in Lestoria/Menu.h b/Adventures in Lestoria/Menu.h index 1acfcfac..9bd5707a 100644 --- a/Adventures in Lestoria/Menu.h +++ b/Adventures in Lestoria/Menu.h @@ -43,6 +43,8 @@ All rights reserved. #include "Attributable.h" #include "olcUTIL_Geometry2D.h" #include "olcPGEX_ViewPort.h" +#include "MenuType.h" +#include "MenuDefinitions.h" #include "InputHelper.h" class AiL; @@ -53,14 +55,6 @@ struct Navigation; class Menu; -struct MenuFuncData{ - Menu&menu; - AiL*const game; - const std::weak_ptr component; - const std::weak_ptr parentComponent={}; - MenuFuncData(Menu&menu,AiL*const game,std::weak_ptr component,std::weak_ptrparentComponent={}); -}; - struct ToggleFuncData:public MenuFuncData{ bool checked; ToggleFuncData(Menu&menu,AiL*const game,std::weak_ptrcomponent,std::weak_ptrparentComponent,bool checked); diff --git a/Adventures in Lestoria/MenuDefinitions.cpp b/Adventures in Lestoria/MenuDefinitions.cpp new file mode 100644 index 00000000..75ad4cfe --- /dev/null +++ b/Adventures in Lestoria/MenuDefinitions.cpp @@ -0,0 +1,42 @@ +#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 © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion + +#include "MenuDefinitions.h" + +MenuFuncData::MenuFuncData(Menu&menu,AiL*const game,std::weak_ptrcomponent,std::weak_ptrparentComponent) + :menu(menu),game(game),component(component),parentComponent(parentComponent){} \ No newline at end of file diff --git a/Adventures in Lestoria/MenuDefinitions.h b/Adventures in Lestoria/MenuDefinitions.h new file mode 100644 index 00000000..2e12eaf1 --- /dev/null +++ b/Adventures in Lestoria/MenuDefinitions.h @@ -0,0 +1,59 @@ +#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 © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once + +#include +#include +#include "Key.h" +#include "MenuType.h" +class Menu; +class AiL; +class MenuComponent; +class ScrollableWindowComponent; + +struct MenuFuncData{ + Menu&menu; + AiL*const game; + const std::weak_ptr component; + const std::weak_ptr parentComponent={}; + MenuFuncData(Menu&menu,AiL*const game,std::weak_ptr component,std::weak_ptrparentComponent={}); +}; + +using InputGroupActionDisplayName=std::variant>; +using ButtonName=std::string; +using MenuInputGroups=std::map>>>; \ No newline at end of file diff --git a/Adventures in Lestoria/State_LevelComplete.cpp b/Adventures in Lestoria/State_LevelComplete.cpp index b5260f64..cea2a6af 100644 --- a/Adventures in Lestoria/State_LevelComplete.cpp +++ b/Adventures in Lestoria/State_LevelComplete.cpp @@ -48,6 +48,10 @@ INCLUDE_MONSTER_LIST INCLUDE_game void State_LevelComplete::OnStateChange(GameState*prevState){ + if(xpGainSound==std::numeric_limits::max()){ + xpGainSound=Audio::LoadAndPlay("xpgain.ogg"_SFX,true); + Audio::Engine().SetVolume(xpGainSound,0.f); + } if(Menu::IsMenuOpen()){ Menu::CloseAllMenus(); } @@ -84,6 +88,7 @@ void State_LevelComplete::OnUserUpdate(AiL*game){ if(accumulatedXP>0){ lastXPChangeTimer-=game->GetElapsedTime(); + Audio::Engine().SetVolume(xpGainSound,0.6f); while(lastXPChangeTimer<=0.f){ int incrementAmt=int(accumulatedXP/(1/"Interface.HUD XP Bar Tick Rate"_F))+1; accumulatedXP-=incrementAmt; @@ -97,6 +102,8 @@ void State_LevelComplete::OnUserUpdate(AiL*game){ } lastXPChangeTimer+="Interface.HUD XP Bar Tick Rate"_F; } + }else{ + Audio::Engine().SetVolume(xpGainSound,0.f); } }; void State_LevelComplete::Draw(AiL*game){ diff --git a/Adventures in Lestoria/State_LevelComplete.h b/Adventures in Lestoria/State_LevelComplete.h index ed5a3c94..5fafaf73 100644 --- a/Adventures in Lestoria/State_LevelComplete.h +++ b/Adventures in Lestoria/State_LevelComplete.h @@ -43,6 +43,7 @@ class State_LevelComplete:public GameState{ float lastXPChangeTimer=0.f; vf2d levelUpTextPos={-100.f,-100.f}; float levelUpTimer=0.f; + size_t xpGainSound=std::numeric_limits::max(); virtual void OnStateChange(GameState*prevState)override final; virtual void OnUserUpdate(AiL*game)override final; virtual void Draw(AiL*game)override final; diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 02413073..b40def4f 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 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 7095 +#define VERSION_BUILD 7112 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/sounds/xpgain.ogg b/Adventures in Lestoria/assets/sounds/xpgain.ogg new file mode 100644 index 00000000..d6be4e15 Binary files /dev/null and b/Adventures in Lestoria/assets/sounds/xpgain.ogg differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 2b88c92c..b0d23bd4 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ