diff --git a/Adventures in Lestoria/AccessoryRowItemDisplay.h b/Adventures in Lestoria/AccessoryRowItemDisplay.h index 0026f235..b661e978 100644 --- a/Adventures in Lestoria/AccessoryRowItemDisplay.h +++ b/Adventures in Lestoria/AccessoryRowItemDisplay.h @@ -37,12 +37,14 @@ All rights reserved. #pragma endregion #pragma once #include "RowItemDisplay.h" +#include "SoundEffect.h" +#include "MenuIconButton.h" INCLUDE_game INCLUDE_GFX class AccessoryRowItemDisplay:public RowItemDisplay{ - std::weak_ptrlockButton; + std::weak_ptrlockButton; public: inline AccessoryRowItemDisplay(geom2d::rectrect,const std::weak_ptritemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE) :RowItemDisplay(rect,itemRef,onClick,itemNameLabelName,itemDescriptionLabelName,attributes){} @@ -54,9 +56,38 @@ public: lockButton.reset(); } } - virtual inline void AfterCreate()override final{ - lockButton=parentComponent.lock()->ADDSUB(std::format("{}_lock",name),MenuComponent)(geom2d::rect{rect.pos,vf2d{16.f,8.f}},"Lock",[](MenuFuncData data){ + inline void AfterCreate()override final{ + lockButton=parentComponent.lock()->ADDSUB(std::format("{}_lock",name),MenuIconButton)(geom2d::rect{rect.pos+vf2d{rect.size.x-10.f,rect.size.y-10.f},vf2d{10.f,10.f}},GFX["unlock.png"].Decal(),[](MenuFuncData data){ + std::weak_ptraccessoryParent=DYNAMIC_POINTER_CAST(data.component.lock()->GetSubcomponentParent()); + accessoryParent.lock()->SetLocked(!accessoryParent.lock()->IsLocked()); + if(accessoryParent.lock()->IsLocked()){ + SoundEffect::PlaySFX("Lock Accessory",SoundEffect::CENTERED); + }else{ + SoundEffect::PlaySFX("Unlock Accessory",SoundEffect::CENTERED); + } + std::weak_ptrlockButton=DYNAMIC_POINTER_CAST(data.component.lock()); return true; })END; } + inline void Update(AiL*game)override final{ + MenuComponent::Update(game); + if(itemRef.lock()->IsLocked()){ + lockButton.lock()->SetIcon(GFX["lock.png"].Decal()); + }else{ + lockButton.lock()->SetIcon(GFX["unlock.png"].Decal()); + } + } + inline const bool IsLocked()const{ + return itemRef.lock()->IsLocked(); + } + inline void SetLocked(const bool locked){ + if(locked){ + itemRef.lock()->Lock(); + }else{ + itemRef.lock()->Unlock(); + } + } + inline const std::weak_ptrGetLockButton()const{ + return lockButton; + } }; \ No newline at end of file diff --git a/Adventures in Lestoria/InventoryWindow.cpp b/Adventures in Lestoria/InventoryWindow.cpp index 44de6f60..b7a1f52d 100644 --- a/Adventures in Lestoria/InventoryWindow.cpp +++ b/Adventures in Lestoria/InventoryWindow.cpp @@ -46,6 +46,7 @@ All rights reserved. #include "RowItemDisplay.h" #include "PlayerMoneyLabel.h" #include "SoundEffect.h" +#include "AccessoryRowItemDisplay.h" INCLUDE_game INCLUDE_ITEM_CATEGORIES @@ -202,7 +203,44 @@ void Menu::InitializeInventoryWindow(){ } }}}, {{game->KEY_SCROLL,Pressed},{"Navigate",[](MenuType type){}}}, - {game->KEY_CONFIRM,{"Select",[](MenuType type){}}}, + {game->KEY_CONFIRM,{[](MenuFuncData data){ + if(!data.menu.GetSelection().expired()&& + !data.menu.GetSelection().lock()->parentComponent.expired()&& + data.menu.GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories"){ + if(DYNAMIC_POINTER_CAST(data.menu.GetSelection().lock())->GetItem().lock()->IsLocked()){ + return "Unlock"; + }else{ + return "Lock"; + } + } + return "Select"; + },[](MenuType type){ + if(!Menu::menus[type]->GetSelection().expired()&& + !Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&& + Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories" + &&Menu::menus[type]->GetSelection().lock()->GetSubcomponentParent().expired()){ + DYNAMIC_POINTER_CAST(Menu::menus[type]->GetSelection().lock())->GetLockButton().lock()->Click(); + } + }}}, + {game->KEY_SELECT,{[](MenuFuncData data){ + if(!data.menu.GetSelection().expired()&& + !data.menu.GetSelection().lock()->parentComponent.expired()&& + data.menu.GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories"){ + if(DYNAMIC_POINTER_CAST(data.menu.GetSelection().lock())->GetItem().lock()->IsLocked()){ + return "Unlock"; + }else{ + return "Lock"; + } + } + return ""; + },[](MenuType type){ + if(!Menu::menus[type]->GetSelection().expired()&& + !Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&& + Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories" + &&Menu::menus[type]->GetSelection().lock()->GetSubcomponentParent().expired()){ + DYNAMIC_POINTER_CAST(Menu::menus[type]->GetSelection().lock())->GetLockButton().lock()->Click(); + } + }}}, } ,{ //Button Navigation Rules {"Back Button",{ diff --git a/Adventures in Lestoria/Item.cpp b/Adventures in Lestoria/Item.cpp index f5d71386..3dfdd7a2 100644 --- a/Adventures in Lestoria/Item.cpp +++ b/Adventures in Lestoria/Item.cpp @@ -1262,4 +1262,15 @@ void Inventory::GivePlayerLoadoutItemsUsed(){ } } ResetLoadoutItemsUsed(); +} + + +const bool Item::IsLocked()const{ + return locked; +} +void Item::Lock(){ + locked=true; +} +void Item::Unlock(){ + locked=false; } \ No newline at end of file diff --git a/Adventures in Lestoria/Item.h b/Adventures in Lestoria/Item.h index a9b09d6e..887dd86c 100644 --- a/Adventures in Lestoria/Item.h +++ b/Adventures in Lestoria/Item.h @@ -174,6 +174,7 @@ private: uint8_t enhancementLevel; ItemInfo*it; Stats randomizedStats; + bool locked=false; void SetAmt(uint32_t newAmt); static ItemEnhancementFunctionPrimingData enhanceFunctionPrimed; @@ -227,6 +228,9 @@ public: static bool IsBlank(std::shared_ptritem); //Use ISBLANK macro instead!! This should not be called directly!! static bool IsBlank(std::weak_ptritem); + const bool IsLocked()const; + void Lock(); + void Unlock(); friend const bool operator==(std::shared_ptrlhs,std::shared_ptrrhs){return lhs->it==rhs->it&&lhs->randomizedStats==rhs->randomizedStats;}; friend const bool operator==(std::shared_ptrlhs,const IT&rhs){return lhs->ActualName()==const_cast(rhs);}; friend const bool operator==(std::weak_ptrlhs,std::weak_ptrrhs){return !lhs.expired()&&!rhs.expired()&&lhs.lock()->it==rhs.lock()->it&&lhs.lock()->randomizedStats==rhs.lock()->randomizedStats;}; diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index 707558e6..78e1bec4 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -140,8 +140,10 @@ Menu*Menu::CreateMenu(MenuType type,vf2d pos,vf2d size){ void Menu::CheckClickAndPerformMenuSelect(AiL*game){ if(game->KEY_CONFIRM.Released()&&!Menu::alreadyClicked&&(MOUSE_NAVIGATION||(!MOUSE_NAVIGATION&&!game->GetMouse(Mouse::LEFT).bReleased&&!game->GetMouse(Mouse::RIGHT).bReleased&&!game->GetMouse(Mouse::MIDDLE).bReleased))){ if(!GetSelection().expired()){ //If we are on controller/gamepad it's possible we haven't highlighted a button yet, so don't click this button right away. + Menu*prevMenu=Menu::IsMenuOpen()?Menu::stack.back():nullptr; MenuSelect(game); - Menu::alreadyClicked=true; + Menu*currentMenu=Menu::IsMenuOpen()?Menu::stack.back():nullptr; + if(prevMenu!=currentMenu)Menu::alreadyClicked=true; //The logic here is that only when we navigate between menus do we care about setting the already clicked flag to prevent further clicks going into the new screen. If we're still on the same menu, then we will proceed with regular inputs. } } } diff --git a/Adventures in Lestoria/MenuComponent.cpp b/Adventures in Lestoria/MenuComponent.cpp index 80faaa26..e4cda8cf 100644 --- a/Adventures in Lestoria/MenuComponent.cpp +++ b/Adventures in Lestoria/MenuComponent.cpp @@ -281,4 +281,8 @@ const bool MenuComponent::IsEnabledOutsideWindow()const{ } const bool MenuComponent::IsDisabledOutsideWindow()const{ return disableOutsideWindow; +} + +const std::weak_ptrMenuComponent::GetSubcomponentParent()const{ + return subcomponentParent; } \ No newline at end of file diff --git a/Adventures in Lestoria/MenuComponent.h b/Adventures in Lestoria/MenuComponent.h index d4061b6a..83fe0955 100644 --- a/Adventures in Lestoria/MenuComponent.h +++ b/Adventures in Lestoria/MenuComponent.h @@ -98,6 +98,8 @@ private: bool disableOutsideWindow=false; //If set to true, this component was automatically set to not be renderable outside the window. bool disable=false; //If set to true, this component will not be rendered or updated. std::string label=""; + + std::weak_ptrsubcomponentParent; //For subcomponents, this value provides the actual component this subcomponent was spawned from. protected: int depth=0; float hoverEffect=0; @@ -168,4 +170,5 @@ public: virtual void OnChapterUpdate(uint8_t newChapter); virtual void Click(); virtual void SetLabel(std::string newLabel); + const std::weak_ptrGetSubcomponentParent()const; }; \ No newline at end of file diff --git a/Adventures in Lestoria/MerchantWindow.cpp b/Adventures in Lestoria/MerchantWindow.cpp index 713fa2a7..f36f20b4 100644 --- a/Adventures in Lestoria/MerchantWindow.cpp +++ b/Adventures in Lestoria/MerchantWindow.cpp @@ -38,6 +38,7 @@ All rights reserved. #include "Menu.h" #include "AdventuresInLestoria.h" +#include "AccessoryRowItemDisplay.h" #include "RowInventoryScrollableWindowComponent.h" #include "MenuItemItemButton.h" #include "MenuComponent.h" @@ -177,6 +178,10 @@ void Menu::InitializeMerchantWindow(){ auto inventoryDisplay=merchantWindow->ADD("Inventory Display - "+category,RowInventoryScrollableWindowComponent)(geom2d::rect{{72,28},{150,merchantWindow->size.y-44}},"Item Name Label","Item Description Label", [](MenuFuncData data){ std::weak_ptritem=DYNAMIC_POINTER_CAST(data.component.lock()); + if(item.lock()->GetItem().lock()->IsLocked()){ + SoundEffect::PlaySFX("Locked Item",SoundEffect::CENTERED); + return true; + } if(item.lock()->GetItem().lock()->CanBeSold()){ Component(SELL_ITEM,"Item Sell Header")->SetItem(item.lock()->GetItem()); Component(SELL_ITEM,"Price per item Amount Label")->SetLabel(std::to_string(item.lock()->GetItem().lock()->SellValue())); @@ -330,6 +335,26 @@ void Menu::InitializeMerchantWindow(){ }}}, {{game->KEY_SCROLL,Pressed},{"Navigate",[](MenuType type){}}}, {game->KEY_CONFIRM,{"Select",[](MenuType type){}}}, + {game->KEY_SELECT,{[](MenuFuncData data){ + /* //Too wordy, let's leave it out for now. + if(!data.menu.GetSelection().expired()&& + !data.menu.GetSelection().lock()->parentComponent.expired()&& + data.menu.GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories"){ + if(DYNAMIC_POINTER_CAST(data.menu.GetSelection().lock())->GetItem().lock()->IsLocked()){ + return "Unlock"; + }else{ + return "Lock"; + } + }*/ + return ""; + },[](MenuType type){ + if(!Menu::menus[type]->GetSelection().expired()&& + !Menu::menus[type]->GetSelection().lock()->parentComponent.expired()&& + Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->GetName()=="Inventory Display - Accessories" + &&Menu::menus[type]->GetSelection().lock()->GetSubcomponentParent().expired()){ + DYNAMIC_POINTER_CAST(Menu::menus[type]->GetSelection().lock())->GetLockButton().lock()->Click(); + } + }}}, } ,{ //Button Navigation Rules {"Leave Button",{ diff --git a/Adventures in Lestoria/SaveFile.cpp b/Adventures in Lestoria/SaveFile.cpp index f773aa45..0812d2a9 100644 --- a/Adventures in Lestoria/SaveFile.cpp +++ b/Adventures in Lestoria/SaveFile.cpp @@ -92,6 +92,7 @@ const void SaveFile::SaveGame(){ saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel()); saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName()); saveFile["Items"][std::format("Item[{}]",itemCount)]["Equip Slot"].SetInt(int(Inventory::GetSlotEquippedIn(item))); + saveFile["Items"][std::format("Item[{}]",itemCount)]["Locked"].SetBool(item->IsLocked()); uint8_t loadoutSlotNumber=255; for(int i=0;iloadout.size();i++){ if(item==game->GetLoadoutItem(i)){loadoutSlotNumber=i;break;} @@ -295,6 +296,13 @@ void SaveFile::LoadFile(){ if(slot!=EquipSlot::NONE){ //This should be equipped somewhere! Inventory::EquipItem(newItem,slot); } + + if(loadFile.GetProperty(std::format("Items.{}",key)).HasProperty("Locked")){ + bool locked=loadFile.GetProperty(std::format("Items.{}",key))["Locked"].GetBool(); + if(locked){ + newItem.lock()->Lock(); + } + } } game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString())); game->GetPlayer()->SetLevel(loadFile["Player"]["Level"].GetInt()); diff --git a/Adventures in Lestoria/ScrollableWindowComponent.h b/Adventures in Lestoria/ScrollableWindowComponent.h index 13bc9b80..24786692 100644 --- a/Adventures in Lestoria/ScrollableWindowComponent.h +++ b/Adventures in Lestoria/ScrollableWindowComponent.h @@ -42,7 +42,7 @@ All rights reserved. using A=Attribute; -#define ADDSUB(key,componentType) _AddSubcomponent(key,std::make_shared +#define ADDSUB(key,componentType) _AddSubcomponent(name,key,std::make_shared INCLUDE_game @@ -364,7 +364,7 @@ public: } public: template - std::shared_ptr _AddSubcomponent(std::string key,std::shared_ptrbutton){ + std::shared_ptr _AddSubcomponent(std::string parentKey,std::string key,std::shared_ptrbutton){ if(Menu::menus[parentMenu]->components.count(key)){ ERR("WARNING! Key "<_AddComponent(key,button); + button->subcomponentParent=Menu::menus[parentMenu]->components.at(parentKey); return button; } template diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt index 9a5cffc2..0f86c64e 100644 --- a/Adventures in Lestoria/TODO.txt +++ b/Adventures in Lestoria/TODO.txt @@ -8,8 +8,6 @@ Materials for initial craft seems to be wrong? need to recheck do we need a minimap? (maybe with fog of war?) Maybe polling that once testing with more people. should gemstones dropp from boss stages aswell? (Maybe lower droprate?) -feature to lock accesoires to protect them from selling would be nice - When opening craft/buy/sell menu, default to the appropriate button. Pressing back on the Select button of the equip menu causes you to exit the menu. Funny text colors with text color override on blacksmith menu diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 2a6d5f93..9c4cf927 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -38,8 +38,8 @@ All rights reserved. #pragma once #define VERSION_MAJOR 0 #define VERSION_MINOR 4 -#define VERSION_PATCH 4 -#define VERSION_BUILD 7947 +#define VERSION_PATCH 5 +#define VERSION_BUILD 7966 #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 a858888e..4dc5629c 100644 --- a/Adventures in Lestoria/assets/config/audio/events.txt +++ b/Adventures in Lestoria/assets/config/audio/events.txt @@ -79,6 +79,16 @@ Events # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) File[0] = item_sell.ogg, 80% } + Lock Accessory + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = button_click2.ogg, 40% + } + Unlock Accessory + { + # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) + File[0] = button_click2.ogg, 60%, 50%, 60% + } Locked Item { # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) diff --git a/Adventures in Lestoria/assets/config/gfx/gfx.txt b/Adventures in Lestoria/assets/config/gfx/gfx.txt index 9fb5573f..6dec3fa1 100644 --- a/Adventures in Lestoria/assets/config/gfx/gfx.txt +++ b/Adventures in Lestoria/assets/config/gfx/gfx.txt @@ -79,6 +79,8 @@ Images GFX_Ursule2 = monsters/Ursule Mother of Bears2.png GFX_Wisp = wisp.png GFX_XPBar = xpbar.png + GFX_Lock = lock.png + GFX_Unlock = unlock.png # Ability Icons GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index e4966460..91647165 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/assets/lock.png b/Adventures in Lestoria/assets/lock.png new file mode 100644 index 00000000..327ea2d0 Binary files /dev/null and b/Adventures in Lestoria/assets/lock.png differ diff --git a/Adventures in Lestoria/assets/unlock.png b/Adventures in Lestoria/assets/unlock.png new file mode 100644 index 00000000..835c4438 Binary files /dev/null and b/Adventures in Lestoria/assets/unlock.png differ diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 12cc56e5..cbff838d 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ