From 8ff130cc5bb4667104a114fc00ec21fa55d73f8b Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Mon, 26 May 2025 20:07:52 +0200 Subject: [PATCH] Fix pseudo regions --- .../randomizer/location_access.cpp | 58 ++++++++++--------- .../Enhancements/randomizer/location_access.h | 6 +- .../overworld/castle_grounds.cpp | 2 +- .../location_access/overworld/lake_hylia.cpp | 16 ++++- .../location_access/overworld/lost_woods.cpp | 2 +- .../overworld/zoras_domain.cpp | 2 +- .../location_access/overworld/zoras_river.cpp | 6 ++ .../Enhancements/randomizer/randomizerTypes.h | 3 + 8 files changed, 62 insertions(+), 33 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index c981ed21c..5ba160d12 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -222,22 +222,7 @@ std::set CalculateAreas(SceneID scene) { } } -Region::Region() = default; -Region::Region(std::string regionName_, SceneID scene_, std::set areas, - std::vector events_, std::vector locations_, - std::list exits_) - : regionName(std::move(regionName_)), scene(scene_), areas(areas), events(std::move(events_)), - locations(std::move(locations_)), exits(std::move(exits_)) { -} -Region::Region(std::string regionName_, SceneID scene_, std::vector events_, - std::vector locations_, std::list exits_) - : regionName(std::move(regionName_)), scene(scene_), areas(CalculateAreas(scene_)), events(std::move(events_)), - locations(std::move(locations_)), exits(std::move(exits_)) { -} - -Region::~Region() = default; - -bool Region::TimePass() { +bool GetTimePassFromScene(SceneID scene) { switch (scene) { case SCENE_DEKU_TREE: case SCENE_DODONGOS_CAVERN: @@ -365,6 +350,25 @@ bool Region::TimePass() { } } +Region::Region() = default; +Region::Region(std::string regionName_, SceneID scene_, bool timePass_, std::set areas, + std::vector events_, std::vector locations_, + std::list exits_) + : regionName(std::move(regionName_)), scene(scene_), timePass(timePass_), areas(areas), events(std::move(events_)), + locations(std::move(locations_)), exits(std::move(exits_)) { +} +Region::Region(std::string regionName_, SceneID scene_, std::vector events_, + std::vector locations_, std::list exits_) + : regionName(std::move(regionName_)), scene(scene_), timePass(GetTimePassFromScene(scene_)), areas(CalculateAreas(scene_)), events(std::move(events_)), + locations(std::move(locations_)), exits(std::move(exits_)) { +} + +Region::~Region() = default; + +bool Region::TimePass() { + return timePass; +} + void Region::ApplyTimePass() { if (TimePass()) { StartPerformanceTimer(PT_TOD_ACCESS); @@ -606,10 +610,10 @@ void RegionTable_Init() { }; // Clear the array from any previous playthrough attempts. This is important so that // locations which appear in both MQ and Vanilla dungeons don't get set in both areas. - areaTable.fill(Region("Invalid Region", SCENE_ID_MAX, {}, {}, {}, {})); + areaTable.fill(Region("Invalid Region", SCENE_ID_MAX, {}, {}, {})); // clang-format off - areaTable[RR_ROOT] = Region("Root", SCENE_ID_MAX, {RA_LINKS_POCKET}, { + areaTable[RR_ROOT] = Region("Root", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, { //Events EventAccess(&logic->KakarikoVillageGateOpen, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}), //The big poes bottle softlock safety check does not account for the guard house lock if the guard house is not shuffled, so the key is needed before we can safely allow bottle use in logic @@ -625,7 +629,7 @@ void RegionTable_Init() { Entrance(RR_ROOT_EXITS, []{return true;}), }); - areaTable[RR_ROOT_EXITS] = Region("Root Exits", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_ROOT_EXITS] = Region("Root Exits", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_CHILD_SPAWN, []{return logic->IsChild;}), Entrance(RR_ADULT_SPAWN, []{return logic->IsAdult;}), @@ -637,42 +641,42 @@ void RegionTable_Init() { Entrance(RR_PRELUDE_OF_LIGHT_WARP, []{return logic->CanUse(RG_PRELUDE_OF_LIGHT) && logic->CanLeaveForest();}), }); - areaTable[RR_CHILD_SPAWN] = Region("Child Spawn", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_CHILD_SPAWN] = Region("Child Spawn", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_KF_LINKS_HOUSE, []{return true;}), }); - areaTable[RR_ADULT_SPAWN] = Region("Adult Spawn", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_ADULT_SPAWN] = Region("Adult Spawn", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_TEMPLE_OF_TIME, []{return true;}), }); - areaTable[RR_MINUET_OF_FOREST_WARP] = Region("Minuet of Forest Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_MINUET_OF_FOREST_WARP] = Region("Minuet of Forest Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_SACRED_FOREST_MEADOW, []{return true;}), }); - areaTable[RR_BOLERO_OF_FIRE_WARP] = Region("Bolero of Fire Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_BOLERO_OF_FIRE_WARP] = Region("Bolero of Fire Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_DMC_CENTRAL_LOCAL, []{return true;}), }); - areaTable[RR_SERENADE_OF_WATER_WARP] = Region("Serenade of Water Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_SERENADE_OF_WATER_WARP] = Region("Serenade of Water Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, []{return true;}), }); - areaTable[RR_REQUIEM_OF_SPIRIT_WARP] = Region("Requiem of Spirit Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_REQUIEM_OF_SPIRIT_WARP] = Region("Requiem of Spirit Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_DESERT_COLOSSUS, []{return true;}), }); - areaTable[RR_NOCTURNE_OF_SHADOW_WARP] = Region("Nocturne of Shadow Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_NOCTURNE_OF_SHADOW_WARP] = Region("Nocturne of Shadow Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return true;}), }); - areaTable[RR_PRELUDE_OF_LIGHT_WARP] = Region("Prelude of Light Warp", SCENE_ID_MAX, {RA_LINKS_POCKET}, {}, {}, { + areaTable[RR_PRELUDE_OF_LIGHT_WARP] = Region("Prelude of Light Warp", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, { //Exits Entrance(RR_TEMPLE_OF_TIME, []{return true;}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index f072d64aa..1e8870836 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -9,6 +9,9 @@ #include "soh/Enhancements/randomizer/context.h" #include "soh/Enhancements/randomizer/logic.h" +#define TIME_PASSES true +#define TIME_DOESNT_PASS false + typedef bool (*ConditionFn)(); // I hate this but every alternative I can think of right now is worse @@ -113,7 +116,7 @@ enum class EntranceType; class Region { public: Region(); - Region(std::string regionName_, SceneID scene_, std::set areas, std::vector events_, + Region(std::string regionName_, SceneID scene_, bool timePass, std::set areas, std::vector events_, std::vector locations_, std::list exits_); Region(std::string regionName_, SceneID scene_, std::vector events_, std::vector locations_, std::list exits_); @@ -121,6 +124,7 @@ class Region { std::string regionName; SceneID scene; + bool timePass; std::set areas; std::vector events; std::vector locations; diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index a620e8036..02c1bdfae 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -9,7 +9,7 @@ void RegionTable_Init_CastleGrounds() { //{RA_HYRULE_CASTLE} and {RA_OUTSIDE_GANONS_CASTLE}, but a setting to merge the latter 2 into the former may be preferred // //Temporarily uses SCENE_OUTSIDE_GANONS_CASTLE to avoid self connection between ages - areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", SCENE_OUTSIDE_GANONS_CASTLE, {RA_CASTLE_GROUNDS}, {}, {}, { + areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", SCENE_OUTSIDE_GANONS_CASTLE, TIME_DOESNT_PASS, {RA_CASTLE_GROUNDS}, {}, {}, { //Exits Entrance(RR_THE_MARKET, []{return true;}), Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return logic->IsChild;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index b29d550c7..72014db09 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -84,14 +84,26 @@ void RegionTable_Init_LakeHylia() { }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), - Entrance(RR_ZORAS_DOMAIN, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), - Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), + Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), Entrance(RR_LH_GROTTO, []{return true;}), }); + areaTable[RR_LH_FROM_SHORTCUT] = Region("LH From Shortcut", SCENE_LAKE_HYLIA, TIME_DOESNT_PASS, {RA_LAKE_HYLIA}, {}, {}, { + //Exits + Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_ZORAS_DOMAIN, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), + }); + + areaTable[RR_LH_FROM_WATER_TEMPLE] = Region("LH From Water Temple", SCENE_LAKE_HYLIA, TIME_DOESNT_PASS, {RA_LAKE_HYLIA}, {}, {}, { + //Exits + Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), + }); + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index dc354b7bc..65f30f4f6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -57,7 +57,7 @@ void RegionTable_Init_LostWoods() { Entrance(RR_LW_FOREST_EXIT, []{return true;}), Entrance(RR_GC_WOODS_WARP, []{return true;}), Entrance(RR_LW_BRIDGE, []{return logic->CanLeaveForest() && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}), - Entrance(RR_ZORAS_RIVER, []{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}), Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 521fc2ed4..3da563c1c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -38,7 +38,7 @@ void RegionTable_Init_ZorasDomain() { }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), - Entrance(RR_LAKE_HYLIA, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), + Entrance(RR_LH_FROM_SHORTCUT, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), Entrance(RR_ZD_BEHIND_KING_ZORA, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}), Entrance(RR_ZD_SHOP, []{return logic->IsChild || logic->BlueFire();}), Entrance(RR_ZORAS_DOMAIN_ISLAND, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 82e62b73d..e2f8bd540 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -71,6 +71,12 @@ void RegionTable_Init_ZoraRiver() { Entrance(RR_ZR_BEHIND_WATERFALL, []{return ctx->GetOption(RSK_SLEEPING_WATERFALL).Is(RO_WATERFALL_OPEN) || Here(RR_ZORAS_RIVER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}) || (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));}), }); + areaTable[RR_ZR_FROM_SHORTCUT] = Region("ZR From Shortcut", SCENE_ZORAS_RIVER, TIME_DOESNT_PASS, {RA_ZORAS_RIVER}, {}, {}, { + //Exits + Entrance(RR_ZORAS_RIVER, []{return logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_THE_LOST_WOODS, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), + }); + areaTable[RR_ZR_BEHIND_WATERFALL] = Region("ZR Behind Waterfall", SCENE_ZORAS_RIVER, {}, {}, { //Exits Entrance(RR_ZORAS_RIVER, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index ce074bf4c..b221cd9f5 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -394,6 +394,8 @@ typedef enum { RR_HF_NEAR_KAK_GROTTO, RR_HF_TEKTITE_GROTTO, RR_LAKE_HYLIA, + RR_LH_FROM_SHORTCUT, + RR_LH_FROM_WATER_TEMPLE, RR_LH_FISHING_ISLAND, RR_LH_OWL_FLIGHT, RR_LH_LAB, @@ -499,6 +501,7 @@ typedef enum { RR_DMC_DISTANT_PLATFORM, RR_ZR_FRONT, RR_ZORAS_RIVER, + RR_ZR_FROM_SHORTCUT, RR_ZR_BEHIND_WATERFALL, RR_ZR_OPEN_GROTTO, RR_ZR_FAIRY_GROTTO,