diff --git a/docs/options api.md b/docs/options api.md index aedd5d76aaa7..cba383232b67 100644 --- a/docs/options api.md +++ b/docs/options api.md @@ -132,7 +132,8 @@ or if I need a boolean object, such as in my slot_data I can access it as: start_with_sword = bool(self.options.starting_sword.value) ``` All numeric options (i.e. Toggle, Choice, Range) can be compared to integers, strings that match their attributes, -strings that match the option attributes after "option_" is stripped, and the attributes themselves. +strings that match the option attributes after "option_" is stripped, and the attributes themselves. The option can +also be checked to see if it exists within a collection, but this will fail for a set of strings due to hashing. ```python # options.py class Logic(Choice): @@ -144,6 +145,12 @@ class Logic(Choice): alias_extra_hard = 2 crazy = 4 # won't be listed as an option and only exists as an attribute on the class +class Weapon(Choice): + option_none = 0 + option_sword = 1 + option_bow = 2 + option_hammer = 3 + # __init__.py from .options import Logic @@ -157,6 +164,16 @@ elif self.options.logic == Logic.option_extreme: do_extreme_things() elif self.options.logic == "crazy": do_insane_things() + +# check if the current option is in a collection of integers using the class attributes +if self.options.weapon in {Weapon.option_bow, Weapon.option_sword}: + do_stuff() +# in order to make a set of strings work, we have to compare against current_key +elif self.options.weapon.current_key in {"none", "hammer"}: + do_something_else() +# though it's usually better to just use a tuple instead +elif self.options.weapon in ("none", "hammer"): + do_something_else() ``` ## Generic Option Classes These options are generically available to every game automatically, but can be overridden for slightly different diff --git a/test/options/__init__.py b/test/options/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/options/test_option_classes.py b/test/options/test_option_classes.py new file mode 100644 index 000000000000..8e2c4702c380 --- /dev/null +++ b/test/options/test_option_classes.py @@ -0,0 +1,67 @@ +import unittest + +from Options import Choice, DefaultOnToggle, Toggle + + +class TestNumericOptions(unittest.TestCase): + def test_numeric_option(self) -> None: + """Tests the initialization and equivalency comparisons of the base Numeric Option class.""" + class TestChoice(Choice): + option_zero = 0 + option_one = 1 + option_two = 2 + alias_three = 1 + non_option_attr = 2 + + class TestToggle(Toggle): + pass + + class TestDefaultOnToggle(DefaultOnToggle): + pass + + with self.subTest("choice"): + choice_option_default = TestChoice.from_any(TestChoice.default) + choice_option_string = TestChoice.from_any("one") + choice_option_int = TestChoice.from_any(2) + choice_option_alias = TestChoice.from_any("three") + choice_option_attr = TestChoice.from_any(TestChoice.option_two) + + self.assertEqual(choice_option_default, TestChoice.option_zero, + "assigning default didn't match default value") + self.assertEqual(choice_option_string, "one") + self.assertEqual(choice_option_int, 2) + self.assertEqual(choice_option_alias, TestChoice.alias_three) + self.assertEqual(choice_option_attr, TestChoice.non_option_attr) + + self.assertRaises(KeyError, TestChoice.from_any, "four") + + self.assertIn(choice_option_int, [1, 2, 3]) + self.assertIn(choice_option_int, {2}) + self.assertIn(choice_option_int, (2,)) + + self.assertIn(choice_option_string, ["one", "two", "three"]) + # this fails since the hash is derived from the value + self.assertNotIn(choice_option_string, {"one"}) + self.assertIn(choice_option_string, ("one",)) + + with self.subTest("toggle"): + toggle_default = TestToggle.from_any(TestToggle.default) + toggle_string = TestToggle.from_any("false") + toggle_int = TestToggle.from_any(0) + toggle_alias = TestToggle.from_any("off") + + self.assertFalse(toggle_default) + self.assertFalse(toggle_string) + self.assertFalse(toggle_int) + self.assertFalse(toggle_alias) + + with self.subTest("on toggle"): + toggle_default = TestDefaultOnToggle.from_any(TestDefaultOnToggle.default) + toggle_string = TestDefaultOnToggle.from_any("true") + toggle_int = TestDefaultOnToggle.from_any(1) + toggle_alias = TestDefaultOnToggle.from_any("on") + + self.assertTrue(toggle_default) + self.assertTrue(toggle_string) + self.assertTrue(toggle_int) + self.assertTrue(toggle_alias)