130 lines
3.3 KiB
Python
Executable File
130 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright (c) 2023 Dominic Masters
|
|
#
|
|
# This software is released under the MIT License.
|
|
# https://opensource.org/licenses/MIT
|
|
|
|
import os
|
|
import argparse
|
|
|
|
# Args
|
|
parser = argparse.ArgumentParser(
|
|
description='Bundles all assets into the internal archive format.'
|
|
)
|
|
parser.add_argument('-i', '--input');
|
|
parser.add_argument('-o', '--output');
|
|
args = parser.parse_args()
|
|
|
|
# Ensure the directory for the output path exists
|
|
if not os.path.exists(os.path.dirname(args.output)):
|
|
os.makedirs(os.path.dirname(args.output))
|
|
|
|
# Read XML file
|
|
import xml.etree.ElementTree as ET
|
|
tree = ET.parse(args.input)
|
|
root = tree.getroot()
|
|
|
|
width = int(root.attrib['width'])
|
|
height = int(root.attrib['height'])
|
|
|
|
# Prep Output
|
|
output = {
|
|
"width": width,
|
|
"height": height,
|
|
"layers": [
|
|
],
|
|
"entities": [
|
|
],
|
|
"triggers": [
|
|
]
|
|
}
|
|
|
|
# for each layer element of root
|
|
for layer in root.findall('layer'):
|
|
layerOut = {
|
|
"tiles": []
|
|
}
|
|
# Find data (CSV)
|
|
data = layer.find('data')
|
|
data = data.text.replace('\n', '').replace(' ', '').split(',')
|
|
# for each tile in data
|
|
for i in range(0, len(data)):
|
|
# minus 1 because tiled is 1 indexed
|
|
tileId = int(data[i]) - 1
|
|
if(int(data[i]) == 0):
|
|
tileId = 0
|
|
layerOut["tiles"].append(tileId)
|
|
|
|
output["layers"].append(layerOut)
|
|
|
|
# Find objectgroup elements
|
|
for objectgroup in root.findall('objectgroup'):
|
|
# for each object element of objectgroup
|
|
|
|
# if layer name attribute containts "ent"
|
|
isEnt = objectgroup.attrib['name'].lower().find('ent') != -1
|
|
|
|
for tiledObject in objectgroup.findall('object'):
|
|
floatX = float(tiledObject.attrib['x'])
|
|
floatY = float(tiledObject.attrib['y'])
|
|
|
|
# tiled uses Px and uses bottom left of sprite
|
|
obj = {
|
|
"x": int( round(floatX / 8) ),
|
|
"y": int( round((floatY - 8) / 8) )
|
|
}
|
|
|
|
propertiesElement = tiledObject.find('properties')
|
|
if propertiesElement is None:
|
|
propertyElements = []
|
|
else:
|
|
propertyElements = propertiesElement.findall('property')
|
|
|
|
properties = {}
|
|
for prop in propertyElements:
|
|
properties[prop.attrib['name']] = prop.attrib['value']
|
|
|
|
if isEnt:
|
|
if not 'type' in tiledObject.attrib:
|
|
raise Exception('Entity missing type attribute')
|
|
entType = tiledObject.attrib['type']
|
|
if entType == 'player':
|
|
obj['type'] = 1
|
|
elif entType == 'npc':
|
|
obj['type'] = 2
|
|
elif entType == 'sign':
|
|
obj['type'] = 3
|
|
|
|
obj["texts"] = []
|
|
for key in properties:
|
|
if key.find('text') != -1:
|
|
obj["texts"].append(properties[key])
|
|
|
|
elif entType == 'door':
|
|
obj['type'] = 4
|
|
obj["door"] = {}
|
|
|
|
if 'x' in properties:
|
|
obj["door"]["x"] = int(properties['x'])
|
|
if 'y' in properties:
|
|
obj["door"]["y"] = int(properties['y'])
|
|
if 'direction' in properties:
|
|
obj["door"]["direction"] = int(properties['direction'])
|
|
if 'map' in properties:
|
|
obj["door"]["map"] = properties['map']
|
|
|
|
else:
|
|
raise Exception('Unknown entity type: ' + entType)
|
|
|
|
output["entities"].append(obj)
|
|
else:
|
|
# trigger
|
|
raise Exception('Triggers not yet implemented')
|
|
|
|
|
|
# write to args output as JSON
|
|
import json
|
|
with open(args.output, 'w') as f:
|
|
# pretty print to debug
|
|
f.write(json.dumps(output, indent=2))
|
|
# f.write(json.dumps(output)) |