papermario/tools/build/world_map.py

87 lines
2.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import argparse
from pathlib import Path
from typing import List, Dict
import xml.etree.ElementTree as ET
def get_required_attrib(elem: ET.Element, attrib: str) -> str:
value = elem.attrib.get(attrib, None)
if value == None:
raise Exception(f"{elem.tag} is missing attribute: '{attrib}'")
return str(value)
class WorldMapEntry:
def __init__(self, elem: ET.Element):
self.location = get_required_attrib(elem, "id")
self.parent = get_required_attrib(elem, "parent")
self.requires = get_required_attrib(elem, "requires")
self.startX = get_required_attrib(elem, "startX")
self.startY = get_required_attrib(elem, "startY")
path_str = get_required_attrib(elem, "path")
self.path = []
if path_str != "":
for i in path_str.split(";"):
self.path.append(i.split(","))
def generate(in_xml: Path, out_c: Path):
xml = ET.parse(in_xml)
ScriptList = xml.getroot()
with open(out_c, "w") as f:
f.write("#ifndef WORLD_MAP_H\n")
f.write("#define WORLD_MAP_H\n")
f.write("/* This file is auto-generated. Do not edit. */\n\n")
f.write('#include "common.h"\n\n')
locations: List[WorldMapEntry] = []
for elem in ScriptList.findall("Location"):
locations.append(WorldMapEntry(elem))
loc_to_idx: Dict[str, int] = {}
for idx, loc in enumerate(locations):
loc_to_idx[loc.location] = idx
# write paths
# note: len(locations) = 34, will only match if hardcoded to 32 here
f.write("Vec2b PauseMapPaths[][32] = {\n")
for loc in locations:
f.write(" { ")
for point in loc.path:
f.write(f"{{ {point[0]}, {point[1]} }}, ")
f.write("},\n")
f.write("};\n\n")
# write locations
f.write("PauseMapSpace PauseMapSpaces[] = {\n")
for idx, loc in enumerate(locations):
if loc.parent not in loc_to_idx:
raise Exception(f"{loc.parent} is not defined")
f.write(
f" {{ .id = {loc.location}, .parent = {loc_to_idx[loc.parent]}, .afterRequirement = {loc.requires}, "
+ f".pos = {{ .x = {loc.startX}, .y = {loc.startY} }}, "
+ f".pathLength = {len(loc.path)}, .path = PauseMapPaths[{idx}] }},\n"
)
f.write("};\n")
f.write("\n#endif // WORLD_MAP_H\n")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generates world map data")
parser.add_argument("in_xml", type=Path, help="input xml file path")
parser.add_argument("header_path", help="output header file to generate")
args = parser.parse_args()
generate(args.in_xml, args.header_path)