From 59a56c803ab00369dd0f67b10695ea6a2cee027c Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Mon, 14 Jun 2021 23:42:13 +0200 Subject: [PATCH] Log which player's plando has caused a placement failure --- Fill.py | 127 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/Fill.py b/Fill.py index 34807be5..789d6eaa 100644 --- a/Fill.py +++ b/Fill.py @@ -367,69 +367,72 @@ def distribute_planned(world: MultiWorld): world_name_lookup = world.world_name_lookup for player in world.player_ids: - placement: PlandoItem - for placement in world.plando_items[player]: - if placement.location in key_drop_data: - placement.warn( - f"Can't place '{placement.item}' at '{placement.location}', as key drop shuffle locations are not supported yet.") - continue - item = ItemFactory(placement.item, player) - target_world: int = placement.world - if target_world is False or world.players == 1: - target_world = player # in own world - elif target_world is True: # in any other world - unfilled = list(location for location in world.get_unfilled_locations_for_players( - placement.location, - set(world.player_ids) - {player}) if location.item_rule(item) - ) - if not unfilled: - placement.failed(f"Could not find a world with an unfilled location {placement.location}", - FillError) + try: + placement: PlandoItem + for placement in world.plando_items[player]: + if placement.location in key_drop_data: + placement.warn( + f"Can't place '{placement.item}' at '{placement.location}', as key drop shuffle locations are not supported yet.") + continue + item = ItemFactory(placement.item, player) + target_world: int = placement.world + if target_world is False or world.players == 1: + target_world = player # in own world + elif target_world is True: # in any other world + unfilled = list(location for location in world.get_unfilled_locations_for_players( + placement.location, + set(world.player_ids) - {player}) if location.item_rule(item) + ) + if not unfilled: + placement.failed(f"Could not find a world with an unfilled location {placement.location}", + FillError) + continue + + target_world = world.random.choice(unfilled).player + + elif target_world is None: # any random world + unfilled = list(location for location in world.get_unfilled_locations_for_players( + placement.location, + set(world.player_ids)) if location.item_rule(item) + ) + if not unfilled: + placement.failed(f"Could not find a world with an unfilled location {placement.location}", + FillError) + continue + + target_world = world.random.choice(unfilled).player + + elif type(target_world) == int: # target world by player id + if target_world not in range(1, world.players + 1): + placement.failed( + f"Cannot place item in world {target_world} as it is not in range of (1, {world.players})", + ValueError) + continue + else: # find world by name + if target_world not in world_name_lookup: + placement.failed(f"Cannot place item to {target_world}'s world as that world does not exist.", + ValueError) + continue + target_world = world_name_lookup[target_world] + + location = world.get_location(placement.location, target_world) + if location.item: + placement.failed(f"Cannot place item into already filled location {location}.") continue - target_world = world.random.choice(unfilled).player - - elif target_world is None: # any random world - unfilled = list(location for location in world.get_unfilled_locations_for_players( - placement.location, - set(world.player_ids)) if location.item_rule(item) - ) - if not unfilled: - placement.failed(f"Could not find a world with an unfilled location {placement.location}", - FillError) + if location.can_fill(world.state, item, False): + world.push_item(location, item, collect=False) + location.event = True # flag location to be checked during fill + location.locked = True + logging.debug(f"Plando placed {item} at {location}") + else: + placement.failed(f"Can't place {item} at {location} due to fill condition not met.") continue - target_world = world.random.choice(unfilled).player - - elif type(target_world) == int: # target world by player id - if target_world not in range(1, world.players + 1): - placement.failed( - f"Cannot place item in world {target_world} as it is not in range of (1, {world.players})", - ValueError) - continue - else: # find world by name - if target_world not in world_name_lookup: - placement.failed(f"Cannot place item to {target_world}'s world as that world does not exist.", - ValueError) - continue - target_world = world_name_lookup[target_world] - - location = world.get_location(placement.location, target_world) - if location.item: - placement.failed(f"Cannot place item into already filled location {location}.") - continue - - if location.can_fill(world.state, item, False): - world.push_item(location, item, collect=False) - location.event = True # flag location to be checked during fill - location.locked = True - logging.debug(f"Plando placed {item} at {location}") - else: - placement.failed(f"Can't place {item} at {location} due to fill condition not met.") - continue - - if placement.from_pool: # Should happen AFTER the item is placed, in case it was allowed to skip failed placement. - try: - world.itempool.remove(item) - except ValueError: - placement.warn(f"Could not remove {item} from pool as it's already missing from it.") + if placement.from_pool: # Should happen AFTER the item is placed, in case it was allowed to skip failed placement. + try: + world.itempool.remove(item) + except ValueError: + placement.warn(f"Could not remove {item} from pool as it's already missing from it.") + except Exception as e: + raise Exception(f"Error running plando for player {player} ({world.player_names[player]})") from e