From 8e283166645383498bfe872e7654fee94412386d Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 19 Mar 2024 17:25:38 -0400 Subject: [PATCH] Adds Magical Silver Rupee --- soh/soh/Enhancements/mods.cpp | 3 ++- .../Enhancements/randomizer/3drando/item_pool.cpp | 4 ++++ soh/soh/Enhancements/randomizer/item_list.cpp | 2 ++ .../randomizer/option_descriptions.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizer.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/randomizerTypes.h | 3 +++ soh/soh/Enhancements/randomizer/randomizer_inf.h | 2 ++ soh/soh/Enhancements/randomizer/settings.cpp | 15 +++++++++++++++ soh/src/code/z_parameter.c | 5 +++++ 9 files changed, 43 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 471c6fb44..d33607ee6 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -1208,7 +1208,8 @@ void RegisterSilverRupeeShuffle() { } else if (silverRupee->type == ENGSWITCH_SILVER_TRACKER) { Rando::Identifier randoIdentifier = { static_cast(gPlayState->sceneNum), RCQUEST_VANILLA, actor->params }; silverRupee->rg = Rando::StaticData::silverTrackerMap.at(randoIdentifier); - if (OTRGlobals::Instance->gRandoContext->GetSilverRupees()->GetInfo(silverRupee->rg).GetCollected() >= silverRupee->silverCount) { + if ((OTRGlobals::Instance->gRandoContext->GetSilverRupees()->GetInfo(silverRupee->rg).GetCollected() >= silverRupee->silverCount) + || Flags_GetRandomizerInf(RAND_INF_MAGICAL_SILVER_RUPEE)) { if ((gPlayState->sceneNum == SCENE_GERUDO_TRAINING_GROUND) && (silverRupee->actor.room == 2)) { Flags_SetTempClear(gPlayState, silverRupee->actor.room); } else { diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 596c78ab4..306333c37 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -1063,6 +1063,10 @@ void GenerateItemPool() { // Silver Rupees + // Add the Magical Silver Rupee if the option is on + if (ctx->GetOption(RSK_MAGICAL_SILVER_RUPEE)) { + AddItemToMainPool(RG_MAGICAL_SILVER_RUPEE); + } // The Silver Rupees to add to the pool will be different according to which dungeons are vanilla/mq. if (ctx->GetOption(RSK_SHUFFLE_SILVER_RUPEES).IsNot(RO_SILVER_SHUFFLE_VANILLA)) { std::vector silversToAdd; diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 2ce5d660e..ad952f054 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -323,6 +323,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_SPIRIT_TRIAL_SILVER_RUPEE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); itemTable[RG_LIGHT_TRIAL_SILVER_RUPEE] = Item(RG_LIGHT_TRIAL_SILVER_RUPEE, Text{ "Light Trial Silver Rupee", "Light Trial Silver Rupee", "Light Trial Silver Rupee"}, ITEMTYPE_SILVERRUPEE, 0, true, &logic->noVariable, RHT_GANONS_CASTLE_SILVER_RUPEE, RG_LIGHT_TRIAL_SILVER_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GOLD, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_SILVER_RUPEE, MOD_RANDOMIZER); itemTable[RG_LIGHT_TRIAL_SILVER_RUPEE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); + itemTable[RG_MAGICAL_SILVER_RUPEE] = Item(RG_MAGICAL_SILVER_RUPEE, Text{ "Magical Silver Rupee", "Magical Silver Rupee", "Magical Silver Rupee" }, ITEMTYPE_SILVERRUPEE, 0, true, &logic->noVariable, RHT_MAGICAL_SILVER_RUPEE, RG_MAGICAL_SILVER_RUPEE, OBJECT_GI_RUPY, GID_RUPEE_GOLD, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_SILVER_RUPEE, MOD_RANDOMIZER); + itemTable[RG_MAGICAL_SILVER_RUPEE].SetCustomDrawFunc(Randomizer_DrawSilverRupee); // Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen) itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, &logic->ProgressiveHookshot, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 208cfe5d1..59b1faaf8 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -404,6 +404,8 @@ void Settings::CreateOptionDescriptions() { "Overworld - Silver Rupees can only appear outside of dungeons.\n" "\n" "Anywhere - Silver Rupees can appear anywhere in the world."; + mOptionDescriptions[RSK_MAGICAL_SILVER_RUPEE] = "Adds a Magical Silver Rupee that opens all silver rupee puzzles to the item pool." + "It is not considered in logic, so you will not be required to find it to beat the seed, but if you do find it, it is a nice bonus."; mOptionDescriptions[RSK_GANONS_BOSS_KEY] = "Vanilla - Ganon's Boss Key will appear in the vanilla location.\n" "\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 12b4f562c..5cc8d5022 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2863,6 +2863,14 @@ void CreateGetItemMessages(const std::array* messageEntries) // "You got a %cSilver Rupee Pouch%w for the&%g{{location}}%w!", // "Du hast einen %cBeutel mit Silberrupien%g für die für die&%g{{location}}%w!", // "Vous avez reçu une %cPochette en Roupie d'Argent%w pour le&%g{{location}}%w!" }); + customMessageManager->CreateMessage(Randomizer::getItemMessageTableID, RG_MAGICAL_SILVER_RUPEE, + CustomMessage("You found the %cMagical Silver Rupee%w!&This magical silver " + "rupee automatically&completes all Silver Rupee Puzzles!", + "You found the %cMagical Silver Rupee%w!&This magical silver " + "rupee automatically&completes all Silver Rupee Puzzles!", + "You found the %cMagical Silver Rupee%w!&This magical silver " + "rupee automatically&completes all Silver Rupee Puzzles!", + TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM)); } void CreateRupeeMessages() { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index d9003f350..7019c70c3 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2139,6 +2139,7 @@ typedef enum { RG_WATER_TRIAL_MQ_SILVER_RUPEE, RG_SHADOW_TRIAL_MQ_SILVER_RUPEE, RG_SILVER_RUPEE_LAST = RG_SHADOW_TRIAL_MQ_SILVER_RUPEE, + RG_MAGICAL_SILVER_RUPEE, RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, @@ -3411,6 +3412,7 @@ typedef enum { RHT_SPIRIT_TEMPLE_SILVER_RUPEE, RHT_SHADOW_TEMPLE_SILVER_RUPEE, RHT_GANONS_CASTLE_SILVER_RUPEE, + RHT_MAGICAL_SILVER_RUPEE, RHT_EPONA, // Entrances RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO, @@ -3867,6 +3869,7 @@ typedef enum { RSK_FISHSANITY_AGE_SPLIT, RSK_SHUFFLE_FISHING_POLE, RSK_SHUFFLE_SILVER_RUPEES, + RSK_MAGICAL_SILVER_RUPEE, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 4fe620bcc..60fd2366c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -417,6 +417,8 @@ typedef enum { RAND_INF_SHADOW_TRIAL_MQ_SILVER_RUPEE_4, RAND_INF_SHADOW_TRIAL_MQ_SILVER_RUPEE_5, + RAND_INF_MAGICAL_SILVER_RUPEE, + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be // ceil(RAND_INF_MAX / 16) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index c6c1e8021..b70fd949f 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -128,6 +128,7 @@ void Settings::CreateOptions() { mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, "gRandomizeGerudoKeys", mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, "gRandomizeBossKeysanity", mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_SHUFFLE_SILVER_RUPEES] = Option::U8("Silver Rupees", {"Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, "gRandomizeSilverRupeeShuffle", mOptionDescriptions[RSK_SHUFFLE_SILVER_RUPEES], WidgetType::Combobox, RO_SILVER_SHUFFLE_VANILLA); + mOptions[RSK_MAGICAL_SILVER_RUPEE] = Option::Bool("Magical Silver Rupee", "gRandomizeMagicalSilverRupee", mOptionDescriptions[RSK_MAGICAL_SILVER_RUPEE]); mOptions[RSK_GANONS_BOSS_KEY] = Option::U8("Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "Triforce Hunt"}, OptionCategory::Setting, "gRandomizeShuffleGanonBossKey", mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA); mOptions[RSK_LACS_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, "gRandomizeLacsStoneCount", "", WidgetType::Slider, 3, true); mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, "gRandomizeLacsMedallionCount", "", WidgetType::Slider, 6, true); @@ -688,6 +689,7 @@ void Settings::CreateOptions() { &mOptions[RSK_GERUDO_KEYS], &mOptions[RSK_BOSS_KEYSANITY], &mOptions[RSK_SHUFFLE_SILVER_RUPEES], + &mOptions[RSK_MAGICAL_SILVER_RUPEE], &mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_LACS_STONE_COUNT], &mOptions[RSK_LACS_MEDALLION_COUNT], @@ -895,6 +897,7 @@ void Settings::CreateOptions() { &mOptions[RSK_GERUDO_KEYS], &mOptions[RSK_BOSS_KEYSANITY], &mOptions[RSK_SHUFFLE_SILVER_RUPEES], + &mOptions[RSK_MAGICAL_SILVER_RUPEE], &mOptions[RSK_GANONS_BOSS_KEY], &mOptions[RSK_LACS_STONE_COUNT], &mOptions[RSK_LACS_MEDALLION_COUNT], @@ -1650,6 +1653,13 @@ void Settings::UpdateOptionProperties() { } else { mOptions[RSK_GANONS_BOSS_KEY].Enable(); } + if (CVarGetInteger("gRandomizeSilverRupeeShuffle", RO_SILVER_SHUFFLE_VANILLA) != RO_SILVER_SHUFFLE_VANILLA) { + mOptions[RSK_SHUFFLE_SILVER_RUPEES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MAGICAL_SILVER_RUPEE].Unhide(); + } else { + mOptions[RSK_SHUFFLE_SILVER_RUPEES].AddFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MAGICAL_SILVER_RUPEE].Hide(); + } mOptions[RSK_GANONS_BOSS_KEY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); mOptions[RSK_LACS_OPTIONS].Hide(); mOptions[RSK_LACS_STONE_COUNT].Hide(); @@ -1774,6 +1784,11 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio mOptions[RSK_GANONS_BOSS_KEY].SetSelectedIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT); } + // Force Magical Silver Rupee off if Silver Rupee Shuffle is off. + if (mOptions[RSK_SHUFFLE_SILVER_RUPEES].Is(RO_SILVER_SHUFFLE_VANILLA)) { + mOptions[RSK_MAGICAL_SILVER_RUPEE].SetSelectedIndex(RO_GENERIC_OFF); + } + // Force 100 GS Shuffle if that's where Ganon's Boss Key is if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { mOptions[RSK_SHUFFLE_100_GS_REWARD].SetSelectedIndex(1); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 7055a9568..8db7bdce5 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2700,6 +2700,11 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { return Return_Item_Entry(giEntry, RG_NONE); } + if (item == RG_MAGICAL_SILVER_RUPEE) { + Flags_SetRandomizerInf(RAND_INF_MAGICAL_SILVER_RUPEE); + 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;