From 2845baad6c38a8e27ad675eb5b82c605b5e9d6f1 Mon Sep 17 00:00:00 2001 From: xxAtrain223 Date: Sun, 24 May 2026 15:49:00 -0700 Subject: [PATCH] Identify checks for Merchants and Scrubs (#6641) Identify checks for merchants and deku scrubs to show their prices and non-mysterious checks in the check tracker. --- .../randomizer/randomizer_check_tracker.cpp | 85 +++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a9dd72d0b0..29418cb918 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -15,6 +15,8 @@ #include "3drando/fill.hpp" #include "soh/Enhancements/debugger/performanceTimer.h" #include "soh/Enhancements/randomizer/randomizer.h" +#include "soh/ObjectExtension/ObjectExtension.h" +#include "overlays/actors/ovl_En_GirlA/z_en_girla.h" #include #include @@ -865,6 +867,32 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { } } +void CheckTrackerDialogMessage() { + auto identifyCheck = [](RandomizerCheck rc) { + auto loc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); + if (loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + loc->SetCheckStatus(RCSHOW_IDENTIFIED); + RecalculateAvailableChecks(); + } + }; + + if (gPlayState->msgCtx.textId == TEXT_BEAN_SALESMAN_BUY_FOR_10) { + identifyCheck(RC_ZR_MAGIC_BEAN_SALESMAN); + } else if (gPlayState->msgCtx.textId == TEXT_MEDIGORON) { + identifyCheck(RC_GC_MEDIGORON); + } else if (gPlayState->msgCtx.textId == TEXT_GRANNYS_SHOP) { + identifyCheck(RC_KAK_GRANNYS_SHOP); + } else if (gPlayState->msgCtx.textId == TEXT_CARPET_SALESMAN_1) { + identifyCheck(RC_WASTELAND_BOMBCHU_SALESMAN); + } else if (gPlayState->msgCtx.textId == TEXT_SCRUB_RANDOM) { + if (auto* actor = gPlayState->msgCtx.talkActor) { + if (auto* checkIdentity = ObjectExtension::GetInstance().Get(actor)) { + identifyCheck(checkIdentity->identity.randomizerCheck); + } + } + } +} + void InitTrackerData(bool isDebug) { TrySetAreas(); areasSpoiled = 0; @@ -1829,6 +1857,42 @@ bool IsHeartPiece(GetItemID giid) { return giid == GI_HEART_PIECE || giid == GI_HEART_PIECE_WIN; } +bool IsMysteryShopItem(RandomizerCheck rc) { + s32 sceneNum = 0; + u8 slotIndex = 0; + + if (rc >= RC_KF_SHOP_ITEM_1 && rc <= RC_KF_SHOP_ITEM_8) { + sceneNum = SCENE_KOKIRI_SHOP; + slotIndex = rc - RC_KF_SHOP_ITEM_1; + } else if (rc >= RC_MARKET_BAZAAR_ITEM_1 && rc <= RC_MARKET_BAZAAR_ITEM_8) { + sceneNum = SCENE_BAZAAR; + slotIndex = rc - RC_MARKET_BAZAAR_ITEM_1; + } else if (rc >= RC_MARKET_POTION_SHOP_ITEM_1 && rc <= RC_MARKET_POTION_SHOP_ITEM_8) { + sceneNum = SCENE_POTION_SHOP_MARKET; + slotIndex = rc - RC_MARKET_POTION_SHOP_ITEM_1; + } else if (rc >= RC_MARKET_BOMBCHU_SHOP_ITEM_1 && rc <= RC_MARKET_BOMBCHU_SHOP_ITEM_8) { + sceneNum = SCENE_BOMBCHU_SHOP; + slotIndex = rc - RC_MARKET_BOMBCHU_SHOP_ITEM_1; + } else if (rc >= RC_KAK_BAZAAR_ITEM_1 && rc <= RC_KAK_BAZAAR_ITEM_8) { + sceneNum = SCENE_TEST01; + slotIndex = rc - RC_KAK_BAZAAR_ITEM_1; + } else if (rc >= RC_KAK_POTION_SHOP_ITEM_1 && rc <= RC_KAK_POTION_SHOP_ITEM_8) { + sceneNum = SCENE_POTION_SHOP_KAKARIKO; + slotIndex = rc - RC_KAK_POTION_SHOP_ITEM_1; + } else if (rc >= RC_GC_SHOP_ITEM_1 && rc <= RC_GC_SHOP_ITEM_8) { + sceneNum = SCENE_GORON_SHOP; + slotIndex = rc - RC_GC_SHOP_ITEM_1; + } else if (rc >= RC_ZD_SHOP_ITEM_1 && rc <= RC_ZD_SHOP_ITEM_8) { + sceneNum = SCENE_ZORA_SHOP; + slotIndex = rc - RC_ZD_SHOP_ITEM_1; + } else { + return false; + } + + ShopItemIdentity shopItemIdentity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(sceneNum, slotIndex + 1); + return shopItemIdentity.enGirlAShopItem == SI_RANDOMIZED_ITEM; +} + void DrawLocation(RandomizerCheck rc) { Color_RGBA8 mainColor; Color_RGBA8 extraColor; @@ -1986,7 +2050,17 @@ void DrawLocation(RandomizerCheck rc) { case RCSHOW_IDENTIFIED: case RCSHOW_SEEN: if (IS_RANDO) { - if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery) { + const auto checkType = loc->GetRCType(); + const bool hideMerchantName = + checkType == RCTYPE_MERCHANT && + (!OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MERCHANT_TEXT_HINT) || mystery); + const bool hideScrubName = + checkType == RCTYPE_SCRUB && + (!OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SCRUB_TEXT_HINT) || mystery); + const bool hideShopName = checkType == RCTYPE_SHOP && mystery && IsMysteryShopItem(rc); + const bool revealItemName = !(hideMerchantName || hideScrubName || hideShopName); + + if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && revealItemName) { if (status == RCSHOW_IDENTIFIED) { txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage( gSaveContext.language); @@ -1996,14 +2070,12 @@ void DrawLocation(RandomizerCheck rc) { .GetName() .GetForLanguage(gSaveContext.language); } - } else if (!mystery) { + } else if (revealItemName) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } - if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) { + if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED) { auto price = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice(); - if (price) { - txt += fmt::format(" - {}", price); - } + txt = !txt.empty() ? fmt::format("{} - {}", txt, price) : fmt::format("{}", price); } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { @@ -2361,6 +2433,7 @@ void CheckTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange); GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet); GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet); + GameInteractor::Instance->RegisterGameHook(CheckTrackerDialogMessage); } void CheckTrackerWindow::UpdateElement() {