diff --git a/Generate.py b/Generate.py index 52babdf18839..24a1e3e41777 100644 --- a/Generate.py +++ b/Generate.py @@ -378,6 +378,35 @@ def roll_linked_options(weights: dict) -> dict: return weights +def compare_results( + yaml_value: Union[str, int, bool, dict, list], + trigger_value: Union[str, int, bool, dict, list], + comparator: str): + if yaml_value is None: + return False + if isinstance(yaml_value, str|bool|int) and isinstance(trigger_value, str|bool|int): + yaml_value = str(yaml_value).lower() + trigger_value = str(trigger_value).lower() + if comparator == "=": + return yaml_value == trigger_value + if comparator == "!=": + return yaml_value != trigger_value + try: + yaml_value = int(yaml_value) + trigger_value = int(trigger_value) + except ValueError: + raise Exception("Value of option_name and option_result must be integers if comparison is not = or !=") + if comparator == "<": + return yaml_value < trigger_value + if comparator == "<=": + return yaml_value <= trigger_value + if comparator == ">": + return yaml_value > trigger_value + if comparator == ">=": + return yaml_value >= trigger_value + raise ValueError(f"option_compare must be one of [=,<,<=,>=,>,!=]") + + def roll_triggers(weights: dict, triggers: list, valid_keys: set) -> dict: weights = copy.deepcopy(weights) # make sure we don't write back to other weights sets in same_settings weights["_Generator_Version"] = Utils.__version__ @@ -385,6 +414,8 @@ def roll_triggers(weights: dict, triggers: list, valid_keys: set) -> dict: try: currently_targeted_weights = weights category = option_set.get("option_category", None) + if "option_compare" not in option_set: + option_set["option_compare"] = "=" if category: currently_targeted_weights = currently_targeted_weights[category] key = get_choice("option_name", option_set) @@ -394,8 +425,10 @@ def roll_triggers(weights: dict, triggers: list, valid_keys: set) -> dict: f'This is probably in error.') trigger_result = get_choice("option_result", option_set) result = get_choice(key, currently_targeted_weights) + compare = get_choice("option_compare", option_set) currently_targeted_weights[key] = result - if result == trigger_result and roll_percentage(get_choice("percentage", option_set, 100)): + if (compare_results(result, trigger_result, compare) and + roll_percentage(get_choice("percentage", option_set, 100))): for category_name, category_options in option_set["options"].items(): currently_targeted_weights = weights if category_name: diff --git a/worlds/generic/docs/triggers_en.md b/worlds/generic/docs/triggers_en.md index b751b8a3ec01..fd78830a671c 100644 --- a/worlds/generic/docs/triggers_en.md +++ b/worlds/generic/docs/triggers_en.md @@ -20,7 +20,7 @@ For more information on plando, you can reference the [general plando guide](/tu Triggers may be defined in either the root or in the relevant game sections. Generally, the best place to do this is the bottom of the YAML for clear organization. -Each trigger consists of four parts: +Each trigger consists of at least four parts: - `option_category` specifies the section which the triggering option is defined in. - Example: `A Link to the Past` - This is the category the option is located in. If the option you're triggering off of is in root then you @@ -32,6 +32,9 @@ Each trigger consists of four parts: - Example: `15` - Each trigger must be used for exactly one option result. If you would like the same thing to occur with multiple results, you would need multiple triggers for this. +- `option_compare` is an optional argument that specifies how the value of the option is compared. Valid values are "=" +, "<", "<=", ">=", ">", or "!=". This defaults to "=" if not specified. + - Example: `"<"` - `options` is where you define what will happen when the trigger activates. This can be something as simple as ensuring another option also gets selected or placing an item in a certain location. It is possible to have multiple things happen in this section. @@ -59,13 +62,14 @@ The above examples all together will end up looking like this: - option_category: A Link to the Past option_name: shop_item_slots option_result: 15 + option_compare: "<=" options: A Link to the Past: start_inventory: Rupees(300): 2 ``` -For this example, if the generator happens to roll 15 shuffled in shop item slots for your game, you'll be granted 600 +For this example, if the generator happens to roll 15 or fewer shuffled in shop item slots for your game, you'll be granted 600 rupees at the beginning. Triggers can also be used to change other options. For example: