pokemon/tools/parse/map_header.py
Zack Buhman a921a44b66 parse: move tokenize_line/tokenize_lines to a new module
At times I forget what I have already written. I hope that this might help keep
things more organized.
2023-07-31 16:23:55 -07:00

96 lines
2.4 KiB
Python

from dataclasses import dataclass
from parse.generic import macro_line
# data/maps/headers/AgathasRoom.asm
@dataclass
class MapHeader:
name1: str
name2: str
tileset: str
connection_names: list[str] # not sure if this one is useful
connections: list[list]
def blocks(self):
return f"{self.name1}_Blocks"
def text_pointers(self):
return f"{self.name1}_TextPointers"
def script(self):
return f"{self.name1}_Script"
def object(self):
return f"{self.name1}_Object"
def width(self):
return f"{self.name2}_WIDTH"
def height(self):
return f"{self.name2}_HEIGHT"
@dataclass
class Connection:
name: str
map_name1: str
map_name2: str
offset: int
def parse_connection():
return
def flatten(tokens):
# expects tokens from a single file
# PalletTown, PALLET_TOWN, OVERWORLD, NORTH | SOUTH
# dw \1_Blocks
# dw \1_TextPointers
# dw \1_Script
# dw {\1_Object}
# \2_WIDTH
# \2_HEIGHT
map_headers = [s for s in tokens if s[0] == 'map_header']
assert len(map_headers) == 1, map_headers
map_header, = map_headers
_, (name1, name2, tileset, connection_mask0) = map_header
connections = [s[1] for s in tokens if s[0] == 'connection']
connection_mask = connection_mask0 if type(connection_mask0) is list else [connection_mask0]
null_mask = lambda m: (
len(m) == 1 and any(m[0] == n for n in {'0', '$0', '$00'})
)
connection_names = (
[] if null_mask(connection_mask) else connection_mask
)
return MapHeader(
name1 = name1,
name2 = name2,
tileset = tileset,
connection_names = sorted(connection_names),
connections = list(sorted(
(
Connection(
name,
map_name1,
map_name2,
int(offset)
)
for name, map_name1, map_name2, offset in connections
),
key=lambda c: c.name))
)
tokenize_lines = macro_line.tokenize_lines
def parse(path):
with open(path) as f:
tokens = list(tokenize_lines(f.read().split('\n')))
return flatten(tokens)
def parse_all(prefix):
base_path = prefix / 'data/maps/headers'
paths = [p for p in base_path.iterdir() if p.is_file()]
return [parse(path) for path in paths]