pokemon/tools/parse/map_objects.py
2023-07-25 05:34:48 +00:00

97 lines
2.4 KiB
Python

from dataclasses import dataclass
from parse import number
from parse.map_header import tokenize_line
@dataclass
class ObjectEvent:
location: tuple[int, int]
sprite_id: str
movement: str
range_or_direction: str
text_id: str
items_id_or_trainer_id_or_pokemon_id: str = None
trainer_number_or_pokemon_level: str = None
@dataclass
class WarpEvent:
location: tuple[int, int]
destination_map: str
destination_warp_id: str
@dataclass
class BgEvent:
location: tuple[int, int]
sign_id: str
@dataclass
class Object:
label: str
warp_events: list
object_events: list
bg_events: list
def tokenize_label(line):
return ('label', line.split(':')[0].strip())
def tokenize_event(line):
return list(tokenize_line(line))
def tokenize_lines(lines):
for line in lines:
if "_event " in line:
yield tokenize_event(line)
elif ':' in line:
yield tokenize_label(line)
def flatten(tokens):
label = None
warp_events = []
object_events = []
bg_events = []
for token_name, args in tokens:
location = lambda : list(map(number.parse, args[0:2]))
if token_name == 'label':
assert label is None
label = token_name
elif token_name == 'object_event':
event = ObjectEvent(
location(),
*(args[2:])
)
object_events.append(event)
elif token_name == 'warp_event':
destination_map, destination_warp_id = args[2:]
event = WarpEvent(
location(),
destination_map,
number.parse(destination_warp_id)
)
warp_events.append(event)
elif token_name == 'bg_event':
event = BgEvent(
location(),
*(args[2:])
)
bg_events.append(event)
else:
assert False, (token_name, args)
assert label is not None
return Object(
label=label,
warp_events = warp_events,
object_events = object_events,
bg_events = bg_events,
)
def parse(path):
with open(path) as f:
tokens = tokenize_lines(f.read().split('\n'))
return flatten(tokens)
def parse_all(prefix):
base_path = prefix / 'data/maps/objects'
paths = (p for p in base_path.iterdir() if p.is_file())
return [parse(path) for path in paths]