mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-26 05:32:07 -04:00
118 lines
3.7 KiB
Python
118 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
# data/moves/effects.asm, data/moves/effects_pointers.asm,
|
|
# constants/move_effect_constants.asm
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
CONST_RE = re.compile(r"^\s*const\s+(EFFECT_[A-Z0-9_]+)")
|
|
POINTER_RE = re.compile(r"^\s*dw\s+([A-Za-z_][A-Za-z0-9_]*)")
|
|
LABEL_RE = re.compile(r"^([A-Za-z_][A-Za-z0-9_]*):")
|
|
CMD_RE = re.compile(r"^\s+([a-z][a-z0-9_]*)\b")
|
|
|
|
|
|
def read_lines(path):
|
|
with open(path, encoding="utf-8") as handle:
|
|
return handle.read().splitlines()
|
|
|
|
|
|
def effect_constants(pret):
|
|
names = []
|
|
for line in read_lines(os.path.join(pret, "constants", "move_effect_constants.asm")):
|
|
match = CONST_RE.match(line)
|
|
if match:
|
|
names.append(match.group(1))
|
|
return names
|
|
|
|
|
|
def effect_pointers(pret):
|
|
labels = []
|
|
for line in read_lines(os.path.join(pret, "data", "moves", "effects_pointers.asm")):
|
|
match = POINTER_RE.match(line)
|
|
if match:
|
|
labels.append(match.group(1))
|
|
return labels
|
|
|
|
|
|
def effect_chains(pret):
|
|
chains = {}
|
|
lines = {}
|
|
current = []
|
|
for number, raw in enumerate(read_lines(os.path.join(pret, "data", "moves", "effects.asm")), 1):
|
|
line = raw.split(";", 1)[0].rstrip()
|
|
if not line.strip():
|
|
continue
|
|
label = LABEL_RE.match(line)
|
|
if label:
|
|
name = label.group(1)
|
|
if current and chains[current[-1]]:
|
|
current = []
|
|
current.append(name)
|
|
chains.setdefault(name, [])
|
|
lines.setdefault(name, number)
|
|
continue
|
|
cmd = CMD_RE.match(line)
|
|
if cmd and current:
|
|
for name in current:
|
|
chains[name].append(cmd.group(1))
|
|
return chains, lines
|
|
|
|
|
|
def audit(pret):
|
|
consts = effect_constants(pret)
|
|
pointers = effect_pointers(pret)
|
|
chains, lines = effect_chains(pret)
|
|
if len(consts) != len(pointers):
|
|
sys.exit("%s: %d constants vs %d pointers" % (pret, len(consts), len(pointers)))
|
|
rows = []
|
|
for effect, label in zip(consts, pointers):
|
|
commands = chains.get(label)
|
|
if commands is None:
|
|
sys.exit("%s: no chain for %s" % (pret, label))
|
|
rows.append((effect, label, commands, lines[label]))
|
|
return rows
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("pret", nargs="*", default=["../pokecrystal", "../pokegold"])
|
|
parser.add_argument("--lua", action="store_true")
|
|
parser.add_argument("--all", action="store_true")
|
|
args = parser.parse_args()
|
|
|
|
per_tree = {}
|
|
for pret in args.pret:
|
|
per_tree[pret] = audit(pret)
|
|
|
|
trees = list(per_tree)
|
|
first = per_tree[trees[0]]
|
|
no_checkhit = [row for row in first if "checkhit" not in row[2]]
|
|
|
|
for pret in trees[1:]:
|
|
other = {row[0]: row[2] for row in per_tree[pret]}
|
|
for effect, _, commands, _ in first:
|
|
if effect not in other:
|
|
print("%s lacks %s" % (pret, effect), file=sys.stderr)
|
|
elif ("checkhit" in commands) != ("checkhit" in other[effect]):
|
|
print("%s disagrees on checkhit for %s" % (pret, effect), file=sys.stderr)
|
|
|
|
if args.lua:
|
|
print("{")
|
|
for effect, _, _, line in no_checkhit:
|
|
print(" %s = true, -- data/moves/effects.asm:%d" % (effect, line))
|
|
print("}")
|
|
return
|
|
|
|
rows = first if args.all else no_checkhit
|
|
for effect, label, commands, line in rows:
|
|
gate = "checkhit" if "checkhit" in commands else "NO_CHECKHIT"
|
|
print("%-32s %-28s %5d %s" % (effect, label, line, gate))
|
|
print("%d of %d effect chains have no checkhit" % (len(no_checkhit), len(first)),
|
|
file=sys.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|