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,