Handled dynamic adding and removing of inventory items and syncing with menu systems.
This commit is contained in:
parent
6656e3d036
commit
04d6f42526
12
Crawler/CharacterInfoWindow.cpp
Normal file
12
Crawler/CharacterInfoWindow.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "Crawler.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Menu.h"
|
||||
|
||||
INCLUDE_game
|
||||
typedef Attribute A;
|
||||
|
||||
void Menu::InitializeCharacterInfoWindow(){
|
||||
Menu*characterInfoWindow=CreateMenu(INVENTORY,CENTERED,game->GetScreenSize()-vi2d{4,4});
|
||||
|
||||
}
|
@ -105,6 +105,11 @@ bool Crawler::OnUserCreate(){
|
||||
camera.EnableWorldBoundary(false);
|
||||
|
||||
ItemInfo::InitializeItems();
|
||||
|
||||
InitializeGraphics();
|
||||
|
||||
Menu::InitializeMenus();
|
||||
|
||||
Inventory::AddItem("Small Health Potion",16);
|
||||
Inventory::AddItem("Large Health Potion",3);
|
||||
Inventory::AddItem("Medium Mana Potion",1);
|
||||
@ -121,20 +126,9 @@ bool Crawler::OnUserCreate(){
|
||||
Inventory::AddItem("Dummy Item 11",8);
|
||||
Inventory::AddItem("Dummy Item 12",3);
|
||||
Inventory::AddItem("Dummy Item 13",6);
|
||||
Inventory::AddItem("Dummy Item 14",192);
|
||||
Inventory::AddItem("Dummy Item 15",35);
|
||||
Inventory::AddItem("Dummy Item 16",6);
|
||||
Inventory::AddItem("Dummy Item 17",3);
|
||||
Inventory::AddItem("Dummy Item 18",1);
|
||||
Inventory::AddItem("Dummy Item 19",8);
|
||||
Inventory::AddItem("Dummy Item 20",4);
|
||||
Inventory::AddItem("Bandages",10);
|
||||
Inventory::AddItem("Blue Slime Remains",22);
|
||||
|
||||
InitializeGraphics();
|
||||
|
||||
Menu::InitializeMenus();
|
||||
|
||||
Monster::InitializeStrategies();
|
||||
//Animations
|
||||
sig::Animation::InitializeAnimations();
|
||||
|
@ -308,6 +308,7 @@
|
||||
<ClCompile Include="Animation.cpp" />
|
||||
<ClCompile Include="Arrow.cpp" />
|
||||
<ClCompile Include="Bullet.cpp" />
|
||||
<ClCompile Include="CharacterInfoWindow.cpp" />
|
||||
<ClCompile Include="ChargedArrow.cpp" />
|
||||
<ClCompile Include="Crawler.cpp" />
|
||||
<ClCompile Include="DamageNumber.cpp" />
|
||||
@ -378,6 +379,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="assets\heart.ico" />
|
||||
<Image Include="assets\menus\Character_Info.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Crawler.rc" />
|
||||
|
@ -55,6 +55,9 @@
|
||||
<Filter Include="Configurations\Items">
|
||||
<UniqueIdentifier>{09fc0cbe-06f7-4fdf-944c-9833066bb9c8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Documentation\Menus">
|
||||
<UniqueIdentifier>{bea40439-f3a2-42f8-be1a-c0a815007075}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="olcPixelGameEngine.h">
|
||||
@ -326,6 +329,9 @@
|
||||
<ClCompile Include="InventoryWindow.cpp">
|
||||
<Filter>Source Files\Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CharacterInfoWindow.cpp">
|
||||
<Filter>Source Files\Interface</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
@ -397,6 +403,9 @@
|
||||
<Image Include="assets\heart.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="assets\menus\Character_Info.png">
|
||||
<Filter>Documentation\Menus</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Crawler.rc">
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "Crawler.h"
|
||||
#include "DEFINES.h"
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "safemap.h"
|
||||
#include "Item.h"
|
||||
@ -8,39 +7,27 @@
|
||||
#include "MenuLabel.h"
|
||||
#include "ScrollableWindowComponent.h"
|
||||
|
||||
INCLUDE_GFX
|
||||
typedef Attribute A;
|
||||
|
||||
void Menu::InitializeInventoryWindow(){
|
||||
constexpr int invWidth=5;
|
||||
constexpr int initialInvHeight=3;
|
||||
int invWidth="ThemeGlobal.InventoryWidth"_I;
|
||||
int initialInvHeight="ThemeGlobal.InventoryHeight"_I;
|
||||
|
||||
constexpr int itemSpacing=8;
|
||||
constexpr int buttonSize=24;
|
||||
constexpr int totalSpacing=buttonSize+itemSpacing;
|
||||
int itemSpacing="ThemeGlobal.InventoryItemSpacing"_I;
|
||||
int buttonSize="ThemeGlobal.InventoryButtonSize"_I;
|
||||
int totalSpacing=buttonSize+itemSpacing;
|
||||
|
||||
vf2d windowSize={totalSpacing*invWidth-itemSpacing+2+24,totalSpacing*(3+1)-itemSpacing+24}; //Need space for the button.
|
||||
vf2d windowSize={float(totalSpacing*invWidth-itemSpacing+2+24),float(totalSpacing*(3+1)-itemSpacing+24)}; //Need space for the button.
|
||||
|
||||
Menu*inventoryWindow=CreateMenu(INVENTORY,CENTERED,windowSize);
|
||||
|
||||
ScrollableWindowComponent*inventory=new ScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,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);
|
||||
|
||||
MenuFunc useItemFunc=[](MenuFuncData data){
|
||||
MenuItemButton*button=(MenuItemButton*)data.component;
|
||||
button->UseItem();
|
||||
};
|
||||
//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.
|
||||
|
||||
for(int i=0;i<Inventory::get("Consumables").size();i++){
|
||||
int x=i%invWidth;
|
||||
int y=i/invWidth;
|
||||
int itemIndex=y*invWidth+x;
|
||||
MenuItemButton*button=new MenuItemButton{INVENTORY,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
|
||||
inventory->AddComponent(inventoryWindow,"item"+std::to_string(itemIndex),button);
|
||||
}
|
||||
|
||||
MenuLabel*itemNameLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,initialInvHeight*totalSpacing-4},windowSize),"",false,true};
|
||||
MenuLabel*itemNameLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing-4)},windowSize),"",false,true};
|
||||
inventoryWindow->AddComponent("itemName",itemNameLabel);
|
||||
MenuLabel*itemDescriptionLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,initialInvHeight*totalSpacing+itemSpacing},{windowSize.x-4,windowSize.y-108}),"",true,true};
|
||||
MenuLabel*itemDescriptionLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing+itemSpacing)},{windowSize.x-4,windowSize.y-108}),"",true,true};
|
||||
inventoryWindow->AddComponent("itemDescription",itemDescriptionLabel);
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include "safemap.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Crawler.h"
|
||||
#include "Menu.h"
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_DATA
|
||||
@ -159,6 +160,9 @@ void Inventory::RemoveItem(IT it,uint32_t amt){
|
||||
}
|
||||
sortedList.erase(sortedList.begin()+count);
|
||||
_inventory.erase(it);
|
||||
ITCategory cat=ITEM_DATA[it].category;
|
||||
//Callback for GUI inventories.
|
||||
Menu::InventorySlotsUpdated(cat);
|
||||
}else{
|
||||
_inventory.at(it).amt-=amt;
|
||||
}
|
||||
@ -170,6 +174,8 @@ std::vector<IT>&Inventory::get(ITCategory itemCategory){
|
||||
|
||||
void Inventory::InsertIntoSortedInv(IT item){
|
||||
sortedInv.at(ITEM_DATA[item].category).push_back(item);
|
||||
//This should be a callback to menus that we need to update the interface with another item slot since a new one has appeared.
|
||||
Menu::InventorySlotsUpdated(ITEM_DATA[item].category);
|
||||
}
|
||||
|
||||
bool Inventory::ExecuteAction(IT item){
|
||||
|
@ -2,6 +2,9 @@
|
||||
#include "MenuComponent.h"
|
||||
#include "DEFINES.h"
|
||||
#include "safemap.h"
|
||||
#include "Item.h"
|
||||
#include "MenuItemButton.h"
|
||||
#include "ScrollableWindowComponent.h"
|
||||
|
||||
bool Menu::MOUSE_NAVIGATION=true;
|
||||
std::vector<Menu*>Menu::stack;
|
||||
@ -32,11 +35,13 @@ void Menu::InitializeMenus(){
|
||||
std::cout<<"WARNING! Menu Type "<<type<<" does not exist!"<<std::endl;
|
||||
throw;
|
||||
}
|
||||
//Lock up everything once it's done.
|
||||
menus[type]->buttons.SetInitialized();
|
||||
menus[type]->keyboardButtons.SetInitialized();
|
||||
for(auto&key:menus[type]->components){
|
||||
MenuComponent*component=key.second;
|
||||
component->AfterCreate();
|
||||
}
|
||||
menus[type]->components.SetInitialized(); //Lock all known components to prevent invalid access.
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,9 +52,33 @@ Menu*Menu::CreateMenu(MenuType type,vf2d pos,vf2d size){
|
||||
|
||||
void Menu::AddComponent(std::string key,MenuComponent*button){
|
||||
if(button->selectable){
|
||||
buttons[button->rect.pos.y].push_back(button);
|
||||
buttons.Unlock();
|
||||
if(buttons.count(button->rect.pos.y)){
|
||||
buttons.at(button->rect.pos.y).push_back(button);
|
||||
}else{
|
||||
buttons[button->rect.pos.y].push_back(button);
|
||||
}
|
||||
if(button->selectableViaKeyboard){
|
||||
keyboardButtons[button->rect.pos.y].push_back(button);
|
||||
keyboardButtons.Unlock();
|
||||
if(keyboardButtons.count(button->rect.pos.y)){
|
||||
keyboardButtons.at(button->rect.pos.y).push_back(button);
|
||||
}else{
|
||||
keyboardButtons[button->rect.pos.y].push_back(button);
|
||||
}
|
||||
}
|
||||
|
||||
//We must lock the values before calling sort. Sort seems to try and create new accesses.
|
||||
buttons.SetInitialized();
|
||||
keyboardButtons.SetInitialized();
|
||||
|
||||
//We make an assumption that menu components are supposed to be in left-to-right order. Sometimes we may add things out-of-order, so this fixes the problem by sorting the items afterwards.
|
||||
std::sort(buttons[button->rect.pos.y].begin(),buttons[button->rect.pos.y].end(),[](MenuComponent*c1,MenuComponent*c2){
|
||||
return c1->GetPos().x<c2->GetPos().x;
|
||||
});
|
||||
if(keyboardButtons.count(button->rect.pos.y)){ //Keyboard buttons may not necessarily contain this key...Let's be sure.
|
||||
std::sort(keyboardButtons[button->rect.pos.y].begin(),keyboardButtons[button->rect.pos.y].end(),[](MenuComponent*c1,MenuComponent*c2){
|
||||
return c1->GetPos().x<c2->GetPos().x;
|
||||
});
|
||||
}
|
||||
}else{
|
||||
displayComponents.push_back(button);
|
||||
@ -59,7 +88,9 @@ void Menu::AddComponent(std::string key,MenuComponent*button){
|
||||
throw;
|
||||
}
|
||||
button->name=key;
|
||||
components.Unlock(); //It's possible we can add a component later on, so we will make sure we remove the lock first.
|
||||
components[key]=button;
|
||||
components.SetInitialized();
|
||||
}
|
||||
|
||||
void Menu::CheckClickAndPerformMenuSelect(Crawler*game){
|
||||
@ -84,7 +115,6 @@ void Menu::HoverMenuSelect(Crawler*game){
|
||||
|
||||
void Menu::MenuSelect(Crawler*game){
|
||||
if(selection==vi2d{-1,-1}||buttons[selection.y][selection.x]->disabled)return;
|
||||
buttons[selection.y][selection.x]->onClick(MenuFuncData{*this,game,buttons[selection.y][selection.x]});
|
||||
if(buttons[selection.y][selection.x]->menuDest!=MenuType::ENUM_END){
|
||||
if(stack.size()<32){
|
||||
stack.push_back(menus[buttons[selection.y][selection.x]->menuDest]);//Navigate to the next menu.
|
||||
@ -93,6 +123,7 @@ void Menu::MenuSelect(Crawler*game){
|
||||
throw;
|
||||
}
|
||||
}
|
||||
buttons[selection.y][selection.x]->onClick(MenuFuncData{*this,game,buttons[selection.y][selection.x]});
|
||||
}
|
||||
|
||||
void Menu::Update(Crawler*game){
|
||||
@ -315,9 +346,9 @@ void Menu::KeyboardButtonNavigation(Crawler*game,vf2d menuPos){
|
||||
selectedItem=true;
|
||||
break;
|
||||
}
|
||||
if(key.first==selection.y&&
|
||||
if(key.first==selection.y
|
||||
//It's entirely possible this button was selected from the button selection list and may be out-of-bounds here.
|
||||
selection.x>=0&&selection.x<keyboardButtons[selection.y].size()){
|
||||
&&selection.x>=0&&selection.x<keyboardButtons[selection.y].size()){
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
@ -528,4 +559,54 @@ void Menu::SetMouseNavigation(bool mouseNavigation){
|
||||
lastActiveMousePos=game->GetMousePos();
|
||||
}
|
||||
MOUSE_NAVIGATION=mouseNavigation;
|
||||
};
|
||||
};
|
||||
|
||||
void Menu::InventorySlotsUpdated(ITCategory cat){
|
||||
//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);
|
||||
MenuType inventoryWindow;
|
||||
if(cat=="Consumables"){
|
||||
inventoryWindow=INVENTORY;
|
||||
}else
|
||||
if(cat=="Equipment"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
||||
return; //Currenly a no-op
|
||||
}else
|
||||
if(cat=="Accesories"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
||||
return; //Currenly a no-op
|
||||
}else
|
||||
if(cat=="Materials"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "Item.h"
|
||||
#include <stack>
|
||||
#include "safemap.h"
|
||||
#include "Theme.h"
|
||||
#include "Attributable.h"
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
#include <functional>
|
||||
|
||||
class Crawler;
|
||||
class MenuComponent;
|
||||
@ -25,8 +24,6 @@ class Menu:IAttributable{
|
||||
friend class Player;
|
||||
|
||||
float buttonHoldTime=0;
|
||||
std::map<int/*Y*/,std::vector<MenuComponent*>>buttons; //Buttons are stored in rows followed by their column order.
|
||||
std::map<int/*Y*/,std::vector<MenuComponent*>>keyboardButtons; //Button ordered storage for keyboard/menu
|
||||
std::vector<MenuComponent*>displayComponents; //Components that are only for displaying purposes.
|
||||
vi2d selection={-1,-1};
|
||||
vi2d lastActiveMousePos={};
|
||||
@ -50,11 +47,13 @@ public:
|
||||
static std::map<MenuType,Menu*>menus;
|
||||
vf2d pos; //Specify the upper-left corner of the window. Using CENTERED will always put this where the upper-left corner would center the window.
|
||||
vf2d size; //Size in tiles (24x24), every menu will be tile-based
|
||||
safemap<int/*Y*/,std::vector<MenuComponent*>>buttons; //Buttons are stored in rows followed by their column order.
|
||||
safemap<int/*Y*/,std::vector<MenuComponent*>>keyboardButtons; //Button ordered storage for keyboard/menu
|
||||
|
||||
static Theme&GetCurrentTheme();
|
||||
bool UsingMouseNavigation();
|
||||
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.
|
||||
private:
|
||||
Menu(vf2d pos,vf2d size);
|
||||
void HoverMenuSelect(Crawler*game);
|
||||
@ -65,6 +64,7 @@ private:
|
||||
static void InitializeTestMenu();
|
||||
static void InitializeTestSubMenu();
|
||||
static void InitializeInventoryWindow();
|
||||
static void InitializeCharacterInfoWindow();
|
||||
//X (0-3), Y (0-2) for specific 9-patch tile (tiled version).
|
||||
static Renderable&GetPatchPart(int x,int y);
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "Crawler.h"
|
||||
#include "MenuComponent.h"
|
||||
|
||||
typedef Attribute A;
|
||||
|
||||
MenuComponent::MenuComponent(MenuType parent,geom2d::rect<float>rect,std::string label,MenuFunc onClick,bool selectable,bool selectableViaKeyboard)
|
||||
:parentMenu(parent),rect(rect),label(label),menuDest(MenuType::ENUM_END),onClick(onClick),hoverEffect(0),selectable(selectable),selectableViaKeyboard(selectableViaKeyboard){}
|
||||
|
||||
@ -78,4 +80,8 @@ bool MenuComponent::PointWithinParent(MenuComponent*child,vi2d drawPos){
|
||||
|
||||
bool MenuComponent::HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton){
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
vf2d MenuComponent::GetPos(){
|
||||
return rect.pos;
|
||||
}
|
@ -25,6 +25,7 @@ protected:
|
||||
bool selectableViaKeyboard=true;
|
||||
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.
|
||||
virtual void Update(Crawler*game);
|
||||
virtual void Draw(Crawler*game,vf2d parentPos,bool focused);
|
||||
virtual void DrawDecal(Crawler*game,vf2d parentPos,bool focused);
|
||||
@ -36,6 +37,7 @@ public:
|
||||
void _Update(Crawler*game);
|
||||
void _Draw(Crawler*game,vf2d parentPos,bool focused);
|
||||
void _DrawDecal(Crawler*game,vf2d parentPos,bool focused);
|
||||
vf2d GetPos();
|
||||
//We picked up a draggable component, we should make a copy and return it here. If a nullptr is returned here, the pickup is not allowed.
|
||||
//WARNING!!! This allocates a brand new component when successful!!! Be prepared to clear it!
|
||||
virtual MenuComponent*PickUpDraggableItem();
|
||||
|
@ -13,7 +13,6 @@ class MenuItemButton:public MenuIconButton{
|
||||
private:
|
||||
std::vector<IT>&invRef;
|
||||
int inventoryIndex=0;
|
||||
bool valid=false;
|
||||
public:
|
||||
inline MenuItemButton(MenuType parent,geom2d::rect<float>rect,std::vector<IT>&invRef,int invIndex,MenuFunc onClick)
|
||||
:MenuIconButton(parent,rect,invRef.size()>invIndex?ITEM_DATA.at(invRef[invIndex]).Decal():nullptr,onClick),invRef(invRef),inventoryIndex(invIndex){
|
||||
|
@ -127,6 +127,31 @@ protected:
|
||||
virtual bool GetHoverState(Crawler*game,MenuComponent*child)override{
|
||||
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos+V(A::SCROLL_OFFSET),child->rect.size},game->GetMousePos());
|
||||
}
|
||||
//Calculates the bounds of all components.
|
||||
geom2d::rect<float> inline CalculateBounds(){
|
||||
geom2d::rect<float>bounds;
|
||||
for(MenuComponent*component:components){
|
||||
if(component->rect.pos.x<bounds.pos.x){
|
||||
float sizeIncrease=bounds.pos.x-component->rect.pos.x;
|
||||
bounds.size.x+=sizeIncrease;
|
||||
bounds.pos.x=component->rect.pos.x;
|
||||
}
|
||||
if(component->rect.right().start.x>bounds.right().start.x){
|
||||
float sizeIncrease=component->rect.right().start.x-bounds.right().start.x;
|
||||
bounds.size.x+=sizeIncrease;
|
||||
}
|
||||
if(component->rect.pos.y<bounds.pos.y){
|
||||
float sizeIncrease=bounds.pos.y-component->rect.pos.y;
|
||||
bounds.size.y+=sizeIncrease;
|
||||
bounds.pos.y=component->rect.pos.y;
|
||||
}
|
||||
if(component->rect.bottom().start.y>bounds.bottom().start.y){
|
||||
float sizeIncrease=component->rect.bottom().start.y-bounds.bottom().start.y;
|
||||
bounds.size.y+=sizeIncrease;
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
public:
|
||||
void inline AddComponent(Menu*parentMenu,std::string key,MenuComponent*button){
|
||||
components.push_back(button);
|
||||
@ -163,4 +188,53 @@ public:
|
||||
V(A::SCROLL_OFFSET).y+=rect.size.y/2;
|
||||
return true;
|
||||
};
|
||||
virtual inline size_t ComponentCount(){
|
||||
return components.size();
|
||||
}
|
||||
virtual void RemoveButton(MenuComponent*button){
|
||||
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);
|
||||
size_t removedCount=0;
|
||||
removedCount+=std::erase(buttonList,button);
|
||||
removedCount+=std::erase(keyboardButtonList,button);
|
||||
if(removedCount!=2){
|
||||
std::cout<<"WARNING! Attempted to remove buttons from button listing, but not found!";
|
||||
throw;
|
||||
}
|
||||
if(buttonList.size()==0){
|
||||
if(!Menu::menus[button->parentMenu]->buttons.erase(button->GetPos().y)){
|
||||
std::cout<<"WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if(keyboardButtonList.size()==0){
|
||||
if(!Menu::menus[button->parentMenu]->keyboardButtons.erase(button->GetPos().y)){
|
||||
std::cout<<"WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void 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.
|
||||
for(int i=0;i<components.size();i++){
|
||||
MenuComponent*button=components[i];
|
||||
button->Update(game); //We have to call update to update the validation state.
|
||||
//HACK ALERT!! This only gets called on inventories...And only on inventory items, which would have the valid flag set. We only care about components that are inventory slots.
|
||||
if(!button->valid){
|
||||
for(int j=i;j<components.size()-1;j++){
|
||||
//Take the item in the next slot and move it to this slot.
|
||||
Menu::menus[components[j]->parentMenu]->components.at(components[j]->name)=components[j+1];
|
||||
components[j]=components[j+1];
|
||||
}
|
||||
MenuComponent*lastButton=Menu::menus[components[components.size()-1]->parentMenu]->components.at(components[components.size()-1]->name);
|
||||
//Now we have to fix up the keyboard button list.
|
||||
RemoveButton(lastButton);
|
||||
Menu::menus[components[components.size()-1]->parentMenu]->components.erase(components[components.size()-1]->name);
|
||||
//Now delete the last slot.
|
||||
components.erase(components.end()-1);
|
||||
i--; //Subtract one from the index so we don't accidently skip slots.
|
||||
}
|
||||
}
|
||||
bounds=CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
|
||||
}
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
#include "Crawler.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Menu.h"
|
||||
#include "Item.h"
|
||||
|
||||
INCLUDE_MONSTER_LIST
|
||||
|
||||
@ -13,6 +14,21 @@ void State_GameRun::OnUserUpdate(Crawler*game){
|
||||
if(game->encounterStarted&&game->totalBossEncounterMobs>0){
|
||||
game->encounterDuration+=game->GetElapsedTime();
|
||||
}
|
||||
|
||||
|
||||
if(game->GetKey(O).bPressed){
|
||||
Inventory::AddItem("Dummy Item 14",192);
|
||||
Inventory::AddItem("Dummy Item 15",35);
|
||||
Inventory::AddItem("Dummy Item 16",6);
|
||||
Inventory::AddItem("Dummy Item 17",3);
|
||||
Inventory::AddItem("Dummy Item 18",1);
|
||||
Inventory::AddItem("Dummy Item 19",8);
|
||||
Inventory::AddItem("Dummy Item 20",4);
|
||||
}
|
||||
if(game->GetKey(P).bPressed){
|
||||
Inventory::AddItem("Medium Mana Potion",1);
|
||||
}
|
||||
|
||||
game->HandleUserInput(game->GetElapsedTime());
|
||||
|
||||
if(game->GetKey(T).bPressed){
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 2127
|
||||
#define VERSION_BUILD 2167
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -13,6 +13,15 @@ ThemeGlobal
|
||||
|
||||
# How far the mouse has to move before mouse mode becomes active from keyboard/controller input mode.
|
||||
MouseActivationDistance = 8
|
||||
|
||||
# How many slots wide the inventory list is.
|
||||
InventoryWidth = 5
|
||||
# How tall the view is for the inventory window (before scrolling)
|
||||
InventoryHeight = 3
|
||||
# Space between each item slot.
|
||||
InventoryItemSpacing = 8
|
||||
# Size of each button.
|
||||
InventoryButtonSize = 24
|
||||
}
|
||||
|
||||
Themes
|
||||
|
BIN
Crawler/assets/menus/Character_Info.png
Normal file
BIN
Crawler/assets/menus/Character_Info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -6,7 +6,7 @@ class safemap{
|
||||
std::map<T,O>map;
|
||||
bool initialized=false;
|
||||
public:
|
||||
O&operator[](T key){
|
||||
O&operator[](T key){
|
||||
if(initialized&&map.count(key)==0){
|
||||
std::cout<<"WARNING! Trying to get non-existent key "<<key<<"!"<<std::endl;
|
||||
throw;
|
||||
@ -35,6 +35,10 @@ public:
|
||||
size_t size(){
|
||||
return map.size();
|
||||
}
|
||||
//Unlocks the map so items can be added to it again. USE WITH CAUTION! And make sure to lock the map again.
|
||||
void Unlock(){
|
||||
initialized=false;
|
||||
}
|
||||
//Clears the entire map and unlocks the map so items can be added to it again.
|
||||
void Reset(){
|
||||
initialized=false;
|
||||
@ -46,6 +50,9 @@ public:
|
||||
auto end()const{
|
||||
return map.end();
|
||||
}
|
||||
size_t erase(const T&key){
|
||||
return map.erase(key);
|
||||
}
|
||||
};
|
||||
|
||||
//A class that has an initialization lock so that when the lock is activated, any further gets that are missing items in it will report themselves for easier debugging detection.
|
||||
|
Loading…
x
Reference in New Issue
Block a user