Fill: allow for single player fill restrictive placement and sweeping (#2415)
* Core: allow for single player state sweeping * Fill: have distribute items use single_player fill when it can * oop * pass locations to sweep_for_events instead of the player * finally found the diff that was breaking swap * LTTP fills everyone's dungeons at once, not just a single player's --------- Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
This commit is contained in:
parent
28262a31b8
commit
005fc4e864
22
Fill.py
22
Fill.py
|
@ -19,11 +19,12 @@ def _log_fill_progress(name: str, placed: int, total_items: int) -> None:
|
||||||
logging.info(f"Current fill step ({name}) at {placed}/{total_items} items placed.")
|
logging.info(f"Current fill step ({name}) at {placed}/{total_items} items placed.")
|
||||||
|
|
||||||
|
|
||||||
def sweep_from_pool(base_state: CollectionState, itempool: typing.Sequence[Item] = tuple()) -> CollectionState:
|
def sweep_from_pool(base_state: CollectionState, itempool: typing.Sequence[Item] = tuple(),
|
||||||
|
locations: typing.Optional[typing.List[Location]] = None) -> CollectionState:
|
||||||
new_state = base_state.copy()
|
new_state = base_state.copy()
|
||||||
for item in itempool:
|
for item in itempool:
|
||||||
new_state.collect(item, True)
|
new_state.collect(item, True)
|
||||||
new_state.sweep_for_events()
|
new_state.sweep_for_events(locations=locations)
|
||||||
return new_state
|
return new_state
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +67,8 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
|
||||||
item_pool.pop(p)
|
item_pool.pop(p)
|
||||||
break
|
break
|
||||||
maximum_exploration_state = sweep_from_pool(
|
maximum_exploration_state = sweep_from_pool(
|
||||||
base_state, item_pool + unplaced_items)
|
base_state, item_pool + unplaced_items, multiworld.get_filled_locations(item.player)
|
||||||
|
if single_player_placement else None)
|
||||||
|
|
||||||
has_beaten_game = multiworld.has_beaten_game(maximum_exploration_state)
|
has_beaten_game = multiworld.has_beaten_game(maximum_exploration_state)
|
||||||
|
|
||||||
|
@ -112,7 +114,9 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
|
||||||
|
|
||||||
location.item = None
|
location.item = None
|
||||||
placed_item.location = None
|
placed_item.location = None
|
||||||
swap_state = sweep_from_pool(base_state, [placed_item, *item_pool] if unsafe else item_pool)
|
swap_state = sweep_from_pool(base_state, [placed_item, *item_pool] if unsafe else item_pool,
|
||||||
|
multiworld.get_filled_locations(item.player)
|
||||||
|
if single_player_placement else None)
|
||||||
# unsafe means swap_state assumes we can somehow collect placed_item before item_to_place
|
# unsafe means swap_state assumes we can somehow collect placed_item before item_to_place
|
||||||
# by continuing to swap, which is not guaranteed. This is unsafe because there is no mechanic
|
# by continuing to swap, which is not guaranteed. This is unsafe because there is no mechanic
|
||||||
# to clean that up later, so there is a chance generation fails.
|
# to clean that up later, so there is a chance generation fails.
|
||||||
|
@ -170,7 +174,9 @@ def fill_restrictive(multiworld: MultiWorld, base_state: CollectionState, locati
|
||||||
|
|
||||||
if cleanup_required:
|
if cleanup_required:
|
||||||
# validate all placements and remove invalid ones
|
# validate all placements and remove invalid ones
|
||||||
state = sweep_from_pool(base_state, [])
|
state = sweep_from_pool(
|
||||||
|
base_state, [], multiworld.get_filled_locations(item.player)
|
||||||
|
if single_player_placement else None)
|
||||||
for placement in placements:
|
for placement in placements:
|
||||||
if multiworld.worlds[placement.item.player].options.accessibility != "minimal" and not placement.can_reach(state):
|
if multiworld.worlds[placement.item.player].options.accessibility != "minimal" and not placement.can_reach(state):
|
||||||
placement.item.location = None
|
placement.item.location = None
|
||||||
|
@ -456,14 +462,16 @@ def distribute_items_restrictive(multiworld: MultiWorld) -> None:
|
||||||
|
|
||||||
if prioritylocations:
|
if prioritylocations:
|
||||||
# "priority fill"
|
# "priority fill"
|
||||||
fill_restrictive(multiworld, multiworld.state, prioritylocations, progitempool, swap=False, on_place=mark_for_locking,
|
fill_restrictive(multiworld, multiworld.state, prioritylocations, progitempool,
|
||||||
|
single_player_placement=multiworld.players == 1, swap=False, on_place=mark_for_locking,
|
||||||
name="Priority")
|
name="Priority")
|
||||||
accessibility_corrections(multiworld, multiworld.state, prioritylocations, progitempool)
|
accessibility_corrections(multiworld, multiworld.state, prioritylocations, progitempool)
|
||||||
defaultlocations = prioritylocations + defaultlocations
|
defaultlocations = prioritylocations + defaultlocations
|
||||||
|
|
||||||
if progitempool:
|
if progitempool:
|
||||||
# "advancement/progression fill"
|
# "advancement/progression fill"
|
||||||
fill_restrictive(multiworld, multiworld.state, defaultlocations, progitempool, name="Progression")
|
fill_restrictive(multiworld, multiworld.state, defaultlocations, progitempool, single_player_placement=multiworld.players == 1,
|
||||||
|
name="Progression")
|
||||||
if progitempool:
|
if progitempool:
|
||||||
raise FillError(
|
raise FillError(
|
||||||
f"Not enough locations for progression items. "
|
f"Not enough locations for progression items. "
|
||||||
|
|
|
@ -264,7 +264,7 @@ def fill_dungeons_restrictive(multiworld: MultiWorld):
|
||||||
|
|
||||||
if loc in all_state_base.events:
|
if loc in all_state_base.events:
|
||||||
all_state_base.events.remove(loc)
|
all_state_base.events.remove(loc)
|
||||||
fill_restrictive(multiworld, all_state_base, locations, in_dungeon_items, True, True, allow_excluded=True,
|
fill_restrictive(multiworld, all_state_base, locations, in_dungeon_items, lock=True, allow_excluded=True,
|
||||||
name="LttP Dungeon Items")
|
name="LttP Dungeon Items")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue