tools/parse: add parsers for pokemon dex data
This commit is contained in:
parent
9f0c07e56a
commit
96cc628664
38
tools/parse/generic/label_data.py
Normal file
38
tools/parse/generic/label_data.py
Normal file
@ -0,0 +1,38 @@
|
||||
from itertools import chain
|
||||
|
||||
def is_label(token_line):
|
||||
return token_line[0].endswith(':')
|
||||
|
||||
def is_data(token_line):
|
||||
return token_line[0] == 'db' or token_line[0] == 'dw' \
|
||||
or token_line[0] == 'text_far'
|
||||
|
||||
Label = object()
|
||||
Data = object()
|
||||
|
||||
def _event(token_line):
|
||||
if is_label(token_line):
|
||||
label0, = token_line
|
||||
yield Label, label0.split(':')[0]
|
||||
elif is_data(token_line):
|
||||
_, args = token_line
|
||||
yield Data, args
|
||||
else:
|
||||
return
|
||||
|
||||
def event(tokens):
|
||||
return list(chain.from_iterable(map(_event, tokens)))
|
||||
|
||||
def pointer_table(type_args, ix):
|
||||
pointer_table = []
|
||||
while ix < len(type_args):
|
||||
type, args = type_args[ix]
|
||||
if type is Label:
|
||||
break
|
||||
elif type is Data:
|
||||
evos_moves_label, = args
|
||||
pointer_table.append(evos_moves_label)
|
||||
else:
|
||||
assert False, type_args
|
||||
ix += 1
|
||||
return ix, pointer_table
|
@ -57,7 +57,6 @@ def parse_base_stat(lines):
|
||||
tmhm,
|
||||
)
|
||||
|
||||
|
||||
def parse(path):
|
||||
with open(path) as f:
|
||||
token_lines = filter_lines(lines(f.read().split('\n')))
|
||||
@ -66,5 +65,5 @@ def parse(path):
|
||||
def parse_all(prefix):
|
||||
base_path = prefix / 'data/pokemon/base_stats'
|
||||
paths = [p for p in base_path.iterdir() if p.is_file()]
|
||||
# order is pokedex order, not constant order
|
||||
# in pokedex order
|
||||
return [parse(path) for path in paths]
|
||||
|
60
tools/parse/pokemon/dex_entries.py
Normal file
60
tools/parse/pokemon/dex_entries.py
Normal file
@ -0,0 +1,60 @@
|
||||
import builtins
|
||||
from dataclasses import dataclass
|
||||
|
||||
from parse.generic import tokenize
|
||||
from parse.generic import number
|
||||
from parse.generic import string
|
||||
from parse.generic import label_data
|
||||
|
||||
@dataclass
|
||||
class DexEntry:
|
||||
label: str
|
||||
species: str
|
||||
height: tuple[int, int]
|
||||
weight: int
|
||||
text_ptr: str
|
||||
|
||||
def dex_entry(type_args, ix):
|
||||
label, species, height, weight, text_ptr = type_args[ix:ix+5]
|
||||
|
||||
label_type, label_value = label
|
||||
assert label_type == label_data.Label, label
|
||||
species_type, (species_value,) = species
|
||||
assert species_type == label_data.Data, species_type
|
||||
height_type, height_value = height
|
||||
assert height_type == label_data.Data, height_type
|
||||
weight_type, (weight_value,) = weight
|
||||
assert weight_type == label_data.Data, weight_type
|
||||
text_ptr_type, (text_ptr_value,) = text_ptr
|
||||
assert text_ptr_type == label_data.Data, text_ptr_type
|
||||
|
||||
entry = DexEntry(
|
||||
label_value,
|
||||
string.parse(species_value).rstrip('@'),
|
||||
tuple(map(number.parse, height_value)),
|
||||
number.parse(weight_value),
|
||||
text_ptr_value
|
||||
)
|
||||
return ix+5, entry
|
||||
|
||||
def build_tables(tokens):
|
||||
type_args = label_data.event(tokens)
|
||||
ix = 0
|
||||
while ix < len(type_args):
|
||||
type, args = type_args[ix]
|
||||
if type is label_data.Label:
|
||||
label = args
|
||||
assert builtins.type(label) is str
|
||||
if label == 'PokedexEntryPointers':
|
||||
ix, pointer_table = label_data.pointer_table(type_args, ix + 1)
|
||||
yield pointer_table
|
||||
else:
|
||||
ix, entry = dex_entry(type_args, ix)
|
||||
yield entry
|
||||
else:
|
||||
assert False, (type, args)
|
||||
|
||||
def parse(prefix):
|
||||
path = prefix / "data/pokemon/dex_entries.asm"
|
||||
with open(path) as f:
|
||||
return list(build_tables(tokenize.lines(f.read().split('\n'))))
|
17
tools/parse/pokemon/dex_order.py
Normal file
17
tools/parse/pokemon/dex_order.py
Normal file
@ -0,0 +1,17 @@
|
||||
from functools import partial
|
||||
from parse.generic import tokenize
|
||||
|
||||
tokenize_lines = partial(tokenize.lines, prefix='db')
|
||||
|
||||
def flatten(tokens):
|
||||
for t in tokens:
|
||||
if t[0] == 'db':
|
||||
_, (name,) = t
|
||||
yield name
|
||||
else:
|
||||
assert False, t
|
||||
|
||||
def parse(prefix):
|
||||
path = prefix / "data/pokemon/dex_order.asm"
|
||||
with open(path) as f:
|
||||
return list(flatten(tokenize_lines(f.read().split('\n'))))
|
0
tools/parse/pokemon/dex_text.py
Normal file
0
tools/parse/pokemon/dex_text.py
Normal file
@ -1,30 +1,9 @@
|
||||
import builtins
|
||||
from dataclasses import dataclass
|
||||
from itertools import chain
|
||||
|
||||
from parse.generic import tokenize
|
||||
from parse.generic import number
|
||||
|
||||
lines = tokenize.lines
|
||||
|
||||
def is_label(token_line):
|
||||
return token_line[0].endswith(':')
|
||||
|
||||
def is_data(token_line):
|
||||
return token_line[0] == 'db' or token_line[0] == 'dw'
|
||||
|
||||
Label = object()
|
||||
Data = object()
|
||||
|
||||
def event(token_line):
|
||||
if is_label(token_line):
|
||||
label0, = token_line
|
||||
yield Label, label0.split(':')[0]
|
||||
elif is_data(token_line):
|
||||
_, args = token_line
|
||||
yield Data, args
|
||||
else:
|
||||
return
|
||||
from parse.generic import label_data
|
||||
|
||||
@dataclass
|
||||
class EvosMoves:
|
||||
@ -54,37 +33,24 @@ def parse_ev(tokens):
|
||||
else:
|
||||
assert False, ev_type
|
||||
|
||||
def parse_pointer_table(type_args, ix):
|
||||
pointer_table = []
|
||||
while ix < len(type_args):
|
||||
type, args = type_args[ix]
|
||||
if type is Label:
|
||||
break
|
||||
elif type is Data:
|
||||
evos_moves_label, = args
|
||||
pointer_table.append(evos_moves_label)
|
||||
else:
|
||||
assert False, type_args
|
||||
ix += 1
|
||||
return ix, pointer_table
|
||||
|
||||
def parse_learnset_entry(args):
|
||||
level_requirement, move_name = args
|
||||
return number.parse(level_requirement), move_name
|
||||
|
||||
def build_tables(tokens):
|
||||
evos_moves = EvosMoves()
|
||||
pointer_table = []
|
||||
|
||||
type_args = list(chain.from_iterable(map(event, tokens)))
|
||||
type_args = label_data.event(tokens)
|
||||
ix = 0
|
||||
while ix < len(type_args):
|
||||
type, args = type_args[ix]
|
||||
if type is Label:
|
||||
if type is label_data.Label:
|
||||
label = args
|
||||
assert builtins.type(label) is str
|
||||
if label == 'EvosMovesPointerTable':
|
||||
ix, pointer_table = parse_pointer_table(type_args, ix + 1)
|
||||
ix, pointer_table = label_data.pointer_table(type_args, ix + 1)
|
||||
yield pointer_table
|
||||
continue
|
||||
if evos_moves.label is not None:
|
||||
yield evos_moves
|
||||
evos_moves = EvosMoves()
|
||||
@ -92,7 +58,7 @@ def build_tables(tokens):
|
||||
assert evos_moves.evolutions == [], evos_moves
|
||||
assert evos_moves.learnset == [], evos_moves
|
||||
evos_moves.label = label
|
||||
elif type is Data:
|
||||
elif type is label_data.Data:
|
||||
if is_evolution(args):
|
||||
evos_moves.evolutions.append(parse_ev(args))
|
||||
elif is_learnset_entry(args):
|
||||
@ -101,17 +67,13 @@ def build_tables(tokens):
|
||||
pass # do nothing
|
||||
else:
|
||||
assert False, (type, args)
|
||||
|
||||
else:
|
||||
assert False, (type, args)
|
||||
|
||||
ix += 1
|
||||
|
||||
|
||||
def parse(prefix):
|
||||
path = prefix / "data/pokemon/evos_moves.asm"
|
||||
with open(path) as f:
|
||||
return list(build_tables(lines(f.read().split('\n'))))
|
||||
|
||||
from pathlib import Path
|
||||
from pprint import pprint
|
||||
pprint(parse(Path("../pokered")))
|
||||
return list(build_tables(tokenize.lines(f.read().split('\n'))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user