From 3148c076ef0d469eb8ffb7022e52723d7e84a1d2 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Fri, 4 Jul 2025 22:48:04 +0000 Subject: [PATCH 01/13] refactor shadow logic --- .../dungeons/shadow_temple.cpp | 315 +++++++++++++----- .../Enhancements/randomizer/randomizerTypes.h | 23 +- 2 files changed, 260 insertions(+), 78 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d276fc418..291c8c70a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -9,117 +9,239 @@ void RegionTable_Init_ShadowTemple() { // Vanilla/MQ Decider areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ();}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return true;}), }); #pragma region Vanilla - areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, { + areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), + }); + + areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS] = Region("Shadow Temple Whispering Walls", SCENE_SHADOW_TEMPLE, { //Events EventAccess(&logic->NutPot, []{return true;}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), - LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_DEAD_HAND, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", SCENE_SHADOW_TEMPLE, { - //Events - EventAccess(&logic->FairyPot, []{return true;}), //This fairy pot is only on 3DS - }, { + areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple Whispering Walls Side Room", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_DEAD_HAND] = Region("Shadow Temple Dead Hand", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}), - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return false;}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), + }); + + areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_SPINNING_BLADES] = Region("Shadow Temple Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_DOCK, []{return false;}), }); areaTable[RR_SHADOW_TEMPLE_HUGE_PIT] = Region("Shadow Temple Huge Pit", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return false;}), // TODO hookshot up + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + }); + + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}), + Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()), - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), - LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}), + Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + }); + + areaTable[RR_SHADOW_TEMPLE_SKULL_JAR] = Region("Shadow Temple Skull Jar", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5))), + LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return true;}), + }); + + // TODO upper/lower logic + areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM] = Region("Shadow Temple Wind Tunnel Hint Room", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_ROOM_TO_BOAT] = Region("Shadow Temple Room to Boat", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2);}), + Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), + }); + + areaTable[RR_SHADOW_TEMPLE_DOCK] = Region("Shadow Temple Dock", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), + Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return logic->HasItem(RG_GORONS_BRACELET);}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ((logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanKillEnemy(RE_FLOORMASTER)), - //RANDOTODO check if child can reach the token - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS);}) + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MAZE] = Region("Shadow Temple Maze", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_X_CROSS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_THREE_SKULL_JARS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WOODEN_SPIKES, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_X_CROSS] = Region("Shadow Temple X-Cross", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanKillEnemy(RE_FLOORMASTER)), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return logic->CanKillEnemy(RE_FLOORMASTER);}), + }); + + areaTable[RR_SHADOW_TEMPLE_THREE_SKULL_JARS] = Region("Shadow Temple Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanAttack()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_WOODEN_SPIKES] = Region("Shadow Temple Wooden Spikes", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, { + //Locations + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return logic->CanUse(RG_HOVER_BOOTS);}), }); #pragma endregion #pragma region MQ - //RANDOTODO doublecheck CanAttack when rewriting, as I assumed it only checked adult due to the entrance areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), @@ -133,41 +255,64 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, logic->CanBreakSmallCrates()), LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, logic->CanBreakSmallCrates()), LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, logic->CanBreakSmallCrates()), - }, - { + }, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}), - Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), }); //Assumes we're in the "main" area and needed lens to enter. logic will need changes if a void warp puts us somewhere weird - areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Region("Shadow Temple MQ Dead Hand Region", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS] = Region("Shadow Temple MQ Whispering Walls", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD)), - //There's a shared flag tied to some glass here. eye target here and killing an enemy group later in the dungeon toggles. I'm building the logic as "intended", assuming the switch needs flipping - LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanHitEyeTargets()), LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), + //There's a shared flag tied to some glass here. eye target here and killing an enemy group later in the dungeon toggles. I'm building the logic as "intended", assuming the switch needs flipping + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{return (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanHitEyeTargets();}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple MQ Whispering Walls Redeads", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return logic->CanKillEnemy(RE_REDEAD);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND] = Region("Shadow Temple MQ Whispering Walls Dead Hand", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return logic->CanKillEnemy(RE_DEAD_HAND);}), }); - //also includes the B2 gibdo room areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", SCENE_SHADOW_TEMPLE, {}, { //Locations - //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, but doesn't seem to affect the chest - LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, but doesn't seem to affect the chest LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && (logic->CanUse(RG_HOVER_BOOTS) || logic->HasFireSource());}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), }); + areaTable[RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM] = Region("Shadow Temple MQ B2 Gibdo Room", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->CanKillEnemy(RE_GIBDO);}), + }); + areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), @@ -202,6 +347,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", SCENE_SHADOW_TEMPLE, {}, { @@ -274,7 +420,8 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), //We need to assume we can get here with or without the glass platforms - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, { @@ -374,17 +521,31 @@ void RegionTable_Init_ShadowTemple() { }); //Assumes lens is checked on entry - areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_X_CROSS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_THREE_SKULL_JARS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_X_CROSS] = Region("Shadow Temple MQ X-Cross", SCENE_SHADOW_TEMPLE, {}, { //Locations //don't use CanDetonateUprightBombFlower as blue fire logic would need to account for player having multiple bottles & taking damage multiple times LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, (logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)) && logic->CanKillEnemy(RE_DEAD_HAND) && (logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_THREE_SKULL_JARS] = Region("Shadow Temple MQ Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", SCENE_SHADOW_TEMPLE, {}, { @@ -402,12 +563,12 @@ void RegionTable_Init_ShadowTemple() { // Boss Room areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = Region("Shadow Temple Boss Entryway", SCENE_SHADOW_TEMPLE, {}, {}, { // Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false;}), - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false;}), - Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}), + Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false;}), + Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false;}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}), }); - areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE_BOSS, { + areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE, { // Events EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), }, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..9de8cb3b1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -935,16 +935,35 @@ typedef enum { RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BEGINNING, + RR_SHADOW_TEMPLE_WHISPERING_WALLS, + RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, + RR_SHADOW_TEMPLE_DEAD_HAND, RR_SHADOW_TEMPLE_FIRST_BEAMOS, + RR_SHADOW_TEMPLE_COMPASS_ROOM, + RR_SHADOW_TEMPLE_SPINNING_BLADES, RR_SHADOW_TEMPLE_HUGE_PIT, + RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, + RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, + RR_SHADOW_TEMPLE_SKULL_JAR, RR_SHADOW_TEMPLE_WIND_TUNNEL, + RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, + RR_SHADOW_TEMPLE_ROOM_TO_BOAT, + RR_SHADOW_TEMPLE_DOCK, RR_SHADOW_TEMPLE_BEYOND_BOAT, + RR_SHADOW_TEMPLE_MAZE, + RR_SHADOW_TEMPLE_X_CROSS, + RR_SHADOW_TEMPLE_THREE_SKULL_JARS, + RR_SHADOW_TEMPLE_WOODEN_SPIKES, + RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, RR_SHADOW_TEMPLE_MQ_ENTRYWAY, RR_SHADOW_TEMPLE_MQ_BEGINNING, RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, - RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, + RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, @@ -963,6 +982,8 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, + RR_SHADOW_TEMPLE_MQ_X_CROSS, + RR_SHADOW_TEMPLE_MQ_THREE_SKULL_JARS, RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, From 6d759215a564e7515ae32e735310b4332f3bb8a4 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 5 Jul 2025 00:22:58 +0000 Subject: [PATCH 02/13] split huge pit, beyond boat, & wind tunnel --- .../dungeons/shadow_temple.cpp | 146 ++++++++++++------ soh/soh/Enhancements/randomizer/logic.cpp | 1 + soh/soh/Enhancements/randomizer/logic.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 12 +- 4 files changed, 106 insertions(+), 54 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 291c8c70a..87b40c28c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -64,10 +64,10 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), }); areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, { @@ -88,7 +88,24 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_DOCK, []{return false;}), }); - areaTable[RR_SHADOW_TEMPLE_HUGE_PIT] = Region("Shadow Temple Huge Pit", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR] = Region("Shadow Temple B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return true;}), + //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily + }); + + areaTable[RR_SHADOW_TEMPLE_UPPER_HUGE_PIT] = Region("Shadow Temple Upper Huge Pit", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT] = Region("Shadow Temple Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), @@ -98,12 +115,10 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), - }, { + },{ //Exits - Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return false;}), // TODO hookshot up - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), }); areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { @@ -116,7 +131,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { @@ -124,9 +139,9 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), - Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_SKULL_JAR] = Region("Shadow Temple Skull Jar", SCENE_SHADOW_TEMPLE, {}, { @@ -138,12 +153,17 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return true;}), }); - // TODO upper/lower logic - areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL] = Region("Shadow Temple Upper Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL] = Region("Shadow Temple Lower Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM] = Region("Shadow Temple Wind Tunnel Hint Room", SCENE_SHADOW_TEMPLE, {}, { @@ -152,7 +172,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_ROOM_TO_BOAT] = Region("Shadow Temple Room to Boat", SCENE_SHADOW_TEMPLE, {}, { @@ -163,15 +183,15 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, []{return logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2);}), - Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2);}), + Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), }); areaTable[RR_SHADOW_TEMPLE_DOCK] = Region("Shadow Temple Dock", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), @@ -179,19 +199,33 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ((logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); - areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5));}) + }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_ACROSS_CHASM, []{return logic->ShadowBridgeBeyondBoatLowered || logic->CanUse(RG_DISTANT_SCARECROW);}), + }); + + areaTable[RR_SHADOW_TEMPLE_ACROSS_CHASM] = Region("Shadow Temple Across Chasm", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanDetonateUprightBombFlower();}) + }, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered;}), + Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), }); areaTable[RR_SHADOW_TEMPLE_MAZE] = Region("Shadow Temple Maze", SCENE_SHADOW_TEMPLE, {}, {}, { @@ -214,7 +248,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_THREE_SKULL_JARS] = Region("Shadow Temple Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanAttack()), + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanAttack()), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), @@ -230,12 +264,16 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, { - //Locations - }, { + areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_BOSS_DOOR, []{return logic->CanUse(RG_HOVER_BOOTS);}), + }); + + areaTable[RR_SHADOW_TEMPLE_BOSS_DOOR] = Region("Shadow Temple Boss Door", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), }); #pragma endregion @@ -332,7 +370,6 @@ void RegionTable_Init_ShadowTemple() { //WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum }); - //Room exists for if it's ever possible to go backwards or void warp into the middle of shadow areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), @@ -371,6 +408,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)), }, { //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->CanUse(RG_LONGSHOT);}), Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}), Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); @@ -420,7 +458,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), //We need to assume we can get here with or without the glass platforms - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); @@ -432,11 +470,17 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL] = Region("Shadow Temple MQ Upper Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT));}), - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), - Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL] = Region("Shadow Temple MQ Lower Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", SCENE_SHADOW_TEMPLE, {}, { @@ -446,7 +490,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", SCENE_SHADOW_TEMPLE, { @@ -462,8 +506,8 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits //child can make it using the wind strat - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", SCENE_SHADOW_TEMPLE, { @@ -563,7 +607,7 @@ void RegionTable_Init_ShadowTemple() { // Boss Room areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = Region("Shadow Temple Boss Entryway", SCENE_SHADOW_TEMPLE, {}, {}, { // Exits - Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false;}), + Entrance(RR_SHADOW_TEMPLE_BOSS_DOOR, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false;}), Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false;}), Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}), }); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3c0c8345e..237185823 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2521,6 +2521,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { MQJabuLiftRoomCow = false; MQShadowFloorSpikeRupees = false; ShadowShortcutBlock = false; + ShadowBridgeBeyondBoatLowered = false; MQWaterStalfosPit = false; MQWaterDragonTorches = false; MQWaterB1Switch = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 2bfea75e9..27d6c23c8 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -170,6 +170,7 @@ class Logic { bool MQJabuLiftRoomCow = false; bool MQShadowFloorSpikeRupees = false; bool ShadowShortcutBlock = false; + bool ShadowBridgeBeyondBoatLowered = false; bool MQWaterStalfosPit = false; bool MQWaterDragonTorches = false; bool MQWaterB1Switch = false; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9de8cb3b1..c670fb691 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -941,20 +941,25 @@ typedef enum { RR_SHADOW_TEMPLE_FIRST_BEAMOS, RR_SHADOW_TEMPLE_COMPASS_ROOM, RR_SHADOW_TEMPLE_SPINNING_BLADES, - RR_SHADOW_TEMPLE_HUGE_PIT, + RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, + RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, + RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, RR_SHADOW_TEMPLE_SKULL_JAR, - RR_SHADOW_TEMPLE_WIND_TUNNEL, + RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, + RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, RR_SHADOW_TEMPLE_ROOM_TO_BOAT, RR_SHADOW_TEMPLE_DOCK, RR_SHADOW_TEMPLE_BEYOND_BOAT, + RR_SHADOW_TEMPLE_ACROSS_CHASM, RR_SHADOW_TEMPLE_MAZE, RR_SHADOW_TEMPLE_X_CROSS, RR_SHADOW_TEMPLE_THREE_SKULL_JARS, RR_SHADOW_TEMPLE_WOODEN_SPIKES, RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, + RR_SHADOW_TEMPLE_BOSS_DOOR, RR_SHADOW_TEMPLE_MQ_ENTRYWAY, RR_SHADOW_TEMPLE_MQ_BEGINNING, @@ -974,7 +979,8 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, - RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, + RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, + RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, RR_SHADOW_TEMPLE_MQ_DOCK, From 77bd67a0616f286913da1344fb48e953fc686d9e Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 5 Jul 2025 05:58:58 +0000 Subject: [PATCH 03/13] apply chasm event to mq, give mq same preboss/door split in final room --- .../dungeons/shadow_temple.cpp | 36 ++++++++++++------- .../Enhancements/randomizer/randomizerTypes.h | 1 + 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 87b40c28c..1ec904aa5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -224,7 +224,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered;}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered && logic->IsAdult;}), Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), }); @@ -525,19 +525,25 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5));}) + }, { //Locations //It's a trick on N64 to kill this and drop down to collect this with normal weapons, as doing so without the statue being dropped voids you to before the boat - //hilariously, you can also hit this with a pot before you bring down the statue, but there's no great way to reset it without crossing. the statues collision is very inconvenient afterwards + //hilariously, you can hit this with a pot before you bring down statue, but there's no great way to reset it without crossing. the statue's collision is very inconvenient afterwards LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return Here(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5));});}), + Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->ShadowBridgeBeyondBoatLowered;}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanDetonateUprightBombFlower();}) + }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, logic->CanBreakPots()), @@ -547,21 +553,25 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, logic->IsAdult), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanDetonateUprightBombFlower();}) && logic->IsAdult;}), - //assumes RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT by previous access. If backwards shadow ever exists remember that child cannot jump onto the statue from this side and make an event for the switch - //Lens isn't needed to reach it but is needed to navigate the next room + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered && logic->IsAdult;}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);});}), - Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple MQ Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, { //Locations //you can drop onto this and the respawn is reasonable - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_HOVER_BOOTS) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), - Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), }); //Assumes lens is checked on entry diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c670fb691..939b6d491 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -986,6 +986,7 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_DOCK, RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, + RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, RR_SHADOW_TEMPLE_MQ_X_CROSS, From b5dbb44fcdc8c9175e3c3c922228fb2be5d32cba Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 5 Jul 2025 14:07:19 +0000 Subject: [PATCH 04/13] from room to boat to wind tunnel need hovers to get back can't reach entry without hookshot or hovers split invisible spikes room for decoupled don't need hovers to get GS from boss door --- .../dungeons/shadow_temple.cpp | 58 +++++++++++++------ .../Enhancements/randomizer/randomizerTypes.h | 4 ++ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 1ec904aa5..bec4aa36f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -18,7 +18,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), }); @@ -134,14 +134,20 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spikes", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), - Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM] = Region("Shadow Temple Invisible Spikes Platform", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_SKULL_JAR] = Region("Shadow Temple Skull Jar", SCENE_SHADOW_TEMPLE, {}, { @@ -155,15 +161,20 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL] = Region("Shadow Temple Upper Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), - Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}), }); areaTable[RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL] = Region("Shadow Temple Lower Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE, []{return true;}), Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE] = Region("Shadow Temple Wind Tunnel Alcove", SCENE_SHADOW_TEMPLE, {}, {}, { + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM] = Region("Shadow Temple Wind Tunnel Hint Room", SCENE_SHADOW_TEMPLE, {}, { @@ -456,10 +467,16 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), - //We need to assume we can get here with or without the glass platforms - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), + //We need to assume we can get here with or without the glass platforms + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM, []{return (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM] = Region("Shadow Temple MQ Floor Spikes Platform", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, { @@ -493,6 +510,11 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return true;}), }); + areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL_ALCOVE] = Region("Shadow Temple MQ Wind Tunnel Alcove", SCENE_SHADOW_TEMPLE, {}, {}, { + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return true;}), + }); + areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", SCENE_SHADOW_TEMPLE, { //Events EventAccess(&logic->NutPot, []{return true;}), @@ -558,17 +580,17 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple MQ Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, { - //Locations - //you can drop onto this and the respawn is reasonable - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_HOVER_BOOTS) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), - }, { + areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple MQ Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", SCENE_SHADOW_TEMPLE, {}, { + //Locations + //you can drop onto this and the respawn is reasonable + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 939b6d491..cfdd72952 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -946,9 +946,11 @@ typedef enum { RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, + RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, RR_SHADOW_TEMPLE_SKULL_JAR, RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, + RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE, RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, RR_SHADOW_TEMPLE_ROOM_TO_BOAT, RR_SHADOW_TEMPLE_DOCK, @@ -978,9 +980,11 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, + RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM, RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, + RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL_ALCOVE, RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, RR_SHADOW_TEMPLE_MQ_DOCK, From 12194c0aa9a0126624322107be46d52d5d13b084 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 5 Jul 2025 15:10:55 +0000 Subject: [PATCH 05/13] MQ: make switch across chasm an event --- .../randomizer/location_access/dungeons/shadow_temple.cpp | 5 +++-- soh/soh/Enhancements/randomizer/logic.cpp | 1 + soh/soh/Enhancements/randomizer/logic.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index bec4aa36f..d9b1186eb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -560,11 +560,13 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->ShadowBridgeBeyondBoatLowered;}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return logic->MQShadowSwitchAcrossChasm;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", SCENE_SHADOW_TEMPLE, { //Events - EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanDetonateUprightBombFlower();}) + EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanDetonateUprightBombFlower();}), + EventAccess(&logic->MQShadowSwitchAcrossChasm, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), @@ -576,7 +578,6 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered && logic->IsAdult;}), - Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);});}), Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return true;}), }); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 237185823..c7014dbf7 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2520,6 +2520,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { LoweredJabuPath = false; MQJabuLiftRoomCow = false; MQShadowFloorSpikeRupees = false; + MQShadowSwitchAcrossChasm = false; ShadowShortcutBlock = false; ShadowBridgeBeyondBoatLowered = false; MQWaterStalfosPit = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 27d6c23c8..d2b864fcc 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -169,6 +169,7 @@ class Logic { bool LoweredJabuPath = false; bool MQJabuLiftRoomCow = false; bool MQShadowFloorSpikeRupees = false; + bool MQShadowSwitchAcrossChasm = false; bool ShadowShortcutBlock = false; bool ShadowBridgeBeyondBoatLowered = false; bool MQWaterStalfosPit = false; From a5978e39a524e904eb11c2c73f61cf63f68eaaab Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 12 Jul 2025 05:43:33 +0000 Subject: [PATCH 06/13] vanilla feedback --- .../dungeons/shadow_temple.cpp | 191 ++++++++++++------ .../Enhancements/randomizer/randomizerTypes.h | 11 +- 2 files changed, 133 insertions(+), 69 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d9b1186eb..f3e5ca77a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -18,37 +18,59 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), }); - areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS] = Region("Shadow Temple Whispering Walls", SCENE_SHADOW_TEMPLE, { + areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_START] = Region("Shadow Temple Whispering Walls Start", SCENE_SHADOW_TEMPLE, { //Events EventAccess(&logic->NutPot, []{return true;}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_END, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + }); + + // shares RR_SHADOW_TEMPLE_WHISPERING_WALLS_START area with pots, but handles lens access for reaching door at start + areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE] = Region("Shadow Temple Whispering Walls Side", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->NutPot, []{return true;}), + }, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_END] = Region("Shadow Temple Whispering Walls End", SCENE_SHADOW_TEMPLE, {}, { + //Locations LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_DEAD_HAND, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_DEAD_HAND, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple Whispering Walls Side Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE)), LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE, []{return Here(RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, []{return logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE);});}), }); areaTable[RR_SHADOW_TEMPLE_DEAD_HAND] = Region("Shadow Temple Dead Hand", SCENE_SHADOW_TEMPLE, {}, { @@ -56,7 +78,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_END, []{return Here(RR_SHADOW_TEMPLE_DEAD_HAND, []{return logic->CanKillEnemy(RE_DEAD_HAND);});}), }); areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", SCENE_SHADOW_TEMPLE, {}, { @@ -64,84 +86,116 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B2, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), }); areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return logic->CanKillEnemy(RE_GIBDO);});}), }); areaTable[RR_SHADOW_TEMPLE_SPINNING_BLADES] = Region("Shadow Temple Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), + LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_DOCK, []{return false;}), + Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->ShadowShortcutBlock;}), }); - areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR] = Region("Shadow Temple B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B2] = Region("Shadow Temple B2 to B3 Corridor B2", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), - Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 1);}), + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), + }); + + areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple B2 to B3 Corridor B2", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B2, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily }); areaTable[RR_SHADOW_TEMPLE_UPPER_HUGE_PIT] = Region("Shadow Temple Upper Huge Pit", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3, []{return logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT_DOOR_LEDGE, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return logic->IsAdult || logic->CanJumpslash() || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}), }); - areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT] = Region("Shadow Temple Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, { - //Locations - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), - },{ + areaTable[RR_SHADOW_TEMPLE_UPPER_HUGE_PIT_DOOR_LEDGE] = Region("Shadow Temple Upper Huge Pit Door Ledge", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + }); + + areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT] = Region("Shadow Temple Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, {},{ + //Exits + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return logic->IsAdult || logic->CanJumpslash();}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA))), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER, []{return logic->IsAdult && ((ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET));}), + }); + + areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER] = Region("Shadow Temple Stone Umbrella Upper", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE] = Region("Shadow Temple Lower Huge Pit Door Ledge", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), }); areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT_DOOR_LEDGE, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spikes", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && + logic->CanUse(Here(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC));}) ? RG_HOOKSHOT : RG_LONGSHOT);}), }); areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM] = Region("Shadow Temple Invisible Spikes Platform", SCENE_SHADOW_TEMPLE, {}, {}, { @@ -153,10 +207,10 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_SKULL_JAR] = Region("Shadow Temple Skull Jar", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5))), - LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), + LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->CanKillEnemy(RE_GOLD_SKULLTULA)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return Here(RR_SHADOW_TEMPLE_SKULL_JAR, []{return logic->CanKillEnemy(RE_KEESE);});}), }); areaTable[RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL] = Region("Shadow Temple Upper Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { @@ -168,41 +222,44 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL] = Region("Shadow Temple Lower Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE] = Region("Shadow Temple Wind Tunnel Alcove", SCENE_SHADOW_TEMPLE, {}, {}, { - Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM] = Region("Shadow Temple Wind Tunnel Hint Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, logic->CanKillEnemy(RE_REDEAD)), LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return logic->CanKillEnemy(RE_REDEAD);}), }); areaTable[RR_SHADOW_TEMPLE_ROOM_TO_BOAT] = Region("Shadow Temple Room to Boat", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_LOWER_WIND_TUNNEL, []{return logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2);}), - Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL_ALCOVE, []{return Here(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2);});}), + Entrance(RR_SHADOW_TEMPLE_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), }); - areaTable[RR_SHADOW_TEMPLE_DOCK] = Region("Shadow Temple Dock", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_DOCK] = Region("Shadow Temple Dock", SCENE_SHADOW_TEMPLE, { + //Event + EventAccess(&logic->ShadowShortcutBlock, []{return logic->HasItem(RG_GORONS_BRACELET);}), + }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4)), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}), @@ -232,6 +289,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + // can reach with logic->IsAdult && logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanJumpslash(), but precise enough to be trick LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits @@ -249,17 +307,17 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_X_CROSS] = Region("Shadow Temple X-Cross", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanKillEnemy(RE_FLOORMASTER)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_FLOORMASTER)), LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MAZE, []{return logic->CanKillEnemy(RE_FLOORMASTER);}), + Entrance(RR_SHADOW_TEMPLE_MAZE, []{return Here(RR_SHADOW_TEMPLE_X_CROSS, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_FLOORMASTER);});}), }); areaTable[RR_SHADOW_TEMPLE_THREE_SKULL_JARS] = Region("Shadow Temple Three Skull Jars", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanAttack()), + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->HasItem(RG_GORONS_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), @@ -278,12 +336,12 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_PRE_BOSS_ROOM] = Region("Shadow Temple Pre Boss Room", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), - Entrance(RR_SHADOW_TEMPLE_BOSS_DOOR, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_BOSS_DOOR, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), }); areaTable[RR_SHADOW_TEMPLE_BOSS_DOOR] = Region("Shadow Temple Boss Door", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_PRE_BOSS_ROOM, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), }); @@ -293,7 +351,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), }); @@ -543,8 +601,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->ShadowShortcutBlock;}), Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), - //funnily enough, the wheel jump seems to be in logic as there's no strength requirement in N64 - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return ((logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", SCENE_SHADOW_TEMPLE, { @@ -645,7 +702,7 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}), }); - areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE, { + areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", SCENE_SHADOW_TEMPLE_BOSS, { // Events EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}), }, { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index cfdd72952..3ffa91b9d 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -935,15 +935,22 @@ typedef enum { RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BEGINNING, - RR_SHADOW_TEMPLE_WHISPERING_WALLS, + RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, + RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE, + RR_SHADOW_TEMPLE_WHISPERING_WALLS_END, RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM, RR_SHADOW_TEMPLE_DEAD_HAND, RR_SHADOW_TEMPLE_FIRST_BEAMOS, RR_SHADOW_TEMPLE_COMPASS_ROOM, RR_SHADOW_TEMPLE_SPINNING_BLADES, - RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR, + RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B2, + RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3, RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, + RR_SHADOW_TEMPLE_UPPER_HUGE_PIT_DOOR_LEDGE, RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, + RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, + RR_SHADOW_TEMPLE_STONE_UMBRELLA, + RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER, RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, From d0d98107d5886ba6ce0d199aab20e9e01c3c5123 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 12 Jul 2025 17:30:40 +0000 Subject: [PATCH 07/13] mq --- .../dungeons/shadow_temple.cpp | 98 +++++++++++++------ soh/soh/Enhancements/randomizer/logic.cpp | 2 + soh/soh/Enhancements/randomizer/logic.h | 2 + .../Enhancements/randomizer/randomizerTypes.h | 9 +- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index f3e5ca77a..d92eb66ec 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -351,7 +351,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}), Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), }); @@ -364,22 +364,37 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, logic->CanBreakSmallCrates()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}), - Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START, []{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}), }); - //Assumes we're in the "main" area and needed lens to enter. logic will need changes if a void warp puts us somewhere weird - areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS] = Region("Shadow Temple MQ Whispering Walls", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START] = Region("Shadow Temple MQ Whispering Walls Start", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE] = Region("Shadow Temple MQ Whispering Walls Side", SCENE_SHADOW_TEMPLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START, []{return true;}), Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END] = Region("Shadow Temple MQ Whispering Walls End", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}), //There's a shared flag tied to some glass here. eye target here and killing an enemy group later in the dungeon toggles. I'm building the logic as "intended", assuming the switch needs flipping - Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{return (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanHitEyeTargets();}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{return logic->CanHitEyeTargets();}), }); areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple MQ Whispering Walls Redeads", SCENE_SHADOW_TEMPLE, {}, { @@ -389,7 +404,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return logic->CanKillEnemy(RE_REDEAD);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE, []{return Here(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);});}), }); areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND] = Region("Shadow Temple MQ Whispering Walls Dead Hand", SCENE_SHADOW_TEMPLE, {}, { @@ -397,27 +412,27 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, []{return logic->CanKillEnemy(RE_DEAD_HAND);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, []{return Here(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{return logic->CanKillEnemy(RE_DEAD_HAND);});}), }); areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", SCENE_SHADOW_TEMPLE, {}, { //Locations - //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, but doesn't seem to affect the chest LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && (logic->CanUse(RG_HOVER_BOOTS) || logic->HasFireSource());}), Entrance(RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), - Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B2, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM] = Region("Shadow Temple MQ B2 Gibdo Room", SCENE_SHADOW_TEMPLE, {}, { //Locations + //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, but doesn't seem to affect the chest LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->CanKillEnemy(RE_GIBDO);}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, []{return logic->CanKillEnemy(RE_GIBDO);});}), }); areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, { @@ -439,21 +454,34 @@ void RegionTable_Init_ShadowTemple() { //WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum }); - areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B2] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily }); - areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", SCENE_SHADOW_TEMPLE, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", SCENE_SHADOW_TEMPLE, { + //Events + EventAccess(&logic->MQShadowPitStairs, []{return logic->HasFireSource();}), + }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}), - Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT_DOOR_LEDGE, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return (logic->MQShadowPitStairs && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT_DOOR_LEDGE] = Region("Shadow Temple MQ Upper Huge Pit Door Ledge", SCENE_SHADOW_TEMPLE, {}, {}, { + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, []{return true;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", SCENE_SHADOW_TEMPLE, {}, { @@ -477,9 +505,15 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->CanUse(RG_LONGSHOT);}), - Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}), - Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, []{return logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return logic->MQShadowPitStairs;}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT_DOOR_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT_DOOR_LEDGE] = Region("Shadow Temple MQ Upper Huge Pit Door Ledge", SCENE_SHADOW_TEMPLE, {}, {}, { + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { @@ -519,7 +553,7 @@ void RegionTable_Init_ShadowTemple() { //Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads)))) (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->CanJumpslash() || (logic->CanUse(RG_HOVER_BOOTS) && Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);}))))) && //1 rupee is in spikes, needs hovers or damage - (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS));}), + (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC));}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))), @@ -553,9 +587,9 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL] = Region("Shadow Temple MQ Lower Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_WIND_TUNNEL, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL_ALCOVE, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", SCENE_SHADOW_TEMPLE, {}, { @@ -569,7 +603,7 @@ void RegionTable_Init_ShadowTemple() { }); areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL_ALCOVE] = Region("Shadow Temple MQ Wind Tunnel Alcove", SCENE_SHADOW_TEMPLE, {}, {}, { - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return true;}), }); @@ -586,8 +620,8 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits //child can make it using the wind strat - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_WIND_TUNNEL, []{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL_ALCOVE, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), }); areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", SCENE_SHADOW_TEMPLE, { @@ -616,14 +650,15 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->ShadowBridgeBeyondBoatLowered;}), + Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->ShadowBridgeBeyondBoatLowered || (logic->MQShadowEyeSwitchAcrossChasm && logic->CanUse(RG_LONGSHOT));}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return logic->MQShadowSwitchAcrossChasm;}), }); areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", SCENE_SHADOW_TEMPLE, { //Events EventAccess(&logic->ShadowBridgeBeyondBoatLowered, []{return logic->CanDetonateUprightBombFlower();}), - EventAccess(&logic->MQShadowSwitchAcrossChasm, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);}), + EventAccess(&logic->MQShadowEyeSwitchAcrossChasm, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME);}), + EventAccess(&logic->MQShadowSwitchAcrossChasm, []{return logic->MQShadowEyeSwitchAcrossChasm && logic->CanUse(RG_LONGSHOT);}), }, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), @@ -654,7 +689,6 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}), }); - //Assumes lens is checked on entry areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index c7014dbf7..8f182715f 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2519,7 +2519,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { JabuNorthTentacle = false; LoweredJabuPath = false; MQJabuLiftRoomCow = false; + MQShadowPitStairs = false; MQShadowFloorSpikeRupees = false; + MQShadowEyeSwitchAcrossChasm = false; MQShadowSwitchAcrossChasm = false; ShadowShortcutBlock = false; ShadowBridgeBeyondBoatLowered = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index d2b864fcc..c9000ee5a 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -168,7 +168,9 @@ class Logic { bool JabuNorthTentacle = false; bool LoweredJabuPath = false; bool MQJabuLiftRoomCow = false; + bool MQShadowPitStairs = false; bool MQShadowFloorSpikeRupees = false; + bool MQShadowEyeSwitchAcrossChasm = false; bool MQShadowSwitchAcrossChasm = false; bool ShadowShortcutBlock = false; bool ShadowBridgeBeyondBoatLowered = false; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 3ffa91b9d..a3b923ad6 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -973,17 +973,22 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_ENTRYWAY, RR_SHADOW_TEMPLE_MQ_BEGINNING, RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, - RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE, + RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, - RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, + RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B2, + RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, + RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT_DOOR_LEDGE, RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, + RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT_DOOR_LEDGE, RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, From c1f7e99321c621e15c99e4ac561db78e11de9464 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 12 Jul 2025 23:55:03 +0000 Subject: [PATCH 08/13] Stone Umbrella: remove needing to be able to kill GS, add getting on umbrella as a simple damage boost --- .../location_access/dungeons/shadow_temple.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index d92eb66ec..80fc0452c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -145,16 +145,18 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA, []{return true;}), }); + // See MQ for comments areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA))), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER, []{return logic->IsAdult && ((ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET));}), + Entrance(RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER, []{return (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->TakeDamage()) || (logic->IsAdult && ((ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)));}), }); areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER] = Region("Shadow Temple Stone Umbrella Upper", SCENE_SHADOW_TEMPLE, {}, { @@ -519,6 +521,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), + //GS can be killed with pot //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. //Handling the trick here instead of upper as using the block to climb is not a valid method for getting this skull without other tricks to use the block before it is intended LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || @@ -530,7 +533,7 @@ void RegionTable_Init_ShadowTemple() { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return Here(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->CanHitSwitch();});}), //Assuming the known setup for RT_SHADOW_UMBRELLA, probably possible without sword + shield - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)));}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, []{return (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->TakeDamage()) || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))));}), }); areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA] = Region("Shadow Temple MQ Upper Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { From a114b6f62b304d43ec4faaa2b4ffeb962f7f85a9 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 12 Jul 2025 23:58:55 +0000 Subject: [PATCH 09/13] copy comment from vanilla to mq too --- .../randomizer/location_access/dungeons/shadow_temple.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 80fc0452c..758bfb1da 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -382,6 +382,7 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, []{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}), }); + // shares RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START area with pots, but handles lens access for reaching door at start areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE] = Region("Shadow Temple MQ Whispering Walls Side", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), From 8b6020aef734134b764c12b752e80810227abd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 13 Jul 2025 00:00:29 +0000 Subject: [PATCH 10/13] stupid gs/hammer interactions Co-authored-by: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com> --- .../randomizer/location_access/dungeons/shadow_temple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 758bfb1da..45f7c2a4a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -180,7 +180,7 @@ void RegionTable_Init_ShadowTemple() { //Locations LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && ((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE_JUMPSLASH)) || CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), From 4f0737c55346708f59a3b5d7d99d3503e62b028b Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 13 Jul 2025 00:07:53 +0000 Subject: [PATCH 11/13] remove RT_LENS_SHADOW_PLATFORM from invisible spikes room --- .../randomizer/location_access/dungeons/shadow_temple.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 45f7c2a4a..92d565c4f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -195,8 +195,8 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), - Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), - Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && + Entrance(RR_SHADOW_TEMPLE_SKULL_JAR, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES_PLATFORM, []{return (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(Here(RR_SHADOW_TEMPLE_INVISIBLE_SPIKES, []{return logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC));}) ? RG_HOOKSHOT : RG_LONGSHOT);}), }); From c8a3ca453d23165aa3af25cd9d1e47bc99610197 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 13 Jul 2025 01:09:02 +0000 Subject: [PATCH 12/13] little fix --- .../randomizer/location_access/dungeons/shadow_temple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 92d565c4f..5e8977903 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -180,7 +180,7 @@ void RegionTable_Init_ShadowTemple() { //Locations LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && ((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE_JUMPSLASH)) || CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), + LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && ((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)) || logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), From d2a603970cb901a232b94715563dc59e339a4755 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Fri, 8 Aug 2025 03:01:44 +0000 Subject: [PATCH 13/13] feedback --- .../location_access/dungeons/shadow_temple.cpp | 15 +++++++-------- soh/soh/Enhancements/randomizer/settings.cpp | 7 +++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 5e8977903..3c873a1eb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -115,7 +115,7 @@ void RegionTable_Init_ShadowTemple() { Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), }); - areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple B2 to B3 Corridor B2", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple B2 to B3 Corridor B3", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_B2_TO_B3_CORRIDOR_B2, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SHADOW_TEMPLE_UPPER_HUGE_PIT, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), @@ -149,8 +149,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || - (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), + //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), }, { @@ -389,7 +389,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_START, []{return true;}), + Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_START, []{return ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM, []{return true;}), }); @@ -457,13 +457,13 @@ void RegionTable_Init_ShadowTemple() { //WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum }); - areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B2] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B2] = Region("Shadow Temple MQ B2 to B3 Corridor B2", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, { + areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3] = Region("Shadow Temple MQ B2 to B3 Corridor B3", SCENE_SHADOW_TEMPLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, []{return logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), @@ -525,8 +525,7 @@ void RegionTable_Init_ShadowTemple() { //GS can be killed with pot //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. //Handling the trick here instead of upper as using the block to climb is not a valid method for getting this skull without other tricks to use the block before it is intended - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || - (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..4322c824e 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -970,15 +970,14 @@ void Settings::CreateOptions() { "where the eye is."); OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "Shadow Temple Stone Umbrella Skip", - "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing " + "A very precise Hover Boots movement from off of the lower chest can get you on top of the falling " "spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, "Shadow Temple Falling Spikes GS with Hover Boots", "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get " - "you on top of the crushing spikes without needing to pull the block. From there, another very precise " + "you on top of the falling spikes without needing to pull the block. From there, another very precise " "Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both " - "Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to " - "enable \"Shadow Temple Stone Umbrella Skip\"."); + "Vanilla and Master Quest. Assumes you can always reach the upper level of the room."); OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, "Shadow Temple Freestanding Key with Bombchu", "Release the Bombchu with good timing so that it explodes near the bottom of the pot.");