Refactor inventory window so the scrollable consumable window now subscribes to a listener.
Listener list system removes the arbitrary requirement of components needing to be called "inventory" (very error-prone)
This commit is contained in:
parent
04d6f42526
commit
46462a24e7
64
Crawler/.vscode/settings.json
vendored
Normal file
64
Crawler/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"numbers": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"semaphore": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"variant": "cpp"
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,10 @@ void Menu::InitializeInventoryWindow(){
|
|||||||
|
|
||||||
ScrollableWindowComponent*inventory=new ScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){});
|
ScrollableWindowComponent*inventory=new ScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){});
|
||||||
inventoryWindow->AddComponent("inventory",inventory);
|
inventoryWindow->AddComponent("inventory",inventory);
|
||||||
|
Menu::AddInventoryListener(inventory,"Consumables");
|
||||||
|
Menu::AddInventoryListener(inventory,"Equipment");
|
||||||
|
Menu::AddInventoryListener(inventory,"Accessories");
|
||||||
|
Menu::AddInventoryListener(inventory,"Materials");
|
||||||
|
|
||||||
//We don't have to actually populate the inventory list because now when an item gets added, it will automatically add the correct component in for us.
|
//We don't have to actually populate the inventory list because now when an item gets added, it will automatically add the correct component in for us.
|
||||||
|
|
||||||
|
@ -564,49 +564,21 @@ void Menu::SetMouseNavigation(bool mouseNavigation){
|
|||||||
void Menu::InventorySlotsUpdated(ITCategory cat){
|
void Menu::InventorySlotsUpdated(ITCategory cat){
|
||||||
//Update the inventory with a new inventory slot, since there's one additional item to interact with now.
|
//Update the inventory with a new inventory slot, since there's one additional item to interact with now.
|
||||||
std::vector<std::string>&inv=Inventory::get(cat);
|
std::vector<std::string>&inv=Inventory::get(cat);
|
||||||
MenuType inventoryWindow;
|
for(MenuComponent*component:inventoryListeners.at(cat)){
|
||||||
if(cat=="Consumables"){
|
component->OnInventorySlotsUpdate(cat);
|
||||||
inventoryWindow=INVENTORY;
|
}
|
||||||
}else
|
}
|
||||||
if(cat=="Equipment"){
|
|
||||||
//TODO: Update different inventories depending on what the item's category is.
|
void Menu::AddInventoryListener(MenuComponent*component,ITCategory category){
|
||||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
if(inventoryListeners.count(category)){
|
||||||
return; //Currenly a no-op
|
std::vector<MenuComponent*>&listenerList=inventoryListeners.at(category);
|
||||||
}else
|
if(std::find(listenerList.begin(),listenerList.end(),component)!=listenerList.end()){
|
||||||
if(cat=="Accesories"){
|
std::cout<<"WARNING! Component "<<component->name<<" has already been added to the "<<category<<" listener list! There should not be any duplicates!!"<<std::endl;
|
||||||
//TODO: Update different inventories depending on what the item's category is.
|
throw;
|
||||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
}
|
||||||
return; //Currenly a no-op
|
listenerList.push_back(component);
|
||||||
}else
|
}else{
|
||||||
if(cat=="Materials"){
|
std::cout<<"WARNING! Inventory category "<<category<<" does not exist!"<<std::endl;
|
||||||
//TODO: Update different inventories depending on what the item's category is.
|
throw;
|
||||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
|
||||||
return; //Currenly a no-op
|
|
||||||
}else{
|
|
||||||
throw;
|
|
||||||
std::cout<<"WARNING! Attempting to add an inventory to a category that does not exist. THIS SHOULD NOT BE HAPPENING!"<<std::endl;
|
|
||||||
}
|
|
||||||
//HACK ALERT!! We make a very bold assumption here that every inventory window will contain a ScrollableWindowComponent called "inventory"! Because it's a safemap, if it doesn't exist it will let us know as such, we won't include any extra checks here.
|
|
||||||
ScrollableWindowComponent*inventory=((ScrollableWindowComponent*)menus[inventoryWindow]->components["inventory"]);
|
|
||||||
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
|
||||||
if(inventory->ComponentCount()<inv.size()){//We need more space to display our items.
|
|
||||||
int invWidth="ThemeGlobal.InventoryWidth"_I;
|
|
||||||
int x=(inv.size()-1)%invWidth;
|
|
||||||
int y=(inv.size()-1)/invWidth;
|
|
||||||
int itemIndex=y*invWidth+x;
|
|
||||||
|
|
||||||
int buttonSize="ThemeGlobal.InventoryButtonSize"_I;
|
|
||||||
int totalSpacing="ThemeGlobal.InventoryItemSpacing"_I+buttonSize;
|
|
||||||
|
|
||||||
MenuFunc useItemFunc=[](MenuFuncData data){
|
|
||||||
MenuItemButton*button=(MenuItemButton*)data.component;
|
|
||||||
button->UseItem();
|
|
||||||
};
|
|
||||||
|
|
||||||
MenuItemButton*button=new MenuItemButton{inventoryWindow,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
|
|
||||||
inventory->AddComponent(menus[inventoryWindow],"item"+std::to_string(itemIndex),button);
|
|
||||||
}else
|
|
||||||
if(inventory->ComponentCount()>inv.size()){ //There are empty spots, so let's clean up.
|
|
||||||
inventory->RemoveEmptySlots();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,12 +24,13 @@ class Menu:IAttributable{
|
|||||||
friend class Player;
|
friend class Player;
|
||||||
|
|
||||||
float buttonHoldTime=0;
|
float buttonHoldTime=0;
|
||||||
std::vector<MenuComponent*>displayComponents; //Components that are only for displaying purposes.
|
std::vector<MenuComponent*>displayComponents; //Comp.onents that are only for displaying purposes.
|
||||||
vi2d selection={-1,-1};
|
vi2d selection={-1,-1};
|
||||||
vi2d lastActiveMousePos={};
|
vi2d lastActiveMousePos={};
|
||||||
|
|
||||||
MenuComponent*draggingComponent=nullptr;
|
MenuComponent*draggingComponent=nullptr;
|
||||||
Renderable r,overlay;
|
Renderable r,overlay;
|
||||||
|
static safemap<ITCategory,std::vector<MenuComponent*>>inventoryListeners; //All menu components that care about inventory updates subscribe to this list indirectly (See Menu::AddInventoryListener()).
|
||||||
public:
|
public:
|
||||||
//The constructor is private. Use CreateMenu() instead!
|
//The constructor is private. Use CreateMenu() instead!
|
||||||
Menu()=default;
|
Menu()=default;
|
||||||
@ -54,6 +55,7 @@ public:
|
|||||||
bool UsingMouseNavigation();
|
bool UsingMouseNavigation();
|
||||||
void SetMouseNavigation(bool mouseNavigation);
|
void SetMouseNavigation(bool mouseNavigation);
|
||||||
static void InventorySlotsUpdated(ITCategory cat); //Called whenever an inventory item gets added to the player's inventory, thus increasing the total number of slots in our bag.
|
static void InventorySlotsUpdated(ITCategory cat); //Called whenever an inventory item gets added to the player's inventory, thus increasing the total number of slots in our bag.
|
||||||
|
static void AddInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
|
||||||
private:
|
private:
|
||||||
Menu(vf2d pos,vf2d size);
|
Menu(vf2d pos,vf2d size);
|
||||||
void HoverMenuSelect(Crawler*game);
|
void HoverMenuSelect(Crawler*game);
|
||||||
|
@ -85,3 +85,5 @@ bool MenuComponent::HandleOutsideDisabledButtonSelection(MenuComponent*disabledB
|
|||||||
vf2d MenuComponent::GetPos(){
|
vf2d MenuComponent::GetPos(){
|
||||||
return rect.pos;
|
return rect.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuComponent::OnInventorySlotsUpdate(ITCategory cat){}
|
@ -45,4 +45,6 @@ public:
|
|||||||
virtual bool DropDraggableItem(MenuComponent*draggable);
|
virtual bool DropDraggableItem(MenuComponent*draggable);
|
||||||
//A notification that a button outside the region has been selected. Return false if it's not allowed.
|
//A notification that a button outside the region has been selected. Return false if it's not allowed.
|
||||||
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
|
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
|
||||||
|
//Called whenever an inventory slot gets updated, whether it's adding or removing an item.
|
||||||
|
virtual void OnInventorySlotsUpdate(ITCategory cat);
|
||||||
};
|
};
|
@ -191,7 +191,7 @@ public:
|
|||||||
virtual inline size_t ComponentCount(){
|
virtual inline size_t ComponentCount(){
|
||||||
return components.size();
|
return components.size();
|
||||||
}
|
}
|
||||||
virtual void RemoveButton(MenuComponent*button){
|
virtual inline void RemoveButton(MenuComponent*button){
|
||||||
std::vector<MenuComponent*>&buttonList=Menu::menus[button->parentMenu]->buttons.at(button->GetPos().y);
|
std::vector<MenuComponent*>&buttonList=Menu::menus[button->parentMenu]->buttons.at(button->GetPos().y);
|
||||||
std::vector<MenuComponent*>&keyboardButtonList=Menu::menus[button->parentMenu]->keyboardButtons.at(button->GetPos().y);
|
std::vector<MenuComponent*>&keyboardButtonList=Menu::menus[button->parentMenu]->keyboardButtons.at(button->GetPos().y);
|
||||||
size_t removedCount=0;
|
size_t removedCount=0;
|
||||||
@ -214,7 +214,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void RemoveEmptySlots(){
|
void inline RemoveEmptySlots(){
|
||||||
//Algorithm will iterate through all slots, finding blank slots. Each time a blank slot is found, all items will shift over by one, and then the last item will be removed. Repeat until all slots iterated through.
|
//Algorithm will iterate through all slots, finding blank slots. Each time a blank slot is found, all items will shift over by one, and then the last item will be removed. Repeat until all slots iterated through.
|
||||||
for(int i=0;i<components.size();i++){
|
for(int i=0;i<components.size();i++){
|
||||||
MenuComponent*button=components[i];
|
MenuComponent*button=components[i];
|
||||||
@ -237,4 +237,28 @@ public:
|
|||||||
}
|
}
|
||||||
bounds=CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
|
bounds=CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
|
||||||
}
|
}
|
||||||
|
virtual void OnInventorySlotsUpdate(ITCategory cat)override{
|
||||||
|
std::vector<std::string>&inv=Inventory::get(cat);
|
||||||
|
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
||||||
|
if(ComponentCount()<inv.size()){//We need more space to display our items.
|
||||||
|
int invWidth="ThemeGlobal.InventoryWidth"_I;
|
||||||
|
int x=(inv.size()-1)%invWidth;
|
||||||
|
int y=(inv.size()-1)/invWidth;
|
||||||
|
int itemIndex=y*invWidth+x;
|
||||||
|
|
||||||
|
int buttonSize="ThemeGlobal.InventoryButtonSize"_I;
|
||||||
|
int totalSpacing="ThemeGlobal.InventoryItemSpacing"_I+buttonSize;
|
||||||
|
|
||||||
|
MenuFunc useItemFunc=[](MenuFuncData data){
|
||||||
|
MenuItemButton*button=(MenuItemButton*)data.component;
|
||||||
|
button->UseItem();
|
||||||
|
};
|
||||||
|
|
||||||
|
MenuItemButton*button=new MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
|
||||||
|
AddComponent(Menu::menus[parentMenu],"item"+std::to_string(itemIndex),button);
|
||||||
|
}else
|
||||||
|
if(ComponentCount()>inv.size()){ //There are empty spots, so let's clean up.
|
||||||
|
RemoveEmptySlots();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user