diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 8571ba384..161f7622f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -17,20 +17,25 @@ void RegionTable_Init_GanonsCastle() { #pragma region Vanilla - areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", SCENE_INSIDE_GANONS_CASTLE, {}, { + areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + Entrance(RR_GANONS_CASTLE_ENTRYWAY, []{return true;}), + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + }); + + areaTable[RR_GANONS_CASTLE_MAIN] = Region("Ganon's Castle Main", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations LOCATION(RC_SHEIK_HINT_GC, true), }, { //Exits - Entrance(RR_GANONS_CASTLE_ENTRYWAY, []{return true;}), - Entrance(RR_GANONS_CASTLE_FOREST_TRIAL, []{return true;}), - Entrance(RR_GANONS_CASTLE_FIRE_TRIAL, []{return true;}), - Entrance(RR_GANONS_CASTLE_WATER_TRIAL, []{return true;}), - Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, []{return true;}), - Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, []{return true;}), - Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}), - Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return true;}), - Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, []{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}), + Entrance(RR_GANONS_CASTLE_LOBBY, []{return true;}), + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_START, []{return true;}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM, []{return Here(RR_GANONS_CASTLE_MAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);});}), + Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return true;}), + Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, []{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}), }); areaTable[RR_GANONS_CASTLE_DEKU_SCRUBS] = Region("Ganon's Castle Deku Scrubs", SCENE_INSIDE_GANONS_CASTLE, { @@ -52,87 +57,283 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, true), }, {}); - areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", SCENE_INSIDE_GANONS_CASTLE, { - //Events - EventAccess(&logic->ForestTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}), - }, { + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM] = Region("Ganon's Castle Forest Trial Wolfos Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS)), - LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))), - LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))), - }, {}); + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM, []{return Here(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)));});}), + }); - areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Region("Ganon's Castle Fire Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_START] = Region("Ganon's Castle Forest Trial Beamos Room Start", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->FireTrialClear, []{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}), + EventAccess(&logic->ForestTrialSilverRupees, []{return true;}), + }, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM, []{return true;}), + }); + + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Forest Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_START, []{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), + // reaching this as child would fit into an unintuitive jumps trick + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, []{return logic->IsAdult && logic->ForestTrialSilverRupees;}), + }); + + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Forest Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->ForestTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, logic->CanUse(RG_GORON_TUNIC)), - }, {}); + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM, []{return true;}), + }); - areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM] = Region("Ganon's Castle Fire Trial Main Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->BlueFireAccess, []{return true;}), - EventAccess(&logic->FairyPot, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);}), - EventAccess(&logic->WaterTrialClear, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(&logic->FireTrialSilverRupees, []{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT);}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, logic->CanUse(RG_GORON_TUNIC)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM_END, []{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_LONGSHOT);}), + }); + + areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM_END] = Region("Ganon's Castle Fire Trial Main Room End", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM, []{return logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM, []{return logic->FireTrialSilverRupees;}), + }); + + areaTable[RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Fire Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->FireTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + //There's no way back across the lava without glitches + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM, []{return true;}), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM] = Region("Ganon's Castle Water Trial Blue Fire Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->BlueFireAccess, []{return logic->CanJumpslash() || logic->HasExplosives();}), + EventAccess(&logic->WaterTrialBlueFireRoomCleared, []{return logic->CanKillEnemy(RE_FREEZARD);}), }, { //Locations LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_2, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots() && logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD)), - }, {}); + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM_END, []{return Here(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return logic->BlueFire();});}), + }); - areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Region("Ganon's Castle Shadow Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM_END] = Region("Ganon's Castle Water Trial Blue Fire Room End", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) || Here(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM_END, []{return logic->BlueFire();});}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return logic->WaterTrialBlueFireRoomCleared;}), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))));}), + EventAccess(&logic->FairyPot, []{return true;}), + EventAccess(&logic->WaterTrialRustedSwitch, []{return logic->IsAdult && (ctx->GetTrickOption(RT_RUSTED_SWITCHES) || logic->BlueFire()) && logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, logic->CanBreakPots() && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))))), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots() && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))))), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG))), - }, {}); + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END, []{return logic->IsAdult;}), + }); - areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END] = Region("Ganon's Castle Water Trial Block Room End", SCENE_INSIDE_GANONS_CASTLE, {}, {}, { + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM, []{return logic->WaterTrialRustedSwitch;}), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Water Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->NutPot, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), - EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), + EventAccess(&logic->WaterTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_BOMBCHU_5))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), - }, {}); + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return true;}), + }); - areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_START] = Region("Ganon's Castle Shadow Trial Start", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_POTS_PLATFORM, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT);}), + // shortcut for longshot to torch, dins, longshot to like like, run to chest platform + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM, []{return logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_LONGSHOT);}), + }); + + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_POTS_PLATFORM] = Region("Ganon's Castle Shadow Pots Platform", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_START, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (logic->ShadowTrialLowerSwitch && logic->CanUse(RG_HOOKSHOT));}), + }); + + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM] = Region("Ganon's Castle Shadow Chest Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->LightTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), + EventAccess(&logic->ShadowTrialRustedSwitch, []{return (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->ShadowTrialLowerSwitch), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_BOOMERANG)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_POTS_PLATFORM, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_LOWER_SWITCH, []{return logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_END, []{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}), + }); + + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_LOWER_SWITCH] = Region("Ganon's Castle Shadow Trial Lower Switch", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->ShadowTrialLowerSwitch, []{return true;}), + }, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->ShadowTrialLowerSwitch && logic->CanUse(RG_LONGSHOT));}), + }); + + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_END] = Region("Ganon's Castle Shadow Trial End", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM, []{return (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasFireSource()) || (logic->ShadowTrialLowerSwitch && logic->CanUse(RG_LONGSHOT));}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_POTS_PLATFORM, []{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_LOWER_SWITCH, []{return logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_FINAL_ROOM, []{return logic->ShadowTrialRustedSwitch;}), + }); + + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Shadow Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->ShadowTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_END, []{return true;}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle Spirit Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + // trick possible as child, but would not be novice trick + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, []{return Here(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash());});}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH] = Region("Ganon's Castle Spirit Trial Before Switch", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->SpiritTrialSwitch, []{return logic->CanUse(RG_BOMBCHU_5);}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanJumpslash() || logic->HasExplosives()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH, []{return logic->SpiritTrialSwitch;}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH] = Region("Ganon's Castle Spirit Trial After Switch", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->SpiritTrialSwitch, []{return logic->CanHitSwitch();}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->SpiritTrialSwitch), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, []{return logic->CanHitSwitch();}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_FINAL_ROOM, []{return Here(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_AFTER_SWITCH, []{return (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_MIRROR_SHIELD));}) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Spirit Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + EventAccess(&logic->NutPot, []{return true;}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH, []{return true;}), + }); + + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM] = Region("Ganon's Castle Light Trial Chests Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage()), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage()), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage()), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_GANONS_CASTLE, 1)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_GANONS_CASTLE, 2)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), - }, {}); + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_BIG_SKULLTULA) && logic->CanKillEnemy(RE_KEESE)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 1);}), + }); + + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM] = Region("Ganon's Castle Light Trial Triforce Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 1);}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + }); + + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM] = Region("Ganon's Castle Light Trial Boulder Room", SCENE_INSIDE_GANONS_CASTLE, {}, { + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots()), + }, { + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM, []{return logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, []{return Here(RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, []{return logic->CanUse(RG_HOOKSHOT);});}), + }); + + areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Light Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->LightTrialClear, []{return (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_LIGHT_ARROWS);}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, []{return true;}), + }); #pragma endregion @@ -231,7 +432,10 @@ void RegionTable_Init_GanonsCastle() { //Locations LOCATION(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, logic->CanBreakPots()), LOCATION(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, logic->CanBreakPots()), - }, {}); + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MQ_FIRE_TRIAL_MAIN_ROOM, []{return true;}), + }); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM] = Region("Ganon's Castle MQ Water Trial Geyser Room", SCENE_INSIDE_GANONS_CASTLE, { //Events @@ -267,19 +471,19 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE] = Region("Ganon's Castle MQ Shadow Trial Starting Ledge", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(&logic->MQShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), }, {}, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return true;}), - Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return (logic->ShadowTrialFirstChest && logic->CanUse(RG_HOOKSHOT)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return (logic->MQShadowTrialFirstChest && logic->CanUse(RG_HOOKSHOT)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}), }); areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM] = Region("Ganon's Castle MQ Shadow Trial Chest Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), + EventAccess(&logic->MQShadowTrialFirstChest, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->ShadowTrialFirstChest), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->MQShadowTrialFirstChest), }, { //Exits //Hookshot here is possible but very tight, but it's basically never relevant @@ -290,7 +494,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_MOVING_PLATFORM] = Region("Ganon's Castle MQ Shadow Trial Moving Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events //A torch run from RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE is possible but tight, so would be a trick - EventAccess(&logic->ShadowTrialFirstChest, []{return logic->CanDetonateUprightBombFlower();}), + EventAccess(&logic->MQShadowTrialFirstChest, []{return logic->CanDetonateUprightBombFlower();}), }, {}, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_CHEST_PLATFORM, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}), @@ -415,7 +619,10 @@ void RegionTable_Init_GanonsCastle() { //Locations LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, logic->CanBreakPots()), LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, logic->CanBreakPots()), - }, {}); + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, []{return logic->SmallKeys(RR_GANONS_CASTLE, 3);}), + }); #pragma endregion @@ -425,8 +632,7 @@ void RegionTable_Init_GanonsCastle() { //Exits Entrance(RR_GANONS_CASTLE_LOBBY, []{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}), Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}), - //RANDOTODO could we just set these events automatically based on the setting? - Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + Entrance(RR_GANONS_TOWER_STAIRS_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && @@ -434,10 +640,22 @@ void RegionTable_Init_GanonsCastle() { (logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}), }); + areaTable[RR_GANONS_TOWER_STAIRS_1] = Region("Ganon's Tower Stairs 1", SCENE_GANONS_TOWER, {}, {}, { + //Exits + Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return true;}), + Entrance(RR_GANONS_TOWER_FLOOR_1, []{return true;}), + }); + areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", SCENE_GANONS_TOWER, {}, {}, { //Exits - Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_GANONS_TOWER_FLOOR_2, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_1, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_2, []{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}), + }); + + areaTable[RR_GANONS_TOWER_STAIRS_2] = Region("Ganon's Tower Stairs 1", SCENE_GANONS_TOWER, {}, {}, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_1, []{return true;}), + Entrance(RR_GANONS_TOWER_FLOOR_2, []{return true;}), }); areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", SCENE_GANONS_TOWER, {}, { @@ -445,14 +663,26 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), }, { //Exits - Entrance(RR_GANONS_TOWER_FLOOR_1, []{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), - Entrance(RR_GANONS_TOWER_FLOOR_3, []{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_2, []{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_3, []{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), + }); + + areaTable[RR_GANONS_TOWER_STAIRS_3] = Region("Ganon's Tower Stairs 1", SCENE_GANONS_TOWER, {}, {}, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_2, []{return true;}), + Entrance(RR_GANONS_TOWER_FLOOR_3, []{return true;}), }); areaTable[RR_GANONS_TOWER_FLOOR_3] = Region("Ganon's Tower Floor 3", SCENE_GANONS_TOWER, {}, {}, { //Exits - Entrance(RR_GANONS_TOWER_FLOOR_2, []{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}), - Entrance(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_3, []{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}), + Entrance(RR_GANONS_TOWER_STAIRS_4, []{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}), + }); + + areaTable[RR_GANONS_TOWER_STAIRS_4] = Region("Ganon's Tower Stairs 1", SCENE_GANONS_TOWER, {}, {}, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_3, []{return true;}), + Entrance(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return true;}), }); areaTable[RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR] = Region("Ganon's Tower Before Ganondorf's Lair", SCENE_GANONS_TOWER, {}, { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3c0c8345e..447de3fc7 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2509,7 +2509,13 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { ForestCanTwistHallway = false; ForestClearBelowBowChest = false; ForestOpenBossCorridor = false; - ShadowTrialFirstChest = false; + ForestTrialSilverRupees = false; + WaterTrialBlueFireRoomCleared = false; + WaterTrialRustedSwitch = false; + SpiritTrialSwitch = false; + ShadowTrialRustedSwitch = false; + ShadowTrialLowerSwitch = false; + MQShadowTrialFirstChest = false; MQGTGMazeSwitch = false; MQGTGRightSideSwitch = false; GTGPlatformSilverRupees = false; @@ -2531,6 +2537,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { MQSpirit3SunsEnemies = false; Spirit1FSilverRupees = false; JabuRutoIn1F = false; + FireTrialSilverRupees = false; CalculatingAvailableChecks = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 2bfea75e9..603ec339f 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -158,7 +158,13 @@ class Logic { bool ForestCanTwistHallway = false; bool ForestClearBelowBowChest = false; // a better name that covers both versions would be nice bool ForestOpenBossCorridor = false; - bool ShadowTrialFirstChest = false; + bool ForestTrialSilverRupees = false; + bool WaterTrialBlueFireRoomCleared = false; + bool WaterTrialRustedSwitch = false; + bool SpiritTrialSwitch = false; + bool ShadowTrialRustedSwitch = false; + bool ShadowTrialLowerSwitch = false; + bool MQShadowTrialFirstChest = false; bool MQGTGMazeSwitch = false; bool MQGTGRightSideSwitch = false; bool GTGPlatformSilverRupees = false; @@ -181,6 +187,7 @@ class Logic { bool MQSpirit3SunsEnemies = false; bool Spirit1FSilverRupees = false; bool JabuRutoIn1F = false; + bool FireTrialSilverRupees = false; /* --- END OF HELPERS AND LOCATION ACCESS --- */ diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..13ea5d9eb 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1034,12 +1034,32 @@ typedef enum { RR_GANONS_CASTLE_LOBBY, RR_GANONS_CASTLE_MAIN, RR_GANONS_CASTLE_DEKU_SCRUBS, - RR_GANONS_CASTLE_FOREST_TRIAL, - RR_GANONS_CASTLE_FIRE_TRIAL, - RR_GANONS_CASTLE_WATER_TRIAL, - RR_GANONS_CASTLE_SHADOW_TRIAL, - RR_GANONS_CASTLE_SPIRIT_TRIAL, - RR_GANONS_CASTLE_LIGHT_TRIAL, + RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, + RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM_START, + RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM, + RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM, + RR_GANONS_CASTLE_FIRE_TRIAL_MAIN_ROOM_END, + RR_GANONS_CASTLE_FIRE_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, + RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM_END, + RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, + RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END, + RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_SHADOW_TRIAL_START, + RR_GANONS_CASTLE_SHADOW_TRIAL_POTS_PLATFORM, + RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM, + RR_GANONS_CASTLE_SHADOW_TRIAL_LOWER_SWITCH, + RR_GANONS_CASTLE_SHADOW_TRIAL_END, + RR_GANONS_CASTLE_SHADOW_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, + RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, + RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH, + RR_GANONS_CASTLE_SPIRIT_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM, + RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM, + RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, + RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, RR_GANONS_CASTLE_MQ_LOBBY, RR_GANONS_CASTLE_MQ_MAIN, @@ -1069,9 +1089,13 @@ typedef enum { RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, RR_GANONS_TOWER_ENTRYWAY, + RR_GANONS_TOWER_STAIRS_1, RR_GANONS_TOWER_FLOOR_1, + RR_GANONS_TOWER_STAIRS_2, RR_GANONS_TOWER_FLOOR_2, + RR_GANONS_TOWER_STAIRS_3, RR_GANONS_TOWER_FLOOR_3, + RR_GANONS_TOWER_STAIRS_4, RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, RR_GANONS_TOWER_GANONDORF_LAIR, RR_GANONS_CASTLE_ESCAPE, @@ -3751,7 +3775,6 @@ typedef enum { RT_OCARINA_ITEMS_BOMB, RT_OCARINA_ITEMS_ESS, RT_OCARINA_ITEMS_PUTAWAY, - RT_ONE_WAY_CLIPS, RT_QUICKDRAW, RT_QUICK_PUTAWAY, RT_SEEMWALK, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..96d5764e5 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -382,7 +382,8 @@ void Settings::CreateOptions() { "Tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle."); OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Hammer Rusted Switches Through Walls", - "Applies to:\n- Fire Temple Highest Goron Chest.\n- MQ Fire Temple Lizalfos Maze.\n- MQ Spirit Trial."); + "Applies to:\n- Fire Temple Highest Goron Chest.\n- Water Trial\n- MQ Fire Temple Lizalfos Maze.\n- MQ " + "Spirit Trial."); OPT_TRICK(RT_FLAMING_CHESTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Flaming Chests", "The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running " "into the flames while Link is invincible after taking damage."); @@ -1131,7 +1132,7 @@ void Settings::CreateOptions() { "Removes the requirements for the Lens of Truth in Ganon's Castle."); OPT_TRICK(RT_GANON_SPIRIT_TRIAL_HOOKSHOT, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "Spirit Trial without Hookshot", - "The highest rupee can be obtained as either age by performing a precise jump and a well-timed jumpslash " + "The highest rupee can be obtained as adult by performing a precise jump and a well-timed jumpslash " "off of an Armos."); OPT_TRICK(RT_LENS_GANON_MQ, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, "Ganon\'s Castle MQ without Lens of Truth",