Lock icons implemented in equip menu. When a piece of gear is already equipped, prevent equip sounds/re-equipping of the same exact piece. Release Build 8105.

mac-build
sigonasr2 12 months ago
parent 67a971658e
commit e4e2a0c55e
  1. 285
      Adventures in Lestoria/CharacterMenuWindow.cpp
  2. 3
      Adventures in Lestoria/TODO.txt
  3. 2
      Adventures in Lestoria/Version.h
  4. 1
      Adventures in Lestoria/assets/config/Monsters.txt
  5. BIN
      x64/Release/Adventures in Lestoria.exe

@ -46,33 +46,19 @@ All rights reserved.
#include "EquipSlotButton.h" #include "EquipSlotButton.h"
#include "Item.h" #include "Item.h"
#include "ScrollableWindowComponent.h" #include "ScrollableWindowComponent.h"
#include "RowItemDisplay.h" #include "AccessoryRowItemDisplay.h"
#include "SoundEffect.h" #include "SoundEffect.h"
#include "ProgressBar.h" #include "ProgressBar.h"
#include <bit> #include "MenuItemLabel.h"
INCLUDE_game INCLUDE_game
INCLUDE_GFX INCLUDE_GFX
void Menu::InitializeCharacterMenuWindow(){ namespace CharacterMenuWindow{
static bool equipmentWindowOpened=false;
static int lastEquipButtonOpened=0;
vf2d windowSize=game->GetScreenSize()-vf2d{52,52};
Menu*characterMenuWindow=CreateMenu(CHARACTER_MENU,CENTERED,windowSize);
characterMenuWindow->ADD("Character Label",MenuLabel)(geom2d::rect<float>{{0,-4},{float(windowSize.x)-1,24}},"Character",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)(geom2d::rect<float>{{0,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
characterMenuWindow->ADD("Character Rotating Display",CharacterRotatingDisplay)(geom2d::rect<float>{{118,18},{130,windowSize.y-28}},GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal())END;
characterMenuWindow->ADD("Level Class Display",MenuLabel)(geom2d::rect<float>{vf2d{126.f,windowSize.y-28},{118.f,8.f}},std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()),1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
characterMenuWindow->ADD("XP Bar",ProgressBar)(geom2d::rect<float>{vf2d{126.f,10.f+windowSize.y-28},{118.f,8.f}},Pixel{247,183,82},BLACK,game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired(),"xp")END;
struct AttributeData{ struct AttributeData{
std::string attrName; std::string attrName;
const std::function<int()>calcFunc; const std::function<int()>calcFunc;
}; };
const static std::array<AttributeData,7>displayAttrs{ const static std::array<AttributeData,7>displayAttrs{
AttributeData{"Health",[&]()->int{return game->GetPlayer()->GetMaxHealth();}}, AttributeData{"Health",[&]()->int{return game->GetPlayer()->GetMaxHealth();}},
AttributeData{"Attack",[&]()->int{return game->GetPlayer()->GetAttack();}}, AttributeData{"Attack",[&]()->int{return game->GetPlayer()->GetAttack();}},
@ -82,8 +68,74 @@ void Menu::InitializeCharacterMenuWindow(){
AttributeData{"Crit Rate",[&]()->int{return ceil(game->GetPlayer()->GetCritRatePct()*100);}}, AttributeData{"Crit Rate",[&]()->int{return ceil(game->GetPlayer()->GetCritRatePct()*100);}},
AttributeData{"Crit Dmg",[&]()->int{return ceil(game->GetPlayer()->GetCritDmgPct()*100);}}, AttributeData{"Crit Dmg",[&]()->int{return ceil(game->GetPlayer()->GetCritDmgPct()*100);}},
}; };
const static std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"}; const static std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"};
template<class T>
std::shared_ptr<RowItemDisplay>GenerateItemDisplay(std::shared_ptr<ScrollableWindowComponent>parent,int invIndex,const std::weak_ptr<Item>it){
auto component=parent->ADD("Equip Item "+std::to_string(invIndex),T)(geom2d::rect<float>{{2,2+invIndex*29.f},{120-15,28}},it,
[&](MenuFuncData data){
const auto SelectedEquipIsDifferent=[](std::weak_ptr<RowItemDisplay>comp){
EquipSlot slot=EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE));
std::weak_ptr<Item>currentItem=Inventory::GetEquip(slot);
switch(slot){
case EquipSlot::RING1:
case EquipSlot::RING2:{
std::weak_ptr<Item>otherItem;
if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else
if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
return ISBLANK(otherItem)||
(&*comp.lock()->GetItem().lock()!=&*otherItem.lock()&&
&*comp.lock()->GetItem().lock()!=&*currentItem.lock());
}break;
default:{
return &*comp.lock()->GetItem().lock()!=&*currentItem.lock();
}
}
};
std::weak_ptr<T>comp=DYNAMIC_POINTER_CAST<T>(data.component.lock());
if(!comp.expired()){
if(SelectedEquipIsDifferent(comp)){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory::EquipItem(comp.lock()->GetItem(),EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE)));
if(Menu::IsCurrentlyActive(data.menu.GetType())){
SoundEffect::PlaySFX(comp.lock()->GetItem().lock()->UseSound(),SoundEffect::CENTERED);
}
for(std::weak_ptr<MenuComponent>button:DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(data.parentComponent.lock())->GetComponents()){
std::weak_ptr<T>comp=DYNAMIC_POINTER_CAST<T>(button.lock());
comp.lock()->SetSelected(false);
}
comp.lock()->SetSelected(true);
for(int counter=0;const AttributeData&attribute:displayAttrs){
std::shared_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label");
statDisplayLabel->SetStatChangeAmt(0);
}
std::shared_ptr<MenuItemItemButton>equipButton=Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[data.parentComponent.lock()->I(A::INDEXED_THEME)]);
equipButton->SetItem(comp.lock()->GetItem(),false);
}
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
}
return true;
},"","")END;
return component;
}
};
void Menu::InitializeCharacterMenuWindow(){
static bool equipmentWindowOpened=false;
static int lastEquipButtonOpened=0;
vf2d windowSize=game->GetScreenSize()-vf2d{52,52};
Menu*characterMenuWindow=CreateMenu(CHARACTER_MENU,CENTERED,windowSize);
characterMenuWindow->ADD("Character Label",MenuLabel)(geom2d::rect<float>{{0,-4},{float(windowSize.x)-1,24}},"Character",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)(geom2d::rect<float>{{0,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
characterMenuWindow->ADD("Character Rotating Display",CharacterRotatingDisplay)(geom2d::rect<float>{{118,18},{130,windowSize.y-28}},GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal())END;
characterMenuWindow->ADD("Level Class Display",MenuLabel)(geom2d::rect<float>{vf2d{126.f,windowSize.y-28},{118.f,8.f}},std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()),1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END;
characterMenuWindow->ADD("XP Bar",ProgressBar)(geom2d::rect<float>{vf2d{126.f,10.f+windowSize.y-28},{118.f,8.f}},Pixel{247,183,82},BLACK,game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired(),"xp")END;
characterMenuWindow->ADD("Equip Selection Outline",MenuComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END characterMenuWindow->ADD("Equip Selection Outline",MenuComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END
->Disable(); ->Disable();
@ -98,11 +150,11 @@ void Menu::InitializeCharacterMenuWindow(){
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Disable(); Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Disable();
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Disable(); Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Disable();
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable(); Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable();
for(int counter=0;const AttributeData&attribute:displayAttrs){ for(int counter=0;const CharacterMenuWindow::AttributeData&attribute:CharacterMenuWindow::displayAttrs){
std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label"); std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label");
statDisplayLabel.lock()->SetStatChangeAmt(0); statDisplayLabel.lock()->SetStatChangeAmt(0);
} }
data.menu.SetSelection(std::string_view(std::format("Equip Slot {}",slotNames[std::bit_width(unsigned(data.menu.I(A::EQUIP_TYPE)))-1]))); data.menu.SetSelection(std::string_view(std::format("Equip Slot {}",CharacterMenuWindow::slotNames[std::bit_width(unsigned(data.menu.I(A::EQUIP_TYPE)))-1])));
equipmentWindowOpened=false; equipmentWindowOpened=false;
return true; return true;
})DEPTH 0 END; })DEPTH 0 END;
@ -129,7 +181,7 @@ void Menu::InitializeCharacterMenuWindow(){
labelY-=8; labelY-=8;
} }
EquipSlot slot=EquipSlot(equipSlot); EquipSlot slot=EquipSlot(equipSlot);
auto equipmentSlot=characterMenuWindow->ADD("Equip Slot "+slotNames[i],EquipSlotButton)(geom2d::rect<float>{{x,y+28},{24,24}},slot, auto equipmentSlot=characterMenuWindow->ADD("Equip Slot "+CharacterMenuWindow::slotNames[i],EquipSlotButton)(geom2d::rect<float>{{x,y+28},{24,24}},slot,
[&](MenuFuncData data){ [&](MenuFuncData data){
EquipSlot slot=EquipSlot(data.component.lock()->I(Attribute::EQUIP_TYPE)); EquipSlot slot=EquipSlot(data.component.lock()->I(Attribute::EQUIP_TYPE));
data.menu.I(A::EQUIP_TYPE)=int(slot); data.menu.I(A::EQUIP_TYPE)=int(slot);
@ -147,50 +199,45 @@ void Menu::InitializeCharacterMenuWindow(){
std::shared_ptr<ScrollableWindowComponent>equipList=Component<ScrollableWindowComponent>(data.component.lock()->parentMenu,"Equip List"); std::shared_ptr<ScrollableWindowComponent>equipList=Component<ScrollableWindowComponent>(data.component.lock()->parentMenu,"Equip List");
equipList->RemoveAllComponents(); equipList->RemoveAllComponents();
for(int counter=0;const std::weak_ptr<Item>it:availableEquipment){ for(int counter=0;const std::weak_ptr<Item>it:availableEquipment){
const static auto OppositeRingSlotDoesNotMatchCurrentEquip=[](std::weak_ptr<RowItemDisplay>comp){ std::shared_ptr<RowItemDisplay>equip;
const bool isAccessorySlot=slot&(EquipSlot::RING1|EquipSlot::RING2);
if(isAccessorySlot){
equip=CharacterMenuWindow::GenerateItemDisplay<AccessoryRowItemDisplay>(equipList,counter,it);
}else{
equip=CharacterMenuWindow::GenerateItemDisplay<RowItemDisplay>(equipList,counter,it);
}
equip->SetHoverFunc(
[&](MenuFuncData data){
const auto SelectedEquipIsDifferent=[](std::weak_ptr<RowItemDisplay>comp){
EquipSlot slot=EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE)); EquipSlot slot=EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE));
std::weak_ptr<Item>currentItem=Inventory::GetEquip(slot);
switch(slot){
case EquipSlot::RING1:
case EquipSlot::RING2:{
std::weak_ptr<Item>otherItem; std::weak_ptr<Item>otherItem;
if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2); if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else else
if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1); if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
return ISBLANK(otherItem)||(&*comp.lock()->GetItem().lock()!=&*otherItem.lock()); return ISBLANK(otherItem)||
}; (&*comp.lock()->GetItem().lock()!=&*otherItem.lock()&&
&*comp.lock()->GetItem().lock()!=&*currentItem.lock());
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)(geom2d::rect<float>{{2,2+counter*29.f},{120-15,28}},it, }break;
[](MenuFuncData data){ default:{
std::weak_ptr<RowItemDisplay>comp=DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component.lock()); return &*comp.lock()->GetItem().lock()!=&*currentItem.lock();
if(!comp.expired()){
if(OppositeRingSlotDoesNotMatchCurrentEquip(comp.lock())){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory::EquipItem(comp.lock()->GetItem(),EquipSlot(comp.lock()->I(Attribute::EQUIP_TYPE)));
if(Menu::IsCurrentlyActive(data.menu.GetType())){
SoundEffect::PlaySFX(comp.lock()->GetItem().lock()->UseSound(),SoundEffect::CENTERED);
}
for(std::weak_ptr<MenuComponent>button:DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(data.parentComponent.lock())->GetComponents()){
std::weak_ptr<RowItemDisplay>comp=DYNAMIC_POINTER_CAST<RowItemDisplay>(button.lock());
comp.lock()->SetSelected(false);
}
comp.lock()->SetSelected(true);
for(int counter=0;const AttributeData&attribute:displayAttrs){
std::shared_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label");
statDisplayLabel->SetStatChangeAmt(0);
}
std::shared_ptr<MenuItemItemButton>equipButton=Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[data.parentComponent.lock()->I(A::INDEXED_THEME)]);
equipButton->SetItem(comp.lock()->GetItem(),false);
} }
}else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
} }
return true; };
},"Item Name","Item Description")END;
equip->SetHoverFunc( if(!data.component.lock()->GetSubcomponentParent().expired())return true;
[&](MenuFuncData data){
std::weak_ptr<RowItemDisplay>button=DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component.lock()); std::weak_ptr<RowItemDisplay>button=DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component.lock());
if(!button.expired()){ if(!button.expired()){
const std::weak_ptr<Item>buttonItem=button.lock()->GetItem(); const std::weak_ptr<Item>buttonItem=button.lock()->GetItem();
std::vector<float>statsBeforeEquip; std::vector<float>statsBeforeEquip;
EquipSlot slot=EquipSlot(button.lock()->I(Attribute::EQUIP_TYPE)); EquipSlot slot=EquipSlot(button.lock()->I(Attribute::EQUIP_TYPE));
for(const AttributeData&attribute:displayAttrs){ for(const CharacterMenuWindow::AttributeData&attribute:CharacterMenuWindow::displayAttrs){
statsBeforeEquip.push_back(attribute.calcFunc()); statsBeforeEquip.push_back(attribute.calcFunc());
} }
@ -202,9 +249,9 @@ void Menu::InitializeCharacterMenuWindow(){
if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2); if(slot&EquipSlot::RING1)otherItem=Inventory::GetEquip(EquipSlot::RING2);
else else
if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1); if(slot&EquipSlot::RING2)otherItem=Inventory::GetEquip(EquipSlot::RING1);
if(OppositeRingSlotDoesNotMatchCurrentEquip(button.lock())){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply. if(SelectedEquipIsDifferent(button.lock())){ //If we find that the opposite ring slot is equipped to us, this would be an item swap or the exact same ring, therefore no stat calculations apply.
Inventory::EquipItem(buttonItem,slot); Inventory::EquipItem(buttonItem,slot);
for(int counter=0;const AttributeData&attribute:displayAttrs){ for(int counter=0;const CharacterMenuWindow::AttributeData&attribute:CharacterMenuWindow::displayAttrs){
std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label"); std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label");
int statChangeAmt=attribute.calcFunc()-statsBeforeEquip[counter]; int statChangeAmt=attribute.calcFunc()-statsBeforeEquip[counter];
statDisplayLabel.lock()->SetStatChangeAmt(statChangeAmt); statDisplayLabel.lock()->SetStatChangeAmt(statChangeAmt);
@ -222,6 +269,10 @@ void Menu::InitializeCharacterMenuWindow(){
if(slot&EquipSlot::RING2)Inventory::EquipItem(otherItem,EquipSlot::RING1); if(slot&EquipSlot::RING2)Inventory::EquipItem(otherItem,EquipSlot::RING1);
} }
} }
Component<MenuItemLabel>(data.menu.GetType(),"Item Name")->SetItem(buttonItem);
Component<MenuItemLabel>(data.menu.GetType(),"Item Description")->SetItem(buttonItem);
Component<MenuItemLabel>(data.menu.GetType(),"Item Name")->Enable();
Component<MenuItemLabel>(data.menu.GetType(),"Item Description")->Enable();
}else{ }else{
ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!"); ERR("WARNING! Attempting to cast a button that isn't a RowItemDisplay!");
} }
@ -229,11 +280,13 @@ void Menu::InitializeCharacterMenuWindow(){
}); });
equip->SetMouseOutFunc( equip->SetMouseOutFunc(
[](MenuFuncData data){ [](MenuFuncData data){
for(int counter=0;const AttributeData&attribute:displayAttrs){ for(int counter=0;const CharacterMenuWindow::AttributeData&attribute:CharacterMenuWindow::displayAttrs){
std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label"); std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label");
statDisplayLabel.lock()->SetStatChangeAmt(0); statDisplayLabel.lock()->SetStatChangeAmt(0);
counter++; counter++;
} }
Component<MenuItemLabel>(data.menu.GetType(),"Item Name")->Disable();
Component<MenuItemLabel>(data.menu.GetType(),"Item Description")->Disable();
return true; return true;
}); });
@ -259,7 +312,7 @@ void Menu::InitializeCharacterMenuWindow(){
auto equipmentList=equipList->GetComponents(); auto equipmentList=equipList->GetComponents();
auto itemEquipped=std::find_if(equipmentList.begin(),equipmentList.end(),[&](std::weak_ptr<MenuComponent>&component){ auto itemEquipped=std::find_if(equipmentList.begin(),equipmentList.end(),[&](std::weak_ptr<MenuComponent>&component){
return !ISBLANK(Inventory::GetEquip(slot))&&&*DYNAMIC_POINTER_CAST<RowItemDisplay>(component)->GetItem().lock()==&*Inventory::GetEquip(slot).lock(); return !ISBLANK(Inventory::GetEquip(slot))&&component.lock()->GetSubcomponentParent().expired()&&&*DYNAMIC_POINTER_CAST<RowItemDisplay>(component)->GetItem().lock()==&*Inventory::GetEquip(slot).lock();
}); });
if(itemEquipped!=equipmentList.end()){ if(itemEquipped!=equipmentList.end()){
data.menu.SetSelection(*itemEquipped,true,true); data.menu.SetSelection(*itemEquipped,true,true);
@ -301,24 +354,23 @@ void Menu::InitializeCharacterMenuWindow(){
equipmentSlot->SetShowQuantity(false); equipmentSlot->SetShowQuantity(false);
equipmentSlot->SetCompactDescriptions(false); equipmentSlot->SetCompactDescriptions(false);
equipSlot<<=1; equipSlot<<=1;
characterMenuWindow->ADD("Equip Label "+slotNames[i],PopupMenuLabel)(geom2d::rect<float>{{labelX,labelY},{24,16}},slotNames[i],vf2d{0.5,1.f},ComponentAttr::SHADOW)END; characterMenuWindow->ADD("Equip Label "+CharacterMenuWindow::slotNames[i],PopupMenuLabel)(geom2d::rect<float>{{labelX,labelY},{24,16}},CharacterMenuWindow::slotNames[i],vf2d{0.5,1.f},ComponentAttr::SHADOW)END;
Menu::AddEquipStatListener(equipmentSlot); Menu::AddEquipStatListener(equipmentSlot);
} }
characterMenuWindow->ADD("Stat Display Outline",MenuComponent)(geom2d::rect<float>{{245,28},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; characterMenuWindow->ADD("Stat Display Outline",MenuComponent)(geom2d::rect<float>{{245,28},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
int yOffset=0; int yOffset=0;
for(const AttributeData&attribute:displayAttrs){ for(const CharacterMenuWindow::AttributeData&attribute:CharacterMenuWindow::displayAttrs){
std::string attrStr=GetLabelText(ItemAttribute::Get(attribute.attrName)); std::string attrStr=GetLabelText(ItemAttribute::Get(attribute.attrName));
auto attrLabel=characterMenuWindow->ADD("Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label",StatLabel)(geom2d::rect<float>{{245,28+2+float(yOffset)},{62,18}},ItemAttribute::Get(attribute.attrName),attribute.calcFunc,1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN|ComponentAttr::FIT_TO_LABEL)END; auto attrLabel=characterMenuWindow->ADD("Attribute "+std::string(ItemAttribute::Get(attribute.attrName).Name())+" Label",StatLabel)(geom2d::rect<float>{{245,28+2+float(yOffset)},{62,18}},ItemAttribute::Get(attribute.attrName),attribute.calcFunc,1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN|ComponentAttr::FIT_TO_LABEL)END;
//Menu::AddEquipStatListener(attrLabel);
yOffset+=20; yOffset+=20;
} }
characterMenuWindow->ADD("Back button",MenuComponent)(geom2d::rect<float>{{windowSize.x/2-64,windowSize.y-4.f},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END; characterMenuWindow->ADD("Back button",MenuComponent)(geom2d::rect<float>{{windowSize.x/2-64,windowSize.y-4.f},{128,12}},"Back",[](MenuFuncData data){Menu::stack.pop_back();return true;})END;
auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuLabel)(geom2d::rect<float>{{0,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END; auto itemNameDisplay=characterMenuWindow->ADD("Item Name",MenuItemLabel)(geom2d::rect<float>{{0,28},{120,12}},std::weak_ptr<Item>{},ITEM_NAME,1.f,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuLabel)(geom2d::rect<float>{{0,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; auto itemDescriptionDisplay=characterMenuWindow->ADD("Item Description",MenuItemLabel)(geom2d::rect<float>{{0,40},{120,windowSize.y-49}},std::weak_ptr<Item>{},ITEM_DESCRIPTION,1.f,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
auto itemEquipNameDisplay=characterMenuWindow->ADD("Item Equip Name",MenuLabel)(geom2d::rect<float>{{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END; auto itemEquipNameDisplay=characterMenuWindow->ADD("Item Equip Name",MenuLabel)(geom2d::rect<float>{{123,28},{120,12}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL)END;
auto itemEquipDescriptionDisplay=characterMenuWindow->ADD("Item Equip Description",MenuLabel)(geom2d::rect<float>{{123,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END; auto itemEquipDescriptionDisplay=characterMenuWindow->ADD("Item Equip Description",MenuLabel)(geom2d::rect<float>{{123,40},{120,windowSize.y-49}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::LEFT_ALIGN|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
@ -329,7 +381,7 @@ void Menu::InitializeCharacterMenuWindow(){
characterMenuWindow->SetupKeyboardNavigation( characterMenuWindow->SetupKeyboardNavigation(
[](MenuType type,Data&returnData){ //On Open [](MenuType type,Data&returnData){ //On Open
returnData=std::format("Equip Slot {}",slotNames[0]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[0]);
}, },
{ //Button Key { //Button Key
{{game->KEY_SHOULDER,Pressed},{"Scroll",[](MenuType type){}}}, {{game->KEY_SHOULDER,Pressed},{"Scroll",[](MenuType type){}}},
@ -422,6 +474,27 @@ void Menu::InitializeCharacterMenuWindow(){
Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->IncreaseSelectionIndex(-3.f); Menu::menus[type]->GetSelection().lock()->parentComponent.lock()->IncreaseSelectionIndex(-3.f);
} }
}}}, }}},
{game->KEY_SELECT,{[](MenuFuncData data){
if(!data.menu.GetSelection().expired()&&
!data.menu.GetSelection().lock()->parentComponent.expired()&&
data.menu.GetSelection().lock()->parentComponent.lock()->GetName()=="Equip List"
&&data.component.lock()->GetSubcomponentParent().expired()
&&EquipSlot(data.menu.I(A::EQUIP_TYPE))&(EquipSlot::RING1|EquipSlot::RING2)){
if(DYNAMIC_POINTER_CAST<AccessoryRowItemDisplay>(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()=="Equip List"
&&Menu::menus[type]->GetSelection().lock()->GetSubcomponentParent().expired()){
DYNAMIC_POINTER_CAST<AccessoryRowItemDisplay>(Menu::menus[type]->GetSelection().lock())->GetLockButton().lock()->Click();
}
}}},
} }
,{ //Button Navigation Rules ,{ //Button Navigation Rules
{"Equip List",{ {"Equip List",{
@ -451,11 +524,11 @@ void Menu::InitializeCharacterMenuWindow(){
}, },
.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();
returnData=std::format("Equip Slot {}",slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]);
}, },
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents(); auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents();
returnData=std::format("Equip Slot {}",slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]);
} }
}}, }},
{"Equip Selection Select Button",{ {"Equip Selection Select Button",{
@ -475,108 +548,108 @@ void Menu::InitializeCharacterMenuWindow(){
}, },
.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();
returnData=std::format("Equip Slot {}",slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]);
}, },
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents(); auto equipList=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents();
returnData=std::format("Equip Slot {}",slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[std::bit_width(unsigned(Menu::menus[type]->I(A::EQUIP_TYPE)))-1]);
} }
}}, }},
{std::format("Equip Slot {}", slotNames[0]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[0]),{
.up="Back button", .up="Back button",
.down=std::format("Equip Slot {}", slotNames[2]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[2]),
.left=[&](MenuType type,Data&returnData){ .left=[&](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[1]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[1]);
} }
}, },
.right=std::format("Equip Slot {}", slotNames[1]),}}, .right=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[1]),}},
{std::format("Equip Slot {}", slotNames[1]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[1]),{
.up="Back button", .up="Back button",
.down=std::format("Equip Slot {}", slotNames[3]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[3]),
.left=std::format("Equip Slot {}", slotNames[0]), .left=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[0]),
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[0]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[0]);
} }
},}}, },}},
{std::format("Equip Slot {}", slotNames[2]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[2]),{
.up=std::format("Equip Slot {}", slotNames[0]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[0]),
.down=std::format("Equip Slot {}", slotNames[4]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[4]),
.left=[](MenuType type,Data&returnData){ .left=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[3]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[3]);
} }
}, },
.right=std::format("Equip Slot {}", slotNames[3]),}}, .right=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[3]),}},
{std::format("Equip Slot {}", slotNames[3]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[3]),{
.up=std::format("Equip Slot {}", slotNames[1]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[1]),
.down=std::format("Equip Slot {}", slotNames[5]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[5]),
.left=std::format("Equip Slot {}", slotNames[2]), .left=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[2]),
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[2]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[2]);
} }
},}}, },}},
{std::format("Equip Slot {}", slotNames[4]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[4]),{
.up=std::format("Equip Slot {}", slotNames[2]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[2]),
.down=std::format("Equip Slot {}", slotNames[6]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[6]),
.left=[](MenuType type,Data&returnData){ .left=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[5]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[5]);
} }
}, },
.right=std::format("Equip Slot {}", slotNames[5]), .right=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[5]),
}}, }},
{std::format("Equip Slot {}", slotNames[5]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[5]),{
.up=std::format("Equip Slot {}", slotNames[3]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[3]),
.down=std::format("Equip Slot {}", slotNames[7]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[7]),
.left=std::format("Equip Slot {}", slotNames[4]), .left=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[4]),
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[4]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[4]);
} }
},}}, },}},
{std::format("Equip Slot {}", slotNames[6]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[6]),{
.up=std::format("Equip Slot {}", slotNames[4]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[4]),
.down="Back button", .down="Back button",
.left=[](MenuType type,Data&returnData){ .left=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[7]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[7]);
} }
}, },
.right=std::format("Equip Slot {}",slotNames[7]), .right=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[7]),
}}, }},
{std::format("Equip Slot {}", slotNames[7]),{ {std::format("Equip Slot {}", CharacterMenuWindow::slotNames[7]),{
.up=std::format("Equip Slot {}", slotNames[5]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[5]),
.down="Back button", .down="Back button",
.left=std::format("Equip Slot {}",slotNames[6]), .left=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[6]),
.right=[](MenuType type,Data&returnData){ .right=[](MenuType type,Data&returnData){
if(equipmentWindowOpened){ if(equipmentWindowOpened){
returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))]; returnData=Component<ScrollableWindowComponent>(type,"Equip List")->GetComponents()[unsigned(Menu::menus[type]->I(A::ITEM_SLOT))];
}else{ }else{
returnData=std::format("Equip Slot {}",slotNames[6]); returnData=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[6]);
} }
},}}, },}},
{"Back button",{ {"Back button",{
.up=std::format("Equip Slot {}", slotNames[7]), .up=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[7]),
.down=std::format("Equip Slot {}", slotNames[0]), .down=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[0]),
.left=std::format("Equip Slot {}", slotNames[7]), .left=std::format("Equip Slot {}", CharacterMenuWindow::slotNames[7]),
.right=std::format("Equip Slot {}",slotNames[6]), .right=std::format("Equip Slot {}",CharacterMenuWindow::slotNames[6]),
}}, }},
}); });
} }

@ -11,6 +11,3 @@ should gemstones dropp from boss stages aswell? (Maybe lower droprate?)
Funny text colors with text color override on blacksmith menu Funny text colors with text color override on blacksmith menu
Toggle for displaying error messages Toggle for displaying error messages
Pressing down from the - button on sherman should move to the craft button as well.
Inventory menu still not blinking
Pressing R2/L2 scrolls through monster loot/stage loot window REALLY fast

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 5 #define VERSION_MINOR 5
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 8087 #define VERSION_BUILD 8105
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -141,6 +141,7 @@ Monsters
# Jump property overrides # Jump property overrides
JumpTimer = 10.0 JumpTimer = 10.0
JumpDelayTime = 1.2
JumpAttackDamage = 20 JumpAttackDamage = 20
JumpKnockbackFactor = 50.0 JumpKnockbackFactor = 50.0
JumpMoveSpd = 90 JumpMoveSpd = 90

Loading…
Cancel
Save