From ce6edf821d4861f2da9e1be6b9b0d5e323574fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Sat, 17 Oct 2026 16:45:33 +0000 Subject: [PATCH] Fix tracker showing too any keys with skeleton key after using key (#7403) --- soh/soh/Enhancements/randomizer/dungeon.cpp | 5 +++++ soh/soh/Enhancements/randomizer/dungeon.h | 2 ++ soh/soh/Enhancements/randomizer/randomizer.cpp | 11 ++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index e0fb53132e..d730287635 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -177,6 +177,11 @@ int8_t GetSceneTotalSmallKeys(const SaveContext* saveContext, const SceneID scen return FindCurrentSmallKeys(saveContext, scene); } +int8_t GetSceneUnspentSmallKeyMax(const SaveContext* saveContext, const SceneID scene) { + int8_t used = GetSceneTotalSmallKeys(saveContext, scene) - FindCurrentSmallKeys(saveContext, scene); + return GetSceneSmallKeyMax(scene) - used; +} + int8_t DungeonInfo::GetUsedSmallKeys(SaveContext* saveContext) const { return FindUsedSmallKeys(saveContext, scene, GetDoorFlags()); } diff --git a/soh/soh/Enhancements/randomizer/dungeon.h b/soh/soh/Enhancements/randomizer/dungeon.h index f956b7bfe3..4e5ca931b7 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.h +++ b/soh/soh/Enhancements/randomizer/dungeon.h @@ -83,6 +83,8 @@ int8_t FindTotalSmallKeys(const SaveContext* saveContext, const SceneID scene, s uint8_t GetSceneSmallKeyMax(SceneID scene); /// Small keys held for the scene plus the ones already spent there. int8_t GetSceneTotalSmallKeys(const SaveContext* saveContext, SceneID scene); +/// The scene's small key max, minus keys already used on doors. Key rings and skeleton key set held keys to this. +int8_t GetSceneUnspentSmallKeyMax(const SaveContext* saveContext, SceneID scene); typedef enum { DEKU_TREE, diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 6d10ccf77e..03b209b0a1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1169,13 +1169,13 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { // This isn't technically necessary, because keys will no longer be consumed, // but for the player's sanity we display that they _have_ keys. for (Rando::DungeonInfo* dungeon : Rando::Context::GetInstance()->GetDungeons()->GetDungeonList()) { - uint8_t keys = Rando::GetSceneSmallKeyMax(dungeon->GetScene()); - if (keys > 0) { - gSaveContext.inventory.dungeonKeys[dungeon->GetScene()] = keys; + if (Rando::GetSceneSmallKeyMax(dungeon->GetScene()) > 0) { + gSaveContext.inventory.dungeonKeys[dungeon->GetScene()] = + Rando::GetSceneUnspentSmallKeyMax(&gSaveContext, dungeon->GetScene()); } } gSaveContext.inventory.dungeonKeys[SCENE_THIEVES_HIDEOUT] = - Rando::GetSceneSmallKeyMax(SCENE_THIEVES_HIDEOUT); + Rando::GetSceneUnspentSmallKeyMax(&gSaveContext, SCENE_THIEVES_HIDEOUT); } else if (item >= RG_KEATON_MASK && item <= RG_MASK_OF_TRUTH) { if (!ChildTradeSlotOccupied()) { INV_CONTENT(ITEM_TRADE_CHILD) = (int)ITEM_MASK_KEATON + (item - RG_KEATON_MASK); @@ -1348,7 +1348,8 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_TREASURE_GAME_KEY_RING)) { u8 keysOnRing = Rando::GetSceneSmallKeyMax((SceneID)mapIndex); gSaveContext.ship.stats.dungeonKeys[mapIndex] = keysOnRing; - gSaveContext.inventory.dungeonKeys[mapIndex] = keysOnRing; + gSaveContext.inventory.dungeonKeys[mapIndex] = + Rando::GetSceneUnspentSmallKeyMax(&gSaveContext, (SceneID)mapIndex); return Return_Item_Entry(giEntry, RG_NONE); }