mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 20:12:30 +01:00
87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
|
#!/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)
|