109 lines
3.3 KiB
Python
109 lines
3.3 KiB
Python
import sys, os
|
|
import argparse
|
|
from datetime import datetime
|
|
import xml.etree.ElementTree as ET
|
|
|
|
# Check if the script is run with the correct arguments
|
|
parser = argparse.ArgumentParser(description="Generate chunk header files")
|
|
parser.add_argument('--output', required=True, help='Dir to output headers')
|
|
parser.add_argument('--input', required=True, help='Input XML file from tiled')
|
|
args = parser.parse_args()
|
|
|
|
# Ensure outdir exists
|
|
outputDir = args.output
|
|
os.makedirs(outputDir, exist_ok=True)
|
|
|
|
# Create world directory if it does not exist
|
|
worldDir = os.path.join(outputDir, "world")
|
|
os.makedirs(worldDir, exist_ok=True)
|
|
|
|
# Some vars used during printing
|
|
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
# Read the input JSON file
|
|
inputFile = args.input
|
|
if not os.path.isfile(inputFile):
|
|
print(f"Error: Input file '{inputFile}' does not exist.")
|
|
sys.exit(1)
|
|
|
|
with open(inputFile, 'r') as f:
|
|
data = f.read()
|
|
|
|
# Parse the XML data
|
|
try:
|
|
root = ET.fromstring(data)
|
|
except ET.ParseError as e:
|
|
print(f"Error parsing XML: {e}")
|
|
sys.exit(1)
|
|
|
|
if root.tag != 'tileset':
|
|
print("Error: Input file is not a valid Tiled XML file.")
|
|
sys.exit(1)
|
|
|
|
if 'tilewidth' not in root.attrib or 'tileheight' not in root.attrib:
|
|
print("Error: Missing tilewidth or tileheight attributes in the tileset.")
|
|
sys.exit(1)
|
|
|
|
if 'tilecount' not in root.attrib or 'columns' not in root.attrib:
|
|
print("Error: Missing tilecount or columns attributes in the tileset.")
|
|
sys.exit(1)
|
|
|
|
tileWidth = int(root.get('tilewidth', 0))
|
|
tileHeight = int(root.get('tileheight', 0))
|
|
tileCount = int(root.get('tilecount', 0)) + 1 # +1 because maps are 1 indexed
|
|
columns = int(root.get('columns', 0))
|
|
|
|
tilesById = {}
|
|
for tile in root.findall('tile'):
|
|
if 'id' not in tile.attrib:
|
|
print("Error: Tile element missing 'id' attribute.")
|
|
continue
|
|
|
|
tileId = int(tile.get('id', -1)) + 1 # +1 because maps are 1 indexed
|
|
if tileId < 0 or tileId >= tileCount:
|
|
print(f"Error: Invalid tile ID {tileId} in tile element.")
|
|
continue
|
|
|
|
tilesById[tileId] = tile
|
|
|
|
# Create the header file
|
|
headerFile = os.path.join(worldDir, "tiledata.h")
|
|
with open(headerFile, 'w') as f:
|
|
f.write(f"// Generated on {now}\n")
|
|
f.write(f"#include \"world/tile.h\"\n\n")
|
|
f.write(f"#define TILE_WIDTH {tileWidth}\n")
|
|
f.write(f"#define TILE_HEIGHT {tileHeight}\n")
|
|
f.write(f"#define TILE_WIDTH_HEIGHT {tileWidth}\n")
|
|
f.write(f"#define TILE_COUNT {tileCount}\n")
|
|
|
|
f.write("static const tilemetadata_t TILE_META_DATA[TILE_COUNT] = {\n")
|
|
for tileId in range(tileCount):
|
|
tile = tilesById.get(tileId, None)
|
|
if tile is None:
|
|
f.write(f" {{ 0 }},\n")
|
|
continue
|
|
|
|
properties = tile.find('properties')
|
|
if properties is None:
|
|
f.write(f" {{ 0 }},\n")
|
|
continue
|
|
|
|
def findProp(name, expectedType=''):
|
|
for prop in properties.findall('property'):
|
|
if prop.get('name') == name:
|
|
if len(expectedType) > 0:
|
|
if 'type' in prop.attrib and prop.get('type') != expectedType:
|
|
continue
|
|
if 'propertytype' in prop.attrib and prop.get('propertytype') != expectedType:
|
|
continue
|
|
return prop.get('value', '')
|
|
return None
|
|
|
|
f.write(f" {{\n")
|
|
|
|
propSolid = findProp('solidType', 'tileSolidType')
|
|
if propSolid is not None:
|
|
f.write(f" .solidType = {propSolid},\n")
|
|
|
|
f.write(f" }},\n")
|
|
f.write("};\n\n") |