From 7d70cc5ec64873181e319de6fb5f9b801f82bb72 Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Thu, 10 Jul 2025 05:55:10 +0000 Subject: [PATCH 1/4] midnight wip, only up to water trial implementing Pepper0ni's feedback from dungeon refactor PR --- .../dungeons/ganons_castle.cpp | 301 ++++++++++++++---- soh/soh/Enhancements/randomizer/logic.cpp | 1 + soh/soh/Enhancements/randomizer/logic.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 30 +- 4 files changed, 260 insertions(+), 73 deletions(-) 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..ec80cb23a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -17,19 +17,24 @@ 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_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_MAIN_ROOM, []{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);}), }); @@ -52,74 +57,179 @@ 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, {}, {}, { + //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);}), + // reaching this as child would fit into an unintuitive jumps trick + // also getting silver rupees as child without hookshot requires voiding to start, which won't work in reverse + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, []{return logic->IsAdult;}), + }); + + areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Forest Trial Final Room", 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->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();}), }, { //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)), - }, {}); - - areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Region("Ganon's Castle Shadow Trial", 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))))));}), }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return Here(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);});}), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM] = Region("Ganon's Castle Water Trial Block Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->FairyPot, []{return true;}), + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots() && logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM, []{return logic->IsAdult && logic->BlueFire() && logic->CanUse(RG_MEGATON_HAMMER);}), + }); + + areaTable[RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Water Trial Final Room", SCENE_INSIDE_GANONS_CASTLE, { + //Events + EventAccess(&logic->WaterTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS);}), + }, { + //Locations + 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_SHADOW_TRIAL_MAIN_ROOM] = Region("Ganon's Castle Shadow Trial Main Room", 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), 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))), - }, {}); + }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_FINAL_ROOM, []{return 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))))));}), + }); - areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", SCENE_INSIDE_GANONS_CASTLE, { + areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_FINAL_ROOM] = Region("Ganon's Castle Shadow 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->ShadowTrialClear, []{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_SHADOW_TRIAL_POT_3, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_MAIN_ROOM, []{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), - }, {}); - - areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", 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));}), }, { + //Exits + Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, []{return ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH] = Region("Ganon's Castle Spirit Trial Before Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanJumpslashExceptHammer()), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return true;}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH, []{return logic->CanUse(RG_BOMBCHU_5);}), + }); + + areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH] = Region("Ganon's Castle Spirit Trial After Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { + //Locations + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanHitSwitch()), + 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 true;}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_FINAL_ROOM, []{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, true), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, true), @@ -128,11 +238,39 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), 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))), - }, {}); + }, { + //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 true;}), + 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 true;}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + }); + + 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 logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + }); #pragma endregion @@ -231,7 +369,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 @@ -415,7 +556,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 +569,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 +577,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 +600,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, {}, { @@ -481,7 +648,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_TOWER_GANONDORF_LAIR, []{return Here(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY);});}), }); - areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONDORF_BOSS, {}, { + areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONS_TOWER, {}, { //Locations LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), }, { @@ -489,7 +656,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_ESCAPE, []{return logic->CanKillEnemy(RE_GANONDORF);}), }); - areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, {}, { + areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", SCENE_GANONS_TOWER, {}, { //Locations //10 pots //RANDOTODO hook potsanity pots up to escape. @@ -501,7 +668,7 @@ void RegionTable_Init_GanonsCastle() { //Entrance(RR_GANONS_CASTLE_GANON_ARENA, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}), }); - areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", SCENE_GANON_BOSS, {}, { + areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", SCENE_GANONS_TOWER, {}, { //Locations LOCATION(RC_GANON, logic->CanKillEnemy(RE_GANON)), }, {}); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..6a7932adc 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2530,6 +2530,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..921a6dfaa 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -181,6 +181,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..3bed6979d 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1034,12 +1034,26 @@ 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_BLOCK_ROOM, + RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM, + RR_GANONS_CASTLE_SHADOW_TRIAL_MAIN_ROOM, + 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 +1083,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, From 003edd2c7a130df53c77c84991422e1634034a6c Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Fri, 11 Jul 2025 04:10:58 +0000 Subject: [PATCH 2/4] deblob shadow trial --- .../dungeons/ganons_castle.cpp | 112 ++++++++++++------ soh/soh/Enhancements/randomizer/logic.cpp | 4 +- soh/soh/Enhancements/randomizer/logic.h | 4 +- .../Enhancements/randomizer/randomizerTypes.h | 6 +- 4 files changed, 89 insertions(+), 37 deletions(-) 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 ec80cb23a..6776c4131 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -27,15 +27,15 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_SHEIK_HINT_GC, true), }, { //Exits - 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_MAIN_ROOM, []{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);}), + 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, { @@ -160,19 +160,63 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return true;}), }); - areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_MAIN_ROOM] = Region("Ganon's Castle Shadow Trial Main Room", 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), - 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_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_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_FINAL_ROOM, []{return 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))))));}), + 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->ShadowTrialRustedSwitch, []{return (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_MEGATON_HAMMER);}), + }, { + //Locations + 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_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->HasFireSource())), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, 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_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)))));}), + 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, { @@ -184,22 +228,22 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots()), }, { //Exits - Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL_MAIN_ROOM, []{return true;}), + 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), + 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;}), - Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, []{return ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT);}), + 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, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanJumpslash() || logic->HasExplosives()), }, { //Exits Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return true;}), @@ -237,7 +281,7 @@ void RegionTable_Init_GanonsCastle() { 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_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_INVISIBLE_ENEMIES_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_BIG_SKULLTULA)), }, { //Exits Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), @@ -249,15 +293,15 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM, []{return true;}), + 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 true;}), - Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_FINAL_ROOM, []{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + 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, { @@ -269,7 +313,7 @@ void RegionTable_Init_GanonsCastle() { 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 logic->SmallKeys(RR_GANONS_CASTLE, 2);}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_ROOM, []{return true;}), }); #pragma endregion @@ -408,19 +452,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 @@ -431,7 +475,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);}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 6a7932adc..9d53d9112 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2508,7 +2508,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { ForestCanTwistHallway = false; ForestClearBelowBowChest = false; ForestOpenBossCorridor = false; - ShadowTrialFirstChest = false; + ShadowTrialRustedSwitch = false; + ShadowTrialLowerSwitch = false; + MQShadowTrialFirstChest = false; MQGTGMazeSwitch = false; MQGTGRightSideSwitch = false; GTGPlatformSilverRupees = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 921a6dfaa..d494ea4d1 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -158,7 +158,9 @@ 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 ShadowTrialRustedSwitch = false; + bool ShadowTrialLowerSwitch = false; + bool MQShadowTrialFirstChest = false; bool MQGTGMazeSwitch = false; bool MQGTGRightSideSwitch = false; bool GTGPlatformSilverRupees = false; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 3bed6979d..c1249b842 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1044,7 +1044,11 @@ typedef enum { RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, RR_GANONS_CASTLE_WATER_TRIAL_FINAL_ROOM, - RR_GANONS_CASTLE_SHADOW_TRIAL_MAIN_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, From c89a5c7dba03cb617bc4481f003699cdbd4f56ff Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sat, 12 Jul 2025 00:55:33 +0000 Subject: [PATCH 3/4] feedback --- .../dungeons/ganons_castle.cpp | 77 ++++++++++++------- soh/soh/Enhancements/randomizer/logic.cpp | 4 + soh/soh/Enhancements/randomizer/logic.h | 4 + .../Enhancements/randomizer/randomizerTypes.h | 3 +- soh/soh/Enhancements/randomizer/settings.cpp | 3 +- 5 files changed, 60 insertions(+), 31 deletions(-) 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 6776c4131..161f7622f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -66,7 +66,10 @@ void RegionTable_Init_GanonsCastle() { 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_FOREST_TRIAL_BEAMOS_ROOM_START] = Region("Ganon's Castle Forest Trial Beamos Room Start", 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->ForestTrialSilverRupees, []{return true;}), + }, {}, { //Exits Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM, []{return true;}), Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_BEAMOS_ROOM, []{return true;}), @@ -74,10 +77,9 @@ void RegionTable_Init_GanonsCastle() { 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);}), + 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 - // also getting silver rupees as child without hookshot requires voiding to start, which won't work in reverse - Entrance(RR_GANONS_CASTLE_FOREST_TRIAL_FINAL_ROOM, []{return logic->IsAdult;}), + 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, { @@ -125,27 +127,39 @@ void RegionTable_Init_GanonsCastle() { 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->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), }, { //Exits - Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), - Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM, []{return Here(RR_GANONS_CASTLE_WATER_TRIAL_BLUE_FIRE_ROOM, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);});}), + 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_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->FairyPot, []{return true;}), + 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_WATER_TRIAL_POT_3, logic->CanBreakPots() && logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD)), + 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_FINAL_ROOM, []{return logic->IsAdult && logic->BlueFire() && logic->CanUse(RG_MEGATON_HAMMER);}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL_BLOCK_ROOM_END, []{return logic->IsAdult;}), + }); + + 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, { @@ -183,7 +197,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_CHEST_PLATFORM] = Region("Ganon's Castle Shadow Chest Platform", SCENE_INSIDE_GANONS_CASTLE, { //Events - EventAccess(&logic->ShadowTrialRustedSwitch, []{return (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_MEGATON_HAMMER);}), + 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_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->ShadowTrialLowerSwitch), @@ -207,14 +221,12 @@ void RegionTable_Init_GanonsCastle() { 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_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->HasFireSource())), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, logic->CanUse(RG_BOOMERANG)), + 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_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)))));}), + 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;}), }); @@ -238,26 +250,33 @@ void RegionTable_Init_GanonsCastle() { }, { //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, {}, { + 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->CanUse(RG_BOMBCHU_5);}), + 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, {}, { + 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->CanHitSwitch()), + 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 true;}), - Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_FINAL_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}), + 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, { @@ -275,13 +294,13 @@ void RegionTable_Init_GanonsCastle() { 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, true), + 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)) && logic->CanKillEnemy(RE_BIG_SKULLTULA)), + 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;}), @@ -692,7 +711,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_TOWER_GANONDORF_LAIR, []{return Here(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY);});}), }); - areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONS_TOWER, {}, { + areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", SCENE_GANONDORF_BOSS, {}, { //Locations LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), }, { @@ -700,7 +719,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_ESCAPE, []{return logic->CanKillEnemy(RE_GANONDORF);}), }); - areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", SCENE_GANONS_TOWER, {}, { + areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, {}, { //Locations //10 pots //RANDOTODO hook potsanity pots up to escape. @@ -712,7 +731,7 @@ void RegionTable_Init_GanonsCastle() { //Entrance(RR_GANONS_CASTLE_GANON_ARENA, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}), }); - areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", SCENE_GANONS_TOWER, {}, { + areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", SCENE_GANON_BOSS, {}, { //Locations LOCATION(RC_GANON, logic->CanKillEnemy(RE_GANON)), }, {}); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 9d53d9112..369f8a7e3 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2508,6 +2508,10 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { ForestCanTwistHallway = false; ForestClearBelowBowChest = false; ForestOpenBossCorridor = false; + ForestTrialSilverRupees = false; + WaterTrialBlueFireRoomCleared = false; + WaterTrialRustedSwitch = false; + SpiritTrialSwitch = false; ShadowTrialRustedSwitch = false; ShadowTrialLowerSwitch = false; MQShadowTrialFirstChest = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index d494ea4d1..603ec339f 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -158,6 +158,10 @@ class Logic { bool ForestCanTwistHallway = false; bool ForestClearBelowBowChest = false; // a better name that covers both versions would be nice bool ForestOpenBossCorridor = false; + bool ForestTrialSilverRupees = false; + bool WaterTrialBlueFireRoomCleared = false; + bool WaterTrialRustedSwitch = false; + bool SpiritTrialSwitch = false; bool ShadowTrialRustedSwitch = false; bool ShadowTrialLowerSwitch = false; bool MQShadowTrialFirstChest = false; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c1249b842..13ea5d9eb 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -1042,7 +1042,9 @@ typedef enum { 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, @@ -3773,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..5cefc8682 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."); From 411b619a0c547a61af9f5f3c2a8daf3577c9650b Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 13 Jul 2025 10:54:48 +0000 Subject: [PATCH 4/4] update RT_GANON_SPIRIT_TRIAL_HOOKSHOT description --- soh/soh/Enhancements/randomizer/settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5cefc8682..96d5764e5 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1132,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",