From f431f7df724bcd3eddb6882589b2772f480b1ff3 Mon Sep 17 00:00:00 2001 From: lil David <1337lilDavid@gmail.com> Date: Sun, 14 Aug 2022 12:29:56 -0500 Subject: [PATCH 1/7] Add Bombchus in Logic rando setting and implement progressive chus --- .../Enhancements/randomizer/randomizer.cpp | 25 ++++++++++++++++++- .../Enhancements/randomizer/randomizerTypes.h | 3 ++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index ca86793cc1..100d36c173 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1452,6 +1452,7 @@ std::unordered_map SpoilerfileSettingNameToEn { "Shuffle Dungeon Items:Gerudo Fortress Keys", RSK_GERUDO_KEYS }, { "Shuffle Dungeon Items:Boss Keys", RSK_BOSS_KEYSANITY }, { "Shuffle Dungeon Items:Ganon's Boss Key", RSK_GANONS_BOSS_KEY }, + { "World Settings:Bombchus in Logic", RSK_BOMBCHUS_IN_LOGIC }, { "Misc Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS }, { "Misc Settings:Hint Clarity", RSK_HINT_CLARITY }, { "Misc Settings:Hint Distribution", RSK_HINT_DISTRIBUTION }, @@ -2229,7 +2230,13 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) return GI_RUPEE_BLUE; case RG_PROGRESSIVE_BOMBCHUS: - return GI_BOMBCHUS_20; //todo progressive? + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { + return GI_BOMBCHUS_20; + } + if (AMMO(ITEM_BOMBCHU) < 5) { + return GI_BOMBCHUS_10; + } + return GI_BOMBCHUS_5; case RG_PROGRESSIVE_MAGIC_METER: switch (gSaveContext.magicLevel) { @@ -3540,6 +3547,7 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_SHUFFLE_TOKENS] = CVar_GetS32("gRandomizeShuffleTokens", 0); cvarSettings[RSK_SHUFFLE_COWS] = CVar_GetS32("gRandomizeShuffleCows", 0); cvarSettings[RSK_SHUFFLE_ADULT_TRADE] = CVar_GetS32("gRandomizeShuffleAdultTrade", 0); + cvarSettings[RSK_BOMBCHUS_IN_LOGIC] = CVar_GetS32("gRandomizeBombchusInLogic", 0); cvarSettings[RSK_SKIP_CHILD_ZELDA] = CVar_GetS32("gRandomizeSkipChildZelda", 0); // if we skip child zelda, we start with zelda's letter, and malon starts @@ -4153,6 +4161,21 @@ void DrawRandoEditor(bool& open) { "This setting does not effect the item earned from playing\n" "the Song of Storms and the frog song minigame." ); + PaddedSeparator(); + + // Bombchus in Logic + // TODO: add to world settings after entrance rando gets merged + SohImGui::EnhancementCheckbox(Settings::BombchusInLogic.GetName().c_str(), "gRandomizeBombchusInLogic"); + InsertHelpHoverText( + "Bombchus are properly considered in logic.\n" + "\n" + "The first Bombchu pack will always be 20, and subsequent packs will be" + "5 or 10 based on how many you have.\n" + "Once found, they can be replenished at the Kokiri shop, Bazaar, or Bombchu" + "shop.\n" + "\n" + "Bombchu Bowling is opened by obtaining Bombchus." + ); } ImGui::PopItemWidth(); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index b09b9dab24..4209766155 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1008,5 +1008,6 @@ typedef enum { RSK_COMPLETE_MASK_QUEST, RSK_ENABLE_GLITCH_CUTSCENES, RSK_SKULLS_SUNS_SONG, - RSK_SHUFFLE_ADULT_TRADE + RSK_SHUFFLE_ADULT_TRADE, + RSK_BOMBCHUS_IN_LOGIC } RandomizerSettingKey; From 8cb50a2ee16ff205e4fcd8fd58b98e8eb88fefc1 Mon Sep 17 00:00:00 2001 From: lil David <1337lilDavid@gmail.com> Date: Sun, 14 Aug 2022 12:30:22 -0500 Subject: [PATCH 2/7] Open Bombchu Bowling with chus --- .../randomizer/3drando/settings.cpp | 2 ++ .../Enhancements/randomizer/randomizer.cpp | 5 ++-- .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 26 ++++++++++++------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 71aa70b323..1482a5cdb2 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2551,6 +2551,8 @@ namespace Settings { MapsAndCompasses.SetSelectedIndex(cvarSettings[RSK_STARTING_MAPS_COMPASSES]); + BombchusInLogic.SetSelectedIndex(cvarSettings[RSK_BOMBCHUS_IN_LOGIC]); + StartingConsumables.SetSelectedIndex(cvarSettings[RSK_STARTING_CONSUMABLES]); StartingMaxRupees.SetSelectedIndex(cvarSettings[RSK_FULL_WALLETS]); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 100d36c173..95401a34ef 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1688,6 +1688,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { case RSK_STARTING_KOKIRI_SWORD: case RSK_COMPLETE_MASK_QUEST: case RSK_ENABLE_GLITCH_CUTSCENES: + case RSK_BOMBCHUS_IN_LOGIC: if(it.value() == "Off") { gSaveContext.randoSettings[index].value = 0; } else if(it.value() == "On") { @@ -4169,9 +4170,9 @@ void DrawRandoEditor(bool& open) { InsertHelpHoverText( "Bombchus are properly considered in logic.\n" "\n" - "The first Bombchu pack will always be 20, and subsequent packs will be" + "The first Bombchu pack will always be 20, and subsequent packs will be " "5 or 10 based on how many you have.\n" - "Once found, they can be replenished at the Kokiri shop, Bazaar, or Bombchu" + "Once found, they can be replenished at the Kokiri shop, Bazaar, or Bombchu " "shop.\n" "\n" "Bombchu Bowling is opened by obtaining Bombchus." diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index dc22f9dab6..28a63bbf62 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -143,13 +143,14 @@ void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, GlobalContext* globalCtx) { } } - // Check for Bomb Bag if Rando is enabled - // RANDOTODO: Check for bombchu pack instead of bomb bag if bombchus are in logic + // Check for Bomb Bag or Bombchus if Rando is enabled, depending on whether bombchus are considered in logic if (gSaveContext.n64ddFlag) { - if (INV_CONTENT(ITEM_BOMB) != ITEM_NONE) { - this->actor.textId = 0xBF; - } else { + u8 bombchusInLogic = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC); + if ((!bombchusInLogic && INV_CONTENT(ITEM_BOMB) == ITEM_NONE) || + (bombchusInLogic && INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE)) { this->actor.textId = 0x7058; + } else { + this->actor.textId = 0xBF; } } } @@ -177,11 +178,16 @@ void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) { this->eyeMode = CHU_GIRL_EYES_AWAKE; this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20; - // Check for beaten Dodongo's Cavern if not rando'd - // check for bomb bag if rando'd - if ((!gSaveContext.n64ddFlag && - !((gSaveContext.eventChkInf[2] & 0x20) || BREG(2))) || - (gSaveContext.n64ddFlag && (INV_CONTENT(ITEM_BOMB) == ITEM_NONE))) { + // Check if beaten Dodongo's Cavern if not rando'd + // check for bomb bag or bombchus if rando'd depending on whether chus are in logic + bool bombchuBowlingClosed; + if (gSaveContext.n64ddFlag) { + u8 explosive = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) ? ITEM_BOMBCHU : ITEM_BOMB; + bombchuBowlingClosed = (INV_CONTENT(explosive) == ITEM_NONE); + } else { + bombchuBowlingClosed = !((gSaveContext.eventChkInf[2] & 0x20) || BREG(2)); + } + if (bombchuBowlingClosed) { this->actionFunc = EnBomBowMan_WaitNotBeatenDC; } else { this->actor.textId = 0x18; From e8df2f2e470719b5d2efd9e83eca0d73605fa456 Mon Sep 17 00:00:00 2001 From: lilDavid <1337lilDavid@gmail.com> Date: Wed, 17 Aug 2022 11:36:41 -0500 Subject: [PATCH 3/7] Open bombchu shop with chus --- .../overlays/actors/ovl_En_GirlA/z_en_girla.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index 5a1a36be7a..f32404cc11 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -633,8 +633,16 @@ s32 EnGirlA_CanBuy_Unk20(GlobalContext* globalCtx, EnGirlA* this) { } s32 EnGirlA_CanBuy_Bombchus(GlobalContext* globalCtx, EnGirlA* this) { - // When in rando, don't allow buying bombchus when the player doesn't have a bomb bag - if (AMMO(ITEM_BOMBCHU) >= 50 || (gSaveContext.n64ddFlag && CUR_CAPACITY(UPG_BOMB_BAG) == 0)) { + // When in rando, don't allow buying bombchus when the player doesn't have required explosives + // If bombchus are in logic, the player needs to have bombchus; otherwise they need a bomb bag + if (gSaveContext.n64ddFlag) { + u8 bombchusInLogic = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC); + if ((!bombchusInLogic && CUR_CAPACITY(UPG_BOMB_BAG) == 0) || + (bombchusInLogic && INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE)) { + return CANBUY_RESULT_CANT_GET_NOW; + } + } + if (AMMO(ITEM_BOMBCHU) >= 50) { return CANBUY_RESULT_CANT_GET_NOW; } if (gSaveContext.rupees < this->basePrice) { @@ -861,6 +869,11 @@ void EnGirlA_BuyEvent_ZoraTunic(GlobalContext* globalCtx, EnGirlA* this) { } void EnGirlA_BuyEvent_ObtainBombchuPack(GlobalContext* globalCtx, EnGirlA* this) { + Rupees_ChangeBy(-this->basePrice); + + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC)) { + return; + } switch (this->actor.params) { case SI_BOMBCHU_10_2: gSaveContext.itemGetInf[0] |= 0x40; @@ -887,7 +900,6 @@ void EnGirlA_BuyEvent_ObtainBombchuPack(GlobalContext* globalCtx, EnGirlA* this) gSaveContext.itemGetInf[0] |= 0x20; break; } - Rupees_ChangeBy(-this->basePrice); } void EnGirlA_Noop(EnGirlA* this, GlobalContext* globalCtx) { From 170b7595725936692bc429518de2c999ea46ffe7 Mon Sep 17 00:00:00 2001 From: lilDavid <1337lilDavid@gmail.com> Date: Thu, 18 Aug 2022 10:38:49 -0500 Subject: [PATCH 4/7] Make Bombchus buyable without a wallet --- .../custom-message/CustomMessageTypes.h | 2 ++ soh/soh/OTRGlobals.cpp | 3 +++ soh/soh/z_message_OTR.cpp | 22 ++++++++++++++++++- .../overlays/actors/ovl_En_GirlA/z_en_girla.c | 7 +++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 1859e83a52..f9a4f7936e 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -1,6 +1,8 @@ #pragma once typedef enum { + TEXT_BUY_BOMBCHU_10_PROMPT = 0x8C, + TEXT_BUY_BOMBCHU_10_DESC = 0xBC, TEXT_GS_NO_FREEZE = 0xB4, TEXT_GS_FREEZE = 0xB5, TEXT_RANDOMIZER_CUSTOM_ITEM = 0xF8, diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 3611c97de2..699c3f103c 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1540,6 +1540,9 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { } } else if (textId == TEXT_SCRUB_POH || textId == TEXT_SCRUB_STICK_UPGRADE || textId == TEXT_SCRUB_NUT_UPGRADE) { messageEntry = Randomizer_GetScrubMessage(textId); + } else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) && + (textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) { + messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); } } if (textId == TEXT_GS_NO_FREEZE || textId == TEXT_GS_FREEZE) { diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index c6be439644..5cfc99395c 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -111,5 +111,25 @@ extern "C" void OTRMessage_Init() TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM, "You got a %rGold Skulltula Token%w!&You've collected %r\x19%w tokens&in total!", "Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r\x19%w symbol gesammelt!", - "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r\x19\%w symboles en tout!" }); + "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r\x19\%w symboles en tout!" + } + ); + CustomMessageManager::Instance->CreateMessage( + customMessageTableID, TEXT_BUY_BOMBCHU_10_DESC, + { + TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, + "\x08%rBombchu (10 pieces) 99 Rupees&%wThis looks like a toy mouse, but&it's actually a self-propelled time&bomb!\x09\x0A", + "\x08%rKrabbelmine 10 Stück 99 Rubine&%wDas ist eine praktische Zeitbombe,&die Du als Distanzwaffe&einsetzen kannst!\x09\x0A", + "\x08%rMissile 10 unités 99 Rubis&%wProfilée comme une souris&mécanique, cette arme est &destructrice!!!\x09\x0A", + } + ); + CustomMessageManager::Instance->CreateMessage( + customMessageTableID, TEXT_BUY_BOMBCHU_10_PROMPT, + { + TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, + "\x08\Bombchu 10 pieces 99 Rupees\x09&&\x1B%gBuy&Don't buy%w", + "\x08Krabbelmine 10 Stück 99 Rubine\x09&&\x1B%gKaufen!&Nicht kaufen!%w", + "\x08Missiles 10 unités 99 Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w", + } + ); } diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index f32404cc11..54af786a64 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -1065,7 +1065,12 @@ void EnGirlA_InitializeItemAction(EnGirlA* this, GlobalContext* globalCtx) { this->canBuyFunc = itemEntry->canBuyFunc; this->itemGiveFunc = itemEntry->itemGiveFunc; this->buyEventFunc = itemEntry->buyEventFunc; - this->basePrice = itemEntry->price; + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) && + this->getItemId == GI_BOMBCHUS_10) { + this->basePrice = 99; + } else { + this->basePrice = itemEntry->price; + } this->itemCount = itemEntry->count; this->hiliteFunc = itemEntry->hiliteFunc; this->giDrawId = itemEntry->giDrawId; From 58aed3dc07fef3a98a208ac377529fa13f83ea99 Mon Sep 17 00:00:00 2001 From: lil David <1337lilDavid@gmail.com> Date: Mon, 22 Aug 2022 10:41:59 -0500 Subject: [PATCH 5/7] Correct bombchus in logic description to only include chu shop --- soh/soh/Enhancements/randomizer/randomizer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 95401a34ef..8616208d3f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4172,8 +4172,7 @@ void DrawRandoEditor(bool& open) { "\n" "The first Bombchu pack will always be 20, and subsequent packs will be " "5 or 10 based on how many you have.\n" - "Once found, they can be replenished at the Kokiri shop, Bazaar, or Bombchu " - "shop.\n" + "Once found, they can be replenished at the Bombchu shop.\n" "\n" "Bombchu Bowling is opened by obtaining Bombchus." ); From 6a900022c07c470b7d5471e2993181b5b6d91b0f Mon Sep 17 00:00:00 2001 From: lilDavid <1337lilDavid@gmail.com> Date: Tue, 23 Aug 2022 07:47:21 -0500 Subject: [PATCH 6/7] Pass vanilla ammo drops to logic --- soh/soh/Enhancements/randomizer/3drando/settings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 1482a5cdb2..9bff10b1ce 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2552,6 +2552,7 @@ namespace Settings { MapsAndCompasses.SetSelectedIndex(cvarSettings[RSK_STARTING_MAPS_COMPASSES]); BombchusInLogic.SetSelectedIndex(cvarSettings[RSK_BOMBCHUS_IN_LOGIC]); + AmmoDrops.SetSelectedIndex(AMMODROPS_VANILLA); // Ensure logic knows bombchu drops aren't implemented yet StartingConsumables.SetSelectedIndex(cvarSettings[RSK_STARTING_CONSUMABLES]); StartingMaxRupees.SetSelectedIndex(cvarSettings[RSK_FULL_WALLETS]); From 0a744cde0132dd7ad5de27e1e6d849bba24b4720 Mon Sep 17 00:00:00 2001 From: lil David <1337lilDavid@gmail.com> Date: Thu, 1 Sep 2022 08:11:17 -0500 Subject: [PATCH 7/7] Clarify comments --- .../actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 8 +++++--- soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c | 4 ++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 28a63bbf62..6bb097d896 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -143,7 +143,8 @@ void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, GlobalContext* globalCtx) { } } - // Check for Bomb Bag or Bombchus if Rando is enabled, depending on whether bombchus are considered in logic + // In randomizer, only check for bomb bag when bombchus aren't in logic + // and only check for bombchus when bombchus are in logic if (gSaveContext.n64ddFlag) { u8 bombchusInLogic = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC); if ((!bombchusInLogic && INV_CONTENT(ITEM_BOMB) == ITEM_NONE) || @@ -178,13 +179,14 @@ void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) { this->eyeMode = CHU_GIRL_EYES_AWAKE; this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20; - // Check if beaten Dodongo's Cavern if not rando'd - // check for bomb bag or bombchus if rando'd depending on whether chus are in logic bool bombchuBowlingClosed; if (gSaveContext.n64ddFlag) { + // when rando'd, check if we have bombchus if chus are in logic + // and check if we have a bomb bag if chus aren't in logic u8 explosive = Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) ? ITEM_BOMBCHU : ITEM_BOMB; bombchuBowlingClosed = (INV_CONTENT(explosive) == ITEM_NONE); } else { + // if not rando'd, check if we have beaten Dodongo's Cavern bombchuBowlingClosed = !((gSaveContext.eventChkInf[2] & 0x20) || BREG(2)); } if (bombchuBowlingClosed) { diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index 54af786a64..cbc2e97499 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -871,9 +871,12 @@ void EnGirlA_BuyEvent_ZoraTunic(GlobalContext* globalCtx, EnGirlA* this) { void EnGirlA_BuyEvent_ObtainBombchuPack(GlobalContext* globalCtx, EnGirlA* this) { Rupees_ChangeBy(-this->basePrice); + // Normally, buying a bombchu pack sets a flag indicating the pack is now sold out + // If they're in logic for rando, skip setting that flag so they can be purchased repeatedly if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC)) { return; } + switch (this->actor.params) { case SI_BOMBCHU_10_2: gSaveContext.itemGetInf[0] |= 0x40; @@ -1065,6 +1068,7 @@ void EnGirlA_InitializeItemAction(EnGirlA* this, GlobalContext* globalCtx) { this->canBuyFunc = itemEntry->canBuyFunc; this->itemGiveFunc = itemEntry->itemGiveFunc; this->buyEventFunc = itemEntry->buyEventFunc; + // If chus are in logic, make the 10 pack affordable without a wallet upgrade if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) && this->getItemId == GI_BOMBCHUS_10) { this->basePrice = 99;