Added some menu scrolling helper functions. Implemented Artificer Enchant window. Added controller compatibility to Artificer Refining Window. Release Build 11652.
This commit is contained in:
parent
a5c10f35e6
commit
86e2976549
@ -251,15 +251,21 @@ namespace ItemTests
|
|||||||
std::weak_ptr<Item>slimeKingRing{Inventory::AddItem("Ring of the Slime King"s)};
|
std::weak_ptr<Item>slimeKingRing{Inventory::AddItem("Ring of the Slime King"s)};
|
||||||
Assert::IsFalse(slimeKingRing.lock()->HasEnchant());
|
Assert::IsFalse(slimeKingRing.lock()->HasEnchant());
|
||||||
for(int i:std::ranges::iota_view(0,1000)){
|
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::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.
|
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);
|
testGame->ChangePlayerClass(WIZARD);
|
||||||
player=testGame->GetPlayer(); //The player pointer has been reassigned...
|
player=testGame->GetPlayer(); //The player pointer has been reassigned...
|
||||||
for(int i:std::ranges::iota_view(0,1000)){
|
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::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.
|
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.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ void Menu::InitializeArtificerDisassembleWindow(){
|
|||||||
EnableDisassemblyDisplay();
|
EnableDisassemblyDisplay();
|
||||||
RowItemDisplay&item{*DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component)};
|
RowItemDisplay&item{*DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component)};
|
||||||
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock());
|
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock());
|
||||||
Component<MenuIconButton>(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal());
|
Component<MenuIconButton>(data.menu.type,"Disassembly Result")->SetIcon(item.GetItem().lock()->Icon().Decal());
|
||||||
Component<MenuLabel>(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName());
|
Component<MenuLabel>(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName());
|
||||||
Component<MenuLabel>(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName())));
|
Component<MenuLabel>(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName())));
|
||||||
return true;
|
return true;
|
||||||
@ -119,7 +119,7 @@ void Menu::InitializeArtificerDisassembleWindow(){
|
|||||||
if(childComponent){
|
if(childComponent){
|
||||||
RowItemDisplay&item{childComponent.value().get()};
|
RowItemDisplay&item{childComponent.value().get()};
|
||||||
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock());
|
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem().lock());
|
||||||
Component<MenuIconButton>(data.menu.type,"Disassembly Result")->SetIcon(GFX.at(item.GetItem().lock()->FragmentName()).Decal());
|
Component<MenuIconButton>(data.menu.type,"Disassembly Result")->SetIcon(item.GetItem().lock()->Icon().Decal());
|
||||||
Component<MenuLabel>(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName());
|
Component<MenuLabel>(data.menu.type,"Disassembly Result Title")->SetLabel(item.GetItem().lock()->FragmentName());
|
||||||
Component<MenuLabel>(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName())));
|
Component<MenuLabel>(data.menu.type,"Fragment Total Count")->SetLabel(std::format("Currently Owned: {}",Inventory::GetItemCount(item.GetItem().lock()->FragmentName())));
|
||||||
EnableDisassemblyDisplay();
|
EnableDisassemblyDisplay();
|
||||||
@ -136,6 +136,8 @@ void Menu::InitializeArtificerDisassembleWindow(){
|
|||||||
|
|
||||||
Menu::AddInventoryListener(inventoryDisplay,"Accessories");
|
Menu::AddInventoryListener(inventoryDisplay,"Accessories");
|
||||||
|
|
||||||
|
ResetDisassemblyDisplay();
|
||||||
|
|
||||||
artificerDisassembleWindow->SetupKeyboardNavigation(
|
artificerDisassembleWindow->SetupKeyboardNavigation(
|
||||||
[](MenuType type,Data&returnData){ //On Open
|
[](MenuType type,Data&returnData){ //On Open
|
||||||
returnData="";
|
returnData="";
|
||||||
|
@ -40,6 +40,7 @@ All rights reserved.
|
|||||||
#include "AdventuresInLestoria.h"
|
#include "AdventuresInLestoria.h"
|
||||||
#include "MenuIconButton.h"
|
#include "MenuIconButton.h"
|
||||||
#include "MenuItemLabel.h"
|
#include "MenuItemLabel.h"
|
||||||
|
#include "SoundEffect.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
|
||||||
@ -68,12 +69,32 @@ void Menu::InitializeArtificerEnchantConfirmWindow(){
|
|||||||
const float takeOldTextWidth{float(game->GetTextSize("Take Old").x)*2.f};
|
const float takeOldTextWidth{float(game->GetTextSize("Take Old").x)*2.f};
|
||||||
auto takeOldButton{artificerEnchantConfirmWindow->ADD("Take Old Button",MenuComponent)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/4.f-takeOldTextWidth/2.f,138.f},{takeOldTextWidth-8.f,20.f}},"Take Old",[](MenuFuncData data){
|
auto takeOldButton{artificerEnchantConfirmWindow->ADD("Take Old Button",MenuComponent)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/4.f-takeOldTextWidth/2.f,138.f},{takeOldTextWidth-8.f,20.f}},"Take Old",[](MenuFuncData data){
|
||||||
onClick:
|
onClick:
|
||||||
|
const std::string&oldEnchantName{Menu::menus[ARTIFICER_ENCHANT]->S(A::ENCHANT_TYPE)};
|
||||||
|
std::weak_ptr<Item>newItem{std::get<std::weak_ptr<Item>>(Component<MenuItemLabel>(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<MenuComponent>(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<MenuLabel>(ARTIFICER_ENCHANT,"Fragment Label")->SetLabel(std::format("{}{} x{} ({})",fragmentItemDisplayCol.toHTMLColorCode(),fragmentName,"Fragment Enchant Cost"_i[0],Inventory::GetItemCount(fragmentName)));
|
||||||
|
Component<MenuLabel>(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;
|
return true;
|
||||||
},vf2d{2.f,2.f})END};
|
},vf2d{2.f,2.f})END};
|
||||||
|
|
||||||
const float takeNewTextWidth{float(game->GetTextSize("Take New").x)*2.f};
|
const float takeNewTextWidth{float(game->GetTextSize("Take New").x)*2.f};
|
||||||
auto takeNewButton{artificerEnchantConfirmWindow->ADD("Take New Button",MenuComponent)(geom2d::rect<float>{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){
|
auto takeNewButton{artificerEnchantConfirmWindow->ADD("Take New Button",MenuComponent)(geom2d::rect<float>{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:
|
onClick:
|
||||||
|
std::weak_ptr<Item>newItem{std::get<std::weak_ptr<Item>>(Component<MenuItemLabel>(data.menu.GetType(),"New Item Description")->GetItem())};
|
||||||
|
Component<MenuComponent>(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<MenuLabel>(ARTIFICER_ENCHANT,"Fragment Label")->SetLabel(std::format("{}{} x{} ({})",fragmentItemDisplayCol.toHTMLColorCode(),fragmentName,"Fragment Enchant Cost"_i[0],Inventory::GetItemCount(fragmentName)));
|
||||||
|
Component<MenuLabel>(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;
|
return true;
|
||||||
},vf2d{2.f,2.f})END};
|
},vf2d{2.f,2.f})END};
|
||||||
|
|
||||||
|
@ -157,7 +157,12 @@ void Menu::InitializeArtificerRefineWindow(){
|
|||||||
|
|
||||||
artificerRefineWindow->SetupKeyboardNavigation(
|
artificerRefineWindow->SetupKeyboardNavigation(
|
||||||
[](MenuType type,Data&returnData){ //On Open
|
[](MenuType type,Data&returnData){ //On Open
|
||||||
returnData="";
|
auto&items{Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetComponents()};
|
||||||
|
if(items.size()>0){
|
||||||
|
returnData=items[0];
|
||||||
|
}else{
|
||||||
|
returnData="Back";
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ //Button Key
|
{ //Button Key
|
||||||
{game->KEY_SCROLL,{"Navigate",[](MenuType type){}}},
|
{game->KEY_SCROLL,{"Navigate",[](MenuType type){}}},
|
||||||
@ -165,12 +170,51 @@ void Menu::InitializeArtificerRefineWindow(){
|
|||||||
Menu::CloseMenu();
|
Menu::CloseMenu();
|
||||||
}}},
|
}}},
|
||||||
{game->KEY_CONFIRM,{"Select",[](MenuType type){}}},
|
{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
|
,{ //Button Navigation Rules
|
||||||
{"Sample Button",{
|
{"Accessory List",{
|
||||||
.up="",
|
.up=[&](MenuType type,Data&returnData){
|
||||||
.down="",
|
Menu::ScrollUp(type,"Accessory List",returnData,"Back");
|
||||||
.left="",
|
},
|
||||||
.right="",}},
|
.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<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild())returnData=Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild().value().get().GetName();
|
||||||
|
else returnData=Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetComponents().back().lock()->GetName();
|
||||||
|
},
|
||||||
|
.down=[&](MenuType type,Data&returnData){
|
||||||
|
if(Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild())returnData=Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild().value().get().GetName();
|
||||||
|
else returnData=Component<RowInventoryScrollableWindowComponent>(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<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetComponents().back().lock()->GetName();
|
||||||
|
},
|
||||||
|
.down=[&](MenuType type,Data&returnData){
|
||||||
|
returnData=Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetComponents().front().lock()->GetName();
|
||||||
|
},
|
||||||
|
.left=[&](MenuType type,Data&returnData){
|
||||||
|
if(Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild())returnData=Component<RowInventoryScrollableWindowComponent>(type,"Accessory List")->GetSelectedChild().value().get().GetName();
|
||||||
|
else returnData="Back";
|
||||||
|
},
|
||||||
|
.right="Back",}},
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
@ -76,7 +76,7 @@ void Menu::InitializeArtificerWindow(){
|
|||||||
|
|
||||||
artificerWindow->SetupKeyboardNavigation(
|
artificerWindow->SetupKeyboardNavigation(
|
||||||
[](MenuType type,Data&returnData){ //On Open
|
[](MenuType type,Data&returnData){ //On Open
|
||||||
returnData="Refine Button";
|
returnData="Disassemble Button";
|
||||||
},
|
},
|
||||||
{ //Button Key
|
{ //Button Key
|
||||||
{game->KEY_SCROLL,{"Navigate",[](MenuType type){}}},
|
{game->KEY_SCROLL,{"Navigate",[](MenuType type){}}},
|
||||||
@ -86,14 +86,14 @@ void Menu::InitializeArtificerWindow(){
|
|||||||
{game->KEY_CONFIRM,{"Select",[](MenuType type){}}},
|
{game->KEY_CONFIRM,{"Select",[](MenuType type){}}},
|
||||||
}
|
}
|
||||||
,{ //Button Navigation Rules
|
,{ //Button Navigation Rules
|
||||||
{"Refine Button",{
|
|
||||||
.up="Leave Button",
|
|
||||||
.down="Disassemble Button",}},
|
|
||||||
{"Disassemble Button",{
|
{"Disassemble Button",{
|
||||||
.up="Refine Button",
|
.up="Leave Button",
|
||||||
|
.down="Refine Button",}},
|
||||||
|
{"Refine Button",{
|
||||||
|
.up="Disassemble Button",
|
||||||
.down="Enchant Button",}},
|
.down="Enchant Button",}},
|
||||||
{"Enchant Button",{
|
{"Enchant Button",{
|
||||||
.up="Disassemble Button",
|
.up="Refine Button",
|
||||||
.down="Help Button",}},
|
.down="Help Button",}},
|
||||||
{"Help Button",{
|
{"Help Button",{
|
||||||
.up="Enchant Button",
|
.up="Enchant Button",
|
||||||
|
@ -476,28 +476,10 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
,{ //Button Navigation Rules
|
,{ //Button Navigation Rules
|
||||||
{"Equip List",{
|
{"Equip List",{
|
||||||
.up=[](MenuType type,Data&returnData){
|
.up=[](MenuType type,Data&returnData){
|
||||||
if(!Menu::menus[type]->GetSelection().expired()){
|
Menu::ScrollUp(type,"Equip List",returnData,"Equip Selection Select Button");
|
||||||
auto selection=Menu::menus[type]->GetSelection().lock();
|
|
||||||
size_t index=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponentIndex(selection);
|
|
||||||
index--;
|
|
||||||
if(index>=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents().size()){
|
|
||||||
returnData="Equip Selection Select Button";
|
|
||||||
}else{
|
|
||||||
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.down=[](MenuType type,Data&returnData){
|
.down=[](MenuType type,Data&returnData){
|
||||||
if(!Menu::menus[type]->GetSelection().expired()){
|
Menu::ScrollDown(type,"Equip List",returnData,"Equip Selection Select Button");
|
||||||
auto selection=Menu::menus[type]->GetSelection().lock();
|
|
||||||
size_t index=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponentIndex(selection);
|
|
||||||
index++;
|
|
||||||
if(index>=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents().size()){
|
|
||||||
returnData="Equip Selection Select Button";
|
|
||||||
}else{
|
|
||||||
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.left=[](MenuType type,Data&returnData){
|
.left=[](MenuType type,Data&returnData){
|
||||||
auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents();
|
auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents();
|
||||||
|
@ -1530,7 +1530,9 @@ const std::optional<std::string>&Item::FragmentIcon()const{
|
|||||||
|
|
||||||
const ItemEnchantInfo Item::ApplyRandomEnchant(){
|
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!");
|
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);
|
_EnchantItem(randomEnchantName);
|
||||||
Inventory::RemoveItem(FragmentName(),"Fragment Enchant Cost"_i[0]);
|
Inventory::RemoveItem(FragmentName(),"Fragment Enchant Cost"_i[0]);
|
||||||
game->GetPlayer()->RemoveMoney("Fragment Enchant Cost"_i[1]);
|
game->GetPlayer()->RemoveMoney("Fragment Enchant Cost"_i[1]);
|
||||||
|
@ -246,7 +246,7 @@ const std::vector<ItemEnchantInfo>ItemEnchant::GetAvailableEnchants(){
|
|||||||
return filteredEnchants;
|
return filteredEnchants;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string ItemEnchant::RollRandomEnchant(){
|
const std::string ItemEnchant::RollRandomEnchant(const std::string_view previousEnchantName){
|
||||||
const std::vector<ItemEnchantInfo>filteredEnchants{GetAvailableEnchants()};
|
const std::vector<ItemEnchantInfo>filteredEnchants{GetAvailableEnchants()};
|
||||||
|
|
||||||
int randomRoll{int(util::random_range(0,100))};
|
int randomRoll{int(util::random_range(0,100))};
|
||||||
@ -256,11 +256,11 @@ const std::string ItemEnchant::RollRandomEnchant(){
|
|||||||
std::vector<ItemEnchantInfo>remainingAvailableEnchants;
|
std::vector<ItemEnchantInfo>remainingAvailableEnchants;
|
||||||
|
|
||||||
if(randomRoll>=generalEnchantRange.first&&randomRoll<generalEnchantRange.second){
|
if(randomRoll>=generalEnchantRange.first&&randomRoll<generalEnchantRange.second){
|
||||||
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[](const ItemEnchantInfo&enchant){return enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::GENERAL;});
|
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[&previousEnchantName](const ItemEnchantInfo&enchant){return enchant.Name()!=previousEnchantName&&enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::GENERAL;});
|
||||||
}else if(randomRoll>=classEnchantRange.first&&randomRoll<classEnchantRange.second){
|
}else if(randomRoll>=classEnchantRange.first&&randomRoll<classEnchantRange.second){
|
||||||
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[](const ItemEnchantInfo&enchant){return enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::CLASS;});
|
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[&previousEnchantName](const ItemEnchantInfo&enchant){return enchant.Name()!=previousEnchantName&&enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::CLASS;});
|
||||||
}else if(randomRoll>=uniqueEnchantRange.first&&randomRoll<uniqueEnchantRange.second){
|
}else if(randomRoll>=uniqueEnchantRange.first&&randomRoll<uniqueEnchantRange.second){
|
||||||
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[](const ItemEnchantInfo&enchant){return enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::UNIQUE;});
|
std::copy_if(filteredEnchants.begin(),filteredEnchants.end(),std::back_inserter(remainingAvailableEnchants),[&previousEnchantName](const ItemEnchantInfo&enchant){return enchant.Name()!=previousEnchantName&&enchant.Category()==ItemEnchantInfo::ItemEnchantCategory::UNIQUE;});
|
||||||
}else ERR(std::format("WARNING! Somehow did not pick a value in any of the given ranges. Rolled value was: {}. Ranges were {}-{}, {}-{}, {}-{}",randomRoll,generalEnchantRange.first,generalEnchantRange.second,classEnchantRange.first,classEnchantRange.second,uniqueEnchantRange.first,uniqueEnchantRange.second));
|
}else ERR(std::format("WARNING! Somehow did not pick a value in any of the given ranges. Rolled value was: {}. Ranges were {}-{}, {}-{}, {}-{}",randomRoll,generalEnchantRange.first,generalEnchantRange.second,classEnchantRange.first,classEnchantRange.second,uniqueEnchantRange.first,uniqueEnchantRange.second));
|
||||||
|
|
||||||
return remainingAvailableEnchants[util::random()%remainingAvailableEnchants.size()].Name();
|
return remainingAvailableEnchants[util::random()%remainingAvailableEnchants.size()].Name();
|
||||||
|
@ -100,6 +100,8 @@ private:
|
|||||||
static std::unordered_map<ItemEnchantCategory,ItemEnchantCategoryData>ENCHANT_CATEGORIES;
|
static std::unordered_map<ItemEnchantCategory,ItemEnchantCategoryData>ENCHANT_CATEGORIES;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Item;
|
||||||
|
|
||||||
class ItemEnchant{
|
class ItemEnchant{
|
||||||
public:
|
public:
|
||||||
ItemEnchant(const std::string_view enchantName);
|
ItemEnchant(const std::string_view enchantName);
|
||||||
@ -109,7 +111,7 @@ public:
|
|||||||
const std::optional<ItemEnchantInfo::AbilitySlot>&AbilitySlot()const;
|
const std::optional<ItemEnchantInfo::AbilitySlot>&AbilitySlot()const;
|
||||||
const static std::vector<ItemEnchantInfo>GetAvailableEnchants();
|
const static std::vector<ItemEnchantInfo>GetAvailableEnchants();
|
||||||
//Rolls a class-appropriate random enchant.
|
//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);
|
void SetAttribute(const std::string_view attr,const float val);
|
||||||
const float&GetAttribute(const std::string_view attr)const;
|
const float&GetAttribute(const std::string_view attr)const;
|
||||||
std::map<ItemAttribute,float>::const_iterator begin()const;
|
std::map<ItemAttribute,float>::const_iterator begin()const;
|
||||||
|
@ -418,6 +418,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
if(std::holds_alternative<MenuDataFunc>(nav.up)){
|
if(std::holds_alternative<MenuDataFunc>(nav.up)){
|
||||||
Data returnData;
|
Data returnData;
|
||||||
std::get<MenuDataFunc>(nav.up)(type,returnData);
|
std::get<MenuDataFunc>(nav.up)(type,returnData);
|
||||||
|
if(!std::holds_alternative<ButtonName>(returnData)&&!std::holds_alternative<std::weak_ptr<MenuComponent>>(returnData))ERR(std::format("WARNING! No valid return type set for up button navigation in menu {}",int(type)));
|
||||||
SetSelection(returnData);
|
SetSelection(returnData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -429,6 +430,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
if(std::holds_alternative<MenuDataFunc>(nav.down)){
|
if(std::holds_alternative<MenuDataFunc>(nav.down)){
|
||||||
Data returnData;
|
Data returnData;
|
||||||
std::get<MenuDataFunc>(nav.down)(type,returnData);
|
std::get<MenuDataFunc>(nav.down)(type,returnData);
|
||||||
|
if(!std::holds_alternative<ButtonName>(returnData)&&!std::holds_alternative<std::weak_ptr<MenuComponent>>(returnData))ERR(std::format("WARNING! No valid return type set for down button navigation in menu {}",int(type)));
|
||||||
SetSelection(returnData);
|
SetSelection(returnData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,6 +442,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
if(std::holds_alternative<MenuDataFunc>(nav.left)){
|
if(std::holds_alternative<MenuDataFunc>(nav.left)){
|
||||||
Data returnData;
|
Data returnData;
|
||||||
std::get<MenuDataFunc>(nav.left)(type,returnData);
|
std::get<MenuDataFunc>(nav.left)(type,returnData);
|
||||||
|
if(!std::holds_alternative<ButtonName>(returnData)&&!std::holds_alternative<std::weak_ptr<MenuComponent>>(returnData))ERR(std::format("WARNING! No valid return type set for left button navigation in menu {}",int(type)));
|
||||||
SetSelection(returnData);
|
SetSelection(returnData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,6 +454,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
|
|||||||
if(std::holds_alternative<MenuDataFunc>(nav.right)){
|
if(std::holds_alternative<MenuDataFunc>(nav.right)){
|
||||||
Data returnData;
|
Data returnData;
|
||||||
std::get<MenuDataFunc>(nav.right)(type,returnData);
|
std::get<MenuDataFunc>(nav.right)(type,returnData);
|
||||||
|
if(!std::holds_alternative<ButtonName>(returnData)&&!std::holds_alternative<std::weak_ptr<MenuComponent>>(returnData))ERR(std::format("WARNING! No valid return type set for right button navigation in menu {}",int(type)));
|
||||||
SetSelection(returnData);
|
SetSelection(returnData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -814,4 +818,32 @@ const bool Menu::GameInitialized()const{
|
|||||||
const bool Menu::IsMouseOverMenu(){
|
const bool Menu::IsMouseOverMenu(){
|
||||||
if(Menu::stack.size()==0)return false;
|
if(Menu::stack.size()==0)return false;
|
||||||
return geom2d::overlaps(game->GetMousePos(),geom2d::rect<float>{Menu::stack.back()->pos-"Interface.9PatchSize"_V.x,Menu::stack.back()->size+"Interface.9PatchSize"_V.y*2});
|
return geom2d::overlaps(game->GetMousePos(),geom2d::rect<float>{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::optional<std::string>wrapDestination){
|
||||||
|
if(!Menu::menus[type]->GetSelection().expired()){
|
||||||
|
auto selection=Menu::menus[type]->GetSelection().lock();
|
||||||
|
size_t index=Component<ScrollableWindowComponent>(type,componentName)->GetComponentIndex(selection);
|
||||||
|
index--;
|
||||||
|
if(index>=Component<ScrollableWindowComponent>(type,componentName)->GetComponents().size()){
|
||||||
|
if(wrapDestination)returnData=wrapDestination.value();
|
||||||
|
else returnData=Component<ScrollableWindowComponent>(type,componentName)->GetComponents().back();
|
||||||
|
}else{
|
||||||
|
returnData=Component<ScrollableWindowComponent>(type,componentName)->GetComponents()[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::ScrollDown(const MenuType type,const std::string&componentName,Data&returnData,const std::optional<std::string>wrapDestination){
|
||||||
|
if(!Menu::menus[type]->GetSelection().expired()){
|
||||||
|
auto selection=Menu::menus[type]->GetSelection().lock();
|
||||||
|
size_t index=Component<ScrollableWindowComponent>(type,componentName)->GetComponentIndex(selection);
|
||||||
|
index++;
|
||||||
|
if(index>=Component<ScrollableWindowComponent>(type,componentName)->GetComponents().size()){
|
||||||
|
if(wrapDestination)returnData=wrapDestination.value();
|
||||||
|
else returnData=Component<ScrollableWindowComponent>(type,componentName)->GetComponents().front();
|
||||||
|
}else{
|
||||||
|
returnData=Component<ScrollableWindowComponent>(type,componentName)->GetComponents()[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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.
|
//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 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.
|
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::optional<std::string>wrapDestination="");
|
||||||
|
//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::optional<std::string>wrapDestination="");
|
||||||
private:
|
private:
|
||||||
Menu(vf2d pos,vf2d size);
|
Menu(vf2d pos,vf2d size);
|
||||||
static MenuType lastMenuTypeCreated;
|
static MenuType lastMenuTypeCreated;
|
||||||
|
@ -90,6 +90,9 @@ public:
|
|||||||
inline virtual void SetItem(std::variant<Item,std::weak_ptr<Item>>itemRef){
|
inline virtual void SetItem(std::variant<Item,std::weak_ptr<Item>>itemRef){
|
||||||
this->itemRef=itemRef;
|
this->itemRef=itemRef;
|
||||||
}
|
}
|
||||||
|
inline const std::variant<Item,std::weak_ptr<Item>>&GetItem()const{
|
||||||
|
return itemRef;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
//DO NOT USE! Use MenuLabel::SetLabel() instead!
|
//DO NOT USE! Use MenuLabel::SetLabel() instead!
|
||||||
inline virtual void SetLabel(std::string text){
|
inline virtual void SetLabel(std::string text){
|
||||||
|
@ -68,6 +68,11 @@ protected:
|
|||||||
return geom2d::overlaps(geom2d::rect<float>{{},rect.size},geom2d::rect<float>{component.lock()->rect.pos+vf2d{2,2},component.lock()->rect.size-vf2d{2,2}});
|
return geom2d::overlaps(geom2d::rect<float>{{},rect.size},geom2d::rect<float>{component.lock()->rect.pos+vf2d{2,2},component.lock()->rect.size-vf2d{2,2}});
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
enum ScrollResult{
|
||||||
|
NOT_SCROLLED,
|
||||||
|
SCROLLED,
|
||||||
|
};
|
||||||
|
|
||||||
inline ScrollableWindowComponent(geom2d::rect<float>rect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
inline ScrollableWindowComponent(geom2d::rect<float>rect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
||||||
:MenuComponent(rect,"",[](MenuFuncData data){return true;},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){
|
:MenuComponent(rect,"",[](MenuFuncData data){return true;},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){
|
||||||
background=attributes&ComponentAttr::BACKGROUND;
|
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);}
|
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_ptr<MenuComponent>GetSelectedComponent(){
|
||||||
|
return GetComponents().at(selectionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ScrollResult IncreaseSelectionIndex(const float val){
|
||||||
float prevIndex=selectionIndex;
|
float prevIndex=selectionIndex;
|
||||||
selectionIndex=std::clamp(selectionIndex+val,0.f,float(components.size()-1));
|
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:
|
protected:
|
||||||
virtual inline vf2d GetScrollAmount()const{
|
virtual inline vf2d GetScrollAmount()const{
|
||||||
@ -402,6 +429,7 @@ public:
|
|||||||
button->renderInMain=false; //Now we are in control!
|
button->renderInMain=false; //Now we are in control!
|
||||||
button->parentComponent=DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(Menu::menus[parentMenu]->components[this->GetName()]);
|
button->parentComponent=DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(Menu::menus[parentMenu]->components[this->GetName()]);
|
||||||
button->disable=disable;
|
button->disable=disable;
|
||||||
|
button->name=key;
|
||||||
|
|
||||||
CalculateBounds();
|
CalculateBounds();
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 11620
|
#define VERSION_BUILD 11652
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -417,6 +417,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] = rockland.ogg, 40%
|
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
|
Toggle On
|
||||||
{
|
{
|
||||||
# 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%)
|
||||||
|
BIN
Adventures in Lestoria/assets/sounds/take_enchant.ogg
Normal file
BIN
Adventures in Lestoria/assets/sounds/take_enchant.ogg
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user