mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-28 20:43:42 +01:00
405 lines
No EOL
12 KiB
Python
405 lines
No EOL
12 KiB
Python
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":
|
|
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):
|
|
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 )
|
|
|
|
|
|
|
|
|
|
nameDialog = data["properties"][0]["value"]
|
|
dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog
|
|
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
|
|
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()
|
|
ydata = bytes()
|
|
|
|
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" ] ) )
|
|
|
|
else:
|
|
print( "PNJ has no Path" )
|
|
|
|
else:
|
|
print( "UNIDENTIFIED PROPERTY : ", j["name"])
|
|
|
|
print( "OBJECT X= ", x, " Y= ", y, "STR= ", dialogID )
|
|
print( " Type= ", tpe, " Name= ", nme )
|
|
print( " Action?= ", needAction )
|
|
|
|
|
|
|
|
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:
|
|
print( "Skip this object" )
|
|
|
|
|
|
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()
|
|
nbdialogs = 0
|
|
|
|
for d in data["dialogs"]:
|
|
print( int(d[ "ID" ]))
|
|
# print( d[ "dialog" ] )
|
|
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) |