Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions src/Helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def resolve_yaml_option(multiworld: MultiWorld, player: int, data: dict) -> bool
option_name = option_name[1:]
required = False

option_name = format_to_valid_identifier(option_name)
if is_option_enabled(multiworld, player, option_name) != required:
return False
return True
Expand Down Expand Up @@ -205,3 +206,10 @@ def convert_to_long_string(input: str | list[str]) -> str:
if not isinstance(input, str):
return str.join("\n ", input)
return input

def format_to_valid_identifier(input: str) -> str:
"""Make sure the input is a valid python identifier"""
input = input.strip()
if input[:1].isdigit():
input = "_" + input
return input.replace(" ", "_")
28 changes: 18 additions & 10 deletions src/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
OptionGroup, StartInventoryPool, Visibility, item_and_loc_options, Option
from .hooks.Options import before_options_defined, after_options_defined, before_option_groups_created, after_option_groups_created
from .Data import category_table, game_table, option_table
from .Helpers import convert_to_long_string
from .Helpers import convert_to_long_string, format_to_valid_identifier
from .Locations import victory_names
from .Items import item_table
from .Game import starting_items
Expand Down Expand Up @@ -85,6 +85,8 @@ def addOptionToGroup(option_name: str, group: str):
for option_name, option in option_table.get('core', {}).items():
if option_name.startswith('_'): #To allow commenting out options
continue
option_display_name = option_name
option_name = format_to_valid_identifier(option_name)

if manual_options.get(option_name):
original_option: Option = manual_options[option_name]
Expand All @@ -97,18 +99,18 @@ def addOptionToGroup(option_name: str, group: str):
if original_option.__base__ != option_type: #only recreate if needed
args = getOriginalOptionArguments(original_option)
manual_options[option_name] = type(option_name, (option_type,), dict(args))
logging.debug(f"Manual: Option.json converted option '{option_name}' into a {option_type}")
logging.debug(f"Manual: Option.json converted option '{option_display_name}' into a {option_type}")

elif issubclass(original_option, Choice):
if option.get("values"):
raise Exception(f"You cannot modify the values of the '{option_name}' option since they cannot have their value changed by Option.json")
raise Exception(f"You cannot modify the values of the '{option_display_name}' option since they cannot have their value changed by Option.json")

if option.get('aliases'):
for alias, value in option['aliases'].items():
original_option.aliases[alias] = value
original_option.options.update(original_option.aliases) #for an alias to be valid it must also be in options

logging.debug(f"Manual: Option.json modified option '{option_name}''s aliases")
logging.debug(f"Manual: Option.json modified option '{option_display_name}''s aliases")

elif issubclass(original_option, Range):
if option.get('values'): #let user add named values
Expand All @@ -122,11 +124,14 @@ def addOptionToGroup(option_name: str, group: str):
args['special_range_names'] = {**args['special_range_names'], **{l.lower(): v for l, v in option['values'].items()}}

manual_options[option_name] = type(option_name, (NamedRange,), dict(args))
logging.debug(f"Manual: Option.json converted option '{option_name}' into a {NamedRange}")
logging.debug(f"Manual: Option.json converted option '{option_display_name}' into a {NamedRange}")

if option.get('display_name'):
manual_options[option_name].display_name = option['display_name']

elif option_name != option_display_name:
manual_options[option_name].display_name = option_display_name

manual_options[option_name].__doc__ = convert_to_long_string(option.get('description', original_doc))
if option.get('rich_text_doc'):
manual_options[option_name].rich_text_doc = option["rich_text_doc"]
Expand All @@ -139,24 +144,25 @@ def addOptionToGroup(option_name: str, group: str):
elif option.get('visibility'):
manual_options[option_name].visibility = convertOptionVisibility(option['visibility'])
else:
logging.debug(f"Manual: Option.json just tried to modify the option '{option_name}' but it doesn't currently exists")
logging.debug(f"Manual: Option.json just tried to modify the option '{option_display_name}' but it doesn't currently exists")


supported_option_types = ["Toggle", "Choice", "Range"]
for option_name, option in option_table.get('user', {}).items():
if option_name.startswith('_'): #To allow commenting out options
continue

option_display_name = option_name
option_name = format_to_valid_identifier(option_name)
if manual_options.get(option_name):
logging.warning(f"Manual: An option with the name '{option_name}' cannot be added since it already exists in Manual Core Options. \nTo modify an existing option move it to the 'core' section of Option.json")
logging.warning(f"Manual: An option with the name '{option_display_name}' cannot be added since it already exists in Manual Core Options. \nTo modify an existing option move it to the 'core' section of Option.json")

else:
option_type = option.get('type', "").title()

if option_type not in supported_option_types:
raise Exception(f'Option {option_name} in options.json has an invalid type of "{option["type"]}".\nIt must be one of the folowing: {supported_option_types}')
raise Exception(f'Option {option_display_name} in options.json has an invalid type of "{option["type"]}".\nIt must be one of the folowing: {supported_option_types}')

args = {'display_name': option.get('display_name', option_name)}
args = {'display_name': option.get('display_name', option_display_name)}

if option_type == "Toggle":
value = option.get('default', False)
Expand Down Expand Up @@ -199,6 +205,7 @@ def addOptionToGroup(option_name: str, group: str):
for option_name in category_table[category].get("yaml_option", []):
if option_name[0] == "!":
option_name = option_name[1:]
option_name = format_to_valid_identifier(option_name)
if option_name not in manual_options:
manual_options[option_name] = type(option_name, (DefaultOnToggle,), {"default": True})
manual_options[option_name].__doc__ = "Should items/locations linked to this option be enabled?"
Expand All @@ -209,6 +216,7 @@ def addOptionToGroup(option_name: str, group: str):
for option_name in starting_items["yaml_option"]:
if option_name[0] == "!":
option_name = option_name[1:]
option_name = format_to_valid_identifier(option_name)
if option_name not in manual_options:
manual_options[option_name] = type(option_name, (DefaultOnToggle,), {"default": True})
manual_options[option_name].__doc__ = "Should items/locations linked to this option be enabled?"
Expand Down