From 1fea642f337ef1424d2aa1068d485c01ab31af10 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 4 Dec 2023 13:26:55 +0000 Subject: [PATCH] Fix OnItemReceive hook for items in the extendedVanillaGetItem table (#3063) --- soh/soh/OTRGlobals.cpp | 44 ++++++++++++++++++++++++++++++++------ soh/soh/OTRGlobals.h | 3 ++- soh/src/code/z_parameter.c | 32 +++++++++++++++++++-------- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 7bf6785a5..177a43834 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -665,7 +665,7 @@ extern "C" void VanillaItemTable_Init() { } } -std::unordered_map ItemIDtoGetItemID{ +std::unordered_map ItemIDtoGetItemIDMap { { ITEM_ARROWS_LARGE, GI_ARROWS_LARGE }, { ITEM_ARROWS_MEDIUM, GI_ARROWS_MEDIUM }, { ITEM_ARROWS_SMALL, GI_ARROWS_SMALL }, @@ -695,7 +695,8 @@ std::unordered_map ItemIDtoGetItemID{ { ITEM_BUG, GI_BUGS }, { ITEM_BULLET_BAG_30, GI_BULLET_BAG_30 }, { ITEM_BULLET_BAG_40, GI_BULLET_BAG_40 }, - { ITEM_BULLET_BAG_50, GI_BULLET_BAG_50 }, { ITEM_CHICKEN, GI_CHICKEN }, + { ITEM_BULLET_BAG_50, GI_BULLET_BAG_50 }, + { ITEM_CHICKEN, GI_CHICKEN }, { ITEM_CLAIM_CHECK, GI_CLAIM_CHECK }, { ITEM_COJIRO, GI_COJIRO }, { ITEM_COMPASS, GI_COMPASS }, @@ -791,11 +792,42 @@ std::unordered_map ItemIDtoGetItemID{ { ITEM_WEIRD_EGG, GI_WEIRD_EGG } }; -extern "C" int32_t GetGIID(uint32_t itemID) { - if (ItemIDtoGetItemID.contains(itemID)) { - return ItemIDtoGetItemID.at(itemID); +extern "C" GetItemID RetrieveGetItemIDFromItemID(ItemID itemID) { + if (ItemIDtoGetItemIDMap.contains(itemID)) { + return ItemIDtoGetItemIDMap.at(itemID); } - return -1; + return GI_MAX; +} + +std::unordered_map ItemIDtoRandomizerGetMap { + { ITEM_SONG_MINUET, RG_MINUET_OF_FOREST }, + { ITEM_SONG_BOLERO, RG_BOLERO_OF_FIRE }, + { ITEM_SONG_SERENADE, RG_SERENADE_OF_WATER }, + { ITEM_SONG_REQUIEM, RG_REQUIEM_OF_SPIRIT }, + { ITEM_SONG_NOCTURNE, RG_NOCTURNE_OF_SHADOW }, + { ITEM_SONG_PRELUDE, RG_PRELUDE_OF_LIGHT }, + { ITEM_SONG_LULLABY, RG_ZELDAS_LULLABY }, + { ITEM_SONG_EPONA, RG_EPONAS_SONG }, + { ITEM_SONG_SARIA, RG_SARIAS_SONG }, + { ITEM_SONG_SUN, RG_SUNS_SONG }, + { ITEM_SONG_TIME, RG_SONG_OF_TIME }, + { ITEM_SONG_STORMS, RG_SONG_OF_STORMS }, + { ITEM_MEDALLION_FOREST, RG_FOREST_MEDALLION }, + { ITEM_MEDALLION_FIRE, RG_FIRE_MEDALLION }, + { ITEM_MEDALLION_WATER, RG_WATER_MEDALLION }, + { ITEM_MEDALLION_SPIRIT, RG_SPIRIT_MEDALLION }, + { ITEM_MEDALLION_SHADOW, RG_SHADOW_MEDALLION }, + { ITEM_MEDALLION_LIGHT, RG_LIGHT_MEDALLION }, + { ITEM_KOKIRI_EMERALD, RG_KOKIRI_EMERALD }, + { ITEM_GORON_RUBY, RG_GORON_RUBY }, + { ITEM_ZORA_SAPPHIRE, RG_ZORA_SAPPHIRE }, +}; + +extern "C" RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID) { + if (ItemIDtoRandomizerGetMap.contains(itemID)) { + return ItemIDtoRandomizerGetMap.at(itemID); + } + return RG_MAX; } extern "C" void OTRExtScanner() { diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 403d493f5..48cd0cd48 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -180,7 +180,8 @@ void SaveManager_ThreadPoolWait(); void CheckTracker_OnMessageClose(); void SoH_ProcessDroppedFiles(); -int32_t GetGIID(uint32_t itemID); +GetItemID RetrieveGetItemIDFromItemID(ItemID itemID); +RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID); #endif #ifdef __cplusplus diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index d7675fd90..552d28e73 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1804,12 +1804,22 @@ u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { GetItemEntry gie = { ITEM_SOLD_OUT, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_LESSER, NULL }; return Return_Item_Entry(gie, returnItem); } - int32_t get = GetGIID(itemID); - if (get == -1) { - modId = MOD_RANDOMIZER; - get = itemID; + + GetItemID getItemID = RetrieveGetItemIDFromItemID(itemID); + if (getItemID != GI_MAX) { + // Vanilla ItemID with an associated GetItemID + return Return_Item_Entry(ItemTable_RetrieveEntry(modId, getItemID), returnItem); } - return Return_Item_Entry(ItemTable_RetrieveEntry(modId, get), returnItem); + + RandomizerGet randomizerGet = RetrieveRandomizerGetFromItemID(itemID); + if (randomizerGet != RG_MAX) { + // Vanilla ItemID with an associated RandomizerGet (These are items in extendedVanillaGetItemTable) + return Return_Item_Entry(ItemTable_RetrieveEntry(MOD_RANDOMIZER, randomizerGet), returnItem); + } + + // All randomizer items should go through Randomizer_Item_Give, so this should never be reached + // but leaving this here just in case, as it was in the original behavior + return Return_Item_Entry(ItemTable_RetrieveEntry(MOD_RANDOMIZER, itemID), returnItem); } /** @@ -6556,11 +6566,15 @@ void Interface_Update(PlayState* play) { gSaveContext.pendingSale = ITEM_NONE; gSaveContext.pendingSaleMod = MOD_NONE; if (tempSaleMod == MOD_NONE) { - s16 giid = GetGIID(tempSaleItem); - if (giid == -1) { - tempSaleMod = MOD_RANDOMIZER; + GetItemID getItemID = RetrieveGetItemIDFromItemID(tempSaleItem); + RandomizerGet randomizerGet = RetrieveRandomizerGetFromItemID(tempSaleItem); + if (getItemID != GI_MAX) { + tempSaleItem = getItemID; } else { - tempSaleItem = giid; + if (randomizerGet != RG_MAX) { + tempSaleItem = randomizerGet; + } + tempSaleMod = MOD_RANDOMIZER; } } GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod, tempSaleItem));