diff --git a/BaseClasses.py b/BaseClasses.py index 854b34a8..e1df8cf3 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -218,12 +218,14 @@ class MultiWorld(): raise Exception(f"Cannot ItemLink across games. Link: {item_link['name']}") item_links[item_link["name"]]["players"][player] = item_link["replacement_item"] item_links[item_link["name"]]["item_pool"] &= set(item_link["item_pool"]) + item_links[item_link["name"]]["exclude"] |= set(item_link.get("exclude", [])) else: if item_link["name"] in self.player_name.values(): raise Exception(f"Cannot name a ItemLink group the same as a player ({item_link['name']}) ({self.get_player_name(player)}).") item_links[item_link["name"]] = { "players": {player: item_link["replacement_item"]}, "item_pool": set(item_link["item_pool"]), + "exclude": set(item_link.get("exclude", [])), "game": self.game[player] } @@ -232,6 +234,8 @@ class MultiWorld(): pool = set() for item in item_link["item_pool"]: pool |= current_item_name_groups.get(item, {item}) + for item in item_link["exclude"]: + pool -= current_item_name_groups.get(item, {item}) item_link["item_pool"] = pool for group_name, item_link in item_links.items(): diff --git a/Options.py b/Options.py index 5a96c620..2ce42289 100644 --- a/Options.py +++ b/Options.py @@ -5,10 +5,9 @@ import numbers import typing import random -from schema import Schema, And, Or +from schema import Schema, And, Or, Optional from Utils import get_fuzzy_results - class AssembleOptions(abc.ABCMeta): def __new__(mcs, name, bases, attrs): options = attrs["options"] = {} @@ -642,6 +641,7 @@ class ItemLinks(OptionList): { "name": And(str, len), "item_pool": [And(str, len)], + Optional("exclude"): [And(str, len)], "replacement_item": Or(And(str, len), None) } ]) @@ -657,6 +657,11 @@ class ItemLinks(OptionList): if item_name not in world.item_names and item_name not in world.item_name_groups: raise Exception(f"Item {item_name} from item link {link} " f"is not a valid item name from {world.game}") + if "exclude" in link: + for item_name in link["exclude"]: + if item_name not in world.item_names and item_name not in world.item_name_groups: + raise Exception(f"Item {item_name} from item link {link} " + f"is not a valid item name from {world.game}") if link["replacement_item"] and link["replacement_item"] not in world.item_names: raise Exception(f"Item {link['replacement_item']} from item link {link} " f"is not a valid item name from {world.game}")