diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 9c1459cef..caf7c811e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -977,6 +977,13 @@ void GenerateItemPool() { AddItemToMainPool(RG_PROGRESSIVE_WALLET); } + if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); + } + + if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); + } if (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) { AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS, 5); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 303b8af42..2f314fc76 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1443,6 +1443,25 @@ void RandomizerOnActorInitHandler(void* actorRef) { Actor_Kill(actor); } } + + //consumable bags + if ( + actor->id = ACTOR_EN_ITEM00 && + ( + ( + RAND_GET_OPTION(RSK_SHUFFLE_DEKU_STICK_BAG) && + CUR_UPG_VALUE(UPG_STICKS) == 0 && + actor->params == ITEM00_STICK + ) || + ( + RAND_GET_OPTION(RSK_SHUFFLE_DEKU_NUT_BAG) && + CUR_UPG_VALUE(UPG_NUTS) == 0 && + actor->params == ITEM00_NUTS + ) + ) + ) { + Actor_Kill(actor); + } } void RandomizerRegisterHooks() { diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 16396c072..9be5551b8 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -123,6 +123,10 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio case RG_PROGRESSIVE_STICK_UPGRADE: switch (CUR_UPG_VALUE(UPG_STICKS)) { case 0: + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { + actual = RG_DEKU_STICK_BAG; + break; + } case 1: actual = RG_DEKU_STICK_CAPACITY_20; break; @@ -137,6 +141,10 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio case RG_PROGRESSIVE_NUT_UPGRADE: switch (CUR_UPG_VALUE(UPG_NUTS)) { case 0: + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { + actual = RG_DEKU_NUT_BAG; + break; + } case 1: actual = RG_DEKU_NUT_CAPACITY_30; break; diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 2b6c42d34..3bdd2709f 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -64,8 +64,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, &logic->ProgressiveBulletBag,RHT_PROGRESSIVE_SLINGSHOT, true); itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Brieftasche" }, ITEMTYPE_ITEM, 0x85, true, &logic->ProgressiveWallet, RHT_PROGRESSIVE_WALLET, true); itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Skala" }, ITEMTYPE_ITEM, 0x86, true, &logic->ProgressiveScale, RHT_PROGRESSIVE_SCALE, true); - itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nusskapazität" }, ITEMTYPE_ITEM, 0x87, false, &logic->noVariable, RHT_PROGRESSIVE_NUT_UPGRADE, true); - itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stick-Kapazität" }, ITEMTYPE_ITEM, 0x88, false, &logic->noVariable, RHT_PROGRESSIVE_STICK_UPGRADE, true); + itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nusskapazität" }, ITEMTYPE_ITEM, 0x87, true, &logic->ProgressiveNutBag, RHT_PROGRESSIVE_NUT_UPGRADE, true); + itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stick-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, &logic->ProgressiveStickBag, RHT_PROGRESSIVE_STICK_UPGRADE, true); itemTable[RG_PROGRESSIVE_BOMBCHUS] = Item(RG_PROGRESSIVE_BOMBCHUS, Text{ "Progressive Bombchu", "Missiles (prog.)", "Progressive Kriechgrube" }, ITEMTYPE_ITEM, 0x89, true, &logic->Bombchus, RHT_PROGRESSIVE_BOMBCHUS, RG_PROGRESSIVE_BOMBCHUS, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, true); itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_PROGRESSIVE_MAGIC_METER, true); itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, &logic->ProgressiveOcarina, RHT_PROGRESSIVE_OCARINA, true); @@ -289,6 +289,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, &logic->ProgressiveWallet, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_DEKU_STICK_BAG] = Item(RG_DEKU_STICK_BAG, Text{ "Deku Stick Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30, true, &logic->ProgressiveStickBag, RHT_NONE, RG_DEKU_STICK_BAG, OBJECT_GI_STICK, GID_STICK, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + + itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, &logic->ProgressiveNutBag, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, &logic->noVariable, RHT_NONE); itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, &logic->noVariable, RHT_NONE); // Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen) @@ -314,10 +318,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesige Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, &logic->ProgressiveWallet, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Reiche Geldbörse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, &logic->ProgressiveWallet, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Bourse de Magnat", "Reiche Geldbörse" },/*FIXME: still says tycoon in french & german*/ ITEMTYPE_ITEM, RG_CHILD_WALLET, true, &logic->ProgressiveWallet, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku Nuss Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, false, &logic->noVariable, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); - itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku Nuss Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, false, &logic->noVariable, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); - itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku Stick Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20,false, &logic->noVariable, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); - itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku Stick Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30,false, &logic->noVariable, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); + itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku Nuss Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, &logic->ProgressiveNutBag, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); + itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku Nuss Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, true, &logic->ProgressiveNutBag, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); + itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku Stick Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20,true, &logic->ProgressiveStickBag, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); + itemTable[RG_DEKU_STICK_CAPACITY_30] = Item(RG_DEKU_STICK_CAPACITY_30, Text{ "Deku Stick Capacity (30)", "Capacité de Bâtons Mojo (30)", "Deku Stick Kapazität (30)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_30,true, &logic->ProgressiveStickBag, RHT_DEKU_STICK_CAPACITY_30, ITEM_STICK_UPGRADE_30, OBJECT_GI_STICK, GID_STICK, 0x91, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE); itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magisches Messgerät" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verbesserte Magieanzeige" }, ITEMTYPE_ITEM, 0x8A, true, &logic->ProgressiveMagic, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce Piece" }, ITEMTYPE_ITEM, 0xDF, true, &logic->TriforcePieces, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 56ed191c0..b1fa969d0 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -297,8 +297,8 @@ namespace Rando { //refills Bombs = BombBag; - Nuts = DekuNutDrop || Nuts; - Sticks = DekuStickDrop || Sticks; + Nuts = (ProgressiveNutBag != 0 && DekuNutDrop) || Nuts; + Sticks = (ProgressiveStickBag != 0 && DekuStickDrop) || Sticks; Bugs = HasBottle && BugsAccess; BlueFire = (HasBottle && BlueFireAccess) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); Fish = HasBottle && FishAccess; @@ -626,6 +626,8 @@ namespace Rando { OcarinaCDownButton = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true) ? 0 : 1; //Progressive Items + ProgressiveStickBag = ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1; + ProgressiveNutBag = ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1; ProgressiveBulletBag = 0; ProgressiveBombBag = 0; ProgressiveMagic = 0; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 5475d4d92..16213049d 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -140,6 +140,8 @@ class Logic { bool GregInLacsLogic = false; // Progressive Items + uint8_t ProgressiveStickBag = 0; + uint8_t ProgressiveNutBag = 0; uint8_t ProgressiveBulletBag = 0; uint8_t ProgressiveBombBag = 0; uint8_t ProgressiveMagic = 0; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 784d9d1f3..3e91715c4 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -249,6 +249,12 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; + mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the deku stick bag into the item pool.\n" + "\n" + "The deku stick bag is required to hold deku sticks."; + mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the deku nut bag into the item pool.\n" + "\n" + "The deku nut bag is required to hold deku nuts."; mOptionDescriptions[RSK_SHOPSANITY] = "Off - All shop items will be the same as vanilla.\n" "\n" "0 Items - Vanilla shop items will be shuffled among different shops.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e75e03ee6..303a6bbfd 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -397,8 +397,16 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // Inventory Items case RG_PROGRESSIVE_STICK_UPGRADE: return CUR_UPG_VALUE(UPG_STICKS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + case RG_DEKU_STICK_1: + case RG_BUY_DEKU_STICK_1: + return CUR_UPG_VALUE(UPG_STICKS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_NUT_UPGRADE: return CUR_UPG_VALUE(UPG_NUTS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + case RG_DEKU_NUTS_5: + case RG_DEKU_NUTS_10: + case RG_BUY_DEKU_NUTS_5: + case RG_BUY_DEKU_NUTS_10: + return CUR_UPG_VALUE(UPG_NUTS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_BOMB_BAG: return CUR_UPG_VALUE(UPG_BOMB_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_BOMBS_5: @@ -694,14 +702,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_PIECE_OF_HEART: case RG_HEART_CONTAINER: case RG_ICE_TRAP: - case RG_DEKU_NUTS_5: - case RG_DEKU_NUTS_10: - case RG_DEKU_STICK_1: case RG_TREASURE_GAME_HEART: case RG_TREASURE_GAME_GREEN_RUPEE: - case RG_BUY_DEKU_NUTS_5: - case RG_BUY_DEKU_NUTS_10: - case RG_BUY_DEKU_STICK_1: case RG_BUY_HEART: case RG_TRIFORCE_PIECE: default: @@ -2952,7 +2954,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = {{ + const std::array getItemMessages = {{ GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn wirklich gefunden!", @@ -3224,6 +3226,8 @@ void Randomizer::CreateCustomMessages() { "Vous trouvez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), GIMESSAGE_UNTRANSLATED(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!"), GIMESSAGE_UNTRANSLATED(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!"), + GIMESSAGE_UNTRANSLATED(RG_DEKU_STICK_BAG, ITEM_STICK, "You found the %rDeku Stick Bag%w!&You can now hold deku sticks!"), + GIMESSAGE_UNTRANSLATED(RG_DEKU_NUT_BAG, ITEM_NUT, "You found the %rDeku Nut Bag%w!&You can now hold deku nuts!"), }}; CreateGetItemMessages(&getItemMessages); CreateRupeeMessages(); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 80d62859c..d15d3d4a3 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1980,6 +1980,8 @@ typedef enum { RG_OCARINA_C_LEFT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, RG_FISHING_POLE, + RG_DEKU_STICK_BAG, + RG_DEKU_NUT_BAG, RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, @@ -3711,6 +3713,8 @@ typedef enum { RSK_FISHSANITY_POND_COUNT, RSK_FISHSANITY_AGE_SPLIT, RSK_SHUFFLE_FISHING_POLE, + RSK_SHUFFLE_DEKU_STICK_BAG, + RSK_SHUFFLE_DEKU_NUT_BAG, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 4900e4a70..8859e8d43 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -150,8 +150,12 @@ void SetStartingItems() { } if (Randomizer_GetSettingValue(RSK_STARTING_CONSUMABLES)) { - GiveLinkDekuSticks(10); - GiveLinkDekuNuts(20); + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { + GiveLinkDekuSticks(10); + } + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { + GiveLinkDekuNuts(20); + } } if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 883a7c208..745593ef5 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -120,6 +120,8 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_CHEST_MINIGAME] = Option::U8("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); mOptions[RSK_SHUFFLE_100_GS_REWARD] = Option::Bool("Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); + mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); + mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); @@ -662,6 +664,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_FISHING_POLE], + &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], }, false, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { &mOptions[RSK_SHOPSANITY], @@ -889,6 +893,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], @@ -1117,6 +1123,8 @@ void Settings::CreateOptions() { { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, { "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD }, { "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS }, + { "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG }, + { "Shuffle Settings:Shuffle Deku Nut Bag", RSK_SHUFFLE_DEKU_NUT_BAG }, { "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD }, { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, { "Start with Fairy Ocarina", RSK_STARTING_OCARINA }, diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 658e96394..2f39ade8c 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1926,6 +1926,26 @@ u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { * @return u8 */ u8 Item_Give(PlayState* play, u8 item) { + //prevents getting sticks without the bag in case something got missed + if ( + IS_RANDO && + (item == ITEM_STICK || item == ITEM_STICKS_5 || item == ITEM_STICKS_10) && + Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG) && + CUR_UPG_VALUE(UPG_STICKS) == 0 + ) { + return; + } + + //prevents getting nuts without the bag in case something got missed + if ( + IS_RANDO && + (item == ITEM_NUT || item == ITEM_NUTS_5 || item == ITEM_NUTS_10) && + Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG) && + CUR_UPG_VALUE(UPG_NUTS) == 0 + ) { + return; + } + lusprintf(__FILE__, __LINE__, 2, "Item Give - item: %#x", item); static s16 sAmmoRefillCounts[] = { 5, 10, 20, 30, 5, 10, 30, 0, 5, 20, 1, 5, 20, 50, 200, 10 }; s16 i; @@ -2776,6 +2796,20 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return Return_Item_Entry(giEntry, RG_NONE); } + if (item == RG_DEKU_STICK_BAG) { + Inventory_ChangeUpgrade(UPG_STICKS, 1); + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); + return Return_Item_Entry(giEntry, RG_NONE); + } + + if (item == RG_DEKU_NUT_BAG) { + Inventory_ChangeUpgrade(UPG_NUTS, 1); + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); + return Return_Item_Entry(giEntry, RG_NONE); + } + temp = gSaveContext.inventory.items[slot]; osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); INV_CONTENT(item) = item; 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 0382735a3..b005cbf3f 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 @@ -487,6 +487,10 @@ s32 EnGirlA_CanBuy_Bombs(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_DekuNuts(PlayState* play, EnGirlA* this) { + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG) && CUR_CAPACITY(UPG_NUTS) == 0) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if ((CUR_CAPACITY(UPG_NUTS) != 0) && (AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS))) { return CANBUY_RESULT_CANT_GET_NOW; } @@ -500,6 +504,10 @@ s32 EnGirlA_CanBuy_DekuNuts(PlayState* play, EnGirlA* this) { } s32 EnGirlA_CanBuy_DekuSticks(PlayState* play, EnGirlA* this) { + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG) && CUR_CAPACITY(UPG_STICKS) == 0) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if ((CUR_CAPACITY(UPG_STICKS) != 0) && (AMMO(ITEM_STICK) >= CUR_CAPACITY(UPG_STICKS))) { return CANBUY_RESULT_CANT_GET_NOW; }