diff --git a/BaseClasses.py b/BaseClasses.py index 36d0bc26..f4189453 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -110,10 +110,14 @@ class MultiWorld(): return self def append(self, region: Region): + assert region.name not in self.region_cache[region.player], \ + f"{region.name} already exists in region cache." self.region_cache[region.player][region.name] = region def extend(self, regions: Iterable[Region]): for region in regions: + assert region.name not in self.region_cache[region.player], \ + f"{region.name} already exists in region cache." self.region_cache[region.player][region.name] = region def add_group(self, new_id: int): @@ -877,6 +881,8 @@ class Region: del(self.region_manager.location_cache[location.player][location.name]) def insert(self, index: int, value: Location) -> None: + assert value.name not in self.region_manager.location_cache[value.player], \ + f"{value.name} already exists in the location cache." self._list.insert(index, value) self.region_manager.location_cache[value.player][value.name] = value @@ -887,6 +893,8 @@ class Region: del(self.region_manager.entrance_cache[entrance.player][entrance.name]) def insert(self, index: int, value: Entrance) -> None: + assert value.name not in self.region_manager.entrance_cache[value.player], \ + f"{value.name} already exists in the entrance cache." self._list.insert(index, value) self.region_manager.entrance_cache[value.player][value.name] = value diff --git a/test/general/test_helpers.py b/test/general/test_helpers.py index 83b56b34..be847397 100644 --- a/test/general/test_helpers.py +++ b/test/general/test_helpers.py @@ -29,8 +29,8 @@ class TestHelpers(unittest.TestCase): "event_loc": None, }, "TestRegion2": { - "loc_1": 321, - "loc_2": 654, + "loc_3": 321, + "loc_4": 654, } } diff --git a/worlds/mmbn3/__init__.py b/worlds/mmbn3/__init__.py index acf258a7..762bfd11 100644 --- a/worlds/mmbn3/__init__.py +++ b/worlds/mmbn3/__init__.py @@ -100,9 +100,7 @@ class MMBN3World(World): for region_info in regions: region = name_to_region[region_info.name] for connection in region_info.connections: - connection_region = name_to_region[connection] - entrance = Entrance(self.player, connection, region) - entrance.connect(connection_region) + entrance = region.connect(name_to_region[connection]) # ACDC Pending with Start Randomizer # if connection == RegionName.ACDC_Overworld: @@ -141,7 +139,6 @@ class MMBN3World(World): if connection == RegionName.WWW_Island: entrance.access_rule = lambda state:\ state.has(ItemName.Progressive_Undernet_Rank, self.player, 8) - region.exits.append(entrance) def create_items(self) -> None: # First add in all progression and useful items diff --git a/worlds/overcooked2/__init__.py b/worlds/overcooked2/__init__.py index 24ac175c..da0e1890 100644 --- a/worlds/overcooked2/__init__.py +++ b/worlds/overcooked2/__init__.py @@ -90,13 +90,7 @@ class Overcooked2World(World): def connect_regions(self, source: str, target: str, rule: Optional[Callable[[CollectionState], bool]] = None): sourceRegion = self.multiworld.get_region(source, self.player) targetRegion = self.multiworld.get_region(target, self.player) - - connection = Entrance(self.player, '', sourceRegion) - if rule: - connection.access_rule = rule - - sourceRegion.exits.append(connection) - connection.connect(targetRegion) + sourceRegion.connect(targetRegion, rule=rule) def add_level_location( self, diff --git a/worlds/ror2/regions.py b/worlds/ror2/regions.py index 13b229da..199fdccf 100644 --- a/worlds/ror2/regions.py +++ b/worlds/ror2/regions.py @@ -140,11 +140,7 @@ def create_explore_region(multiworld: MultiWorld, player: int, name: str, data: def create_connections_in_regions(multiworld: MultiWorld, player: int, name: str, data: RoRRegionData) -> None: region = multiworld.get_region(name, player) if data.region_exits: - for region_exit in data.region_exits: - r_exit_stage = Entrance(player, region_exit, region) - exit_region = multiworld.get_region(region_exit, player) - r_exit_stage.connect(exit_region) - region.exits.append(r_exit_stage) + region.add_exits(data.region_exits) def create_classic_regions(ror2_world: "RiskOfRainWorld") -> None: diff --git a/worlds/ror2/rules.py b/worlds/ror2/rules.py index 442e6c00..b4d5fe68 100644 --- a/worlds/ror2/rules.py +++ b/worlds/ror2/rules.py @@ -9,14 +9,16 @@ if TYPE_CHECKING: # Rule to see if it has access to the previous stage -def has_entrance_access_rule(multiworld: MultiWorld, stage: str, entrance: str, player: int) -> None: - multiworld.get_entrance(entrance, player).access_rule = \ - lambda state: state.has(entrance, player) and state.has(stage, player) +def has_entrance_access_rule(multiworld: MultiWorld, stage: str, region: str, player: int) -> None: + rule = lambda state: state.has(region, player) and state.has(stage, player) + for entrance in multiworld.get_region(region, player).entrances: + entrance.access_rule = rule -def has_all_items(multiworld: MultiWorld, items: Set[str], entrance: str, player: int) -> None: - multiworld.get_entrance(entrance, player).access_rule = \ - lambda state: state.has_all(items, player) and state.has(entrance, player) +def has_all_items(multiworld: MultiWorld, items: Set[str], region: str, player: int) -> None: + rule = lambda state: state.has_all(items, player) and state.has(region, player) + for entrance in multiworld.get_region(region, player).entrances: + entrance.access_rule = rule # Checks to see if chest/shrine are accessible @@ -45,8 +47,9 @@ def check_location(state, environment: str, player: int, item_number: int, item_ def get_stage_event(multiworld: MultiWorld, player: int, stage_number: int) -> None: if stage_number == 4: return - multiworld.get_entrance(f"OrderedStage_{stage_number + 1}", player).access_rule = \ - lambda state: state.has(f"Stage {stage_number + 1}", player) + rule = lambda state: state.has(f"Stage {stage_number + 1}", player) + for entrance in multiworld.get_region(f"OrderedStage_{stage_number + 1}", player).entrances: + entrance.access_rule = rule def set_rules(ror2_world: "RiskOfRainWorld") -> None: diff --git a/worlds/ror2/test/test_limbo_goal.py b/worlds/ror2/test/test_limbo_goal.py index f8757a91..9be9cca1 100644 --- a/worlds/ror2/test/test_limbo_goal.py +++ b/worlds/ror2/test/test_limbo_goal.py @@ -8,8 +8,8 @@ class LimboGoalTest(RoR2TestBase): def test_limbo(self) -> None: self.collect_all_but(["Hidden Realm: A Moment, Whole", "Victory"]) - self.assertFalse(self.can_reach_entrance("Hidden Realm: A Moment, Whole")) + self.assertFalse(self.can_reach_region("Hidden Realm: A Moment, Whole")) self.assertBeatable(False) self.collect_by_name("Hidden Realm: A Moment, Whole") - self.assertTrue(self.can_reach_entrance("Hidden Realm: A Moment, Whole")) + self.assertTrue(self.can_reach_region("Hidden Realm: A Moment, Whole")) self.assertBeatable(True) diff --git a/worlds/ror2/test/test_mithrix_goal.py b/worlds/ror2/test/test_mithrix_goal.py index 7ed9a2cd..03b82311 100644 --- a/worlds/ror2/test/test_mithrix_goal.py +++ b/worlds/ror2/test/test_mithrix_goal.py @@ -8,18 +8,18 @@ class MithrixGoalTest(RoR2TestBase): def test_mithrix(self) -> None: self.collect_all_but(["Commencement", "Victory"]) - self.assertFalse(self.can_reach_entrance("Commencement")) + self.assertFalse(self.can_reach_region("Commencement")) self.assertBeatable(False) self.collect_by_name("Commencement") - self.assertTrue(self.can_reach_entrance("Commencement")) + self.assertTrue(self.can_reach_region("Commencement")) self.assertBeatable(True) def test_stage5(self) -> None: self.collect_all_but(["Stage 4", "Sky Meadow", "Victory"]) - self.assertFalse(self.can_reach_entrance("Sky Meadow")) + self.assertFalse(self.can_reach_region("Sky Meadow")) self.assertBeatable(False) self.collect_by_name("Sky Meadow") - self.assertFalse(self.can_reach_entrance("Sky Meadow")) + self.assertFalse(self.can_reach_region("Sky Meadow")) self.collect_by_name("Stage 4") - self.assertTrue(self.can_reach_entrance("Sky Meadow")) + self.assertTrue(self.can_reach_region("Sky Meadow")) self.assertBeatable(True) diff --git a/worlds/ror2/test/test_voidling_goal.py b/worlds/ror2/test/test_voidling_goal.py index a7520a5c..77d1349f 100644 --- a/worlds/ror2/test/test_voidling_goal.py +++ b/worlds/ror2/test/test_voidling_goal.py @@ -9,17 +9,17 @@ class VoidlingGoalTest(RoR2TestBase): def test_planetarium(self) -> None: self.collect_all_but(["The Planetarium", "Victory"]) - self.assertFalse(self.can_reach_entrance("The Planetarium")) + self.assertFalse(self.can_reach_region("The Planetarium")) self.assertBeatable(False) self.collect_by_name("The Planetarium") - self.assertTrue(self.can_reach_entrance("The Planetarium")) + self.assertTrue(self.can_reach_region("The Planetarium")) self.assertBeatable(True) def test_void_locus_to_victory(self) -> None: self.collect_all_but(["Void Locus", "Commencement"]) self.assertFalse(self.can_reach_location("Victory")) self.collect_by_name("Void Locus") - self.assertTrue(self.can_reach_entrance("Victory")) + self.assertTrue(self.can_reach_location("Victory")) def test_commencement_to_victory(self) -> None: self.collect_all_but(["Void Locus", "Commencement"]) diff --git a/worlds/sm64ex/Regions.py b/worlds/sm64ex/Regions.py index c04b862f..8c2d32e4 100644 --- a/worlds/sm64ex/Regions.py +++ b/worlds/sm64ex/Regions.py @@ -200,7 +200,6 @@ def create_regions(world: MultiWorld, player: int): create_locs(thi_large_top, "THI: 100 Coins") regFloor3 = create_region("Third Floor", player, world) - world.regions.append(regFloor3) regTTC = create_region("Tick Tock Clock", player, world) create_locs(regTTC, "TTC: Stop Time for Red Coins") @@ -230,13 +229,7 @@ def create_regions(world: MultiWorld, player: int): def connect_regions(world: MultiWorld, player: int, source: str, target: str, rule=None): sourceRegion = world.get_region(source, player) targetRegion = world.get_region(target, player) - - connection = Entrance(player, '', sourceRegion) - if rule: - connection.access_rule = rule - - sourceRegion.exits.append(connection) - connection.connect(targetRegion) + sourceRegion.connect(targetRegion, rule=rule) def create_region(name: str, player: int, world: MultiWorld) -> Region: diff --git a/worlds/timespinner/Regions.py b/worlds/timespinner/Regions.py index fc753564..f80babc0 100644 --- a/worlds/timespinner/Regions.py +++ b/worlds/timespinner/Regions.py @@ -247,13 +247,7 @@ def connect(world: MultiWorld, player: int, source: str, target: str, sourceRegion = world.get_region(source, player) targetRegion = world.get_region(target, player) - - connection = Entrance(player, "", sourceRegion) - - if rule: - connection.access_rule = rule - sourceRegion.exits.append(connection) - connection.connect(targetRegion) + sourceRegion.connect(targetRegion, rule=rule) def split_location_datas_per_region(locations: List[LocationData]) -> Dict[str, List[LocationData]]: