diff --git a/Crawler/ClassSelectionWindow.cpp b/Crawler/ClassSelectionWindow.cpp index 52b4f124..e537c384 100644 --- a/Crawler/ClassSelectionWindow.cpp +++ b/Crawler/ClassSelectionWindow.cpp @@ -8,7 +8,64 @@ INCLUDE_game typedef Attribute A; void Menu::InitializeClassSelectionWindow(){ - Menu*classSelectionWindow=CreateMenu(CLASS_SELECTION,CENTERED,game->GetScreenSize()-vi2d{4,4}); + Menu*classSelectionWindow=CreateMenu(CLASS_SELECTION,CENTERED,game->GetScreenSize()-vi2d{24,24}); classSelectionWindow->S(A::CLASS_SELECTION)="Warrior"; //Default selected class. + + vf2d outlineSize=classSelectionWindow->size-vf2d{13,13}; + + MenuLabel*outline=new MenuLabel(CLASS_SELECTION,{{4,4},outlineSize},"",1,true,false,true,false); + + classSelectionWindow->AddComponent("Outline Border",outline); + + vf2d buttonPadding={2,2}; + vf2d buttonSize={outlineSize.y/3-buttonPadding.y*3,outlineSize.y/3-buttonPadding.y*3}; + + float buttonTotalWidth=(buttonSize.x+buttonPadding.x)*3; + + vf2d buttonStartPos=outline->GetPos()+vf2d{outlineSize.x/2,outlineSize.y/3}-vf2d{buttonTotalWidth/2,0}; + + MenuComponent*warriorButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{0,0},buttonSize},Warrior::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Warrior::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + MenuComponent*rangerButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{1,0},buttonSize},Ranger::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Ranger::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + MenuComponent*wizardButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{2,0},buttonSize},Wizard::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Wizard::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + MenuComponent*thiefButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{0,1},buttonSize},Thief::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Thief::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + MenuComponent*trapperButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{1,1},buttonSize},Trapper::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Trapper::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + MenuComponent*witchButton=new MenuComponent(CLASS_SELECTION,{buttonStartPos+(buttonSize+buttonPadding)*vf2d{2,1},buttonSize},Witch::name,CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=Witch::name; + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + + classSelectionWindow->AddComponent("Warrior Button",warriorButton); + classSelectionWindow->AddComponent("Ranger Button",rangerButton); + classSelectionWindow->AddComponent("Wizard Button",wizardButton); + classSelectionWindow->AddComponent("Thief Button",thiefButton); + classSelectionWindow->AddComponent("Trapper Button",trapperButton); + classSelectionWindow->AddComponent("Witch Button",witchButton); } \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 4b956a11..62d744c0 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -107,6 +107,7 @@ bool Crawler::OnUserCreate(){ ItemInfo::InitializeItems(); InitializeGraphics(); + InitializeClasses(); Menu::InitializeMenus(); @@ -138,7 +139,6 @@ bool Crawler::OnUserCreate(){ view=TileTransformedView{GetScreenSize(),{1,1}}; LoadLevel(LEVEL_NAMES["starting_map"_S]); - InitializeClasses(); ChangePlayerClass(WARRIOR); GameState::Initialize(); diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index d58ab5bf..1c152b17 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -13,6 +13,7 @@ std::string Menu::themeSelection="BlueDefault"; safeunorderedmapMenu::themes; safemap>Menu::inventoryListeners; const vf2d Menu::CENTERED = {-456,-456}; +std::vectorMenu::unhandledComponents; INCLUDE_GFX extern vi2d WINDOW_SIZE; @@ -25,6 +26,12 @@ Menu::Menu(vf2d pos,vf2d size) overlay.Create(WINDOW_SIZE.x,WINDOW_SIZE.y); } +Menu::~Menu(){ + for(auto key:components){ + delete key.second; + } +} + void Menu::InitializeMenus(){ stack.reserve(32); InitializeTestMenu(); @@ -47,6 +54,18 @@ void Menu::InitializeMenus(){ component->AfterCreate(); } } + + if(Menu::unhandledComponents.size()>0){ + std::cout<<"WARNING! There are "<name<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. @@ -127,7 +148,6 @@ 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){ diff --git a/Crawler/Menu.h b/Crawler/Menu.h index fac7672d..59934711 100644 --- a/Crawler/Menu.h +++ b/Crawler/Menu.h @@ -27,7 +27,6 @@ class Menu:IAttributable{ friend class ItemInfo; float buttonHoldTime=0; - std::vectordisplayComponents; //Comp.onents that are only for displaying purposes. vi2d selection={-1,-1}; vi2d lastActiveMousePos={}; @@ -37,7 +36,7 @@ class Menu:IAttributable{ public: //The constructor is private. Use CreateMenu() instead! Menu()=default; - virtual ~Menu()=default; + ~Menu(); void AddComponent(std::string key,MenuComponent*button); void Update(Crawler*game); void Draw(Crawler*game); @@ -47,8 +46,10 @@ public: static std::vectorstack; static std::string themeSelection; static safeunorderedmapthemes; + static std::vectorunhandledComponents; //This list contains MenuComponents that are created and haven't been assigned via AddComponent. If we get to the end of menu initialization and there are any components in this vector, we have leaked memory and will report this. static const vf2d CENTERED; safemapcomponents; //A friendly way to interrogate any component we are interested in. + std::vectordisplayComponents; //Components that are only for displaying purposes. static std::mapmenus; 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 diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp index c458e4f8..82e4129f 100644 --- a/Crawler/MenuComponent.cpp +++ b/Crawler/MenuComponent.cpp @@ -4,11 +4,27 @@ typedef Attribute A; MenuComponent::MenuComponent(MenuType parent,geom2d::rectrect,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){} + :parentMenu(parent),rect(rect),label(label),menuDest(MenuType::ENUM_END),onClick(onClick),hoverEffect(0),selectable(selectable),selectableViaKeyboard(selectableViaKeyboard){ + Menu::unhandledComponents.push_back(this); +} MenuComponent::MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuType menuDest,MenuFunc onClick,bool selectable,bool selectableViaKeyboard) :MenuComponent(parent,rect,label,onClick,selectable,selectableViaKeyboard){ this->menuDest=menuDest; + Menu::unhandledComponents.push_back(this); +} + +MenuComponent::~MenuComponent(){ + Menu*pMenu=Menu::menus[parentMenu]; + for(auto key:pMenu->buttons){ + std::vector&components=key.second; + std::erase_if(components,[&](MenuComponent*component){return component==this;}); + } + for(auto key:pMenu->keyboardButtons){ + std::vector&components=key.second; + std::erase_if(components,[&](MenuComponent*component){return component==this;}); + } + std::erase_if(pMenu->displayComponents,[&](MenuComponent*component){return component==this;}); } void MenuComponent::AfterCreate(){} diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h index c594f6da..76687c0c 100644 --- a/Crawler/MenuComponent.h +++ b/Crawler/MenuComponent.h @@ -37,6 +37,7 @@ protected: public: MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuFunc onClick,bool selectable=true,bool selectableViaKeyboard=true); MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuType menuDest,MenuFunc onClick,bool selectable=true,bool selectableViaKeyboard=true); + virtual ~MenuComponent(); void _Update(Crawler*game); void _Draw(Crawler*game,vf2d parentPos,bool focused); void _DrawDecal(Crawler*game,vf2d parentPos,bool focused); diff --git a/Crawler/ScrollableWindowComponent.h b/Crawler/ScrollableWindowComponent.h index cd0cc4ea..e8fae819 100644 --- a/Crawler/ScrollableWindowComponent.h +++ b/Crawler/ScrollableWindowComponent.h @@ -28,7 +28,10 @@ public: } virtual inline ~ScrollableWindowComponent(){ - + MenuComponent::~MenuComponent(); + for(MenuComponent*component:components){ + delete component; + } } protected: virtual inline void AfterCreate()override{ diff --git a/Crawler/State_MainMenu.cpp b/Crawler/State_MainMenu.cpp index d87fa0cb..cd969223 100644 --- a/Crawler/State_MainMenu.cpp +++ b/Crawler/State_MainMenu.cpp @@ -3,7 +3,7 @@ #include "Menu.h" void State_MainMenu::OnStateChange(GameState*prevState){ - Menu::OpenMenu(MenuType::CLASS_INFO); + Menu::OpenMenu(MenuType::CLASS_SELECTION); }; void State_MainMenu::OnUserUpdate(Crawler*game){ diff --git a/Crawler/Version.h b/Crawler/Version.h index c627e79a..c7639ece 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 2306 +#define VERSION_BUILD 2329 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/config/gfx/gfx.txt b/Crawler/assets/config/gfx/gfx.txt index 456f03b4..9232fd76 100644 --- a/Crawler/assets/config/gfx/gfx.txt +++ b/Crawler/assets/config/gfx/gfx.txt @@ -57,4 +57,5 @@ Images # Full Class Icons GFX_Warrior_Full = knight_full_render1.png + GFX_Unknown_Full = unknown_full_render.png } \ No newline at end of file