From a5917e53116b672ac4e709bb78fc05d5dad19286 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Tue, 5 Aug 2025 18:17:07 +0000 Subject: [PATCH] Rando: option for Mido to hint location of Kokiri Sword also fix bug where Mido blocks path to Deku Tree when Closed Forest off but Zelda's Letter not skipped --- .../custom-message/CustomMessageTypes.h | 4 +++ .../randomizer/3drando/hint_list.cpp | 5 +++ .../randomizer/option_descriptions.cpp | 1 + .../Enhancements/randomizer/randomizerTypes.h | 3 ++ soh/soh/Enhancements/randomizer/savefile.cpp | 5 +++ soh/soh/Enhancements/randomizer/settings.cpp | 35 ++++++++++++++----- .../Enhancements/randomizer/static_data.cpp | 2 ++ soh/soh/OTRGlobals.cpp | 4 +++ 8 files changed, 51 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index b5bc0fd6e..811505479 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -88,6 +88,10 @@ typedef enum { TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890, TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891, TEXT_WARP_PRELUDE_OF_LIGHT = 0x0892, + TEXT_MIDO_HOME_AFTER_ZELDAS_LETTER = 0x1028, + TEXT_MIDO_SPEAK_TO_MIDO_FIRST_TIME = 0x102F, + TEXT_MIDO_SPEAK_TO_MIDO_AGAIN = 0x1030, + TEXT_MIDO_HOME_BEFORE_ZELDAS_LETTER = 0x1046, TEXT_SCRUB_POH = 0x10A2, TEXT_SARIA_SFM = 0x10AD, TEXT_SCRUB_STICK_UPGRADE = 0x10DC, diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 21891ff81..85d3471e5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2257,6 +2257,11 @@ void StaticData::HintTable_Init() { /*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#.^Tu devrais aller y jeter un coup d'oeil, @!\x0B", {QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE)); + hintTextTable[RHT_MIDO_HINT] = HintText(CustomMessage("You'll never find the #Kokiri Sword# I hid in #[[1]]#!", + /*german*/ TODO_TRANSLATE, + /*french*/ TODO_TRANSLATE, + {QM_GREEN, QM_RED})); + hintTextTable[RHT_LOACH_HINT] = HintText(CustomMessage("What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that I'll give my %g[[1]]%w to anyone who catches it. Seriously!", /*german*/ "Was?^Du willst etwas über die&%rhylianische Forelle%w wissen?&Es ist ein riesiger Fisch,&der unfassbar selten ist!^Wenn Du mir eine bringst, |springt|springen| für Dich&%g[[1]]%w dabei raus.&Ganz im Ernst!", /*french*/ "Quoi?&Tu veux en savoir plus sur le&%rBrochet d'Hyrule%w?^C'est un gros poisson, mais il&est si rare que je donne&%g[[1]]%w&à celui qui l'attrape.^Ouais, j'suis sérieux!", diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 50d11d9b2..bd19b3dcb 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -684,6 +684,7 @@ void Settings::CreateOptionDescriptions() { "tell you what's the reward for the Hyrule Loach."; mOptionDescriptions[RSK_SARIA_HINT] = "Talking to Saria either in person or through Saria's Song will tell you the " "location of a progressive magic meter."; + mOptionDescriptions[RSK_MIDO_HINT] = "Talking to Mido as child will tell you the location of the Kokiri Sword."; mOptionDescriptions[RSK_FISHING_POLE_HINT] = "Talking to the fishing pond owner without the fishing pole will tell you its location."; mOptionDescriptions[RSK_OOT_HINT] = diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..e52662faf 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4127,6 +4127,7 @@ typedef enum { RH_ALTAR_CHILD, RH_ALTAR_ADULT, RH_SARIA_HINT, + RH_MIDO_HINT, RH_LOACH_HINT, RH_FISHING_POLE, RH_MINUET_WARP_LOC, @@ -5395,6 +5396,7 @@ typedef enum { RHT_GREG_HINT, RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT, + RHT_MIDO_HINT, RHT_LOACH_HINT, RHT_FISHING_POLE_HINT, // Static Entrance Hints @@ -5835,6 +5837,7 @@ typedef enum { RSK_GREG_HINT, RSK_LOACH_HINT, RSK_SARIA_HINT, + RSK_MIDO_HINT, RSK_FROGS_HINT, RSK_OOT_HINT, RSK_KAK_10_SKULLS_HINT, diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 51101f6fa..ade5dd163 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -243,6 +243,11 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); + if (Randomizer_GetSettingValue(RSK_FOREST) == RO_CLOSED_FOREST_OFF) { + Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_MIDO_AFTER_DEKU_TREES_DEATH); + } + // Go away Ruto (Water Temple first cutscene). gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..9b67a717d 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -281,6 +281,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_GREG_HINT, "Greg the Green Rupee Hint", CVAR_RANDOMIZER_SETTING("GregHint"), mOptionDescriptions[RSK_GREG_HINT], IMFLAG_NONE); OPT_BOOL(RSK_LOACH_HINT, "Hyrule Loach Hint", CVAR_RANDOMIZER_SETTING("LoachHint"), mOptionDescriptions[RSK_LOACH_HINT], IMFLAG_NONE); OPT_BOOL(RSK_SARIA_HINT, "Saria's Hint", CVAR_RANDOMIZER_SETTING("SariaHint"), mOptionDescriptions[RSK_SARIA_HINT], IMFLAG_NONE); + OPT_BOOL(RSK_MIDO_HINT, "Mido's Hint", CVAR_RANDOMIZER_SETTING("MidoHint"), mOptionDescriptions[RSK_MIDO_HINT], IMFLAG_NONE); OPT_BOOL(RSK_FISHING_POLE_HINT, "Fishing Pole Hint", CVAR_RANDOMIZER_SETTING("FishingPoleHint"), mOptionDescriptions[RSK_FISHING_POLE_HINT], IMFLAG_NONE); OPT_BOOL(RSK_FROGS_HINT, "Frog Ocarina Game Hint", CVAR_RANDOMIZER_SETTING("FrogsHint"), mOptionDescriptions[RSK_FROGS_HINT], IMFLAG_NONE); OPT_BOOL(RSK_OOT_HINT, "Ocarina of Time Hint", CVAR_RANDOMIZER_SETTING("OoTHint"), mOptionDescriptions[RSK_OOT_HINT], IMFLAG_NONE); @@ -1352,14 +1353,31 @@ void Settings::CreateOptions() { WidgetContainerType::SECTION); mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup( "Extra Hints", - { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], &mOptions[RSK_SHEIK_LA_HINT], - &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], - &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], - &mOptions[RSK_BIGGORON_HINT], &mOptions[RSK_BIG_POES_HINT], &mOptions[RSK_CHICKENS_HINT], - &mOptions[RSK_MALON_HINT], &mOptions[RSK_HBA_HINT], &mOptions[RSK_FISHING_POLE_HINT], - &mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_MERCHANT_TEXT_HINT], - &mOptions[RSK_KAK_10_SKULLS_HINT], &mOptions[RSK_KAK_20_SKULLS_HINT], &mOptions[RSK_KAK_30_SKULLS_HINT], - &mOptions[RSK_KAK_40_SKULLS_HINT], &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], + { &mOptions[RSK_TOT_ALTAR_HINT], + &mOptions[RSK_GANONDORF_HINT], + &mOptions[RSK_SHEIK_LA_HINT], + &mOptions[RSK_DAMPES_DIARY_HINT], + &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], + &mOptions[RSK_SARIA_HINT], + &mOptions[RSK_MIDO_HINT], + &mOptions[RSK_FROGS_HINT], + &mOptions[RSK_OOT_HINT], + &mOptions[RSK_BIGGORON_HINT], + &mOptions[RSK_BIG_POES_HINT], + &mOptions[RSK_CHICKENS_HINT], + &mOptions[RSK_MALON_HINT], + &mOptions[RSK_HBA_HINT], + &mOptions[RSK_FISHING_POLE_HINT], + &mOptions[RSK_WARP_SONG_HINTS], + &mOptions[RSK_SCRUB_TEXT_HINT], + &mOptions[RSK_MERCHANT_TEXT_HINT], + &mOptions[RSK_KAK_10_SKULLS_HINT], + &mOptions[RSK_KAK_20_SKULLS_HINT], + &mOptions[RSK_KAK_30_SKULLS_HINT], + &mOptions[RSK_KAK_40_SKULLS_HINT], + &mOptions[RSK_KAK_50_SKULLS_HINT], + &mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_MASK_SHOP_HINT] }, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = @@ -1619,6 +1637,7 @@ void Settings::CreateOptions() { &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], &mOptions[RSK_SARIA_HINT], + &mOptions[RSK_MIDO_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], &mOptions[RSK_WARP_SONG_HINTS], diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index 448b33819..1becef894 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -71,6 +71,7 @@ std::unordered_map StaticData::hintNames = { { RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child") }, { RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult") }, { RH_SARIA_HINT, CustomMessage("Saria's Magic Hint") }, + { RH_MIDO_HINT, CustomMessage("Mido's Kokiri Sword Hint") }, { RH_LOACH_HINT, CustomMessage("Loach Hint") }, { RH_FISHING_POLE, CustomMessage("Fishing Pole Hint") }, { RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination") }, @@ -194,6 +195,7 @@ std::unordered_map StaticData::staticHintInfoMap {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})}, {RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)}, + {RH_MIDO_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_MIDO_HINT}, RSK_MIDO_HINT, true, {}, {RG_KOKIRI_SWORD}, {}, true)}, {RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})}, {RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)}, {RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})}, diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d59871d54..30e101479 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2473,6 +2473,10 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if ((textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER) && ctx->GetOption(RSK_SARIA_HINT)) { messageEntry = ctx->GetHint(RH_SARIA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1); + } else if ((textId == TEXT_MIDO_SPEAK_TO_MIDO_FIRST_TIME || textId == TEXT_MIDO_SPEAK_TO_MIDO_AGAIN || + textId == TEXT_MIDO_HOME_AFTER_ZELDAS_LETTER || textId == TEXT_MIDO_HOME_BEFORE_ZELDAS_LETTER) && + ctx->GetOption(RSK_MIDO_HINT)) { + messageEntry = ctx->GetHint(RH_MIDO_HINT)->GetHintMessage(MF_AUTO_FORMAT); } else if (ctx->GetOption(RSK_BIGGORON_HINT) && (textId == TEXT_BIGGORON_BETTER_AT_SMITHING || textId == TEXT_BIGGORON_WAITING_FOR_YOU || textId == TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS || textId == TEXT_BIGGORON_I_MAAAADE_THISSSS)) {