diff --git a/Crawler/CharacterRotatingDisplay.h b/Crawler/CharacterRotatingDisplay.h index 2099af2d..1bb699c4 100644 --- a/Crawler/CharacterRotatingDisplay.h +++ b/Crawler/CharacterRotatingDisplay.h @@ -9,7 +9,7 @@ class CharacterRotatingDisplay:public MenuComponent{ protected: Decal*icon; float timer; - float rotatingFactor=18; + float rotatingFactor=7; float perspectiveFactor=6; public: inline CharacterRotatingDisplay(MenuType parent,geom2d::rectrect,Decal*icon) diff --git a/Crawler/ClassSelectionWindow.cpp b/Crawler/ClassSelectionWindow.cpp index e537c384..12e15896 100644 --- a/Crawler/ClassSelectionWindow.cpp +++ b/Crawler/ClassSelectionWindow.cpp @@ -3,6 +3,7 @@ #include "DEFINES.h" #include "Menu.h" #include "MenuLabel.h" +#include "MenuAnimatedIconButton.h" INCLUDE_game typedef Attribute A; @@ -14,58 +15,62 @@ void Menu::InitializeClassSelectionWindow(){ vf2d outlineSize=classSelectionWindow->size-vf2d{13,13}; + MenuLabel*classSelectionLabel=new MenuLabel(CLASS_SELECTION,{{4,20},{outlineSize.x,32}},"Choose a Character Class",2,true,true,true,true); + classSelectionWindow->AddComponent("Class Selection Title Label",classSelectionLabel); + 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}; + 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. 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); + std::arrayclassNames={ + Warrior::name, + Ranger::name, + Wizard::name, + Thief::name, + Trapper::name, + Witch::name, + }; + std::arrayclassAnimationNames={ + Warrior::walk_s, + Ranger::walk_s, + Wizard::walk_s, + Thief::walk_s, + Trapper::walk_s, + Witch::walk_s, + }; + + for(int i=0;i<6;i++){ + std::string className=classNames[i]; + std::string classAnimationName=classAnimationNames[i]; + vf2d offsetPos={ + buttonStartPos.x+(buttonSize.x+buttonPadding.x)*float(i%3), + buttonStartPos.y+(buttonSize.y+buttonPadding.y+2*outlineSize.y/9)*float(i/3)+2*outlineSize.y/9, + }; + vf2d backgroundOffsetPos={ + buttonStartPos.x+(buttonSize.x+buttonPadding.x)*float(i%3), + buttonStartPos.y+(buttonSize.y+buttonPadding.y+2*outlineSize.y/9)*float(i/3), + }; + vf2d backgroundSize={floor(outlineSize.y/3-buttonPadding.y*3),outlineSize.y/3-buttonPadding.y*3}; //The floor is for fixing a small pixel rounding bug. + MenuLabel*backgroundOutline=new MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,backgroundSize},"",1,true,false,true,true); + MenuLabel*classLabel=new MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,buttonSize},className,1,true,true); + MenuAnimatedIconButton*classSprite=new MenuAnimatedIconButton(CLASS_SELECTION,{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){},false); + MenuComponent*classButton=new MenuComponent(CLASS_SELECTION,{offsetPos,buttonSize},"Info",CLASS_INFO, + [](MenuFuncData data){ + data.menu.S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION); + delete Menu::menus[CLASS_INFO]; + Menu::InitializeClassInfoWindow(); + }); + classButton->S(A::CLASS_SELECTION)=className; + classSelectionWindow->AddComponent(className+" Button",classButton); + classSelectionWindow->AddComponent(className+" Background",backgroundOutline); + classSelectionWindow->AddComponent(className+" Label",classLabel); + classSelectionWindow->AddComponent(className+" Icon",classSprite); + } } \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 62d744c0..826693b0 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -109,6 +109,14 @@ bool Crawler::OnUserCreate(){ InitializeGraphics(); InitializeClasses(); + Monster::InitializeStrategies(); + //Animations + sig::Animation::InitializeAnimations(); + MonsterData::InitializeMonsterData(); + + sig::Animation::SetupPlayerAnimations(); + view=TileTransformedView{GetScreenSize(),{1,1}}; + Menu::InitializeMenus(); Inventory::AddItem("Small Health Potion",16); @@ -130,14 +138,6 @@ bool Crawler::OnUserCreate(){ Inventory::AddItem("Bandages",10); Inventory::AddItem("Blue Slime Remains",22); - Monster::InitializeStrategies(); - //Animations - sig::Animation::InitializeAnimations(); - MonsterData::InitializeMonsterData(); - - sig::Animation::SetupPlayerAnimations(); - view=TileTransformedView{GetScreenSize(),{1,1}}; - LoadLevel(LEVEL_NAMES["starting_map"_S]); ChangePlayerClass(WARRIOR); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 352b7b62..cff5ede7 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -156,7 +156,7 @@ - Level3 + TurnOffAllWarnings true true true @@ -219,7 +219,7 @@ - Level3 + TurnOffAllWarnings true true true @@ -331,6 +331,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index 4114a6fc..e58383cf 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -350,6 +350,9 @@ Source Files\Interface + + Header Files\Interface + diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index d275580c..f9ca84b2 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -14,6 +14,18 @@ safeunorderedmapMenu::themes; safemap>Menu::inventoryListeners; const vf2d Menu::CENTERED = {-456,-456}; std::vectorMenu::unhandledComponents; +////////////////////////////////////////////////////////////////////////////////////////////////// +///__///////////////////////////////////////////////////////////////////////////////////////////// +//| |//////////////////////////////////////////////////////////////////////////////////////////// +//| |/////WARNING! If you are adding something here you likely are adding another container with MenuComponent pointers in it right now. +//| |/////Because we are handling raw pointers, you must also add this container to the list of iterating search removal contains that occur in the +//| |/////DESTRUCTOR of MenuComponents!!!!! THIS IS NOT A DRILL! +//|__|//////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +///__///////////////////////////////////////////////////////////////////////////////////////////// +//|__///////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// MenuType Menu::lastMenuTypeCreated; std::string Menu::lastRegisteredComponent; diff --git a/Crawler/Menu.h b/Crawler/Menu.h index f2c3da87..41bad1c7 100644 --- a/Crawler/Menu.h +++ b/Crawler/Menu.h @@ -79,7 +79,7 @@ private: static void InitializeClassInfoWindow(); static void InitializeClassSelectionWindow(); static void InitializeMainMenuWindow(); - //X (0-3), Y (0-2) for specific 9-patch tile (tiled version). + //X (0-2), Y (0-2) for specific 9-patch tile (tiled version). static Renderable&GetPatchPart(int x,int y); void KeyboardButtonNavigation(Crawler*game,vf2d menuPos); diff --git a/Crawler/MenuAnimatedIconButton.h b/Crawler/MenuAnimatedIconButton.h new file mode 100644 index 00000000..d8e90f42 --- /dev/null +++ b/Crawler/MenuAnimatedIconButton.h @@ -0,0 +1,28 @@ +#pragma once +#include "MenuIconButton.h" +#include "DEFINES.h" +#include "Crawler.h" + +INCLUDE_game +INCLUDE_ANIMATION_DATA + +class MenuAnimatedIconButton:public MenuIconButton{ +protected: + std::string animation; +private: + float animationTime=0; +public: + inline MenuAnimatedIconButton(MenuType parent,geom2d::rectrect,std::string animation,MenuFunc onClick,bool selectable=true) + :MenuIconButton(parent,rect,nullptr,onClick,selectable),animation(animation){} +protected: + virtual inline void Update(Crawler*game)override{ + MenuIconButton::Update(game); + animationTime+=game->GetElapsedTime(); + } + virtual inline void Draw(Crawler*game,vf2d parentPos,bool focused)override{ + MenuComponent::Draw(game,parentPos,focused); //INTENTIONAL! The way we draw animations is different from static images, we skip over MenuIconButton's draw! + Sprite*spr=ANIMATION_DATA[animation].GetFrame(animationTime).GetSourceImage()->Sprite(); + geom2d::rectsprRect=ANIMATION_DATA[animation].GetFrame(animationTime).GetSourceRect(); + game->DrawPartialSprite(parentPos+rect.middle()-sprRect.size/2,spr,sprRect.pos,sprRect.size,1,Sprite::Flip::NONE); + } +}; \ No newline at end of file diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp index f479dad6..4f4e3368 100644 --- a/Crawler/MenuComponent.cpp +++ b/Crawler/MenuComponent.cpp @@ -106,4 +106,8 @@ vf2d MenuComponent::GetPos(){ return rect.pos; } -void MenuComponent::OnInventorySlotsUpdate(ITCategory cat){} \ No newline at end of file +void MenuComponent::OnInventorySlotsUpdate(ITCategory cat){} + +std::string MenuComponent::GetLabel(){ + return label; +} \ No newline at end of file diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h index 2a5755bc..d71efda3 100644 --- a/Crawler/MenuComponent.h +++ b/Crawler/MenuComponent.h @@ -52,4 +52,5 @@ public: 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); + std::string GetLabel(); }; \ No newline at end of file diff --git a/Crawler/MenuIconButton.h b/Crawler/MenuIconButton.h index d6ab4082..294f56bb 100644 --- a/Crawler/MenuIconButton.h +++ b/Crawler/MenuIconButton.h @@ -9,8 +9,8 @@ class MenuIconButton:public MenuComponent{ protected: Decal*icon; public: - inline MenuIconButton(MenuType parent,geom2d::rectrect,Decal*icon,MenuFunc onClick) - :MenuComponent(parent,rect,"",onClick),icon(icon){} + inline MenuIconButton(MenuType parent,geom2d::rectrect,Decal*icon,MenuFunc onClick,bool selectable=true) + :MenuComponent(parent,rect,"",onClick,selectable),icon(icon){} protected: virtual inline void Update(Crawler*game)override{ MenuComponent::Update(game); diff --git a/Crawler/Version.h b/Crawler/Version.h index 0d7fec4b..56b0df1b 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 2335 +#define VERSION_BUILD 2391 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/nico-warrior.png b/Crawler/assets/nico-warrior.png index 56cbe0fe..17b3bd36 100644 Binary files a/Crawler/assets/nico-warrior.png and b/Crawler/assets/nico-warrior.png differ diff --git a/Crawler/assets/nico-warrior.xcf b/Crawler/assets/nico-warrior.xcf index f118bc8a..cf2bc664 100644 Binary files a/Crawler/assets/nico-warrior.xcf and b/Crawler/assets/nico-warrior.xcf differ diff --git a/Crawler/safemap.h b/Crawler/safemap.h index 5cab0820..a303b478 100644 --- a/Crawler/safemap.h +++ b/Crawler/safemap.h @@ -6,7 +6,7 @@ class safemap{ std::mapmap; 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 "<