From 42b35634a50da4a812a5a44cff81126b3745c878 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Fri, 12 May 2023 15:18:26 -0700 Subject: [PATCH] Fixed residual values in global save block causing new files to save all sections previously loaded for metadata initialization, regardless of that section's execution during the save process. Fixed loading and saving of blank sceneTimestamps due to default construction of data structures during JSON loading making all "empty" entries have scene and room of 0. Moved SoH stats initialization to `gameplaystats.cpp` via `SaveManager::AddInitFunction`. --- soh/soh/Enhancements/gameplaystats.cpp | 69 +++++++++++++++++++++----- soh/soh/SaveManager.cpp | 45 +---------------- 2 files changed, 59 insertions(+), 55 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 2b76b932a..a6d48a9a1 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -199,22 +199,25 @@ void LoadStatsVersion1() { SaveManager::Instance->LoadArray( "itemTimestamps", ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.sohStats.itemTimestamp[i]); }); - int sceneTimestampCount = 0; SaveManager::Instance->LoadArray( - "sceneTimestamps", ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps), [&sceneTimestampCount](size_t i) { + "sceneTimestamps", ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps), [](size_t i) { SaveManager::Instance->LoadStruct("", [&i]() { - SaveManager::Instance->LoadData("scene", gSaveContext.sohStats.sceneTimestamps[i].scene); - SaveManager::Instance->LoadData("room", gSaveContext.sohStats.sceneTimestamps[i].room); - SaveManager::Instance->LoadData("sceneTime", gSaveContext.sohStats.sceneTimestamps[i].sceneTime); - SaveManager::Instance->LoadData("roomTime", gSaveContext.sohStats.sceneTimestamps[i].roomTime); - SaveManager::Instance->LoadData("isRoom", gSaveContext.sohStats.sceneTimestamps[i].isRoom); + int scene, room, sceneTime, roomTime, isRoom; + SaveManager::Instance->LoadData("scene", scene); + SaveManager::Instance->LoadData("room", room); + SaveManager::Instance->LoadData("sceneTime", sceneTime); + SaveManager::Instance->LoadData("roomTime", roomTime); + SaveManager::Instance->LoadData("isRoom", isRoom); + if (scene == 0 && room == 0 && sceneTime == 0 && roomTime == 0 && isRoom == 0) { + return; + } + gSaveContext.sohStats.sceneTimestamps[i].scene = scene; + gSaveContext.sohStats.sceneTimestamps[i].room = room; + gSaveContext.sohStats.sceneTimestamps[i].sceneTime = sceneTime; + gSaveContext.sohStats.sceneTimestamps[i].roomTime = roomTime; + gSaveContext.sohStats.sceneTimestamps[i].isRoom = isRoom; }); - sceneTimestampCount++; }); - for (int j = sceneTimestampCount; j < 8191; j++) { - gSaveContext.sohStats.sceneTimestamps[j].scene = 254; - gSaveContext.sohStats.sceneTimestamps[j].room = 254; - } SaveManager::Instance->LoadData("tsIdx", gSaveContext.sohStats.tsIdx); SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.sohStats.count), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.sohStats.count[i]); @@ -273,6 +276,47 @@ void SaveStats(SaveContext* saveContext) { [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->sohStats.locationsSkipped[i]); }); } +void InitStats(bool isDebug) { + gSaveContext.sohStats.heartPieces = isDebug ? 8 : 0; + gSaveContext.sohStats.heartContainers = isDebug ? 8 : 0; + for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) { + gSaveContext.sohStats.dungeonKeys[dungeon] = isDebug ? 8 : 0; + } + gSaveContext.sohStats.playTimer = 0; + gSaveContext.sohStats.pauseTimer = 0; + for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp); timestamp++) { + gSaveContext.sohStats.itemTimestamp[timestamp] = 0; + } + for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps); timestamp++) { + gSaveContext.sohStats.sceneTimestamps[timestamp].sceneTime = 0; + gSaveContext.sohStats.sceneTimestamps[timestamp].roomTime = 0; + gSaveContext.sohStats.sceneTimestamps[timestamp].scene = 254; + gSaveContext.sohStats.sceneTimestamps[timestamp].room = 254; + gSaveContext.sohStats.sceneTimestamps[timestamp].isRoom = 0; + } + gSaveContext.sohStats.tsIdx = 0; + for (int count = 0; count < ARRAY_COUNT(gSaveContext.sohStats.count); count++) { + gSaveContext.sohStats.count[count] = 0; + } + gSaveContext.sohStats.gameComplete = false; + for (int scenesIdx = 0; scenesIdx < ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered); scenesIdx++) { + gSaveContext.sohStats.scenesDiscovered[scenesIdx] = 0; + } + for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered); entrancesIdx++) { + gSaveContext.sohStats.entrancesDiscovered[entrancesIdx] = 0; + } + for (int rc = 0; rc < ARRAY_COUNT(gSaveContext.sohStats.locationsSkipped); rc++) { + gSaveContext.sohStats.locationsSkipped[rc] = 0; + } + + strncpy(gSaveContext.sohStats.buildVersion, (const char*)gBuildVersion, + sizeof(gSaveContext.sohStats.buildVersion) - 1); + gSaveContext.sohStats.buildVersion[sizeof(gSaveContext.sohStats.buildVersion) - 1] = 0; + gSaveContext.sohStats.buildVersionMajor = gBuildVersionMajor; + gSaveContext.sohStats.buildVersionMinor = gBuildVersionMinor; + gSaveContext.sohStats.buildVersionPatch = gBuildVersionPatch; +} + void SortChronological(TimestampInfo* arr, size_t len) { TimestampInfo temp; for (int i = 0; i < len; i++) { @@ -774,5 +818,6 @@ extern "C" void InitStatTracker() { SetupDisplayColors(); SaveManager::Instance->AddLoadFunction("sohStats", 1, LoadStatsVersion1); SaveManager::Instance->AddSaveFunction("sohStats", 1, SaveStats); + SaveManager::Instance->AddInitFunction(InitStats); SaveManager::Instance->RegisterGameSaveSection("sohStats"); } \ No newline at end of file diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 52f5eab44..873399080 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -413,6 +413,7 @@ void SaveManager::Init() { for (int fileNum = 0; fileNum < MaxFiles; fileNum++) { if (std::filesystem::exists(GetFileName(fileNum))) { LoadFile(fileNum); + saveBlock = nlohmann::json::object(); } } } @@ -529,37 +530,6 @@ void SaveManager::InitFileNormal() { } gSaveContext.inventory.defenseHearts = 0; gSaveContext.inventory.gsTokens = 0; - gSaveContext.sohStats.heartPieces = 0; - gSaveContext.sohStats.heartContainers = 0; - for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) { - gSaveContext.sohStats.dungeonKeys[dungeon] = 0; - } - gSaveContext.sohStats.playTimer = 0; - gSaveContext.sohStats.pauseTimer = 0; - for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.itemTimestamp); timestamp++) { - gSaveContext.sohStats.itemTimestamp[timestamp] = 0; - } - for (int timestamp = 0; timestamp < ARRAY_COUNT(gSaveContext.sohStats.sceneTimestamps); timestamp++) { - gSaveContext.sohStats.sceneTimestamps[timestamp].sceneTime = 0; - gSaveContext.sohStats.sceneTimestamps[timestamp].roomTime = 0; - gSaveContext.sohStats.sceneTimestamps[timestamp].scene = 254; - gSaveContext.sohStats.sceneTimestamps[timestamp].room = 254; - gSaveContext.sohStats.sceneTimestamps[timestamp].isRoom = 0; - } - gSaveContext.sohStats.tsIdx = 0; - for (int count = 0; count < ARRAY_COUNT(gSaveContext.sohStats.count); count++) { - gSaveContext.sohStats.count[count] = 0; - } - gSaveContext.sohStats.gameComplete = false; - for (int scenesIdx = 0; scenesIdx < ARRAY_COUNT(gSaveContext.sohStats.scenesDiscovered); scenesIdx++) { - gSaveContext.sohStats.scenesDiscovered[scenesIdx] = 0; - } - for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.sohStats.entrancesDiscovered); entrancesIdx++) { - gSaveContext.sohStats.entrancesDiscovered[entrancesIdx] = 0; - } - for (int rc = 0; rc < ARRAY_COUNT(gSaveContext.sohStats.locationsSkipped); rc++) { - gSaveContext.sohStats.locationsSkipped[rc] = 0; - } for (int scene = 0; scene < ARRAY_COUNT(gSaveContext.sceneFlags); scene++) { gSaveContext.sceneFlags[scene].chest = 0; gSaveContext.sceneFlags[scene].swch = 0; @@ -628,13 +598,6 @@ void SaveManager::InitFileNormal() { gSaveContext.pendingSale = ITEM_NONE; gSaveContext.pendingSaleMod = MOD_NONE; - strncpy(gSaveContext.sohStats.buildVersion, (const char*)gBuildVersion, - sizeof(gSaveContext.sohStats.buildVersion) - 1); - gSaveContext.sohStats.buildVersion[sizeof(gSaveContext.sohStats.buildVersion) - 1] = 0; - gSaveContext.sohStats.buildVersionMajor = gBuildVersionMajor; - gSaveContext.sohStats.buildVersionMinor = gBuildVersionMinor; - gSaveContext.sohStats.buildVersionPatch = gBuildVersionPatch; - // RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT) } @@ -718,11 +681,6 @@ void SaveManager::InitFileDebug() { } gSaveContext.inventory.defenseHearts = 0; gSaveContext.inventory.gsTokens = 0; - gSaveContext.sohStats.heartPieces = 8; - gSaveContext.sohStats.heartContainers = 8; - for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) { - gSaveContext.sohStats.dungeonKeys[dungeon] = 8; - } gSaveContext.horseData.scene = SCENE_SPOT00; gSaveContext.horseData.pos.x = -1840; @@ -760,6 +718,7 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, const for (auto& sectionHandler : sectionSaveHandlers) { nlohmann::json& sectionBlock = saveBlock["sections"][sectionHandler.first]; sectionBlock["version"] = sectionHandler.second.first; + sectionBlock["data"] = nlohmann::json::object(); currentJsonContext = §ionBlock["data"]; sectionHandler.second.second(saveContext);