From a1526bf6846045d826bd90efe2361aef5edc2fa0 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 3 Sep 2024 20:08:00 -0700 Subject: [PATCH 1/9] Update check status in the check tracker to the new system. Status and Skipped are now stored in ItemLocation, though still saved separately in the trackerData section. --- soh/include/z64save.h | 2 +- .../Enhancements/randomizer/hook_handlers.cpp | 25 +- .../Enhancements/randomizer/item_location.cpp | 21 +- .../Enhancements/randomizer/item_location.h | 9 +- .../Enhancements/randomizer/randomizer.cpp | 2 - .../Enhancements/randomizer/randomizerTypes.h | 27 +-- .../randomizer/randomizer_check_tracker.cpp | 221 ++++++++---------- .../randomizer/randomizer_check_tracker.h | 11 +- soh/soh/Enhancements/randomizer/savefile.cpp | 2 +- soh/soh/SaveManager.cpp | 9 +- soh/soh/SaveManager.h | 2 + 11 files changed, 156 insertions(+), 175 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 617c2acf526..c6db012e1df 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -68,6 +68,7 @@ typedef enum { // Pre-existing IDs for save sections in base code SECTION_ID_STATS, SECTION_ID_ENTRANCES, SECTION_ID_SCENES, + SECTION_ID_TRACKER_DATA, SECTION_ID_MAX } SaveFuncIDs; @@ -279,7 +280,6 @@ typedef struct { /* */ u8 pendingIceTrapCount; /* */ SohStats sohStats; /* */ FaroresWindData backupFW; - /* */ RandomizerCheckTrackerData checkTrackerData[RC_MAX]; // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 4bd8da74259..29ea3e7b4ac 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -305,7 +305,8 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { auto loc = Rando::Context::GetInstance()->GetItemLocation(randomizerQueuedCheck); if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, static_cast(randomizerQueuedCheck)); - loc->MarkAsObtained(); + loc->SetCheckStatus(RCSHOW_COLLECTED); + SaveManager::Instance->SaveSection(gSaveContext.fileNum, SECTION_ID_TRACKER_DATA, true); randomizerQueuedCheck = RC_UNKNOWN_CHECK; randomizerQueuedItemEntry = GET_ITEM_NONE; } @@ -656,7 +657,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; } else { *should = true; - Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->MarkAsObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->SetCheckStatus(RCSHOW_COLLECTED); } break; case VB_ITEM00_DESPAWN: { @@ -1173,25 +1174,25 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { // probably need to do something different when we implement shuffle if (sceneNum == SCENE_TREASURE_BOX_SHOP) { Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->MarkAsNotObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->SetCheckStatus(RCSHOW_UNCHECKED); } // LACs & Prelude checks diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index 3185fce8aa1..d303b3c3b17 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -102,15 +102,23 @@ void ItemLocation::SetCustomPrice(const uint16_t price_) { } bool ItemLocation::HasObtained() const { - return obtained; + return status == RCSHOW_COLLECTED || status == RCSHOW_SAVED; } -void ItemLocation::MarkAsObtained() { - obtained = true; +void ItemLocation::SetCheckStatus(RandomizerCheckStatus status_) { + status = status_; } -void ItemLocation::MarkAsNotObtained() { - obtained = false; +RandomizerCheckStatus ItemLocation::GetCheckStatus() { + return status; +} + +void ItemLocation::SetIsSkipped(bool isSkipped_) { + isSkipped = isSkipped_; +} + +bool ItemLocation::GetIsSkipped() { + return isSkipped; } bool ItemLocation::IsHintable() const { @@ -213,6 +221,7 @@ void ItemLocation::ResetVariables() { wothCandidate = false; barrenCandidate = false; area = RA_NONE; - obtained = false; + status = RCSHOW_UNCHECKED; + isSkipped = false; } } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index b40cac537b8..868b384b5dc 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -32,8 +32,10 @@ class ItemLocation { bool HasCustomPrice() const; void SetCustomPrice(uint16_t price_); bool HasObtained() const; - void MarkAsObtained(); - void MarkAsNotObtained(); + void SetCheckStatus(RandomizerCheckStatus status_); + RandomizerCheckStatus GetCheckStatus(); + void SetIsSkipped(bool isSkipped_); + bool GetIsSkipped(); bool IsHintable() const; void SetAsHintable(); bool IsAHintAccessible() const; @@ -70,6 +72,7 @@ class ItemLocation { bool visibleInImGui = false; bool wothCandidate = false; bool barrenCandidate = false; - bool obtained = false; + RandomizerCheckStatus status = RCSHOW_UNCHECKED; + bool isSkipped = false; }; } // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index cc572629f10..e60eda0b9b6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -56,8 +56,6 @@ std::set spoilerExcludedLocations; std::set enabledTricks; std::set enabledGlitches; -std::set> checkTrackerStates; - u8 generated; char* seedString; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 507ae5fec2b..304fef213cd 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -27,16 +27,6 @@ typedef struct { uint8_t id; } Sprite; -// Check tracker check visibility categories -typedef enum { - RCSHOW_UNCHECKED, - RCSHOW_SEEN, - RCSHOW_IDENTIFIED, - RCSHOW_SCUMMED, - RCSHOW_COLLECTED, - RCSHOW_SAVED, -} RandomizerCheckStatus; - typedef enum { HINT_TYPE_HINT_KEY, HINT_TYPE_AREA, @@ -315,6 +305,16 @@ typedef enum { RCAREA_INVALID } RandomizerCheckArea; +// Check tracker check visibility categories +typedef enum { + RCSHOW_UNCHECKED, + RCSHOW_SEEN, + RCSHOW_IDENTIFIED, + RCSHOW_SCUMMED, + RCSHOW_COLLECTED, + RCSHOW_SAVED, +} RandomizerCheckStatus; + typedef enum { RR_NONE, RR_ROOT, @@ -3886,13 +3886,6 @@ typedef enum { RSK_MAX } RandomizerSettingKey; -typedef struct { - RandomizerCheckStatus status; - uint16_t skipped; - int16_t price; - uint16_t hintItem; -} RandomizerCheckTrackerData; - //Generic Settings (any binary option can use this) // off/on typedef enum { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d617f6fd00f..c1ba3e84122 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -36,21 +36,6 @@ extern std::vector equipmentItems; using json = nlohmann::json; -void to_json(json& j, const RandomizerCheckTrackerData& rctd) { - j = json { - { "status", rctd.status == RCSHOW_COLLECTED ? RCSHOW_SAVED : rctd.status }, - { "skipped", rctd.skipped }, - { "price", rctd.price }, - { "hintItem", rctd.hintItem }}; - } - -void from_json(const json& j, RandomizerCheckTrackerData& rctd) { - j.at("status").get_to(rctd.status); - j.at("skipped").get_to(rctd.skipped); - j.at("hintItem").get_to(rctd.hintItem); - j.at("price").get_to(rctd.price); -} - namespace CheckTracker { // settings @@ -220,38 +205,32 @@ std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; -void DefaultCheckData(RandomizerCheck rc) { - gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED; - gSaveContext.checkTrackerData[rc].skipped = 0; - gSaveContext.checkTrackerData[rc].hintItem = RC_UNKNOWN_CHECK; -} - void SongFromImpa() { if (IS_RANDO) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA) == RO_GENERIC_ON && IS_RANDO) { - if (gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status != RCSHOW_SAVED) { - gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status = RCSHOW_SAVED; - } + //if (gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status != RCSHOW_SAVED) { + // gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status = RCSHOW_SAVED; + //} } } } void GiftFromSages() { if (!IS_RANDO) { - DefaultCheckData(RC_GIFT_FROM_SAGES); + //DefaultCheckData(RC_GIFT_FROM_SAGES); } } std::vector checks; // Function for adding Link's Pocket check void LinksPocket() { - if (IS_RANDO) { + /*if (IS_RANDO) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING || OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DUNGEON_REWARDS) == RO_DUNGEON_REWARDS_END_OF_DUNGEON) { DefaultCheckData(RC_LINKS_POCKET); gSaveContext.checkTrackerData[RC_LINKS_POCKET].status = RCSHOW_SAVED; } - } + }*/ } void TrySetAreas() { @@ -292,8 +271,7 @@ void RecalculateAreaTotals() { continue; } areaCheckTotals[rcArea]++; - if (gSaveContext.checkTrackerData[rc].skipped || gSaveContext.checkTrackerData[rc].status == RCSHOW_COLLECTED - || gSaveContext.checkTrackerData[rc].status == RCSHOW_SAVED) { + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped() || OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->HasObtained()) { areaChecksGotten[rcArea]++; } } @@ -304,13 +282,13 @@ void RecalculateAreaTotals() { } void SetCheckCollected(RandomizerCheck rc) { - gSaveContext.checkTrackerData[rc].status = RCSHOW_COLLECTED; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetCheckStatus(RCSHOW_COLLECTED); Rando::Location* loc = Rando::StaticData::GetLocation(rc); if (IsVisibleInCheckTracker(rc)) { - if (!gSaveContext.checkTrackerData[rc].skipped) { + if (!OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped()) { areaChecksGotten[loc->GetArea()]++; } else { - gSaveContext.checkTrackerData[rc].skipped = false; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); } } SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); @@ -439,8 +417,8 @@ void SetShopSeen(uint32_t sceneNum, bool prices) { } bool statusChanged = false; for (int i = start; i < start + 8; i++) { - if (gSaveContext.checkTrackerData[i].status == RCSHOW_UNCHECKED) { - gSaveContext.checkTrackerData[i].status = RCSHOW_SEEN; + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetCheckStatus() == RCSHOW_UNCHECKED) { + OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->SetCheckStatus(RCSHOW_SEEN); statusChanged = true; } } @@ -499,23 +477,23 @@ void CheckTrackerLoadGame(int32_t fileNum) { TrySetAreas(); for (auto& entry : Rando::StaticData::GetLocationTable()) { RandomizerCheck rc = entry.GetRandomizerCheck(); - RandomizerCheckTrackerData rcTrackerData = gSaveContext.checkTrackerData[rc]; if (rc == RC_UNKNOWN_CHECK || rc == RC_MAX || rc == RC_LINKS_POCKET || !Rando::StaticData::GetLocation(rc) != RC_UNKNOWN_CHECK) { continue; } - Rando::Location* entry2; - if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) { - entry2 = Rando::StaticData::GetLocation(rc); - } else { - entry2 = Rando::StaticData::GetLocation(rc); - } + Rando::Location* entry2 = Rando::StaticData::GetLocation(rc); + Rando::ItemLocation* loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); + //if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) { + // entry2 = Rando::StaticData::GetLocation(rc); + //} else { + // entry2 = Rando::StaticData::GetLocation(rc); + //} checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck()); if (IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) { areaCheckTotals[entry2->GetArea()]++; - if (rcTrackerData.status == RCSHOW_SAVED || rcTrackerData.skipped) { + if (loc->GetCheckStatus() == RCSHOW_SAVED || loc->GetIsSkipped()) { areaChecksGotten[entry2->GetArea()]++; } } @@ -581,10 +559,9 @@ void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) { if (GetCheckArea() == RCAREA_KAKARIKO_VILLAGE && gPlayState->sceneNum == SCENE_BAZAAR) { slot = RC_KAK_BAZAAR_ITEM_1 + cursorSlot; } - auto status = gSaveContext.checkTrackerData[slot].status; + auto status = OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->GetCheckStatus(); if (status == RCSHOW_SEEN) { - gSaveContext.checkTrackerData[slot].status = RCSHOW_IDENTIFIED; - gSaveContext.checkTrackerData[slot].price = basePrice; + OTRGlobals::Instance->gRandoContext->GetItemLocation(slot)->SetCheckStatus(RCSHOW_IDENTIFIED); SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); } } @@ -617,8 +594,7 @@ void CheckTrackerFrame() { return; } // TODO: Move to OnAmmoChange hook once it gets added. - if (gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_COLLECTED && - gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_SAVED) { + if (!OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->HasObtained()) { if (BEANS_BOUGHT >= 10) { SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN); } @@ -827,33 +803,49 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; - for (auto& loc : Rando::StaticData::GetLocationTable()) { - if (loc.GetRandomizerCheck() != RC_UNKNOWN_CHECK && loc.GetRandomizerCheck() != RC_MAX) { - DefaultCheckData(loc.GetRandomizerCheck()); - } - } + //for (auto& loc : Rando::StaticData::GetLocationTable()) { + // if (loc.GetRandomizerCheck() != RC_UNKNOWN_CHECK && loc.GetRandomizerCheck() != RC_MAX) { + // DefaultCheckData(loc.GetRandomizerCheck()); + // } + //} UpdateAllOrdering(); } -void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) { - SaveManager::Instance->SaveArray("checks", ARRAY_COUNT(saveContext->checkTrackerData), [&](size_t i) { - if (saveContext->checkTrackerData[i].status == RCSHOW_COLLECTED) { - if (gameSave) { - gSaveContext.checkTrackerData[i].status = saveContext->checkTrackerData[i].status = RCSHOW_SAVED; - UpdateAllOrdering(); - UpdateInventoryChecks(); - } else { - saveContext->checkTrackerData[i].status = RCSHOW_SCUMMED; +void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { + bool updateOrdering = false; + std::vector checkCount; + for (int i = RC_UNKNOWN_CHECK; i < RC_MAX; i++) { + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetCheckStatus() != RCSHOW_UNCHECKED || + OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetIsSkipped()) + checkCount.push_back(static_cast(i)); + } + SaveManager::Instance->SaveArray("checkStatus", checkCount.size(), [&](size_t i) { + RandomizerCheck check = checkCount.at(i); + RandomizerCheckStatus savedStatus = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetCheckStatus(); + bool isSkipped = OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetIsSkipped(); + if (savedStatus == RCSHOW_COLLECTED) { + if (fullSave) { + OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->SetCheckStatus(RCSHOW_SAVED); + savedStatus = RCSHOW_SAVED; + updateOrdering = true; + } + else { + savedStatus = RCSHOW_SCUMMED; } } - SaveManager::Instance->SaveStruct("", [&]() { - SaveManager::Instance->SaveData("status", saveContext->checkTrackerData[i].status); - SaveManager::Instance->SaveData("skipped", saveContext->checkTrackerData[i].skipped); - SaveManager::Instance->SaveData("price", saveContext->checkTrackerData[i].price); - SaveManager::Instance->SaveData("hintItem", saveContext->checkTrackerData[i].hintItem); - }); + if (savedStatus != RCSHOW_UNCHECKED || isSkipped) { + SaveManager::Instance->SaveStruct("", [&]() { + SaveManager::Instance->SaveData("randomizerCheck", check); + SaveManager::Instance->SaveData("status", savedStatus); + SaveManager::Instance->SaveData("skipped", isSkipped); + }); + } }); SaveManager::Instance->SaveData("areasSpoiled", areasSpoiled); + if (updateOrdering) { + UpdateAllOrdering(); + UpdateAllAreas(); + } } void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { @@ -861,15 +853,21 @@ void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { } void LoadFile() { - SaveManager::Instance->LoadArray("checks", RC_MAX, [](size_t i) { + SaveManager::Instance->LoadArray("checkStatus", RC_MAX, [](size_t i) { SaveManager::Instance->LoadStruct("", [&]() { - SaveManager::Instance->LoadData("status", gSaveContext.checkTrackerData[i].status); - SaveManager::Instance->LoadData("skipped", gSaveContext.checkTrackerData[i].skipped); - SaveManager::Instance->LoadData("price", gSaveContext.checkTrackerData[i].price); - SaveManager::Instance->LoadData("hintItem", gSaveContext.checkTrackerData[i].hintItem); + RandomizerCheckStatus status; + bool skipped; + RandomizerCheck rc; + SaveManager::Instance->LoadData("randomizerCheck", rc, RC_UNKNOWN_CHECK); + SaveManager::Instance->LoadData("status", status, RCSHOW_UNCHECKED); + SaveManager::Instance->LoadData("skipped", skipped, false); + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetCheckStatus(status); + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(skipped); + }); }); - }); - SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled); + SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled, (uint32_t)0); + UpdateAllOrdering(); + UpdateAllAreas(); } void Teardown() { @@ -885,33 +883,17 @@ bool IsAreaSpoiled(RandomizerCheckArea rcArea) { return areasSpoiled & (1 << rcArea); } -void SetAreaSpoiled(RandomizerCheckArea rcArea) { - areasSpoiled |= (1 << rcArea); - SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); +void SetAreasSpoiled(uint32_t areasSpoiled_) { + areasSpoiled = areasSpoiled_; } -void UpdateCheck(uint32_t check, RandomizerCheckTrackerData data) { - auto area = Rando::StaticData::GetLocation(static_cast(check))->GetArea(); - if ((!gSaveContext.checkTrackerData[check].skipped && data.skipped) || - ((gSaveContext.checkTrackerData[check].status != RCSHOW_COLLECTED && gSaveContext.checkTrackerData[check].status != RCSHOW_SAVED) && - (data.status == RCSHOW_COLLECTED || data.status == RCSHOW_SAVED))) { - areaChecksGotten[area]++; - } else if ((gSaveContext.checkTrackerData[check].skipped && !data.skipped) || - ((gSaveContext.checkTrackerData[check].status == RCSHOW_COLLECTED || gSaveContext.checkTrackerData[check].status == RCSHOW_SAVED) && - (data.status != RCSHOW_COLLECTED && data.status != RCSHOW_SAVED))) { - areaChecksGotten[area]--; - } - gSaveContext.checkTrackerData[check] = data; - UpdateOrdering(area); +uint32_t GetAreasSpoiled() { + return areasSpoiled; } -void CheckTrackerWindow::Draw() { - if (!IsVisible()) { - return; - } - DrawElement(); - // Sync up the IsVisible flag if it was changed by ImGui - SyncVisibilityConsoleVariable(); +void SetAreaSpoiled(RandomizerCheckArea rcArea) { + areasSpoiled |= (1 << rcArea); + SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); } void CheckTrackerWindow::DrawElement() { @@ -1368,6 +1350,13 @@ void UpdateInventoryChecks() { void UpdateAreaFullyChecked(RandomizerCheckArea area) { } +void UpdateAllAreas() { + // Sort the entire thing + for (int i = 0; i < RCAREA_INVALID; i++) { + UpdateAreas(static_cast(i)); + } +} + void UpdateAreas(RandomizerCheckArea area) { areasFullyChecked[area] = areaChecksGotten[area] == checksByArea.find(area)->second.size(); } @@ -1393,14 +1382,14 @@ bool IsEoDCheck(RandomizerCheckType type) { } bool CompareChecks(RandomizerCheck i, RandomizerCheck j) { - RandomizerCheckTrackerData iShow = gSaveContext.checkTrackerData[i]; - RandomizerCheckTrackerData jShow = gSaveContext.checkTrackerData[j]; Rando::Location* x = Rando::StaticData::GetLocation(i); Rando::Location* y = Rando::StaticData::GetLocation(j); - bool iCollected = iShow.status == RCSHOW_COLLECTED || iShow.status == RCSHOW_SAVED; - bool iSaved = iShow.status == RCSHOW_SAVED; - bool jCollected = jShow.status == RCSHOW_COLLECTED || jShow.status == RCSHOW_SAVED; - bool jSaved = jShow.status == RCSHOW_SAVED; + auto itemI = OTRGlobals::Instance->gRandoContext->GetItemLocation(i); + auto itemJ = OTRGlobals::Instance->gRandoContext->GetItemLocation(j); + bool iCollected = itemI->HasObtained(); + bool iSaved = itemI->GetCheckStatus() == RCSHOW_SAVED; + bool jCollected = itemJ->HasObtained(); + bool jSaved = itemJ->GetCheckStatus() == RCSHOW_SAVED; if (!iCollected && jCollected) { return true; @@ -1414,9 +1403,9 @@ bool CompareChecks(RandomizerCheck i, RandomizerCheck j) { return false; } - if (!iShow.skipped && jShow.skipped) { + if (!itemI->GetIsSkipped() && itemJ->GetIsSkipped()) { return true; - } else if (iShow.skipped && !jShow.skipped) { + } else if (itemI->GetIsSkipped() && !itemJ->GetIsSkipped()) { return false; } @@ -1446,14 +1435,8 @@ void DrawLocation(RandomizerCheck rc) { bool showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); Rando::Location* loc = Rando::StaticData::GetLocation(rc); Rando::ItemLocation* itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); - RandomizerCheckTrackerData checkData = gSaveContext.checkTrackerData[rc]; - RandomizerCheckStatus status = checkData.status; - - if (itemLoc->HasObtained()) { - status = RCSHOW_COLLECTED; - } - - bool skipped = checkData.skipped; + RandomizerCheckStatus status = itemLoc->GetCheckStatus(); + bool skipped = itemLoc->GetIsSkipped(); if (status == RCSHOW_COLLECTED) { if (!showHidden && CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0)) { return; @@ -1525,10 +1508,10 @@ void DrawLocation(RandomizerCheck rc) { if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED || skipped) { if (UIWidgets::StateButton(std::to_string(rc).c_str(), skipped ? ICON_FA_PLUS : ICON_FA_TIMES)) { if (skipped) { - gSaveContext.checkTrackerData[rc].skipped = false; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); areaChecksGotten[loc->GetArea()]--; } else { - gSaveContext.checkTrackerData[rc].skipped = true; + OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(true); areaChecksGotten[loc->GetArea()]++; } UpdateOrdering(loc->GetArea()); @@ -1550,9 +1533,7 @@ void DrawLocation(RandomizerCheck rc) { bool mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && itemLoc->IsAddedToPool(); - if (checkData.hintItem != 0) { - // TODO hints - } else if (status != RCSHOW_UNCHECKED) { + if (status != RCSHOW_UNCHECKED) { switch (status) { case RCSHOW_SAVED: case RCSHOW_COLLECTED: @@ -1582,7 +1563,7 @@ void DrawLocation(RandomizerCheck rc) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } if (!IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { - txt += fmt::format(" - {}", gSaveContext.checkTrackerData[rc].price); + txt += fmt::format(" - {}", OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice()); } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { @@ -1796,7 +1777,7 @@ void CheckTrackerWindow::InitElement() { Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor"), Color_Saved_Extra_Default); SaveManager::Instance->AddInitFunction(InitTrackerData); - sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, -1); + sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, SECTION_PARENT_NONE); SaveManager::Instance->AddLoadFunction("trackerData", 1, LoadFile); GameInteractor::Instance->RegisterGameHook(CheckTrackerLoadGame); GameInteractor::Instance->RegisterGameHook([](uint32_t fileNum) { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 295bb39b09f..f287ff58fd8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -51,13 +51,14 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc); bool IsCheckShuffled(RandomizerCheck rc); void InitTrackerData(bool isDebug); RandomizerCheckArea GetCheckArea(); -void UpdateCheck(uint32_t, RandomizerCheckTrackerData); uint16_t GetTotalChecks(); uint16_t GetTotalChecksGotten(); bool IsAreaSpoiled(RandomizerCheckArea rcArea); +uint32_t GetAreasSpoiled(); +void SetAreasSpoiled(uint32_t areasSpoiled_); void SetAreaSpoiled(RandomizerCheckArea rcArea); +void UpdateInventoryChecks(); +void UpdateAreas(RandomizerCheckArea area); +void UpdateAllOrdering(); +void UpdateAllAreas(); } // namespace CheckTracker - - -void to_json(nlohmann::json & j, const RandomizerCheckTrackerData& rctd); -void from_json(const nlohmann::json& j, RandomizerCheckTrackerData& rctd); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 8859e8d43cb..bfa2f760607 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -97,7 +97,7 @@ void GiveLinksPocketItem() { if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, (GetItemID)RG_NONE); StartingItemGive(getItemEntry); - Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->MarkAsObtained(); + Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->SetCheckStatus(RCSHOW_SAVED); // If we re-add the above, we'll get the item on save creation, now it's given on first load Flags_SetRandomizerInf(RAND_INF_LINKS_POCKET); } diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 4398d25a545..ba3af402cd9 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -111,6 +111,7 @@ SaveManager::SaveManager() { coreSectionIDsByName["sohStats"] = SECTION_ID_STATS; coreSectionIDsByName["entrances"] = SECTION_ID_ENTRANCES; coreSectionIDsByName["scenes"] = SECTION_ID_SCENES; + coreSectionIDsByName["trackerData"] = SECTION_ID_TRACKER_DATA; AddLoadFunction("base", 1, LoadBaseVersion1); AddLoadFunction("base", 2, LoadBaseVersion2); AddLoadFunction("base", 3, LoadBaseVersion3); @@ -404,13 +405,6 @@ void SaveManager::LoadRandomizerVersion3() { // all ItemLocations is 0 anyway. randoContext->GetItemLocation(i)->SetCustomPrice(price); } - uint16_t obtained = 0; - SaveManager::Instance->LoadData("obtained", obtained, (uint16_t)0); - if (obtained) { - randoContext->GetItemLocation(i)->MarkAsObtained(); - } else { - randoContext->GetItemLocation(i)->MarkAsNotObtained(); - } }); }); @@ -496,7 +490,6 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f if (randoContext->GetItemLocation(i)->HasCustomPrice()) { SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice()); } - SaveManager::Instance->SaveData("obtained", randoContext->GetItemLocation(i)->HasObtained()); }); }); diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index 55480b675c4..ac139ed9729 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -163,6 +163,8 @@ class SaveManager { static void LoadRandomizerVersion1(); static void LoadRandomizerVersion2(); static void LoadRandomizerVersion3(); + static void LoadTrackerData(); + static void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave); static void SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave); static void LoadBaseVersion1(); From 3fc90d84bbf52bf1320815938b7bbc2056bf45a3 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Tue, 3 Sep 2024 20:21:15 -0700 Subject: [PATCH 2/9] Fix shop checks not showing prices when identified. --- soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index c1ba3e84122..6403ac7185b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1562,7 +1562,7 @@ void DrawLocation(RandomizerCheck rc) { } else if (!mystery) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } - if (!IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { + if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { txt += fmt::format(" - {}", OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice()); } } else { From c01b30a6b06f543fa2a9421a23690c5ee27ec17c Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 4 Sep 2024 11:33:24 -0700 Subject: [PATCH 3/9] Patch fix for check status bleed. Some cleanup of unused code. --- .../randomizer/randomizer_check_tracker.cpp | 56 ------------------- .../randomizer/randomizer_check_tracker.h | 1 - soh/soh/SaveManager.cpp | 2 +- 3 files changed, 1 insertion(+), 58 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 6403ac7185b..536ef7ebb5b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -140,7 +140,6 @@ bool CompareChecks(RandomizerCheck, RandomizerCheck); bool CheckByArea(RandomizerCheckArea); void DrawLocation(RandomizerCheck); void EndFloatWindows(); -bool HasItemBeenCollected(RandomizerCheck); void LoadSettings(); void RainbowTick(); void UpdateAreas(RandomizerCheckArea area); @@ -427,51 +426,6 @@ void SetShopSeen(uint32_t sceneNum, bool prices) { } } -bool HasItemBeenCollected(RandomizerCheck rc) { - if (gPlayState == nullptr) { - return false; - } - Rando::Location* x = Rando::StaticData::GetLocation(rc); - Rando::SpoilerCollectionCheck check = x->GetCollectionCheck(); - auto flag = check.flag; - auto scene = check.scene; - auto type = check.type; - - switch (type) { - case SpoilerCollectionCheckType::SPOILER_CHK_ALWAYS_COLLECTED: - return true; - case SpoilerCollectionCheckType::SPOILER_CHK_CHEST: - return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.chest & (1 << flag)) || - gSaveContext.sceneFlags[scene].chest & (1 << flag); - case SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE: - return (gPlayState->sceneNum == scene && gPlayState->actorCtx.flags.collect & (1 << flag)) || - gSaveContext.sceneFlags[scene].collect & (1 << flag); - case SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM: - case SpoilerCollectionCheckType::SPOILER_CHK_FISH: - case SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF: - case SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD: - return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)); - case SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF: - return gSaveContext.eventChkInf[flag / 16] & (0x01 << flag % 16); - case SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA: - return GET_GS_FLAGS(scene) & flag; - case SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE: - return gSaveContext.infTable[scene] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); - case SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF: - return gSaveContext.itemGetInf[flag / 16] & INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(flag); - case SpoilerCollectionCheckType::SPOILER_CHK_NONE: - return false; - case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER: - // Gravedigger has a fix in place that means one of two save locations. Check both. - return (gSaveContext.itemGetInf[1] & 0x1000) || // vanilla flag - ((IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("GravediggingTourFix"), 0)) && - gSaveContext.sceneFlags[scene].collect & (1 << flag) || (gPlayState->actorCtx.flags.collect & (1 << flag))); // rando/fix flag - default: - return false; - } - return false; -} - void CheckTrackerLoadGame(int32_t fileNum) { LoadSettings(); TrySetAreas(); @@ -484,11 +438,6 @@ void CheckTrackerLoadGame(int32_t fileNum) { Rando::Location* entry2 = Rando::StaticData::GetLocation(rc); Rando::ItemLocation* loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); - //if (rc == RC_GIFT_FROM_SAGES && !IS_RANDO) { - // entry2 = Rando::StaticData::GetLocation(rc); - //} else { - // entry2 = Rando::StaticData::GetLocation(rc); - //} checksByArea.find(entry2->GetArea())->second.push_back(entry2->GetRandomizerCheck()); if (IsVisibleInCheckTracker(entry2->GetRandomizerCheck())) { @@ -803,11 +752,6 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; - //for (auto& loc : Rando::StaticData::GetLocationTable()) { - // if (loc.GetRandomizerCheck() != RC_UNKNOWN_CHECK && loc.GetRandomizerCheck() != RC_MAX) { - // DefaultCheckData(loc.GetRandomizerCheck()); - // } - //} UpdateAllOrdering(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index f287ff58fd8..7c1ada4de79 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -44,7 +44,6 @@ class CheckTrackerWindow : public Ship::GuiWindow { //repeat... #define INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(idx) (0x8000 >> (7 - (idx % 8) + ((idx % 16) / 8) * 8)) -void DefaultCheckData(RandomizerCheck rc); void Teardown(); void UpdateAllOrdering(); bool IsVisibleInCheckTracker(RandomizerCheck rc); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index ba3af402cd9..10e3a694b40 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -659,8 +659,8 @@ void SaveManager::Init() { if (std::filesystem::exists(GetFileName(fileNum))) { LoadFile(fileNum); saveBlock = nlohmann::json::object(); + OTRGlobals::Instance->gRandoContext->ClearItemLocations(); } - } } From b77a6b634524cae98a33ec8a80b75578f3ced918 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 4 Sep 2024 13:05:57 -0700 Subject: [PATCH 4/9] Small tracker optimizations. --- .../randomizer/randomizer_check_tracker.cpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 536ef7ebb5b..403b2288a9e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -134,7 +134,7 @@ OSContPad* trackerButtonsPressed; std::unordered_map checkNameOverrides; bool ShouldShowCheck(RandomizerCheck rc); -bool ShouldHideArea(RandomizerCheckArea rcArea); +bool UpdateFilters(); void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0); bool CompareChecks(RandomizerCheck, RandomizerCheck); bool CheckByArea(RandomizerCheckArea); @@ -203,6 +203,9 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; +static uint32_t filterSize = 0; +static std::array filterAreasHidden = { 0 }; +static std::array filterChecksHidden = { 0 }; void SongFromImpa() { if (IS_RANDO) { @@ -753,6 +756,7 @@ void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; UpdateAllOrdering(); + UpdateFilters(); } void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { @@ -819,6 +823,8 @@ void Teardown() { ClearAreaChecksAndTotals(); checksByArea.clear(); areasSpoiled = 0; + filterAreasHidden = { 0 }; + filterChecksHidden = { 0 }; lastLocationChecked = RC_UNKNOWN_CHECK; } @@ -911,7 +917,9 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = true; } UIWidgets::Tooltip("Clear the search field"); - checkSearch.Draw(); + //if (checkSearch.Draw()) { + // UpdateFilters(); + //} UIWidgets::PaddedSeparator(); @@ -965,7 +973,7 @@ void CheckTrackerWindow::DrawElement() { previousShowHidden = showHidden; doAreaScroll = true; } - if ((shouldHideFilteredAreas && ShouldHideArea(rcArea)) || + if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || (!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) ) { doDraw = false; @@ -1025,7 +1033,7 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = false; } for (auto rc : checks) { - if (doDraw && isThisAreaSpoiled && ShouldShowCheck(rc)) { + if (doDraw && isThisAreaSpoiled && !filterChecksHidden[rc]) { DrawLocation(rc); } } @@ -1045,13 +1053,11 @@ void CheckTrackerWindow::DrawElement() { } } -bool ShouldHideArea(RandomizerCheckArea rcArea) { - if (checkSearch.Filters.Size == 0 || checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) { - return false; - } - for (auto check : checksByArea[rcArea]) { - if (ShouldShowCheck(check)) { - return false; +bool UpdateFilters() { + for (auto& [rcArea, checks] : checksByArea) { + filterAreasHidden[rcArea] = !checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str()); + for (auto check : checks) { + filterChecksHidden[check] = !ShouldShowCheck(check); } } @@ -1533,8 +1539,7 @@ void DrawLocation(RandomizerCheck rc) { } if (CVarGetInteger("gCheckTrackerOptionShowLogic", 0)) { - std::vector locationsInRegion = areaTable[itemLoc->GetParentRegionKey()].locations; - for (auto& locationInRegion : locationsInRegion) { + for (auto& locationInRegion : areaTable[itemLoc->GetParentRegionKey()].locations) { if (locationInRegion.GetLocation() == rc) { std::string conditionStr = locationInRegion.GetConditionStr(); if (conditionStr != "true") { From 7676f4714d8cd9d62a42de29db058c7bda9a94a2 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 4 Sep 2024 15:25:02 -0700 Subject: [PATCH 5/9] Fix check hiding. --- .../Enhancements/randomizer/randomizer_check_tracker.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 403b2288a9e..ce6e7898160 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -203,9 +203,8 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; -static uint32_t filterSize = 0; -static std::array filterAreasHidden = { 0 }; -static std::array filterChecksHidden = { 0 }; +std::array filterAreasHidden = { 0 }; +std::array filterChecksHidden = { 0 }; void SongFromImpa() { if (IS_RANDO) { @@ -500,6 +499,7 @@ void CheckTrackerLoadGame(int32_t fileNum) { initialized = true; UpdateAllOrdering(); UpdateInventoryChecks(); + UpdateFilters(); } void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) { @@ -755,8 +755,6 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; - UpdateAllOrdering(); - UpdateFilters(); } void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { From 6c059d9947693a498352ef346af384846f589b33 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 4 Sep 2024 17:13:35 -0700 Subject: [PATCH 6/9] Bit more cleanup. --- .../randomizer/randomizer_check_tracker.cpp | 10 ---------- .../Enhancements/randomizer/randomizer_check_tracker.h | 2 -- 2 files changed, 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index ce6e7898160..70fffa7bcfb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -831,14 +831,6 @@ bool IsAreaSpoiled(RandomizerCheckArea rcArea) { return areasSpoiled & (1 << rcArea); } -void SetAreasSpoiled(uint32_t areasSpoiled_) { - areasSpoiled = areasSpoiled_; -} - -uint32_t GetAreasSpoiled() { - return areasSpoiled; -} - void SetAreaSpoiled(RandomizerCheckArea rcArea) { areasSpoiled |= (1 << rcArea); SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true); @@ -1739,8 +1731,6 @@ void CheckTrackerWindow::InitElement() { hideShopRightChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideRightShopChecks"), 1); alwaysShowGS = CVarGetInteger(CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), 0); - - //LocationTable_Init(); } } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 7c1ada4de79..4e6972e6b07 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -53,8 +53,6 @@ RandomizerCheckArea GetCheckArea(); uint16_t GetTotalChecks(); uint16_t GetTotalChecksGotten(); bool IsAreaSpoiled(RandomizerCheckArea rcArea); -uint32_t GetAreasSpoiled(); -void SetAreasSpoiled(uint32_t areasSpoiled_); void SetAreaSpoiled(RandomizerCheckArea rcArea); void UpdateInventoryChecks(); void UpdateAreas(RandomizerCheckArea area); From 22ea6a3d0530e42225c386ddc81d0c787692fbf8 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 14 Sep 2024 13:24:47 -0700 Subject: [PATCH 7/9] Unhide the filter and make it work again... --- .../randomizer/randomizer_check_tracker.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 70fffa7bcfb..fe2be49468c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -907,9 +907,9 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = true; } UIWidgets::Tooltip("Clear the search field"); - //if (checkSearch.Draw()) { - // UpdateFilters(); - //} + if (checkSearch.Draw()) { + UpdateFilters(); + } UIWidgets::PaddedSeparator(); @@ -1047,7 +1047,12 @@ bool UpdateFilters() { for (auto& [rcArea, checks] : checksByArea) { filterAreasHidden[rcArea] = !checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str()); for (auto check : checks) { - filterChecksHidden[check] = !ShouldShowCheck(check); + if (ShouldShowCheck(check)) { + filterAreasHidden[rcArea] = false; + filterChecksHidden[check] = false; + } else { + filterChecksHidden[check] = true; + } } } @@ -1058,8 +1063,9 @@ bool ShouldShowCheck(RandomizerCheck check) { return ( IsVisibleInCheckTracker(check) && (checkSearch.Filters.Size == 0 || - checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea()).c_str()) || - checkSearch.PassFilter(Rando::StaticData::GetLocation(check)->GetShortName().c_str())) + checkSearch.PassFilter((Rando::StaticData::GetLocation(check)->GetShortName() + " " + + Rando::StaticData::GetLocation(check)->GetName() + " " + + RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())).c_str())) ); } From a77504b54d2a34880fa2d0f7690974ed615187e1 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 14 Sep 2024 15:52:48 -0700 Subject: [PATCH 8/9] Fix area totals tracking. Fix skipped status saving. --- .../Enhancements/randomizer/hook_handlers.cpp | 3 ++ .../randomizer/randomizer_check_tracker.cpp | 46 +++++++++++-------- .../randomizer/randomizer_check_tracker.h | 1 + 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 29ea3e7b4ac..4d500ada9c7 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -306,6 +306,7 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, static_cast(randomizerQueuedCheck)); loc->SetCheckStatus(RCSHOW_COLLECTED); + CheckTracker::RecalculateAllAreaTotals(); SaveManager::Instance->SaveSection(gSaveContext.fileNum, SECTION_ID_TRACKER_DATA, true); randomizerQueuedCheck = RC_UNKNOWN_CHECK; randomizerQueuedItemEntry = GET_ITEM_NONE; @@ -658,6 +659,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void } else { *should = true; Rando::Context::GetInstance()->GetItemLocation(RC_TOT_MASTER_SWORD)->SetCheckStatus(RCSHOW_COLLECTED); + CheckTracker::RecalculateAllAreaTotals(); } break; case VB_ITEM00_DESPAWN: { @@ -1193,6 +1195,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->SetCheckStatus(RCSHOW_UNCHECKED); + CheckTracker::RecalculateAllAreaTotals(); } // LACs & Prelude checks diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index fe2be49468c..fa67fd1eb18 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -260,26 +260,28 @@ uint16_t GetTotalChecksGotten() { return totalChecksGotten; } -void RecalculateAreaTotals() { - for (auto [rcArea, checks] : checksByArea) { - if (rcArea == RCAREA_INVALID) { - return; +void RecalculateAreaTotals(RandomizerCheckArea rcArea) { + areaChecksGotten[rcArea] = 0; + areaCheckTotals[rcArea] = 0; + for (auto rc : checksByArea.at(rcArea)) { + if (!IsVisibleInCheckTracker(rc)) { + continue; } - areaChecksGotten[rcArea] = 0; - areaCheckTotals[rcArea] = 0; - for (auto rc : checks) { - if (!IsVisibleInCheckTracker(rc)) { - continue; - } - areaCheckTotals[rcArea]++; - if (OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped() || OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->HasObtained()) { - areaChecksGotten[rcArea]++; - } + areaCheckTotals[rcArea]++; + if (OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetIsSkipped() || OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->HasObtained()) { + areaChecksGotten[rcArea]++; } } + CalculateTotals(); +} - totalChecks = 0; - totalChecksGotten = 0; +void RecalculateAllAreaTotals() { + for (auto& [rcArea, checks] : checksByArea) { + if (rcArea == RCAREA_INVALID) { + return; + } + RecalculateAreaTotals(rcArea); + } } void SetCheckCollected(RandomizerCheck rc) { @@ -406,6 +408,8 @@ void ClearAreaChecksAndTotals() { areaChecksGotten[rcArea] = 0; areaCheckTotals[rcArea] = 0; } + totalChecks = 0; + totalChecksGotten = 0; } void SetShopSeen(uint32_t sceneNum, bool prices) { @@ -768,7 +772,7 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { SaveManager::Instance->SaveArray("checkStatus", checkCount.size(), [&](size_t i) { RandomizerCheck check = checkCount.at(i); RandomizerCheckStatus savedStatus = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetCheckStatus(); - bool isSkipped = OTRGlobals::Instance->gRandoContext->GetItemLocation(i)->GetIsSkipped(); + bool isSkipped = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetIsSkipped(); if (savedStatus == RCSHOW_COLLECTED) { if (fullSave) { OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->SetCheckStatus(RCSHOW_SAVED); @@ -1319,7 +1323,7 @@ void UpdateOrdering(RandomizerCheckArea rcArea) { if(checksByArea.contains(rcArea)) { std::sort(checksByArea.find(rcArea)->second.begin(), checksByArea.find(rcArea)->second.end(), CompareChecks); } - + RecalculateAllAreaTotals(); CalculateTotals(); } @@ -1456,9 +1460,11 @@ void DrawLocation(RandomizerCheck rc) { if (skipped) { OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); areaChecksGotten[loc->GetArea()]--; + totalChecksGotten--; } else { OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(true); areaChecksGotten[loc->GetArea()]++; + totalChecksGotten++; } UpdateOrdering(loc->GetArea()); UpdateInventoryChecks(); @@ -1668,12 +1674,12 @@ void CheckTrackerSettingsWindow::DrawElement() { UIWidgets::Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. Otherwise, Vanilla/MQ dungeon locations must be unlocked."); if (UIWidgets::EnhancementCheckbox("Hide right-side shop item checks", CVAR_TRACKER_CHECK("HideRightShopChecks"), false, "", UIWidgets::CheckboxGraphics::Cross, true)) { hideShopRightChecks = !hideShopRightChecks; - RecalculateAreaTotals(); + RecalculateAllAreaTotals(); } UIWidgets::Tooltip("If enabled, will prevent the tracker from displaying slots 1-4 in all shops."); if (UIWidgets::EnhancementCheckbox("Always show gold skulltulas", CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), false, "")) { alwaysShowGS = !alwaysShowGS; - RecalculateAreaTotals(); + RecalculateAllAreaTotals(); } UIWidgets::Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings."); UIWidgets::EnhancementCheckbox("Show Logic", "gCheckTrackerOptionShowLogic"); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 4e6972e6b07..07390e9458b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -58,4 +58,5 @@ void UpdateInventoryChecks(); void UpdateAreas(RandomizerCheckArea area); void UpdateAllOrdering(); void UpdateAllAreas(); +void RecalculateAllAreaTotals(); } // namespace CheckTracker From 5f4a23007dad4cb99108931916723e606f979d21 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Sat, 14 Sep 2024 23:31:11 -0700 Subject: [PATCH 9/9] Merge conflict cleanup. --- soh/soh/Enhancements/randomizer/randomizer_check_tracker.h | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 07390e9458b..3d3330f218f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -21,7 +21,6 @@ class CheckTrackerSettingsWindow : public Ship::GuiWindow { class CheckTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; - void Draw() override; ~CheckTrackerWindow() {}; protected: