mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00
ItemLinks: move item links to events, mess up their logic in doing so and lock them behind plando option "item_links" until they're fixed.
This commit is contained in:
@@ -21,11 +21,13 @@ else:
|
||||
auto_world = object
|
||||
|
||||
|
||||
class Group(TypedDict):
|
||||
class Group(TypedDict, total=False):
|
||||
name: str
|
||||
game: str
|
||||
world: auto_world
|
||||
players: Set[int]
|
||||
item_pool: Set[str]
|
||||
replacement_items: Dict[int, Optional[str]]
|
||||
|
||||
|
||||
class MultiWorld():
|
||||
@@ -43,6 +45,7 @@ class MultiWorld():
|
||||
groups: Dict[int, Group]
|
||||
is_race: bool = False
|
||||
precollected_items: Dict[int, List[Item]]
|
||||
state: CollectionState
|
||||
|
||||
class AttributeProxy():
|
||||
def __init__(self, rule):
|
||||
@@ -65,7 +68,6 @@ class MultiWorld():
|
||||
self.seed = None
|
||||
self.seed_name: str = "Unavailable"
|
||||
self.precollected_items = {player: [] for player in self.player_ids}
|
||||
self.state = CollectionState(self)
|
||||
self._cached_entrances = None
|
||||
self._cached_locations = None
|
||||
self._entrance_cache = {}
|
||||
@@ -145,6 +147,9 @@ class MultiWorld():
|
||||
self.worlds = {}
|
||||
self.slot_seeds = {}
|
||||
|
||||
def get_all_ids(self):
|
||||
return self.player_ids + tuple(self.groups)
|
||||
|
||||
def add_group(self, name: str, game: str, players: Set[int] = frozenset()) -> Tuple[int, Group]:
|
||||
"""Create a group with name and return the assigned player ID and group.
|
||||
If a group of this name already exists, the set of players is extended instead of creating a new one."""
|
||||
@@ -166,33 +171,11 @@ class MultiWorld():
|
||||
getattr(self, option_key)[new_id] = option(option.default)
|
||||
|
||||
self.worlds[new_id] = world_type(self, new_id)
|
||||
|
||||
self.player_name[new_id] = name
|
||||
# TODO: remove when LttP are transitioned over
|
||||
self.difficulty_requirements[new_id] = self.difficulty_requirements[next(iter(players))]
|
||||
|
||||
new_group = self.groups[new_id] = Group(name=name, game=game, players=players,
|
||||
world=self.worlds[new_id])
|
||||
|
||||
# instead of collect/remove overwrites, should encode sending as Events so they show up in spoiler log
|
||||
def group_collect(state, item) -> bool:
|
||||
changed = False
|
||||
for player in new_group["players"]:
|
||||
max(self.worlds[player].collect(state, item), changed)
|
||||
return changed
|
||||
|
||||
def group_remove(state, item) -> bool:
|
||||
changed = False
|
||||
for player in new_group["players"]:
|
||||
max(self.worlds[player].remove(state, item), changed)
|
||||
return changed
|
||||
|
||||
new_world = new_group["world"]
|
||||
new_world.collect = group_collect
|
||||
new_world.remove = group_remove
|
||||
|
||||
self.worlds[new_id] = new_world
|
||||
|
||||
return new_id, new_group
|
||||
|
||||
def get_player_groups(self, player) -> Set[int]:
|
||||
@@ -221,6 +204,35 @@ class MultiWorld():
|
||||
setattr(self, option_key, getattr(args, option_key, {}))
|
||||
self.worlds[player] = world_type(self, player)
|
||||
|
||||
item_links = {}
|
||||
|
||||
for player in self.player_ids:
|
||||
for item_link in self.item_links[player].value:
|
||||
if item_link["name"] in item_links:
|
||||
item_links[item_link["name"]]["players"][player] = item_link["replacement_item"]
|
||||
item_links[item_link["name"]]["item_pool"] &= set(item_link["item_pool"])
|
||||
else:
|
||||
if item_link["name"] in self.player_name.values():
|
||||
raise Exception(f"Cannot name a ItemLink group the same as a player ({item_link['name']}).")
|
||||
item_links[item_link["name"]] = {
|
||||
"players": {player: item_link["replacement_item"]},
|
||||
"item_pool": set(item_link["item_pool"]),
|
||||
"game": self.game[player]
|
||||
}
|
||||
|
||||
for name, item_link in item_links.items():
|
||||
current_item_name_groups = AutoWorld.AutoWorldRegister.world_types[item_link["game"]].item_name_groups
|
||||
pool = set()
|
||||
for item in item_link["item_pool"]:
|
||||
pool |= current_item_name_groups.get(item, {item})
|
||||
item_link["item_pool"] = pool
|
||||
|
||||
for group_name, item_link in item_links.items():
|
||||
game = item_link["game"]
|
||||
group_id, group = self.add_group(group_name, game, set(item_link["players"]))
|
||||
group["item_pool"] = item_link["item_pool"]
|
||||
group["replacement_items"] = item_link["players"]
|
||||
|
||||
# intended for unittests
|
||||
def set_default_common_options(self):
|
||||
for option_key, option in Options.common_options.items():
|
||||
@@ -544,12 +556,12 @@ class CollectionState(object):
|
||||
def __init__(self, parent: MultiWorld):
|
||||
self.prog_items = Counter()
|
||||
self.world = parent
|
||||
self.reachable_regions = {player: set() for player in range(1, parent.players + 1)}
|
||||
self.blocked_connections = {player: set() for player in range(1, parent.players + 1)}
|
||||
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.path = {}
|
||||
self.locations_checked = set()
|
||||
self.stale = {player: True for player in range(1, parent.players + 1)}
|
||||
self.stale = {player: True for player in parent.get_all_ids()}
|
||||
for items in parent.precollected_items.values():
|
||||
for item in items:
|
||||
self.collect(item, True)
|
||||
@@ -591,9 +603,9 @@ class CollectionState(object):
|
||||
ret = CollectionState(self.world)
|
||||
ret.prog_items = self.prog_items.copy()
|
||||
ret.reachable_regions = {player: copy.copy(self.reachable_regions[player]) for player in
|
||||
range(1, self.world.players + 1)}
|
||||
self.reachable_regions}
|
||||
ret.blocked_connections = {player: copy.copy(self.blocked_connections[player]) for player in
|
||||
range(1, self.world.players + 1)}
|
||||
self.blocked_connections}
|
||||
ret.events = copy.copy(self.events)
|
||||
ret.path = copy.copy(self.path)
|
||||
ret.locations_checked = copy.copy(self.locations_checked)
|
||||
|
Reference in New Issue
Block a user