Added XP bar animations and steady increasing progress bar. Added level up animation text on stage completion screen. Refactor enable and disable functions for menu components. Differentiated between disabling due to being outside the window, and manual enable/disabling of components. Fix infinite loop bug with components outside of a scrollable window component not being iterated over. Fix bug with hovering over non-navigational components causing the default component for a menu to be selected while in mouse navigation mode. Release Build 7095.

pull/35/head
sigonasr2 12 months ago
parent 22b1557c05
commit 8afd66632a
  1. 3
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 10
      Adventures in Lestoria/BlacksmithCraftingWindow.cpp
  3. 44
      Adventures in Lestoria/CharacterMenuWindow.cpp
  4. 4
      Adventures in Lestoria/ClassSelectionWindow.cpp
  5. 6
      Adventures in Lestoria/DynamicCounter.cpp
  6. 4
      Adventures in Lestoria/GameState.cpp
  7. 1
      Adventures in Lestoria/GameState.h
  8. 8
      Adventures in Lestoria/InventoryWindow.cpp
  9. 12
      Adventures in Lestoria/LevelCompleteWindow.cpp
  10. 4
      Adventures in Lestoria/LoadGameWindow.cpp
  11. 23
      Adventures in Lestoria/Menu.cpp
  12. 36
      Adventures in Lestoria/MenuComponent.cpp
  13. 12
      Adventures in Lestoria/MenuComponent.h
  14. 8
      Adventures in Lestoria/MenuItemButton.h
  15. 8
      Adventures in Lestoria/MenuItemItemButton.h
  16. 28
      Adventures in Lestoria/MerchantWindow.cpp
  17. 2
      Adventures in Lestoria/Player.cpp
  18. 8
      Adventures in Lestoria/RowItemDisplay.h
  19. 50
      Adventures in Lestoria/ScrollableWindowComponent.h
  20. 2
      Adventures in Lestoria/Slider.h
  21. 37
      Adventures in Lestoria/State_LevelComplete.cpp
  22. 5
      Adventures in Lestoria/State_LevelComplete.h
  23. 18
      Adventures in Lestoria/State_OverworldMap.cpp
  24. 2
      Adventures in Lestoria/Version.h
  25. 2
      Adventures in Lestoria/assets/Campaigns/1_B1.tmx
  26. 6
      Adventures in Lestoria/assets/config/Interface.txt
  27. 5
      Adventures in Lestoria/assets/config/audio/events.txt
  28. BIN
      Adventures in Lestoria/assets/sounds/levelup.ogg
  29. BIN
      x64/Release/Adventures in Lestoria.exe

@ -304,6 +304,7 @@ bool AiL::OnUserUpdate(float fElapsedTime){
RenderWorld(GetElapsedTime());
GameState::STATE->Draw(this);
RenderMenu();
GameState::STATE->DrawOverlay(this);
RenderFadeout();
RenderVersionInfo();
#ifndef __EMSCRIPTEN__
@ -3053,7 +3054,7 @@ void AiL::UpdateDiscordStatus(std::string levelName,std::string className){
if(levelName!="Main Menu"){
newActivity.SetState(std::format("Level {} {}",player->Level(),className).c_str());
assets.SetSmallText(std::format("Level {} {}",player->Level(),className).c_str());
assets.SetSmallText(std::format("{} the {}",SaveFile::GetSaveFileName(),className).c_str());
std::for_each(className.begin(),className.end(),[](char&c){c=std::tolower(c);});
assets.SetSmallImage(("nico-"+className+"_512").c_str());
}

@ -74,8 +74,8 @@ void Menu::InitializeBlacksmithCraftingWindow(){
auto weaponTab=blacksmithWindow->ADD("Weapon Tab",MenuComponent)(geom2d::rect<float>{{2,0},{blacksmithWindow->size.x/2-4,24}},"Weapon",[](MenuFuncData data){
Component<MenuComponent>(BLACKSMITH,"Armor Tab")->selected=false;
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Weapon Inventory Display")->Enable(true);
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Armor Inventory Display")->Enable(false);
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Weapon Inventory Display")->Enable();
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Armor Inventory Display")->Disable();
data.component.lock()->selected=true;
return true;
})END;
@ -83,8 +83,8 @@ void Menu::InitializeBlacksmithCraftingWindow(){
weaponTab->selectionType=SelectionType::HIGHLIGHT;
auto armorTab=blacksmithWindow->ADD("Armor Tab",MenuComponent)(geom2d::rect<float>{{blacksmithWindow->size.x/2+2,0},{blacksmithWindow->size.x/2-4,24}},"Armor",[](MenuFuncData data){
Component<MenuComponent>(BLACKSMITH,"Weapon Tab")->selected=false;
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Weapon Inventory Display")->Enable(false);
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Armor Inventory Display")->Enable(true);
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Weapon Inventory Display")->Disable();
Component<RowInventoryScrollableWindowComponent>(BLACKSMITH,"Armor Inventory Display")->Enable();
data.component.lock()->selected=true;
return true;
})END;
@ -175,7 +175,7 @@ void Menu::InitializeBlacksmithCraftingWindow(){
InventoryCreator::RowPlayerArmor_InventoryUpdate,
InventoryWindowOptions{.padding=1,.size={207,28}}
)END;
armorDisplay->Enable(false);
armorDisplay->Disable();
armorDisplay->SetCompactDescriptions(CRAFTING_INFO);
#pragma endregion

@ -78,18 +78,18 @@ void Menu::InitializeCharacterMenuWindow(){
characterMenuWindow->ADD("Equip Selection Outline",MenuComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END
->Enable(false);
->Disable();
characterMenuWindow->ADD("Equip List",ScrollableWindowComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37-24}})DEPTH -1 END
->Enable(false);
->Disable();
characterMenuWindow->ADD("Equip Selection Bottom Outline",MenuComponent)(geom2d::rect<float>{{123,28+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END
->Enable(false);
->Disable();
auto equipSelectionSelectButton=characterMenuWindow->ADD("Equip Selection Select Button",MenuComponent)(geom2d::rect<float>{{123+12,28+(windowSize.y-37-24)+6},{96,12}},"Select",
[](MenuFuncData data){
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Outline")->Enable(false);
Component<ScrollableWindowComponent>(data.component.lock()->parentMenu,"Equip List")->Enable(false);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Enable(false);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Enable(false);
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable(true);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Outline")->Disable();
Component<ScrollableWindowComponent>(data.component.lock()->parentMenu,"Equip List")->Disable();
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Disable();
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Disable();
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable();
for(int counter=0;const std::string&attribute:displayAttrs){
std::weak_ptr<StatLabel>statDisplayLabel=Component<StatLabel>(CHARACTER_MENU,"Attribute "+std::string(ItemAttribute::Get(attribute).Name())+" Label");
statDisplayLabel.lock()->SetStatChangeAmt(0);
@ -98,7 +98,7 @@ void Menu::InitializeCharacterMenuWindow(){
return true;
})DEPTH 0 END;
equipSelectionSelectButton->Enable(false);
equipSelectionSelectButton->Disable();
const static auto GetLabelText=[](ItemAttribute attribute){
std::string attrStr=std::string(attribute.Name())+":\n ";
@ -233,26 +233,26 @@ void Menu::InitializeCharacterMenuWindow(){
counter++;
}
equipList->I(Attribute::INDEXED_THEME)=data.component.lock()->I(Attribute::INDEXED_THEME);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Outline")->Enable(true);
equipList->Enable(true);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Enable(true);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Enable(true);
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable(false);
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Outline")->Enable();
equipList->Enable();
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Bottom Outline")->Enable();
Component<MenuComponent>(data.component.lock()->parentMenu,"Equip Selection Select Button")->Enable();
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Disable();
equipmentWindowOpened=true;
return true;
},[](MenuFuncData data){//On Mouse Hover
EquipSlot slot=DYNAMIC_POINTER_CAST<EquipSlotButton>(data.component.lock())->GetSlot();
const std::weak_ptr<Item>equip=Inventory::GetEquip(slot);
if(!ISBLANK(equip)){
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable(false);
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Disable();
}
return true;
},[](MenuFuncData data){//On Mouse Out
if(!equipmentWindowOpened){
Component<MenuLabel>(data.component.lock()->parentMenu,"Item Equip Description")->SetLabel("");
Component<MenuLabel>(data.component.lock()->parentMenu,"Item Equip Name")->Enable(false);
Component<MenuLabel>(data.component.lock()->parentMenu,"Item Equip Description")->Enable(false);
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable(true);
Component<MenuLabel>(data.component.lock()->parentMenu,"Item Equip Name")->Disable();
Component<MenuLabel>(data.component.lock()->parentMenu,"Item Equip Description")->Disable();
Component<CharacterRotatingDisplay>(data.component.lock()->parentMenu,"Character Rotating Display")->Enable();
}
return true;
},"Item Equip Name","Item Equip Description")END;
@ -283,8 +283,8 @@ void Menu::InitializeCharacterMenuWindow(){
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;
itemNameDisplay->Enable(false);
itemDescriptionDisplay->Enable(false);
itemEquipNameDisplay->Enable(false);
itemEquipDescriptionDisplay->Enable(false);
itemNameDisplay->Disable();
itemDescriptionDisplay->Disable();
itemEquipNameDisplay->Disable();
itemEquipDescriptionDisplay->Disable();
}

@ -92,7 +92,7 @@ void Menu::InitializeClassSelectionWindow(){
#endif
return true;
})END
->disabled=true;
->Disable();
vf2d buttonPadding={2,2};
vf2d buttonSize={floor(outlineSize.y/3-buttonPadding.y*3),outlineSize.y/9-buttonPadding.y*3}; //The floor is for fixing a small pixel rounding bug.
@ -146,7 +146,7 @@ void Menu::InitializeClassSelectionWindow(){
classSelectionWindow->ADD(className+" Label",MenuLabel)(geom2d::rect<float>{backgroundOffsetPos,buttonSize},className,1,ComponentAttr::SHADOW)END;
auto classSprite=classSelectionWindow->ADD(className+" Icon",MenuAnimatedIconToggleButton)(geom2d::rect<float>{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){
data.menu.components["Confirm"]->Enable(true);
data.menu.components["Confirm"]->Enable();
data.menu.components["Confirm"]->S(A::CLASS_SELECTION)=data.component.lock()->S(A::CLASS_SELECTION);
return true;
})END;

@ -66,14 +66,16 @@ void DynamicCounter::Update(){
tickTimer-=tickRate;
if(displayNumber!=int(*targetNumber)){
if(displayNumber>int(*targetNumber)){
displayNumber--;
int incrementAmt=int(abs(*targetNumber-displayNumber)/(1/tickRate))+1;
displayNumber=std::max(displayNumber-incrementAmt,*targetNumber);
if(targetNumberChanged){
adjustedCol=decreaseCol;
targetChangedTimer=colorChangeTime;
}
}else{
displayNumber++;
int incrementAmt=int(abs(*targetNumber-displayNumber)/(1/tickRate))+1;
displayNumber=std::min(displayNumber+incrementAmt,*targetNumber);
if(targetNumberChanged){
adjustedCol=increaseCol;

@ -82,4 +82,6 @@ GameState::~GameState(){}
void GameState::GetAnyKeyPress(Key k){}
void GameState::GetAnyKeyRelease(Key k){}
void GameState::GetAnyMousePress(int32_t mouseButton){}
void GameState::GetAnyMouseRelease(int32_t mouseButton){}
void GameState::GetAnyMouseRelease(int32_t mouseButton){}
void GameState::DrawOverlay(AiL*game){};

@ -67,6 +67,7 @@ public:
virtual void OnStateChange(GameState*prevState)=0;
virtual void OnUserUpdate(AiL*game)=0;
virtual void Draw(AiL*game)=0;
virtual void DrawOverlay(AiL*game);
virtual void GetAnyKeyPress(Key k);
virtual void GetAnyKeyRelease(Key k);
virtual void GetAnyMousePress(int32_t mouseButton);

@ -78,9 +78,9 @@ void Menu::InitializeInventoryWindow(){
auto button=inventoryWindow->ADD(category+" Inventory Tab",MenuComponent)(geom2d::rect<float>{{2,30+yOffset},{68,16}},category,MenuType::ENUM_END,
[&](MenuFuncData data){
//Close the old inventory window and show the proper one.
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Enable(false);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Disable();
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->SetSelected(false);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component.lock()->S(A::CATEGORY_NAME))->Enable(true);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component.lock()->S(A::CATEGORY_NAME))->Enable();
Component<MenuComponent>(data.menu.GetType(),data.component.lock()->S(A::CATEGORY_NAME)+" Inventory Tab")->SetSelected(true);
data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)=data.component.lock()->S(A::CATEGORY_NAME);
return true;
@ -103,10 +103,12 @@ void Menu::InitializeInventoryWindow(){
if(first){
inventoryWindow->S(A::LAST_INVENTORY_TYPE_OPENED)=category;
button->onClick(MenuFuncData{*inventoryWindow,game,button}); //Simulate a click of this button if it's the top one for an initial inventory display.
inventoryDisplay->Enable();
}else{
inventoryDisplay->Disable();
}
Menu::AddInventoryListener(inventoryDisplay,category);
inventoryDisplay->Enable(first);
inventoryDisplay->SetCompactDescriptions(NON_COMPACT);
yOffset+=20;

@ -115,7 +115,9 @@ void Menu::InitializeLevelCompleteWindow(){
}
}}},
{game->KEY_SCROLL,{"View Items",[](MenuType type){}}},
{game->KEY_START,{"Continue",[](MenuType type){}}},
{game->KEY_START,{"Continue",[](MenuType type){
Component<MenuComponent>(type,"Next Button")->Click();
}}},
}
,{ //Button Navigation Rules
{"Monster Loot Window",{
@ -152,7 +154,7 @@ void Menu::InitializeLevelCompleteWindow(){
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.
int colIndex=selectedButton.lock()->inventoryIndex; //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){
@ -205,7 +207,7 @@ void Menu::InitializeLevelCompleteWindow(){
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;
int colIndex=selectedButton.lock()->inventoryIndex;
//Get the base row index of the new inventory.
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Stage Loot Window");
if(stageLootWindow->GetComponents().size()>0){
@ -336,7 +338,7 @@ void Menu::InitializeLevelCompleteWindow(){
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;
int colIndex=selectedButton.lock()->inventoryIndex;
//Get the base row index of the new inventory.
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
if(stageLootWindow->GetComponents().size()>0){
@ -389,7 +391,7 @@ void Menu::InitializeLevelCompleteWindow(){
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;
int colIndex=selectedButton.lock()->inventoryIndex;
//Get the base row index of the new inventory.
auto stageLootWindow=Component<InventoryScrollableWindowComponent>(type,"Monster Loot Window");
if(stageLootWindow->GetComponents().size()>0){

@ -46,9 +46,9 @@ void Menu::InitializeLoadGameWindow(){
loadGameWindow->ADD("Game Files Label",MenuLabel)(geom2d::rect<float>{{-8,-12},{208,12}},"Load Game",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
loadGameWindow->ADD("Game Files List",ScrollableWindowComponent)(geom2d::rect<float>{{40,24},{112,116}})END
->Enable(true);
->Enable();
loadGameWindow->ADD("Online Game Files List",ScrollableWindowComponent)(geom2d::rect<float>{{40,24},{112,116}})END
->Enable(false);
->Disable();
loadGameWindow->ADD("Go Back Button",MenuComponent)(geom2d::rect<float>{{72,148},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END;
#ifdef __EMSCRIPTEN__
auto offlineCharacterTab = loadGameWindow->ADD("Offline Character Tab",MenuComponent)(geom2d::rect<float>{{-8,4},{102,16}},"Offline Characters",[](MenuFuncData data){

@ -132,7 +132,7 @@ void Menu::CheckClickAndPerformMenuSelect(AiL*game){
}
void Menu::HoverMenuSelect(AiL*game){
if(!game->IsFocused()||selection.expired()||selection.lock()->disabled||selection.lock()->grayedOut||Menu::alreadyClicked||Menu::scrolling)return;
if(!game->IsFocused()||selection.expired()||selection.lock()->disable||selection.lock()->disableOutsideWindow||selection.lock()->grayedOut||Menu::alreadyClicked||Menu::scrolling)return;
if(selection.lock()->draggable){
if(buttonHoldTime<"ThemeGlobal.MenuHoldTime"_F){
@ -147,7 +147,7 @@ void Menu::HoverMenuSelect(AiL*game){
}
void Menu::MenuSelect(AiL*game){
if(!game->IsFocused()||selection.expired()||selection.lock()->disabled||selection.lock()->grayedOut)return;
if(!game->IsFocused()||selection.expired()||selection.lock()->disable||selection.lock()->disableOutsideWindow||selection.lock()->grayedOut)return;
bool buttonStillValid=selection.lock()->onClick(MenuFuncData{*this,game,selection,dynamic_pointer_cast<ScrollableWindowComponent>(selection.lock()->parentComponent.lock())});
if(buttonStillValid){
if(selection.lock()->menuDest!=MenuType::ENUM_END){
@ -170,7 +170,7 @@ void Menu::Update(AiL*game){
}
for(auto&[key,button]:components){
if(!button->disabled){
if(!button->disable||!button->disableOutsideWindow){
button->hovered=false;
}
}
@ -186,7 +186,7 @@ void Menu::Update(AiL*game){
selection={};
for(auto&[key,component]:components){
if(component->selectable){
if(!component->disabled&&!component->grayedOut){
if(!component->disable&&!component->disableOutsideWindow&&!component->grayedOut){
if(component->GetHoverState(game)){
component->hovered=true;
itemHovered=true;
@ -338,6 +338,8 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
}
}
if(!selection.expired()){
const int MAX_ITERATIONS=10; //Skip a maximum amount of items in case everything gets disabled somehow, prevents an infinite loop.
int iterationCount=0;
do{
if(navigationGroups.size()==0)break; //We don't do anything here when there are no navigation groups.
std::string selectionButtonName=selection.lock()->GetName();
@ -386,10 +388,15 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
SetSelection(returnData);
}
}
}else{
}else
if(!Menu::UsingMouseNavigation()){
if(std::holds_alternative<ButtonName>(defaultButton)&&std::get<ButtonName>(defaultButton).length()>0||std::holds_alternative<std::weak_ptr<MenuComponent>>(defaultButton))SetSelection(defaultButton,true);
}else{
break; //There's no reason to be doing anything here if we navigate with the mouse.
}
}while(selection.lock()->disabled||selection.lock()->grayedOut);
iterationCount++;
if(iterationCount==MAX_ITERATIONS)ERR("WARNING! We've entered the max iteration count of automatic Menu navigation! THIS LIKELY MEANS WE'VE DONE SOMETHING TERRIBLY WRONG!");
}while(iterationCount<MAX_ITERATIONS&&(selection.lock()->grayedOut||selection.lock()->disable));
}
if(game->KEY_UP.Released()||game->KEY_RIGHT.Released()||game->KEY_LEFT.Released()||game->KEY_DOWN.Released()||
@ -399,7 +406,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
buttonHoldTime=0;
}
if(&*prevSelection.lock()!=&*selection.lock()){
if(!selection.expired()&&(selection.lock()->disabled||selection.lock()->grayedOut)){
if(!selection.expired()&&selection.lock()->disableOutsideWindow){
bool handled=false;
if(!UsingMouseNavigation()){
//Let's transfer some information about our selection being off the screen. Our intention with keyboard controls is that the screen will scroll to the correct location instead.
@ -500,7 +507,7 @@ Pixel Menu::GetRenderColor(){
}
bool Menu::HandleOutsideDisabledButtonSelection(std::weak_ptr<MenuComponent>disabledButton){
if(!disabledButton.expired()){
if(!disabledButton.expired()&&!disabledButton.lock()->parentComponent.expired()){
return disabledButton.lock()->parentComponent.lock()->HandleOutsideDisabledButtonSelection(disabledButton);
}else{
return false;

@ -80,7 +80,7 @@ void MenuComponent::Update(AiL*game){
}
void MenuComponent::_Update(AiL*game){
if(!disabled){
if(!disable&&!disableOutsideWindow){
_OnHover();
Update(game);
}
@ -130,7 +130,7 @@ void MenuComponent::DrawDecal(ViewPort&window,bool focused){
}
void MenuComponent::_DrawDecal(ViewPort&window,bool focused){
if(!disabled){
if(!disable&&!disableOutsideWindow){
DrawDecal(window,focused);
}
}
@ -188,8 +188,20 @@ const std::string&MenuComponent::GetLabel()const{
return label;
}
void MenuComponent::Enable(bool enabled){
disabled=!enabled;
void MenuComponent::Enable(){
disable=false;
};
void MenuComponent::Disable(){
disable=true;
};
void MenuComponent::EnableOutsideWindow(){
disableOutsideWindow=false;
};
void MenuComponent::DisableOutsideWindow(){
disableOutsideWindow=true;
};
void MenuComponent::Cleanup(){}
@ -248,7 +260,7 @@ void MenuComponent::OnPlayerMoneyUpdate(uint32_t newMoney){}
void MenuComponent::OnChapterUpdate(uint8_t newChapter){}
void MenuComponent::Click(){
if(grayedOut||disabled)return;
if(grayedOut||disable||disableOutsideWindow)return;
bool buttonStillValid=onClick(MenuFuncData{*Menu::menus[parentMenu],game,Menu::menus[parentMenu]->components[name]});
if(buttonStillValid){
if(menuDest!=MenuType::ENUM_END){
@ -263,4 +275,18 @@ void MenuComponent::Click(){
}
void MenuComponent::SetLabel(std::string newLabel){
label=newLabel;
}
const bool MenuComponent::IsEnabled()const{
return !IsDisabled();
}
const bool MenuComponent::IsDisabled()const{
return disable;
}
const bool MenuComponent::IsEnabledOutsideWindow()const{
return !IsDisabledOutsideWindow();
}
const bool MenuComponent::IsDisabledOutsideWindow()const{
return disableOutsideWindow;
}

@ -94,6 +94,8 @@ private:
void _OnMouseOut();
void _OnHover();
SelectionType selectionType=CROSSHAIR;
bool disableOutsideWindow=false; //If set to true, this component was automatically set to not be renderable outside the window.
bool disable=false; //If set to true, this component will not be rendered or updated.
protected:
int depth=0;
float hoverEffect=0;
@ -110,7 +112,6 @@ protected:
bool selectable=true;
bool selectableViaKeyboard=true;
bool selected=false;
bool disabled=false; //If set to true, this component will not be rendered or updated.
bool renderInMain=true; //If set to false, this component is the responsibility of some other windowing system and won't be rendered or updated via the main window loop.
bool valid=true; //If set to false, this would cause the component to be removed.
bool fitToLabel=false; //Will shrink text horizontally to fit the size of the label if the display text is too large.
@ -128,6 +129,10 @@ protected:
virtual bool PointWithinParent(MenuComponent*child,geom2d::rect<float> drawRect);
virtual void OnMouseOut();
virtual void OnHover();
virtual void EnableOutsideWindow();
virtual void DisableOutsideWindow();
const bool IsEnabledOutsideWindow()const;
const bool IsDisabledOutsideWindow()const;
public:
MenuType parentMenu=MenuType::ENUM_END;
std::weak_ptr<ScrollableWindowComponent>parentComponent{};
@ -150,7 +155,10 @@ public:
std::string GetName();
virtual void SetSelected(bool selected)final;
virtual void SetSelectionType(SelectionType selectionType)final;
virtual void Enable(bool enabled);
virtual void Enable();
virtual void Disable();
const bool IsEnabled()const;
const bool IsDisabled()const;
virtual void Cleanup();
virtual void SetHoverFunc(std::function<bool(MenuFuncData)>func);
virtual void SetMouseOutFunc(std::function<bool(MenuFuncData)>func);

@ -97,10 +97,10 @@ public:
protected:
virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Disable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Disable();
}
}
void UpdateLabel(){
@ -118,11 +118,11 @@ protected:
}
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText;
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable();
}
}
virtual inline void OnHover()override{

@ -106,10 +106,10 @@ public:
protected:
virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Disable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Disable();
}
}
virtual inline void OnHover()override{
@ -135,11 +135,11 @@ protected:
}
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText;
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable();
}
}
virtual inline void Update(AiL*game)override{

@ -62,15 +62,15 @@ void Menu::InitializeMerchantWindow(){
std::sort(categories.begin(),categories.end(),[](std::pair<std::string,int>&cat1,std::pair<std::string,int>&cat2){return cat1.second<cat2.second;});
auto buyTab=merchantWindow->ADD("Buy Tab",MenuComponent)(geom2d::rect<float>{{2,0},{merchantWindow->size.x/2-4,24}},"Buy",[](MenuFuncData data){
Component<RowInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Enable(true);
Component<RowInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Enable();
Component<MenuComponent>(MERCHANT,"Sell Tab")->selected=false;
Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Enable(false);
Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Disable();
for(auto&[category,items]:ITEM_CATEGORIES){
if(DATA["ItemCategory"][category].GetString(0)=="!HIDE")continue; //This category is meant to be hidden!
Component<MenuComponent>(MERCHANT,category+" Inventory Tab")->Enable(false);
Component<MenuComponent>(MERCHANT,category+" Inventory Tab")->Disable();
}
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Enable(false);
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->Enable(false);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Disable();
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->Disable();
data.component.lock()->selected=true;
return true;
})END;
@ -78,15 +78,15 @@ void Menu::InitializeMerchantWindow(){
buyTab->selectionType=SelectionType::HIGHLIGHT;
auto sellTab=merchantWindow->ADD("Sell Tab",MenuComponent)(geom2d::rect<float>{{merchantWindow->size.x/2+2,0},{merchantWindow->size.x/2-4,24}},"Sell",[](MenuFuncData data){
Component<RowInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Enable(false);
Component<RowInventoryScrollableWindowComponent>(MERCHANT,"Merchant Inventory Display")->Disable();
Component<MenuComponent>(MERCHANT,"Buy Tab")->selected=false;
Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Enable(true);
Component<MenuComponent>(MERCHANT,"Inventory Tabs Outline")->Enable();
for(auto&[category,items]:ITEM_CATEGORIES){
if(DATA["ItemCategory"][category].GetString(0)=="!HIDE")continue; //This category is meant to be hidden!
Component<MenuComponent>(MERCHANT,category+" Inventory Tab")->Enable(true);
Component<MenuComponent>(MERCHANT,category+" Inventory Tab")->Enable();
}
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Enable(true);
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->Enable(true);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Enable();
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->Enable();
data.component.lock()->selected=true;
return true;
})END;
@ -140,9 +140,9 @@ void Menu::InitializeMerchantWindow(){
auto button=merchantWindow->ADD(category+" Inventory Tab",MenuComponent)(geom2d::rect<float>{{2,30+yOffset},{68,16}},category,MenuType::ENUM_END,
[&](MenuFuncData data){
//Close the old inventory window and show the proper one.
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Enable(false);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.menu.S(A::LAST_INVENTORY_TYPE_OPENED))->Disable();
Component<MenuComponent>(data.menu.GetType(),data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)+" Inventory Tab")->SetSelected(false);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component.lock()->S(A::CATEGORY_NAME))->Enable(true);
Component<RowInventoryScrollableWindowComponent>(data.menu.GetType(),"Inventory Display - "+data.component.lock()->S(A::CATEGORY_NAME))->Enable();
Component<MenuComponent>(data.menu.GetType(),data.component.lock()->S(A::CATEGORY_NAME)+" Inventory Tab")->SetSelected(true);
data.menu.S(A::LAST_INVENTORY_TYPE_OPENED)=data.component.lock()->S(A::CATEGORY_NAME);
return true;
@ -185,10 +185,12 @@ void Menu::InitializeMerchantWindow(){
if(first){
merchantWindow->S(A::LAST_INVENTORY_TYPE_OPENED)=category;
button->onClick(MenuFuncData{*merchantWindow,game,button}); //Simulate a click of this button if it's the top one for an initial inventory display.
inventoryDisplay->Enable();
}else{
inventoryDisplay->Disable();
}
Menu::AddInventoryListener(inventoryDisplay,category);
inventoryDisplay->Enable(first);
inventoryDisplay->SetCompactDescriptions(NON_COMPACT);
yOffset+=20;

@ -1211,7 +1211,7 @@ void Player::AddXP(const uint32_t xpGain){
uint32_t nextLevelXP=NextLevelXPRequired();
while(currentLevelXP>nextLevelXP){
currentLevelXP-=nextLevelXP;
level++;
SetLevel(Level()+1);
OnLevelUp();
}
}

@ -188,10 +188,10 @@ public:
}
virtual inline void OnMouseOut()override{
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Disable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(false);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Disable();
}
}
virtual inline void SetShowQuantity(bool showQuantity){
@ -220,11 +220,11 @@ public:
}
if(itemNameLabelName!=""){
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemNameLabelName)->Enable();
}
if(itemDescriptionLabelName!=""){
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText;
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable(true);
Component<MenuLabel>(parentMenu,itemDescriptionLabelName)->Enable();
}
}
virtual inline void OnHover()override{

@ -119,8 +119,20 @@ protected:
upButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+vf2d{rect.size.x-12,0}).str()+"_"+vf2d(12,12).str(),MenuComponent)(geom2d::rect<float>{rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH depth-1 END;
downButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+rect.size-vf2d{12,12}).str()+"_"+vf2d(12,12).str(),MenuComponent)(geom2d::rect<float>{rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()-vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH depth-1 END;
subWindow=ViewPort::rectViewPort({},rect.size,Menu::menus[parentMenu]->pos+rect.pos);
if(!upButton.expired()){upButton.lock()->Enable(!disabled);}
if(!downButton.expired()){downButton.lock()->Enable(!disabled);}
if(!upButton.expired()){
if(IsEnabled()){
upButton.lock()->Enable();
}else{
upButton.lock()->Disable();
}
}
if(!downButton.expired()){
if(IsEnabled()){
downButton.lock()->Enable();
}else{
downButton.lock()->Disable();
}
}
}
virtual inline void BeforeUpdate(AiL*game)override{
MenuComponent::BeforeUpdate(game);
@ -184,15 +196,19 @@ protected:
std::sort(components.begin(),components.end(),[](std::weak_ptr<MenuComponent>c1,std::weak_ptr<MenuComponent>c2){return c1.lock()->depth>c2.lock()->depth;});
for(std::weak_ptr<MenuComponent>component:components){
component.lock()->disabled=!OnScreen(component.lock());
if(OnScreen(component.lock())){
component.lock()->EnableOutsideWindow();
}else{
component.lock()->DisableOutsideWindow();
}
component.lock()->_Update(game);
}
upButton.lock()->disabled=false;
downButton.lock()->disabled=false;
upButton.lock()->disable=false;
downButton.lock()->disable=false;
if(geom2d::contains(rect,bounds)){//This means we have no reason to show a scrollbar.
upButton.lock()->disabled=true;
downButton.lock()->disabled=true;
upButton.lock()->disable=true;
downButton.lock()->disable=true;
}
#pragma region Move scroll offset towards target offset
@ -285,7 +301,7 @@ public:
components.push_back(button);
button->renderInMain=false; //Now we are in control!
button->parentComponent=DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(Menu::menus[parentMenu]->components[this->GetName()]);
button->disabled=disabled;
button->disable=disable;
CalculateBounds();
@ -307,12 +323,20 @@ public:
inline std::vector<std::weak_ptr<MenuComponent>>&GetComponents(){
return components;
}
virtual inline void Enable(bool enabled)override final{
disabled=!enabled;
virtual inline void Enable()override final{
MenuComponent::Enable();
for(std::weak_ptr<MenuComponent>component:components){
component.lock()->Enable();
}
if(upButton.lock()){upButton.lock()->Enable();}
if(downButton.lock()){downButton.lock()->Enable();}
};
virtual inline void Disable()override final{
MenuComponent::Disable();
for(std::weak_ptr<MenuComponent>component:components){
component.lock()->Enable(enabled);
component.lock()->Disable();
}
if(upButton.lock()){upButton.lock()->Enable(enabled);}
if(downButton.lock()){downButton.lock()->Enable(enabled);}
if(upButton.lock()){upButton.lock()->Disable();}
if(downButton.lock()){downButton.lock()->Disable();}
};
};

@ -77,7 +77,7 @@ public:
inline virtual void Update(AiL*game)override final{
MenuComponent::Update(game);
if(disabled)return;
if(IsDisabled()||IsDisabledOutsideWindow())return;
if(hovered&&(game->KEY_CONFIRM.Pressed()||game->GetMouse(Mouse::LEFT).bPressed)){
dragging=true;

@ -42,6 +42,7 @@ All rights reserved.
#include "MenuLabel.h"
#include "SaveFile.h"
#include "ProgressBar.h"
#include "SoundEffect.h"
INCLUDE_MONSTER_LIST
INCLUDE_game
@ -50,8 +51,10 @@ void State_LevelComplete::OnStateChange(GameState*prevState){
if(Menu::IsMenuOpen()){
Menu::CloseAllMenus();
}
levelUpTextPos={-100.f,-100.f};
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());
accumulatedXP=game->GetPlayer()->GetAccumulatedXP();
game->GetPlayer()->AddXP(game->GetPlayer()->GetAccumulatedXP());
for(const ItemMapData&data:game->GetCurrentMap().GetStageLoot()){
uint8_t amountDiff=data.maxAmt-data.minAmt;
@ -69,7 +72,39 @@ void State_LevelComplete::OnStateChange(GameState*prevState){
Menu::OpenMenu(LEVEL_COMPLETE);
};
void State_LevelComplete::OnUserUpdate(AiL*game){
if(levelUpTimer>0.f){
levelUpTimer=std::max(0.f,levelUpTimer-game->GetElapsedTime());
levelUpTextPos.y-=(16/"Interface.HUD Level Up Timer"_F)*game->GetElapsedTime();
if(levelUpTimer<0.f){
levelUpTimer=0.f;
levelUpTextPos=Menu::menus[LEVEL_COMPLETE]->pos.x+Component<MenuLabel>(LEVEL_COMPLETE,"Level Display")->GetPos()+Component<MenuLabel>(LEVEL_COMPLETE,"Level Display")->GetSize()-vf2d{0.f,16.f};
}
}
if(accumulatedXP>0){
lastXPChangeTimer-=game->GetElapsedTime();
while(lastXPChangeTimer<=0.f){
int incrementAmt=int(accumulatedXP/(1/"Interface.HUD XP Bar Tick Rate"_F))+1;
accumulatedXP-=incrementAmt;
auto progressBar=Component<ProgressBar>(MenuType::LEVEL_COMPLETE,"XP Bar");
progressBar->UpdateProgressBar(progressBar->GetCurrentProgress()+incrementAmt);
if(progressBar->GetCurrentProgress()>=progressBar->GetFinalProgress()){
levelUpTextPos=Menu::menus[LEVEL_COMPLETE]->pos+Component<MenuLabel>(LEVEL_COMPLETE,"Level Display")->GetPos()+Component<MenuLabel>(LEVEL_COMPLETE,"Level Display")->GetSize();
levelUpTimer="Interface.HUD Level Up Timer"_F;
progressBar->ResetProgressBar(progressBar->GetCurrentProgress()-progressBar->GetFinalProgress(),game->GetPlayer()->NextLevelXPRequired());
SoundEffect::PlaySFX("Level Up",SoundEffect::CENTERED);
}
lastXPChangeTimer+="Interface.HUD XP Bar Tick Rate"_F;
}
}
};
void State_LevelComplete::Draw(AiL*game){
game->RenderHud();
};
};
void State_LevelComplete::DrawOverlay(AiL*game){
game->DrawShadowStringPropDecal(levelUpTextPos+vf2d{8.f,0.f},"Level Up!",YELLOW);
game->DrawRotatedDecal(levelUpTextPos+vf2d{2.f,1.f},GFX["overworld_arrow.png"].Decal(),-PI/2,GFX["overworld_arrow.png"].Sprite()->Size(),{1.f,1.f},BLACK);
game->DrawRotatedDecal(levelUpTextPos+vf2d{2.f,0.f},GFX["overworld_arrow.png"].Decal(),-PI/2,GFX["overworld_arrow.png"].Sprite()->Size(),{1.f,1.f},YELLOW);
}

@ -39,7 +39,12 @@ All rights reserved.
#include "GameState.h"
class State_LevelComplete:public GameState{
int accumulatedXP=0;
float lastXPChangeTimer=0.f;
vf2d levelUpTextPos={-100.f,-100.f};
float levelUpTimer=0.f;
virtual void OnStateChange(GameState*prevState)override final;
virtual void OnUserUpdate(AiL*game)override final;
virtual void Draw(AiL*game)override final;
virtual void DrawOverlay(AiL*game)override final;
};

@ -74,7 +74,11 @@ void State_OverworldMap::OnStateChange(GameState*prevState){
Component<MenuLabel>(OVERWORLD_LEVEL_SELECT,"Chapter Label")->SetLabel("Chapter "+std::to_string(game->GetCurrentChapter()));
Component<MenuLabel>(OVERWORLD_LEVEL_SELECT,"Stage Label")->SetLabel(currentConnectionPoint->name);
Component<EncountersSpawnListScrollableWindowComponent>(OVERWORLD_LEVEL_SELECT,"Spawns List")->UpdateSpawns(currentConnectionPoint->spawns);
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable(currentConnectionPoint->levelDataExists);
if(currentConnectionPoint->levelDataExists){
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable();
}else{
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Disable();
}
Menu::OpenMenu(OVERWORLD_LEVEL_SELECT,false);
game->UpdateDiscordStatus("Overworld Map",game->GetPlayer()->GetClassName());
};
@ -243,8 +247,16 @@ void State_OverworldMap::UpdateCurrentConnectionPoint(const ConnectionPoint&conn
currentConnectionPoint=const_cast<ConnectionPoint*>(&connection);
Component<MenuLabel>(OVERWORLD_LEVEL_SELECT,"Stage Label")->SetLabel(currentConnectionPoint->name);
Component<EncountersSpawnListScrollableWindowComponent>(OVERWORLD_LEVEL_SELECT,"Spawns List")->UpdateSpawns(currentConnectionPoint->spawns);
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable(currentConnectionPoint->levelDataExists);
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Change Loadout Button")->Enable(currentConnectionPoint->levelDataExists&&!(currentConnectionPoint->type=="STORY"||currentConnectionPoint->type=="SHOP"));
if(currentConnectionPoint->levelDataExists){
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable();
}else{
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Disable();
}
if(currentConnectionPoint->levelDataExists&&!(currentConnectionPoint->type=="STORY"||currentConnectionPoint->type=="SHOP")){
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Change Loadout Button")->Enable();
}else{
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Change Loadout Button")->Disable();
}
}
std::optional<ConnectionPoint*>State_OverworldMap::ConnectionPointFromString(std::string_view mapName){

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 7041
#define VERSION_BUILD 7095
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -415,7 +415,7 @@
</layer>
<objectgroup id="5" name="Spawn Zones">
<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="77.8813" y="303.88" width="120" height="120"/>
<object id="2" name="End Zone" type="EndZone" x="3191" y="1507" width="120" height="120"/>
<object id="3" name="Spawn Group 1" type="SpawnGroup" x="670" y="157" width="506" height="492">
<ellipse/>
</object>

@ -50,4 +50,10 @@ Interface
# How long between each reduction/addition of health.
HUD Mana Tick Rate = 0.01s
# How long between each addition to the XP bar on the level complete screen.
HUD XP Bar Tick Rate = 0.005s
# How long the timer text rises up
HUD Level Up Timer = 0.2s
}

@ -88,6 +88,11 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = item_collect.ogg, 40%
}
Level Up
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = levelup.ogg, 100%
}
Monster Hurt
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)

Loading…
Cancel
Save