Core: generalize pre_fill item pool handling

This commit is contained in:
Fabian Dill 2022-02-13 23:02:18 +01:00
parent 34b9344084
commit d7d1d54a0b
5 changed files with 34 additions and 28 deletions

View File

@ -312,10 +312,9 @@ class MultiWorld():
for item in self.itempool: for item in self.itempool:
self.worlds[item.player].collect(ret, item) self.worlds[item.player].collect(ret, item)
from worlds.alttp.Dungeons import get_dungeon_item_pool for player in self.player_ids:
for item in get_dungeon_item_pool(self): subworld = self.worlds[player]
subworld = self.worlds[item.player] for item in subworld.get_pre_fill_items():
if item.name in subworld.dungeon_local_item_names:
subworld.collect(ret, item) subworld.collect(ret, item)
ret.sweep_for_events() ret.sweep_for_events()

View File

@ -215,6 +215,10 @@ class World(metaclass=AutoWorldRegister):
if item.advancement: if item.advancement:
return item.name 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. # following methods should not need to be overridden.
def collect(self, state: CollectionState, item: Item) -> bool: def collect(self, state: CollectionState, item: Item) -> bool:
name = self.collect_item(state, item) 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())) self.world.itempool.append(self.create_item(self.get_filler_item_name()))
# any methods attached to this can be used as part of CollectionState, # any methods attached to this can be used as part of CollectionState,
# please use a prefix as all of them get clobbered together # please use a prefix as all of them get clobbered together
class LogicMixin(metaclass=AutoLogicRegister): class LogicMixin(metaclass=AutoLogicRegister):

View File

@ -1,3 +1,5 @@
import typing
from BaseClasses import Dungeon from BaseClasses import Dungeon
from worlds.alttp.Bosses import BossFactory from worlds.alttp.Bosses import BossFactory
from Fill import fill_restrictive from Fill import fill_restrictive
@ -13,6 +15,7 @@ def create_dungeons(world, player):
dungeon_items, player) dungeon_items, player)
for item in dungeon.all_items: for item in dungeon.all_items:
item.dungeon = dungeon item.dungeon = dungeon
item.world = world
dungeon.boss = BossFactory(default_boss, player) if default_boss else None dungeon.boss = BossFactory(default_boss, player) if default_boss else None
for region in dungeon.regions: for region in dungeon.regions:
world.get_region(region, player).dungeon = dungeon world.get_region(region, player).dungeon = dungeon
@ -108,21 +111,15 @@ def create_dungeons(world, player):
world.dungeons[dungeon.name, dungeon.player] = dungeon world.dungeons[dungeon.name, dungeon.player] = dungeon
def get_dungeon_item_pool(world): def get_dungeon_item_pool(world) -> typing.List:
items = [item for dungeon in world.dungeons.values() for item in dungeon.all_items] return [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_player(world, player): def get_dungeon_item_pool_player(world, player) -> typing.List:
items = [item for dungeon in world.dungeons.values() if dungeon.player == player for item in dungeon.all_items] return [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 fill_dungeons_restrictive(autoworld, world): def fill_dungeons_restrictive(world):
"""Places dungeon-native items into their dungeons, places nothing if everything is shuffled outside.""" """Places dungeon-native items into their dungeons, places nothing if everything is shuffled outside."""
localized: set = set() localized: set = set()
dungeon_specific: set = set() dungeon_specific: set = set()

View File

@ -1,6 +1,7 @@
import typing import typing
def GetBeemizerItem(world, player, item):
def GetBeemizerItem(world, player: int, item):
item_name = item if isinstance(item, str) else item.name item_name = item if isinstance(item, str) else item.name
if item_name not in trap_replaceable: if item_name not in trap_replaceable:
@ -16,6 +17,7 @@ def GetBeemizerItem(world, player, item):
else: else:
return "Bee Trap" if isinstance(item, str) else world.create_item("Bee Trap", player) 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 # should be replaced with direct world.create_item(item) call in the future
def ItemFactory(items, player: int): def ItemFactory(items, player: int):
from worlds.alttp import ALTTPWorld from worlds.alttp import ALTTPWorld
@ -35,6 +37,7 @@ def ItemFactory(items, player: int):
return ret[0] return ret[0]
return ret return ret
class ItemData(typing.NamedTuple): class ItemData(typing.NamedTuple):
advancement: bool advancement: bool
type: typing.Optional[str] type: typing.Optional[str]

View File

@ -249,7 +249,7 @@ class ALTTPWorld(World):
@classmethod @classmethod
def stage_pre_fill(cls, world): def stage_pre_fill(cls, world):
from .Dungeons import fill_dungeons_restrictive from .Dungeons import fill_dungeons_restrictive
fill_dungeons_restrictive(cls, world) fill_dungeons_restrictive(world)
@classmethod @classmethod
def stage_post_fill(cls, world): def stage_post_fill(cls, world):
@ -363,17 +363,9 @@ class ALTTPWorld(World):
fill_locations.remove(loc) fill_locations.remove(loc)
world.random.shuffle(fill_locations) world.random.shuffle(fill_locations)
# TODO: investigate not creating the key in the first place # TODO: investigate not creating the key in the first place
if __debug__: progitempool[:] = [item for item in progitempool if
# keeping this here while I'm not sure we caught all instances of multiple HC small keys in the pool item.player not in standard_keyshuffle_players or
count = len(progitempool) 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)"]
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)"]
if trash_counts: if trash_counts:
locations_mapping = {player: [] for player in trash_counts} locations_mapping = {player: [] for player in trash_counts}
@ -405,6 +397,16 @@ class ALTTPWorld(World):
def get_filler_item_name(self) -> str: def get_filler_item_name(self) -> str:
return "Rupees (5)" # temporary 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: def get_same_seed(world, seed_def: tuple) -> str:
seeds: typing.Dict[tuple, str] = getattr(world, "__named_seeds", {}) seeds: typing.Dict[tuple, str] = getattr(world, "__named_seeds", {})