From 0348eb2e74f0e836d0882d048b1529470a397ce2 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 2 Aug 2023 01:49:25 +0000 Subject: [PATCH] generate: add moves --- tools/generate/__main__.py | 3 +- tools/generate/files.py | 3 + tools/generate/move/moves.py | 110 +++++++++++++++++++++++++++++++++++ tools/parse/move/moves.py | 10 ++-- 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 tools/generate/move/moves.py diff --git a/tools/generate/__main__.py b/tools/generate/__main__.py index 79d7322..0868132 100644 --- a/tools/generate/__main__.py +++ b/tools/generate/__main__.py @@ -9,8 +9,9 @@ def generate(base_path, target_path): path = base_path / filename if path != target_path: continue + buf = func().getvalue() with open(path, 'w') as f: - f.write(func().getvalue()) + f.write(buf) # sys.argv[1] is secretly used in parse base_path = Path(sys.argv[2]) diff --git a/tools/generate/files.py b/tools/generate/files.py index 54bf1a3..acc4ea9 100644 --- a/tools/generate/files.py +++ b/tools/generate/files.py @@ -5,6 +5,7 @@ from generate import tilesets from generate import collision_tile_ids from generate import text from generate import text_pointers +from generate.move import moves files = [ (maps.generate_header, "maps.hpp"), @@ -21,4 +22,6 @@ files = [ (text.generate_source, "text.cpp"), (text_pointers.generate_header, "text_pointers.hpp"), (text_pointers.generate_source, "text_pointers.cpp"), + (moves.generate_header, "moves.hpp"), + (moves.generate_source, "moves.cpp"), ] diff --git a/tools/generate/move/moves.py b/tools/generate/move/moves.py new file mode 100644 index 0000000..9429e65 --- /dev/null +++ b/tools/generate/move/moves.py @@ -0,0 +1,110 @@ +""" +struct move_t { + uint8_t effect; // fixme: constants/move_effect_constants.asm + uint8_t power; + uint8_t type; // fixme: constants/type_constants.asm + uint8_t accuracy; + uint8_t pp; + + enum move { + wing_attack, + }; +}; + +const move_t moves[] = { + [move_t::pound] = { + .effect = + .power = + .type = + .accuracy = + .pp = + }, +}; +""" + +from generate.generate import renderer +from parse import parse + +# parse.move_constants_list() +# parse.move_names_list() +# parse.move_moves_list() + +def includes_header(): + yield "#pragma once" + yield "" + +def move_constants(): + _move_constants = parse.move_constants_list() + _moves = list(parse.move_moves_list()) + for constant_ix, constant_name in enumerate(_move_constants): + # move_constants is also used for animation names it will be + # modeled in a separate enum (e.g: there is no such move as + # "shrinking_square_black_anim", so it shouldn't appear in + # this enum). This appears to be a questionable decision in + # the pokered decompilation project, not an original design + # decision in the game. + if constant_ix < len(_moves): + yield constant_name + +def struct_move_t(): + _move_constants = move_constants() + _move_constants_str = (f"{s.lower()}," for s in _move_constants) + return [ + "struct move_t {", + "uint8_t animation;", + "uint8_t effect;", + "uint8_t power;", + "uint8_t type;", + "uint8_t accuracy;", + "uint8_t pp;", + "", + "enum move {", + *_move_constants_str, + "};", + "};", + ] + +def extern_moves(): + yield "extern const move_t moves[];" + +def generate_header(): + render, out = renderer() + render(includes_header()) + render(struct_move_t()) + render(extern_moves()) + return out + +def move(constant_index, constant_name): + _move = parse.move_moves_list()[constant_index] + return [ + f"[move_t::{constant_name.lower()}] = {{", + ".animation = 0,", + ".effect = 0,", + f".power = {_move.power},", + ".type = 0,", + f".accuracy = {_move.accuracy},", + f".pp = {_move.pp},", + "}," + ] + +def moves(): + yield "const move_t moves[] = {" + for constant_index, constant_name in enumerate(move_constants()): + if constant_index == 0: + # no_move + yield f"[move_t::{constant_name.lower()}] = {{ 0 }}," + else: + yield from move(constant_index - 1, constant_name) + yield "};" + +def includes_source(): + yield '#include ' + yield '' + yield '#include "moves.hpp"' + yield '' + +def generate_source(): + render, out = renderer() + render(includes_source()) + render(moves()) + return out diff --git a/tools/parse/move/moves.py b/tools/parse/move/moves.py index 310c25b..5abd6b9 100644 --- a/tools/parse/move/moves.py +++ b/tools/parse/move/moves.py @@ -7,7 +7,7 @@ tokenize_lines = partial(tokenize.lines, prefix='move ') @dataclass class Move: - constant_name: str + animation_name: str effect: str power: int type: str @@ -17,9 +17,9 @@ class Move: def flatten(tokens): for t in tokens: assert t[0] == 'move', t - _, (constant_name, effect, power, type, accuracy, pp) = t - yield constant_name, Move( - constant_name, + _, (animation_name, effect, power, type, accuracy, pp) = t + yield Move( + animation_name, effect, number.parse(power), type, @@ -30,4 +30,4 @@ def flatten(tokens): def parse(prefix): path = prefix / 'data/moves/moves.asm' with open(path) as f: - return dict(flatten(tokenize_lines(f.read().split('\n')))) + return list(flatten(tokenize_lines(f.read().split('\n'))))