Core: add visibility attribute to Option (#3125)

This commit is contained in:
Fabian Dill 2024-04-14 20:49:43 +02:00 committed by GitHub
parent fb1cf26118
commit 09abc5beaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 9 deletions

View File

@ -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(

View File

@ -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()

View File

@ -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"

View File

@ -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,
} }