Saving and loading saves items in proper sorted order. Fixed bug with get inventory slot function. Connection point data is now static.
This commit is contained in:
parent
0d6ab94fda
commit
ad1e2260cf
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,6 +28,7 @@ memoryleak.txt
|
||||
[Dd]ebugPublic/
|
||||
*.tlog/
|
||||
Crawler/x64/
|
||||
Crawler/assets/saves/
|
||||
[Rr]eleases/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
|
||||
@ -39,6 +39,7 @@ All rights reserved.
|
||||
#include "olcUTIL_Geometry2D.h"
|
||||
|
||||
struct ConnectionPoint{
|
||||
friend class State_OverworldMap;
|
||||
geom2d::rect<float>rect;
|
||||
std::string type;
|
||||
std::string name;
|
||||
@ -52,4 +53,5 @@ struct ConnectionPoint{
|
||||
neighbors.fill(-1);
|
||||
}
|
||||
bool IsNeighbor(ConnectionPoint&testPoint);
|
||||
static void UpdateCurrentConnectionPoint(const ConnectionPoint&connection);
|
||||
};
|
||||
|
||||
@ -2540,7 +2540,7 @@ void Crawler::InitializePlayerLevelCap(){
|
||||
}
|
||||
|
||||
void Crawler::ResetGame(){
|
||||
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
|
||||
GameState::ChangeState(States::MAIN_MENU,0.5f);
|
||||
for(int i=int(EquipSlot::HELMET);i<=int(EquipSlot::RING2);i<<=1){
|
||||
Inventory::UnequipItem(EquipSlot(i));
|
||||
}
|
||||
@ -2551,9 +2551,11 @@ void Crawler::ResetGame(){
|
||||
player->stats.Reset();
|
||||
player->ResetAccumulatedXP();
|
||||
player->totalXPEarned=0;
|
||||
player->SetMoney(100U);
|
||||
Unlock::unlocks.clear();
|
||||
Unlock::Initialize();
|
||||
DYNAMIC_CAST<State_OverworldMap*>(GameState::STATE)->SetStageMarker("Stage I-I");
|
||||
State_OverworldMap::SetStageMarker("Stage I-I");
|
||||
State_OverworldMap::UpdateCurrentConnectionPoint(*State_OverworldMap::currentConnectionPoint);
|
||||
SetChapter(1);
|
||||
SaveFile::SetSaveFileName("");
|
||||
}
|
||||
@ -355,6 +355,10 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LoadFileButton.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PlayerMoneyLabel.h">
|
||||
<SubType>
|
||||
</SubType>
|
||||
@ -535,6 +539,10 @@
|
||||
<ClCompile Include="LevelCompleteWindow.cpp" />
|
||||
<ClCompile Include="LightningBolt.cpp" />
|
||||
<ClCompile Include="LightningBoltEmitter.cpp" />
|
||||
<ClCompile Include="LoadGameWindow.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MainMenuWindow.cpp" />
|
||||
<ClCompile Include="Map.cpp" />
|
||||
<ClCompile Include="Menu.cpp" />
|
||||
|
||||
@ -396,6 +396,9 @@
|
||||
<ClInclude Include="SaveFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LoadFileButton.h">
|
||||
<Filter>Header Files\Interface</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
@ -665,6 +668,9 @@
|
||||
<ClCompile Include="SaveFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LoadGameWindow.cpp">
|
||||
<Filter>Source Files\Interface</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
||||
@ -488,7 +488,14 @@ bool Inventory::RemoveItem(std::weak_ptr<Item>itemRef,ITCategory inventory,uint3
|
||||
return true;
|
||||
}else{
|
||||
if(itemRef.lock()->IsEquippable()){ //Since equipment doesn't stack, if we have more than one piece we have to still remove that piece.
|
||||
size_t erased=std::erase_if(_inventory,[&](const std::pair<const IT,std::shared_ptr<Item>>data){return data.second==itemRef;});
|
||||
bool found=false;
|
||||
size_t erased=std::erase_if(_inventory,[&](const std::pair<const IT,std::shared_ptr<Item>>data){
|
||||
if(!found&&data.second==itemRef){
|
||||
found=true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if(erased!=1)ERR(std::format("Did not erase a single element, instead erased {} elements.",erased));
|
||||
inv.erase(inv.begin()+count); //Clears it from the detected sorted inventory as well!
|
||||
Menu::InventorySlotsUpdated(inventory);
|
||||
@ -664,11 +671,7 @@ const bool Item::IsBlank()const{
|
||||
void Inventory::Clear(ITCategory itemCategory){
|
||||
std::vector<std::shared_ptr<Item>>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
|
||||
for(std::shared_ptr<Item>&item:itemList){
|
||||
size_t itemQuantity=GetItemCount(item->ActualName());//Normally we want to clear all the items that are actually in our inventory...But...
|
||||
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){//These do not affect the actual inventory, we just clear the lists.
|
||||
itemQuantity=item->Amt();
|
||||
}
|
||||
RemoveItem(item,itemCategory,uint32_t(itemQuantity));
|
||||
RemoveItem(item,itemCategory,item->Amt());
|
||||
}
|
||||
}
|
||||
|
||||
@ -930,17 +933,7 @@ void Item::SetAmt(uint32_t newAmt){
|
||||
}
|
||||
|
||||
const std::weak_ptr<Item>Inventory::GetInventorySlot(ITCategory itemCategory,size_t slot){
|
||||
auto GetFirstIndex = [](ITCategory itemCategory,size_t slot){
|
||||
auto firstIter=std::find_if(get(itemCategory).begin(),get(itemCategory).end(),[&](std::shared_ptr<Item>item){
|
||||
if(item->ActualName()==get(itemCategory).at(slot)->ActualName())return true;
|
||||
return false;
|
||||
});
|
||||
size_t firstIndex=firstIter-get(itemCategory).begin();
|
||||
if(firstIter==get(itemCategory).end())ERR(std::format("Invalid slot {} for category {} specified!",slot,itemCategory));
|
||||
return firstIndex;
|
||||
};
|
||||
|
||||
return GetItem(get(itemCategory).at(slot)->ActualName())[slot-GetFirstIndex(itemCategory,slot)];
|
||||
return get(itemCategory).at(slot);
|
||||
}
|
||||
|
||||
bool Item::IsBlank(std::shared_ptr<Item>item){
|
||||
|
||||
64
Crawler/LoadFileButton.h
Normal file
64
Crawler/LoadFileButton.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2018 - 2022 OneLoneCoder.com
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce the above
|
||||
copyright notice. This list of conditions and the following disclaimer must be
|
||||
reproduced in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Portions of this software are copyright © 2023 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
|
||||
#include "MenuComponent.h"
|
||||
|
||||
class LoadFileButton:public MenuComponent{
|
||||
double playTime;
|
||||
int chapter;
|
||||
int level;
|
||||
std::string className;
|
||||
std::string saveFileName;
|
||||
int saveFileID;
|
||||
public:
|
||||
inline LoadFileButton(geom2d::rect<float>rect,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 DrawDecal(ViewPort&window,bool focused){
|
||||
MenuComponent::DrawDecal(window,focused);
|
||||
|
||||
|
||||
}
|
||||
|
||||
inline const int&getSaveFileID()const{
|
||||
return saveFileID;
|
||||
}
|
||||
};
|
||||
46
Crawler/LoadGameWindow.cpp
Normal file
46
Crawler/LoadGameWindow.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2018 - 2022 OneLoneCoder.com
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce the above
|
||||
copyright notice. This list of conditions and the following disclaimer must be
|
||||
reproduced in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Portions of this software are copyright © 2023 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
|
||||
#include "Menu.h"
|
||||
#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;
|
||||
}
|
||||
@ -39,6 +39,7 @@ All rights reserved.
|
||||
#include "DEFINES.h"
|
||||
#include "Menu.h"
|
||||
#include "MenuComponent.h"
|
||||
#include "SaveFile.h"
|
||||
|
||||
INCLUDE_game
|
||||
using A=Attribute;
|
||||
@ -51,6 +52,13 @@ void Menu::InitializeMainMenuWindow(){
|
||||
Menu::OpenMenu(SAVE_FILE_NAME);
|
||||
return true;
|
||||
})END;
|
||||
mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",DO_NOTHING)END;
|
||||
mainMenuWindow->ADD("Quit Game Button",MenuComponent)({{12,68},{72,24}},"Quit Game",DO_NOTHING)END;
|
||||
mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",[](MenuFuncData data){
|
||||
SaveFile::UpdateSaveGameData();
|
||||
Menu::OpenMenu(LOAD_GAME);
|
||||
return true;
|
||||
})END;
|
||||
mainMenuWindow->ADD("Quit Game Button",MenuComponent)({{12,68},{72,24}},"Quit Game",[](MenuFuncData data){
|
||||
game->EndGame();
|
||||
return true;
|
||||
})END;
|
||||
}
|
||||
@ -112,6 +112,7 @@ void Menu::InitializeMenus(){
|
||||
InitializeConsumableCraftingWindow();
|
||||
InitializeConsumableCraftItemWindow();
|
||||
InitializeSaveFileWindow();
|
||||
InitializeLoadGameWindow();
|
||||
|
||||
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){
|
||||
if(menus.count(type)==0){
|
||||
|
||||
@ -80,6 +80,7 @@ enum MenuType{
|
||||
CRAFT_CONSUMABLE,
|
||||
CONSUMABLE_CRAFT_ITEM,
|
||||
SAVE_FILE_NAME,
|
||||
LOAD_GAME,
|
||||
#pragma region Enum End //DO NOT REMOVE
|
||||
///////////////////////////////////////////////////////////
|
||||
/*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
|
||||
@ -106,6 +107,7 @@ class Menu:public IAttributable{
|
||||
static void InitializeConsumableCraftingWindow();
|
||||
static void InitializeConsumableCraftItemWindow();
|
||||
static void InitializeSaveFileWindow();
|
||||
static void InitializeLoadGameWindow();
|
||||
|
||||
friend class Crawler;
|
||||
friend struct Player;
|
||||
|
||||
@ -191,6 +191,10 @@ vf2d MenuComponent::GetPos(){
|
||||
return rect.pos;
|
||||
}
|
||||
|
||||
const vf2d&MenuComponent::GetSize()const{
|
||||
return rect.size;
|
||||
}
|
||||
|
||||
std::string MenuComponent::GetLabel(){
|
||||
return label;
|
||||
}
|
||||
|
||||
@ -132,6 +132,7 @@ public:
|
||||
MenuComponent(geom2d::rect<float>rect,std::string label,MenuType menuDest,MenuFunc onClick,vf2d labelScaling,ButtonAttr attributes=ButtonAttr::NONE);
|
||||
virtual ~MenuComponent();
|
||||
vf2d GetPos();
|
||||
const vf2d&GetSize()const;
|
||||
//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();
|
||||
|
||||
@ -56,5 +56,9 @@ void Menu::InitializeOverworldMenuWindow(){
|
||||
})END;
|
||||
overworldMenuWindow->ADD("Inventory Button",MenuComponent)({{4,12+28*2},{88,24}},"Inventory",[](MenuFuncData data){Menu::OpenMenu(INVENTORY);return true;})END;
|
||||
overworldMenuWindow->ADD("Settings Button",MenuComponent)({{4,12+28*3},{88,24}},"Settings",[](MenuFuncData data){/*Menu::OpenMenu(SETTINGS_MENU);*/return true;})END;
|
||||
overworldMenuWindow->ADD("Quit Button",MenuComponent)({{4,12+28*4},{88,24}},"Quit Game",[](MenuFuncData data){game->EndGame();return true;})END;
|
||||
overworldMenuWindow->ADD("Quit Button",MenuComponent)({{4,12+28*4},{88,24}},"Quit Game",[](MenuFuncData data){
|
||||
Menu::CloseAllMenus();
|
||||
game->ResetGame();
|
||||
return true;
|
||||
})END;
|
||||
}
|
||||
@ -43,6 +43,8 @@ All rights reserved.
|
||||
#include "State_OverworldMap.h"
|
||||
#include "SaveFile.h"
|
||||
#include "ClassInfo.h"
|
||||
#include "ScrollableWindowComponent.h"
|
||||
#include "LoadFileButton.h"
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
@ -62,18 +64,21 @@ const size_t SaveFile::GetSaveFileCount(){
|
||||
const void SaveFile::SaveGame(){
|
||||
utils::datafile saveFile;
|
||||
utils::datafile::INITIAL_SETUP_COMPLETE=false;
|
||||
for(size_t itemCount=0;auto&[name,item]:Inventory::_inventory){
|
||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
||||
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)));
|
||||
for(const auto&[attr,val]:item->RandomStats()){
|
||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Attributes"][std::string(attr.ActualName())].SetReal(val);
|
||||
for(size_t itemCount=0;auto&[cat,items]:Inventory::sortedInv){
|
||||
for(std::shared_ptr<Item>&item:items){
|
||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Amt"].SetInt(item->Amt());
|
||||
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)));
|
||||
for(const auto&[attr,val]:item->RandomStats()){
|
||||
saveFile["Items"][std::format("Item[{}]",itemCount)]["Attributes"][std::string(attr.ActualName())].SetReal(val);
|
||||
}
|
||||
itemCount++;
|
||||
}
|
||||
itemCount++;
|
||||
}
|
||||
saveFile["Player"]["Class"].SetString(game->GetPlayer()->GetClassName());
|
||||
saveFile["Player"]["Level"].SetInt(game->GetPlayer()->Level());
|
||||
saveFile["Player"]["Money"].SetInt(game->GetPlayer()->GetMoney());
|
||||
saveFile["Player"]["Current EXP"].SetInt(game->GetPlayer()->CurrentXP());
|
||||
saveFile["Player"]["Total EXP"].SetInt(game->GetPlayer()->TotalXP());
|
||||
for(const auto&[attr,val]:game->GetPlayer()->GetBaseStats()){
|
||||
@ -85,39 +90,56 @@ const void SaveFile::SaveGame(){
|
||||
saveFile["Overworld Map Location"].SetString(State_OverworldMap::GetCurrentConnectionPoint().name);
|
||||
saveFile["Chapter"].SetInt(game->GetCurrentChapter());
|
||||
saveFile["Save Name"].SetString(std::string(GetSaveFileName()));
|
||||
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||||
saveFile["Game Time"].SetReal(game->GetRuntime());
|
||||
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");
|
||||
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);
|
||||
metadata.GetProperty(std::format("save{}",saveFileID)).SetString(game->GetPlayer()->GetClassName(),3U);
|
||||
metadata.GetProperty(std::format("save{}",saveFileID)).SetString(std::string(SaveFile::GetSaveFileName()),4U);
|
||||
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
|
||||
|
||||
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||||
}
|
||||
|
||||
const void SaveFile::LoadGame(){
|
||||
utils::datafile loadFile;
|
||||
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
game->ResetGame();
|
||||
for(auto&[key,size]:loadFile["Items"]){
|
||||
std::weak_ptr<Item>newItem=Inventory::AddItem(loadFile["Items"][key]["Item Name"].GetString(),loadFile["Items"][key]["Amt"].GetInt());
|
||||
newItem.lock()->enhancementLevel=loadFile["Items"][key]["Enhancement Level"].GetInt();
|
||||
for(auto&[attr,size]:loadFile.GetProperty(std::format("{}.Attributes",key))){
|
||||
newItem.lock()->randomizedStats.A(attr)=loadFile.GetProperty(std::format("{}.Attributes.{}",key,attr)).GetReal();
|
||||
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
||||
std::weak_ptr<Item>newItem=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();
|
||||
}
|
||||
}
|
||||
EquipSlot slot=EquipSlot(loadFile.GetProperty(std::format("{}.Equip Slot",key)).GetInt());
|
||||
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(const auto&[key,size]:loadFile["Player"]["Base Stats"]){
|
||||
game->GetPlayer()->SetBaseStat(key,loadFile["Player"]["Base Stats"][key].GetReal());
|
||||
for(auto&[key,data]:loadFile["Player"]["Base Stats"].GetOrderedKeys()){
|
||||
game->GetPlayer()->SetBaseStat(key,data.GetReal());
|
||||
}
|
||||
for(const auto&[key,size]:loadFile["Unlocks"]){
|
||||
for(const auto&[key,data]:loadFile["Unlocks"].GetOrderedKeys()){
|
||||
Unlock::UnlockArea(key);
|
||||
}
|
||||
DYNAMIC_CAST<State_OverworldMap*>(GameState::STATE)->SetStageMarker(loadFile["Overworld Map Location"].GetString());
|
||||
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(){
|
||||
@ -130,4 +152,24 @@ const void SaveFile::SetSaveFileName(std::string_view saveFileName){
|
||||
|
||||
const void SaveFile::SetSaveFileID(size_t saveFileID){
|
||||
SaveFile::saveFileID=saveFileID;
|
||||
}
|
||||
}
|
||||
|
||||
const void SaveFile::UpdateSaveGameData(){
|
||||
auto gameFilesList=Component<ScrollableWindowComponent>(LOAD_GAME,"Game Files List");
|
||||
gameFilesList->RemoveAllComponents();
|
||||
const size_t saveFileCount=GetSaveFileCount();
|
||||
utils::datafile metadata;
|
||||
utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat");
|
||||
float offsetY=0;
|
||||
for(size_t i=0;i<saveFileCount;i++){
|
||||
if(metadata.HasProperty(std::format("save{}",i))){
|
||||
gameFilesList->ADD(std::format("Load File Button - Save {}",i),LoadFileButton)({{0,offsetY},{gameFilesList->GetSize().x-13,48}},metadata[std::format("save{}",i)],i,[](MenuFuncData data){
|
||||
LoadFileButton*comp=DYNAMIC_CAST<LoadFileButton*>(data.component);
|
||||
saveFileID=comp->getSaveFileID();
|
||||
SaveFile::LoadGame();
|
||||
return true;
|
||||
},ButtonAttr::NONE)END;
|
||||
offsetY+=49;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,4 +49,6 @@ public:
|
||||
static const void SaveGame();
|
||||
static const void LoadGame();
|
||||
static const void SetSaveFileID(size_t saveFileID);
|
||||
//Called whenever the save game data is updated.
|
||||
static const void UpdateSaveGameData();
|
||||
};
|
||||
@ -130,7 +130,7 @@ protected:
|
||||
|
||||
if(mouseOverScrollbar||scrollBarSelected){
|
||||
scrollBarHoverTime=std::min(scrollBarHoverTime+game->GetElapsedTime(),"ThemeGlobal.HighlightTime"_F);
|
||||
if(game->GetMouse(0).bPressed){
|
||||
if(game->GetMouse(0).bPressed&&!geom2d::contains(rect,bounds)){
|
||||
scrollBarSelected=true;
|
||||
}
|
||||
if(game->GetMouse(0).bReleased){
|
||||
@ -201,7 +201,9 @@ protected:
|
||||
for(MenuComponent*component:components){
|
||||
component->_DrawDecal(subWindow,focused);
|
||||
}
|
||||
DrawScrollbar(window,{},focused);
|
||||
if(!geom2d::contains(rect,bounds)){
|
||||
DrawScrollbar(window,{},focused);
|
||||
}
|
||||
}
|
||||
virtual bool GetHoverState(Crawler*game,MenuComponent*child)override{
|
||||
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos,rect.size},game->GetMousePos())&& //Make sure the mouse is inside the parent window component first....
|
||||
|
||||
@ -52,6 +52,7 @@ INCLUDE_MONSTER_LIST
|
||||
INCLUDE_game
|
||||
|
||||
std::vector<ConnectionPoint>State_OverworldMap::connections;
|
||||
ConnectionPoint*State_OverworldMap::currentConnectionPoint=nullptr;
|
||||
|
||||
State_OverworldMap::State_OverworldMap(){
|
||||
SetStageMarker("Stage I-I"); //Eventually we will load the game from a file and this will not be necessary. We just set it to this for now.
|
||||
@ -111,7 +112,7 @@ void State_OverworldMap::OnUserUpdate(Crawler*game){
|
||||
if(neighborInd==-1)continue;
|
||||
ConnectionPoint&neighbor=ConnectionPointFromIndex(neighborInd);
|
||||
if(Unlock::IsUnlocked(neighbor.unlockCondition)&&&cp==&neighbor){
|
||||
currentConnectionPoint=&neighbor;
|
||||
UpdateCurrentConnectionPoint(neighbor);
|
||||
playerTargetPos=currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16};
|
||||
float angleTo=util::angleTo(game->GetPlayer()->GetPos(),playerTargetPos);
|
||||
if(angleTo>=-3*PI/4&&angleTo<-PI/4){
|
||||
@ -125,10 +126,6 @@ void State_OverworldMap::OnUserUpdate(Crawler*game){
|
||||
}else{
|
||||
game->GetPlayer()->UpdateWalkingAnimation(LEFT);
|
||||
}
|
||||
Component<MenuLabel>(OVERWORLD_LEVEL_SELECT,"Stage Label")->SetLabel(currentConnectionPoint->name);
|
||||
Component<EncountersSpawnListScrollableWindowComponent>(OVERWORLD_LEVEL_SELECT,"Spawns List")->UpdateSpawns(currentConnectionPoint->spawns);
|
||||
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable(currentConnectionPoint->levelDataExists);
|
||||
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Change Loadout Button")->Enable(currentConnectionPoint->levelDataExists&&!(currentConnectionPoint->type=="STORY"||currentConnectionPoint->type=="SHOP"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -177,4 +174,14 @@ void State_OverworldMap::StartLevel(){
|
||||
game->LoadLevel(LEVEL_NAMES.at(State_OverworldMap::GetCurrentConnectionPoint().map));
|
||||
GameState::ChangeState(States::GAME_RUN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void State_OverworldMap::UpdateCurrentConnectionPoint(const ConnectionPoint&connection){
|
||||
currentConnectionPoint=const_cast<ConnectionPoint*>(&connection);
|
||||
Component<MenuLabel>(OVERWORLD_LEVEL_SELECT,"Stage Label")->SetLabel(currentConnectionPoint->name);
|
||||
Component<EncountersSpawnListScrollableWindowComponent>(OVERWORLD_LEVEL_SELECT,"Spawns List")->UpdateSpawns(currentConnectionPoint->spawns);
|
||||
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable(currentConnectionPoint->levelDataExists);
|
||||
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Change Loadout Button")->Enable(currentConnectionPoint->levelDataExists&&!(currentConnectionPoint->type=="STORY"||currentConnectionPoint->type=="SHOP"));
|
||||
}
|
||||
@ -42,7 +42,7 @@ All rights reserved.
|
||||
|
||||
class State_OverworldMap:public GameState{
|
||||
friend class Crawler;
|
||||
ConnectionPoint*currentConnectionPoint;
|
||||
static ConnectionPoint*currentConnectionPoint;
|
||||
float currentTime=0;
|
||||
vf2d playerTargetPos;
|
||||
const float playerMoveSpd=48.0;
|
||||
@ -50,10 +50,11 @@ public:
|
||||
State_OverworldMap();
|
||||
static std::vector<ConnectionPoint>connections;
|
||||
static ConnectionPoint&GetCurrentConnectionPoint();
|
||||
void SetStageMarker(std::string connectionName);
|
||||
static void SetStageMarker(std::string connectionName);
|
||||
static ConnectionPoint&ConnectionPointFromIndex(int ind);
|
||||
virtual void OnStateChange(GameState*prevState)override final;
|
||||
virtual void OnUserUpdate(Crawler*game)override final;
|
||||
virtual void Draw(Crawler*game)override final;
|
||||
static void StartLevel();
|
||||
static void UpdateCurrentConnectionPoint(const ConnectionPoint&connection);
|
||||
};
|
||||
@ -7,7 +7,15 @@ Save/Load Game
|
||||
- Unlock Progress
|
||||
- World Map Location
|
||||
- Chapter #
|
||||
- Gold
|
||||
- Save File Name
|
||||
- Game Play Time
|
||||
|
||||
Load Game Screen:
|
||||
Save File Name
|
||||
Game Play Time
|
||||
Chapter #
|
||||
Level / Class
|
||||
|
||||
- Start a New Game File
|
||||
- Load a Game (Load list displays save files in reverse chronological order based on last access)
|
||||
@ -26,10 +34,12 @@ Audio Engine
|
||||
- Attack / Enemy Sound Effects
|
||||
- Music Loading/Looping
|
||||
Settings Menu
|
||||
- Any settings should be saved to the save file!
|
||||
- Volume Controls
|
||||
- Key Configuration
|
||||
-Upon pressing a key, check if the key is bound to another option, if so,
|
||||
remove that bind from the list. Up to two keys may be binded per action.
|
||||
-We have to save keybinds to the save file.
|
||||
|
||||
|
||||
January 31st
|
||||
|
||||
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 5220
|
||||
#define VERSION_BUILD 5256
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
||||
@ -1,354 +0,0 @@
|
||||
|
||||
Items
|
||||
{
|
||||
|
||||
Item[0]
|
||||
{
|
||||
Amt = 9
|
||||
Enhancement Level = 0
|
||||
Item Name = Bandages
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[1]
|
||||
{
|
||||
Amt = 22
|
||||
Enhancement Level = 0
|
||||
Item Name = Blue Slime Remains
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[2]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Bone Armor
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[3]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Bone Gloves
|
||||
Equip Slot = 8
|
||||
}
|
||||
|
||||
|
||||
Item[4]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Bone Pants
|
||||
Equip Slot = 16
|
||||
}
|
||||
|
||||
|
||||
Item[5]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Copper Armor
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[6]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Copper Helmet
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[7]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Copper Pants
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[8]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Copper Shoes
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[9]
|
||||
{
|
||||
Amt = 2
|
||||
Enhancement Level = 0
|
||||
Item Name = Elixir of Bear Strength
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[10]
|
||||
{
|
||||
Amt = 42
|
||||
Enhancement Level = 0
|
||||
Item Name = Green Slime Remains
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[11]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Laser Sword
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[12]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Leather Gloves
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[13]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Leather Helmet
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[14]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Leather Pants
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[15]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Leather Shoes
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[16]
|
||||
{
|
||||
Amt = 16
|
||||
Enhancement Level = 0
|
||||
Item Name = Minor Health Potion
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[17]
|
||||
{
|
||||
Amt = 4
|
||||
Enhancement Level = 0
|
||||
Item Name = Red Slime Remains
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[18]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Ring of the Slime King
|
||||
Equip Slot = 128
|
||||
|
||||
Attributes
|
||||
{
|
||||
Attack = 4.000000
|
||||
Health = 17.000000
|
||||
Mana = 1.000000
|
||||
Move Spd % = 3.000000
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Item[19]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Ring of the Slime King
|
||||
Equip Slot = 0
|
||||
|
||||
Attributes
|
||||
{
|
||||
Attack = 3.000000
|
||||
Health = 8.000000
|
||||
Mana = 3.000000
|
||||
Move Spd % = 1.000000
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Item[20]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Ring of the Slime King
|
||||
Equip Slot = 0
|
||||
|
||||
Attributes
|
||||
{
|
||||
Attack = 3.000000
|
||||
Health = 6.000000
|
||||
Mana = 1.000000
|
||||
Move Spd % = 3.000000
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Item[21]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Armor
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[22]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Armor
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[23]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Armor
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[24]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Gloves
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[25]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Gloves
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[26]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Gloves
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[27]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Gloves
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[28]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Helmet
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[29]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Shoes
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[30]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Shell Sword
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
|
||||
Item[31]
|
||||
{
|
||||
Amt = 1
|
||||
Enhancement Level = 0
|
||||
Item Name = Wooden Sword
|
||||
Equip Slot = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Player
|
||||
{
|
||||
Class = Wizard
|
||||
Level = 1
|
||||
Current EXP = 44
|
||||
Total EXP = 44
|
||||
|
||||
Base Stats
|
||||
{
|
||||
Attack = 15.000000
|
||||
CDR = 0.000000
|
||||
Crit Dmg = 50.000000
|
||||
Crit Rate = 0.000000
|
||||
Defense = 0.000000
|
||||
HP6 Recovery % = 0.000000
|
||||
Health = 80.000000
|
||||
Health % = 0.000000
|
||||
Mana = 100.000000
|
||||
Move Spd % = 100.000000
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Unlocks
|
||||
{
|
||||
CAMPAIGN_1_1 = True
|
||||
WORLD_MAP = True
|
||||
}
|
||||
|
||||
Overworld Map Location = Stage I-I
|
||||
Chapter = 1
|
||||
Save Name = Test File
|
||||
@ -1038,6 +1038,7 @@ namespace olc
|
||||
// to specify the primary screen
|
||||
void SetDrawTarget(Sprite* target);
|
||||
double GetRuntime() const;
|
||||
void SetRuntime(const double runTime);
|
||||
// Gets the current Frames Per Second
|
||||
uint32_t GetFPS() const;
|
||||
// Gets last update of elapsed time
|
||||
@ -2195,6 +2196,10 @@ namespace olc
|
||||
double PixelGameEngine::GetRuntime() const
|
||||
{ return dRunTime; }
|
||||
|
||||
void PixelGameEngine::SetRuntime(const double runTime){
|
||||
dRunTime=runTime;
|
||||
}
|
||||
|
||||
uint32_t PixelGameEngine::GetFPS() const
|
||||
{ return nLastFPS; }
|
||||
|
||||
|
||||
@ -145,6 +145,10 @@ namespace olc::utils
|
||||
return m_mapObjects;
|
||||
}
|
||||
|
||||
inline std::vector<std::pair<std::string,datafile>>&GetOrderedKeys(){
|
||||
return m_vecObjects;
|
||||
}
|
||||
|
||||
// Checks if a property exists - useful to avoid creating properties
|
||||
// via reading them, though non-essential
|
||||
inline bool HasProperty(const std::string& sName)
|
||||
@ -281,6 +285,8 @@ namespace olc::utils
|
||||
|
||||
inline static bool Read(datafile& n, const std::string& sFileName, const char sListSep = ',')
|
||||
{
|
||||
bool previousSetupState=INITIAL_SETUP_COMPLETE;
|
||||
INITIAL_SETUP_COMPLETE=false;
|
||||
// Open the file!
|
||||
std::ifstream file(sFileName);
|
||||
if (file.is_open())
|
||||
@ -435,11 +441,13 @@ namespace olc::utils
|
||||
|
||||
// Close and exit!
|
||||
file.close();
|
||||
INITIAL_SETUP_COMPLETE=previousSetupState;
|
||||
return true;
|
||||
}
|
||||
|
||||
// File not found, so fail
|
||||
ERR("WARNING! Could not open file "<<sFileName<<"!");
|
||||
INITIAL_SETUP_COMPLETE=previousSetupState;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user