Fix pseudo regions

This commit is contained in:
Pepe20129 2025-05-26 20:07:52 +02:00
commit 8ff130cc5b
8 changed files with 62 additions and 33 deletions

View file

@ -222,22 +222,7 @@ std::set<RandomizerArea> CalculateAreas(SceneID scene) {
}
}
Region::Region() = default;
Region::Region(std::string regionName_, SceneID scene_, std::set<RandomizerArea> areas,
std::vector<EventAccess> events_, std::vector<LocationAccess> locations_,
std::list<Rando::Entrance> 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<EventAccess> events_,
std::vector<LocationAccess> locations_, std::list<Rando::Entrance> 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<RandomizerArea> areas,
std::vector<EventAccess> events_, std::vector<LocationAccess> locations_,
std::list<Rando::Entrance> 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<EventAccess> events_,
std::vector<LocationAccess> locations_, std::list<Rando::Entrance> 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;}),
});

View file

@ -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<RandomizerArea> areas, std::vector<EventAccess> events_,
Region(std::string regionName_, SceneID scene_, bool timePass, std::set<RandomizerArea> areas, std::vector<EventAccess> events_,
std::vector<LocationAccess> locations_, std::list<Rando::Entrance> exits_);
Region(std::string regionName_, SceneID scene_, std::vector<EventAccess> events_,
std::vector<LocationAccess> locations_, std::list<Rando::Entrance> exits_);
@ -121,6 +124,7 @@ class Region {
std::string regionName;
SceneID scene;
bool timePass;
std::set<RandomizerArea> areas;
std::vector<EventAccess> events;
std::vector<LocationAccess> locations;

View file

@ -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;}),

View file

@ -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);}),

View file

@ -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();});}),
});

View file

@ -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;}),

View file

@ -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;}),

View file

@ -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,