From 73a739b7a495640591cde8405391bcc8fc2fce9a Mon Sep 17 00:00:00 2001 From: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> Date: Sat, 5 Sep 2026 16:51:12 +0100 Subject: [PATCH] Fix various trick issues (#7145) --- soh/assets/custom/lang/en_US.json | 12 ++++++++---- soh/soh/Enhancements/debugger/colViewer.cpp | 2 +- .../location_access/dungeons/fire_temple.cpp | 3 ++- .../location_access/dungeons/ganons_castle.cpp | 4 ++-- .../dungeons/gerudo_training_ground.cpp | 5 +++-- .../location_access/dungeons/water_temple.cpp | 3 +-- .../location_access/overworld/kakariko.cpp | 2 +- .../location_access/overworld/lost_woods.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 16 ++-------------- .../randomizer/randomizerEnums/RandomizerTrick.h | 1 + soh/soh/Enhancements/randomizer/settings.cpp | 1 + 11 files changed, 23 insertions(+), 28 deletions(-) diff --git a/soh/assets/custom/lang/en_US.json b/soh/assets/custom/lang/en_US.json index 21e94bc7af..fd0fdcf258 100644 --- a/soh/assets/custom/lang/en_US.json +++ b/soh/assets/custom/lang/en_US.json @@ -2078,8 +2078,8 @@ "description": "Can be obtained without Hookshot by using the Hover Boots off of one of the roots." }, "lw_bridge": { - "name": "Jump onto the Lost Woods Bridge as Adult with Nothing", - "description": "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean." + "name": "Jump onto the Lost Woods Bridge as Adult with a Jumpslash", + "description": "With very precise movement and a jumpslash it's possible for Adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean." }, "lw_mido_backflip": { "name": "Backflip over Mido as Adult", @@ -2090,8 +2090,8 @@ "description": "You need Deku Sticks or Kokiri Sword to dive with Navi for entering Zora's River." }, "lw_gs_bean": { - "name": "Lost Woods Adult GS without Bean", - "description": "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." + "name": "Lost Woods Adult GS with Hookshot", + "description": "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 Bow, Bombchus or Din's Fire. Using Longshot to both kill the skull and grab the token is in default logic." }, "hc_storms_gs": { "name": "Hyrule Castle Storms Grotto GS with Just Boomerang", @@ -2592,6 +2592,10 @@ "name": "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", "description": "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal." }, + "water_high_emblem_jump": { + "name": "Water Temple Jump to High Emblem with Nothing", + "description": "Adult can jump directly to the Emblem that sets the water level to high from the pillar with nothing by aiming for the middle of the ledge. Child with the help of Bunny Hood can do the same, but even easier." + }, "water_longshot_torch": { "name": "Water Temple Torch Longshot", "description": [ diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 8f2663e359..c34e738a72 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -670,7 +670,7 @@ void DrawColCheckCollision() { color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC.Value"), { 0, 0, 255, 255 }); dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); DrawColCheckList(dl, col.colAC, col.colACCount); - color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT.Value"), { 0, 0, 255, 255 }); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT.Value"), { 255, 0, 0, 255 }); dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); DrawColCheckList(dl, col.colAT, col.colATCount); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index cb1046c1df..75d5e96c3a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/randomizer/location_access.h" #include "soh/Enhancements/randomizer/entrance.h" #include "soh/Enhancements/randomizer/dungeon.h" +#include "soh/Enhancements/randomizer/randomizerEnums.h" using namespace Rando; @@ -751,7 +752,7 @@ void RegionTable_Init_FireTemple() { //Exits ENTRANCE(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, true), //Explosives can also reach this room. Chus is relatively simple, they need to detonate on the first horizontal bar up from the floor while horizontally near the switch, but bombs are much harder - ENTRANCE(RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE, AnyAgeTime([]{return logic->CanJumpslash() || (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_BOMBCHU_5));})), + ENTRANCE(RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE, AnyAgeTime([]{return logic->CanJumpslash() || (ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_BOMBCHU_5)) || (ctx->GetTrickOption(RT_BOMB_DETONATION) && logic->CanUse(RG_BOMB_BAG));})), ENTRANCE(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, (logic->HasExplosives() || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT)), ENTRANCE(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM)), ENTRANCE(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, false), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 9cbefdb5dc..30ae3ba9cf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -213,10 +213,10 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanBreakPots()), }, { //Locations - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots()), }, { //Exits ENTRANCE(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 72e48f075e..9e90eacfa8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -1,6 +1,7 @@ #include "soh/Enhancements/randomizer/location_access.h" #include "soh/Enhancements/randomizer/entrance.h" #include "soh/Enhancements/randomizer/dungeon.h" +#include "soh/Enhancements/randomizer/randomizerEnums.h" using namespace Rando; @@ -349,9 +350,9 @@ void RegionTable_Init_GerudoTrainingGround() { }, { //Exits ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM_ALCOVE, true), - //implies dropping down to hit the switch. Using swords, especially master, is a bit awkward, may be trick worthy, but is only relevant with other tricks + //implies dropping down to hit the switch. Using swords, especially master, is a bit awkward, may be a separate trick. //chus work, but the aim is awkward. - ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, AnyAgeTime([]{return logic->CanHitSwitch(ctx->GetTrickOption(RT_VISIBLE_COLLISION) ? ED_MASTER_SWORD_JUMPSLASH : ED_BOOMERANG);})), + ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, AnyAgeTime([]{return logic->CanHitSwitch(!ctx->GetTrickOption(RT_VISIBLE_COLLISION) ? ED_BOMB_THROW : logic->IsAdult ? ED_MASTER_SWORD_JUMPSLASH : ED_LONG_JUMPSLASH);})), ENTRANCE(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, true), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index b4ffa4b26d..156b8446f5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -741,8 +741,7 @@ void RegionTable_Init_WaterTemple() { ENTRANCE(RR_WATER_TEMPLE_MQ_RISING_TARGET_LEDGE, ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()))), //this swimless jump with irons may be a trick as you have to put irons on quite late. ENTRANCE(RR_WATER_TEMPLE_MQ_LIZALFOS_LOOP_A, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), - //Jumping across is possible but a trick due to the janky ledge - ENTRANCE(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->BunnyHood() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))), + ENTRANCE(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || ((logic->IsAdult || logic->BunnyHood()) && ctx->GetTrickOption(RT_WATER_HIGH_EMBLEM_JUMP))), }); //This region specifically covers the topmost platform around central pillar diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 55ac819eac..6d15b05850 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -149,7 +149,7 @@ void RegionTable_Init_Kakariko() { ENTRANCE(RR_KAK_BACKYARD, true), ENTRANCE(RR_KAK_POTION_SHOP, logic->IsAdult && logic->AtDay && logic->HasItem(RG_KAK_POTION_SHOP_KEY)), //can ledgegrab fence to rooftop with hover boots, but that's more difficult than the unintuitive jump, so not including in default logic - ENTRANCE(RR_KAK_ROOFTOP, ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER) && logic->IsAdult), + ENTRANCE(RR_KAK_ROOFTOP, ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_MEGATON_HAMMER)), }); areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", SCENE_KAKARIKO_CENTER_GUEST_HOUSE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 1dc911b90a..94c67c9e9b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -58,7 +58,7 @@ void RegionTable_Init_LostWoods() { ENTRANCE(RR_LW_FOREST_EXIT, true), ENTRANCE(RR_LW_UNDER_BRIDGE, true), ENTRANCE(RR_GC_WOODS_WARP, true), - ENTRANCE(RR_LW_BRIDGE, (logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->BunnyHood() || logic->CanUse(RG_LONGSHOT)), + ENTRANCE(RR_LW_BRIDGE, (logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) || (ctx->GetTrickOption(RT_LW_BRIDGE) && logic->CanJumpslash()))) || logic->CanUse(RG_HOVER_BOOTS) || logic->BunnyHood() || logic->CanUse(RG_LONGSHOT)), ENTRANCE(RR_ZR_FROM_SHORTCUT, logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash())), ENTRANCE(RR_LW_BEYOND_MIDO, logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP)), ENTRANCE(RR_LW_NEAR_SHORTCUTS_GROTTO, AnyAgeTime([]{return logic->BlastOrSmash();})), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index d9e27ff434..b70908eb94 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1401,21 +1401,9 @@ bool Logic::CanRecoilHoverFromObject(TorchRecoilRequirements req) { } bool Logic::Water3FCentralToHighEmblem() { - //"Just jumping" to this ledge is complicated, as the nearest part of the ledge is janky - // Adult without bunny hood can airdrift left to get a clean ledge grab, however if the scarecrow has spawned (which - // is a perm flag that with skip scarecrow inevitably activates while setting water to high) the usable ledge area - // is much smaller. Unlike most jumps like this, Bunny hood does not solve the jump, at least for Adult. For child - // it makes this not only possible but much less prone to issues than either Adult jump. Adult can instead aim even - // further left to get a good ledge climb, but will almost always be blocked by the scarecrow if that exists. - // otherwise Adult with bunny will result in worse ledge bugging than not using bunny. You can climb up even if you - // start doing weird ledge things with a well timed jumpslash. Hovers are similarly unintuitive, needing the player - // aim for the far side of the ledge, but the scarecrow is less annoying as even if you get pushed off, hovers will - // save you and push you slightly right, eventually giving you a good ledge grab - return (IsAdult && (CanUse(RG_HOVER_BOOTS) || - (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && CanUse(RG_BOMB_BAG) && TakeDamage()))) || - CanMiddairGroundJump() || + return (IsAdult && CanUse(RG_HOVER_BOOTS)) || CanMiddairGroundJump() || (Get(LOGIC_WATER_SCARECROW) && CanUse(RG_HOOKSHOT) || - (logic->IsChild && logic->BunnyHood() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))); + ((logic->IsAdult || logic->BunnyHood()) && ctx->GetTrickOption(RT_WATER_HIGH_EMBLEM_JUMP))); } bool Logic::WaterRisingTargetTo3FCentral() { diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h index 88925da0fe..c23a5b7a64 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/RandomizerTrick.h @@ -146,6 +146,7 @@ RANDO_ENUM_ITEM(RT_FIRE_MQ_MAZE_SIDE_ROOM) RANDO_ENUM_ITEM(RT_FIRE_MQ_MAZE_HOVERS) RANDO_ENUM_ITEM(RT_FIRE_MQ_MAZE_JUMP) RANDO_ENUM_ITEM(RT_FIRE_MQ_ABOVE_MAZE_GS) +RANDO_ENUM_ITEM(RT_WATER_HIGH_EMBLEM_JUMP) RANDO_ENUM_ITEM(RT_WATER_LONGSHOT_TORCH) RANDO_ENUM_ITEM(RT_WATER_CRACKED_WALL_HOVERS) RANDO_ENUM_ITEM(RT_WATER_CRACKED_WALL) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index df72aa88c8..af2fea8fec 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1749,6 +1749,7 @@ void Settings::CreateOptions() { OPT_TRICK(RT_FIRE_MQ_MAZE_HOVERS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, "FIMazHB"); OPT_TRICK(RT_FIRE_MQ_MAZE_JUMP, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIMazJmp"); OPT_TRICK(RT_FIRE_MQ_ABOVE_MAZE_GS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "FIGSLS"); + OPT_TRICK(RT_WATER_HIGH_EMBLEM_JUMP, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTHiJmp"); OPT_TRICK(RT_WATER_LONGSHOT_TORCH, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTTorLS"); OPT_TRICK(RT_WATER_CRACKED_WALL_HOVERS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, "WTCrkHB"); OPT_TRICK(RT_WATER_CRACKED_WALL, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, "WTCrkJmp");