Core: add visibility attribute to Option (#3125)
This commit is contained in:
parent
fb1cf26118
commit
09abc5beaa
|
@ -1352,11 +1352,13 @@ class Spoiler:
|
||||||
def to_file(self, filename: str) -> None:
|
def to_file(self, filename: str) -> None:
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from worlds import AutoWorld
|
from worlds import AutoWorld
|
||||||
|
from Options import Visibility
|
||||||
|
|
||||||
def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None:
|
def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None:
|
||||||
res = getattr(self.multiworld.worlds[player].options, option_key)
|
res = getattr(self.multiworld.worlds[player].options, option_key)
|
||||||
display_name = getattr(option_obj, "display_name", option_key)
|
if res.visibility & Visibility.spoiler:
|
||||||
outfile.write(f"{display_name + ':':33}{res.current_option_name}\n")
|
display_name = getattr(option_obj, "display_name", option_key)
|
||||||
|
outfile.write(f"{display_name + ':':33}{res.current_option_name}\n")
|
||||||
|
|
||||||
with open(filename, 'w', encoding="utf-8-sig") as outfile:
|
with open(filename, 'w', encoding="utf-8-sig") as outfile:
|
||||||
outfile.write(
|
outfile.write(
|
||||||
|
|
27
Options.py
27
Options.py
|
@ -7,6 +7,7 @@ import math
|
||||||
import numbers
|
import numbers
|
||||||
import random
|
import random
|
||||||
import typing
|
import typing
|
||||||
|
import enum
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@ -20,6 +21,15 @@ if typing.TYPE_CHECKING:
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
|
|
||||||
|
class Visibility(enum.IntFlag):
|
||||||
|
none = 0b0000
|
||||||
|
template = 0b0001
|
||||||
|
simple_ui = 0b0010 # show option in simple menus, such as player-options
|
||||||
|
complex_ui = 0b0100 # show option in complex menus, such as weighted-options
|
||||||
|
spoiler = 0b1000
|
||||||
|
all = 0b1111
|
||||||
|
|
||||||
|
|
||||||
class AssembleOptions(abc.ABCMeta):
|
class AssembleOptions(abc.ABCMeta):
|
||||||
def __new__(mcs, name, bases, attrs):
|
def __new__(mcs, name, bases, attrs):
|
||||||
options = attrs["options"] = {}
|
options = attrs["options"] = {}
|
||||||
|
@ -102,6 +112,7 @@ T = typing.TypeVar('T')
|
||||||
class Option(typing.Generic[T], metaclass=AssembleOptions):
|
class Option(typing.Generic[T], metaclass=AssembleOptions):
|
||||||
value: T
|
value: T
|
||||||
default: typing.ClassVar[typing.Any] # something that __init__ will be able to convert to the correct type
|
default: typing.ClassVar[typing.Any] # something that __init__ will be able to convert to the correct type
|
||||||
|
visibility = Visibility.all
|
||||||
|
|
||||||
# convert option_name_long into Name Long as display_name, otherwise name_long is the result.
|
# convert option_name_long into Name Long as display_name, otherwise name_long is the result.
|
||||||
# Handled in get_option_name()
|
# Handled in get_option_name()
|
||||||
|
@ -1115,6 +1126,17 @@ class ItemLinks(OptionList):
|
||||||
link.setdefault("link_replacement", None)
|
link.setdefault("link_replacement", None)
|
||||||
|
|
||||||
|
|
||||||
|
class Removed(FreeText):
|
||||||
|
"""This Option has been Removed."""
|
||||||
|
default = ""
|
||||||
|
visibility = Visibility.none
|
||||||
|
|
||||||
|
def __init__(self, value: str):
|
||||||
|
if value:
|
||||||
|
raise Exception("Option removed, please update your options file.")
|
||||||
|
super().__init__(value)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PerGameCommonOptions(CommonOptions):
|
class PerGameCommonOptions(CommonOptions):
|
||||||
local_items: LocalItems
|
local_items: LocalItems
|
||||||
|
@ -1170,7 +1192,10 @@ def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], ge
|
||||||
|
|
||||||
for game_name, world in AutoWorldRegister.world_types.items():
|
for game_name, world in AutoWorldRegister.world_types.items():
|
||||||
if not world.hidden or generate_hidden:
|
if not world.hidden or generate_hidden:
|
||||||
all_options: typing.Dict[str, AssembleOptions] = world.options_dataclass.type_hints
|
all_options: typing.Dict[str, AssembleOptions] = {
|
||||||
|
option_name: option for option_name, option in world.options_dataclass.type_hints.items()
|
||||||
|
if option.visibility & Visibility.template
|
||||||
|
}
|
||||||
|
|
||||||
with open(local_path("data", "options.yaml")) as f:
|
with open(local_path("data", "options.yaml")) as f:
|
||||||
file_data = f.read()
|
file_data = f.read()
|
||||||
|
|
|
@ -45,7 +45,15 @@ def create():
|
||||||
}
|
}
|
||||||
|
|
||||||
game_options = {}
|
game_options = {}
|
||||||
|
visible: typing.Set[str] = set()
|
||||||
|
visible_weighted: typing.Set[str] = set()
|
||||||
|
|
||||||
for option_name, option in all_options.items():
|
for option_name, option in all_options.items():
|
||||||
|
if option.visibility & Options.Visibility.simple_ui:
|
||||||
|
visible.add(option_name)
|
||||||
|
if option.visibility & Options.Visibility.complex_ui:
|
||||||
|
visible_weighted.add(option_name)
|
||||||
|
|
||||||
if option_name in handled_in_js:
|
if option_name in handled_in_js:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -116,8 +124,6 @@ def create():
|
||||||
else:
|
else:
|
||||||
logging.debug(f"{option} not exported to Web Options.")
|
logging.debug(f"{option} not exported to Web Options.")
|
||||||
|
|
||||||
player_options["gameOptions"] = game_options
|
|
||||||
|
|
||||||
player_options["presetOptions"] = {}
|
player_options["presetOptions"] = {}
|
||||||
for preset_name, preset in world.web.options_presets.items():
|
for preset_name, preset in world.web.options_presets.items():
|
||||||
player_options["presetOptions"][preset_name] = {}
|
player_options["presetOptions"][preset_name] = {}
|
||||||
|
@ -156,12 +162,23 @@ def create():
|
||||||
|
|
||||||
os.makedirs(os.path.join(target_folder, 'player-options'), exist_ok=True)
|
os.makedirs(os.path.join(target_folder, 'player-options'), exist_ok=True)
|
||||||
|
|
||||||
|
filtered_player_options = player_options
|
||||||
|
filtered_player_options["gameOptions"] = {
|
||||||
|
option_name: option_data for option_name, option_data in game_options.items()
|
||||||
|
if option_name in visible
|
||||||
|
}
|
||||||
|
|
||||||
with open(os.path.join(target_folder, 'player-options', game_name + ".json"), "w") as f:
|
with open(os.path.join(target_folder, 'player-options', game_name + ".json"), "w") as f:
|
||||||
json.dump(player_options, f, indent=2, separators=(',', ': '))
|
json.dump(filtered_player_options, f, indent=2, separators=(',', ': '))
|
||||||
|
|
||||||
|
filtered_player_options["gameOptions"] = {
|
||||||
|
option_name: option_data for option_name, option_data in game_options.items()
|
||||||
|
if option_name in visible_weighted
|
||||||
|
}
|
||||||
|
|
||||||
if not world.hidden and world.web.options_page is True:
|
if not world.hidden and world.web.options_page is True:
|
||||||
# Add the random option to Choice, TextChoice, and Toggle options
|
# Add the random option to Choice, TextChoice, and Toggle options
|
||||||
for option in game_options.values():
|
for option in filtered_player_options["gameOptions"].values():
|
||||||
if option["type"] == "select":
|
if option["type"] == "select":
|
||||||
option["options"].append({"name": "Random", "value": "random"})
|
option["options"].append({"name": "Random", "value": "random"})
|
||||||
|
|
||||||
|
@ -170,7 +187,7 @@ def create():
|
||||||
|
|
||||||
weighted_options["baseOptions"]["game"][game_name] = 0
|
weighted_options["baseOptions"]["game"][game_name] = 0
|
||||||
weighted_options["games"][game_name] = {
|
weighted_options["games"][game_name] = {
|
||||||
"gameSettings": game_options,
|
"gameSettings": filtered_player_options["gameOptions"],
|
||||||
"gameItems": tuple(world.item_names),
|
"gameItems": tuple(world.item_names),
|
||||||
"gameItemGroups": [
|
"gameItemGroups": [
|
||||||
group for group in world.item_name_groups.keys() if group != "Everything"
|
group for group in world.item_name_groups.keys() if group != "Everything"
|
||||||
|
|
|
@ -2,7 +2,7 @@ import typing
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, StartInventoryPool, PlandoBosses,\
|
from Options import Choice, Range, Option, Toggle, DefaultOnToggle, DeathLink, StartInventoryPool, PlandoBosses,\
|
||||||
FreeText
|
FreeText, Removed
|
||||||
|
|
||||||
|
|
||||||
class GlitchesRequired(Choice):
|
class GlitchesRequired(Choice):
|
||||||
|
@ -795,4 +795,9 @@ alttp_options: typing.Dict[str, type(Option)] = {
|
||||||
"music": Music,
|
"music": Music,
|
||||||
"reduceflashing": ReduceFlashing,
|
"reduceflashing": ReduceFlashing,
|
||||||
"triforcehud": TriforceHud,
|
"triforcehud": TriforceHud,
|
||||||
|
|
||||||
|
# removed:
|
||||||
|
"goals": Removed,
|
||||||
|
"smallkey_shuffle": Removed,
|
||||||
|
"bigkey_shuffle": Removed,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue