update Options system, preparing for integration
This commit is contained in:
parent
1d58f54101
commit
68a1070237
162
Options.py
162
Options.py
|
@ -1,86 +1,142 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from enum import IntEnum, auto, Enum
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Toggle(IntEnum):
|
class AssembleOptions(type):
|
||||||
off = 0
|
def __new__(cls, name, bases, attrs):
|
||||||
on = 1
|
options = attrs["options"] = {}
|
||||||
|
name_lookup = attrs["name_lookup"] = {}
|
||||||
|
for base in bases:
|
||||||
|
options.update(base.options)
|
||||||
|
name_lookup.update(name_lookup)
|
||||||
|
new_options = {name[7:].lower(): option_id for name, option_id in attrs.items() if
|
||||||
|
name.startswith("option_")}
|
||||||
|
attrs["name_lookup"].update({option_id: name for name, option_id in new_options.items()})
|
||||||
|
options.update(new_options)
|
||||||
|
|
||||||
|
#apply aliases, without name_lookup
|
||||||
|
options.update({name[6:].lower(): option_id for name, option_id in attrs.items() if
|
||||||
|
name.startswith("alias_")})
|
||||||
|
return super(AssembleOptions, cls).__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
|
|
||||||
|
class Option(metaclass=AssembleOptions):
|
||||||
|
value: int
|
||||||
|
name_lookup: typing.Dict[int, str]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.__class__.__name__}({self.get_option_name()})"
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.value)
|
||||||
|
|
||||||
|
def get_option_name(self):
|
||||||
|
return self.name_lookup[self.value]
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.value)
|
||||||
|
|
||||||
|
|
||||||
|
class Toggle(Option):
|
||||||
|
option_false = 0
|
||||||
|
option_true = 1
|
||||||
|
|
||||||
|
def __init__(self, value: int):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_text(cls, text: str) -> Toggle:
|
def from_text(cls, text: str) -> Toggle:
|
||||||
if text.lower() in {"off", "0", "false", "none", "null", "no"}:
|
if text.lower() in {"off", "0", "false", "none", "null", "no"}:
|
||||||
return Toggle.off
|
return cls(0)
|
||||||
else:
|
else:
|
||||||
return Toggle.on
|
return cls(1)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, Toggle):
|
||||||
|
return self.value == other.value
|
||||||
|
else:
|
||||||
|
return self.value == other
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if isinstance(other, Toggle):
|
||||||
|
return self.value > other.value
|
||||||
|
else:
|
||||||
|
return self.value > other
|
||||||
|
|
||||||
|
def get_option_name(self):
|
||||||
|
return bool(self.value)
|
||||||
|
|
||||||
|
class Choice(Option):
|
||||||
|
def __init__(self, value: int):
|
||||||
|
self.value: int = value
|
||||||
|
|
||||||
class Choice(IntEnum):
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_text(cls, text: str) -> Choice:
|
def from_text(cls, text: str) -> Choice:
|
||||||
for option in cls:
|
|
||||||
if option.name == text.lower():
|
for optionname, value in cls.options.items():
|
||||||
return option
|
if optionname == text.lower():
|
||||||
|
return cls(value)
|
||||||
raise KeyError(
|
raise KeyError(
|
||||||
f'Could not find option "{text}" for "{cls.__name__}", known options are {", ".join(f"{option.name}" for option in cls)}')
|
f'Could not find option "{text}" for "{cls.__name__}", '
|
||||||
|
f'known options are {", ".join(f"{option}" for option in cls.name_lookup.values())}')
|
||||||
|
|
||||||
|
|
||||||
class Logic(Choice):
|
class Logic(Choice):
|
||||||
no_glitches = auto()
|
option_no_glitches = 0
|
||||||
no_logic = auto()
|
option_minor_glitches = 1
|
||||||
|
option_overworld_glitches = 2
|
||||||
|
option_no_logic = 4
|
||||||
|
alias_owg = 2
|
||||||
|
|
||||||
|
|
||||||
class Goal(Choice):
|
class Goal(Choice):
|
||||||
ganon = auto()
|
option_ganon = 0
|
||||||
fast_ganon = auto()
|
option_fast_ganon = 1
|
||||||
all_dungeons = auto()
|
option_all_dungeons = 2
|
||||||
pedestal = auto()
|
option_pedestal = 3
|
||||||
triforce_hunt = auto()
|
option_triforce_hunt = 4
|
||||||
|
|
||||||
|
|
||||||
class Accessibility(Choice):
|
class Accessibility(Choice):
|
||||||
locations = auto()
|
option_locations = 0
|
||||||
items = auto()
|
option_items = 1
|
||||||
beatable = auto()
|
option_beatable = 2
|
||||||
|
|
||||||
|
|
||||||
class Crystals(Enum):
|
class Crystals(Choice):
|
||||||
# can't use IntEnum since there's also random
|
# can't use IntEnum since there's also random
|
||||||
C0 = 0
|
option_0 = 0
|
||||||
C1 = 1
|
option_1 = 1
|
||||||
C2 = 2
|
option_2 = 2
|
||||||
C3 = 3
|
option_3 = 3
|
||||||
C4 = 4
|
option_4 = 4
|
||||||
C5 = 5
|
option_5 = 5
|
||||||
C6 = 6
|
option_6 = 6
|
||||||
C7 = 7
|
option_7 = 7
|
||||||
Random = -1
|
option_random = -1
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_text(text: str) -> Crystals:
|
|
||||||
for option in Crystals:
|
|
||||||
if str(option.value) == text.lower():
|
|
||||||
return option
|
|
||||||
return Crystals.Random
|
|
||||||
|
|
||||||
|
|
||||||
class WorldState(Choice):
|
class WorldState(Choice):
|
||||||
standard = auto()
|
option_standard = 1
|
||||||
open = auto()
|
option_open = 0
|
||||||
retro = auto()
|
option_inverted = 2
|
||||||
inverted = auto()
|
|
||||||
|
|
||||||
|
|
||||||
class Bosses(Choice):
|
class Bosses(Choice):
|
||||||
vanilla = auto()
|
option_vanilla = 0
|
||||||
simple = auto()
|
option_simple = 1
|
||||||
full = auto()
|
option_full = 2
|
||||||
chaos = auto()
|
option_chaos = 3
|
||||||
|
option_singularity = 4
|
||||||
|
|
||||||
|
|
||||||
class Enemies(Choice):
|
class Enemies(Choice):
|
||||||
vanilla = auto()
|
option_vanilla = 0
|
||||||
shuffled = auto()
|
option_shuffled = 1
|
||||||
chaos = auto()
|
option_chaos = 2
|
||||||
|
|
||||||
|
|
||||||
mapshuffle = Toggle
|
mapshuffle = Toggle
|
||||||
|
@ -95,10 +151,16 @@ if __name__ == "__main__":
|
||||||
test = argparse.Namespace()
|
test = argparse.Namespace()
|
||||||
test.logic = Logic.from_text("no_logic")
|
test.logic = Logic.from_text("no_logic")
|
||||||
test.mapshuffle = mapshuffle.from_text("ON")
|
test.mapshuffle = mapshuffle.from_text("ON")
|
||||||
|
test.hints = hints.from_text('OFF')
|
||||||
try:
|
try:
|
||||||
test.logic = Logic.from_text("owg")
|
test.logic = Logic.from_text("overworld_glitches_typo")
|
||||||
|
except KeyError as e:
|
||||||
|
print(e)
|
||||||
|
try:
|
||||||
|
test.logic_owg = Logic.from_text("owg")
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print(e)
|
print(e)
|
||||||
if test.mapshuffle:
|
if test.mapshuffle:
|
||||||
print("Mapshuffle is on")
|
print("Mapshuffle is on")
|
||||||
|
print(f"Hints are {bool(test.hints)}")
|
||||||
print(test)
|
print(test)
|
||||||
|
|
Loading…
Reference in New Issue