Skip to content

Commit f94a484

Browse files
authored
Merge pull request ArchipelagoMW#2 from alwaysintreble/generic-entrance-rando
2 parents 9f17b59 + cbb31f4 commit f94a484

File tree

352 files changed

+69876
-12867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

352 files changed

+69876
-12867
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
*.apmc
1010
*.apz5
1111
*.aptloz
12+
*.apemerald
1213
*.pyc
1314
*.pyd
1415
*.sfc
1516
*.z64
1617
*.n64
1718
*.nes
19+
*.smc
1820
*.sms
1921
*.gb
2022
*.gbc

BaseClasses.py

+29-18
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ def extend(self, regions: Iterable[Region]):
116116
for region in regions:
117117
self.region_cache[region.player][region.name] = region
118118

119+
def add_group(self, new_id: int):
120+
self.region_cache[new_id] = {}
121+
self.entrance_cache[new_id] = {}
122+
self.location_cache[new_id] = {}
123+
119124
def __iter__(self) -> Iterator[Region]:
120125
for regions in self.region_cache.values():
121126
yield from regions.values()
@@ -223,6 +228,7 @@ def add_group(self, name: str, game: str, players: Set[int] = frozenset()) -> Tu
223228
return group_id, group
224229
new_id: int = self.players + len(self.groups) + 1
225230

231+
self.regions.add_group(new_id)
226232
self.game[new_id] = game
227233
self.player_types[new_id] = NetUtils.SlotType.group
228234
world_type = AutoWorld.AutoWorldRegister.world_types[game]
@@ -621,7 +627,7 @@ class CollectionState():
621627
additional_copy_functions: List[Callable[[CollectionState, CollectionState], CollectionState]] = []
622628

623629
def __init__(self, parent: MultiWorld, allow_partial_entrances: bool = False):
624-
self.prog_items = {player: Counter() for player in parent.player_ids}
630+
self.prog_items = {player: Counter() for player in parent.get_all_ids()}
625631
self.multiworld = parent
626632
self.reachable_regions = {player: set() for player in parent.get_all_ids()}
627633
self.blocked_connections = {player: set() for player in parent.get_all_ids()}
@@ -656,10 +662,9 @@ def update_reachable_regions(self, player: int):
656662
if new_region in rrp:
657663
bc.remove(connection)
658664
elif connection.can_reach(self):
659-
if not self.allow_partial_entrances:
660-
assert new_region, f"tried to search through an Entrance \"{connection}\" with no Region"
661-
elif not new_region:
665+
if self.allow_partial_entrances and not new_region:
662666
continue
667+
assert new_region, f"tried to search through an Entrance \"{connection}\" with no Region"
663668
rrp.add(new_region)
664669
bc.remove(connection)
665670
bc.update(new_region.exits)
@@ -716,37 +721,43 @@ def sweep_for_events(self, key_only: bool = False, locations: Optional[Iterable[
716721
assert isinstance(event.item, Item), "tried to collect Event with no Item"
717722
self.collect(event.item, True, event)
718723

724+
# item name related
719725
def has(self, item: str, player: int, count: int = 1) -> bool:
720726
return self.prog_items[player][item] >= count
721727

722-
def has_all(self, items: Set[str], player: int) -> bool:
728+
def has_all(self, items: Iterable[str], player: int) -> bool:
723729
"""Returns True if each item name of items is in state at least once."""
724730
return all(self.prog_items[player][item] for item in items)
725731

726-
def has_any(self, items: Set[str], player: int) -> bool:
732+
def has_any(self, items: Iterable[str], player: int) -> bool:
727733
"""Returns True if at least one item name of items is in state at least once."""
728734
return any(self.prog_items[player][item] for item in items)
729735

730736
def count(self, item: str, player: int) -> int:
731737
return self.prog_items[player][item]
732738

739+
def item_count(self, item: str, player: int) -> int:
740+
Utils.deprecate("Use count instead.")
741+
return self.count(item, player)
742+
743+
# item name group related
733744
def has_group(self, item_name_group: str, player: int, count: int = 1) -> bool:
734745
found: int = 0
746+
player_prog_items = self.prog_items[player]
735747
for item_name in self.multiworld.worlds[player].item_name_groups[item_name_group]:
736-
found += self.prog_items[player][item_name]
748+
found += player_prog_items[item_name]
737749
if found >= count:
738750
return True
739751
return False
740752

741753
def count_group(self, item_name_group: str, player: int) -> int:
742754
found: int = 0
755+
player_prog_items = self.prog_items[player]
743756
for item_name in self.multiworld.worlds[player].item_name_groups[item_name_group]:
744-
found += self.prog_items[player][item_name]
757+
found += player_prog_items[item_name]
745758
return found
746759

747-
def item_count(self, item: str, player: int) -> int:
748-
return self.prog_items[player][item]
749-
760+
# Item related
750761
def collect(self, item: Item, event: bool = False, location: Optional[Location] = None) -> bool:
751762
if location:
752763
self.locations_checked.add(location)
@@ -774,7 +785,7 @@ def remove(self, item: Item):
774785

775786

776787
class Entrance:
777-
class Type(IntEnum):
788+
class EntranceType(IntEnum):
778789
ONE_WAY = 1
779790
TWO_WAY = 2
780791

@@ -785,13 +796,13 @@ class Type(IntEnum):
785796
parent_region: Optional[Region]
786797
connected_region: Optional[Region] = None
787798
er_group: str
788-
er_type: Type
799+
er_type: EntranceType
789800
# LttP specific, TODO: should make a LttPEntrance
790801
addresses = None
791802
target = None
792803

793-
def __init__(self, player: int, name: str = '', parent: Region = None,
794-
er_group: str = 'Default', er_type: Type = Type.ONE_WAY):
804+
def __init__(self, player: int, name: str = "", parent: Region = None,
805+
er_group: str = "Default", er_type: EntranceType = EntranceType.ONE_WAY):
795806
self.name = name
796807
self.parent_region = parent
797808
self.player = player
@@ -800,7 +811,7 @@ def __init__(self, player: int, name: str = '', parent: Region = None,
800811

801812
def can_reach(self, state: CollectionState) -> bool:
802813
if self.parent_region.can_reach(state) and self.access_rule(state):
803-
if not self.hide_path and not self in state.path:
814+
if not self.hide_path and self not in state.path:
804815
state.path[self] = (self.name, state.path.get(self.parent_region, (self.parent_region.name, None)))
805816
return True
806817

@@ -812,7 +823,7 @@ def connect(self, region: Region, addresses: Any = None, target: Any = None) ->
812823
self.addresses = addresses
813824
region.entrances.append(self)
814825

815-
def is_valid_source_transition(self, state: ERPlacementState) -> bool:
826+
def is_valid_source_transition(self, state: "ERPlacementState") -> bool:
816827
"""
817828
Determines whether this is a valid source transition, that is, whether the entrance
818829
randomizer is allowed to pair it to place any other regions. By default, this is the
@@ -823,7 +834,7 @@ def is_valid_source_transition(self, state: ERPlacementState) -> bool:
823834
"""
824835
return self.can_reach(state.collection_state)
825836

826-
def can_connect_to(self, other: Entrance, state: ERPlacementState) -> bool:
837+
def can_connect_to(self, other: Entrance, state: "ERPlacementState") -> bool:
827838
"""
828839
Determines whether a given Entrance is a valid target transition, that is, whether
829840
the entrance randomizer is allowed to pair this Entrance to that Entrance.

CommonClient.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,8 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
737737
elif 'InvalidGame' in errors:
738738
ctx.event_invalid_game()
739739
elif 'IncompatibleVersion' in errors:
740-
raise Exception('Server reported your client version as incompatible')
740+
raise Exception('Server reported your client version as incompatible. '
741+
'This probably means you have to update.')
741742
elif 'InvalidItemsHandling' in errors:
742743
raise Exception('The item handling flags requested by the client are not supported')
743744
# last to check, recoverable problem

0 commit comments

Comments
 (0)