diff --git a/dump.yaml b/dump.yaml index 635c1185..aef6a0c3 100644 --- a/dump.yaml +++ b/dump.yaml @@ -12957,3 +12957,442 @@ dungeon_completion_requirements: Ancient Cistern: \Ancient Cistern\Flame Room\Farore's Flame Sandship: \Sandship\Boss Room\Nayru's Flame Fire Sanctuary: \Fire Sanctuary\Flame Room\Din's Flame +well_known_requirements: + open_got: \GoT Opening Requirement + raise_got: \GoT Raising Requirement + horde_door: \Horde Door Requirement + impa_song_check: \Faron\Sealed Grounds\Sealed Temple\Song from Impa + complete_triforce: \Complete Triforce +options: + Open Thunderhead option: + type: query + option: open-thunderhead + op: eq + value: Open + negation: false + Open ET option: + type: query + option: open-et + op: eq + value: true + negation: false + Open LMF option: + type: query + option: open-lmf + op: eq + value: Open + negation: false + LMF Nodes On option: + type: query + option: open-lmf + op: eq + value: Main Node + negation: false + Floria Gates option: + type: query + option: open-lake-floria + op: eq + value: Floria Gates + negation: false + Talk to Yerbal option: + type: query + option: open-lake-floria + op: eq + value: Talk to Yerbal + negation: false + Vanilla Lake Floria option: + type: query + option: open-lake-floria + op: eq + value: Vanilla + negation: false + Open Lake Floria option: + type: query + option: open-lake-floria + op: eq + value: Open + negation: false + Randomized Beedle option: + type: query + option: shopsanity + op: eq + value: true + negation: false + Gondo Upgrades On option: + type: query + option: gondo-upgrades + op: eq + value: true + negation: true + FS Lava Flow option: + type: query + option: fs-lava-flow + op: eq + value: true + negation: false + BiT patches: + type: query + option: bit-patches + op: eq + value: Fix BiT Crashes + negation: false + Nonlethal Hot Cave: + type: query + option: damage-multiplier + op: lt + value: 12 + negation: false + Upgraded Skyward Strike option: + type: query + option: upgraded-skyward-strike + op: eq + value: true + negation: false + Bomb Throws Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Bomb Throws + negation: false + Long Range Skyward Strike Jumpslash Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Long Range Skyward Strike Jumpslash + negation: false + Advanced Lizalfos Combat Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Advanced Lizalfos Combat + negation: false + Waterfall Cave Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Waterfall Cave Jump + negation: false + Beedle's Shop With Bombs Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Beedle's Shop With Bombs + negation: false + Baby Rattle from Beedle's Shop Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Baby Rattle from Beedle's Shop + negation: false + Sky Keep Entrance Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sky Keep Entrance Jump + negation: false + Gravestone Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Gravestone Jump + negation: false + Sky - Volcanic Island Dive Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sky - Volcanic Island Dive + negation: false + Sky - Beedle's Island Cage Chest Dive Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sky - Beedle's Island Cage Chest Dive + negation: false + Thunderhead - East Island Dive Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Thunderhead - East Island Dive + negation: false + Gym's Rope Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Gym's Rope Jump + negation: false + Early Lake Floria - Fence Hop Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Early Lake Floria - Fence Hop + negation: false + Early Lake Floria - Swordless Rope Floria Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Early Lake Floria - Swordless Rope Floria + negation: false + Faron - Bokoblin Luring Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Faron - Bokoblin Luring + negation: false + Stuttersprint Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Stuttersprint + negation: false + Itemless First Timeshift Stone Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Itemless First Timeshift Stone + negation: false + Lanayru Mine - Quick Bomb Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Lanayru Mine - Quick Bomb + negation: false + Brakeslide Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Brakeslide + negation: false + Lanayru Desert - Ampilus Bomb Toss Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Lanayru Desert - Ampilus Bomb Toss + negation: false + Temple of Time - Slingshot Shot Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Temple of Time - Slingshot Shot + negation: false + Temple of Time Skip - Brakeslide Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Temple of Time Skip - Brakeslide + negation: false + Secret Passageway Hook Beetle Opening Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Secret Passageway Hook Beetle Opening + negation: false + Lightning Node End with Bombs Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Lightning Node End with Bombs + negation: false + Cactus Bomb Whip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Cactus Bomb Whip + negation: false + Skipper's Retreat Fast Clawshots Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Skipper's Retreat Fast Clawshots + negation: false + Pirate Stronghold - Beetle Pillar Checks Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Pirate Stronghold - Beetle Pillar Checks + negation: false + Skyview - Spider Roll Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Skyview - Spider Roll + negation: false + Skyview Slingshot Shot Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Skyview Slingshot Shot + negation: false + Earth Temple - Keese Yeet Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Earth Temple - Keese Yeet + negation: false + Earth Temple - Slope Stuttersprint Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Earth Temple - Slope Stuttersprint + negation: false + Earth Temple - Bomb Flower Scaldera Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Earth Temple - Bomb Flower Scaldera + negation: false + LMF - Whip First Room Switch Trick: + type: query + option: enabled-tricks-bitless + op: in + value: LMF - Whip First Room Switch + negation: false + LMF - Keylocked Slingshot Trickshot Trick: + type: query + option: enabled-tricks-bitless + op: in + value: LMF - Keylocked Slingshot Trickshot + negation: false + LMF - Whip Armos Room Timeshift Stone Trick: + type: query + option: enabled-tricks-bitless + op: in + value: LMF - Whip Armos Room Timeshift Stone + negation: false + LMF - Minecart Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: LMF - Minecart Jump + negation: false + LMF - Moldarach without Gust Bellows Trick: + type: query + option: enabled-tricks-bitless + op: in + value: LMF - Moldarach without Gust Bellows + negation: false + Ancient Cistern - Cistern Clip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Ancient Cistern - Cistern Clip + negation: false + Ancient Cistern - Cistern Whip Room Clip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Ancient Cistern - Cistern Whip Room Clip + negation: false + Ancient Cistern - Map Chest Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Ancient Cistern - Map Chest Jump + negation: false + Ancient Cistern - Lever Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Ancient Cistern - Lever Jump + negation: false + Ancient Cistern - Basement Highflip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Ancient Cistern - Basement Highflip + negation: false + Sandship - No Combination Hint Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sandship - No Combination Hint + negation: false + Sandship - Itemless Spume Skip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sandship - Itemless Spume Skip + negation: false + Sandship - Mast Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sandship - Mast Jump + negation: false + Fire Sanctuary - Pillar Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Fire Sanctuary - Pillar Jump + negation: false + Fire Sanctuary - Swordless Pillar Jump Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Fire Sanctuary - Swordless Pillar Jump + negation: false + Fire Sanctuary - No Bombable Wall Hint Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Fire Sanctuary - No Bombable Wall Hint + negation: false + Sky Keep - Shooting LMF Bow Switches in Present Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sky Keep - Shooting LMF Bow Switches in Present + negation: false + Sky Keep - FS Room Clawshots Vine Clip Trick: + type: query + option: enabled-tricks-bitless + op: in + value: Sky Keep - FS Room Clawshots Vine Clip + negation: false +counters: + Gratitude Crystals: + targets: + - item: Gratitude Crystal + expression: + type: mul + factor: 1 + - item: Gratitude Crystal Pack + expression: + type: mul + factor: 5 + Wallet Capacity: + targets: + - item: Progressive Wallet + expression: + type: lookup + dict: + 0: 300 + 1: 500 + 2: 1000 + 3: 5000 + 4: 9000 + - item: Extra Wallet + expression: + type: mul + factor: 300 + Unique Rupees: + targets: + - item: Green Rupee + expression: + type: mul + factor: 1 + - item: Blue Rupee + expression: + type: mul + factor: 5 + - item: Red Rupee + expression: + type: mul + factor: 20 + - item: Silver Rupee + expression: + type: mul + factor: 100 + - item: Gold Rupee + expression: + type: mul + factor: 300 diff --git a/logic/dump.py b/logic/dump.py index bb1437de..b68a74d7 100644 --- a/logic/dump.py +++ b/logic/dump.py @@ -1,4 +1,5 @@ from logic.constants import * +from logic.inventory import EXTENDED_ITEM def dump_constants(short_to_full): @@ -18,6 +19,13 @@ def dump_constants(short_to_full): "dungeon_completion_requirements": { k: short_to_full(v) for k, v in DUNGEON_FINAL_CHECK.items() }, + "well_known_requirements": { + "open_got": short_to_full(GOT_OPENING_REQUIREMENT), + "raise_got": short_to_full(GOT_RAISING_REQUIREMENT), + "horde_door": short_to_full(HORDE_DOOR_REQUIREMENT), + "impa_song_check": short_to_full(SONG_IMPA_CHECK), + "complete_triforce": short_to_full(COMPLETE_TRIFORCE), + }, } @@ -41,3 +49,7 @@ def dungeon(pool, short_to_full): ), "exit_from_inside": short_to_full(exit_from_dungeon), } + + +def dump_counters_and_options(): + return {"options": EXTENDED_ITEM.options, "counters": EXTENDED_ITEM.counters} diff --git a/logic/logic_expression.py b/logic/logic_expression.py index 10e8eb10..2f198244 100644 --- a/logic/logic_expression.py +++ b/logic/logic_expression.py @@ -52,6 +52,9 @@ def with_options(self, options, required_dungeons): def parse(text: str) -> QueryExpression: raise NotImplementedError + def dump(self): + raise NotImplementedError + def QueryElseBanned(query: QueryExpression) -> QueryExpression: query.else_banned = True @@ -81,6 +84,15 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return not options[self.option] return options[self.option] + def dump(self): + return { + "type": "query", + "option": self.option, + "op": "eq", + "value": True, + "negation": self.negation, + } + @dataclass class QueryOption(QueryExpression): @@ -93,6 +105,15 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return options[self.option] != self.value return options[self.option] == self.value + def dump(self): + return { + "type": "query", + "option": self.option, + "op": "eq", + "value": self.value, + "negation": self.negation, + } + @dataclass class QueryLessThanOption(QueryExpression): @@ -105,6 +126,15 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return options[self.option] >= self.threshold return options[self.option] < self.threshold + def dump(self): + return { + "type": "query", + "option": self.option, + "op": "lt", + "value": self.threshold, + "negation": self.negation, + } + @dataclass class QueryGreaterThanOption(QueryExpression): @@ -117,6 +147,15 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return options[self.option] <= self.threshold return options[self.option] > self.threshold + def dump(self): + return { + "type": "query", + "option": self.option, + "op": "gt", + "value": self.threshold, + "negation": self.negation, + } + @dataclass class QueryContainerOption(QueryExpression): @@ -129,6 +168,15 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return self.value not in options[self.option] return self.value in options[self.option] + def dump(self): + return { + "type": "query", + "option": self.option, + "op": "in", + "value": self.value, + "negation": self.negation, + } + @dataclass class QueryRequiredDungeon(QueryExpression): @@ -140,6 +188,13 @@ def eval(self, options: Options, required_dungeons: List[str]) -> bool: return self.dungeon not in required_dungeons return self.dungeon in required_dungeons + def dump(self): + return { + "type": "req_dungeon", + "dungeon": self.dungeon, + "negation": self.negation, + } + @dataclass class QueryAndCombination(QueryExpression): @@ -148,6 +203,13 @@ class QueryAndCombination(QueryExpression): def eval(self, options: Options, required_dungeons: List[str]) -> bool: return all(arg.eval(options, required_dungeons) for arg in self.arguments) + def dump(self): + return { + "type": "combination", + "op": "and", + "args": [arg.dump() for arg in self.arguments], + } + @dataclass class QueryOrCombination(QueryExpression): @@ -156,6 +218,13 @@ class QueryOrCombination(QueryExpression): def eval(self, options: Options, required_dungeons: List[str]) -> bool: return any(arg.eval(options, required_dungeons) for arg in self.arguments) + def dump(self): + return { + "type": "combination", + "op": "or", + "args": [arg.dump() for arg in self.arguments], + } + # Parsing @@ -824,6 +893,8 @@ def mk_pair(self, a, b): def mk_counter_atom(self, item, c): if item not in RAW_ITEM_NAMES and item not in EXTENDED_ITEM: raise ValueError(f"Unknown item {item}") + if GLOBAL_DUMP_MODE: + return [{"item": str(item), "expression": c}] if item in EXTENDED_ITEM: return [({EXTENDED_ITEM[item]}, c)] s = {EXTENDED_ITEM[number(item, index)] for index in range(ITEM_COUNTS[item])} @@ -832,11 +903,15 @@ def mk_counter_atom(self, item, c): def mk_counter_multiplier(self, count, item): count = int(count) c = lambda n: count * n + if GLOBAL_DUMP_MODE: + c = {"type": "mul", "factor": count} return self.mk_counter_atom(item, c) def mk_counter_value_list(self, item, *counts): counts_dict = {i: int(count) for i, count in enumerate(counts)} c = lambda n: counts_dict[n] + if GLOBAL_DUMP_MODE: + c = {"type": "lookup", "dict": counts_dict} return self.mk_counter_atom(item, c) def mk_counter_add(self, left, right): @@ -886,9 +961,19 @@ def combination_representer(dumper, data): return dumper.represent_scalar("tag:yaml.org,2002:str", str(data), "folded") +def option_representer(dumper: yaml.Dumper, data): + return dumper.represent_dict(data.dump()) + + +def counter_representer(dumper: yaml.Dumper, data: Counter): + return dumper.represent_dict({"targets": data.targets}) + + yaml.add_representer(BasicTextAtom, text_atom_representer) yaml.add_representer(EmptyReq, true_atom_representer) yaml.add_representer(ImpossibleReq, false_atom_representer) yaml.add_representer(UnknownReq, unknown_atom_representer) yaml.add_representer(AndCombination, combination_representer) yaml.add_representer(OrCombination, combination_representer) +yaml.add_multi_representer(QueryExpression, option_representer) +yaml.add_representer(Counter, counter_representer) diff --git a/randoscript.py b/randoscript.py index a7ca1217..afc3eff8 100644 --- a/randoscript.py +++ b/randoscript.py @@ -3,7 +3,7 @@ import argparse import yaml import json -from logic.dump import dump_constants +from logic.dump import dump_constants, dump_counters_and_options from logic.logic_input import Areas from yaml_files import requirements, checks, hints, map_exits @@ -132,7 +132,11 @@ def main(): with open(dest, mode="w") as f: yaml.Dumper.ignore_aliases = lambda *args: True yaml.dump( - {**areas.to_dict(), **dump_constants(areas.short_to_full)}, + { + **areas.to_dict(), + **dump_constants(areas.short_to_full), + **dump_counters_and_options(), + }, f, sort_keys=False, )