From e30f364bbda5208e5593939bf877327687cf15fe Mon Sep 17 00:00:00 2001 From: blastron Date: Wed, 16 Aug 2023 07:03:41 -0700 Subject: [PATCH] Witness: Fix for Witness plando crashes. (#2092) --- worlds/witness/__init__.py | 5 +++++ worlds/witness/items.py | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index ccbacb41..f0520275 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -234,6 +234,11 @@ class WitnessWorld(World): return slot_data def create_item(self, item_name: str) -> Item: + # If the player's plando options are malformed, the item_name parameter could be a dictionary containing the + # name of the item, rather than the item itself. This is a workaround to prevent a crash. + if type(item_name) is dict: + item_name = list(item_name.keys())[0] + # this conditional is purely for unit tests, which need to be able to create an item before generate_early item_data: ItemData if hasattr(self, 'items') and self.items and item_name in self.items.item_data: diff --git a/worlds/witness/items.py b/worlds/witness/items.py index b8e439d7..7e083534 100644 --- a/worlds/witness/items.py +++ b/worlds/witness/items.py @@ -219,17 +219,21 @@ class WitnessPlayerItems: # regardless of whether or not they actually wind up being manually placed. for plando_setting in self._world.plando_items[self._player_id]: if plando_setting.get("from_pool", True): - for item_setting_key in (key for key in ["item", "items"] if key in plando_setting): + for item_setting_key in [key for key in ["item", "items"] if key in plando_setting]: if type(plando_setting[item_setting_key]) is str: - output.remove(plando_setting[item_setting_key]) + output -= {plando_setting[item_setting_key]} elif type(plando_setting[item_setting_key]) is dict: output -= {item for item, weight in plando_setting[item_setting_key].items() if weight} else: # Assume this is some other kind of iterable. - output -= plando_setting[item_setting_key] + for inner_item in plando_setting[item_setting_key]: + if type(inner_item) is str: + output -= {inner_item} + elif type(inner_item) is dict: + output -= {item for item, weight in inner_item.items() if weight} # Sort the output for consistency across versions if the implementation changes but the logic does not. - return sorted(output) + return sorted(list(output)) def get_door_ids_in_pool(self) -> List[int]: """