Compare commits

...

20 Commits

Author SHA1 Message Date
87686ed9e6 Merge pull request 'SkillMenu' (#92) from SkillMenu into master
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m2s
Reviewed-on: #92
2025-08-04 08:58:27 -05:00
7fb7430a6f Fix for Issue #94. Release Build 12247.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m43s
2025-08-04 08:41:12 -05:00
4d2eb86efe ItemEnchant::AbilitySlot renamed to ItemEnchant::EnchantAbilitySlot. Release Build 12246.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m13s
2025-08-01 14:13:47 -05:00
9b252334e5 Proper implementation of skill and ability displays in the Character menu. Ready for merge. Release Build 12245.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 8m2s
2025-08-01 13:46:33 -05:00
ad28ead6d5 Ability icons and label default visibility and toggle visibility taken care of. 2025-07-30 08:45:28 -05:00
0d5d0cda5c Working copy merge from multimultishotdamagemultchange branch.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m23s
2025-07-30 08:27:57 -05:00
9ee29654b8 Rebuild 2025-07-30 08:25:47 -05:00
f0b7f3979c Skill Tab merge
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m12s
2025-07-30 08:20:59 -05:00
e2e4892741 Default Pack key exception catching added. 2025-07-30 08:20:13 -05:00
7247d226e8 Skill menu (re)positioning.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m36s
2025-06-17 09:51:16 -04:00
be05839743 Add ability list updating for the hub pause character menu. Release Build 12234.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m28s
2025-06-17 09:42:47 -04:00
c14740687b Fix reference problems with ability displays. Release Build 12233.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 6m49s
2025-06-16 16:43:36 -04:00
7f4e6282b7 Fix bug with reading an enhanced ability's config value from a location that is not the ability's settings group (was not returning false to jump to the next check). Release Build 12227. 2025-06-16 16:43:23 -04:00
83317bacb6 Merge into master
Some checks failed
Emscripten Build / Build_and_Deploy_Web_Build (push) Has been cancelled
2025-06-16 16:42:25 -04:00
8f1a4e0699 Add in ability display labels. Release Build 12210.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 9m29s
2025-06-02 14:13:39 -05:00
3cf5651d95 Add skill menu buttons and text displays. Release Build 12209.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 10m6s
2025-06-02 13:28:44 -05:00
93fb1fd48e Add functional Equipment and Skills Tab toggle functionality.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 8m43s
2025-06-02 07:55:15 -05:00
667c5d2da6 Work in progress Character menu buttons.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 7m1s
2025-05-19 06:57:14 -05:00
2b77818001 Fix up issues with reading test configs in non-testing mode and unncessary normal config variables stored for reading in testing mode. Release Build 12197. 2025-05-16 15:39:37 -05:00
532d846ea4 Add in selection highlight buttons outline for the new skills tab.
All checks were successful
Emscripten Build / Build_and_Deploy_Web_Build (push) Successful in 11m56s
2025-05-15 15:51:10 -04:00
18 changed files with 210 additions and 28 deletions

View File

@ -126,6 +126,7 @@ const std::string Ability::GetDescriptionWithPlayerModifiers()const{
std::string separatorVal{variableName.substr(separatorMarker+1)};
if(!specialPrefixes.count(separatorKey))ERR(std::format("Could not find translation function for key {} inside special prefixes map!",separatorKey))
else {
if(!data.HasProperty(separatorVal))return false; //Could not be found in this section, will need to seek in another location.
finalText+=specialValCol.toHTMLColorCode()+specialPrefixes[separatorKey](data,separatorVal)+WHITE.toHTMLColorCode();
bracesFound=false;
return true;
@ -176,6 +177,7 @@ const std::string Ability::GetDescriptionWithPlayerModifiers()const{
std::string separatorVal{variableName.substr(separatorMarker+1)};
if(!specialPrefixes.count(separatorKey))ERR(std::format("Could not find translation function for key {} inside special prefixes map!",separatorKey))
else {
if(!data.HasProperty(separatorVal))return false; //Could not be found in this section, will need to seek in another location.
finalText+=specialValCol.toHTMLColorCode()+specialPrefixes[separatorKey](data,separatorVal)+WHITE.toHTMLColorCode();
bracesFound=false;
return true;

View File

@ -56,6 +56,14 @@ struct PrecastData{
PrecastData(float castTime,float range,float size);
};
enum class EnchantAbilitySlot{
ABILITY1,
ABILITY2,
ABILITY3,
ABILITY4,
DEFENSIVE
};
//Abilities are tied to class data which is defined in Class.cpp.
struct Ability{
std::string name="";

View File

@ -171,12 +171,12 @@ AiL::AiL(bool testingMode){
#pragma region Extra Config Initializations
if(TestingModeEnabled()){ //Unit Test-specific custom configurations.
std::string CONFIG_PATH = "config_path"_S;
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
ITEM_CONFIG = CONFIG_PATH + "item-test_config"_S;
ITEM_SET_CONFIG = CONFIG_PATH + "item_set-test_config"_S;
std::string ITEM_CONFIG = CONFIG_PATH + "item-test_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set-test_config"_S;
std::string ITEM_ENCHANTS_CONFIG = CONFIG_PATH + "Item Enchants Test Config"_S;
utils::datafile::Read(DATA,ITEM_CONFIG,',',datafile::OverwriteMode::OVERWRITE);
utils::datafile::Read(DATA,ITEM_SET_CONFIG,',',datafile::OverwriteMode::OVERWRITE);
utils::datafile::Read(DATA,ITEM_ENCHANTS_CONFIG,',',datafile::OverwriteMode::OVERWRITE);
auto keys=DATA.GetProperty("ItemConfiguration");
for(auto&[key,value]:keys){
std::string config=DATA["ItemConfiguration"][key].GetString();
@ -233,9 +233,11 @@ void InitializeGameConfigurations(){
{
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
std::string ITEM_ENCHANT_CONFIG = CONFIG_PATH + "Item Enchants"_S;
utils::datafile::Read(DATA,ITEM_CONFIG);
utils::datafile::Read(DATA,ITEM_SET_CONFIG);
utils::datafile::Read(DATA,ITEM_ENCHANT_CONFIG);
}
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
@ -285,7 +287,7 @@ void InitializeGameConfigurations(){
}
bool AiL::OnUserCreate(){
if(PACK_KEY=="INSERT_PACK_KEY_HERE")ERR("ERROR! Starting the game with the default pack ID is not allowed!");
if(PACK_KEY=="INSERT_PACK_KEY_HERE"||PACK_KEY=="INSERT PACK KEY HERE")ERR("ERROR! Starting the game with the default pack ID is not allowed!");
gamepack.LoadPack("assets/"+"gamepack_file"_S,PACK_KEY);
GamePad::init();

View File

@ -1,3 +1,4 @@
#pragma region License
/*
License (OLC-3)
@ -136,8 +137,12 @@ void Menu::InitializeCharacterMenuWindow(){
->Disable();
characterMenuWindow->ADD("Equip List",ScrollableWindowComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37-24}})DEPTH -1 END
->Disable();
characterMenuWindow->ADD("Equip Selection Bottom Outline",MenuComponent)(geom2d::rect<float>{{123,28+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END
characterMenuWindow->ADD("Equip Selection Bottom Outline",MenuComponent)(geom2d::rect<float>{{123,28+(windowSize.y-37-24)},{120,24}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)DEPTH 2 END
->Disable();
auto abilitySelectionOutline{characterMenuWindow->ADD("Ability Selection Outline",MenuComponent)(geom2d::rect<float>{{123,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)DEPTH 0 END};
abilitySelectionOutline->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")->Disable();
@ -166,6 +171,7 @@ void Menu::InitializeCharacterMenuWindow(){
};
int equipSlot=1;
#pragma region Equipment Selection Boxes
for(int i=0;i<8;i++){
float x=31+(i%2)*33;
float y=24+(i/2)*28;
@ -335,6 +341,120 @@ void Menu::InitializeCharacterMenuWindow(){
characterMenuWindow->ADD("Equip Label "+CharacterMenuWindow::slotNames[i],PopupMenuLabel)(geom2d::rect<float>{{labelX,labelY},{24,16}},CharacterMenuWindow::slotNames[i],vf2d{0.5,1.f},ComponentAttr::SHADOW)END;
Menu::AddEquipStatListener(equipmentSlot);
}
#pragma endregion
auto abilityNameLabel{characterMenuWindow->ADD("Ability Name Text",MenuLabel)(geom2d::rect<float>{{123,28},{116,12}},"",1.f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)DEPTH -1 END};
auto abilityDescriptionLabel{characterMenuWindow->ADD("Ability Description Text",MenuLabel)(geom2d::rect<float>{{125,30+16},{116,windowSize.y-39-16}},"",1.f,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW)DEPTH -1 END};
abilityNameLabel->Disable();
#pragma region Skill Selection Boxes
const std::array abilityBoxes{
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility1(),EnchantAbilitySlot::ABILITY1},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility2(),EnchantAbilitySlot::ABILITY2},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility3(),EnchantAbilitySlot::ABILITY3},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility4(),EnchantAbilitySlot::ABILITY4},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetRightClickAbility(),EnchantAbilitySlot::DEFENSIVE},
};
for(size_t i{0};auto&[ability,slot]:abilityBoxes){
float x=8;
float y=14+i*28;
float labelX=24;
float labelY=24+i*26+28;
auto skillBox{characterMenuWindow->ADD(std::format("Skill Icon Label {}",i),MenuIconButton)(geom2d::rect<float>{{x,y+28},{24,24}},GFX[ability.get().icon].Decal(),DO_NOTHING)END};
auto skillNameLabel{characterMenuWindow->ADD(std::format("Skill Name Label {}",i),MenuLabel)(geom2d::rect<float>{{labelX+4,labelY-6},{96,24}},ability.get().GetNameWithPlayerModifiers())END};
skillBox->SetHoverFunc([slot](MenuFuncData data){
const auto&ability{game->GetPlayer()->GetAbility(slot)};
auto abilityNameTextLabel{Component<MenuLabel>(data.menu.GetType(),"Ability Name Text")};
auto abilityDescriptionTextLabel{Component<MenuLabel>(data.menu.GetType(),"Ability Description Text")};
abilityNameTextLabel->SetLabel(ability.GetNameWithPlayerModifiers());
abilityDescriptionTextLabel->SetLabel(ability.GetDescriptionWithPlayerModifiers());
abilityNameTextLabel->Enable();
abilityDescriptionTextLabel->Enable();
Component<MenuComponent>(data.menu.GetType(),"Ability Selection Outline")->Enable();
return true;
});
skillBox->SetMouseOutFunc([](MenuFuncData data){
Component<MenuLabel>(data.menu.GetType(),"Ability Name Text")->Disable();
Component<MenuLabel>(data.menu.GetType(),"Ability Description Text")->Disable();
Component<MenuComponent>(data.menu.GetType(),"Ability Selection Outline")->Disable();
return true;
});
skillBox->Disable(); //Hide these by default.
skillNameLabel->Disable(); //Hide these by default.
i++;
}
#pragma endregion
enum class ClickedTab{
EQUIPMENT,
SKILLS
};
//Used in conjunction with the onClick events of MenuComponents tab.
auto OnTabClick=[](const ClickedTab tabClicked,const MenuFuncData&data){
using enum ClickedTab;
auto abilityNameLabel{Component<MenuLabel>(data.menu.GetType(),"Ability Name Text")};
auto abilityDescriptionLabel{Component<MenuLabel>(data.menu.GetType(),"Ability Description Text")};
for(int i=0;i<8;i++){
auto slot{Component<EquipSlotButton>(data.menu.GetType(),std::format("Equip Slot {}",CharacterMenuWindow::slotNames[i]))};
if(tabClicked==EQUIPMENT)slot->Enable();
else slot->Disable();
}
const std::array abilityBoxes{
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility1(),EnchantAbilitySlot::ABILITY1},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility2(),EnchantAbilitySlot::ABILITY2},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility3(),EnchantAbilitySlot::ABILITY3},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility4(),EnchantAbilitySlot::ABILITY4},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetRightClickAbility(),EnchantAbilitySlot::DEFENSIVE},
};
for(int i=0;i<abilityBoxes.size();i++){
auto&[ability,slot]{abilityBoxes[i]};
auto abilityIcon{Component<MenuIconButton>(data.menu.GetType(),std::format("Skill Icon Label {}",i))};
auto abilityText{Component<MenuLabel>(data.menu.GetType(),std::format("Skill Name Label {}",i))};
abilityIcon->SetIcon(GFX[ability.get().icon].Decal());
abilityText->SetLabel(ability.get().GetNameWithPlayerModifiers());
if(tabClicked==SKILLS){
if(abilityText->GetLabel()!="???"){ //Unknown abilities should remain hidden for the player's surprise.
abilityIcon->Enable();
abilityText->Enable();
}
}else{
abilityIcon->Disable();
abilityText->Disable();
}
}
Component<MenuComponent>(data.menu.GetType(),"Equipment Tab")->SetSelected(tabClicked==EQUIPMENT);
Component<MenuComponent>(data.menu.GetType(),"Skills Tab")->SetSelected(tabClicked==SKILLS);
const static std::array<std::string,8>slotNames{"Helmet","Weapon","Armor","Gloves","Pants","Shoes","Ring 1","Ring 2"};
if(tabClicked==EQUIPMENT){
abilityNameLabel->Disable();
abilityDescriptionLabel->Disable();
for(size_t ind{0};ind<slotNames.size();ind++){
Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[ind])->Enable();
Component<PopupMenuLabel>(CHARACTER_MENU,"Equip Label "+slotNames[ind])->Enable();
}
}else{
abilityNameLabel->Enable();
abilityDescriptionLabel->Enable();
for(size_t ind{0};ind<slotNames.size();ind++){
Component<MenuItemItemButton>(CHARACTER_MENU,"Equip Slot "+slotNames[ind])->Disable();
Component<PopupMenuLabel>(CHARACTER_MENU,"Equip Label "+slotNames[ind])->Disable();
}
}
};
auto equipmentTab = characterMenuWindow->ADD("Equipment Tab",MenuComponent)(geom2d::rect<float>{{2,30},{58,10}},"Equipment",[&OnTabClick](MenuFuncData data){
OnTabClick(ClickedTab::EQUIPMENT,data);
return true;
},ButtonAttr::FIT_TO_LABEL)END;
equipmentTab->SetSelectionType(HIGHLIGHT);
equipmentTab->SetSelected(true);
auto skillsTab = characterMenuWindow->ADD("Skills Tab",MenuComponent)(geom2d::rect<float>{{62,30},{56,10}},"Skills",[&OnTabClick](MenuFuncData data){
OnTabClick(ClickedTab::SKILLS,data);
return true;
},ButtonAttr::FIT_TO_LABEL)END;
skillsTab->SetSelectionType(HIGHLIGHT);
skillsTab->SetSelected(false);
characterMenuWindow->ADD("Stat Display Outline",MenuComponent)(geom2d::rect<float>{{245,28},{62,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END;

View File

@ -44,6 +44,7 @@ All rights reserved.
#include "CharacterRotatingDisplay.h"
#include "ClassInfo.h"
#include "Unlock.h"
#include "MenuIconButton.h"
INCLUDE_game
INCLUDE_GFX
@ -59,6 +60,22 @@ void Menu::InitializeHubPauseWindow(){
hubPauseWindow->ADD("Character Button",MenuComponent)(geom2d::rect<float>{{6.f,28.f},{84.f,24.f}},"Character",[](MenuFuncData data){
Component<CharacterRotatingDisplay>(CHARACTER_MENU,"Character Rotating Display")->SetIcon(GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal());
Component<MenuComponent>(CHARACTER_MENU,"Equip Selection Select Button")->Click();
std::array abilityBoxes{
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility1(),EnchantAbilitySlot::ABILITY1},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility2(),EnchantAbilitySlot::ABILITY2},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility3(),EnchantAbilitySlot::ABILITY3},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility4(),EnchantAbilitySlot::ABILITY4},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetRightClickAbility(),EnchantAbilitySlot::DEFENSIVE},
};
for(size_t i{0};auto&[ability,slot]:abilityBoxes){
//Attempt to update icons in case the abilities have changed at some point.
//Attempt to update labels in case they have changed.
auto skillBox{Component<MenuIconButton>(CHARACTER_MENU,std::format("Skill Icon Label {}",i))};
auto skillNameLabel{Component<MenuLabel>(CHARACTER_MENU,std::format("Skill Name Label {}",i))};
skillBox->SetIcon(GFX[ability.get().icon].Decal());
skillNameLabel->SetLabel(ability.get().GetNameWithPlayerModifiers());
i++;
}
Menu::OpenMenu(CHARACTER_MENU);
return true;
},ButtonAttr::FIT_TO_LABEL)END;

View File

@ -102,8 +102,8 @@ void ItemEnchantInfo::Initialize(){
newEnchant.category=enchantCategory;
newEnchant.name=keyName;
std::string enchantDescription{enchant["Description"].GetString()};
using enum AbilitySlot;
const std::unordered_map<std::string,AbilitySlot>affectSlots{
using enum EnchantAbilitySlot;
const std::unordered_map<std::string,EnchantAbilitySlot>affectSlots{
{"Auto Attack",AUTO_ATTACK},
{"Right Click Ability",RIGHT_CLICK},
{"Ability 1",ABILITY_1},
@ -236,7 +236,7 @@ const std::string_view ItemEnchant::Description()const{
const ItemEnchantInfo::ItemEnchantCategory&ItemEnchant::Category()const{
return GetEnchantInfo().Category();
}
const std::optional<ItemEnchantInfo::AbilitySlot>&ItemEnchant::AbilitySlot()const{
const std::optional<ItemEnchantInfo::EnchantAbilitySlot>&ItemEnchant::EnchantAbilitySlot()const{
return GetEnchantInfo().abilitySlot;
}
const std::unordered_map<std::string,ItemEnchantInfo>&ItemEnchantInfo::GetEnchants(){
@ -324,7 +324,7 @@ const Pixel&ItemEnchant::DisplayCol()const{
return ItemEnchantInfo::enchantTextDisplayCol.at(Category());
}
const std::optional<ItemEnchantInfo::AbilitySlot>&ItemEnchantInfo::GetAbilitySlot()const{
const std::optional<ItemEnchantInfo::EnchantAbilitySlot>&ItemEnchantInfo::GetAbilitySlot()const{
return abilitySlot;
}

View File

@ -56,7 +56,7 @@ public:
CLASS,
UNIQUE,
};
enum class AbilitySlot{
enum class EnchantAbilitySlot{
AUTO_ATTACK,
RIGHT_CLICK,
ABILITY_1,
@ -84,7 +84,7 @@ public:
const std::string_view Description()const;
const ItemEnchantCategory&Category()const;
const std::optional<Class>&GetClass()const;
const std::optional<AbilitySlot>&GetAbilitySlot()const;
const std::optional<EnchantAbilitySlot>&GetAbilitySlot()const;
const std::optional<Ability*>GetAbility()const; //Get the ability this enchant is tied to.
const Pixel&DisplayCol()const;
const float GetConfigValue(const std::string_view keyName)const;
@ -104,7 +104,7 @@ private:
std::string name;
std::string description;
std::optional<Class>abilityClass;
std::optional<AbilitySlot>abilitySlot;
std::optional<EnchantAbilitySlot>abilitySlot;
ItemAttributable minStatModifiers;
ItemAttributable maxStatModifiers;
std::unordered_map<std::string,float>config;
@ -121,7 +121,7 @@ public:
const std::string Name(ItemEnchantInfo::TextStyle style=ItemEnchantInfo::TextStyle::NORMAL)const;
const std::string_view Description()const;
const ItemEnchantInfo::ItemEnchantCategory&Category()const;
const std::optional<ItemEnchantInfo::AbilitySlot>&AbilitySlot()const;
const std::optional<ItemEnchantInfo::EnchantAbilitySlot>&EnchantAbilitySlot()const;
const static std::vector<ItemEnchantInfo>GetAvailableEnchants();
//Rolls a class-appropriate random enchant.
const static ItemEnchant RollRandomEnchant(const std::optional<ItemEnchant>previousEnchant={});

View File

@ -731,7 +731,7 @@ void Menu::AddChapterListener(std::weak_ptr<MenuComponent>component){
if(std::find_if(chapterListeners.begin(),chapterListeners.end(),[&](auto&ptr){return &*ptr.lock()==&*component.lock();})!=chapterListeners.end()){
ERR("WARNING! Component "<<component.lock()->name<<" has already been added to the Chapter listener list! There should not be any duplicates!!")
}
chapterListeners.push_back(component);
chapterListeners.emplace_back(component);
}
ToggleFuncData::ToggleFuncData(Menu&menu,AiL*const game,std::weak_ptr<MenuComponent>component,std::weak_ptr<ScrollableWindowComponent>parentComponent,bool checked)

View File

@ -67,9 +67,9 @@ using ToggleFunc=std::function<bool(ToggleFuncData)>;
#define END )
#define DEPTH ,
#define DEFAULT_DEPTH -999999
#define STARTING_DEPTH 999999
#define MAX_MENUS 64
constexpr int DEFAULT_DEPTH = -999999;
constexpr int STARTING_DEPTH = 999999;
constexpr uint16_t MAX_MENUS = 64;
using Data=std::variant<ButtonName,std::weak_ptr<MenuComponent>>;
using MenuDataFunc=std::function<void(MenuType,Data&)>;
@ -139,7 +139,6 @@ class Menu:public IAttributable{
static std::vector<std::weak_ptr<MenuComponent>>equipStatListeners; //All menu components that care about stat/equip updates subscribe to this list indirectly (See Menu::AddStatListener()).
static std::vector<std::weak_ptr<MenuComponent>>chapterListeners; //All menu components that care about story chapter updates subscribe to this list indirectly (See Menu::AddChapterListener()).
const static bool CanModifyEquipSlots();
public:
//The constructor is private. Use CreateMenu() instead!

View File

@ -98,8 +98,8 @@ private:
std::string label="";
std::weak_ptr<MenuComponent>subcomponentParent; //For subcomponents, this value provides the actual component this subcomponent was spawned from.
int depth=0; //Higher depth (positive) means buried further back. Lower depth (negative) means behind. If you have to modify depth, use the DEPTH macro!!!
protected:
int depth=0;
float hoverEffect=0;
std::string name="";
geom2d::rect<float>rect;

View File

@ -37,13 +37,13 @@ All rights reserved.
#pragma endregion
#include "Menu.h"
#include "MenuComponent.h"
#include "GameState.h"
#include "MenuLabel.h"
#include "AdventuresInLestoria.h"
#include "CharacterRotatingDisplay.h"
#include "ClassInfo.h"
#include "Unlock.h"
#include "MenuItemButton.h"
INCLUDE_game
INCLUDE_GFX
@ -59,6 +59,24 @@ void Menu::InitializePauseWindow(){
pauseWindow->ADD("Character Button",MenuComponent)(geom2d::rect<float>{{6.f,28.f},{84.f,24.f}},"Character",[](MenuFuncData data){
Component<CharacterRotatingDisplay>(CHARACTER_MENU,"Character Rotating Display")->SetIcon(GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal());
Component<MenuComponent>(CHARACTER_MENU,"Equip Selection Select Button")->Click();
std::array abilityBoxes{
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility1(),EnchantAbilitySlot::ABILITY1},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility2(),EnchantAbilitySlot::ABILITY2},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility3(),EnchantAbilitySlot::ABILITY3},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetAbility4(),EnchantAbilitySlot::ABILITY4},
std::pair<std::reference_wrapper<Ability>,EnchantAbilitySlot>{game->GetPlayer()->GetRightClickAbility(),EnchantAbilitySlot::DEFENSIVE},
};
for(size_t i{0};auto&[ability,slot]:abilityBoxes){
//Attempt to update icons in case the abilities have changed at some point.
//Attempt to update labels in case they have changed.
auto skillBox{Component<MenuIconButton>(CHARACTER_MENU,std::format("Skill Icon Label {}",i))};
auto skillNameLabel{Component<MenuLabel>(CHARACTER_MENU,std::format("Skill Name Label {}",i))};
skillBox->SetIcon(GFX[ability.get().icon].Decal());
skillNameLabel->SetLabel(ability.get().GetNameWithPlayerModifiers());
skillBox->Disable();
skillNameLabel->Disable();
i++;
}
Menu::OpenMenu(CHARACTER_MENU);
return true;
},ButtonAttr::FIT_TO_LABEL)END;

View File

@ -2326,4 +2326,17 @@ const vf2d&Player::GetPreviousPos()const{
const std::unordered_set<std::string>&Player::GetEnchants()const{
return enchantList;
}
const Ability&Player::GetAbility(EnchantAbilitySlot slot){
using enum EnchantAbilitySlot;
switch(slot){
case ABILITY1:return GetAbility1();
case ABILITY2:return GetAbility2();
case ABILITY3:return GetAbility3();
case ABILITY4:return GetAbility4();
case DEFENSIVE:return GetRightClickAbility();
}
ERR(std::format("WARNING! Unknown ability slot {} specified when attempting to retrieve Ability! THIS SHOULD NOT BE HAPPENING!",int(slot)));
return GetAbility1(); //THIS SHOULD NEVER BE HIT!!!
}

View File

@ -230,6 +230,7 @@ public:
virtual Ability&GetAbility2()=0;
virtual Ability&GetAbility3()=0;
virtual Ability&GetAbility4()=0;
const Ability&GetAbility(EnchantAbilitySlot slot);
virtual void SetAbility4(const Ability&originalAbility)=0; //NOTE: Make sure to provide the original ability and not a current ability!
virtual std::string&GetWalkNAnimation()=0;
virtual std::string&GetWalkEAnimation()=0;

View File

@ -79,11 +79,11 @@ void State_MainMenu::OnUserUpdate(AiL*game){
game->UpdateCamera(game->GetElapsedTime());
game->ClearTimedOutGarbage();
};
}
void State_MainMenu::Draw(AiL*game){
game->RenderWorld(game->GetElapsedTime());
TitleScreen::Draw();
};
}
const ZoneData&State_MainMenu::ChooseRandomFocusArea(){
//std::vector<ZoneData>

View File

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

View File

@ -67,6 +67,12 @@ item_set_config = items/ItemSets.txt
# Item Set Unit Testing Config
item_set-test_config = items/ItemSets-test.txt
# Item Enchants Config
Item Enchants = items/ItemEnchants.txt
# Item enchants unit testing config
Item Enchants Test Config = items/ItemEnchants-test.txt
# Path to items configuration
item_directory = items/

View File

@ -1,15 +1,11 @@
ItemConfiguration
{
Item Database = ItemDatabase.txt
Item Enchants = ItemEnchants.txt
Item Scripts = ItemScript.txt
Item Categories = ItemCategory.txt
Equipment = Equipment.txt
Weapons = Weapons.txt
Accessories = Accessories.txt
# Item enchants unit testing config
Item Enchants Test Config = ItemEnchants-test.txt
}
Item
{