From d7d1d54a0b44c856f66ffa62c943202666798db5 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Sun, 13 Feb 2022 23:02:18 +0100 Subject: [PATCH] Core: generalize pre_fill item pool handling --- BaseClasses.py | 7 +++---- worlds/AutoWorld.py | 5 +++++ worlds/alttp/Dungeons.py | 19 ++++++++----------- worlds/alttp/Items.py | 5 ++++- worlds/alttp/__init__.py | 26 ++++++++++++++------------ 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 96aa98a5..61bbcb10 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -312,10 +312,9 @@ class MultiWorld(): for item in self.itempool: self.worlds[item.player].collect(ret, item) - from worlds.alttp.Dungeons import get_dungeon_item_pool - for item in get_dungeon_item_pool(self): - subworld = self.worlds[item.player] - if item.name in subworld.dungeon_local_item_names: + for player in self.player_ids: + subworld = self.worlds[player] + for item in subworld.get_pre_fill_items(): subworld.collect(ret, item) ret.sweep_for_events() diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 9aea3fa6..bd5861c5 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -215,6 +215,10 @@ class World(metaclass=AutoWorldRegister): if item.advancement: return item.name + # called to create all_state, return Items that are created during pre_fill + def get_pre_fill_items(self) -> List[Item]: + return [] + # following methods should not need to be overridden. def collect(self, state: CollectionState, item: Item) -> bool: name = self.collect_item(state, item) @@ -236,6 +240,7 @@ class World(metaclass=AutoWorldRegister): self.world.itempool.append(self.create_item(self.get_filler_item_name())) + # any methods attached to this can be used as part of CollectionState, # please use a prefix as all of them get clobbered together class LogicMixin(metaclass=AutoLogicRegister): diff --git a/worlds/alttp/Dungeons.py b/worlds/alttp/Dungeons.py index cca78999..861dce9a 100644 --- a/worlds/alttp/Dungeons.py +++ b/worlds/alttp/Dungeons.py @@ -1,3 +1,5 @@ +import typing + from BaseClasses import Dungeon from worlds.alttp.Bosses import BossFactory from Fill import fill_restrictive @@ -13,6 +15,7 @@ def create_dungeons(world, player): dungeon_items, player) for item in dungeon.all_items: item.dungeon = dungeon + item.world = world dungeon.boss = BossFactory(default_boss, player) if default_boss else None for region in dungeon.regions: world.get_region(region, player).dungeon = dungeon @@ -108,21 +111,15 @@ def create_dungeons(world, player): world.dungeons[dungeon.name, dungeon.player] = dungeon -def get_dungeon_item_pool(world): - items = [item for dungeon in world.dungeons.values() for item in dungeon.all_items] - for item in items: - item.world = world - return items +def get_dungeon_item_pool(world) -> typing.List: + return [item for dungeon in world.dungeons.values() for item in dungeon.all_items] -def get_dungeon_item_pool_player(world, player): - items = [item for dungeon in world.dungeons.values() if dungeon.player == player for item in dungeon.all_items] - for item in items: - item.world = world - return items +def get_dungeon_item_pool_player(world, player) -> typing.List: + return [item for dungeon in world.dungeons.values() if dungeon.player == player for item in dungeon.all_items] -def fill_dungeons_restrictive(autoworld, world): +def fill_dungeons_restrictive(world): """Places dungeon-native items into their dungeons, places nothing if everything is shuffled outside.""" localized: set = set() dungeon_specific: set = set() diff --git a/worlds/alttp/Items.py b/worlds/alttp/Items.py index 2c6edbbf..1dbc6424 100644 --- a/worlds/alttp/Items.py +++ b/worlds/alttp/Items.py @@ -1,6 +1,7 @@ import typing -def GetBeemizerItem(world, player, item): + +def GetBeemizerItem(world, player: int, item): item_name = item if isinstance(item, str) else item.name if item_name not in trap_replaceable: @@ -16,6 +17,7 @@ def GetBeemizerItem(world, player, item): else: return "Bee Trap" if isinstance(item, str) else world.create_item("Bee Trap", player) + # should be replaced with direct world.create_item(item) call in the future def ItemFactory(items, player: int): from worlds.alttp import ALTTPWorld @@ -35,6 +37,7 @@ def ItemFactory(items, player: int): return ret[0] return ret + class ItemData(typing.NamedTuple): advancement: bool type: typing.Optional[str] diff --git a/worlds/alttp/__init__.py b/worlds/alttp/__init__.py index f6b08b4e..e4512ecb 100644 --- a/worlds/alttp/__init__.py +++ b/worlds/alttp/__init__.py @@ -249,7 +249,7 @@ class ALTTPWorld(World): @classmethod def stage_pre_fill(cls, world): from .Dungeons import fill_dungeons_restrictive - fill_dungeons_restrictive(cls, world) + fill_dungeons_restrictive(world) @classmethod def stage_post_fill(cls, world): @@ -363,17 +363,9 @@ class ALTTPWorld(World): fill_locations.remove(loc) world.random.shuffle(fill_locations) # TODO: investigate not creating the key in the first place - if __debug__: - # keeping this here while I'm not sure we caught all instances of multiple HC small keys in the pool - count = len(progitempool) - progitempool[:] = [item for item in progitempool if - item.player not in standard_keyshuffle_players or - item.name != "Small Key (Hyrule Castle)"] - assert len(progitempool) + len(standard_keyshuffle_players) == count - else: - progitempool[:] = [item for item in progitempool if - item.player not in standard_keyshuffle_players or - item.name != "Small Key (Hyrule Castle)"] + progitempool[:] = [item for item in progitempool if + item.player not in standard_keyshuffle_players or + item.name != "Small Key (Hyrule Castle)"] if trash_counts: locations_mapping = {player: [] for player in trash_counts} @@ -405,6 +397,16 @@ class ALTTPWorld(World): def get_filler_item_name(self) -> str: return "Rupees (5)" # temporary + def get_pre_fill_items(self): + res = [] + if self.dungeon_local_item_names: + for (name, player), dungeon in self.world.dungeons.items(): + if player == self.player: + for item in dungeon.all_items: + if item.name in self.dungeon_local_item_names: + res.append(item) + return res + def get_same_seed(world, seed_def: tuple) -> str: seeds: typing.Dict[tuple, str] = getattr(world, "__named_seeds", {})