Fix minimal accessibility failures (#726)
This commit is contained in:
parent
e6a4925f0c
commit
885c8d3fcc
|
@ -531,7 +531,7 @@ class MultiWorld():
|
||||||
|
|
||||||
beatable_fulfilled = False
|
beatable_fulfilled = False
|
||||||
|
|
||||||
def location_conditition(location: Location):
|
def location_condition(location: Location):
|
||||||
"""Determine if this location has to be accessible, location is already filtered by location_relevant"""
|
"""Determine if this location has to be accessible, location is already filtered by location_relevant"""
|
||||||
if location.player in players["minimal"]:
|
if location.player in players["minimal"]:
|
||||||
return False
|
return False
|
||||||
|
@ -548,7 +548,7 @@ class MultiWorld():
|
||||||
def all_done():
|
def all_done():
|
||||||
"""Check if all access rules are fulfilled"""
|
"""Check if all access rules are fulfilled"""
|
||||||
if beatable_fulfilled:
|
if beatable_fulfilled:
|
||||||
if any(location_conditition(location) for location in locations):
|
if any(location_condition(location) for location in locations):
|
||||||
return False # still locations required to be collected
|
return False # still locations required to be collected
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
44
Fill.py
44
Fill.py
|
@ -4,9 +4,10 @@ import collections
|
||||||
import itertools
|
import itertools
|
||||||
from collections import Counter, deque
|
from collections import Counter, deque
|
||||||
|
|
||||||
from BaseClasses import CollectionState, Location, LocationProgressType, MultiWorld, Item
|
from BaseClasses import CollectionState, Location, LocationProgressType, MultiWorld, Item, ItemClassification
|
||||||
|
|
||||||
from worlds.AutoWorld import call_all
|
from worlds.AutoWorld import call_all
|
||||||
|
from worlds.generic.Rules import add_item_rule
|
||||||
|
|
||||||
|
|
||||||
class FillError(RuntimeError):
|
class FillError(RuntimeError):
|
||||||
|
@ -209,6 +210,34 @@ def fast_fill(world: MultiWorld,
|
||||||
return item_pool[placing:], fill_locations[placing:]
|
return item_pool[placing:], fill_locations[placing:]
|
||||||
|
|
||||||
|
|
||||||
|
def accessibility_corrections(world: MultiWorld, state: CollectionState, locations, pool=[]):
|
||||||
|
maximum_exploration_state = sweep_from_pool(state, pool)
|
||||||
|
minimal_players = {player for player in world.player_ids if world.accessibility[player] == "minimal"}
|
||||||
|
unreachable_locations = [location for location in world.get_locations() if location.player in minimal_players and
|
||||||
|
not location.can_reach(maximum_exploration_state)]
|
||||||
|
for location in unreachable_locations:
|
||||||
|
if (location.item is not None and location.item.advancement and location.address is not None and not
|
||||||
|
location.locked and location.item.player not in minimal_players):
|
||||||
|
pool.append(location.item)
|
||||||
|
state.remove(location.item)
|
||||||
|
location.item = None
|
||||||
|
location.event = False
|
||||||
|
if location in state.events:
|
||||||
|
state.events.remove(location)
|
||||||
|
locations.append(location)
|
||||||
|
|
||||||
|
if pool:
|
||||||
|
fill_restrictive(world, state, locations, pool)
|
||||||
|
|
||||||
|
|
||||||
|
def inaccessible_location_rules(world: MultiWorld, state: CollectionState, locations):
|
||||||
|
maximum_exploration_state = sweep_from_pool(state, [])
|
||||||
|
unreachable_locations = [location for location in locations if not location.can_reach(maximum_exploration_state)]
|
||||||
|
for location in unreachable_locations:
|
||||||
|
add_item_rule(location, lambda item: not ((item.classification & 0b0011) and
|
||||||
|
world.accessibility[item.player] != 'minimal'))
|
||||||
|
|
||||||
|
|
||||||
def distribute_items_restrictive(world: MultiWorld) -> None:
|
def distribute_items_restrictive(world: MultiWorld) -> None:
|
||||||
fill_locations = sorted(world.get_unfilled_locations())
|
fill_locations = sorted(world.get_unfilled_locations())
|
||||||
world.random.shuffle(fill_locations)
|
world.random.shuffle(fill_locations)
|
||||||
|
@ -239,7 +268,15 @@ def distribute_items_restrictive(world: MultiWorld) -> None:
|
||||||
defaultlocations = locations[LocationProgressType.DEFAULT]
|
defaultlocations = locations[LocationProgressType.DEFAULT]
|
||||||
excludedlocations = locations[LocationProgressType.EXCLUDED]
|
excludedlocations = locations[LocationProgressType.EXCLUDED]
|
||||||
|
|
||||||
fill_restrictive(world, world.state, prioritylocations, progitempool, lock=True)
|
prioritylocations_lock = prioritylocations.copy()
|
||||||
|
|
||||||
|
fill_restrictive(world, world.state, prioritylocations, progitempool)
|
||||||
|
accessibility_corrections(world, world.state, prioritylocations, progitempool)
|
||||||
|
|
||||||
|
for location in prioritylocations_lock:
|
||||||
|
if location.item:
|
||||||
|
location.locked = True
|
||||||
|
|
||||||
if prioritylocations:
|
if prioritylocations:
|
||||||
defaultlocations = prioritylocations + defaultlocations
|
defaultlocations = prioritylocations + defaultlocations
|
||||||
|
|
||||||
|
@ -248,6 +285,9 @@ def distribute_items_restrictive(world: MultiWorld) -> None:
|
||||||
if progitempool:
|
if progitempool:
|
||||||
raise FillError(
|
raise FillError(
|
||||||
f'Not enough locations for progress items. There are {len(progitempool)} more items than locations')
|
f'Not enough locations for progress items. There are {len(progitempool)} more items than locations')
|
||||||
|
accessibility_corrections(world, world.state, defaultlocations)
|
||||||
|
|
||||||
|
inaccessible_location_rules(world, world.state, defaultlocations)
|
||||||
|
|
||||||
remaining_fill(world, excludedlocations, filleritempool)
|
remaining_fill(world, excludedlocations, filleritempool)
|
||||||
if excludedlocations:
|
if excludedlocations:
|
||||||
|
|
Loading…
Reference in New Issue