From f4408d5e7ebaa8067b7b386cf0489d708dcc1f67 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 23 Mar 2025 17:01:46 +0000 Subject: [PATCH 1/2] Fix SFM logic SFM mixed child wolfos / adult moblin logic, making both incorrect In particular, Din's Fire is ineffective on Moblins, & slashing your way through them should not be in logic Adds trick for getting through SFM as adult without killing moblins Includes small cleanup elsewhere in logic --- .../location_access/dungeons/deku_tree.cpp | 2 +- .../location_access/overworld/castle_grounds.cpp | 2 +- .../overworld/sacred_forest_meadow.cpp | 12 +++++++++--- .../overworld/{zora_river.cpp => zoras_river.cpp} | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 ++ soh/soh/Enhancements/randomizer/settings.cpp | 1 + 7 files changed, 17 insertions(+), 6 deletions(-) rename soh/soh/Enhancements/randomizer/location_access/overworld/{zora_river.cpp => zoras_river.cpp} (98%) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 4740a754160..df47f0f42fc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -216,7 +216,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return true;}), + Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, []{return Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));});}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b4b77056b4e..60aa8432fed 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -21,7 +21,7 @@ void RegionTable_Init_CastleGrounds() { }, { //Locations LOCATION(RC_HC_MALON_EGG, true), - LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()), + LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index ecc0577e29f..3719dce2475 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -6,9 +6,14 @@ using namespace Rando; void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_LW_BEYOND_MIDO, []{return true;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE);}), - Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), + Entrance(RR_LW_BEYOND_MIDO, []{return true;}), + Entrance(RR_SFM_MAZE, []{return logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS);}), + Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), + }); + + areaTable[RR_SFM_MAZE] = Region("SFM Maze", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, {}, {}, { + Entrance(RR_SFM_ENTRYWAY, []{return true;}), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->IsChild || logic->GetTrickOption(RT_SFM_JUMP_ABOVE_MAZE) || logic->CanKillEnemy(RE_MOBLIN);}), }); areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, { @@ -31,6 +36,7 @@ void RegionTable_Init_SacredForestMeadow() { }, { //Exits Entrance(RR_SFM_ENTRYWAY, []{return true;}), + Entrance(RR_SFM_MAZE, []{return true;}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}), Entrance(RR_SFM_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zora_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp similarity index 98% rename from soh/soh/Enhancements/randomizer/location_access/overworld/zora_river.cpp rename to soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 16ac1b2710f..f12de9128ce 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zora_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -6,7 +6,7 @@ using namespace Rando; void RegionTable_Init_ZoraRiver() { areaTable[RR_ZR_FRONT] = Region("ZR Front", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanAttack()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), }, { //Exits Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 62c14e6ffab..ff705e00679 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -617,6 +617,8 @@ namespace Rando { case RE_WHITE_WOLFOS: case RE_WALLMASTER: return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); + case RE_MOBLIN: + return CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HasExplosives() || (CanUse(RG_BOOMERANG) && CanJumpslash()); case RE_GERUDO_WARRIOR: return CanJumpslash() || CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON) && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5))); case RE_GIBDO: diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 23cbb290fc5..da54d1db7ee 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2870,6 +2870,7 @@ typedef enum { RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, RT_LW_GS_BEAN, + RT_SFM_JUMP_ABOVE_MAZE, RT_HC_STORMS_GS, RT_KAK_MAN_ON_ROOF, RT_KAK_TOWER_GS, @@ -5718,6 +5719,7 @@ typedef enum { RE_IRON_KNUCKLE, RE_FLARE_DANCER, RE_WOLFOS, + RE_MOBLIN, RE_FLOORMASTER, RE_REDEAD, RE_MEG, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index a2bf3660d9f..692929b37e6 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -363,6 +363,7 @@ void Settings::CreateOptions() { OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::INTERMEDIATE}, "Lost Woods Adult GS without Bean", "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); + OPT_TRICK(RT_SFM_JUMP_ABOVE_MAZE, RCQUEST_BOTH, RA_SACRED_FOREST_MEADOW, {Tricks::Tag::INTERMEDIATE}, "Sacred Forest Meadow Jump Above Maze", "You can jump above the maze in the Sacred Forest Meadow, skipping need to kill Moblins."); OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Hyrule Castle Storms Grotto GS with Just Boomerang", "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall."); OPT_TRICK(RT_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Man on Roof without Hookshot", "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's roof from the ledge as adult."); OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::INTERMEDIATE}, "Kakariko Tower GS with Jump Slash", "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage."); From f2e2b0d06960f24587f8bce8ef646a2540a575f6 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 23 Mar 2025 19:03:39 +0000 Subject: [PATCH 2/2] moblins not required --- .../overworld/sacred_forest_meadow.cpp | 12 +++--------- soh/soh/Enhancements/randomizer/logic.cpp | 2 -- soh/soh/Enhancements/randomizer/randomizerTypes.h | 2 -- soh/soh/Enhancements/randomizer/settings.cpp | 1 - 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 3719dce2475..e09e9559b27 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -6,14 +6,9 @@ using namespace Rando; void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_LW_BEYOND_MIDO, []{return true;}), - Entrance(RR_SFM_MAZE, []{return logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS);}), - Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), - }); - - areaTable[RR_SFM_MAZE] = Region("SFM Maze", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, {}, {}, { - Entrance(RR_SFM_ENTRYWAY, []{return true;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->IsChild || logic->GetTrickOption(RT_SFM_JUMP_ABOVE_MAZE) || logic->CanKillEnemy(RE_MOBLIN);}), + Entrance(RR_LW_BEYOND_MIDO, []{return true;}), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS);}), + Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), }); areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", "Sacred Forest Meadow", {RA_SACRED_FOREST_MEADOW}, NO_DAY_NIGHT_CYCLE, { @@ -36,7 +31,6 @@ void RegionTable_Init_SacredForestMeadow() { }, { //Exits Entrance(RR_SFM_ENTRYWAY, []{return true;}), - Entrance(RR_SFM_MAZE, []{return true;}), Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}), Entrance(RR_SFM_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index ff705e00679..62c14e6ffab 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -617,8 +617,6 @@ namespace Rando { case RE_WHITE_WOLFOS: case RE_WALLMASTER: return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); - case RE_MOBLIN: - return CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HasExplosives() || (CanUse(RG_BOOMERANG) && CanJumpslash()); case RE_GERUDO_WARRIOR: return CanJumpslash() || CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON) && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5))); case RE_GIBDO: diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index da54d1db7ee..23cbb290fc5 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -2870,7 +2870,6 @@ typedef enum { RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, RT_LW_GS_BEAN, - RT_SFM_JUMP_ABOVE_MAZE, RT_HC_STORMS_GS, RT_KAK_MAN_ON_ROOF, RT_KAK_TOWER_GS, @@ -5719,7 +5718,6 @@ typedef enum { RE_IRON_KNUCKLE, RE_FLARE_DANCER, RE_WOLFOS, - RE_MOBLIN, RE_FLOORMASTER, RE_REDEAD, RE_MEG, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 692929b37e6..a2bf3660d9f 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -363,7 +363,6 @@ void Settings::CreateOptions() { OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::INTERMEDIATE}, "Lost Woods Adult GS without Bean", "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); - OPT_TRICK(RT_SFM_JUMP_ABOVE_MAZE, RCQUEST_BOTH, RA_SACRED_FOREST_MEADOW, {Tricks::Tag::INTERMEDIATE}, "Sacred Forest Meadow Jump Above Maze", "You can jump above the maze in the Sacred Forest Meadow, skipping need to kill Moblins."); OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Hyrule Castle Storms Grotto GS with Just Boomerang", "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall."); OPT_TRICK(RT_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Man on Roof without Hookshot", "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's roof from the ledge as adult."); OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::INTERMEDIATE}, "Kakariko Tower GS with Jump Slash", "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage.");