Correct memory leak in consuming items from inventory. Added overworld menu layout. Warrior Up walk animation has head bobbing like all the others now. Fixed alignment of items for ScrollableWindowComponents, fix scrollbar resizing when parent component has offsets.

pull/28/head
sigonasr2 1 year ago
parent 395b2e3ab8
commit 30a5cdc488
  1. 2
      Crawler/CharacterInfoWindow.cpp
  2. 5
      Crawler/ClassSelectionWindow.cpp
  3. 18
      Crawler/Crawler.cpp
  4. 5
      Crawler/Crawler.h
  5. 1
      Crawler/Crawler.vcxproj
  6. 3
      Crawler/Crawler.vcxproj.filters
  7. 3
      Crawler/DEFINES.h
  8. 2
      Crawler/GameState.cpp
  9. 9
      Crawler/InventoryScrollableWindowComponent.h
  10. 2
      Crawler/InventoryWindow.cpp
  11. 15
      Crawler/Item.cpp
  12. 4
      Crawler/Item.h
  13. 6
      Crawler/Map.cpp
  14. 6
      Crawler/Map.h
  15. 19
      Crawler/Menu.cpp
  16. 7
      Crawler/Menu.h
  17. 1
      Crawler/MenuAnimatedIconToggleButton.h
  18. 6
      Crawler/MenuComponent.cpp
  19. 5
      Crawler/MenuItemButton.h
  20. 1
      Crawler/Monster.h
  21. 3
      Crawler/MonsterData.cpp
  22. 52
      Crawler/OverworldMapLevelWindow.cpp
  23. 28
      Crawler/ScrollableWindowComponent.h
  24. 2
      Crawler/State_OverworldMap.cpp
  25. 7
      Crawler/TMXParser.h
  26. 4
      Crawler/TestMenu.cpp
  27. 3
      Crawler/TestSubMenu.cpp
  28. 2
      Crawler/Version.h
  29. 2
      Crawler/assets/config/configuration.txt
  30. 59942
      Crawler/assets/memoryleak.txt
  31. BIN
      Crawler/assets/nico-warrior.png
  32. BIN
      Crawler/assets/nico-warrior.xcf
  33. 11
      Crawler/olcUTIL_Camera2D.h

@ -49,7 +49,7 @@ void Menu::InitializeClassInfoWindow(){
classInfoWindow->AddComponent("Ability 3 Display",ability3); classInfoWindow->AddComponent("Ability 3 Display",ability3);
classInfoWindow->AddComponent("Right Click Ability Display",rightClickAbility); classInfoWindow->AddComponent("Right Click Ability Display",rightClickAbility);
MenuComponent*backButton=NEW MenuComponent(CLASS_INFO,{{classInfoWindow->center().x/2,healthDisplayLabelPos.y+32*4+abilityIconOffsets.y+12},{classInfoWindow->size.x/2,16}},"Back",[](MenuFuncData data){Menu::CloseMenu();}); MenuComponent*backButton=NEW MenuComponent(CLASS_INFO,{{classInfoWindow->center().x/2,healthDisplayLabelPos.y+32*4+abilityIconOffsets.y+12},{classInfoWindow->size.x/2,16}},"Back",[](MenuFuncData data){Menu::CloseMenu();return true;});
classInfoWindow->AddComponent("Back Button",backButton); classInfoWindow->AddComponent("Back Button",backButton);
} }

@ -26,12 +26,13 @@ void Menu::InitializeClassSelectionWindow(){
vf2d navigationButtonSize={24*2.5f,16}; vf2d navigationButtonSize={24*2.5f,16};
MenuComponent*backButton=NEW MenuComponent(CLASS_SELECTION,{{4+2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Back",[](MenuFuncData data){Menu::CloseMenu();}); MenuComponent*backButton=NEW MenuComponent(CLASS_SELECTION,{{4+2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Back",[](MenuFuncData data){Menu::CloseMenu();return true;});
classSelectionWindow->AddComponent("Back Button",backButton); classSelectionWindow->AddComponent("Back Button",backButton);
MenuComponent*confirmButton=NEW MenuComponent(CLASS_SELECTION,{{outlineSize.x+4-navigationButtonSize.x-2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Confirm",[](MenuFuncData data){ MenuComponent*confirmButton=NEW MenuComponent(CLASS_SELECTION,{{outlineSize.x+4-navigationButtonSize.x-2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Confirm",[](MenuFuncData data){
std::string selectedClass=data.component->S(A::CLASS_SELECTION); std::string selectedClass=data.component->S(A::CLASS_SELECTION);
data.game->ChangePlayerClass(classutils::StringToClass(selectedClass)); data.game->ChangePlayerClass(classutils::StringToClass(selectedClass));
GameState::ChangeState(States::OVERWORLD_MAP); GameState::ChangeState(States::OVERWORLD_MAP);
return true;
}); });
confirmButton->disabled=true; confirmButton->disabled=true;
classSelectionWindow->AddComponent("Confirm",confirmButton); classSelectionWindow->AddComponent("Confirm",confirmButton);
@ -79,6 +80,7 @@ void Menu::InitializeClassSelectionWindow(){
MenuAnimatedIconToggleButton*classSprite=NEW MenuAnimatedIconToggleButton(CLASS_SELECTION,{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){ MenuAnimatedIconToggleButton*classSprite=NEW MenuAnimatedIconToggleButton(CLASS_SELECTION,{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){
data.menu.components["Confirm"]->Enable(true); data.menu.components["Confirm"]->Enable(true);
data.menu.components["Confirm"]->S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION); data.menu.components["Confirm"]->S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION);
return true;
}); });
toggleGroup.push_back(classSprite); toggleGroup.push_back(classSprite);
MenuComponent*classButton=NEW MenuComponent(CLASS_SELECTION,{offsetPos,buttonSize},"Info",CLASS_INFO, MenuComponent*classButton=NEW MenuComponent(CLASS_SELECTION,{offsetPos,buttonSize},"Info",CLASS_INFO,
@ -86,6 +88,7 @@ void Menu::InitializeClassSelectionWindow(){
data.menu.S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION); data.menu.S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION);
delete Menu::menus[CLASS_INFO]; delete Menu::menus[CLASS_INFO];
Menu::InitializeClassInfoWindow(); Menu::InitializeClassInfoWindow();
return true;
}); });
classSprite->S(A::CLASS_SELECTION)=classButton->S(A::CLASS_SELECTION)=className; classSprite->S(A::CLASS_SELECTION)=classButton->S(A::CLASS_SELECTION)=className;
classSelectionWindow->AddComponent(className+" Button",classButton); classSelectionWindow->AddComponent(className+" Button",classButton);

@ -1368,11 +1368,7 @@ void Crawler::LoadLevel(MapName map){
player->SetPos(MAP_DATA[map].MapData.playerSpawnLocation); player->SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
vf2d cameraStartPos=player->GetPos()+vf2d(-24*6,0); vf2d cameraStartPos=player->GetPos()+vf2d(-24*6,0);
camera.SetMode(Camera2D::Mode::Simple); camera.MoveCamera(cameraStartPos);
camera.SetTarget(cameraStartPos);
camera.Update(game->GetElapsedTime());
camera.SetMode(Camera2D::Mode::LazyFollow);
camera.SetTarget(player->GetPos());
pathfinder.Initialize(); pathfinder.Initialize();
} }
@ -1779,7 +1775,9 @@ void Crawler::RenderMenu(){
Menu::stack.back()->Update(this); Menu::stack.back()->Update(this);
} }
if(Menu::stack.size()>0){ if(Menu::stack.size()>0){
FillRectDecal({0,0},WINDOW_SIZE,{0,0,0,uint8_t(255*0.4)}); if(Menu::cover){
FillRectDecal({0,0},WINDOW_SIZE,{0,0,0,uint8_t(255*0.4)});
}
for(Menu*menu:Menu::stack){ for(Menu*menu:Menu::stack){
menu->Draw(this); menu->Draw(this);
} }
@ -1883,4 +1881,12 @@ void Crawler::ValidateGameStatus(){
void Crawler::RenderVersionInfo(){ void Crawler::RenderVersionInfo(){
std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD)); std::string versionStr("v" + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + "." + std::to_string(VERSION_BUILD));
DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4,versionStr,WHITE,BLACK,{0.4,0.4},0.4); DrawShadowStringDecal(vf2d{ GetScreenSize() } - vf2d{ GetTextSize(versionStr) }*0.4,versionStr,WHITE,BLACK,{0.4,0.4},0.4);
}
int Crawler::GetCurrentChapter(){
return chapter;
}
void Crawler::SetChapter(int chapter){
this->chapter=chapter;
} }

@ -28,11 +28,11 @@ public:
static float SIZE_CHANGE_SPEED; static float SIZE_CHANGE_SPEED;
float levelTime; float levelTime;
Camera2D camera; Camera2D camera;
std::map<MapName,Map>MAP_DATA;
private: private:
std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted; std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted;
std::vector<TileRenderData*>tilePreparationList,tileForegroundList; std::vector<TileRenderData*>tilePreparationList,tileForegroundList;
std::vector<vf2d>circleCooldownPoints; std::vector<vf2d>circleCooldownPoints;
std::map<MapName,Map>MAP_DATA;
std::map<std::string,TilesetData>MAP_TILESETS; std::map<std::string,TilesetData>MAP_TILESETS;
vf2d worldShake={}; vf2d worldShake={};
float worldShakeTime=0; float worldShakeTime=0;
@ -58,6 +58,7 @@ private:
float encounterDuration=0; float encounterDuration=0;
bool encounterStarted=false; bool encounterStarted=false;
int totalBossEncounterMobs=0; int totalBossEncounterMobs=0;
int chapter=1; //We start at chapter 1.
std::vector<Monster>monstersToBeSpawned; std::vector<Monster>monstersToBeSpawned;
@ -135,6 +136,8 @@ public:
void InitializeGraphics(); void InitializeGraphics();
void RenderVersionInfo(); void RenderVersionInfo();
MapTag GetCurrentMap(); MapTag GetCurrentMap();
int GetCurrentChapter();
void SetChapter(int chapter);
struct TileGroupData{ struct TileGroupData{
vi2d tilePos; vi2d tilePos;

@ -343,6 +343,7 @@
<ClCompile Include="MenuComponent.cpp" /> <ClCompile Include="MenuComponent.cpp" />
<ClCompile Include="Meteor.cpp" /> <ClCompile Include="Meteor.cpp" />
<ClCompile Include="OverworldDisplayWindow.cpp" /> <ClCompile Include="OverworldDisplayWindow.cpp" />
<ClCompile Include="OverworldMapLevelWindow.cpp" />
<ClCompile Include="RunAway.cpp" /> <ClCompile Include="RunAway.cpp" />
<ClCompile Include="RunTowards.cpp" /> <ClCompile Include="RunTowards.cpp" />
<ClCompile Include="Pathfinding.cpp" /> <ClCompile Include="Pathfinding.cpp" />

@ -389,6 +389,9 @@
<ClCompile Include="OverworldDisplayWindow.cpp"> <ClCompile Include="OverworldDisplayWindow.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="OverworldMapLevelWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -15,7 +15,8 @@
#define INCLUDE_GFX extern safemap<std::string,Renderable>GFX; #define INCLUDE_GFX extern safemap<std::string,Renderable>GFX;
#define INCLUDE_ITEM_DATA extern safemap<std::string,ItemInfo>ITEM_DATA; #define INCLUDE_ITEM_DATA extern safemap<std::string,ItemInfo>ITEM_DATA;
#define INCLUDE_ITEM_CATEGORIES extern safemap<std::string,std::set<std::string>>ITEM_CATEGORIES; #define INCLUDE_ITEM_CATEGORIES extern safemap<std::string,std::set<std::string>>ITEM_CATEGORIES;
#define DO_NOTHING [](MenuFuncData data){} #define DO_NOTHING [](MenuFuncData data){return true;}
#define INCLUDE_LEVEL_NAMES extern safemap<std::string,MapName>LEVEL_NAMES;
#define ACCESS_PLAYER Player*p=game->GetPlayer(); #define ACCESS_PLAYER Player*p=game->GetPlayer();

@ -10,7 +10,7 @@ void GameState::Initialize(){
NEW_STATE(States::OVERWORLD_MAP,State_OverworldMap); NEW_STATE(States::OVERWORLD_MAP,State_OverworldMap);
NEW_STATE(States::MAIN_MENU,State_MainMenu); NEW_STATE(States::MAIN_MENU,State_MainMenu);
GameState::ChangeState(States::GAME_RUN); GameState::ChangeState(States::OVERWORLD_MAP);
} }
GameState::~GameState(){} GameState::~GameState(){}

@ -10,8 +10,8 @@ typedef Attribute A;
class InventoryScrollableWindowComponent:public ScrollableWindowComponent{ class InventoryScrollableWindowComponent:public ScrollableWindowComponent{
protected: protected:
public: public:
inline InventoryScrollableWindowComponent(MenuType parent,geom2d::rect<float>rect,Decal*icon,MenuFunc onClick) inline InventoryScrollableWindowComponent(MenuType parent,geom2d::rect<float>rect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:ScrollableWindowComponent(parent,rect,icon,onClick){} :ScrollableWindowComponent(parent,rect,attributes){}
protected: protected:
virtual inline 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);
@ -21,8 +21,6 @@ protected:
removedCount+=std::erase(keyboardButtonList,button); removedCount+=std::erase(keyboardButtonList,button);
if(removedCount!=2){ if(removedCount!=2){
std::cout<<"WARNING! Attempted to remove buttons from button listing, but not found!"; std::cout<<"WARNING! Attempted to remove buttons from button listing, but not found!";
;
} }
if(buttonList.size()==0){ if(buttonList.size()==0){
if(!Menu::menus[button->parentMenu]->buttons.erase(button->GetPos().y)){ if(!Menu::menus[button->parentMenu]->buttons.erase(button->GetPos().y)){
@ -54,6 +52,7 @@ protected:
//Now delete the last slot. //Now delete the last slot.
components.erase(components.end()-1); components.erase(components.end()-1);
i--; //Subtract one from the index so we don't accidently skip slots. i--; //Subtract one from the index so we don't accidently skip slots.
delete lastButton;
} }
} }
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.
@ -72,7 +71,7 @@ protected:
MenuFunc useItemFunc=[](MenuFuncData data){ MenuFunc useItemFunc=[](MenuFuncData data){
MenuItemButton*button=(MenuItemButton*)data.component; MenuItemButton*button=(MenuItemButton*)data.component;
button->UseItem(); return !button->UseItem();
}; };
MenuItemButton*button=NEW MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc}; MenuItemButton*button=NEW MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};

@ -21,7 +21,7 @@ void Menu::InitializeInventoryWindow(){
Menu*inventoryWindow=CreateMenu(INVENTORY,CENTERED,windowSize); Menu*inventoryWindow=CreateMenu(INVENTORY,CENTERED,windowSize);
InventoryScrollableWindowComponent*inventory=NEW InventoryScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){}); InventoryScrollableWindowComponent*inventory=NEW InventoryScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}});
inventoryWindow->AddComponent("inventory",inventory); inventoryWindow->AddComponent("inventory",inventory);
Menu::AddInventoryListener(inventory,"Consumables"); Menu::AddInventoryListener(inventory,"Consumables");
Menu::AddInventoryListener(inventory,"Equipment"); Menu::AddInventoryListener(inventory,"Equipment");

@ -137,19 +137,22 @@ uint32_t Inventory::GetItemCount(IT it){
} }
} }
void Inventory::UseItem(IT it,uint32_t amt){ //Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
if(!_inventory.count(it))return; bool Inventory::UseItem(IT it,uint32_t amt){
if(!_inventory.count(it))return false;
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory) //There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
for(int i=0;i<amt;i++){ for(int i=0;i<amt;i++){
if(ExecuteAction(it)){ if(ExecuteAction(it)){
RemoveItem(it); return RemoveItem(it);
} }
} }
return false;
} }
void Inventory::RemoveItem(IT it,uint32_t amt){ //Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
bool Inventory::RemoveItem(IT it,uint32_t amt){
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory) //There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it))return; if(!_inventory.count(it))return false;
if(amt>=_inventory.at(it).Amt()){ if(amt>=_inventory.at(it).Amt()){
int count=0; int count=0;
std::vector<IT>&sortedList=sortedInv.at(_inventory.at(it).Category()); std::vector<IT>&sortedList=sortedInv.at(_inventory.at(it).Category());
@ -162,8 +165,10 @@ void Inventory::RemoveItem(IT it,uint32_t amt){
ITCategory cat=ITEM_DATA[it].category; ITCategory cat=ITEM_DATA[it].category;
//Callback for GUI inventories. //Callback for GUI inventories.
Menu::InventorySlotsUpdated(cat); Menu::InventorySlotsUpdated(cat);
return true;
}else{ }else{
_inventory.at(it).amt-=amt; _inventory.at(it).amt-=amt;
return false;
} }
} }

@ -40,8 +40,8 @@ public:
static uint32_t GetItemCount(IT it); static uint32_t GetItemCount(IT it);
static Item GetItem(IT it); static Item GetItem(IT it);
//Auto-executes its use function and removes the amt specified from the inventory. Multiple amounts will cause the item to execute its useFunc multiple times. //Auto-executes its use function and removes the amt specified from the inventory. Multiple amounts will cause the item to execute its useFunc multiple times.
static void UseItem(IT it,uint32_t amt=1); static bool UseItem(IT it,uint32_t amt=1);
static void RemoveItem(IT it,uint32_t amt=1); static bool RemoveItem(IT it,uint32_t amt=1);
static std::vector<IT>&get(ITCategory itemCategory); static std::vector<IT>&get(ITCategory itemCategory);
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2); static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);

@ -1,11 +1,17 @@
#include "Map.h" #include "Map.h"
#include "Crawler.h" #include "Crawler.h"
#include "safemap.h"
INCLUDE_game INCLUDE_game
INCLUDE_LEVEL_NAMES
float TileGroup::FADE_TIME=0.3; float TileGroup::FADE_TIME=0.3;
uint8_t TileGroup::FADE_AMT=160; uint8_t TileGroup::FADE_AMT=160;
Map&MapHelper::MapFromString(std::string mapName){
return game->MAP_DATA[LEVEL_NAMES[mapName]];
}
void TileGroup::InsertTile(TileRenderData tile){ void TileGroup::InsertTile(TileRenderData tile){
if(tiles.size()==0){ if(tiles.size()==0){
range={tile.pos,{game->GetCurrentMap().tilewidth,game->GetCurrentMap().tilewidth}}; range={tile.pos,{game->GetCurrentMap().tilewidth,game->GetCurrentMap().tilewidth}};

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include <set> #include <set>
#include "TMXParser.h"
struct XMLTag; struct XMLTag;
@ -11,6 +12,11 @@ enum MapName{
WORLD_MAP WORLD_MAP
}; };
class MapHelper{
public:
static Map&MapFromString(std::string mapName);
};
struct TileCollisionData{ struct TileCollisionData{
geom2d::rect<int>collision; geom2d::rect<int>collision;
}; };

@ -28,6 +28,7 @@ std::vector<MenuComponent*>Menu::unhandledComponents;
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
MenuType Menu::lastMenuTypeCreated; MenuType Menu::lastMenuTypeCreated;
std::string Menu::lastRegisteredComponent; std::string Menu::lastRegisteredComponent;
bool Menu::cover;
INCLUDE_GFX INCLUDE_GFX
extern vi2d WINDOW_SIZE; extern vi2d WINDOW_SIZE;
@ -54,6 +55,7 @@ void Menu::InitializeMenus(){
InitializeClassSelectionWindow(); InitializeClassSelectionWindow();
InitializeClassInfoWindow(); InitializeClassInfoWindow();
InitializeMainMenuWindow(); InitializeMainMenuWindow();
InitializeOverworldMapLevelWindow();
for(MenuType type=TEST;type<MenuType::ENUM_END;type=MenuType(int(type+1))){ for(MenuType type=TEST;type<MenuType::ENUM_END;type=MenuType(int(type+1))){
if(menus.count(type)==0){ if(menus.count(type)==0){
@ -154,12 +156,14 @@ void Menu::HoverMenuSelect(Crawler*game){
void Menu::MenuSelect(Crawler*game){ void Menu::MenuSelect(Crawler*game){
if(selection==vi2d{-1,-1}||buttons[selection.y][selection.x]->disabled)return; 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]}); bool buttonStillValid=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(buttonStillValid){
if(stack.size()<32){ if(buttons[selection.y][selection.x]->menuDest!=MenuType::ENUM_END){
stack.push_back(menus[buttons[selection.y][selection.x]->menuDest]);//Navigate to the next menu. if(stack.size()<32){
}else{ stack.push_back(menus[buttons[selection.y][selection.x]->menuDest]);//Navigate to the next menu.
ERR("WARNING! Exceeded menu stack size limit!") }else{
ERR("WARNING! Exceeded menu stack size limit!")
}
} }
} }
} }
@ -339,7 +343,8 @@ void Menu::Draw(Crawler*game){
} }
}; };
void Menu::OpenMenu(MenuType menu){ void Menu::OpenMenu(MenuType menu,bool cover){
Menu::cover=cover;
stack.clear(); stack.clear();
stack.push_back(menus[menu]); stack.push_back(menus[menu]);
} }

@ -16,6 +16,7 @@ enum MenuType{
CLASS_INFO, CLASS_INFO,
CLASS_SELECTION, CLASS_SELECTION,
MAIN_MENU, MAIN_MENU,
OVERWORLD_LEVEL_SELECT,
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_END//////////////////////////////// /*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -41,7 +42,7 @@ public:
void Update(Crawler*game); void Update(Crawler*game);
void Draw(Crawler*game); void Draw(Crawler*game);
static void InitializeMenus(); static void InitializeMenus();
static void OpenMenu(MenuType menu); static void OpenMenu(MenuType menu,bool cover=true);
static void CloseMenu(); static void CloseMenu();
static void CloseAllMenus(); static void CloseAllMenus();
static void CleanupAllMenus(); static void CleanupAllMenus();
@ -83,6 +84,7 @@ private:
static void InitializeClassInfoWindow(); static void InitializeClassInfoWindow();
static void InitializeClassSelectionWindow(); static void InitializeClassSelectionWindow();
static void InitializeMainMenuWindow(); static void InitializeMainMenuWindow();
static void InitializeOverworldMapLevelWindow();
//X (0-2), 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); static Renderable&GetPatchPart(int x,int y);
@ -97,6 +99,7 @@ private:
Pixel GetRenderColor(); Pixel GetRenderColor();
static bool MOUSE_NAVIGATION; static bool MOUSE_NAVIGATION;
static bool cover; //A black cover for when a menu pops up to fade out the stuff behind it.
}; };
struct MenuFuncData{ struct MenuFuncData{
@ -105,4 +108,4 @@ struct MenuFuncData{
MenuComponent*component; MenuComponent*component;
}; };
typedef std::function<void(MenuFuncData)> MenuFunc; typedef std::function<bool(MenuFuncData)> MenuFunc;

@ -17,6 +17,7 @@ public:
MenuAnimatedIconToggleButton*button=(MenuAnimatedIconToggleButton*)data.component; MenuAnimatedIconToggleButton*button=(MenuAnimatedIconToggleButton*)data.component;
button->Select(); button->Select();
button->_onClick(data); button->_onClick(data);
return true;
}),_onClick(onClick){} }),_onClick(onClick){}
protected: protected:
virtual inline void Update(Crawler*game)override{ virtual inline void Update(Crawler*game)override{

@ -46,13 +46,13 @@ void MenuComponent::_Update(Crawler*game){
void MenuComponent::Draw(Crawler*game,vf2d parentPos){ void MenuComponent::Draw(Crawler*game,vf2d parentPos){
if(background){ if(background){
game->FillRect(rect.pos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F)); game->FillRect(rect.pos+parentPos,rect.size,PixelLerp(Menu::themes[Menu::themeSelection].GetButtonCol(),Menu::themes[Menu::themeSelection].GetHighlightCol(),hoverEffect/"ThemeGlobal.HighlightTime"_F));
} }
if(border){ if(border){
game->DrawRect(rect.pos,rect.size); game->DrawRect(rect.pos+parentPos,rect.size);
} }
if(showDefaultLabel){ if(showDefaultLabel){
game->DrawStringProp(rect.pos+rect.size/2-game->GetTextSizeProp(label)/2,label); game->DrawStringProp(rect.pos+parentPos+rect.size/2-game->GetTextSizeProp(label)/2,label);
} }
} }

@ -22,8 +22,9 @@ public:
inline Item GetItem(){ inline Item GetItem(){
return Inventory::GetItem(invRef.at(inventoryIndex)); return Inventory::GetItem(invRef.at(inventoryIndex));
} }
inline void UseItem(uint32_t amt=1){ //Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
if(invRef.size()<=inventoryIndex)return; inline bool UseItem(uint32_t amt=1){
if(invRef.size()<=inventoryIndex)return false;
return Inventory::UseItem(invRef.at(inventoryIndex),amt); return Inventory::UseItem(invRef.at(inventoryIndex),amt);
} }
protected: protected:

@ -51,6 +51,7 @@ struct MonsterData{
std::vector<std::string>GetAnimations(){ std::vector<std::string>GetAnimations(){
return animations; return animations;
} }
std::string GetDisplayName();
static void InitializeMonsterData(); static void InitializeMonsterData();
static std::map<int,Renderable*>imgs; static std::map<int,Renderable*>imgs;
}; };

@ -127,6 +127,9 @@ int MonsterData::GetID(){
int MonsterData::GetAIStrategy(){ int MonsterData::GetAIStrategy(){
return strategy; return strategy;
} }
std::string MonsterData::GetDisplayName(){
return name;
}
std::string MonsterData::GetIdleAnimation(){ std::string MonsterData::GetIdleAnimation(){
return animations[IDLE]; return animations[IDLE];

@ -0,0 +1,52 @@
#pragma once
#include "Crawler.h"
#include "DEFINES.h"
#include "Menu.h"
#include "ScrollableWindowComponent.h"
#include "MenuLabel.h"
#include "MenuComponent.h"
#include "State_OverworldMap.h"
#include "Map.h"
INCLUDE_game
INCLUDE_LEVEL_NAMES
INCLUDE_MONSTER_DATA
typedef Attribute A;
void Menu::InitializeOverworldMapLevelWindow(){
vf2d windowSize={game->GetScreenSize().x/3.f-24,float(game->GetScreenSize().y)-48};
Menu*levelSelectWindow=CreateMenu(OVERWORLD_LEVEL_SELECT,{game->GetScreenSize().x-game->GetScreenSize().x/3.f,24},windowSize);
State_OverworldMap*overworldMap=(State_OverworldMap*)GameState::states[States::OVERWORLD_MAP]; //HACK ALERT!! We're going to make an assumption that we are in the overworld map state.
//Map&loadedMap=MapHelper::MapFromString(overworldMap->GetCurrentConnectionPoint().map);
//std::set<int>&spawns=loadedMap.spawns;
/*int yOffset=40;
for(int key:spawns){
MenuLabel*testLabel=new MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,float(yOffset)},{windowSize.x,24}},MONSTER_DATA[key].GetDisplayName());
yOffset+=28;
levelSelectWindow->AddComponent(MONSTER_DATA[key].GetDisplayName()+" Display Label",testLabel);
}*/
MenuLabel*chapterLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,4},{windowSize.x,16}},"Chapter "+std::to_string(game->GetCurrentChapter()),1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
MenuLabel*stageLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,24},{windowSize.x,16}},"Stage",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
MenuLabel*panel1Back=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,0},{windowSize.x-1,44}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE);
levelSelectWindow->AddComponent("Panel 1 Back",panel1Back);
levelSelectWindow->AddComponent("Chapter Label",chapterLabel);
levelSelectWindow->AddComponent("Stage Label",stageLabel);
MenuLabel*encountersLabel=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,52},{windowSize.x-1,12}},"Encounters:",1,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN);
ScrollableWindowComponent*spawns=NEW ScrollableWindowComponent(OVERWORLD_LEVEL_SELECT,{{1,64},{windowSize.x-2,84}},ComponentAttr::BACKGROUND);
MenuLabel*panel2Back=NEW MenuLabel(OVERWORLD_LEVEL_SELECT,{{0,52},{windowSize.x-1,96}},"",1,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE);
levelSelectWindow->AddComponent("Panel 2 Back",panel2Back);
levelSelectWindow->AddComponent("Encounters Label",encountersLabel);
levelSelectWindow->AddComponent("Spawns List",spawns);
MenuComponent*changeLoadoutButton=NEW MenuComponent(OVERWORLD_LEVEL_SELECT,{{0,152},{windowSize.x-1,12}},"Change Loadout",INVENTORY,[](MenuFuncData data){return true;});
MenuComponent*enterButton=NEW MenuComponent(OVERWORLD_LEVEL_SELECT,{{0,166},{windowSize.x-1,16}},"Enter",[](MenuFuncData data){return true;});
levelSelectWindow->AddComponent("Change Loadout Button",changeLoadoutButton);
levelSelectWindow->AddComponent("Enter Button",enterButton);
}

@ -22,14 +22,16 @@ protected:
return geom2d::overlaps(rect,geom2d::rect<float>{component->rect.pos+V(A::SCROLL_OFFSET)+vf2d{2,2},component->rect.size-vf2d{2,2}}); return geom2d::overlaps(rect,geom2d::rect<float>{component->rect.pos+V(A::SCROLL_OFFSET)+vf2d{2,2},component->rect.size-vf2d{2,2}});
} }
public: public:
inline ScrollableWindowComponent(MenuType parent,geom2d::rect<float>rect,Decal*icon,MenuFunc onClick) inline ScrollableWindowComponent(MenuType parent,geom2d::rect<float>rect,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:MenuComponent(parent,rect,"",onClick,ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){ :MenuComponent(parent,rect,"",[](MenuFuncData data){return true;},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD){
background=attributes&ComponentAttr::BACKGROUND;
border=attributes&ComponentAttr::OUTLINE;
r.Create(rect.size.x,rect.size.y); r.Create(rect.size.x,rect.size.y);
} }
protected: protected:
virtual inline void AfterCreate()override{ virtual inline void AfterCreate()override{
upButton=NEW MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD); upButton=NEW MenuComponent(parentMenu,{rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
downButton=NEW MenuComponent(parentMenu,{rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD); downButton=NEW MenuComponent(parentMenu,{rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
//Let's use the internal name of this component to add unique names for sub-components. //Let's use the internal name of this component to add unique names for sub-components.
Menu::menus[parentMenu]->AddComponent(name+upButton->rect.pos.str()+"_"+upButton->rect.size.str(),upButton); Menu::menus[parentMenu]->AddComponent(name+upButton->rect.pos.str()+"_"+upButton->rect.size.str(),upButton);
Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton); Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton);
@ -56,6 +58,7 @@ protected:
float totalContentHeight=bounds.size.y; float totalContentHeight=bounds.size.y;
if(totalContentHeight==0)totalContentHeight=1;
float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight);
//The scroll amount moves centered on the position the mouse is at. //The scroll amount moves centered on the position the mouse is at.
float newScrollbarTop=(game->GetMousePos().y-windowAbsPos.y-12)-scrollBarHeight/2; float newScrollbarTop=(game->GetMousePos().y-windowAbsPos.y-12)-scrollBarHeight/2;
@ -73,7 +76,11 @@ protected:
} }
} }
V(A::SCROLL_OFFSET).y=std::clamp(V(A::SCROLL_OFFSET).y,-(bounds.size.y-rect.size.y),0.f); if(bounds.size.y-rect.size.y>0){
V(A::SCROLL_OFFSET).y=std::clamp(V(A::SCROLL_OFFSET).y,-(bounds.size.y-rect.size.y),0.f);
}else{
V(A::SCROLL_OFFSET).y=0;
}
for(MenuComponent*component:components){ for(MenuComponent*component:components){
component->disabled=!OnScreen(component); component->disabled=!OnScreen(component);
@ -103,19 +110,22 @@ protected:
float spaceBetweenTopAndBottomArrows=rect.size.y-24; float spaceBetweenTopAndBottomArrows=rect.size.y-24;
float viewHeight=rect.size.y; float viewHeight=rect.size.y;
float totalContentHeight=bounds.size.y; float totalContentHeight=bounds.size.y;
if(totalContentHeight==0)totalContentHeight=1;
float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight); float scrollBarScale=(spaceBetweenTopAndBottomArrows/totalContentHeight);
scrollBarHeight=viewHeight*scrollBarScale-1; scrollBarHeight=std::min(spaceBetweenTopAndBottomArrows,viewHeight*scrollBarScale-1);
scrollBarTop=-V(A::SCROLL_OFFSET).y*scrollBarScale+1; scrollBarTop=-V(A::SCROLL_OFFSET).y*scrollBarScale+1;
float focusedWindowColorMult=(focused?1:"ThemeGlobal.MenuUnfocusedColorMult"_F); float focusedWindowColorMult=(focused?1:"ThemeGlobal.MenuUnfocusedColorMult"_F);
game->FillRectDecal(rect.pos+parentPos+vf2d{rect.size.x-13,scrollBarTop+12},{12,scrollBarHeight},PixelLerp(Menu::GetCurrentTheme().GetButtonCol(),Menu::GetCurrentTheme().GetHighlightCol(),scrollBarHoverTime/"ThemeGlobal.HighlightTime"_F)*focusedWindowColorMult); game->FillRectDecal(rect.pos+parentPos+vf2d{rect.size.x-11.75f,scrollBarTop+12},{12,scrollBarHeight},PixelLerp(Menu::GetCurrentTheme().GetButtonCol(),Menu::GetCurrentTheme().GetHighlightCol(),scrollBarHoverTime/"ThemeGlobal.HighlightTime"_F)*focusedWindowColorMult);
game->DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-13,scrollBarTop+12},{12,scrollBarHeight},WHITE*focusedWindowColorMult); game->DrawRectDecal(rect.pos+parentPos+vf2d{rect.size.x-11.75f,scrollBarTop+12},{12,scrollBarHeight},WHITE*focusedWindowColorMult);
} }
virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{ virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{
MenuComponent::DrawDecal(game,parentPos,focused); MenuComponent::DrawDecal(game,parentPos,focused);
game->DrawRectDecal(rect.pos+Menu::menus[parentMenu]->pos,rect.size); if(border){
game->DrawRectDecal(rect.pos+Menu::menus[parentMenu]->pos,rect.size);
}
for(MenuComponent*component:components){ for(MenuComponent*component:components){
component->_DrawDecal(game,rect.pos+Menu::menus[parentMenu]->pos+V(A::SCROLL_OFFSET),focused); component->_DrawDecal(game,rect.pos+Menu::menus[parentMenu]->pos+V(A::SCROLL_OFFSET),focused);
} }

@ -24,6 +24,8 @@ void State_OverworldMap::OnStateChange(GameState*prevState){
game->GetPlayer()->UpdateWalkingAnimation(DOWN); game->GetPlayer()->UpdateWalkingAnimation(DOWN);
game->GetPlayer()->SetState(State::FORCE_WALK); game->GetPlayer()->SetState(State::FORCE_WALK);
game->GetPlayer()->SetSizeMult(1); game->GetPlayer()->SetSizeMult(1);
game->camera.MoveCamera(game->GetPlayer()->GetPos());
Menu::OpenMenu(OVERWORLD_LEVEL_SELECT,false);
}; };
void State_OverworldMap::OnUserUpdate(Crawler*game){ void State_OverworldMap::OnUserUpdate(Crawler*game){
game->camera.SetTarget(currentConnectionPoint->rect.middle()+vf2d{game->GetScreenSize().x/6.0f,0}); game->camera.SetTarget(currentConnectionPoint->rect.middle()+vf2d{game->GetScreenSize().x/6.0f,0});

@ -2,6 +2,7 @@
#include "olcPixelGameEngine.h" #include "olcPixelGameEngine.h"
#include "olcUTIL_Geometry2D.h" #include "olcUTIL_Geometry2D.h"
#include <sstream> #include <sstream>
#include <set>
using namespace olc; using namespace olc;
@ -49,6 +50,7 @@ struct Map{
Renderable*optimizedTile=nullptr; Renderable*optimizedTile=nullptr;
std::vector<XMLTag> TilesetData; std::vector<XMLTag> TilesetData;
std::vector<LayerTag> LayerData; std::vector<LayerTag> LayerData;
std::set<int>spawns;
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID. std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles); std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles);
@ -256,7 +258,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
XMLTag newTag=ReadNextTag(); XMLTag newTag=ReadNextTag();
if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate") { if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate"){
currentStagePlate=nullptr; currentStagePlate=nullptr;
} }
@ -274,7 +276,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
LayerTag l = {newTag}; LayerTag l = {newTag};
parsedMapInfo.LayerData.push_back(l); parsedMapInfo.LayerData.push_back(l);
}else }else
if (newTag.tag=="object"&&newTag.data["type"]=="SpawnGroup") { if (newTag.tag=="object"&&newTag.data["type"]=="SpawnGroup"){
if(newTag.GetInteger("id")!=0){ if(newTag.GetInteger("id")!=0){
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag}; parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag};
prevSpawner=newTag.GetInteger("id"); prevSpawner=newTag.GetInteger("id");
@ -310,6 +312,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
} else } else
if (newTag.tag=="property"&&monsterPropertyTagCount==0) { if (newTag.tag=="property"&&monsterPropertyTagCount==0) {
monsterTag.data["value"]=newTag.data["value"]; monsterTag.data["value"]=newTag.data["value"];
parsedMapInfo.spawns.insert(newTag.GetInteger("value"));
monsterPropertyTagCount++; monsterPropertyTagCount++;
} else } else
if (newTag.tag=="property"&&monsterPropertyTagCount==1) { if (newTag.tag=="property"&&monsterPropertyTagCount==1) {

@ -6,16 +6,18 @@ void Menu::InitializeTestMenu(){
MenuFunc quitWindow=[](MenuFuncData data){ MenuFunc quitWindow=[](MenuFuncData data){
data.menu.stack.clear(); data.menu.stack.clear();
return true;
}; };
testMenu->AddComponent("Close",NEW MenuComponent(TEST,{{24*1,24*1},{24*2,24*1}},"Close",quitWindow)); testMenu->AddComponent("Close",NEW MenuComponent(TEST,{{24*1,24*1},{24*2,24*1}},"Close",quitWindow));
MenuFunc doNothing=[](MenuFuncData data){}; MenuFunc doNothing=[](MenuFuncData data){return true;};
testMenu->AddComponent("Test",NEW MenuComponent(TEST,{{24*4,24*1},{24*3,24*1}},"Test",doNothing)); testMenu->AddComponent("Test",NEW MenuComponent(TEST,{{24*4,24*1},{24*3,24*1}},"Test",doNothing));
MenuFunc HurtPlayer=[](MenuFuncData data){ MenuFunc HurtPlayer=[](MenuFuncData data){
data.game->GetPlayer()->Hurt(20,data.game->GetPlayer()->OnUpperLevel(),data.game->GetPlayer()->GetZ()); data.game->GetPlayer()->Hurt(20,data.game->GetPlayer()->OnUpperLevel(),data.game->GetPlayer()->GetZ());
return true;
}; };
testMenu->AddComponent("Hurt Player",NEW MenuComponent(TEST,{{24*4,24*3},{24*3,24*1}},"Hurt Player",HurtPlayer)); testMenu->AddComponent("Hurt Player",NEW MenuComponent(TEST,{{24*4,24*3},{24*3,24*1}},"Hurt Player",HurtPlayer));

@ -13,6 +13,7 @@ void Menu::InitializeTestSubMenu(){
MenuFunc goBack=[](MenuFuncData data){ MenuFunc goBack=[](MenuFuncData data){
data.menu.stack.pop_back(); data.menu.stack.pop_back();
return true;
}; };
testSubMenu->AddComponent("BACK",NEW MenuComponent(TEST_2,{{24*1,24*1},{24*2,24*1}},"Go Back",goBack)); testSubMenu->AddComponent("BACK",NEW MenuComponent(TEST_2,{{24*1,24*1},{24*2,24*1}},"Go Back",goBack));
@ -41,6 +42,7 @@ void Menu::InitializeTestSubMenu(){
} }
index++; index++;
} }
return true;
}; };
testSubMenu->AddComponent("PREV_THEME",NEW MenuComponent(TEST_2,{{24*-0.5,24*3},{24*1,24*1}},"<",themePrev)); testSubMenu->AddComponent("PREV_THEME",NEW MenuComponent(TEST_2,{{24*-0.5,24*3},{24*1,24*1}},"<",themePrev));
@ -58,6 +60,7 @@ void Menu::InitializeTestSubMenu(){
} }
index++; index++;
} }
return true;
}; };
testSubMenu->AddComponent("NEXT_THEME",NEW MenuComponent(TEST_2,{{24*3.5,24*3},{24*1,24*1}},">",themeNext)); testSubMenu->AddComponent("NEXT_THEME",NEW MenuComponent(TEST_2,{{24*3.5,24*3},{24*1,24*1}},">",themeNext));

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 2642 #define VERSION_BUILD 2718
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -16,7 +16,7 @@ Interface
map_config = levels.txt map_config = levels.txt
# Starting map when loading the game. # Starting map when loading the game.
starting_map = CAMPAIGN_1_1 starting_map = WORLD_MAP
# Player Properties Loading Config # Player Properties Loading Config
player_config = Player.txt player_config = Player.txt

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

@ -183,6 +183,17 @@ namespace olc::utils
return m_vEdgeTriggerDistance; return m_vEdgeTriggerDistance;
} }
// Directly moves the camera to a new point, useful when transitioning areas.
inline void MoveCamera(vf2d pos){
Mode prevMode=m_nMode;
vf2d&prevTarget=*m_pTarget;
SetMode(Mode::Simple);
SetTarget(pos);
Update(0);
SetMode(prevMode);
SetTarget(prevTarget);
}
// Update camera, animating if necessary, obeying world boundary rules // Update camera, animating if necessary, obeying world boundary rules
// returns true if target is visible // returns true if target is visible
inline virtual bool Update(const float fElapsedTime) inline virtual bool Update(const float fElapsedTime)

Loading…
Cancel
Save