From ed29b321736ecd551d803c1622b26aab202b000e Mon Sep 17 00:00:00 2001 From: Trysdyn Black Date: Sun, 13 Oct 2024 16:02:27 -0700 Subject: [PATCH] Add support for ITEM EFFECTS section --- README.md | 1 - main.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index be4dce8..3a2db6b 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ BCCE is in active development and this may break at any time; see the first para These sections in the BCEX/BCCE spoiler logs currently have no logic and I'm aware of it. That doesn't mean sections *not* listed here have support; they may not and I'm not aware of them. -- ITEM EFFECTS - SHOPS - TREASURE CHESTS - JUNCTIONS diff --git a/main.py b/main.py index a236a75..f8145d5 100644 --- a/main.py +++ b/main.py @@ -10,12 +10,11 @@ import sys from pathlib import Path -class Parser: +class Parser: # noqa: PLR0904 """ BCEX/BCCE spoiler logfile parser. Sections missing support: - - ITEM EFFECTS - SHOPS - TREASURE CHESTS - JUNCTIONS @@ -501,6 +500,7 @@ class Parser: need. """ result = {} + mode = None for line in data.split("\n"): if "-----" in line or not line.strip(): @@ -517,6 +517,68 @@ class Parser: return result + @staticmethod + def parse_ITEM_EFFECTS(data: str) -> dict[str, dict]: # noqa: C901, PLR0912 + """ + Parse the BCCE-only ITEM EFFECTS section. + + This is a weird chimera section with multiple sub-sections. Most of these + sub-sections can just be k:v or k:v, v, v parsed. Elemental properties is + a special indented list and special features can contain command changers + so we need a lot of special parsing. + """ + result = {} + mode = None + item = None + + for line in data.split("\n"): + if "-----" in line or not line.strip(): + continue + + if line == line.upper(): + mode = line.lower().strip().replace(" ", "_") + result[mode] = {} + # Everything here is k:v splitable except the elemental properties + # section which is k:v but with a return and indent and multiple values. + elif mode == "elemental_properties": + if line.startswith(" "): + tok_line = line.split() + operator = "+" if "Gained" in tok_line else "-" if "Lost" in tok_line else "" + element = tok_line[-1] + effect = tok_line[2].strip(":") + + if item not in result[mode]: + result[mode][item] = [] + + result[mode][item].append(f"{operator}{element} {effect}") + else: + item = line.split(":")[0] + result[mode][item] = [] + else: + item, effect = line.split(":") + item = item.strip() + effect = effect.strip() + + for effect_token in effect.split(", "): + # This is a command change. This can appear in command_changers *or* features + # In either case the result goes in command changers for consistency + if "->" in effect_token: + old, new = effect_token.split("->") + # We don't have a guarantee COMMAND CHANGERS is in yet... + if "command_changers" not in result: + result["command_changers"] = {} + if item not in result["command_changers"]: + result["command_changers"][item] = {} + + result["command_changers"][item][old.strip()] = new.strip() + # Everything else should hopefully just be a basic effect list + else: + if item not in result[mode]: + result[mode][item] = [] + result[mode][item].append(effect_token.strip()) + + return result + @staticmethod def cleanup_STATS(data: dict) -> bool: """