Fix minimal accessibility failures (#726)

This commit is contained in:
Alchav 2022-09-29 13:59:57 -04:00 committed by GitHub
parent e6a4925f0c
commit 885c8d3fcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 4 deletions

View File

@ -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
View File

@ -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: