From f2161297a8d63c416d2bbed03ccde73cb4ac96c5 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:21:22 +0100 Subject: [PATCH 01/13] Fix break room access and crates underneath crates logic (#5347) * fix break room acces and crates underneath crates logic * apply GF_JUMP to the jump from NEAR_GS to LONG_ROOF to reach BREAK_ROOM --- .../location_access/gerudo_fortress.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp index 4b4579210..dd95b11fb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/gerudo_fortress.cpp @@ -27,8 +27,8 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanGetNightTimeGS()), LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), - LOCATION(RC_GF_BREAK_ROOM_POT_1, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), - LOCATION(RC_GF_BREAK_ROOM_POT_2, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), + LOCATION(RC_GF_BREAK_ROOM_POT_1, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GF_JUMP) && (ctx->GetTrickOption(RT_GF_KITCHEN) || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))) && logic->CanBreakPots()), + LOCATION(RC_GF_BREAK_ROOM_POT_2, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GF_JUMP) && (ctx->GetTrickOption(RT_GF_KITCHEN) || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))) && logic->CanBreakPots()), LOCATION(RC_GF_KITCHEN_POT_1, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), LOCATION(RC_GF_KITCHEN_POT_2, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), @@ -43,7 +43,7 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, logic->CanBreakPots()), LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, logic->CanBreakPots()), - LOCATION(RC_GF_ABOVE_JAIL_CRATE, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GF_ABOVE_JAIL_CRATE, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || (logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GF_JUMP))) && logic->CanBreakCrates()), LOCATION(RC_GF_OUTSIDE_CENTER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_GF_OUTSIDE_CENTER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_GF_OUTSIDE_CENTER_CRATE_3, logic->CanBreakCrates()), @@ -60,7 +60,7 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_ARCHERY_START_CRATE_1, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), LOCATION(RC_GF_ARCHERY_START_CRATE_2, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), LOCATION(RC_GF_ARCHERY_LEFT_END_CRATE_1, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), - LOCATION(RC_GF_ARCHERY_LEFT_END_CRATE_2, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), + LOCATION(RC_GF_ARCHERY_LEFT_END_CRATE_2, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && (logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS)))), LOCATION(RC_GF_ARCHERY_LEFT_END_CHILD_CRATE, logic->IsChild && logic->HasExplosives() && logic->CanBreakCrates()), LOCATION(RC_GF_ARCHERY_RIGHT_END_CRATE_1, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), LOCATION(RC_GF_ARCHERY_RIGHT_END_CRATE_2, (logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) && logic->CanBreakCrates()), @@ -69,10 +69,10 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_KITCHEN_CRATE_3, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), LOCATION(RC_GF_KITCHEN_CRATE_4, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), LOCATION(RC_GF_KITCHEN_CRATE_5, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GF_BREAK_ROOM_CRATE_1, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GF_BREAK_ROOM_CRATE_2, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GF_BREAK_ROOM_CRATE_3, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GF_BREAK_ROOM_CRATE_4, ((logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GF_BREAK_ROOM_CRATE_1, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GF_JUMP) && (ctx->GetTrickOption(RT_GF_KITCHEN) || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))) && logic->CanBreakCrates()), + LOCATION(RC_GF_BREAK_ROOM_CRATE_2, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GF_JUMP) && (ctx->GetTrickOption(RT_GF_KITCHEN) || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))) && logic->CanBreakCrates()), + LOCATION(RC_GF_BREAK_ROOM_CRATE_3, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || ((logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_JUMP)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW)))) && logic->CanBreakCrates()), + LOCATION(RC_GF_BREAK_ROOM_CRATE_4, (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || ((logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_JUMP)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW)))) && logic->CanBreakCrates()), LOCATION(RC_GF_NORTH_F1_CARPENTER_CRATE, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), LOCATION(RC_GF_NORTH_F3_CARPENTER_CRATE, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_F2_CARPENTER_CRATE_1, logic->CanBreakCrates()), From 30520a7565b239c4e58ea514a20464f8f59f76c2 Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Wed, 9 Apr 2025 17:35:39 +0200 Subject: [PATCH 02/13] Rando: Last missing french + tiny tweak (#5359) * Update hint_list_exclude_overworld.cpp * missing ones * Oops forgot a ' --- .../hint_list/hint_list_exclude_dungeon.cpp | 2 +- .../hint_list/hint_list_exclude_overworld.cpp | 148 +++++++++--------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index f29f2ecfb..75072e72a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -303,7 +303,7 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { hintTextTable[RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in Dodongo's Cavern# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein in Dodongos Höhle# #[[1]]# enthülle.", - /*french*/ "Selon moi, #jouer un air orageux pour une pierre étrange dans la Caverne Dodongo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange dans la Caverne Dodongo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_DODONGOS_CAVERN_GRASS] = HintText(CustomMessage("They say that some #grass in Dodongo's Cavern# hides #[[1]]#.", /*german*/ "Man erzählt sich, daß etwas #Gras in Dodongos Höhle# #[[1]]# verstecke.", diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 1329bb377..b47c68646 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -1759,259 +1759,259 @@ void StaticData::HintTable_Init_Exclude_Overworld() { hintTextTable[RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the castle# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb des Schloßes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous le château révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous le château# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near an ancient tree# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein nahe eines antiken Baumes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange près d'un arbre ancien révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange près d'un arbre ancien# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near an ancient tree# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein nahe eines antiken Baumes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange près d'un arbre ancien révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange près d'un arbre ancien# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest village# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher ein Dorf im Wald überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surplombant un village forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surplombant un village forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest village# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher ein Dorf im Wald überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surplombant un village forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surplombant un village forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a forest village# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb eines Dorfes im Wald# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous un village forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous un village forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a forest village# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb eines Dorfes im Wald# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous un village forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous un village forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher einen See nährenden Fluß überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surplombant la rivière qui alimente un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surplombant la rivière qui alimente un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher einen See nährenden Fluß überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surplombant la rivière qui alimente un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surplombant la rivière qui alimente un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein am Rücken eines Sees# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange au fond d'un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange au fond d'un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein am Rücken eines Sees# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange au fond d'un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange au fond d'un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein am Rücken eines Sees# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange au fond d'un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange au fond d'un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein am Rücken eines Sees# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange au fond d'un lac révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange au fond d'un lac# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a perplexing wood# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein innerhalb eines verwirrenden Waldes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange dans un bois déroutant révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange dans un bois déroutant# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a perplexing wood# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein innerhalb eines verwirrenden Waldes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange dans un bois déroutant révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange dans un bois déroutant# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest maze# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher ein Waldlabyrinth überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surplombant un labyrinthe forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surplombant un labyrinthe forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest maze# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher ein Waldlabyrinth überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surplombant un labyrinthe forestier révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surplombant un labyrinthe forestier# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher ein Versteck im Wald überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surveillant une cachette dans les bois révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surveillant une cachette dans les bois# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher ein Versteck im Wald überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surveillant une cachette dans les bois révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surveillant une cachette dans les bois# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone listening to an aquatic king# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher einem aquatischen König zuhört#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange écoutant un roi aquatique révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange écoutant un roi aquatique# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone listening to an aquatic king# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher einem aquatischen König zuhört#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange écoutant un roi aquatique révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange écoutant un roi aquatique# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in the outskirts of a deep fountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein am Rand eines tiefen Brunnens# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange en périphérie d'une profonde fontaine révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange en périphérie d'une profonde fontaine# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in the outskirts of a deep fountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein am Rand eines tiefen Brunnens# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange en périphérie d'une profonde fontaine révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange en périphérie d'une profonde fontaine# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher einen Wächter des Meeres beobachtet#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surveillant un gardien de la mer révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surveillant un gardien de la mer# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher einen Wächter des Meeres beobachtet#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surveillant un gardien de la mer révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surveillant un gardien de la mer# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overwatching a river# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher einen Fluß überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange surplombant une rivière révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange surplombant une rivière# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overwatching a river# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher einen Fluß überblickt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange surplombant une rivière révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange surplombant une rivière# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a waterfall# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb eines Wasserfalls# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous une cascade révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous une cascade# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a waterfall# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb eines Wasserfalls# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous une cascade révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous une cascade# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone hiding near a cow# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein, welcher sich nahe einer Kuh versteckt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange cachée près d'une vache révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange cachée près d'une vache# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone hiding near a cow# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein, welcher sich nahe einer Kuh versteckt#, #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange cachée près d'une vache révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange cachée près d'une vache# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb des Eingangs zum Markt# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous l'entrée du marché révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous l'entrée du marché# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb des Eingangs zum Markt# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous l'entrée du marché révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous l'entrée du marché# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb von Killeranas bewachten Bäumen# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous des arbres gardés par un Peahat révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous des arbres gardés par un Peahat# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb von Killeranas bewachten Bäumen# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous des arbres gardés par un Peahat révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous des arbres gardés par un Peahat# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb eines Dorfes am Fuße eines Berges# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous un village au pied d'une montagne révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous un village au pied d'une montagne# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb eines Dorfes am Fuße eines Berges# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous un village au pied d'une montagne révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous un village au pied d'une montagne# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a plateau by a river# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein auf einem Plateau von einem Fluß# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange dans un plateau près d'une rivière révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange dans un plateau près d'une rivière# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a plateau by a river# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein auf einem Plateau bei einem Fluß# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange dans un plateau près d'une rivière révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange dans un plateau près d'une rivière# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb eines Auswegs des Waldes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous une issue de la forêt révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous une issue de la forêt# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb eines Auswegs des Waldes# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous une issue de la forêt révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous une issue de la forêt# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein unterhalb eines Eingangs zu einem Dorf innerhalb eines Berges# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange sous l'entrée d'un village dans une montagne révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange sous l'entrée d'un village dans une montagne# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein unterhalb eines Eingangs zu einem Dorf innerhalb eines Berges# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange sous l'entrée d'un village dans une montagne révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange sous l'entrée d'un village dans une montagne# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within the side of a crater# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer Melodie für einen seltsamen Stein innerhalb der Seite eines Kraters# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie pour une pierre étrange dans le côté d'un cratère révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie pour une pierre étrange dans le côté d'un cratère# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within the side of a crater# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Spielen einer stürmischen Melodie für einen seltsamen Stein innerhalb der Seite eines Kraters# #[[1]]# enthülle.", - /*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange dans le côté d'un cratère révèle [[1]].", {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une pierre étrange dans le côté d'un cratère# révèle [[1]].", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_ISLAND_SUN_FAIRY] = HintText(CustomMessage("They say that #summoning the sun on the lake's island# calls #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Beschwören der Sonne auf der Insel eines Sees# #[[1]]# anrufe.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #appeler le soleil sur l'île du lac # révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_POND_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling rain to the field's pond# summons #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Anrufen des Regens für den Tümpel eines Feldes# #[[1]]# beschwöre.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse dans l'étang d'une plaine# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_FENCE_GROTTO_STORMS_FAIRY] = HintText(CustomMessage("They say that #making it rain in a scrub's cave# wakes #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Machen von Regen in der Höhle eines Dekus# #[[1]]# erwecke.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse dans la grotte d'une Peste Mojo# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMT_FLAG_SUN_FAIRY] = HintText(CustomMessage("They say that #changing the time in front of the trail's flag# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Verändern der Zeit im Angesicht der Flagge eines Pfades# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #appeler le soleil devant un drapeau du Mont du Péril # révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_DMT_COW_GROTTO_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling a storm for a lonely cow# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Anrufen eines Sturms für eine einsame Kuh# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse pour une vache solitaire# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_SHORTCUT_STORMS_FAIRY] = HintText(CustomMessage("They say that #making it rain in the Lost Woods# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Machen von Regen in den verlorenen Wäldern# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #jouer une mélodie orageuse dans les Bois Perdus# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_GF_KITCHEN_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a guarded kitchen# exposes #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Anrufen der Sonne in einer bewachten Küche# #[[1]]# freilege.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #appeler le soleil dans une cuisine gardée# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun for scrubs in the Lost Woods# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Anrufen der Sonne für Dekus in den verlorenen Wäldern# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #appeler le soleil pour les Pestes dans les Bois Perdus # révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a royal tomb# reveals #[[1]]#.", /*german*/ "Man erzählt sich, daß das #Anrufen der Sonne in einer königlichen Gruft# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*french*/ "Selon moi, #appeler le soleil dans une tombe royale# révèle #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_KF_GRASS] = HintText(CustomMessage("They say that #cutting some grass in a forest# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einem Wald# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einem Wald# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans un fôret# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_LW_GRASS] = HintText(CustomMessage("They say that #cutting some grass in the woods# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in den Wäldern# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in den Wäldern# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans des bois# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_MARKET_GRASS] = HintText(CustomMessage("They say that #cutting some grass in the market# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf dem Markt# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf dem Markt# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans un marché# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_HC_GRASS] = HintText(CustomMessage("They say that #cutting some grass near the castle# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in der Nähe vom Schloß# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in der Nähe vom Schloß# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe près du château# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_KAK_GRASS] = HintText(CustomMessage("They say that #cutting some grass in a village# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einem Dorf# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einem Dorf# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans un village# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_GY_GRASS] = HintText(CustomMessage("They say that #cutting some grass in a graveyard# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf einem Friedhof# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf einem Friedhof# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans un cimetère# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_LH_GRASS] = HintText(CustomMessage("They say that #cutting some grass near a lake# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser nahe eines Sees# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser nahe eines Sees# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe près d'un lac# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_HF_GRASS] = HintText(CustomMessage("They say that #cutting some grass on a field# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf einem Feld# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser auf einem Feld# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe dans une plaine# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_ZR_GRASS] = HintText(CustomMessage("They say that #cutting some grass near a river# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in der Nähe von einem Fluß# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in der Nähe von einem Fluß# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe près d'une rivière# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_GROTTO_GRASS] = HintText(CustomMessage("They say that #cutting some grass in a grotto# reveals #[[1]]#.", - /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einer Grotte# #[[1]]# enthülle.", - /*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN})); + /*german*/ "Man erzählt sich, daß das #Schneiden einiger Gräser in einer Grotte# #[[1]]# enthülle.", + /*french*/ "Selon moi, de l'#herbe# cache #[[1]]#.", {QM_RED, QM_GREEN})); hintTextTable[RHT_CRATE_GERUDO_VALLEY] = HintText(CustomMessage("They say that a #crate in Gerudo Valley# contains #[[1]]#.", /*german*/ "Man erzählt sich, daß eine #Kiste im Gerudotal# #[[1]]# enthielte.", From 2576f75b1a1ca06f325108469cd3c51cf4ffa6ff Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 9 Apr 2025 12:20:37 -0400 Subject: [PATCH 03/13] Fix non-loach fish making it into the pool when Loach Only is selected. (#5360) --- soh/soh/Enhancements/randomizer/context.cpp | 2 -- soh/soh/Enhancements/randomizer/fishsanity.cpp | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index fa755325e..4127ab21a 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -180,8 +180,6 @@ void Context::GenerateLocationPool() { location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || - (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && - mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) || (location.GetRCType() == RCTYPE_FISH && !mFishsanity->GetFishLocationIncluded(&location)) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OFF)) || (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) || diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index fe9b4c0f1..8d4435f9a 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -78,6 +78,9 @@ bool Fishsanity::GetFishLocationIncluded(Rando::Location* loc, FishsanityOptions return false; } RandomizerCheck rc = loc->GetRandomizerCheck(); + if (mode == RO_FISHSANITY_HYRULE_LOACH && rc != RC_LH_HYRULE_LOACH) { + return false; + } // Are pond fish enabled, and is this a pond fish location? if (mode != RO_FISHSANITY_OVERWORLD && numFish > 0 && loc->GetScene() == SCENE_FISHING_POND && loc->GetActorID() == ACTOR_FISHING) { From 9250af0216d5b559262f5fae4cf1a470e2683353 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:01:26 -0400 Subject: [PATCH 04/13] add check for agony option (#5365) --- soh/soh/Enhancements/randomizer/ShuffleGrass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index f318ad948..b8d31144a 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -35,8 +35,10 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) { if (grassActor->grassIdentity.randomizerCheck != RC_MAX && Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) == 0) { int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - if (csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) { + if ((csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) && + (!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, true, GI_NONE); GetItemCategory getItemCategory = itemEntry.getItemCategory; From cf755203949cfd47727fe94b6db55105fde0bef8 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 9 Apr 2025 15:16:25 -0400 Subject: [PATCH 05/13] Fix crash in Message Viewer when playing with an NTSC OTR. (#5367) --- .../Enhancements/debugger/MessageViewer.cpp | 34 ++++++++----------- soh/soh/Enhancements/debugger/MessageViewer.h | 5 ++- soh/soh/SohGui/SohMenu.h | 7 ++++ soh/soh/SohGui/SohMenuSettings.cpp | 7 +--- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index fef875e94..83aac4d6c 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.cpp +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -2,6 +2,7 @@ #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" +#include "soh/SohGui/SohMenu.h" #include "soh/OTRGlobals.h" #include @@ -56,22 +57,12 @@ void MessageViewer::DrawElement() { memset(mTextIdBuf, 0, sizeof(char) * MAX_STRING_SIZE); } PopStyleCheckbox(); - ImGui::Text("Language"); - ImGui::SameLine(); - PushStyleCombobox(THEME_COLOR); - if (ImGui::BeginCombo("##Language", mLanguages[mLanguage])) { - // ReSharper disable CppDFAUnreachableCode - for (size_t i = 0; i < mLanguages.size(); i++) { - if (strlen(mLanguages[i]) > 0) { - if (ImGui::Selectable(mLanguages[i], i == mLanguage)) { - mLanguage = i; - } - } - } - ImGui::EndCombo(); - } - PopStyleCombobox(); - UIWidgets::InsertHelpHoverText("Which language to load from the selected text ID"); + SohGui::SohMenu::UpdateLanguageMap(SohGui::languages); + UIWidgets::Combobox("Language", &mLanguage, SohGui::languages, + UIWidgets::ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(0) + .Tooltip("Which language to load from the selected text ID")); PushStyleButton(THEME_COLOR); if (ImGui::Button("Display Message##ExistingMessage")) { mDisplayExistingMessageClicked = true; @@ -196,6 +187,11 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan R_TEXT_CHAR_SCALE = 75; R_TEXT_LINE_SPACING = 12; R_TEXT_INIT_XPOS = 65; + if (language == LANGUAGE_JPN) { + R_TEXT_CHAR_SCALE = 88; + R_TEXT_LINE_SPACING = 18; + R_TEXT_INIT_XPOS = 65; + } char* buffer = font->msgBuf; msgCtx->textId = textId; if (strlen(tableId) == 0) { @@ -207,10 +203,8 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan constexpr int maxBufferSize = sizeof(font->msgBuf); const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId); font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition(); - switch (language) { - font->msgLength = - SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize); - } + font->msgLength = + SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize); msgCtx->msgLength = static_cast(font->msgLength); } msgCtx->textBoxProperties = font->charTexBuf[0]; diff --git a/soh/soh/Enhancements/debugger/MessageViewer.h b/soh/soh/Enhancements/debugger/MessageViewer.h index 20924a0b6..83e290114 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.h +++ b/soh/soh/Enhancements/debugger/MessageViewer.h @@ -4,7 +4,7 @@ #ifdef __cplusplus #include "GuiWindow.h" -#include +#include extern "C" { #endif /** @@ -41,7 +41,6 @@ class MessageViewer : public Ship::GuiWindow { void DisplayCustomMessage() const; static constexpr uint16_t MAX_STRING_SIZE = 1024; - static constexpr std::array mLanguages = { "English", "German", "French" }; static constexpr int HEXADECIMAL = 0; static constexpr int DECIMAL = 1; char* mTableIdBuf; @@ -49,7 +48,7 @@ class MessageViewer : public Ship::GuiWindow { char* mTextIdBuf; uint16_t mTextId; int mTextIdBase = HEXADECIMAL; - size_t mLanguage = LANGUAGE_ENG; + int32_t mLanguage = LANGUAGE_ENG; char* mCustomMessageBuf; std::string mCustomMessageString; bool mDisplayExistingMessageClicked = false; diff --git a/soh/soh/SohGui/SohMenu.h b/soh/soh/SohGui/SohMenu.h index 4a72938bb..eb3b1f4f7 100644 --- a/soh/soh/SohGui/SohMenu.h +++ b/soh/soh/SohGui/SohMenu.h @@ -28,6 +28,13 @@ void disableBetaQuest(); namespace SohGui { +static std::unordered_map languages = { + { LANGUAGE_ENG, "English" }, + { LANGUAGE_GER, "German" }, + { LANGUAGE_FRA, "French" }, + { LANGUAGE_JPN, "Japanese" }, +}; + static const std::unordered_map menuThemeOptions = { { UIWidgets::Colors::Red, "Red" }, { UIWidgets::Colors::DarkRed, "Dark Red" }, diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp index 94619a43b..2b1f77799 100644 --- a/soh/soh/SohGui/SohMenuSettings.cpp +++ b/soh/soh/SohGui/SohMenuSettings.cpp @@ -14,12 +14,7 @@ namespace SohGui { extern std::shared_ptr mSohMenu; using namespace UIWidgets; -static const std::unordered_map languages = { - { LANGUAGE_ENG, "English" }, - { LANGUAGE_GER, "German" }, - { LANGUAGE_FRA, "French" }, - { LANGUAGE_JPN, "Japanese" }, -}; + static std::unordered_map imguiScaleOptions = { { 0, "Small" }, { 1, "Normal" }, From 93d49d5c41fb144c00b72d76f5d2e810358ba1e1 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:17:25 +0100 Subject: [PATCH 06/13] Fix ZD beehives and some small cleanup. (#5353) * clean up zora domain logic * revert useless short circuits --- .../location_access/overworld/zoras_domain.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 07922bc8f..3bee82b26 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -17,8 +17,8 @@ void RegionTable_Init_ZorasDomain() { //Locations LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), - LOCATION(RC_ZD_KING_ZORA_THAWED, logic->KingZoraThawed), - LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), + LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->KingZoraThawed), + LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle()), @@ -28,8 +28,8 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_ZD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZD_GOSSIP_STONE, true), - LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()), - LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->IsChild && logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->IsChild && logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_NEAR_SHOP_POT_1, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_2, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), @@ -50,9 +50,12 @@ void RegionTable_Init_ZorasDomain() { Entrance(RR_ZD_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); - areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->KingZoraThawed, []{return logic->IsAdult && logic->BlueFire();}), + }, { //Locations - LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->IsChild && logic->CanBreakUpperBeehives()), }, { //Exits Entrance(RR_ZORAS_DOMAIN, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}), From c21c632c09533956bc5343bf221604bca62133b4 Mon Sep 17 00:00:00 2001 From: Extloga <141232749+Extloga@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:24:05 +0200 Subject: [PATCH 07/13] Additions for the currencies in randomizer.cpp (#5344) * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp * Rearrangement of the currencies in randomizer.cpp --- .../Enhancements/randomizer/randomizer.cpp | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 9eaba3365..7a5f8dd69 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -65,9 +65,10 @@ const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi"; const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; -static const char* englishRupeeNames[175] = { +static const char* englishRupeeNames[190] = { "[P]", "Bad RNG Rolls", + "Baht", "Bananas", "Beanbean Coins", "Beans", @@ -86,6 +87,7 @@ static const char* englishRupeeNames[175] = { "BugFrags", "Canadian Dollars", "Cards", + "Cents", "Chaos Orbs", "Clams", "Coal", @@ -106,6 +108,8 @@ static const char* englishRupeeNames[175] = { "Darseks", "Dead Memes", "Diamonds", + "Dimes", + "Dinars", "DNA", "Doge", "Dogecoin", @@ -114,7 +118,9 @@ static const char* englishRupeeNames[175] = { "Dollarydoos", "Dosh", "Doubloons", + "Drakes", "Dwarfbucks", + "ECU", "Elexit", "Emeralds", "Energon", @@ -150,7 +156,7 @@ static const char* englishRupeeNames[175] = { "KF7 Ammo", "Kinstones", "Kremcoins", - "Kroner", + "Kronor", "Leaves", "Lemmings", "Lien", @@ -173,11 +179,14 @@ static const char* englishRupeeNames[175] = { "Munny", "Mushrooms", "Mysteries", + "Naira", "Neopoints", + "Nickels", "Notes", "Nuyen", "Orbs", "Ore", + "Pence", "Pix", "Pixels", "Plastyks", @@ -190,19 +199,23 @@ static const char* englishRupeeNames[175] = { "Pounds", "Power Pellets", "Primogems", - "Réals", + "Rand", + "Reais", "Refined Metal", "Remote Mines", "Retweets", "Rhinu", + "Rials", "Rings", "Riot Points", + "Riyals", "Robux", "Rubies", "Rubles", "Runite Ore", "Rupees", "Saint Quartz", + "Sapphires", "Septims", "Shekels", "Shillings", @@ -235,24 +248,27 @@ static const char* englishRupeeNames[175] = { "Vespene Gas", "Watts", "Widgets", + "Won", "Woolongs", "World Dollars", "Wumpa Fruit", "Yen", + "Yuan", "Zenny", "Zorkmids", }; -static const char* germanRupeeNames[65] = { - "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent", "Diamanten", - "Diridari", "Dogecoin", "ECU", "Elexit", "Erz", "Erzbrocken", "Euro", "EXP", - "Forint", "Franken", "Freunde", "Gil", "Gold", "Groschen", "Gulden", "Gummibären", - "Heller", "Juwelen", "Karolin", "Kartoffeln", "Kies", "Knete", "Knochen", "Kohle", - "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Kröten", "Mark", "Mäuse", "Monde", - "Moorhühner", "Moos", "Münzen", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", - "Pilze", "Plastiks", "Pokédollar", "Radieschen", "Rappen", "Rubine", "Saphire", "Schilling", - "Seelen", "Smaragde", "Steine", "Sterne", "Sternis", "Tael", "Taler", "Wagenchips", - "Zenny" +static const char* germanRupeeNames[80] = { + "Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent", + "Diamanten", "Dinar", "Diridari", "Dogecoin", "Dollar", "Draken", "ECU", "Elexit", + "Erz", "Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil", + "Gold", "Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln", + "Kies", "Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken", + "Kröten", "Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen", + "Naira", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", + "Pokédollar", "Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine", + "Rupien", "Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne", + "Sternis", "Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny", }; static const char* frenchRupeeNames[40] = { @@ -260,7 +276,7 @@ static const char* frenchRupeeNames[40] = { "Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", "Dollars", "Émeraudes", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", "Grouses", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", - "Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies" + "Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies", }; Randomizer::Randomizer() { From c3322c85ae74110b171851b3a072bb79ba84c557 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 9 Apr 2025 12:26:20 -0700 Subject: [PATCH 08/13] Swap call to `RecalculateAvailableChecks()` in `SaveFile()` to a variable that triggers a recalculation in `DrawElement()`. (#5366) --- .../Enhancements/randomizer/randomizer_check_tracker.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 6be7f8f40..fcb86f9c3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -245,6 +245,7 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; +static bool recalculateAvailable = false; std::array filterAreasHidden = { 0 }; std::array filterChecksHidden = { 0 }; @@ -877,7 +878,7 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) { SaveTrackerData(saveContext, sectionID, fullSave); if (fullSave) { - RecalculateAvailableChecks(); + recalculateAvailable = true; } } @@ -2032,6 +2033,10 @@ static std::unordered_map buttonStrings = { }; void CheckTrackerSettingsWindow::DrawElement() { + if (recalculateAvailable) { + recalculateAvailable = false; + RecalculateAvailableChecks(); + } ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); if (ImGui::BeginTable("CheckTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f); From e98a6c3748f055429eb0229ce5b99eae1cf4ce98 Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 9 Apr 2025 13:38:27 -0700 Subject: [PATCH 09/13] Fix migrators for tracker colors to match new menu formats. (#5369) Add temporary additional clearing to CVarColorPicker's reset functionality to resolve already migrated issues. --- .../randomizer/randomizer_check_tracker.cpp | 16 ++------ soh/soh/SohGui/UIWidgets.cpp | 6 +++ soh/soh/config/ConfigMigrators.h | 41 ++++++++++--------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index fcb86f9c3..93798fea5 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1087,14 +1087,6 @@ void CheckTrackerWindow::DrawElement() { bool doingCollapseOrExpand = optExpandAll || optCollapseAll; bool isThisAreaSpoiled; RandomizerCheckArea lastArea = RCAREA_INVALID; - Color_RGBA8 areaCompleteColor = - CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); - Color_RGBA8 areaIncompleteColor = - CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); - Color_RGBA8 extraCompleteColor = - CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); - Color_RGBA8 extraIncompleteColor = - CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); Color_RGBA8 mainColor; Color_RGBA8 extraColor; std::string stemp; @@ -1122,11 +1114,11 @@ void CheckTrackerWindow::DrawElement() { } else { // Get the colour for the area if (thisAreaFullyChecked) { - mainColor = areaCompleteColor; - extraColor = extraCompleteColor; + mainColor = Color_Area_Complete_Main; + extraColor = Color_Area_Complete_Extra; } else { - mainColor = areaIncompleteColor; - extraColor = extraIncompleteColor; + mainColor = Color_Area_Incomplete_Main; + extraColor = Color_Area_Incomplete_Extra; } // Draw the area diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp index f5e84f302..3c4e91147 100644 --- a/soh/soh/SohGui/UIWidgets.cpp +++ b/soh/soh/SohGui/UIWidgets.cpp @@ -895,6 +895,12 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul UIWidgets::ButtonOptions({ { .tooltip = "Resets this color to its default value" } }) .Color(themeColor) .Size(UIWidgets::Sizes::Inline))) { + // TODO: Remove for next minor or major version, temporary fix for already migrated configs to 3 for 9.0.0 + CVarClear((std::string(cvarName) + ".R").c_str()); + CVarClear((std::string(cvarName) + ".G").c_str()); + CVarClear((std::string(cvarName) + ".B").c_str()); + CVarClear((std::string(cvarName) + ".A").c_str()); + CVarClear((std::string(cvarName) + ".Type").c_str()); CVarClearBlock(valueCVar.c_str()); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/config/ConfigMigrators.h b/soh/soh/config/ConfigMigrators.h index a312be604..ee7e91792 100644 --- a/soh/soh/config/ConfigMigrators.h +++ b/soh/soh/config/ConfigMigrators.h @@ -1263,10 +1263,10 @@ std::vector version3Migrations = { { MigrationAction::Rename, "gUnfixGoronSpin", "gCosmetics.UnfixGoronSpin" }, { MigrationAction::Rename, "gNL_Diamond_Env", "gCosmetics.Magic.NayrusSecondary" }, { MigrationAction::Rename, "gUseSpellsCol", "gCosmetics.UseSpellsColors" }, - { MigrationAction::Rename, "gItemTrackerBgColorA", "gTrackers.ItemTracker.BgColorA" }, - { MigrationAction::Rename, "gItemTrackerBgColorB", "gTrackers.ItemTracker.BgColorB" }, - { MigrationAction::Rename, "gItemTrackerBgColorG", "gTrackers.ItemTracker.BgColorG" }, - { MigrationAction::Rename, "gItemTrackerBgColorR", "gTrackers.ItemTracker.BgColorR" }, + { MigrationAction::Rename, "gItemTrackerBgColorA", "gTrackers.ItemTracker.BgColor.Value.A" }, + { MigrationAction::Rename, "gItemTrackerBgColorB", "gTrackers.ItemTracker.BgColor.Value.B" }, + { MigrationAction::Rename, "gItemTrackerBgColorG", "gTrackers.ItemTracker.BgColor.Value.G" }, + { MigrationAction::Rename, "gItemTrackerBgColorR", "gTrackers.ItemTracker.BgColor.Value.R" }, { MigrationAction::Rename, "gItemTrackerCapacityTrack", "gTrackers.ItemTracker.ItemCountType" }, { MigrationAction::Rename, "gItemTrackerComboButton1", "gTrackers.ItemTracker.ComboButton1" }, { MigrationAction::Rename, "gItemTrackerComboButton2", "gTrackers.ItemTracker.ComboButton2" }, @@ -1310,22 +1310,24 @@ std::vector version3Migrations = { { MigrationAction::Rename, "gEntranceTrackerSortBy", "gTrackers.EntranceTracker.SortBy" }, { MigrationAction::Rename, "gCheckTrackerAreaCompleteHide", "gTrackers.CheckTracker.AreaComplete.Hide" }, { MigrationAction::Rename, "gCheckTrackerAreaExtraCompleteColor", - "gTrackers.CheckTracker.AreaComplete.ExtraColor" }, - { MigrationAction::Rename, "gCheckTrackerAreaExtraIncompleteColor", - "gTrackers.CheckTracker.AreaIncomplete.ExtraColor" }, + "gTrackers.CheckTracker.AreaComplete.ExtraColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerAreaExtraIncompleteColor.Value", + "gTrackers.CheckTracker.AreaIncomplete.ExtraColor.Value" }, { MigrationAction::Rename, "gCheckTrackerAreaIncompleteHide", "gTrackers.CheckTracker.AreaIncomplete.Hide" }, - { MigrationAction::Rename, "gCheckTrackerAreaMainCompleteColor", "gTrackers.CheckTracker.AreaComplete.MainColor" }, - { MigrationAction::Rename, "gCheckTrackerAreaMainIncompleteColor", - "gTrackers.CheckTracker.AreaIncomplete.MainColor" }, - { MigrationAction::Rename, "gCheckTrackerBgColor", "gTrackers.CheckTracker.BgColor" }, - { MigrationAction::Rename, "gCheckTrackerCollectedExtraColor", "gTrackers.CheckTracker.Collected.ExtraColor" }, + { MigrationAction::Rename, "gCheckTrackerAreaMainCompleteColor", + "gTrackers.CheckTracker.AreaComplete.MainColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerAreaMainIncompleteColor.Value", + "gTrackers.CheckTracker.AreaIncomplete.MainColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerBgColor", "gTrackers.CheckTracker.BgColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerCollectedExtraColor", + "gTrackers.CheckTracker.Collected.ExtraColor.Value" }, { MigrationAction::Rename, "gCheckTrackerCollectedHide", "gTrackers.CheckTracker.Collected.Hide" }, - { MigrationAction::Rename, "gCheckTrackerCollectedMainColor", "gTrackers.CheckTracker.Collected.MainColor" }, + { MigrationAction::Rename, "gCheckTrackerCollectedMainColor", "gTrackers.CheckTracker.Collected.MainColor.Value" }, { MigrationAction::Rename, "gCheckTrackerComboButton1", "gTrackers.CheckTracker.ComboButton1" }, { MigrationAction::Rename, "gCheckTrackerComboButton2", "gTrackers.CheckTracker.ComboButton2" }, { MigrationAction::Rename, "gCheckTrackerDisplayType", "gTrackers.CheckTracker.DisplayType" }, - { MigrationAction::Rename, "gCheckTrackerHintedExtraColor", "gTrackers.CheckTracker.Hinted.ExtraColor" }, - { MigrationAction::Rename, "gCheckTrackerHintedMainColor", "gTrackers.CheckTracker.Hinted.MainColor" }, + { MigrationAction::Rename, "gCheckTrackerHintedExtraColor", "gTrackers.CheckTracker.Hinted.ExtraColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerHintedMainColor", "gTrackers.CheckTracker.Hinted.MainColor.Value" }, { MigrationAction::Rename, "gCheckTrackerHintedHide", "gTrackers.CheckTracker.Hinted.Hide" }, { MigrationAction::Rename, "gCheckTrackerHudEditMode", "gTrackers.CheckTracker.Draggable" }, { MigrationAction::Rename, "gCheckTrackerKnownHide", "gTrackers.CheckTracker.Scummed.Hide" }, @@ -1334,7 +1336,7 @@ std::vector version3Migrations = { "gTrackers.CheckTracker.HideUnshuffledShopChecks" }, { MigrationAction::Rename, "gCheckTrackerOptionMQSpoilers", "gTrackers.CheckTracker.MQSpoilers" }, { MigrationAction::Rename, "gCheckTrackerOptionShowHidden", "gTrackers.CheckTracker.ShowHidden" }, - { MigrationAction::Rename, "gCheckTrackerSavedExtraColor", "gTrackers.CheckTracker.Saved.ExtraColor" }, + { MigrationAction::Rename, "gCheckTrackerSavedExtraColor", "gTrackers.CheckTracker.Saved.ExtraColor.Value" }, { MigrationAction::Rename, "gCheckTrackerSavedHide", "gTrackers.CheckTracker.Saved.Hide" }, { MigrationAction::Rename, "gCheckTrackerSavedMainColor", "gTrackers.CheckTracker.Saved.MainColor" }, { MigrationAction::Rename, "gCheckTrackerScummedExtraColor", "gTrackers.CheckTracker.Scummed.ExtraColor" }, @@ -1345,10 +1347,11 @@ std::vector version3Migrations = { { MigrationAction::Rename, "gCheckTrackerShowOnlyPaused", "gTrackers.CheckTracker.ShowOnlyPaused" }, { MigrationAction::Rename, "gCheckTrackerSkippedExtraColor", "gTrackers.CheckTracker.Skipped.ExtraColor" }, { MigrationAction::Rename, "gCheckTrackerSkippedHide", "gTrackers.CheckTracker.Skipped.Hide" }, - { MigrationAction::Rename, "gCheckTrackerSkippedMainColor", "gTrackers.CheckTracker.Skipped.MainColor" }, - { MigrationAction::Rename, "gCheckTrackerUncheckedExtraColor", "gTrackers.CheckTracker.Unchecked.ExtraColor" }, + { MigrationAction::Rename, "gCheckTrackerSkippedMainColor", "gTrackers.CheckTracker.Skipped.MainColor.Value" }, + { MigrationAction::Rename, "gCheckTrackerUncheckedExtraColor", + "gTrackers.CheckTracker.Unchecked.ExtraColor.Value" }, { MigrationAction::Rename, "gCheckTrackerUncheckedHide", "gTrackers.CheckTracker.Unchecked.Hide" }, - { MigrationAction::Rename, "gCheckTrackerUncheckedMainColor", "gTrackers.CheckTracker.Unchecked.MainColor" }, + { MigrationAction::Rename, "gCheckTrackerUncheckedMainColor", "gTrackers.CheckTracker.Unchecked.MainColor.Value" }, { MigrationAction::Rename, "gCheckTrackerWindowType", "gTrackers.CheckTracker.WindowType" }, { MigrationAction::Rename, "gRandomize10GSHint", "gRandoSettings.10GSHint" }, { MigrationAction::Rename, "gRandomize20GSHint", "gRandoSettings.20GSHint" }, From 73400f58560719e21703c3b867677856412f9204 Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:46:43 +0100 Subject: [PATCH 10/13] IC ledge to fountain child logic fixed (#5368) * IC ledge to fountain child logic fixed * fully unblob ZF --- soh/soh/Enhancements/randomizer/entrance.cpp | 8 +- .../location_access/dungeons/ice_cavern.cpp | 2 +- .../overworld/zoras_fountain.cpp | 97 +++++++++++++++---- .../Enhancements/randomizer/randomizerTypes.h | 6 ++ 4 files changed, 87 insertions(+), 26 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 05638a2b3..40eaca212 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -878,10 +878,10 @@ int EntranceShuffler::ShuffleAllEntrances() { { EntranceType::Dungeon, RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_OUTSIDE_TEMPLE } }, { { EntranceType::Dungeon, RR_KAK_WELL, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE }, { EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } }, - { { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE }, - { EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } }, - { { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE }, - { EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } }, + { { EntranceType::Dungeon, RR_ZF_LEDGE, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE }, + { EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZF_LEDGE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } }, + { { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE }, + { EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } }, { { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE }, { EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } }, diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index ff2bf9594..7aa2066ca 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -11,7 +11,7 @@ void RegionTable_Init_IceCavern() { //Exits Entrance(RR_ICE_CAVERN_BEGINNING, []{return ctx->GetDungeon(ICE_CAVERN)->IsVanilla();}), Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return ctx->GetDungeon(ICE_CAVERN)->IsMQ() && logic->CanUseProjectile();}), - Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), + Entrance(RR_ZF_LEDGE, []{return true;}), }); #pragma region Vanilla diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index a03070454..3ac0921a3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -11,18 +11,44 @@ void RegionTable_Init_ZorasFountain() { EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}), }, { //Locations - LOCATION(RC_ZF_ICEBERG_FREESTANDING_POH, logic->IsAdult), + LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), + LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), + LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}), + Entrance(RR_ZF_ICEBERGS, []{return logic->IsAdult;}), + Entrance(RR_ZF_LAKEBED, []{return logic->CanUse(RG_IRON_BOOTS);}), + //child can break the brown rock without lifting the silver rock and it stays gone for adult, but it's not intuitive and there's no reasonable case where it matters. + Entrance(RR_ZF_HIDDEN_CAVE, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash();}), + Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}), + Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}), + Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}), + }); + + areaTable[RR_ZF_ICEBERGS] = Region("ZF Icebergs", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ZF_ICEBERG_FREESTANDING_POH, logic->IsAdult), + }, { + //Exits + //This hover is pretty tight, come at it with momentum and aim for the small corner polygon of the big iceburg while spamming roll + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}), + Entrance(RR_ZF_LAKEBED, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ZF_LEDGE, []{return true;}), + }); + + areaTable[RR_ZF_LAKEBED] = Region("ZF Lakebed", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), - LOCATION(RC_ZF_GS_TREE, logic->IsChild), - LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->CanGetNightTimeGS()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), - LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), @@ -41,18 +67,47 @@ void RegionTable_Init_ZorasFountain() { LOCATION(RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), LOCATION(RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), - LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), - LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), - LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), - LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), }, { //Exits - Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}), - Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}), - Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return logic->IsAdult;}), - Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}), + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE);}), + }); + + areaTable[RR_ZF_LEDGE] = Region("ZF Ledge", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_ZF_ICEBERGS, []{return logic->IsAdult;}), + Entrance(RR_ZF_LAKEBED, []{return logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}), + }); + + areaTable[RR_ZF_HIDDEN_CAVE] = Region("ZF Hidden Cave", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->IsAdult && logic->CanBreakPots()), + }, { + //Exits + //There are invisible big skultullas here as adult but they do not block the path and can be "seen" with Z-target + //Lens is not currently needed for this either, implying they are not considered blocking, but it's open for discussion long-term + Entrance(RR_ZF_HIDDEN_LEDGE, []{return true;}), + }); + + areaTable[RR_ZF_HIDDEN_LEDGE] = Region("ZF Hidden Ledge", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && logic->CanGetNightTimeGS()), + }, { + //Exits + //It is possible to avoid fall damage by jumping towards the right and landing in deeper water, but this is basically never relevent + Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}), + Entrance(RR_ZF_HIDDEN_CAVE, []{return true;}), + }); + + areaTable[RR_ZF_ROCK] = Region("ZF Rock", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //Has a wonder item + }, { + //Exits + Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), }); areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 34bddd0a5..ce074bf4c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -509,6 +509,12 @@ typedef enum { RR_ZD_SHOP, RR_ZD_STORMS_GROTTO, RR_ZORAS_FOUNTAIN, + RR_ZF_ICEBERGS, + RR_ZF_LAKEBED, + RR_ZF_LEDGE, + RR_ZF_HIDDEN_CAVE, + RR_ZF_HIDDEN_LEDGE, + RR_ZF_ROCK, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_LON_LON_RANCH, RR_LLR_TALONS_HOUSE, From c12349a7a3643931aa0853ef6d2f18e76094c36d Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 9 Apr 2025 13:58:06 -0700 Subject: [PATCH 11/13] Add check for bean inventory slot having bean on it to allow availability to succeed with ammo count 0. (#5370) --- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index ed91b21b8..9fd460d93 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -71,7 +71,7 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_DISTANT_SCARECROW: return ScarecrowsSong() && CanUse(RG_LONGSHOT); case RG_MAGIC_BEAN: - return GetAmmo(ITEM_BEAN) > 0; + return GetAmmo(ITEM_BEAN) > 0 || CheckInventory(ITEM_BEAN, true); case RG_KOKIRI_SWORD: case RG_DEKU_SHIELD: case RG_GORON_TUNIC: From a99e8836fb113ae72f69e0e0821706f3edddac3f Mon Sep 17 00:00:00 2001 From: Malkierian Date: Wed, 9 Apr 2025 15:18:44 -0700 Subject: [PATCH 12/13] Allow seeded enemy rando to use the values of the enemy list selection. (#5371) --- soh/soh/Enhancements/enemyrandomizer.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index f202e1b1f..84e1d040e 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -318,26 +318,20 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* po return 1; } -std::vector selectedEnemyList; +static std::vector selectedEnemyList; void GetSelectedEnemies() { selectedEnemyList.clear(); - if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM) { - for (int i = 0; i < 49; i++) { - if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) { - selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); - } else if (CVarGetInteger(enemyCVarList[i], 1)) { - selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); - } - } - if (selectedEnemyList.size() == 0) { - selectedEnemyList.push_back(randomizedEnemySpawnTable[0]); - } - } else { - for (int i = 0; i < 49; i++) { + for (int i = 0; i < 49; i++) { + if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); + } else if (CVarGetInteger(enemyCVarList[i], 1)) { selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); } } + if (selectedEnemyList.size() == 0) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[0]); + } } EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { @@ -348,7 +342,7 @@ EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); Random_Init(finalSeed); - uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE); + uint32_t randomNumber = Random(0, selectedEnemyList.size()); return selectedEnemyList[randomNumber]; } else { uint32_t randomSelectedEnemy = Random(0, selectedEnemyList.size()); From 85bc67ef24fef818f7c71123322c3c008547fb24 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 9 Apr 2025 19:04:28 -0400 Subject: [PATCH 13/13] Blair Bravo version bump (#5372) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c3945459..6dc479fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") -project(Ship VERSION 9.0.0 LANGUAGES C CXX) +project(Ship VERSION 9.0.1 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake)