Collab_RPG/assets/converters.py

369 lines
11 KiB
Python
Raw Normal View History

from random import randint
from PIL import Image
import fxconv
import json
import pathlib
import csv
import os
def convert(input, output, params, target):
if params["custom-type"] == "map":
print("ERROR : Asset ", params["name"], " has legacy type map")
return 1
elif params["custom-type"] == "world":
convert_world(input, output, params, target)
return 0
elif params["custom-type"] == "custom-image":
convert_custom_image(input, output, params, target)
return 0
elif params["custom-type"] == "font":
convert_font(input, output, params, target)
return 0
elif params["custom-type"] == "dialogs":
convert_dialogs(input, output, params, target)
return 0
else:
return 1
def convert_world(input, output, params, target):
print( "WE ARE COMPUTING THE WORLD", input )
data = json.load(open(input, "r"))
nbMaps = ["fileName" in i for i in data["maps"]].count(True)
print( "We have to treat ", nbMaps, " maps")
print( "So let's go ... ")
structWorld = fxconv.Structure()
#structExtra = fxconv.Structure()
for i in range(nbMaps):
nameMap = data["maps"][i]["fileName"].replace(".tmx","")
nameMapFree = nameMap.split("/")[-1]
#count the number of "back" (cd ..) to locate the map on the computer
nbRetour = nameMap.count("..")+1
#create the map absolute path
nameTMX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".tmx"
nameJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
commandline = 'tiled --export-map json ' + nameTMX + ' ' + nameJSON
print( "TILED COMMAND LINE FOR MAPS : ", commandline )
os.system( commandline )
mapPath = "/".join(input.split("/")[:-nbRetour]) + "/" + nameMap + ".json"
print("Map ", i , " name : ", mapPath )
xmin = data["maps"][i]["x"]
print( "xmin = ", xmin )
ymin = data["maps"][i]["y"]
print( "ymin = ", ymin )
xmax = data["maps"][i]["x"] + data["maps"][i]["width"]
print( "xmax = ", xmax )
ymax = data["maps"][i]["y"] + data["maps"][i]["height"]
print( "ymax = ", ymax )
map = get_tile_map_data( mapPath, output, params, target, xmin, ymin, xmax, ymax)
print( "Map = ", map )
structWorld += fxconv.ptr( map )
structWorld += fxconv.u32(0)
#generate !
fxconv.elf(structWorld, output, "_" + params["name"], **target)
def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax):
print( "WE ARE COMPUTING THE MAP : ", input )
data = json.load(open(input, "r"))
#find the tileset in use. it's a relative path (like ../tileset.tsx)
nameTileset = data["tilesets"][0]["source"].replace(".tsx","")
print(nameTileset)
#the name of the tileset without the .something
nameTilesetFree = nameTileset.split("/")[-1]
#count the number of "back" (cd ..) to locate the tileset on the computer
nbRetour = nameTileset.count("..")+1
#create the tileset absolute path
tilesetTSX = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".tsx"
tilesetJSON = "/".join(input.split("/")[:-nbRetour]) + "/" + nameTileset + ".json"
commandline = 'tiled --export-tileset json ' + tilesetTSX + ' ' + tilesetJSON
print( "TILED COMMAND LINE FOR TILESET : ", commandline )
os.system( commandline )
tileset = open(tilesetJSON, "r")
data_tileset = json.load(tileset)
tileset_size = data_tileset.get("columns")
tileset.close()
#find the ID of the first tile in the walkable tileset ()
indexWalkable = data["tilesets"][1]["firstgid"]
print(indexWalkable)
#Extract from the json the width, height
w, h = data["width"], data["height"]
#nbTileLayer is the number of "true" layers (without ObjectsLayer)
nbTilelayer = ["data" in i for i in data["layers"]].count(True) - 1
print( nbTilelayer)
#index of the various layers (may change from one map to another)
layer_walkable = 0
layer_foreground = 0
layer_background = 0
#create the structure of the map
structMap = fxconv.Structure()
structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer)
structMap += fxconv.u32(tileset_size)
structMap += fxconv.u32(xmin) + fxconv.u32(ymin) + fxconv.u32(xmax) + fxconv.u32(ymax)
structMap += fxconv.ref(f"img_{nameTilesetFree}")
#extraction of the data contained in the layer "Walkable" of the map
for i in range(nbTilelayer+1):
datavalid = data["layers"][i]
if datavalid["name"]=="Walkable":
layer_walkable = i
print( "Walkable Tile Data in layer : ", layer_walkable)
break
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 )
#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
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
print( "Foreground Tile Data in layer : ", layer_foreground)
break
elif i==nbTilelayer:
printf( "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):
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
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
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()
nbExtraData = 0
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 ( "SGN", "NPC", "INFO" ):
nbExtraData = nbExtraData + 1
x = i["x"] + xmin
y = i["y"] + ymin
nme = i["name"]
dialogID = None
needAction = None
path = 0
path_length = 0
xdata = None
ydata = None
#we now fill all the properties of this item
for j in i["properties"]:
#property "dialog"
if j["name"]=="dialogID": dialogID = j[ "value" ]
#property "isQuestion"
elif j["name"]=="needAction": needAction = j[ "value" ]
else:
#Extra properties for NPCs (path)
if tpe=="NPC":
if j["name"]=="hasPath":
pathID = None
path = j[ "value" ]
if path==1:
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" ]
print( "path ID is identified : ID= ", pathID )
for v in layer["objects"]:
if v[ "id" ] == pathID:
print( "path data found : " )
xdata = bytes("", "UTF-16")
ydata = bytes("", "UTF-16")
for w in v[ "polyline" ]:
path_length = path_length + 1
print( "X= ", w[ "x" ], " Y= ", w[ "y" ] )
xdata += fxconv.u16( int( w[ "x" ] ) )
ydata += fxconv.u16( int( w[ "y" ] ) )
print("xdata : ", xdata)
print("ydata : ", ydata)
else:
print( "PNJ has no Path" )
else:
print( "UNIDENTIFIED PROPERTY : ", j["name"])
print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialog )
print( " Type= ", tpe, " Name= ", nme )
print( " Q?= ", quest, " Choi= ", choi )
print( " c1= ", conc1, " c2=", conc2)
structData += fxconv.u32( int(x) )
structData += fxconv.u32( int(y) )
structData += fxconv.string( nme )
structData += fxconv.string( tpe )
structData += fxconv.u32( int(dialogID))
structData += fxconv.u32( int(needAction) )
if path==0:
structData += fxconv.u32(0)
structData += fxconv.u32(0)
structData += fxconv.u32(0)
structData += fxconv.u32(0)
else:
o_xdata = fxconv.Structure()
o_xdata += xdata
o_ydata = fxconv.Structure()
o_ydata += ydata
structData += fxconv.u32(path)
structData += fxconv.u32(path_length)
structData += fxconv.ptr(o_xdata)
structData += fxconv.ptr(o_ydata)
#else we do nothing (yet)
else:
break
return nbExtraData, 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):
print( "WE ARE COMPUTING THE DIALOGS FROM : ", input )
data = json.load(open(input, "r"))
structDialogs = fxconv.Structure()
for d in data["dialogs"]:
structDialogs += fxconv.u32( int(d[ "ID" ] ) )
structDialogs += fxconv.string( int(d[ "dialog" ] ) )
structDialogs += fxconv.u32( int(d[ "isQuestion" ] ) )
structDialogs += fxconv.string( int(d[ "choice" ] ) )
structDialogs += fxconv.string( int(d[ "conclusion1" ] ) )
structDialogs += fxconv.u32( int(d[ "next1" ] ) )
structDialogs += fxconv.string( int(d[ "conclusion2" ] ) )
structDialogs += fxconv.u32( int(d[ "next2" ] ) )
structDialogs += fxconv.u32( int(d[ "nextOther" ] ) )
fxconv.elf(structDialogs, output, "_" + params["name"], **target)