Added wrapping menu macro functionality. Implemented controller compatibility for level complete window. Added right alignment for menu labels. Added ProgressBar component. Added XP-related functions for callbacks to other components in-game. Fix giant normalized vector issue with Wolf AI script. Release Build 7041.
This commit is contained in:
parent
52a01d04ad
commit
22b1557c05
@ -504,6 +504,10 @@
|
|||||||
<ClInclude Include="Unlock.h" />
|
<ClInclude Include="Unlock.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
<ClInclude Include="Version.h" />
|
<ClInclude Include="Version.h" />
|
||||||
|
<ClInclude Include="ProgressBar.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Ability.cpp" />
|
<ClCompile Include="Ability.cpp" />
|
||||||
|
@ -453,6 +453,9 @@
|
|||||||
<ClInclude Include="InputDisplayComponent.h">
|
<ClInclude Include="InputDisplayComponent.h">
|
||||||
<Filter>Header Files\Interface</Filter>
|
<Filter>Header Files\Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ProgressBar.h">
|
||||||
|
<Filter>Header Files\Interface</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Player.cpp">
|
<ClCompile Include="Player.cpp">
|
||||||
|
@ -320,16 +320,16 @@ bool AiL::OnUserUpdate(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AiL::LeftHeld(){
|
bool AiL::LeftHeld(){
|
||||||
return KEY_LEFT.Held();
|
return KEY_LEFT.Held()||KEY_SCROLLHORZ_L.Analog()<=-0.2f;
|
||||||
}
|
}
|
||||||
bool AiL::RightHeld(){
|
bool AiL::RightHeld(){
|
||||||
return KEY_RIGHT.Held();
|
return KEY_RIGHT.Held()||KEY_SCROLLHORZ_L.Analog()>=0.2f;
|
||||||
}
|
}
|
||||||
bool AiL::UpHeld(){
|
bool AiL::UpHeld(){
|
||||||
return KEY_UP.Held();
|
return KEY_UP.Held()||KEY_SCROLLVERT_L.Analog()<=-0.2f;
|
||||||
}
|
}
|
||||||
bool AiL::DownHeld(){
|
bool AiL::DownHeld(){
|
||||||
return KEY_DOWN.Held();
|
return KEY_DOWN.Held()||KEY_SCROLLVERT_L.Analog()>=0.2f;
|
||||||
}
|
}
|
||||||
bool AiL::LeftReleased(){
|
bool AiL::LeftReleased(){
|
||||||
return KEY_LEFT.Released();
|
return KEY_LEFT.Released();
|
||||||
@ -2193,7 +2193,7 @@ void AiL::ChangePlayerClass(Class cl){
|
|||||||
player.reset(NEW Witch(player.get()));
|
player.reset(NEW Witch(player.get()));
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
player->level=1;
|
player->SetLevel(level);
|
||||||
player->levelCap=levelCap;
|
player->levelCap=levelCap;
|
||||||
player->stats=previousStats;
|
player->stats=previousStats;
|
||||||
player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt());
|
player->SetBaseStat("Health",DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt());
|
||||||
@ -2215,6 +2215,7 @@ void AiL::ChangePlayerClass(Class cl){
|
|||||||
GetPlayer()->SetItem2UseFunc(itemAbility2);
|
GetPlayer()->SetItem2UseFunc(itemAbility2);
|
||||||
GetPlayer()->SetItem3UseFunc(itemAbility3);
|
GetPlayer()->SetItem3UseFunc(itemAbility3);
|
||||||
camera.SetTarget(player->GetPos());
|
camera.SetTarget(player->GetPos());
|
||||||
|
Component<MenuLabel>(CHARACTER_MENU,"Level Class Display")->SetLabel(std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()));
|
||||||
Player::moneyListeners=moneyListeners;
|
Player::moneyListeners=moneyListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ All rights reserved.
|
|||||||
#include "ScrollableWindowComponent.h"
|
#include "ScrollableWindowComponent.h"
|
||||||
#include "RowItemDisplay.h"
|
#include "RowItemDisplay.h"
|
||||||
#include "SoundEffect.h"
|
#include "SoundEffect.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
INCLUDE_GFX
|
INCLUDE_GFX
|
||||||
@ -62,6 +63,9 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)(geom2d::rect<float>{{0,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)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("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;
|
||||||
|
|
||||||
const static std::array<std::string,7>displayAttrs{
|
const static std::array<std::string,7>displayAttrs{
|
||||||
"Health",
|
"Health",
|
||||||
"Attack",
|
"Attack",
|
||||||
|
@ -169,7 +169,6 @@ void Menu::InitializeConsumableInventoryWindow(){
|
|||||||
int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; /*Moving up moves the cursor up an entire row.*/ \
|
int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; /*Moving up moves the cursor up an entire row.*/ \
|
||||||
if(newRowIndex<0){
|
if(newRowIndex<0){
|
||||||
#define DefaultBehavior \
|
#define DefaultBehavior \
|
||||||
return; \
|
|
||||||
} \
|
} \
|
||||||
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
/*Select the component that matches this new number.*/ \
|
/*Select the component that matches this new number.*/ \
|
||||||
@ -292,7 +291,8 @@ void Menu::InitializeConsumableInventoryWindow(){
|
|||||||
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
int newRowIndex=selectedButton.lock()->inventoryIndex+1; \
|
int newRowIndex=selectedButton.lock()->inventoryIndex+1; \
|
||||||
if(newRowIndex>rowBaseIndex+invWidth-1)
|
int newRowBaseIndex = (newRowIndex / invWidth) * invWidth; \
|
||||||
|
if(rowBaseIndex!=newRowBaseIndex||newRowIndex>=itemsList.size())
|
||||||
#define DefaultBehavior \
|
#define DefaultBehavior \
|
||||||
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
||||||
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
||||||
@ -303,7 +303,9 @@ void Menu::InitializeConsumableInventoryWindow(){
|
|||||||
returnData=*component; \
|
returnData=*component; \
|
||||||
} \
|
} \
|
||||||
}else
|
}else
|
||||||
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex-=invWidth;
|
#define DEFAULT_WRAPPING_BEHAVIOR \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
newRowIndex=rowBaseIndex;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
#define SUBCLASS MenuItemButton
|
#define SUBCLASS MenuItemButton
|
||||||
DetectInventory(InventoryScrollableWindowComponent,type,"inventory")
|
DetectInventory(InventoryScrollableWindowComponent,type,"inventory")
|
||||||
|
@ -66,17 +66,21 @@ protected:
|
|||||||
const std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const onInventorySlotsUpdate;
|
const std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const onInventorySlotsUpdate;
|
||||||
const std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const addButtonOnSlotUpdate;
|
const std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)>*const addButtonOnSlotUpdate;
|
||||||
CompactText compact=COMPACT;
|
CompactText compact=COMPACT;
|
||||||
InventoryWindowOptions options;
|
|
||||||
std::string itemNameLabelName;
|
std::string itemNameLabelName;
|
||||||
std::string itemDescriptionLabelName;
|
std::string itemDescriptionLabelName;
|
||||||
bool inventoryButtonsActive=true;
|
bool inventoryButtonsActive=true;
|
||||||
|
private:
|
||||||
|
InventoryWindowOptions options;
|
||||||
|
int invWidth;
|
||||||
public:
|
public:
|
||||||
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
||||||
:InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,DO_NOTHING,DO_NOTHING,creator,options,inventoryButtonsActive,attributes){
|
:InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,DO_NOTHING,DO_NOTHING,creator,options,inventoryButtonsActive,attributes){
|
||||||
}
|
}
|
||||||
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
|
||||||
:ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),
|
:ScrollableWindowComponent(rect,attributes),inventoryButtonHoverAction(inventoryButtonHoverAction),inventoryButtonMouseOutAction(inventoryButtonMouseOutAction),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),
|
||||||
options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive),addButtonOnSlotUpdate(creator.AddButtonOnSlotUpdate),onInventorySlotsUpdate(creator.InventorySlotsUpdate){}
|
options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive),addButtonOnSlotUpdate(creator.AddButtonOnSlotUpdate),onInventorySlotsUpdate(creator.InventorySlotsUpdate){
|
||||||
|
SetInventoryOptions(options);
|
||||||
|
}
|
||||||
virtual inline void Update(AiL*game)override{
|
virtual inline void Update(AiL*game)override{
|
||||||
ScrollableWindowComponent::Update(game);
|
ScrollableWindowComponent::Update(game);
|
||||||
bool noneHovered=true;
|
bool noneHovered=true;
|
||||||
@ -98,6 +102,15 @@ public:
|
|||||||
itemButton.lock()->SetCompactDescriptions(compact);
|
itemButton.lock()->SetCompactDescriptions(compact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const int GetInventoryWidth()const{
|
||||||
|
return invWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetInventoryOptions(InventoryWindowOptions newOptions){
|
||||||
|
options=newOptions;
|
||||||
|
invWidth=int((rect.size.x-12)/(float(options.size.x)+options.padding));
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual inline void Cleanup()override final{
|
virtual inline void Cleanup()override final{
|
||||||
|
@ -551,16 +551,10 @@ const bool Input::AxesActive(){
|
|||||||
if(gamepad->stillConnected){
|
if(gamepad->stillConnected){
|
||||||
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
|
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
|
||||||
xAxis=gamepad->getAxis(GPAxes::RX);
|
xAxis=gamepad->getAxis(GPAxes::RX);
|
||||||
}else
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::LX))>0.f){
|
|
||||||
xAxis=gamepad->getAxis(GPAxes::LX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
|
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
|
||||||
yAxis=gamepad->getAxis(GPAxes::RY);
|
yAxis=gamepad->getAxis(GPAxes::RY);
|
||||||
}else
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::LY))>0.f){
|
|
||||||
yAxis=gamepad->getAxis(GPAxes::LY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
|
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
|
||||||
|
@ -38,11 +38,11 @@ All rights reserved.
|
|||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "AdventuresInLestoria.h"
|
#include "AdventuresInLestoria.h"
|
||||||
#include "MenuLabel.h"
|
#include "MenuLabel.h"
|
||||||
#include "MenuComponent.h"
|
|
||||||
#include "InventoryScrollableWindowComponent.h"
|
#include "InventoryScrollableWindowComponent.h"
|
||||||
#include "PopupMenuLabel.h"
|
#include "PopupMenuLabel.h"
|
||||||
#include "Unlock.h"
|
#include "Unlock.h"
|
||||||
#include "State_OverworldMap.h"
|
#include "State_OverworldMap.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
|
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
|
|
||||||
@ -51,7 +51,10 @@ void Menu::InitializeLevelCompleteWindow(){
|
|||||||
|
|
||||||
Menu*levelCompleteWindow=Menu::CreateMenu(LEVEL_COMPLETE,windowSize.pos,windowSize.size);
|
Menu*levelCompleteWindow=Menu::CreateMenu(LEVEL_COMPLETE,windowSize.pos,windowSize.size);
|
||||||
|
|
||||||
levelCompleteWindow->ADD("Stage Complete Label",MenuLabel)(geom2d::rect<float>{{0,4},{windowSize.size.x-1.f,20}},"Stage Completed",2,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND|ComponentAttr::SHADOW)END;
|
levelCompleteWindow->ADD("Stage Complete Label",MenuLabel)(geom2d::rect<float>{{0,-8},{windowSize.size.x-1.f,20}},"Stage Completed",2,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND|ComponentAttr::SHADOW)END;
|
||||||
|
|
||||||
|
levelCompleteWindow->ADD("XP Bar",ProgressBar)(geom2d::rect<float>{vf2d{windowSize.size.x/2.f-96.f,18.f},{192.f,8.f}},Pixel{247,183,82},BLACK,game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired(),"xp")END;
|
||||||
|
levelCompleteWindow->ADD("Level Display",MenuLabel)(geom2d::rect<float>{vf2d{windowSize.size.x/2.f-96.f-42.f,18.f},{42.f,8.f}},std::format("Lv{}",game->GetPlayer()->Level()),1.f,ComponentAttr::SHADOW|ComponentAttr::RIGHT_ALIGN)END;
|
||||||
|
|
||||||
levelCompleteWindow->ADD("Monster Loot Outline",MenuComponent)(geom2d::rect<float>{{0,32},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
|
levelCompleteWindow->ADD("Monster Loot Outline",MenuComponent)(geom2d::rect<float>{{0,32},{windowSize.size.x-80.f,72}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;
|
||||||
levelCompleteWindow->ADD("Monster Loot Label",MenuLabel)(geom2d::rect<float>{{0,32},{windowSize.size.x-80.f,12}},"Monster Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END;
|
levelCompleteWindow->ADD("Monster Loot Label",MenuLabel)(geom2d::rect<float>{{0,32},{windowSize.size.x-80.f,12}},"Monster Loot",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE)END;
|
||||||
@ -117,39 +120,412 @@ void Menu::InitializeLevelCompleteWindow(){
|
|||||||
,{ //Button Navigation Rules
|
,{ //Button Navigation Rules
|
||||||
{"Monster Loot Window",{
|
{"Monster Loot Window",{
|
||||||
.up=[](MenuType type,Data&returnData){
|
.up=[](MenuType type,Data&returnData){
|
||||||
auto&selection=Menu::menus[type]->GetSelection();
|
#pragma region Inventory Wrapping Handling Up Macros
|
||||||
auto&itemsList=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window")->GetComponents();
|
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
|
||||||
auto itemsWindow=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();});
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
if(itemsList.size()>0){
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
if(component==itemsList.end()){
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
//Set the selected button to the last element in the list.
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
returnData=itemsList.back();
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.back(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; /*Moving up moves the cursor up an entire row.*/ \
|
||||||
|
if(newRowIndex<0){
|
||||||
|
#define DefaultBehavior \
|
||||||
|
} \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=itemsList.size()-1;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
int colIndex=(newRowIndex+invWidth)%invWidth; //Negative index, so we have to loop around.
|
||||||
|
//Get the base row index of the new inventory.
|
||||||
|
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
|
||||||
|
if(stageLootWindow->GetComponents().size()>0){
|
||||||
|
int rowBaseIndex=(stageLootWindow->GetComponents().back().lock()->inventoryIndex/invWidth)*invWidth;
|
||||||
|
returnData=stageLootWindow->GetComponents()[std::clamp(rowBaseIndex+colIndex,0,int(stageLootWindow->GetComponents().size()-1))];
|
||||||
|
return;
|
||||||
}else{
|
}else{
|
||||||
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding));
|
returnData=selectedButton;
|
||||||
std::weak_ptr<MenuItemButton>selectedButton=DYNAMIC_POINTER_CAST<MenuItemButton>(*component);
|
|
||||||
int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; //Moving up moves the cursor up an entire row.
|
|
||||||
if(newRowIndex<0){
|
|
||||||
//This means we have to wrap around.
|
|
||||||
returnData="OK Button";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex));
|
|
||||||
//Select the component that matches this new number.
|
|
||||||
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<MenuItemButton>(comp)->inventoryIndex==newRowIndex;});
|
|
||||||
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex));
|
|
||||||
returnData=*component;
|
|
||||||
}
|
}
|
||||||
}else{
|
}
|
||||||
returnData="OK Button";
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.down="Load Game Button",}},
|
.down=[](MenuType type,Data&returnData){
|
||||||
{"Load Game Button",{
|
#pragma region Inventory Wrapping Handling Down Macros
|
||||||
.up="New Game Button",
|
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
|
||||||
.down="Quit Game Button",}},
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
{"Quit Game Button",{
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
.up="Load Game Button",
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
.down="New Game Button",}},
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.front();\
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex+invWidth; /*Moving down moves the cursor down an entire row.*/ \
|
||||||
|
if(newRowIndex>=itemsList.size()){ \
|
||||||
|
int currentRow=newRowIndex/invWidth; \
|
||||||
|
/*The logic here is, if we clamp this row index to the last possible index and we're still on the same row, it means there is at least an item on this row. So we go to that instead.*/ \
|
||||||
|
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
||||||
|
int newRow=newRowIndex/invWidth; \
|
||||||
|
if(currentRow!=newRow) //This means we are on a different row, so the row we went down on didn't have any items. Simply drop down to the OK Button.
|
||||||
|
#define DefaultBehavior \
|
||||||
|
} \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=0;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
int colIndex=newRowIndex%invWidth;
|
||||||
|
//Get the base row index of the new inventory.
|
||||||
|
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
|
||||||
|
if(stageLootWindow->GetComponents().size()>0){
|
||||||
|
returnData=stageLootWindow->GetComponents()[std::clamp(colIndex,0,int(stageLootWindow->GetComponents().size()-1))];
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
returnData=selectedButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.left=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Left Macros
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.back(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex-1; \
|
||||||
|
if(newRowIndex<rowBaseIndex)
|
||||||
|
#define DefaultBehavior \
|
||||||
|
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
||||||
|
if(newRowIndex<0)newRowIndex+=itemsList.size(); \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
}else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex+=invWidth;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
returnData="Next Button";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.right=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Right Macros
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.front(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex+1; \
|
||||||
|
int newRowBaseIndex = (newRowIndex / invWidth) * invWidth; \
|
||||||
|
if(rowBaseIndex!=newRowBaseIndex)
|
||||||
|
#define DefaultBehavior \
|
||||||
|
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
||||||
|
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
}else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
newRowIndex=rowBaseIndex;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Monster Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
returnData="Next Button";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},}},
|
||||||
|
{"Stage Loot Window",{
|
||||||
|
.up=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Up Macros
|
||||||
|
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.back(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; /*Moving up moves the cursor up an entire row.*/ \
|
||||||
|
if(newRowIndex<0){
|
||||||
|
#define DefaultBehavior \
|
||||||
|
} \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=itemsList.size()-1;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
int colIndex=(newRowIndex+invWidth)%invWidth;
|
||||||
|
//Get the base row index of the new inventory.
|
||||||
|
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
||||||
|
if(stageLootWindow->GetComponents().size()>0){
|
||||||
|
int rowBaseIndex=(stageLootWindow->GetComponents().back().lock()->inventoryIndex/invWidth)*invWidth;
|
||||||
|
returnData=stageLootWindow->GetComponents()[std::clamp(rowBaseIndex+colIndex,0,int(stageLootWindow->GetComponents().size()-1))];
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
returnData=selectedButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.down=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Down Macros
|
||||||
|
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.front();\
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex+invWidth; /*Moving down moves the cursor down an entire row.*/ \
|
||||||
|
if(newRowIndex>=itemsList.size()){ \
|
||||||
|
int currentRow=newRowIndex/invWidth; \
|
||||||
|
/*The logic here is, if we clamp this row index to the last possible index and we're still on the same row, it means there is at least an item on this row. So we go to that instead.*/ \
|
||||||
|
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
||||||
|
int newRow=newRowIndex/invWidth; \
|
||||||
|
if(currentRow!=newRow) //This means we are on a different row, so the row we went down on didn't have any items. Simply drop down to the OK Button.
|
||||||
|
#define DefaultBehavior \
|
||||||
|
} \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=0;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
int colIndex=newRowIndex%invWidth;
|
||||||
|
//Get the base row index of the new inventory.
|
||||||
|
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
||||||
|
if(stageLootWindow->GetComponents().size()>0){
|
||||||
|
returnData=stageLootWindow->GetComponents()[std::clamp(colIndex,0,int(stageLootWindow->GetComponents().size()-1))];
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
returnData=selectedButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.left=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Left Macros
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.back(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex-1; \
|
||||||
|
if(newRowIndex<rowBaseIndex)
|
||||||
|
#define DefaultBehavior \
|
||||||
|
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
||||||
|
if(newRowIndex<0)newRowIndex+=itemsList.size(); \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
}else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR newRowIndex+=invWidth;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
returnData="Next Button";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.right=[](MenuType type,Data&returnData){
|
||||||
|
#pragma region Inventory Wrapping Handling Right Macros
|
||||||
|
#define DetectInventory(menuClass,menuType,inventoryComponentName) \
|
||||||
|
auto&selection=Menu::menus[menuType]->GetSelection(); \
|
||||||
|
auto&itemsList=Component<menuClass>(menuType,inventoryComponentName)->GetComponents(); \
|
||||||
|
auto itemsWindow=Component<menuClass>(menuType,inventoryComponentName); \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); \
|
||||||
|
if(itemsList.size()>0){ \
|
||||||
|
if(component==itemsList.end()){ \
|
||||||
|
/*Set the selected button to the last element in the list.*/ \
|
||||||
|
returnData=itemsList.front(); \
|
||||||
|
}else{ \
|
||||||
|
int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); \
|
||||||
|
std::weak_ptr<SUBCLASS>selectedButton=DYNAMIC_POINTER_CAST<SUBCLASS>(*component); \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
int newRowIndex=selectedButton.lock()->inventoryIndex+1; \
|
||||||
|
int newRowBaseIndex = (newRowIndex / invWidth) * invWidth; \
|
||||||
|
if(rowBaseIndex!=newRowBaseIndex||newRowIndex>=itemsList.size())
|
||||||
|
#define DefaultBehavior \
|
||||||
|
newRowIndex=std::clamp(newRowIndex,0,int(itemsList.size()-1)); \
|
||||||
|
newRowIndex=std::min(int(itemsList.size())-1,newRowIndex); \
|
||||||
|
if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
/*Select the component that matches this new number.*/ \
|
||||||
|
auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST<SUBCLASS>(comp)->inventoryIndex==newRowIndex;}); \
|
||||||
|
if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); \
|
||||||
|
returnData=*component; \
|
||||||
|
} \
|
||||||
|
}else
|
||||||
|
#define DEFAULT_WRAPPING_BEHAVIOR \
|
||||||
|
int rowBaseIndex=(selectedButton.lock()->inventoryIndex/invWidth)*invWidth; \
|
||||||
|
newRowIndex=rowBaseIndex;
|
||||||
|
#pragma endregion
|
||||||
|
#define SUBCLASS MenuItemButton
|
||||||
|
DetectInventory(InventoryScrollableWindowComponent,type,"Stage Loot Window")
|
||||||
|
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
|
||||||
|
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
|
||||||
|
returnData="Next Button";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DefaultBehavior{ //When nothing is found...
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},}},
|
||||||
|
{"Next Button",{
|
||||||
|
.up=[](MenuType type,Data&returnData){
|
||||||
|
auto monsterLoot=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
||||||
|
auto stageLoot=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
|
||||||
|
if(monsterLoot->GetComponents().size()>0){
|
||||||
|
int invWidth=monsterLoot->GetInventoryWidth();
|
||||||
|
returnData=monsterLoot->GetComponents()[0];
|
||||||
|
}else
|
||||||
|
if(stageLoot->GetComponents().size()>0){
|
||||||
|
int invWidth=stageLoot->GetInventoryWidth();
|
||||||
|
returnData=stageLoot->GetComponents()[0];
|
||||||
|
}else{
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.left=[](MenuType type,Data&returnData){
|
||||||
|
auto monsterLoot=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
||||||
|
auto stageLoot=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
|
||||||
|
if(monsterLoot->GetComponents().size()>0){
|
||||||
|
int invWidth=monsterLoot->GetInventoryWidth();
|
||||||
|
returnData=monsterLoot->GetComponents()[std::clamp(invWidth-1,0,int(monsterLoot->GetComponents().size()-1))];
|
||||||
|
}else
|
||||||
|
if(stageLoot->GetComponents().size()>0){
|
||||||
|
int invWidth=stageLoot->GetInventoryWidth();
|
||||||
|
returnData=stageLoot->GetComponents()[std::clamp(invWidth-1,0,int(stageLoot->GetComponents().size()-1))];
|
||||||
|
}else{
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.right=[](MenuType type,Data&returnData){
|
||||||
|
auto monsterLoot=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
|
||||||
|
auto stageLoot=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
|
||||||
|
if(monsterLoot->GetComponents().size()>0){
|
||||||
|
returnData=monsterLoot->GetComponents()[0];
|
||||||
|
}else
|
||||||
|
if(stageLoot->GetComponents().size()>0){
|
||||||
|
returnData=stageLoot->GetComponents()[0];
|
||||||
|
}else{
|
||||||
|
returnData="Next Button";
|
||||||
|
}
|
||||||
|
},}},
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -49,11 +49,12 @@ enum class ButtonAttr{
|
|||||||
enum class ComponentAttr{
|
enum class ComponentAttr{
|
||||||
NONE= 0b0'0000'0000,
|
NONE= 0b0'0000'0000,
|
||||||
LEFT_ALIGN= 0b0'0000'0001, //Labels are centered by default.
|
LEFT_ALIGN= 0b0'0000'0001, //Labels are centered by default.
|
||||||
SHADOW= 0b0'0000'0010, //Adds shadows to the label text.
|
RIGHT_ALIGN= 0b0'0000'0010, //Labels are centered by default.
|
||||||
OUTLINE= 0b0'0000'0100, //Adds an outline around the component.
|
SHADOW= 0b0'0000'0100, //Adds shadows to the label text.
|
||||||
BACKGROUND= 0b0'0000'1000, //Renders the background of the menu theme for this component.
|
OUTLINE= 0b0'0000'1000, //Adds an outline around the component.
|
||||||
FIT_TO_LABEL= 0b0'0001'0000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
|
BACKGROUND= 0b0'0001'0000, //Renders the background of the menu theme for this component.
|
||||||
FIXED_WIDTH_FONT= 0b0'0010'0000, //Uses a fixed-width font (instead of a proportional one) for text rendering.
|
FIT_TO_LABEL= 0b0'0010'0000, //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
|
||||||
|
FIXED_WIDTH_FONT= 0b0'0100'0000, //Uses a fixed-width font (instead of a proportional one) for text rendering.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SelectionType{
|
enum class SelectionType{
|
||||||
|
@ -49,6 +49,7 @@ protected:
|
|||||||
float scale=1;
|
float scale=1;
|
||||||
bool shadow=false;
|
bool shadow=false;
|
||||||
bool centered=true;
|
bool centered=true;
|
||||||
|
bool rightAlign=false;
|
||||||
bool proportional=true;
|
bool proportional=true;
|
||||||
bool runOnLabelChangeFunc=false;
|
bool runOnLabelChangeFunc=false;
|
||||||
std::function<void(std::string_view newLabel)>onLabelChangeFunc;
|
std::function<void(std::string_view newLabel)>onLabelChangeFunc;
|
||||||
@ -59,7 +60,7 @@ public:
|
|||||||
this->onLabelChangeFunc=onLabelChangeFunc;
|
this->onLabelChangeFunc=onLabelChangeFunc;
|
||||||
}
|
}
|
||||||
inline MenuLabel(geom2d::rect<float>rect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
|
inline MenuLabel(geom2d::rect<float>rect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE)
|
||||||
:MenuComponent(rect,label,MenuFunc{},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD),scale(scale),centered(!(attributes&ComponentAttr::LEFT_ALIGN)),shadow(attributes&ComponentAttr::SHADOW),proportional(!(attributes&ComponentAttr::FIXED_WIDTH_FONT)){
|
:MenuComponent(rect,label,MenuFunc{},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD),scale(scale),rightAlign(attributes&ComponentAttr::RIGHT_ALIGN),centered(!(attributes&ComponentAttr::LEFT_ALIGN)&&!(attributes&ComponentAttr::RIGHT_ALIGN)),shadow(attributes&ComponentAttr::SHADOW),proportional(!(attributes&ComponentAttr::FIXED_WIDTH_FONT)){
|
||||||
border=attributes&ComponentAttr::OUTLINE;
|
border=attributes&ComponentAttr::OUTLINE;
|
||||||
this->background=attributes&ComponentAttr::BACKGROUND;
|
this->background=attributes&ComponentAttr::BACKGROUND;
|
||||||
showDefaultLabel=false;
|
showDefaultLabel=false;
|
||||||
@ -95,7 +96,11 @@ protected:
|
|||||||
|
|
||||||
vf2d drawPos=vf2d{-1,0}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
|
vf2d drawPos=vf2d{-1,0}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
|
||||||
if(!centered){
|
if(!centered){
|
||||||
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
|
if(rightAlign){
|
||||||
|
drawPos=vf2d{rect.pos.x+rect.size.x-labelTextSize.x-2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
|
||||||
|
}else{ //Left Align
|
||||||
|
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shadow){
|
if(shadow){
|
||||||
|
@ -48,7 +48,7 @@ enum MenuType{
|
|||||||
MAIN_MENU, //100% Controller Compatibility
|
MAIN_MENU, //100% Controller Compatibility
|
||||||
OVERWORLD_LEVEL_SELECT, //100% Controller Compatibility - Scrolling for keyboard?
|
OVERWORLD_LEVEL_SELECT, //100% Controller Compatibility - Scrolling for keyboard?
|
||||||
ITEM_LOADOUT, //100% Controller Compatibility
|
ITEM_LOADOUT, //100% Controller Compatibility
|
||||||
LEVEL_COMPLETE, //0% Controller Compatibility
|
LEVEL_COMPLETE, //100% Controller Compatibility
|
||||||
OVERWORLD_MENU, //0% Controller Compatibility
|
OVERWORLD_MENU, //0% Controller Compatibility
|
||||||
CHARACTER_MENU, //0% Controller Compatibility
|
CHARACTER_MENU, //0% Controller Compatibility
|
||||||
INVENTORY, //0% Controller Compatibility
|
INVENTORY, //0% Controller Compatibility
|
||||||
|
@ -52,6 +52,8 @@ All rights reserved.
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include "SoundEffect.h"
|
#include "SoundEffect.h"
|
||||||
#include "olcPGEX_Gamepad.h"
|
#include "olcPGEX_Gamepad.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
|
#include "MenuLabel.h"
|
||||||
|
|
||||||
INCLUDE_MONSTER_DATA
|
INCLUDE_MONSTER_DATA
|
||||||
INCLUDE_MONSTER_LIST
|
INCLUDE_MONSTER_LIST
|
||||||
@ -1213,6 +1215,16 @@ void Player::AddXP(const uint32_t xpGain){
|
|||||||
OnLevelUp();
|
OnLevelUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Component<ProgressBar>(MenuType::CHARACTER_MENU,"XP Bar")->ResetProgressBar(game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SetXP(const uint32_t xp){
|
||||||
|
currentLevelXP=xp;
|
||||||
|
Component<ProgressBar>(MenuType::CHARACTER_MENU,"XP Bar")->ResetProgressBar(game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::SetTotalXPEarned(const uint32_t totalXP){
|
||||||
|
totalXPEarned=totalXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::OnLevelUp(){
|
void Player::OnLevelUp(){
|
||||||
@ -1226,6 +1238,11 @@ const uint8_t Player::LevelCap()const{
|
|||||||
const uint8_t Player::Level()const{
|
const uint8_t Player::Level()const{
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
void Player::SetLevel(uint8_t newLevel){
|
||||||
|
level=newLevel;
|
||||||
|
Component<MenuLabel>(CHARACTER_MENU,"Level Class Display")->SetLabel(std::format("Lv{} {}",game->GetPlayer()->Level(),game->GetPlayer()->GetClassName()));
|
||||||
|
Component<MenuLabel>(LEVEL_COMPLETE,"Level Display")->SetLabel(std::format("Lv{}",game->GetPlayer()->Level()));
|
||||||
|
}
|
||||||
const uint32_t Player::CurrentXP()const{
|
const uint32_t Player::CurrentXP()const{
|
||||||
return currentLevelXP;
|
return currentLevelXP;
|
||||||
}
|
}
|
||||||
@ -1283,16 +1300,10 @@ const vf2d Player::GetAimingLocation(){
|
|||||||
if(gamepad->stillConnected){
|
if(gamepad->stillConnected){
|
||||||
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
|
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
|
||||||
xAxis=gamepad->getAxis(GPAxes::RX);
|
xAxis=gamepad->getAxis(GPAxes::RX);
|
||||||
}else
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::LX))>0.f){
|
|
||||||
xAxis=gamepad->getAxis(GPAxes::LX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
|
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
|
||||||
yAxis=gamepad->getAxis(GPAxes::RY);
|
yAxis=gamepad->getAxis(GPAxes::RY);
|
||||||
}else
|
|
||||||
if(fabs(gamepad->getAxis(GPAxes::LY))>0.f){
|
|
||||||
yAxis=gamepad->getAxis(GPAxes::LY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
|
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
|
||||||
|
@ -91,7 +91,6 @@ class Player{
|
|||||||
friend class State_GameRun;
|
friend class State_GameRun;
|
||||||
friend class Inventory;
|
friend class Inventory;
|
||||||
friend void ItemOverlay::Draw();
|
friend void ItemOverlay::Draw();
|
||||||
friend class SaveFile;
|
|
||||||
public:
|
public:
|
||||||
Player();
|
Player();
|
||||||
//So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class
|
//So this is rather fascinating and only exists because we have the ability to change classes which means we need to initialize a class
|
||||||
@ -241,6 +240,9 @@ public:
|
|||||||
void Knockup(float duration);
|
void Knockup(float duration);
|
||||||
const vf2d GetAimingLocation();
|
const vf2d GetAimingLocation();
|
||||||
const vf2d GetWorldAimingLocation();
|
const vf2d GetWorldAimingLocation();
|
||||||
|
void SetXP(const uint32_t xp);
|
||||||
|
void SetTotalXPEarned(const uint32_t totalXP);
|
||||||
|
void SetLevel(uint8_t newLevel);
|
||||||
private:
|
private:
|
||||||
int hp="Warrior.BaseHealth"_I;
|
int hp="Warrior.BaseHealth"_I;
|
||||||
int mana="Player.BaseMana"_I;
|
int mana="Player.BaseMana"_I;
|
||||||
|
90
Adventures in Lestoria/ProgressBar.h
Normal file
90
Adventures in Lestoria/ProgressBar.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#pragma region License
|
||||||
|
/*
|
||||||
|
License (OLC-3)
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||||||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||||||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without specific
|
||||||
|
prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
Portions of this software are copyright © 2024 The FreeType
|
||||||
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MenuComponent.h"
|
||||||
|
#include "DEFINES.h"
|
||||||
|
|
||||||
|
INCLUDE_GFX
|
||||||
|
INCLUDE_game
|
||||||
|
|
||||||
|
class ProgressBar:public MenuComponent{
|
||||||
|
Pixel backCol;
|
||||||
|
Pixel textCol;
|
||||||
|
int currentProgress;
|
||||||
|
int finalProgress;
|
||||||
|
std::string subText;
|
||||||
|
public:
|
||||||
|
inline ProgressBar(geom2d::rect<float>rect,Pixel backCol,Pixel textCol,int currentProgress,int finalProgress,std::string subText)
|
||||||
|
:MenuComponent::MenuComponent(rect,"",DO_NOTHING,ButtonAttr::UNSELECTABLE),backCol(backCol),textCol(textCol),currentProgress(currentProgress),finalProgress(finalProgress),subText(subText){}
|
||||||
|
inline void UpdateProgressBar(int newProgress){
|
||||||
|
currentProgress=newProgress;
|
||||||
|
}
|
||||||
|
inline void ResetProgressBar(int currentProgress,int finalProgress){
|
||||||
|
this->currentProgress=currentProgress;
|
||||||
|
this->finalProgress=finalProgress;
|
||||||
|
}
|
||||||
|
inline const int GetCurrentProgress()const{
|
||||||
|
return currentProgress;
|
||||||
|
}
|
||||||
|
inline const int GetFinalProgress()const{
|
||||||
|
return finalProgress;
|
||||||
|
}
|
||||||
|
inline void SetSubText(std::string subText){
|
||||||
|
this->subText=subText;
|
||||||
|
}
|
||||||
|
inline virtual void DrawDecal(ViewPort&window,bool focused)override final{
|
||||||
|
|
||||||
|
float barPct=float(currentProgress)/float(finalProgress);
|
||||||
|
vf2d barSize=rect.size-vf2d{2.f,2.f};
|
||||||
|
Pixel lighterCol=backCol;
|
||||||
|
lighterCol.r=std::min(255U,lighterCol.r+30U);
|
||||||
|
lighterCol.g=std::min(255U,lighterCol.g+30U);
|
||||||
|
lighterCol.b=std::min(255U,lighterCol.b+30U);
|
||||||
|
window.GradientFillRectDecal(rect.pos+vf2d{1.f,1.f},vf2d{barPct*barSize.x,barSize.y},lighterCol,backCol,backCol,lighterCol);
|
||||||
|
window.GradientFillRectDecal(rect.pos+vf2d{(barPct*(barSize)).x+1.f,2.f},vf2d{1.f,barSize.y-2.f},lighterCol,backCol,backCol,lighterCol);
|
||||||
|
|
||||||
|
window.DrawPartialDecal(rect.pos,vf2d{2.f,rect.size.y},GFX["xpbar.png"].Decal(),vf2d{0.f,0.f},vf2d{2.f,8.f},WHITE);
|
||||||
|
window.DrawPartialDecal(rect.pos+vf2d{2.f,0.f},vf2d{rect.size.x-4.f,rect.size.y},GFX["xpbar.png"].Decal(),vf2d{2.f,0.f},vf2d{1.f,8.f},WHITE);
|
||||||
|
window.DrawPartialDecal(rect.pos+vf2d{rect.size.x-2.f,0.f},vf2d{2.f,rect.size.y},GFX["xpbar.png"].Decal(),vf2d{3.f,0.f},vf2d{2.f,8.f},WHITE);
|
||||||
|
|
||||||
|
std::string barText=std::format("{}/{}{}",currentProgress,finalProgress,subText);
|
||||||
|
vf2d textSize=game->GetTextSizeProp(barText);
|
||||||
|
window.DrawShadowStringPropDecal(rect.pos+rect.size/2.f-textSize/2.f,barText);
|
||||||
|
}
|
||||||
|
};
|
@ -253,10 +253,10 @@ void SaveFile::LoadFile(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString()));
|
game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString()));
|
||||||
game->GetPlayer()->level=loadFile["Player"]["Level"].GetInt();
|
game->GetPlayer()->SetLevel(loadFile["Player"]["Level"].GetInt());
|
||||||
game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt());
|
game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt());
|
||||||
game->GetPlayer()->currentLevelXP=loadFile["Player"]["Current EXP"].GetInt();
|
game->GetPlayer()->SetXP(loadFile["Player"]["Current EXP"].GetInt());
|
||||||
game->GetPlayer()->totalXPEarned=loadFile["Player"]["Total EXP"].GetInt();
|
game->GetPlayer()->SetTotalXPEarned(loadFile["Player"]["Total EXP"].GetInt());
|
||||||
for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){
|
for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){
|
||||||
game->GetPlayer()->SetBaseStat(key,data.GetReal());
|
game->GetPlayer()->SetBaseStat(key,data.GetReal());
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ All rights reserved.
|
|||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "MenuLabel.h"
|
#include "MenuLabel.h"
|
||||||
#include "SaveFile.h"
|
#include "SaveFile.h"
|
||||||
|
#include "ProgressBar.h"
|
||||||
|
|
||||||
INCLUDE_MONSTER_LIST
|
INCLUDE_MONSTER_LIST
|
||||||
INCLUDE_game
|
INCLUDE_game
|
||||||
@ -50,6 +51,7 @@ void State_LevelComplete::OnStateChange(GameState*prevState){
|
|||||||
Menu::CloseAllMenus();
|
Menu::CloseAllMenus();
|
||||||
}
|
}
|
||||||
Component<MenuLabel>(MenuType::LEVEL_COMPLETE,"Level EXP Gain Outline")->SetLabel(std::format("+{} Exp",game->GetPlayer()->GetAccumulatedXP()));
|
Component<MenuLabel>(MenuType::LEVEL_COMPLETE,"Level EXP Gain Outline")->SetLabel(std::format("+{} Exp",game->GetPlayer()->GetAccumulatedXP()));
|
||||||
|
Component<ProgressBar>(MenuType::LEVEL_COMPLETE,"XP Bar")->ResetProgressBar(game->GetPlayer()->CurrentXP(),game->GetPlayer()->NextLevelXPRequired());
|
||||||
game->GetPlayer()->AddXP(game->GetPlayer()->GetAccumulatedXP());
|
game->GetPlayer()->AddXP(game->GetPlayer()->GetAccumulatedXP());
|
||||||
for(const ItemMapData&data:game->GetCurrentMap().GetStageLoot()){
|
for(const ItemMapData&data:game->GetCurrentMap().GetStageLoot()){
|
||||||
uint8_t amountDiff=data.maxAmt-data.minAmt;
|
uint8_t amountDiff=data.maxAmt-data.minAmt;
|
||||||
|
@ -34,3 +34,5 @@ January 31st
|
|||||||
- Save window position and size
|
- Save window position and size
|
||||||
|
|
||||||
- Fullscreen toggle
|
- Fullscreen toggle
|
||||||
|
|
||||||
|
- Condense stage track (loading times)
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 7010
|
#define VERSION_BUILD 7041
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -115,10 +115,10 @@ void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){
|
|||||||
m.target=m.path.GetSplinePoint(m.pathIndex).pos;
|
m.target=m.path.GetSplinePoint(m.pathIndex).pos;
|
||||||
geom2d::line<float>moveTowardsLine=geom2d::line(m.pos,m.path.GetSplinePoint(m.pathIndex).pos);
|
geom2d::line<float>moveTowardsLine=geom2d::line(m.pos,m.path.GetSplinePoint(m.pathIndex).pos);
|
||||||
|
|
||||||
if(moveTowardsLine.length()>4.f){
|
if(moveTowardsLine.length()>1.f){
|
||||||
m.UpdateFacingDirection(moveTowardsLine.end);
|
m.UpdateFacingDirection(moveTowardsLine.end);
|
||||||
|
m.SetPos(m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult());
|
||||||
}
|
}
|
||||||
m.SetPos(m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult());
|
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="148" height="131" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="68">
|
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="148" height="131" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="68">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
|
||||||
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
|
||||||
@ -415,7 +415,7 @@
|
|||||||
</layer>
|
</layer>
|
||||||
<objectgroup id="5" name="Spawn Zones">
|
<objectgroup id="5" name="Spawn Zones">
|
||||||
<object id="1" name="Player Spawn" type="PlayerSpawnLocation" x="96" y="360" width="24" height="24"/>
|
<object id="1" name="Player Spawn" type="PlayerSpawnLocation" x="96" y="360" width="24" height="24"/>
|
||||||
<object id="2" name="End Zone" type="EndZone" x="3191" y="1507" width="120" height="120"/>
|
<object id="2" name="End Zone" type="EndZone" x="77.8813" y="303.88" width="120" height="120"/>
|
||||||
<object id="3" name="Spawn Group 1" type="SpawnGroup" x="670" y="157" width="506" height="492">
|
<object id="3" name="Spawn Group 1" type="SpawnGroup" x="670" y="157" width="506" height="492">
|
||||||
<ellipse/>
|
<ellipse/>
|
||||||
</object>
|
</object>
|
||||||
|
@ -71,6 +71,7 @@ Images
|
|||||||
GFX_Exclamation = exclamation.png
|
GFX_Exclamation = exclamation.png
|
||||||
GFX_Ursule2 = monsters/Ursule Mother of Bears2.png
|
GFX_Ursule2 = monsters/Ursule Mother of Bears2.png
|
||||||
GFX_Wisp = wisp.png
|
GFX_Wisp = wisp.png
|
||||||
|
GFX_XPBar = xpbar.png
|
||||||
|
|
||||||
# Ability Icons
|
# Ability Icons
|
||||||
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png
|
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png
|
||||||
|
BIN
Adventures in Lestoria/assets/xpbar.png
Normal file
BIN
Adventures in Lestoria/assets/xpbar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 554 B |
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user