Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 40 additions & 16 deletions src/Helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,35 @@ def is_category_enabled(multiworld: MultiWorld, player: int, category_name: str)
return hook_result

category_data = category_table.get(category_name, {})
return resolve_yaml_option(multiworld, player, category_data)
resolve_option = resolve_yaml_option(multiworld, player, category_data)
return resolve_option or resolve_option is None

def resolve_yaml_option(multiworld: MultiWorld, player: int, data: dict) -> bool:
if "yaml_option" in data:
for option_name in data["yaml_option"]:
required = True
eval_f = lambda x: x.value
if "<" in option_name:
option_name, target = option_name.split("<")
eval_f = lambda x: x.value < int(target)
elif ">" in option_name:
option_name, target = option_name.split(">")
eval_f = lambda x: x.value > int(target)
elif "=" in option_name:
option_name, target = option_name.split("=")
eval_f = lambda x: x.value == int(target)
elif ":" in option_name:
option_name, target = option_name.split(":")
eval_f = lambda x: x.current_key == target
if option_name.startswith("!"):
option_name = option_name[1:]
required = False

eval_f = lambda x: not eval_f(x)
option_name = format_to_valid_identifier(option_name)
if is_option_enabled(multiworld, player, option_name) != required:
option = getattr(multiworld.worlds[player].options, option_name, None)
if not eval_f(option):
return False
return True
return True
return None

def is_item_name_enabled(multiworld: MultiWorld, player: int, item_name: str) -> bool:
"""Check if an item named 'item_name' has been disabled by a yaml option."""
Expand All @@ -86,12 +101,17 @@ def is_item_name_enabled(multiworld: MultiWorld, player: int, item_name: str) ->
return is_item_enabled(multiworld, player, item)

def is_item_enabled(multiworld: MultiWorld, player: int, item: "ManualItem") -> bool:
from .Data import item_table
"""Check if an item has been disabled by a yaml option."""
hook_result = before_is_item_enabled(multiworld, player, item)
if hook_result is not None:
return hook_result

return _is_manualobject_enabled(multiworld, player, item)

try_resolve = resolve_yaml_option(multiworld, player, item_table.get(item.name, {}))
if try_resolve is None:
return _is_manualobject_enabled(multiworld, player, item)
else:
return try_resolve

def is_location_name_enabled(multiworld: MultiWorld, player: int, location_name: str) -> bool:
"""Check if a location named 'location_name' has been disabled by a yaml option."""
Expand All @@ -102,24 +122,28 @@ def is_location_name_enabled(multiworld: MultiWorld, player: int, location_name:
return is_location_enabled(multiworld, player, location)

def is_location_enabled(multiworld: MultiWorld, player: int, location: "ManualLocation") -> bool:
from .Data import location_table
"""Check if a location has been disabled by a yaml option."""
hook_result = before_is_location_enabled(multiworld, player, location)
if hook_result is not None:
return hook_result

return _is_manualobject_enabled(multiworld, player, location)

try_resolve = resolve_yaml_option(multiworld, player, location_table.get(location.name, {}))
if try_resolve is None:
return _is_manualobject_enabled(multiworld, player, location)
else:
return try_resolve

def _is_manualobject_enabled(multiworld: MultiWorld, player: int, object: any) -> bool:
"""Internal method: Check if a Manual Object has any category disabled by a yaml option.
\nPlease use the proper is_'item/location'_enabled or is_'item/location'_name_enabled methods instead.
"""
enabled = True
for category in object.get("category", []):
if not is_category_enabled(multiworld, player, category):
enabled = False
break

return enabled
resolve = is_category_enabled(multiworld, player, category)
if resolve == False:
return False
return True

def get_items_for_player(multiworld: MultiWorld, player: int, includePrecollected: bool = False) -> List[Item]:
"""Return list of items of a player including placed items"""
Expand Down
6 changes: 6 additions & 0 deletions src/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def addOptionToGroup(option_name: str, group: str):

for category in category_table:
for option_name in category_table[category].get("yaml_option", []):
for c in "><=:": # Range and Choice options must be defined using Options.json
if c in option_name:
continue
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this check for option_name in manual_options, and throw an exception if they forgot to define it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e5f27a8

if option_name[0] == "!":
option_name = option_name[1:]
option_name = format_to_valid_identifier(option_name)
Expand All @@ -214,6 +217,9 @@ def addOptionToGroup(option_name: str, group: str):
for starting_items in starting_items:
if starting_items.get("yaml_option"):
for option_name in starting_items["yaml_option"]:
for c in "><=:": # Range and Choice options must be defined using Options.json
if c in option_name:
continue
if option_name[0] == "!":
option_name = option_name[1:]
option_name = format_to_valid_identifier(option_name)
Expand Down