diff --git a/Adventures in Lestoria Tests/ItemTests.cpp b/Adventures in Lestoria Tests/ItemTests.cpp index f841032b..e78603db 100644 --- a/Adventures in Lestoria Tests/ItemTests.cpp +++ b/Adventures in Lestoria Tests/ItemTests.cpp @@ -251,15 +251,21 @@ namespace ItemTests std::weak_ptrslimeKingRing{Inventory::AddItem("Ring of the Slime King"s)}; Assert::IsFalse(slimeKingRing.lock()->HasEnchant()); for(int i:std::ranges::iota_view(0,1000)){ - slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant()); + std::string previousEnchantName{}; + if(slimeKingRing.lock()->HasEnchant())previousEnchantName=slimeKingRing.lock()->GetEnchant().value().Name(); + slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant(previousEnchantName)); Assert::IsTrue(slimeKingRing.lock()->HasEnchant()); + Assert::AreNotEqual(previousEnchantName,slimeKingRing.lock()->GetEnchant().value().Name(),L"The previous enchant should never be the same as the new enchant attempt."); if(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().has_value())Assert::AreEqual(int(player->GetClass()),int(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().value())); //Validate enchant is only for this class if it's a class-based ability. } testGame->ChangePlayerClass(WIZARD); player=testGame->GetPlayer(); //The player pointer has been reassigned... for(int i:std::ranges::iota_view(0,1000)){ - slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant()); + std::string previousEnchantName{}; + if(slimeKingRing.lock()->HasEnchant())previousEnchantName=slimeKingRing.lock()->GetEnchant().value().Name(); + slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant(previousEnchantName)); Assert::IsTrue(slimeKingRing.lock()->HasEnchant()); + Assert::AreNotEqual(previousEnchantName,slimeKingRing.lock()->GetEnchant().value().Name(),L"The previous enchant should never be the same as the new enchant attempt."); if(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().has_value())Assert::AreEqual(int(player->GetClass()),int(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().value())); //Validate enchant is only for this class if it's a class-based ability. } } diff --git a/Adventures in Lestoria/ArtificerDisassembleWindow.cpp b/Adventures in Lestoria/ArtificerDisassembleWindow.cpp index 3442c2cb..44bfd88d 100644 --- a/Adventures in Lestoria/ArtificerDisassembleWindow.cpp +++ b/Adventures in Lestoria/ArtificerDisassembleWindow.cpp @@ -109,7 +109,7 @@ void Menu::InitializeArtificerDisassembleWindow(){ EnableDisassemblyDisplay(); RowItemDisplay&item{*DYNAMIC_POINTER_CAST(data.component)}; Component(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock()); - Component(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal()); + Component(data.menu.type,"Disassembly Result")->SetIcon(item.GetItem().lock()->Icon().Decal()); Component(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName()); Component(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName()))); return true; @@ -119,7 +119,7 @@ void Menu::InitializeArtificerDisassembleWindow(){ if(childComponent){ RowItemDisplay&item{childComponent.value().get()}; Component(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock()); - Component(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal()); + Component(data.menu.type,"Disassembly Result")->SetIcon(item.GetItem().lock()->Icon().Decal()); Component(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName()); Component(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName()))); EnableDisassemblyDisplay(); @@ -136,6 +136,8 @@ void Menu::InitializeArtificerDisassembleWindow(){ Menu::AddInventoryListener(inventoryDisplay,"Accessories"); + ResetDisassemblyDisplay(); + artificerDisassembleWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open returnData=""; diff --git a/Adventures in Lestoria/ArtificerEnchantConfirmWindow.cpp b/Adventures in Lestoria/ArtificerEnchantConfirmWindow.cpp index 8b51258d..7181d53f 100644 --- a/Adventures in Lestoria/ArtificerEnchantConfirmWindow.cpp +++ b/Adventures in Lestoria/ArtificerEnchantConfirmWindow.cpp @@ -40,6 +40,7 @@ All rights reserved. #include "AdventuresInLestoria.h" #include "MenuIconButton.h" #include "MenuItemLabel.h" +#include "SoundEffect.h" INCLUDE_game @@ -68,12 +69,32 @@ void Menu::InitializeArtificerEnchantConfirmWindow(){ const float takeOldTextWidth{float(game->GetTextSize("Take Old").x)*2.f}; auto takeOldButton{artificerEnchantConfirmWindow->ADD("Take Old Button",MenuComponent)(geom2d::rect{{artificerEnchantConfirmWindow->size.x/4.f-takeOldTextWidth/2.f,138.f},{takeOldTextWidth-8.f,20.f}},"Take Old",[](MenuFuncData data){ onClick: + const std::string&oldEnchantName{Menu::menus[ARTIFICER_ENCHANT]->S(A::ENCHANT_TYPE)}; + std::weak_ptrnewItem{std::get>(Component(data.menu.GetType(),"New Item Description")->GetItem())}; //NOTE: We're making an assumption here that the new item description holds a weak pointer. This should be true because the only way to get here was to set it up through clicking the Enchant button in Artificer Enchant Window. + newItem.lock()->_EnchantItem(oldEnchantName); + Component(ARTIFICER_ENCHANT,"Fragment Enchant Button")->SetGrayedOut(!newItem.lock()->CanBeEnchanted()); + const std::string_view fragmentName{newItem.lock()->FragmentName()}; + const Pixel fragmentItemDisplayCol{Inventory::GetItemCount(fragmentName)>="Fragment Enchant Cost"_i[0]?WHITE:RED}; + const Pixel moneyCostDisplayCol{game->GetPlayer()->GetMoney()>="Fragment Enchant Cost"_i[1]?WHITE:RED}; + Component(ARTIFICER_ENCHANT,"Fragment Label")->SetLabel(std::format("{}{} x{} ({})",fragmentItemDisplayCol.toHTMLColorCode(),fragmentName,"Fragment Enchant Cost"_i[0],Inventory::GetItemCount(fragmentName))); + Component(ARTIFICER_ENCHANT,"Fragment Money Cost Label")->SetLabel(std::format("{}{} gold",moneyCostDisplayCol.toHTMLColorCode(),"Fragment Enchant Cost"_i[1])); + SoundEffect::PlaySFX("Take Enchant",SoundEffect::CENTERED); + Menu::CloseMenu(); return true; },vf2d{2.f,2.f})END}; const float takeNewTextWidth{float(game->GetTextSize("Take New").x)*2.f}; auto takeNewButton{artificerEnchantConfirmWindow->ADD("Take New Button",MenuComponent)(geom2d::rect{vf2d{artificerEnchantConfirmWindow->size.x/2.f+8.f+artificerEnchantConfirmWindow->size.x/4.f-takeNewTextWidth/2.f,138.f},{takeNewTextWidth-8.f,20.f}},"Take New",[](MenuFuncData data){ onClick: + std::weak_ptrnewItem{std::get>(Component(data.menu.GetType(),"New Item Description")->GetItem())}; + Component(ARTIFICER_ENCHANT,"Fragment Enchant Button")->SetGrayedOut(!newItem.lock()->CanBeEnchanted()); + const std::string_view fragmentName{newItem.lock()->FragmentName()}; + const Pixel fragmentItemDisplayCol{Inventory::GetItemCount(fragmentName)>="Fragment Enchant Cost"_i[0]?WHITE:RED}; + const Pixel moneyCostDisplayCol{game->GetPlayer()->GetMoney()>="Fragment Enchant Cost"_i[1]?WHITE:RED}; + Component(ARTIFICER_ENCHANT,"Fragment Label")->SetLabel(std::format("{}{} x{} ({})",fragmentItemDisplayCol.toHTMLColorCode(),fragmentName,"Fragment Enchant Cost"_i[0],Inventory::GetItemCount(fragmentName))); + Component(ARTIFICER_ENCHANT,"Fragment Money Cost Label")->SetLabel(std::format("{}{} gold",moneyCostDisplayCol.toHTMLColorCode(),"Fragment Enchant Cost"_i[1])); + SoundEffect::PlaySFX("Take Enchant",SoundEffect::CENTERED); + Menu::CloseMenu(); return true; },vf2d{2.f,2.f})END}; diff --git a/Adventures in Lestoria/ArtificerRefineWindow.cpp b/Adventures in Lestoria/ArtificerRefineWindow.cpp index 53c4fd7f..2674a820 100644 --- a/Adventures in Lestoria/ArtificerRefineWindow.cpp +++ b/Adventures in Lestoria/ArtificerRefineWindow.cpp @@ -157,7 +157,12 @@ void Menu::InitializeArtificerRefineWindow(){ artificerRefineWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open - returnData=""; + auto&items{Component(type,"Accessory List")->GetComponents()}; + if(items.size()>0){ + returnData=items[0]; + }else{ + returnData="Back"; + } }, { //Button Key {game->KEY_SCROLL,{"Navigate",[](MenuType type){}}}, @@ -165,12 +170,51 @@ void Menu::InitializeArtificerRefineWindow(){ Menu::CloseMenu(); }}}, {game->KEY_CONFIRM,{"Select",[](MenuType type){}}}, + {{game->KEY_SHOULDER2,Pressed},{"Scroll Up/Down",[](MenuType type){}}}, + {{game->KEY_SHOULDER,Pressed},{"Scroll Up/Down",[](MenuType type){}}}, + {{game->KEY_FASTSCROLLUP,PressedDAS},{"Scroll",[](MenuType type){ + Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->DecreaseSelectionIndex(3.f); + }}}, + {{game->KEY_FASTSCROLLDOWN,PressedDAS},{"Scroll",[](MenuType type){ + Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->IncreaseSelectionIndex(3.f); + }}}, } ,{ //Button Navigation Rules - {"Sample Button",{ - .up="", - .down="", - .left="", - .right="",}}, - }); + {"Accessory List",{ + .up=[&](MenuType type,Data&returnData){ + Menu::ScrollUp(type,"Accessory List",returnData,"Back"); + }, + .down=[&](MenuType type,Data&returnData){ + Menu::ScrollDown(type,"Accessory List",returnData,"Back"); + }, + .left="Back", + .right=[&](MenuType type,Data&returnData){ + Menu::menus[type]->GetSelection().lock()->Click(); + returnData="Fragment Refine Button"; + },}}, + {"Back",{ + .up=[&](MenuType type,Data&returnData){ + if(Component(type,"Accessory List")->GetSelectedChild())returnData=Component(type,"Accessory List")->GetSelectedChild().value().get().GetName(); + else returnData=Component(type,"Accessory List")->GetComponents().back().lock()->GetName(); + }, + .down=[&](MenuType type,Data&returnData){ + if(Component(type,"Accessory List")->GetSelectedChild())returnData=Component(type,"Accessory List")->GetSelectedChild().value().get().GetName(); + else returnData=Component(type,"Accessory List")->GetComponents().front().lock()->GetName(); + }, + .left="Fragment Refine Button", + .right="Fragment Refine Button",}}, + {"Fragment Refine Button",{ + .up=[&](MenuType type,Data&returnData){ + returnData=Component(type,"Accessory List")->GetComponents().back().lock()->GetName(); + }, + .down=[&](MenuType type,Data&returnData){ + returnData=Component(type,"Accessory List")->GetComponents().front().lock()->GetName(); + }, + .left=[&](MenuType type,Data&returnData){ + if(Component(type,"Accessory List")->GetSelectedChild())returnData=Component(type,"Accessory List")->GetSelectedChild().value().get().GetName(); + else returnData="Back"; + }, + .right="Back",}}, + } + ); } \ No newline at end of file diff --git a/Adventures in Lestoria/ArtificerWindow.cpp b/Adventures in Lestoria/ArtificerWindow.cpp index aef63c45..a7c3c6e1 100644 --- a/Adventures in Lestoria/ArtificerWindow.cpp +++ b/Adventures in Lestoria/ArtificerWindow.cpp @@ -76,7 +76,7 @@ void Menu::InitializeArtificerWindow(){ artificerWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open - returnData="Refine Button"; + returnData="Disassemble Button"; }, { //Button Key {game->KEY_SCROLL,{"Navigate",[](MenuType type){}}}, @@ -86,14 +86,14 @@ void Menu::InitializeArtificerWindow(){ {game->KEY_CONFIRM,{"Select",[](MenuType type){}}}, } ,{ //Button Navigation Rules - {"Refine Button",{ - .up="Leave Button", - .down="Disassemble Button",}}, {"Disassemble Button",{ - .up="Refine Button", + .up="Leave Button", + .down="Refine Button",}}, + {"Refine Button",{ + .up="Disassemble Button", .down="Enchant Button",}}, {"Enchant Button",{ - .up="Disassemble Button", + .up="Refine Button", .down="Help Button",}}, {"Help Button",{ .up="Enchant Button", diff --git a/Adventures in Lestoria/CharacterMenuWindow.cpp b/Adventures in Lestoria/CharacterMenuWindow.cpp index 47d37be2..87fa124e 100644 --- a/Adventures in Lestoria/CharacterMenuWindow.cpp +++ b/Adventures in Lestoria/CharacterMenuWindow.cpp @@ -476,28 +476,10 @@ void Menu::InitializeCharacterMenuWindow(){ ,{ //Button Navigation Rules {"Equip List",{ .up=[](MenuType type,Data&returnData){ - if(!Menu::menus[type]->GetSelection().expired()){ - auto selection=Menu::menus[type]->GetSelection().lock(); - size_t index=Component(type,"Equip List")->GetComponentIndex(selection); - index--; - if(index>=Component(type,"Equip List")->GetComponents().size()){ - returnData="Equip Selection Select Button"; - }else{ - returnData=Component(type,"Equip List")->GetComponents()[index]; - } - } + Menu::ScrollUp(type,"Equip List",returnData,"Equip Selection Select Button"); }, .down=[](MenuType type,Data&returnData){ - if(!Menu::menus[type]->GetSelection().expired()){ - auto selection=Menu::menus[type]->GetSelection().lock(); - size_t index=Component(type,"Equip List")->GetComponentIndex(selection); - index++; - if(index>=Component(type,"Equip List")->GetComponents().size()){ - returnData="Equip Selection Select Button"; - }else{ - returnData=Component(type,"Equip List")->GetComponents()[index]; - } - } + Menu::ScrollDown(type,"Equip List",returnData,"Equip Selection Select Button"); }, .left=[](MenuType type,Data&returnData){ auto equipList=Component(type,"Equip List")->GetComponents(); diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp index bc4c2640..fb6a638e 100644 --- a/Adventures in Lestoria/Item.cpp +++ b/Adventures in Lestoria/Item.cpp @@ -1530,7 +1530,9 @@ const std::optional&Item::FragmentIcon()const{ const ItemEnchantInfo Item::ApplyRandomEnchant(){ if(!CanBeEnchanted())ERR("WARNING! Trying to enchant an item that cannot be enchanted! Make sure you are checking with CanBeEnchanted() before calling this function!"); - EnchantName randomEnchantName{ItemEnchant::RollRandomEnchant()}; + std::string currentEnchantName{""}; + if(HasEnchant())currentEnchantName=GetEnchant().value().Name(); + EnchantName randomEnchantName{ItemEnchant::RollRandomEnchant(currentEnchantName)}; _EnchantItem(randomEnchantName); Inventory::RemoveItem(FragmentName(),"Fragment Enchant Cost"_i[0]); game->GetPlayer()->RemoveMoney("Fragment Enchant Cost"_i[1]); diff --git a/Adventures in Lestoria/ItemEnchant.cpp b/Adventures in Lestoria/ItemEnchant.cpp index a26ee179..a56c9528 100644 --- a/Adventures in Lestoria/ItemEnchant.cpp +++ b/Adventures in Lestoria/ItemEnchant.cpp @@ -246,7 +246,7 @@ const std::vectorItemEnchant::GetAvailableEnchants(){ return filteredEnchants; } -const std::string ItemEnchant::RollRandomEnchant(){ +const std::string ItemEnchant::RollRandomEnchant(const std::string_view previousEnchantName){ const std::vectorfilteredEnchants{GetAvailableEnchants()}; int randomRoll{int(util::random_range(0,100))}; @@ -256,11 +256,11 @@ const std::string ItemEnchant::RollRandomEnchant(){ std::vectorremainingAvailableEnchants; if(randomRoll>=generalEnchantRange.first&&randomRoll=classEnchantRange.first&&randomRoll=uniqueEnchantRange.first&&randomRollENCHANT_CATEGORIES; }; +class Item; + class ItemEnchant{ public: ItemEnchant(const std::string_view enchantName); @@ -109,7 +111,7 @@ public: const std::optional&AbilitySlot()const; const static std::vectorGetAvailableEnchants(); //Rolls a class-appropriate random enchant. - const static std::string RollRandomEnchant(); + const static std::string RollRandomEnchant(const std::string_view previousEnchantName); void SetAttribute(const std::string_view attr,const float val); const float&GetAttribute(const std::string_view attr)const; std::map::const_iterator begin()const; diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index dfbfab7f..92bb033c 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -418,6 +418,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(std::holds_alternative(nav.up)){ Data returnData; std::get(nav.up)(type,returnData); + if(!std::holds_alternative(returnData)&&!std::holds_alternative>(returnData))ERR(std::format("WARNING! No valid return type set for up button navigation in menu {}",int(type))); SetSelection(returnData); } } @@ -429,6 +430,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(std::holds_alternative(nav.down)){ Data returnData; std::get(nav.down)(type,returnData); + if(!std::holds_alternative(returnData)&&!std::holds_alternative>(returnData))ERR(std::format("WARNING! No valid return type set for down button navigation in menu {}",int(type))); SetSelection(returnData); } } @@ -440,6 +442,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(std::holds_alternative(nav.left)){ Data returnData; std::get(nav.left)(type,returnData); + if(!std::holds_alternative(returnData)&&!std::holds_alternative>(returnData))ERR(std::format("WARNING! No valid return type set for left button navigation in menu {}",int(type))); SetSelection(returnData); } } @@ -451,6 +454,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(std::holds_alternative(nav.right)){ Data returnData; std::get(nav.right)(type,returnData); + if(!std::holds_alternative(returnData)&&!std::holds_alternative>(returnData))ERR(std::format("WARNING! No valid return type set for right button navigation in menu {}",int(type))); SetSelection(returnData); } } @@ -814,4 +818,32 @@ const bool Menu::GameInitialized()const{ const bool Menu::IsMouseOverMenu(){ if(Menu::stack.size()==0)return false; return geom2d::overlaps(game->GetMousePos(),geom2d::rect{Menu::stack.back()->pos-"Interface.9PatchSize"_V.x,Menu::stack.back()->size+"Interface.9PatchSize"_V.y*2}); +} + +void Menu::ScrollUp(const MenuType type,const std::string&componentName,Data&returnData,const std::optionalwrapDestination){ + if(!Menu::menus[type]->GetSelection().expired()){ + auto selection=Menu::menus[type]->GetSelection().lock(); + size_t index=Component(type,componentName)->GetComponentIndex(selection); + index--; + if(index>=Component(type,componentName)->GetComponents().size()){ + if(wrapDestination)returnData=wrapDestination.value(); + else returnData=Component(type,componentName)->GetComponents().back(); + }else{ + returnData=Component(type,componentName)->GetComponents()[index]; + } + } +} + +void Menu::ScrollDown(const MenuType type,const std::string&componentName,Data&returnData,const std::optionalwrapDestination){ + if(!Menu::menus[type]->GetSelection().expired()){ + auto selection=Menu::menus[type]->GetSelection().lock(); + size_t index=Component(type,componentName)->GetComponentIndex(selection); + index++; + if(index>=Component(type,componentName)->GetComponents().size()){ + if(wrapDestination)returnData=wrapDestination.value(); + else returnData=Component(type,componentName)->GetComponents().front(); + }else{ + returnData=Component(type,componentName)->GetComponents()[index]; + } + } } \ No newline at end of file diff --git a/Adventures in Lestoria/Menu.h b/Adventures in Lestoria/Menu.h index 7a575094..f0762952 100644 --- a/Adventures in Lestoria/Menu.h +++ b/Adventures in Lestoria/Menu.h @@ -208,6 +208,10 @@ public: //Returns whether or not this menu type is currently in the foreground of the game, and thus being interacted with by the user. static bool IsCurrentlyActive(MenuType type); static const bool IsMouseOverMenu(); //Returns whether the mouse is hovering over any portion of the menu, thus can be used if a menu is not supposed to cover up everything to determine mouse interactions. + //If a wrap destination is specified, will resolve the selection to that button when the top is reached, otherwise will default to wrapping around. + static void ScrollUp(const MenuType type,const std::string&componentName,Data&returnData,const std::optionalwrapDestination=""); + //If a wrap destination is specified, will resolve the selection to that button when the bottom is reached, otherwise will default to wrapping around. + static void ScrollDown(const MenuType type,const std::string&componentName,Data&returnData,const std::optionalwrapDestination=""); private: Menu(vf2d pos,vf2d size); static MenuType lastMenuTypeCreated; diff --git a/Adventures in Lestoria/MenuItemLabel.h b/Adventures in Lestoria/MenuItemLabel.h index 8c43dd54..a744454e 100644 --- a/Adventures in Lestoria/MenuItemLabel.h +++ b/Adventures in Lestoria/MenuItemLabel.h @@ -90,6 +90,9 @@ public: inline virtual void SetItem(std::variant>itemRef){ this->itemRef=itemRef; } + inline const std::variant>&GetItem()const{ + return itemRef; + } protected: //DO NOT USE! Use MenuLabel::SetLabel() instead! inline virtual void SetLabel(std::string text){ diff --git a/Adventures in Lestoria/ScrollableWindowComponent.h b/Adventures in Lestoria/ScrollableWindowComponent.h index 41bfadd9..c436d7e7 100644 --- a/Adventures in Lestoria/ScrollableWindowComponent.h +++ b/Adventures in Lestoria/ScrollableWindowComponent.h @@ -68,6 +68,11 @@ protected: return geom2d::overlaps(geom2d::rect{{},rect.size},geom2d::rect{component.lock()->rect.pos+vf2d{2,2},component.lock()->rect.size-vf2d{2,2}}); } public: + enum ScrollResult{ + NOT_SCROLLED, + SCROLLED, + }; + inline ScrollableWindowComponent(geom2d::rectrect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) :MenuComponent(rect,"",[](MenuFuncData data){return true;},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){ background=attributes&ComponentAttr::BACKGROUND; @@ -139,10 +144,32 @@ public: if(size_t(prevIndex)!=size_t(selectionIndex)){Menu::menus[parentMenu]->SetSelection(components[size_t(selectionIndex)],false);} } - inline void IncreaseSelectionIndex(const float val){ + inline const size_t GetSelectionIndex()const{ + return selectionIndex; + } + + inline std::weak_ptrGetSelectedComponent(){ + return GetComponents().at(selectionIndex); + } + + inline ScrollResult IncreaseSelectionIndex(const float val){ float prevIndex=selectionIndex; selectionIndex=std::clamp(selectionIndex+val,0.f,float(components.size()-1)); - if(size_t(prevIndex)!=size_t(selectionIndex)){Menu::menus[parentMenu]->SetSelection(components[size_t(selectionIndex)],false);} + if(size_t(prevIndex)!=size_t(selectionIndex)){ + Menu::menus[parentMenu]->SetSelection(components[size_t(selectionIndex)],false); + return SCROLLED; + } + return NOT_SCROLLED; + } + + inline ScrollResult DecreaseSelectionIndex(const float val){ + float prevIndex=selectionIndex; + selectionIndex=std::clamp(selectionIndex-val,0.f,float(components.size()-1)); + if(size_t(prevIndex)!=size_t(selectionIndex)){ + Menu::menus[parentMenu]->SetSelection(components[size_t(selectionIndex)],false); + return SCROLLED; + } + return NOT_SCROLLED; } protected: virtual inline vf2d GetScrollAmount()const{ @@ -402,6 +429,7 @@ public: button->renderInMain=false; //Now we are in control! button->parentComponent=DYNAMIC_POINTER_CAST(Menu::menus[parentMenu]->components[this->GetName()]); button->disable=disable; + button->name=key; CalculateBounds(); diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 5f09f584..cb4b9204 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 11620 +#define VERSION_BUILD 11652 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/config/audio/events.txt b/Adventures in Lestoria/assets/config/audio/events.txt index ac752ad4..cb88387e 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -417,6 +417,11 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) File[0] = rockland.ogg, 40% } + Take Enchant + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = take_enchant.ogg, 80% + } Toggle On { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/Adventures in Lestoria/assets/sounds/take_enchant.ogg b/Adventures in Lestoria/assets/sounds/take_enchant.ogg new file mode 100644 index 00000000..3b2b977c Binary files /dev/null and b/Adventures in Lestoria/assets/sounds/take_enchant.ogg differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 46e65b22..8948ee31 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ