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
This commit is contained in:
Demur Rumed 2025-08-05 18:17:07 +00:00
commit a5917e5311
8 changed files with 51 additions and 8 deletions

View file

@ -88,6 +88,10 @@ typedef enum {
TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890, TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890,
TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891, TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891,
TEXT_WARP_PRELUDE_OF_LIGHT = 0x0892, 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_SCRUB_POH = 0x10A2,
TEXT_SARIA_SFM = 0x10AD, TEXT_SARIA_SFM = 0x10AD,
TEXT_SCRUB_STICK_UPGRADE = 0x10DC, TEXT_SCRUB_STICK_UPGRADE = 0x10DC,

View file

@ -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", /*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)); {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!", 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!", /*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!", /*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!",

View file

@ -684,6 +684,7 @@ void Settings::CreateOptionDescriptions() {
"tell you what's the reward for the Hyrule Loach."; "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 " 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."; "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] = mOptionDescriptions[RSK_FISHING_POLE_HINT] =
"Talking to the fishing pond owner without the fishing pole will tell you its location."; "Talking to the fishing pond owner without the fishing pole will tell you its location.";
mOptionDescriptions[RSK_OOT_HINT] = mOptionDescriptions[RSK_OOT_HINT] =

View file

@ -4127,6 +4127,7 @@ typedef enum {
RH_ALTAR_CHILD, RH_ALTAR_CHILD,
RH_ALTAR_ADULT, RH_ALTAR_ADULT,
RH_SARIA_HINT, RH_SARIA_HINT,
RH_MIDO_HINT,
RH_LOACH_HINT, RH_LOACH_HINT,
RH_FISHING_POLE, RH_FISHING_POLE,
RH_MINUET_WARP_LOC, RH_MINUET_WARP_LOC,
@ -5395,6 +5396,7 @@ typedef enum {
RHT_GREG_HINT, RHT_GREG_HINT,
RHT_SARIA_TALK_HINT, RHT_SARIA_TALK_HINT,
RHT_SARIA_SONG_HINT, RHT_SARIA_SONG_HINT,
RHT_MIDO_HINT,
RHT_LOACH_HINT, RHT_LOACH_HINT,
RHT_FISHING_POLE_HINT, RHT_FISHING_POLE_HINT,
// Static Entrance Hints // Static Entrance Hints
@ -5835,6 +5837,7 @@ typedef enum {
RSK_GREG_HINT, RSK_GREG_HINT,
RSK_LOACH_HINT, RSK_LOACH_HINT,
RSK_SARIA_HINT, RSK_SARIA_HINT,
RSK_MIDO_HINT,
RSK_FROGS_HINT, RSK_FROGS_HINT,
RSK_OOT_HINT, RSK_OOT_HINT,
RSK_KAK_10_SKULLS_HINT, RSK_KAK_10_SKULLS_HINT,

View file

@ -243,6 +243,11 @@ extern "C" void Randomizer_InitSaveFile() {
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); 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). // Go away Ruto (Water Temple first cutscene).
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10);

View file

@ -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_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_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_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_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_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); 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); WidgetContainerType::SECTION);
mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup( mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup(
"Extra Hints", "Extra Hints",
{ &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], &mOptions[RSK_SHEIK_LA_HINT], { &mOptions[RSK_TOT_ALTAR_HINT],
&mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], &mOptions[RSK_GANONDORF_HINT],
&mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], &mOptions[RSK_SHEIK_LA_HINT],
&mOptions[RSK_BIGGORON_HINT], &mOptions[RSK_BIG_POES_HINT], &mOptions[RSK_CHICKENS_HINT], &mOptions[RSK_DAMPES_DIARY_HINT],
&mOptions[RSK_MALON_HINT], &mOptions[RSK_HBA_HINT], &mOptions[RSK_FISHING_POLE_HINT], &mOptions[RSK_GREG_HINT],
&mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_MERCHANT_TEXT_HINT], &mOptions[RSK_LOACH_HINT],
&mOptions[RSK_KAK_10_SKULLS_HINT], &mOptions[RSK_KAK_20_SKULLS_HINT], &mOptions[RSK_KAK_30_SKULLS_HINT], &mOptions[RSK_SARIA_HINT],
&mOptions[RSK_KAK_40_SKULLS_HINT], &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_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] }, &mOptions[RSK_MASK_SHOP_HINT] },
WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones.");
mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] =
@ -1619,6 +1637,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_GREG_HINT], &mOptions[RSK_GREG_HINT],
&mOptions[RSK_LOACH_HINT], &mOptions[RSK_LOACH_HINT],
&mOptions[RSK_SARIA_HINT], &mOptions[RSK_SARIA_HINT],
&mOptions[RSK_MIDO_HINT],
&mOptions[RSK_FROGS_HINT], &mOptions[RSK_FROGS_HINT],
&mOptions[RSK_OOT_HINT], &mOptions[RSK_OOT_HINT],
&mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_WARP_SONG_HINTS],

View file

@ -71,6 +71,7 @@ std::unordered_map<uint32_t, CustomMessage> StaticData::hintNames = {
{ RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child") }, { RH_ALTAR_CHILD, CustomMessage("ToT Altar as Child") },
{ RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult") }, { RH_ALTAR_ADULT, CustomMessage("ToT Altar as Adult") },
{ RH_SARIA_HINT, CustomMessage("Saria's Magic Hint") }, { RH_SARIA_HINT, CustomMessage("Saria's Magic Hint") },
{ RH_MIDO_HINT, CustomMessage("Mido's Kokiri Sword Hint") },
{ RH_LOACH_HINT, CustomMessage("Loach Hint") }, { RH_LOACH_HINT, CustomMessage("Loach Hint") },
{ RH_FISHING_POLE, CustomMessage("Fishing Pole Hint") }, { RH_FISHING_POLE, CustomMessage("Fishing Pole Hint") },
{ RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination") }, { RH_MINUET_WARP_LOC, CustomMessage("Minuet of Forest Destination") },
@ -194,6 +195,7 @@ std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap
{RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {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_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_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_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_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})}, {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})},

View file

@ -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) && } else if ((textId >= TEXT_SARIAS_SONG_FACE_TO_FACE && textId <= TEXT_SARIAS_SONG_CHANNELING_POWER) &&
ctx->GetOption(RSK_SARIA_HINT)) { ctx->GetOption(RSK_SARIA_HINT)) {
messageEntry = ctx->GetHint(RH_SARIA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 1); 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) && } else if (ctx->GetOption(RSK_BIGGORON_HINT) &&
(textId == TEXT_BIGGORON_BETTER_AT_SMITHING || textId == TEXT_BIGGORON_WAITING_FOR_YOU || (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)) { textId == TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS || textId == TEXT_BIGGORON_I_MAAAADE_THISSSS)) {