diff --git a/Crawler/C++ Header File (OLC-3).zip b/Crawler/C++ Header File (OLC-3).zip index 55ab0c30..06791b1a 100644 Binary files a/Crawler/C++ Header File (OLC-3).zip and b/Crawler/C++ Header File (OLC-3).zip differ diff --git a/Crawler/C++ Source File (OLC-3).zip b/Crawler/C++ Source File (OLC-3).zip index 8334de3e..30df570c 100644 Binary files a/Crawler/C++ Source File (OLC-3).zip and b/Crawler/C++ Source File (OLC-3).zip differ diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 69757b6d..9188f7d0 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -2555,6 +2555,9 @@ void Crawler::ResetGame(){ player->ResetAccumulatedXP(); player->totalXPEarned=0; player->SetMoney(100U); + for(int i=0;iClearLoadoutItem(i); + } Unlock::unlocks.clear(); Unlock::Initialize(); State_OverworldMap::SetStageMarker("Stage I-I"); diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index 1c107785..71947fe0 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -58,6 +58,7 @@ class Crawler : public olc::PixelGameEngine { friend class GameState; friend class State_GameRun; + friend class SaveFile; friend class sig::Animation; std::unique_ptrplayer; public: diff --git a/Crawler/LoadFileButton.h b/Crawler/LoadFileButton.h index d620da7b..c0582e1e 100644 --- a/Crawler/LoadFileButton.h +++ b/Crawler/LoadFileButton.h @@ -38,24 +38,63 @@ All rights reserved. #pragma once #include "MenuComponent.h" +#include "ClassInfo.h" + +INCLUDE_ANIMATION_DATA class LoadFileButton:public MenuComponent{ - double playTime; - int chapter; - int level; - std::string className; - std::string saveFileName; - int saveFileID; + double playTime=-1; + int chapter=-1; + int level=-1; + std::string className=""; + std::string saveFileName=""; + int saveFileID=-1; + float animationTime=0; public: inline LoadFileButton(geom2d::rectrect,const utils::datafile&metadata,const int saveFileID,MenuFunc onClick,ButtonAttr attributes) :MenuComponent(rect,"",onClick,attributes),playTime(metadata.GetReal(0U)),chapter(metadata.GetInt(1U)),level(metadata.GetInt(2U)),className(metadata.GetString(3U)),saveFileName(metadata.GetString(4U)),saveFileID(saveFileID){ showDefaultLabel=false; } + inline void Update(Crawler*game)override{ + MenuComponent::Update(game); + if(playTime==-1){ + grayedOut=true; + } + animationTime+=game->GetElapsedTime(); + } + inline void DrawDecal(ViewPort&window,bool focused){ MenuComponent::DrawDecal(window,focused); + if(playTime==-1){ + window.DrawShadowStringPropDecal(rect.pos+vf2d{2,2},"UNKNOWN"); + }else{ + window.DrawShadowStringPropDecal(rect.pos+vf2d{2,2},saveFileName); + + const std::mapclassAnimations={ + {Warrior::name,Warrior::walk_s}, + {Ranger::name,Ranger::walk_s}, + {Wizard::name,Wizard::walk_s}, + {Thief::name,Thief::walk_s}, + {Trapper::name,Trapper::walk_s}, + {Witch::name,Witch::walk_s}, + }; + + std::string chapterText=std::format("Ch.{}",chapter); + vf2d chapterTextSize=game->GetTextSize(chapterText); + window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-chapterTextSize.x-2,2},chapterText); + + const Animate2D::Frame&frame=ANIMATION_DATA[classAnimations.at(className)].GetFrame(animationTime); + geom2d::rectsprRect=frame.GetSourceRect(); + window.DrawPartialDecal(rect.pos+vf2d{rect.size.x-26,rect.size.y-36},sprRect.size,frame.GetSourceImage()->Decal(),sprRect.pos,sprRect.size); + std::string levelClassText=std::format("Lv{} {}",level,className); + vf2d levelClassTextSize=game->GetTextSize(levelClassText); + window.DrawShadowStringDecal(rect.pos+vf2d{rect.size.x-levelClassTextSize.x-2,rect.size.y-10},levelClassText); + + window.DrawShadowStringDecal(rect.pos+vf2d{2,12},util::timerStr(playTime)); + } } inline const int&getSaveFileID()const{ diff --git a/Crawler/LoadGameWindow.cpp b/Crawler/LoadGameWindow.cpp index ccbe1c05..200ba9a2 100644 --- a/Crawler/LoadGameWindow.cpp +++ b/Crawler/LoadGameWindow.cpp @@ -40,7 +40,9 @@ All rights reserved. #include "ScrollableWindowComponent.h" void Menu::InitializeLoadGameWindow(){ - Menu*loadGameWindow=CreateMenu(LOAD_GAME,CENTERED,vi2d{96,96}); - - loadGameWindow->ADD("Game Files List",ScrollableWindowComponent)({{-8,0},{112,104}})END; + Menu*loadGameWindow=CreateMenu(LOAD_GAME,CENTERED,vi2d{96,120}); + + loadGameWindow->ADD("Game Files Label",MenuLabel)({{-8,-12},{112,12}},"Load Game",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END; + loadGameWindow->ADD("Game Files List",ScrollableWindowComponent)({{-8,4},{112,116}})END; + loadGameWindow->ADD("Go Back Button",MenuComponent)({{24,124},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END; } \ No newline at end of file diff --git a/Crawler/SaveFile.cpp b/Crawler/SaveFile.cpp index 7dbfd6d8..e407dcca 100644 --- a/Crawler/SaveFile.cpp +++ b/Crawler/SaveFile.cpp @@ -53,15 +53,18 @@ std::string SaveFile::saveFileName=""; const size_t SaveFile::GetSaveFileCount(){ size_t count=0; - for(auto&path:std::filesystem::directory_iterator("save_file_path"_S)){ - if(path.is_regular_file()){ - count++; + if(std::filesystem::exists("save_file_path"_S)){ + for(auto&path:std::filesystem::directory_iterator("save_file_path"_S)){ + if(path.is_regular_file()&&path.path()!="metadata.dat"){ + count++; + } } } return count; } const void SaveFile::SaveGame(){ + std::filesystem::create_directories("save_file_path"_S); utils::datafile saveFile; utils::datafile::INITIAL_SETUP_COMPLETE=false; for(size_t itemCount=0;auto&[cat,items]:Inventory::sortedInv){ @@ -70,6 +73,11 @@ const void SaveFile::SaveGame(){ saveFile["Items"][std::format("Item[{}]",itemCount)]["Enhancement Level"].SetInt(item->EnhancementLevel()); saveFile["Items"][std::format("Item[{}]",itemCount)]["Item Name"].SetString(item->ActualName()); saveFile["Items"][std::format("Item[{}]",itemCount)]["Equip Slot"].SetInt(int(Inventory::GetSlotEquippedIn(item))); + uint8_t loadoutSlotNumber=255; + for(int i=0;iloadout.size();i++){ + if(item==game->GetLoadoutItem(i)){loadoutSlotNumber=i;break;} + } + saveFile["Items"][std::format("Item[{}]",itemCount)]["LoadoutSlot"].SetInt(loadoutSlotNumber); for(const auto&[attr,val]:item->RandomStats()){ saveFile["Items"][std::format("Item[{}]",itemCount)]["Attributes"][std::string(attr.ActualName())].SetReal(val); } @@ -94,7 +102,9 @@ const void SaveFile::SaveGame(){ utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); utils::datafile metadata; - utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat"); + if(std::filesystem::exists("save_file_path"_S+"metadata.dat")){ + utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat"); + } metadata.GetProperty(std::format("save{}",saveFileID)).SetReal(game->GetRuntime(),0U); metadata.GetProperty(std::format("save{}",saveFileID)).SetInt(game->GetCurrentChapter(),1U); metadata.GetProperty(std::format("save{}",saveFileID)).SetInt(game->GetPlayer()->Level(),2U); @@ -106,40 +116,52 @@ const void SaveFile::SaveGame(){ } const void SaveFile::LoadGame(){ + std::filesystem::create_directories("save_file_path"_S); utils::datafile loadFile; - utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); - game->ResetGame(); - for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){ - std::weak_ptrnewItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt()); - newItem.lock()->enhancementLevel=data["Enhancement Level"].GetInt(); - if(loadFile.GetProperty(std::format("Items.{}",key)).HasProperty("Attributes")){ - for(auto&[attr,data]:loadFile.GetProperty(std::format("Items.{}.Attributes",key)).GetOrderedKeys()){ - newItem.lock()->randomizedStats.A(attr)=data.GetReal(); + if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){ + utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); + game->ResetGame(); + for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){ + std::weak_ptrnewItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt()); + newItem.lock()->enhancementLevel=data["Enhancement Level"].GetInt(); + if(loadFile.GetProperty(std::format("Items.{}",key)).HasProperty("Attributes")){ + for(auto&[attr,data]:loadFile.GetProperty(std::format("Items.{}.Attributes",key)).GetOrderedKeys()){ + newItem.lock()->randomizedStats.A(attr)=data.GetReal(); + } + } + if(data.HasProperty("LoadoutSlot")){ + uint8_t loadoutSlot=data["LoadoutSlot"].GetInt(); + if(loadoutSlot!=255){ + game->SetLoadoutItem(loadoutSlot,newItem.lock()->ActualName()); + } + } + + EquipSlot slot=EquipSlot(loadFile.GetProperty(std::format("Items.{}.Equip Slot",key)).GetInt()); + if(slot!=EquipSlot::NONE){ //This should be equipped somewhere! + Inventory::EquipItem(newItem,slot); } } - EquipSlot slot=EquipSlot(loadFile.GetProperty(std::format("Items.{}.Equip Slot",key)).GetInt()); - if(slot!=EquipSlot::NONE){ //This should be equipped somewhere! - Inventory::EquipItem(newItem,slot); + game->ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString())); + game->GetPlayer()->level=loadFile["Player"]["Level"].GetInt(); + game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt()); + game->GetPlayer()->currentLevelXP=loadFile["Player"]["Current EXP"].GetInt(); + game->GetPlayer()->totalXPEarned=loadFile["Player"]["Total EXP"].GetInt(); + for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){ + game->GetPlayer()->SetBaseStat(key,data.GetReal()); } + for(const auto&[key,data]:loadFile["Unlocks"].GetOrderedKeys()){ + Unlock::UnlockArea(key); + } + State_OverworldMap::SetStageMarker(loadFile["Overworld Map Location"].GetString()); + game->SetChapter(loadFile["Chapter"].GetInt()); + SaveFile::SetSaveFileName(loadFile["Save Name"].GetString()); + game->SetRuntime(loadFile["Game Time"].GetReal()); + game->GetPlayer()->RecalculateEquipStats(); + + GameState::ChangeState(States::OVERWORLD_MAP,0.5f); + }else{ + std::cout<ChangePlayerClass(classutils::StringToClass(loadFile["Player"]["Class"].GetString())); - game->GetPlayer()->level=loadFile["Player"]["Level"].GetInt(); - game->GetPlayer()->SetMoney(loadFile["Player"]["Money"].GetInt()); - game->GetPlayer()->currentLevelXP=loadFile["Player"]["Current EXP"].GetInt(); - game->GetPlayer()->totalXPEarned=loadFile["Player"]["Total EXP"].GetInt(); - for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){ - game->GetPlayer()->SetBaseStat(key,data.GetReal()); - } - for(const auto&[key,data]:loadFile["Unlocks"].GetOrderedKeys()){ - Unlock::UnlockArea(key); - } - State_OverworldMap::SetStageMarker(loadFile["Overworld Map Location"].GetString()); - game->SetChapter(loadFile["Chapter"].GetInt()); - SaveFile::SetSaveFileName(loadFile["Save Name"].GetString()); - game->SetRuntime(loadFile["Game Time"].GetReal()); - game->GetPlayer()->RecalculateEquipStats(); - - GameState::ChangeState(States::OVERWORLD_MAP,0.5f); } const std::string_view SaveFile::GetSaveFileName(){ diff --git a/Crawler/Version.h b/Crawler/Version.h index 961073f9..e1ea9208 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 5262 +#define VERSION_BUILD 5279 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/saves/metadata.dat b/Crawler/assets/saves/metadata.dat index e69de29b..6f66f2c1 100644 --- a/Crawler/assets/saves/metadata.dat +++ b/Crawler/assets/saves/metadata.dat @@ -0,0 +1,2 @@ +save0 = 534.977882, 1, 2, Ranger, Sig +save1 = 107.824620, 1, 1, Wizard, WIZ