Started writing a new converter

This commit is contained in:
mibi88 2024-07-30 17:44:12 +02:00
parent a06977469c
commit bc8382ac65
4 changed files with 385 additions and 519 deletions

View file

@ -32,7 +32,8 @@ set(SOURCES
) )
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets # Shared assets, fx-9860G-only assets and fx-CG-50-only assets
set(ASSETS set(ASSETS
assets/WorldRPG.world #assets/WorldRPG.world
assets/level0.tmx
# ... # ...
) )

View file

@ -1,522 +1,375 @@
from random import randint import xml.etree.ElementTree as ET
from PIL import Image
import fxconv
import json import json
import pathlib
import csv
import os import os
import sys
DEBUG = 0 VERBOSE = 1
SIGN_TYPES = ["INFO", "SGN"]
# TODO: Add more doc.
class Tileset:
"""
Handle the tiled tileset.
"""
def __init__(self, element: ET.Element, parent_dir = ""):
firstgid_str = element.get("firstgid")
if firstgid_str == None: raise Exception("firstgid not found!")
self.firstgid = int(firstgid_str)
self.source = element.get("source")
if self.source == None: raise Exception("source not found!")
self.source = parent_dir + self.source
tree = ET.parse(self.source)
self.root = tree.getroot()
tilecount_str = self.root.get("tilecount")
if tilecount_str == None: raise Exception("tilecount not found!")
self.tilecount = int(tilecount_str)
def is_raw_in_tileset(self, raw: int) -> bool:
if raw >= self.firstgid and raw < self.firstgid+self.tilecount:
return True
return False
def get_tile_from_raw(self, raw: int) -> int:
if not self.is_raw_in_tileset(raw) and raw:
raise Exception(f"Tile {raw} not in tileset!")
return raw-self.firstgid
class Layer:
"""
A class to handle a tiled map layer
"""
def __init__(self, element: ET.Element):
self.element = element
def get_width(self) -> int:
"""
Get the layer width
"""
value = self.element.get("width")
if value == None: raise Exception("Layer width not found")
return int(value)
def get_height(self) -> int:
"""
Get the layer height
"""
value = self.element.get("height")
if value == None: raise Exception("Layer height not found")
return int(value)
def get_raw_data(self) -> list:
"""
Get the data of the map
"""
data_tag = self.element.find("data")
if data_tag == None: raise Exception("Data not found!")
raw_data = data_tag.text.split(",")
int_data = []
for tile in raw_data:
int_data.append(int(tile))
return int_data
def get_data_with_tileset(self, tileset: Tileset):
raw_data = self.get_raw_data()
out_data = []
for i in raw_data:
out_data.append(tileset.get_tile_from_raw(i))
return out_data
class Object:
"""
An group object (see ObjectGroup) object.
"""
def __init__(self, element: ET.Element):
self.element = element
self.name = element.get("name")
if self.name == None: raise Exception("Name attribute missing!")
self.type = element.get("type")
if self.type == None: raise Exception("Type attribute missing!")
x_str = element.get("x")
if x_str == None: raise Exception("X attribute missing!")
self.x = int(float(x_str))
y_str = element.get("y")
if y_str == None: raise Exception("Y attribute missing!")
self.y = int(float(y_str))
self.id = element.get("id")
if self.id == None: raise Exception("ID attribute missing!")
def __get_point(self) -> list:
# Private method to get a point. Used in get_data.
return [self.x, self.y]
def __get_polyline(self) -> list:
# Private method to get a polyline. Used in get_data.
data = self.element.find("polyline").get("points")
if data == None: raise Exception("Data not found!")
data = data.replace(' ', ',').split(',')
out_data = []
for i in data:
out_data.append(int(float(i)))
return out_data
def get_data(self) -> list:
"""
Get the geometric shape of this object.
"""
if self.element.find("point") != None:
# It is a point.
return self.__get_point()
if self.element.find("polyline") != None:
# It is a polyline.
return self.__get_polyline()
raise Exception("Unknown data!")
def get_data_type(self) -> str:
"""
Get the geometric shape of this object.
"""
if self.element.find("point") != None:
# It is a point.
return "point"
if self.element.find("polyline") != None:
# It is a polyline.
return "polyline"
raise Exception("Unknown data!")
def get_property(self, property: str) -> str:
"""
Get the value of a property.
"""
properties = self.element.find("properties")
if properties == None: raise Exception("Properties not found!")
for i in properties:
if i.get("name") == property:
value = i.get("value")
if value == None: raise Exception("Property value not found!")
return value
raise Exception(f"Property {property} not found!")
class ObjectGroup:
"""
Handle tiled object groups. They can contain points, lines and other
geometric shapes that can be very handy to add NPCs, the path they walk on,
as we do it here, in Collab_RPG.
"""
def __init__(self, element: ET.Element):
self.element = element
self.objects = []
for object in self.element.iterfind("object"):
self.objects.append(Object(object))
class Map:
"""
A class to handle the tiled maps.
"""
def __init__(self, input: str):
"""
Loads a tmx map made with tiled.
"""
tree = ET.parse(input)
self.root = tree.getroot()
self.parent_dir = os.path.abspath(input).rpartition('/')[0]
def get_property(self, property: str) -> str:
"""
Get a map property.
"""
properties = self.root.find("properties")
# If properties wasn't found.
if properties == None:
raise Exception("Properties not found!")
for child in properties:
# Look at the name attribute of each property
if child.get("name") == property:
value = child.get("value")
if value == None: raise Exception("Value attribute not found!")
return value
# The dialog file property wasn't found.
raise Exception(f"\"{property}\" property not found!")
def get_layer_by_id(self, layer_id: str) -> Layer:
"""
Get a layer by its id.
"""
for layer in self.root.iterfind("layer"):
if layer.get("id") == layer_id:
return Layer(layer)
raise Exception("Layer not found!")
def get_layer_by_name(self, name: str) -> Layer:
"""
Get a layer by its name.
"""
for layer in self.root.iterfind("layer"):
if layer.get("name") == name:
return Layer(layer)
raise Exception("Layer not found!")
def get_objectgroup_by_id(self, group_id: str) -> Layer:
"""
Get a layer by its id.
"""
for layer in self.root.iterfind("objectgroup"):
if layer.get("id") == group_id:
return ObjectGroup(layer)
raise Exception("Object group not found!")
def get_objectgroup_by_name(self, name: str) -> Layer:
"""
Get a layer by its name.
"""
for layer in self.root.iterfind("objectgroup"):
if layer.get("name") == name:
return ObjectGroup(layer)
raise Exception("Object group not found!")
def get_tileset_by_firstgid(self, firstgid: int) -> Tileset:
for tileset in self.root.iterfind("tileset"):
if tileset.get("firstgid") == str(firstgid):
return Tileset(tileset, self.parent_dir + "/")
raise Exception("Tileset not found!")
def convert(input, output, params, target): def convert(input, output, params, target):
if params["custom-type"] == "map": if params["custom-type"] == "tmx":
print("ERROR : Asset ", params["name"], " has legacy type map") convert_map(input, output, params, target)
return 1
elif params["custom-type"] == "world":
convert_world(input, output, params, target)
return 0 return 0
elif params["custom-type"] == "custom-image": elif params["custom-type"] == "json":
convert_custom_image(input, output, params, target) convert_dialog(input, output, params, target)
return 0 return 0
elif params["custom-type"] == "font":
convert_font(input, output, params, target)
return 0
elif params["custom-type"] == "dialogs":
print("ERROR : Asset ", params["name"], " has legacy type dialog")
#convert_dialogs(input, output, params, target)
return 0
else:
return 1
def convert_world(input, output, params, target): def convert_map(input, output, params, target):
print( "WE ARE COMPUTING THE WORLD", input ) if VERBOSE: print(f"INFO: Converting map {input} -> {output}")
input_map = Map(input)
data = json.load(open(input, "r")) dialog_file = ""
nbMaps = ["fileName" in i for i in data["maps"]].count(True) background_layer = []
if DEBUG: print( "We have to treat ", nbMaps, " maps") foreground_layer = []
if DEBUG: print( "So let's go ... ") walkable_layer = []
width = 0
structWorld = fxconv.Structure() height = 0
#structExtra = fxconv.Structure() outdoor_tileset = None
walkable_tileset = None
for i in range(nbMaps):
nameMap = data["maps"][i]["fileName"].replace(".tmx","") npc_paths = {}
nameMapFree = nameMap.split("/")[-1] npcs = {}
#count the number of "back" (cd ..) to locate the map on the computer signs = {}
nbRetour = nameMap.count("..")+1
#create the map absolute path # Get the dialog file
try:
nameTMX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".tmx" if VERBOSE: print("INFO: Getting the dialog file")
nameJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json" dialog_file = input_map.get_property("dialogFile")
if VERBOSE: print(f"INFO: Dialog file: {dialog_file}.")
commandline = 'tiled --export-map json ' + nameTMX + ' ' + nameJSON except Exception as e:
if DEBUG: print( "TILED COMMAND LINE FOR MAPS : ", commandline ) sys.stderr.write(f"ERROR: Failed to get the dialog file.\n"
os.system( commandline ) + f" Error message: {e}\n")
sys.exit(1)
mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
if DEBUG: print("Map ", i , " name : ", mapPath ) # Get the outdoor tileset
try:
xmin = data["maps"][i]["x"] if VERBOSE: print("INFO: Getting the outdoor tileset")
if DEBUG: print( "xmin = ", xmin ) outdoor_tileset = input_map.get_tileset_by_firstgid(1)
except Exception as e:
ymin = data["maps"][i]["y"] sys.stderr.write(f"ERROR: Failed to get the outdoor tileset.\n"
if DEBUG: print( "ymin = ", ymin ) + f" Error message: {e}\n")
sys.exit(1)
xmax = data["maps"][i]["x"] + data["maps"][i]["width"]
if DEBUG: print( "xmax = ", xmax ) # Get the walkable tileset
try:
ymax = data["maps"][i]["y"] + data["maps"][i]["height"] if VERBOSE: print("INFO: Getting the walkable tileset")
if DEBUG: print( "ymax = ", ymax ) walkable_tileset = input_map.get_tileset_by_firstgid(409)
except Exception as e:
map = get_tile_map_data( mapPath, output, params, target, xmin, ymin, xmax, ymax) sys.stderr.write(f"ERROR: Failed to get the walkable tileset.\n"
if DEBUG: print( "Map = ", map ) + f" Error message: {e}\n")
structWorld += fxconv.ptr( map ) sys.exit(1)
#structWorld += fxconv.u32(0) # Get the background
try:
#generate ! if VERBOSE: print("INFO: Getting the background layer")
fxconv.elf(structWorld, output, "_" + params["name"], **target) bg_layer = input_map.get_layer_by_name("Background")
# The bg layer will be used to set the map width and height.
width = bg_layer.get_width()
def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax): height = bg_layer.get_height()
print( "WE ARE COMPUTING THE MAP : ", input ) if VERBOSE: print(f"INFO: Map size: ({width}, {height}).")
data = json.load(open(input, "r")) # Get the layer data himself
background_layer = bg_layer.get_data_with_tileset(outdoor_tileset)
#find the tileset in use. it's a relative path (like ../tileset.tsx) # Check if the size of the layer data is correct.
nameTileset = data["tilesets"][0]["source"].replace(".tsx","") if len(background_layer) != width*height:
if DEBUG: print(nameTileset) raise Exception("Bad layer size!")
#the name of the tileset without the .something if VERBOSE: print("INFO: Layer data has the right size.")
nameTilesetFree = nameTileset.split("/")[-1] except Exception as e:
#count the number of "back" (cd ..) to locate the tileset on the computer sys.stderr.write(f"ERROR: Failed to get the background layer.\n"
nbRetour = nameTileset.count("..")+1 + f" Error message: {e}\n")
#create the tileset absolute path sys.exit(1)
tilesetTSX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".tsx"
tilesetJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json" # Get the foreground
try:
commandline = 'tiled --export-tileset json ' + tilesetTSX + ' ' + tilesetJSON if VERBOSE: print("INFO: Getting the foreground layer")
if DEBUG: print( "TILED COMMAND LINE FOR TILESET : ", commandline ) fg_layer = input_map.get_layer_by_name("Foreground")
os.system( commandline ) # Get the layer data himself
foreground_layer = fg_layer.get_data_with_tileset(outdoor_tileset)
tileset = open(tilesetJSON, "r") # Check if the size of the layer data is correct.
data_tileset = json.load(tileset) if len(foreground_layer) != width*height:
tileset_size = data_tileset.get("columns") raise Exception("Bad layer size!")
tileset.close() if VERBOSE: print("INFO: Layer data has the right size.")
except Exception as e:
#find the ID of the first tile in the walkable tileset () sys.stderr.write(f"ERROR: Failed to get the foreground layer.\n"
indexWalkable = data["tilesets"][1]["firstgid"] + f" Error message: {e}\n")
if DEBUG: print(indexWalkable) sys.exit(1)
#Extract from the json the width, height # Get the walkable layer
w, h = data["width"], data["height"] try:
if VERBOSE: print("INFO: Getting the walkable layer")
#nbTileLayer is the number of "true" layers (without ObjectsLayer) wk_layer = input_map.get_layer_by_name("Walkable")
nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1 # Get the layer data himself
if DEBUG: print( nbTilelayer) walkable_layer = wk_layer.get_data_with_tileset(walkable_tileset)
# Check if the size of the layer data is correct.
#index of the various layers (may change from one map to another) if len(walkable_layer) != width*height:
layer_walkable = 0 raise Exception("Bad layer size!")
layer_foreground = 0 if VERBOSE: print("INFO: Layer data has the right size.")
layer_background = 0 except Exception as e:
sys.stderr.write(f"ERROR: Failed to get the walkable layer.\n"
#create the structure of the map + f" Error message: {e}\n")
structMap = fxconv.Structure() sys.exit(1)
structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) # Get the extra data
structMap += fxconv.u32(tileset_size) try:
if VERBOSE: print("INFO: Getting the extra data")
structMap += fxconv.u32(xmin) + fxconv.u32(ymin) + fxconv.u32(xmax) + fxconv.u32(ymax) ed_objgroup = input_map.get_objectgroup_by_name("ExtraData")
# Get the paths the NPCs take.
structMap += fxconv.ref(f"img_{nameTilesetFree}") for object in ed_objgroup.objects:
if object.get_data_type() == "polyline":
npc_paths[object.id] = object.get_data()
#extraction of the data contained in the layer "Walkable" of the map # Get the NPCs
for i in range(nbTilelayer+1): for object in ed_objgroup.objects:
datavalid = data["layers"][i] if object.get_data_type() == "point" and object.type == "NPC":
if datavalid["name"]=="Walkable": path = None
layer_walkable = i if int(object.get_property("hasPath")):
if DEBUG: print( "Walkable Tile Data in layer : ", layer_walkable) if object.get_property("path") in npc_paths:
break path = npc_paths[object.get_property("path")]
elif i==nbTilelayer:
print( "ERROR : No Walkable layer data !!!" )
walk_data = bytes()
layer = data["layers"][layer_walkable]
for tile in layer["data"]:
#print( tile )
if tile == 0: walk_data += fxconv.u8(tile) #if walkable_data = 0 then it is a blanck cell so nothing to change
else : walk_data += fxconv.u8(tile-indexWalkable) #if !=0 than we need to shift the tile number by considering the first tileID (given by indexwalkable)
structMap += fxconv.ptr(walk_data)
nbextra = 0
extradata = fxconv.Structure()
nbextra, extradata = get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax)
if (nbextra==0):
structMap += fxconv.u32( 0 )
structMap += fxconv.u32( 0 )
else:
structMap += fxconv.u32( int(nbextra) )
structMap += fxconv.ptr( extradata )
nameDialog = data["properties"][0]["value"]
dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog
if DEBUG: print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile )
nbdiag = 0
diagdata = fxconv.Structure()
nbdiag, diagdata = convert_dialogs(dialogfile, output, params, target)
if (nbdiag==0):
structMap += fxconv.u32( 0 )
structMap += fxconv.u32( 0 )
else:
structMap += fxconv.u32( int(nbdiag) )
structMap += fxconv.ptr( diagdata )
#extraction of the data contained in the layer "Background" and "Foreground" of the map
#import the Background layer of the map
for i in range(nbTilelayer+1):
datavalid = data["layers"][i]
if datavalid["name"]=="Background":
layer_background = i
if DEBUG: print( "Background Tile Data in layer : ", layer_background)
break
elif i==nbTilelayer:
print( "ERROR : No Background layer data !!!" )
layer_data = bytes()
layer = data["layers"][layer_background]
for tile in layer["data"]:
layer_data += fxconv.u16(tile-1)
structMap += fxconv.ptr(layer_data)
#import the foreground layer of the map
for i in range(nbTilelayer+1):
datavalid = data["layers"][i]
if datavalid["name"]=="Foreground":
layer_foreground = i
if DEBUG: print( "Foreground Tile Data in layer : ", layer_foreground)
break
elif i==nbTilelayer:
print( "ERROR : No Foreground layer data !!!" )
layer_data = bytes()
layer = data["layers"][layer_foreground]
for tile in layer["data"]:
layer_data += fxconv.u16(tile-1)
structMap += fxconv.ptr(layer_data)
return structMap
def get_extra_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
if DEBUG: print( "WE ARE COMPUTING THE EXTRA DATA OF THE MAP : ", input )
data = json.load(open(input, "r"))
nblayer = ["id" in i for i in data["layers"]].count(True) - 1
if DEBUG: print( "I found ", nblayer, " of extradata")
#index of the various layers (may change from one map to another)
layer_extradata = 0
#import the foreground layer of the map
for i in range(nblayer+1):
datavalid = data["layers"][i]
if datavalid["name"]=="ExtraData":
layer_extradata = i
if DEBUG: print( "Extra Data in layer : ", layer_extradata)
break
elif i==nblayer:
print( "ERROR : No ExtraData layer data !!!" )
return 0, fxconv.u32(0)
#create the structure of the map
structData = fxconv.Structure()
nbSign = 0
nbNPC = 0
nbPortal = 0
nbDiag = 0
npcs = fxconv.Structure()
signs = fxconv.Structure()
portals = fxconv.Structure()
layer = data["layers"][layer_extradata]
for i in layer["objects"]:
#get the type of the item
tpe = i["type"]
#we check if the type corresponds to a items of type Point in Tiled
if tpe in ("NPC"):
currData = fxconv.Structure()
x = i["x"] + xmin
y = i["y"] + ymin
nme = i["name"]
dialogID = None
needAction = None
path = 0
path_length = 0
xdata = None
ydata = None
face_type = "MALE"
#we now fill all the properties of this item
for j in i["properties"]:
#property "dialog"
if j["name"]=="dialogID":
dialogID = j[ "value" ]
nbDiag += 1
#property "isQuestion"
elif j["name"]=="needAction": needAction = j[ "value" ]
else:
#Extra properties for NPCs (path and face)
if tpe=="NPC":
if j["name"]=="face":
face_type = j["value"]
elif j["name"]=="hasPath":
pathID = None
path = j[ "value" ]
if path==1:
if DEBUG: print( "PNJ has path - NOW LOOKING FOR RELEVANT DATA" )
# we start looking for path data with first the ID of the path Object
for u in i["properties"]:
if u["name"]=="path":
pathID = u[ "value" ]
if DEBUG: print( "path ID is identified : ID= ", pathID )
for v in layer["objects"]:
if v[ "id" ] == pathID:
if DEBUG: print( "path data found : " )
xdata = bytes()
ydata = bytes()
for w in v[ "polyline" ]:
path_length = path_length + 1
if DEBUG: print( "X= ", w[ "x" ], " Y= ", w[ "y" ] )
xdata += fxconv.u16( int( w[ "x" ] ) )
ydata += fxconv.u16( int( w[ "y" ] ) )
else:
if DEBUG: print( "PNJ has no Path" )
else: else:
print( "UNIDENTIFIED PROPERTY : ", j["name"]) raise Exception("Path required but not found!")
data = {
"position": object.get_data(),
"needAction": object.get_property("needAction"),
"dialogID": object.get_property("dialogID"),
#"face": object.get_property("face"),
"path": path
}
npcs[object.id] = data
# Get the signs
for object in ed_objgroup.objects:
if object.get_data_type() == "point" and object.type in SIGN_TYPES:
data = {
"needAction": object.get_property("needAction"),
"dialogID": object.get_property("dialogID")
}
signs[object.id] = data
except Exception as e:
sys.stderr.write(f"ERROR: Failed to get the extra data.\n"
+ f" Error message: {e}\n")
sys.exit(1)
# Generate the structs
#
if DEBUG: def convert_dialog(input, output, params, target):
print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID ) if VERBOSE: print(f"INFO: Converting dialog file {input} -> {output}")
print( " Type= ", tpe, " Name= ", nme, "Face =", face_type)
print( " Action?= ", needAction )
currData += fxconv.u32(0)
currData += fxconv.u32(0)
currData += fxconv.u32( int(x) )
currData += fxconv.u32( int(y) )
currData += fxconv.u16(0) #TODO : faceid
currData += fxconv.u8(0)
currData += fxconv.u8(1)
currData += fxconv.u32( int(dialogID) )
currData += fxconv.u32( int(needAction) )
currData += fxconv.string( nme )
if path==0:
currData += fxconv.u32(0)
currData += fxconv.u32(0)
currData += fxconv.u32(0)
currData += fxconv.u32(0)
currData += fxconv.u32(0)
else:
o_xdata = fxconv.Structure()
o_xdata += xdata
o_ydata = fxconv.Structure()
o_ydata += ydata
currData += fxconv.u32(path)
currData += fxconv.u32(path_length)
currData += fxconv.u32(0)
currData += fxconv.ptr(o_xdata)
currData += fxconv.ptr(o_ydata)
#TODO
currData += fxconv.i32(0)
currData += fxconv.u8(0)
currData += fxconv.u8(0)
currData += fxconv.u16(0)
nbNPC += 1
signs += currData
elif tpe in ["SGN", "INFO"]:
currData = fxconv.Structure()
x = i["x"] + xmin
y = i["y"] + ymin
nme = i["name"]
if tpe == "SIGN":
icon = 0
else:
icon = 1
dialogID = None
needAction = None
#we now fill all the properties of this item
for j in i["properties"]:
#property "dialog"
if j["name"]=="dialogID":
dialogID = j[ "value" ]
nbDiag += 1
#property "isQuestion"
elif j["name"]=="needAction": needAction = j[ "value" ]
else:
print( "UNIDENTIFIED PROPERTY : ", j["name"])
currData += fxconv.u32( int(x) )
currData += fxconv.u32( int(y) )
currData += fxconv.u32(icon)
currData += fxconv.string( nme )
currData += fxconv.u32( int(dialogID) )
currData += fxconv.u32( int(needAction) )
nbSign += 1
signs += currData
elif tpe == "PORTAL":
nbPortal+=1
currData = fxconv.Structure()
x = i["x"] + xmin
y = i["y"] + ymin
h = -1
w = -1
tp_interior = -1
tp_to = -1
for j in i["properties"]:
if j["name"] == "h":
h = j["value"]
if j["name"] == "w":
w = j["value"]
if j["name"] == "tp_interior":
tp_interior = j["value"]
if j["name"] == "tp_to":
tp_to = j["value"]
if w==-1 or h==-1 or tp_interior==-1 or tp_to==-1:
print("ERROR : Invalid portal " + i["ID"])
continue
currData += fxconv.u32(int(x))
currData += fxconv.u32(int(y))
currData += fxconv.u32(int(w))
currData += fxconv.u32(int(h))
currData += fxconv.u16(int(tp_interior))
currData += fxconv.u16(int(tp_to))
portals += currData
#else we do nothing
else:
print( 'Unknown object type "'+tpe+'" !' )
structData += fxconv.u32(nbNPC)
if nbNPC:
structData += fxconv.ptr(npcs)
else:
structData += fxconv.u32(0)
structData += fxconv.u32(nbSign)
if nbSign:
structData += fxconv.ptr(signs)
else:
structData += fxconv.u32(0)
structData += fxconv.u32(nbPortal)
if nbPortal:
structData += fxconv.ptr(portals)
else:
structData += fxconv.u32(0)
return nbDiag, structData
def convert_custom_image(input, output, params, target):
scale = int(params.get("scale", 1))
# Upscale image before converting
im = Image.open(input)
im = im.resize((im.width * scale, im.height * scale),
resample=Image.NEAREST)
o = fxconv.convert_image_cg(im, params)
fxconv.elf(o, output, "_" + params["name"], **target)
def convert_font(input, output, params, target):
o = fxconv.convert_topti(input, params)
fxconv.elf(o, output, "_" + params["name"], **target)
def convert_dialogs(input, output, params, target):
if DEBUG: print( "WE ARE COMPUTING THE DIALOGS FROM : ", input )
data = json.load(open(input, "r"))
structDialogs = fxconv.Structure()
nbdialogs = 0
for d in data["dialogs"]:
if DEBUG: print( int(d[ "ID" ]))
# print( d[ "dialog" ] )
if DEBUG: print( int(d[ "isQuestion" ]) )
# print( d[ "choice" ].replace('$', chr(0)) )
# print( d[ "conclusion1" ] )
# print( int(d[ "next1" ] ) )
# print( d[ "conclusion2" ] )
# print( int(d[ "next2" ] ) )
# print( int(d[ "nextOther" ]) )
nbdialogs = nbdialogs + 1
structDialogs += fxconv.u32( int(d[ "ID" ] ) )
structDialogs += fxconv.string( d[ "dialog" ] )
structDialogs += fxconv.u32( int(d[ "isQuestion" ] ) )
structDialogs += fxconv.string( d[ "choice" ].replace('$', chr(0)) )
structDialogs += fxconv.string( d[ "conclusion1" ] )
structDialogs += fxconv.u32( int(d[ "next1" ] ) )
structDialogs += fxconv.string( d[ "conclusion2" ] )
structDialogs += fxconv.u32( int(d[ "next2" ] ) )
structDialogs += fxconv.u32( int(d[ "nextOther" ] ) )
return nbdialogs, structDialogs
#fxconv.elf(structDialogs, output, "_" + params["name"], **target)

View file

@ -1,7 +1,19 @@
WorldRPG.world: level0.tmx:
custom-type: world custom-type: tmx
name: worldRPG name: level0
#DialogsRPG.json: level1.tmx:
# custom-type: dialogs custom-type: tmx
# name: dialogRPG name: level1
level2.tmx:
custom-type: tmx
name: level2
level3.tmx:
custom-type: tmx
name: level3
level4.tmx:
custom-type: tmx
name: level4

0
assets/tiled.py Normal file
View file