This commit is contained in:
Philip Dubé 2025-08-13 19:09:04 +00:00 committed by GitHub
commit 64de39fccf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 517 additions and 134 deletions

View file

@ -9,120 +9,351 @@ void RegionTable_Init_ShadowTemple() {
// Vanilla/MQ Decider // Vanilla/MQ Decider
areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", SCENE_SHADOW_TEMPLE, {}, {}, { areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", SCENE_SHADOW_TEMPLE, {}, {}, {
//Exits //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_SHADOW_TEMPLE_MQ_BEGINNING, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ();}),
Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return true;}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return true;}),
}); });
#pragma region Vanilla #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 (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_START] = Region("Shadow Temple Whispering Walls Start", SCENE_SHADOW_TEMPLE, {
//Events //Events
EventAccess(&logic->NutPot, []{return true;}), EventAccess(&logic->NutPot, []{return true;}),
}, { }, {
//Locations //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_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, 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_3, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, 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_WHISPERING_WALLS_POT_5, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, 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_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->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE)),
LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, 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_MAP_CHEST_POT_2, logic->CanBreakPots()),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{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);});}),
Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return logic->CanUse(RG_HOVER_BOOTS);}),
}); });
areaTable[RR_SHADOW_TEMPLE_FIRST_BEAMOS] = Region("Shadow Temple First Beamos", SCENE_SHADOW_TEMPLE, { areaTable[RR_SHADOW_TEMPLE_DEAD_HAND] = Region("Shadow Temple Dead Hand", SCENE_SHADOW_TEMPLE, {}, {
//Events //Locations
EventAccess(&logic->FairyPot, []{return true;}), //This fairy pot is only on 3DS LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)),
}, { }, {
//Exits
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, {}, {
//Locations //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)), LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, []{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}), Entrance(RR_SHADOW_TEMPLE_BEGINNING, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return false;}), 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_HUGE_PIT] = Region("Shadow Temple Huge Pit", SCENE_SHADOW_TEMPLE, {}, { areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO)),
}, {
//Exits
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->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 logic->ShadowShortcutBlock;}),
});
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_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 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);}),
//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 //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)), LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //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_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_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", SCENE_SHADOW_TEMPLE, {}, { 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 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;}),
});
// See MQ for comments
areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield.
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()), 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_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()),
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)),
}, { }, {
//Exits //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_LOWER_HUGE_PIT, []{return true;}),
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_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, {}, { 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->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_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)),
}, {
//Exits
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, 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_DOOR_LEDGE, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}),
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);}),
});
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, {}, {
//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)),
}, {
//Exits
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, {}, {}, {
//Exits
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 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 (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, 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 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, (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_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, {
//Event
EventAccess(&logic->ShadowShortcutBlock, []{return logic->HasItem(RG_GORONS_BRACELET);}),
}, {
//Locations
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);}),
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, {
//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()),
}, {
//Exits
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)),
// 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
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);}),
});
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, (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 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->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)),
}, {
//Exits
Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}),
});
areaTable[RR_SHADOW_TEMPLE_WOODEN_SPIKES] = Region("Shadow Temple Wooden Spikes", SCENE_SHADOW_TEMPLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), 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_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_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 //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;}),
});
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 (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 (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
}); });
#pragma endregion #pragma endregion
#pragma region MQ #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, {}, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", SCENE_SHADOW_TEMPLE, {}, {}, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), 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);}), Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
}); });
@ -133,39 +364,78 @@ 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_2, logic->CanBreakSmallCrates()),
LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, 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()), LOCATION(RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, logic->CanBreakSmallCrates()),
}, }, {
{
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, []{return true;}), 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_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_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_START] = Region("Shadow Temple MQ Whispering Walls Start", SCENE_SHADOW_TEMPLE, {}, {
areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Region("Shadow Temple MQ Dead Hand Region", SCENE_SHADOW_TEMPLE, {}, {
//Locations //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_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, 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_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));}),
});
// 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()),
LOCATION(RC_SHADOW_TEMPLE_MQ_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_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->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_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return true;}), 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, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)),
}, {
//Exits
Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, []{return Here(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", SCENE_SHADOW_TEMPLE, {}, {
//Locations //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))),
LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //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_SPINNING_BLADE_ROOM, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}), Entrance(RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, []{return true;}),
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 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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, {
@ -187,21 +457,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 //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_B2] = Region("Shadow Temple MQ B2 to B3 Corridor B2", SCENE_SHADOW_TEMPLE, {}, {}, {
areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", SCENE_SHADOW_TEMPLE, {}, {}, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}), Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}),
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}), 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 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;}),
//bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily //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 //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, { }, {
//Exits //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_UPPER_HUGE_PIT_DOOR_LEDGE, []{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}),
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_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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", SCENE_SHADOW_TEMPLE, {}, {
@ -225,17 +508,24 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)), LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)),
}, { }, {
//Exits //Exits
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();});}), 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);}), });
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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), 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. //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 //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) || 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))),
(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_WEST_POT, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_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)), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanUse(RG_BOOMERANG)),
@ -243,7 +533,7 @@ void RegionTable_Init_ShadowTemple() {
//Exits //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();});}), 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 //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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA] = Region("Shadow Temple MQ Upper Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, {
@ -266,7 +556,7 @@ void RegionTable_Init_ShadowTemple() {
//Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads)))) //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);}))))) && (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 //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 //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))), 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))),
@ -274,7 +564,14 @@ void RegionTable_Init_ShadowTemple() {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}), Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->MQShadowFloorSpikeRupees;}),
//We need to assume we can get here with or without the glass platforms //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_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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, {
@ -285,11 +582,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);});}), 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 //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_FLOOR_SPIKES_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}),
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_LOWER_WIND_TUNNEL, []{return (logic->CanUse(RG_HOVER_BOOTS) && logic->CanPassEnemy(RE_BIG_SKULLTULA)) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), });
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_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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", SCENE_SHADOW_TEMPLE, {}, {
@ -299,7 +602,12 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, { }, {
//Exits //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_WIND_TUNNEL_ALCOVE] = Region("Shadow Temple MQ Wind Tunnel Alcove", SCENE_SHADOW_TEMPLE, {}, {}, {
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;}),
}); });
areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", SCENE_SHADOW_TEMPLE, { areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", SCENE_SHADOW_TEMPLE, {
@ -315,7 +623,7 @@ void RegionTable_Init_ShadowTemple() {
}, { }, {
//Exits //Exits
//child can make it using the wind strat //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_WIND_TUNNEL_ALCOVE, []{return true;}),
Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}), Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}),
}); });
@ -330,23 +638,31 @@ void RegionTable_Init_ShadowTemple() {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->ShadowShortcutBlock;}), 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);}), 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->HasItem(RG_GORONS_BRACELET)) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}),
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 //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 //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_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_WEST_POT, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()),
}, { }, {
//Exits //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 || (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, {}, { 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->MQShadowEyeSwitchAcrossChasm, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME);}),
EventAccess(&logic->MQShadowSwitchAcrossChasm, []{return logic->MQShadowEyeSwitchAcrossChasm && logic->CanUse(RG_LONGSHOT);}),
}, {
//Locations //Locations
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, logic->CanBreakPots()),
@ -356,10 +672,13 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, logic->IsAdult), LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, logic->IsAdult),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanDetonateUprightBombFlower();}) && logic->IsAdult;}), Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->ShadowBridgeBeyondBoatLowered && 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 Entrance(RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM, []{return true;}),
//Lens isn't needed to reach it but is needed to navigate the next room });
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);});}),
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));}), 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));}),
}); });
@ -369,22 +688,35 @@ void RegionTable_Init_ShadowTemple() {
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->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 //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_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;}), 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, {}, {}, {
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 //Locations
//don't use CanDetonateUprightBombFlower as blue fire logic would need to account for player having multiple bottles & taking damage multiple times //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_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_1, logic->CanBreakPots()),
LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, logic->CanBreakPots()),
}, { }, {
//Exits //Exits
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return true;}), Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, []{return true;}),
Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}), });
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, {}, { areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", SCENE_SHADOW_TEMPLE, {}, {
@ -402,8 +734,8 @@ void RegionTable_Init_ShadowTemple() {
// Boss Room // Boss Room
areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = Region("Shadow Temple Boss Entryway", SCENE_SHADOW_TEMPLE, {}, {}, { areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = Region("Shadow Temple Boss Entryway", SCENE_SHADOW_TEMPLE, {}, {}, {
// Exits // Exits
Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{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_BEYOND_BOAT, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && 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);}), Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}),
}); });

View file

@ -2519,8 +2519,12 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
JabuNorthTentacle = false; JabuNorthTentacle = false;
LoweredJabuPath = false; LoweredJabuPath = false;
MQJabuLiftRoomCow = false; MQJabuLiftRoomCow = false;
MQShadowPitStairs = false;
MQShadowFloorSpikeRupees = false; MQShadowFloorSpikeRupees = false;
MQShadowEyeSwitchAcrossChasm = false;
MQShadowSwitchAcrossChasm = false;
ShadowShortcutBlock = false; ShadowShortcutBlock = false;
ShadowBridgeBeyondBoatLowered = false;
MQWaterStalfosPit = false; MQWaterStalfosPit = false;
MQWaterDragonTorches = false; MQWaterDragonTorches = false;
MQWaterB1Switch = false; MQWaterB1Switch = false;

View file

@ -168,8 +168,12 @@ class Logic {
bool JabuNorthTentacle = false; bool JabuNorthTentacle = false;
bool LoweredJabuPath = false; bool LoweredJabuPath = false;
bool MQJabuLiftRoomCow = false; bool MQJabuLiftRoomCow = false;
bool MQShadowPitStairs = false;
bool MQShadowFloorSpikeRupees = false; bool MQShadowFloorSpikeRupees = false;
bool MQShadowEyeSwitchAcrossChasm = false;
bool MQShadowSwitchAcrossChasm = false;
bool ShadowShortcutBlock = false; bool ShadowShortcutBlock = false;
bool ShadowBridgeBeyondBoatLowered = false;
bool MQWaterStalfosPit = false; bool MQWaterStalfosPit = false;
bool MQWaterDragonTorches = false; bool MQWaterDragonTorches = false;
bool MQWaterB1Switch = false; bool MQWaterB1Switch = false;

View file

@ -935,34 +935,78 @@ typedef enum {
RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ROOM,
RR_SHADOW_TEMPLE_BEGINNING, RR_SHADOW_TEMPLE_BEGINNING,
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_FIRST_BEAMOS,
RR_SHADOW_TEMPLE_HUGE_PIT, RR_SHADOW_TEMPLE_COMPASS_ROOM,
RR_SHADOW_TEMPLE_WIND_TUNNEL, RR_SHADOW_TEMPLE_SPINNING_BLADES,
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,
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,
RR_SHADOW_TEMPLE_BEYOND_BOAT, 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_ENTRYWAY,
RR_SHADOW_TEMPLE_MQ_BEGINNING, RR_SHADOW_TEMPLE_MQ_BEGINNING,
RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM,
RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, 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_FIRST_BEAMOS,
RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM,
RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM,
RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, 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,
RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT_DOOR_LEDGE,
RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM,
RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, 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_STONE_UMBRELLA_ROOM,
RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA,
RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM,
RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_PLATFORM,
RR_SHADOW_TEMPLE_MQ_STALFOS_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_TUNNEL_ALCOVE,
RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM,
RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM,
RR_SHADOW_TEMPLE_MQ_DOCK, RR_SHADOW_TEMPLE_MQ_DOCK,
RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT,
RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM,
RR_SHADOW_TEMPLE_MQ_PRE_BOSS_ROOM,
RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, RR_SHADOW_TEMPLE_MQ_BOSS_DOOR,
RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, 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_MQ_SPIKE_WALLS_ROOM,
RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY,

View file

@ -970,15 +970,14 @@ void Settings::CreateOptions() {
"where the eye is."); "where the eye is.");
OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT },
"Shadow Temple Stone Umbrella Skip", "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."); "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 }, OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT },
"Shadow Temple Falling Spikes GS with Hover Boots", "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 " "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 " "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 " "Vanilla and Master Quest. Assumes you can always reach the upper level of the room.");
"enable \"Shadow Temple Stone Umbrella Skip\".");
OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE },
"Shadow Temple Freestanding Key with Bombchu", "Shadow Temple Freestanding Key with Bombchu",
"Release the Bombchu with good timing so that it explodes near the bottom of the pot."); "Release the Bombchu with good timing so that it explodes near the bottom of the pot.");