diff --git a/BaseClasses.py b/BaseClasses.py index 1188e722..61f3f8f6 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -430,7 +430,7 @@ class MultiWorld(): subworld = self.worlds[player] for item in subworld.get_pre_fill_items(): subworld.collect(ret, item) - ret.sweep_for_events() + ret.sweep_for_advancements() if use_cache: self._all_state = ret @@ -661,7 +661,7 @@ class CollectionState(): multiworld: MultiWorld reachable_regions: Dict[int, Set[Region]] blocked_connections: Dict[int, Set[Entrance]] - events: Set[Location] + advancements: Set[Location] path: Dict[Union[Region, Entrance], PathValue] locations_checked: Set[Location] stale: Dict[int, bool] @@ -673,7 +673,7 @@ class CollectionState(): self.multiworld = parent self.reachable_regions = {player: set() for player in parent.get_all_ids()} self.blocked_connections = {player: set() for player in parent.get_all_ids()} - self.events = set() + self.advancements = set() self.path = {} self.locations_checked = set() self.stale = {player: True for player in parent.get_all_ids()} @@ -722,7 +722,7 @@ class CollectionState(): self.reachable_regions.items()} ret.blocked_connections = {player: entrance_set.copy() for player, entrance_set in self.blocked_connections.items()} - ret.events = self.events.copy() + ret.advancements = self.advancements.copy() ret.path = self.path.copy() ret.locations_checked = self.locations_checked.copy() for function in self.additional_copy_functions: @@ -755,19 +755,24 @@ class CollectionState(): return self.multiworld.get_region(spot, player).can_reach(self) def sweep_for_events(self, locations: Optional[Iterable[Location]] = None) -> None: + Utils.deprecate("sweep_for_events has been renamed to sweep_for_advancements. The functionality is the same. " + "Please switch over to sweep_for_advancements.") + return self.sweep_for_advancements(locations) + + def sweep_for_advancements(self, locations: Optional[Iterable[Location]] = None) -> None: if locations is None: locations = self.multiworld.get_filled_locations() - reachable_events = True - # since the loop has a good chance to run more than once, only filter the events once - locations = {location for location in locations if location.advancement and location not in self.events} + reachable_advancements = True + # since the loop has a good chance to run more than once, only filter the advancements once + locations = {location for location in locations if location.advancement and location not in self.advancements} - while reachable_events: - reachable_events = {location for location in locations if location.can_reach(self)} - locations -= reachable_events - for event in reachable_events: - self.events.add(event) - assert isinstance(event.item, Item), "tried to collect Event with no Item" - self.collect(event.item, True, event) + while reachable_advancements: + reachable_advancements = {location for location in locations if location.can_reach(self)} + locations -= reachable_advancements + for advancement in reachable_advancements: + self.advancements.add(advancement) + assert isinstance(advancement.item, Item), "tried to collect Event with no Item" + self.collect(advancement.item, True, advancement) # item name related def has(self, item: str, player: int, count: int = 1) -> bool: @@ -871,7 +876,7 @@ class CollectionState(): self.stale[item.player] = True if changed and not prevent_sweep: - self.sweep_for_events() + self.sweep_for_advancements() return changed diff --git a/Fill.py b/Fill.py index 15d5842e..e2fcff00 100644 --- a/Fill.py +++ b/Fill.py @@ -29,7 +29,7 @@ def sweep_from_pool(base_state: CollectionState, itempool: typing.Sequence[Item] new_state = base_state.copy() for item in itempool: new_state.collect(item, True) - new_state.sweep_for_events(locations=locations) + new_state.sweep_for_advancements(locations=locations) return new_state @@ -329,8 +329,8 @@ def accessibility_corrections(multiworld: MultiWorld, state: CollectionState, lo pool.append(location.item) state.remove(location.item) location.item = None - if location in state.events: - state.events.remove(location) + if location in state.advancements: + state.advancements.remove(location) locations.append(location) if pool and locations: locations.sort(key=lambda loc: loc.progress_type != LocationProgressType.PRIORITY) @@ -363,7 +363,7 @@ def distribute_early_items(multiworld: MultiWorld, early_priority_locations: typing.List[Location] = [] loc_indexes_to_remove: typing.Set[int] = set() base_state = multiworld.state.copy() - base_state.sweep_for_events(locations=(loc for loc in multiworld.get_filled_locations() if loc.address is None)) + base_state.sweep_for_advancements(locations=(loc for loc in multiworld.get_filled_locations() if loc.address is None)) for i, loc in enumerate(fill_locations): if loc.can_reach(base_state): if loc.progress_type == LocationProgressType.PRIORITY: @@ -558,7 +558,7 @@ def flood_items(multiworld: MultiWorld) -> None: progress_done = False # sweep once to pick up preplaced items - multiworld.state.sweep_for_events() + multiworld.state.sweep_for_advancements() # fill multiworld from top of itempool while we can while not progress_done: @@ -746,7 +746,7 @@ def balance_multiworld_progression(multiworld: MultiWorld) -> None: ), items_to_test): reducing_state.collect(location.item, True, location) - reducing_state.sweep_for_events(locations=locations_to_test) + reducing_state.sweep_for_advancements(locations=locations_to_test) if multiworld.has_beaten_game(balancing_state): if not multiworld.has_beaten_game(reducing_state): @@ -829,7 +829,7 @@ def distribute_planned(multiworld: MultiWorld) -> None: warn(warning, force) swept_state = multiworld.state.copy() - swept_state.sweep_for_events() + swept_state.sweep_for_advancements() reachable = frozenset(multiworld.get_reachable_locations(swept_state)) early_locations: typing.Dict[int, typing.List[str]] = collections.defaultdict(list) non_early_locations: typing.Dict[int, typing.List[str]] = collections.defaultdict(list) diff --git a/test/bases.py b/test/bases.py index 83461b15..a3ea2331 100644 --- a/test/bases.py +++ b/test/bases.py @@ -24,7 +24,7 @@ class TestBase(unittest.TestCase): for item in items: item.classification = ItemClassification.progression state.collect(item, prevent_sweep=True) - state.sweep_for_events() + state.sweep_for_advancements() state.update_reachable_regions(1) self._state_cache[self.multiworld, tuple(items)] = state return state @@ -221,8 +221,8 @@ class WorldTestBase(unittest.TestCase): if isinstance(items, Item): items = (items,) for item in items: - if item.location and item.advancement and item.location in self.multiworld.state.events: - self.multiworld.state.events.remove(item.location) + if item.location and item.advancement and item.location in self.multiworld.state.advancements: + self.multiworld.state.advancements.remove(item.location) self.multiworld.state.remove(item) def can_reach_location(self, location: str) -> bool: diff --git a/test/general/test_fill.py b/test/general/test_fill.py index db24b706..2dba147a 100644 --- a/test/general/test_fill.py +++ b/test/general/test_fill.py @@ -192,7 +192,7 @@ class TestFillRestrictive(unittest.TestCase): location_pool = player1.locations[1:] + player2.locations item_pool = player1.prog_items[:-1] + player2.prog_items fill_restrictive(multiworld, multiworld.state, location_pool, item_pool) - multiworld.state.sweep_for_events() # collect everything + multiworld.state.sweep_for_advancements() # collect everything # all of player2's locations and items should be accessible (not all of player1's) for item in player2.prog_items: @@ -443,8 +443,8 @@ class TestFillRestrictive(unittest.TestCase): item = player1.prog_items[0] item.code = None location.place_locked_item(item) - multiworld.state.sweep_for_events() - multiworld.state.sweep_for_events() + multiworld.state.sweep_for_advancements() + multiworld.state.sweep_for_advancements() self.assertTrue(multiworld.state.prog_items[item.player][item.name], "Sweep did not collect - Test flawed") self.assertEqual(multiworld.state.prog_items[item.player][item.name], 1, "Sweep collected multiple times") diff --git a/worlds/alttp/Dungeons.py b/worlds/alttp/Dungeons.py index 150d52cc..8405fc44 100644 --- a/worlds/alttp/Dungeons.py +++ b/worlds/alttp/Dungeons.py @@ -248,7 +248,7 @@ def fill_dungeons_restrictive(multiworld: MultiWorld): pass for item in pre_fill_items: multiworld.worlds[item.player].collect(all_state_base, item) - all_state_base.sweep_for_events() + all_state_base.sweep_for_advancements() # Remove completion condition so that minimal-accessibility worlds place keys properly for player in {item.player for item in in_dungeon_items}: @@ -262,8 +262,8 @@ def fill_dungeons_restrictive(multiworld: MultiWorld): all_state_base.remove(item_factory(key_data[3], multiworld.worlds[player])) loc = multiworld.get_location(key_loc, player) - if loc in all_state_base.events: - all_state_base.events.remove(loc) + if loc in all_state_base.advancements: + all_state_base.advancements.remove(loc) fill_restrictive(multiworld, all_state_base, locations, in_dungeon_items, lock=True, allow_excluded=True, name="LttP Dungeon Items") diff --git a/worlds/alttp/test/dungeons/TestDungeon.py b/worlds/alttp/test/dungeons/TestDungeon.py index 796bfeec..5ab1b230 100644 --- a/worlds/alttp/test/dungeons/TestDungeon.py +++ b/worlds/alttp/test/dungeons/TestDungeon.py @@ -54,7 +54,7 @@ class TestDungeon(LTTPTestBase): for item in items: item.classification = ItemClassification.progression - state.collect(item, prevent_sweep=True) # prevent_sweep=True prevents running sweep_for_events() and picking up - state.sweep_for_events() # key drop keys repeatedly + state.collect(item, prevent_sweep=True) # prevent_sweep=True prevents running sweep_for_advancements() and picking up + state.sweep_for_advancements() # key drop keys repeatedly self.assertEqual(self.multiworld.get_location(location, 1).can_reach(state), access, f"failed {self.multiworld.get_location(location, 1)} with: {item_pool}") diff --git a/worlds/lingo/__init__.py b/worlds/lingo/__init__.py index 9853be73..2a61a71f 100644 --- a/worlds/lingo/__init__.py +++ b/worlds/lingo/__init__.py @@ -85,7 +85,7 @@ class LingoWorld(World): state.collect(self.create_item(self.player_logic.forced_good_item), True) all_locations = self.multiworld.get_locations(self.player) - state.sweep_for_events(locations=all_locations) + state.sweep_for_advancements(locations=all_locations) unreachable_locations = [location for location in all_locations if not state.can_reach_location(location.name, self.player)] diff --git a/worlds/oot/EntranceShuffle.py b/worlds/oot/EntranceShuffle.py index 058fdbed..cda442ff 100644 --- a/worlds/oot/EntranceShuffle.py +++ b/worlds/oot/EntranceShuffle.py @@ -445,7 +445,7 @@ def shuffle_random_entrances(ootworld): # Gather locations to keep reachable for validation all_state = ootworld.get_state_with_complete_itempool() - all_state.sweep_for_events(locations=ootworld.get_locations()) + all_state.sweep_for_advancements(locations=ootworld.get_locations()) locations_to_ensure_reachable = {loc for loc in world.get_reachable_locations(all_state, player) if not (loc.type == 'Drop' or (loc.type == 'Event' and 'Subrule' in loc.name))} # Set entrance data for all entrances @@ -791,8 +791,8 @@ def validate_world(ootworld, entrance_placed, locations_to_ensure_reachable, all all_state = all_state_orig.copy() none_state = none_state_orig.copy() - all_state.sweep_for_events(locations=ootworld.get_locations()) - none_state.sweep_for_events(locations=ootworld.get_locations()) + all_state.sweep_for_advancements(locations=ootworld.get_locations()) + none_state.sweep_for_advancements(locations=ootworld.get_locations()) if ootworld.shuffle_interior_entrances or ootworld.shuffle_overworld_entrances or ootworld.spawn_positions: time_travel_state = none_state.copy() diff --git a/worlds/oot/Rules.py b/worlds/oot/Rules.py index 529411f6..4bbf1543 100644 --- a/worlds/oot/Rules.py +++ b/worlds/oot/Rules.py @@ -228,7 +228,7 @@ def set_shop_rules(ootworld): def set_entrances_based_rules(ootworld): all_state = ootworld.get_state_with_complete_itempool() - all_state.sweep_for_events(locations=ootworld.get_locations()) + all_state.sweep_for_advancements(locations=ootworld.get_locations()) for location in filter(lambda location: location.type == 'Shop', ootworld.get_locations()): # If a shop is not reachable as adult, it can't have Goron Tunic or Zora Tunic as child can't buy these diff --git a/worlds/oot/__init__.py b/worlds/oot/__init__.py index 24be303f..ee78958b 100644 --- a/worlds/oot/__init__.py +++ b/worlds/oot/__init__.py @@ -847,7 +847,7 @@ class OOTWorld(World): # Make sure to only kill actual internal events, not in-game "events" all_state = self.get_state_with_complete_itempool() all_locations = self.get_locations() - all_state.sweep_for_events(locations=all_locations) + all_state.sweep_for_advancements(locations=all_locations) reachable = self.multiworld.get_reachable_locations(all_state, self.player) unreachable = [loc for loc in all_locations if (loc.internal or loc.type == 'Drop') and loc.address is None and loc.locked and loc not in reachable] @@ -875,7 +875,7 @@ class OOTWorld(World): state = base_state.copy() for item in self.get_pre_fill_items(): self.collect(state, item) - state.sweep_for_events(locations=self.get_locations()) + state.sweep_for_advancements(locations=self.get_locations()) return state # Prefill shops, songs, and dungeon items @@ -887,7 +887,7 @@ class OOTWorld(World): state = CollectionState(self.multiworld) for item in self.itempool: self.collect(state, item) - state.sweep_for_events(locations=self.get_locations()) + state.sweep_for_advancements(locations=self.get_locations()) # Place dungeon items special_fill_types = ['GanonBossKey', 'BossKey', 'SmallKey', 'HideoutSmallKey', 'Map', 'Compass'] diff --git a/worlds/pokemon_rb/__init__.py b/worlds/pokemon_rb/__init__.py index 277d73b2..c1d84318 100644 --- a/worlds/pokemon_rb/__init__.py +++ b/worlds/pokemon_rb/__init__.py @@ -296,7 +296,7 @@ class PokemonRedBlueWorld(World): if attempt > 1: for mon in poke_data.pokemon_data.keys(): state.collect(self.create_item(mon), True) - state.sweep_for_events() + state.sweep_for_advancements() self.multiworld.random.shuffle(badges) self.multiworld.random.shuffle(badgelocs) badgelocs_copy = badgelocs.copy() diff --git a/worlds/pokemon_rb/regions.py b/worlds/pokemon_rb/regions.py index a9206fe6..938c39b3 100644 --- a/worlds/pokemon_rb/regions.py +++ b/worlds/pokemon_rb/regions.py @@ -2439,7 +2439,7 @@ def door_shuffle(world, multiworld, player, badges, badge_locs): state_copy = state.copy() state_copy.collect(item, True) - state.sweep_for_events(locations=event_locations) + state.sweep_for_advancements(locations=event_locations) new_reachable_entrances = len([entrance for entrance in entrances if entrance in reachable_entrances or entrance.parent_region.can_reach(state_copy)]) return new_reachable_entrances > len(reachable_entrances) @@ -2480,7 +2480,7 @@ def door_shuffle(world, multiworld, player, badges, badge_locs): while entrances: state.update_reachable_regions(player) - state.sweep_for_events(locations=event_locations) + state.sweep_for_advancements(locations=event_locations) multiworld.random.shuffle(entrances) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 3b599bc9..02d11373 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -219,7 +219,7 @@ class WitnessWorld(World): # Only sweeps for events because having this behavior be random based on Tutorial Gate would be strange. state = CollectionState(self.multiworld) - state.sweep_for_events(locations=event_locations) + state.sweep_for_advancements(locations=event_locations) num_early_locs = sum(1 for loc in self.multiworld.get_reachable_locations(state, self.player) if loc.address) diff --git a/worlds/witness/test/test_panel_hunt.py b/worlds/witness/test/test_panel_hunt.py index 2fc16f78..af6855dc 100644 --- a/worlds/witness/test/test_panel_hunt.py +++ b/worlds/witness/test/test_panel_hunt.py @@ -23,7 +23,7 @@ class TestMaxPanelHuntMinChecks(WitnessTestBase): for _ in range(100): state_100.collect(panel_hunt_item, True) - state_100.sweep_for_events([self.world.get_location("Tutorial Gate Open Solved")]) + state_100.sweep_for_advancements([self.world.get_location("Tutorial Gate Open Solved")]) self.assertTrue(self.multiworld.completion_condition[self.player](state_100)) @@ -33,7 +33,7 @@ class TestMaxPanelHuntMinChecks(WitnessTestBase): for _ in range(99): state_99.collect(panel_hunt_item, True) - state_99.sweep_for_events([self.world.get_location("Tutorial Gate Open Solved")]) + state_99.sweep_for_advancements([self.world.get_location("Tutorial Gate Open Solved")]) self.assertFalse(self.multiworld.completion_condition[self.player](state_99))