2022-05-22 23:58:00 +02:00
from random import randint
2021-07-29 18:33:22 +02:00
import fxconv
2021-07-30 02:01:05 +02:00
import json
2022-02-17 21:26:33 +01:00
import pathlib
2022-05-03 00:40:09 +02:00
import csv
2021-07-29 18:33:22 +02:00
def convert ( input , output , params , target ) :
if params [ " custom-type " ] == " map " :
convert_map ( input , output , params , target )
return 0
2022-01-24 21:27:51 +01:00
elif params [ " custom-type " ] == " capacities " :
2022-01-24 15:15:12 +01:00
convert_capa ( input , output , params , target )
return 0
2022-02-10 15:20:42 +01:00
elif params [ " custom-type " ] == " monster " :
convert_monster ( input , output , params , target )
return 0
2022-03-23 01:16:24 +01:00
elif params [ " custom-type " ] == " player_moves " :
convert_player_moves ( input , output , params , target )
return 0
2022-04-16 02:21:07 +02:00
elif params [ " custom-type " ] == " items " :
convert_items ( input , output , params , target )
return 0
2022-05-03 00:40:09 +02:00
elif params [ " custom-type " ] == " table_type " :
convert_table_type ( input , output , params , target )
return 0
2021-07-29 18:33:22 +02:00
else :
return 1
def convert_map ( input , output , params , target ) :
2021-08-27 02:11:05 +02:00
TILE_BRIDGE = - 1 #only for bridge detection to avoid solid behind
2021-07-31 03:40:14 +02:00
TILE_AIR = 0
TILE_SOLID = 1
2021-08-22 02:39:01 +02:00
TILE_DOOR_IN = 2
TILE_DOOR_OUT = 3
2021-08-26 01:17:48 +02:00
TILE_TALKABLE = 4
2022-01-18 23:43:48 +01:00
TILE_TELEPORTER = 5
2022-01-23 00:53:07 +01:00
TILE_GRASS = 6
2022-03-22 23:16:37 +01:00
TILE_ICE = 7
2021-07-29 18:33:22 +02:00
2022-01-18 18:59:09 +01:00
DIALOG_LAYOUT = " dialog "
2022-01-18 23:43:48 +01:00
TELEPORTER_LAYOUT = " teleporter "
2022-02-17 00:02:00 +01:00
ZONE_LAYOUT = " zone "
2022-01-18 18:59:09 +01:00
data = json . load ( open ( input , " r " ) )
2021-07-30 02:01:05 +02:00
2021-08-22 02:39:01 +02:00
#find the tileset in use. it's a relative path (like ../tileset.tsx)
nameTileset = data [ " tilesets " ] [ 0 ] [ " source " ] . replace ( " .tsx " , " " )
2022-05-26 18:47:58 +02:00
print ( nameTileset )
2021-08-22 02:39:01 +02:00
#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
2022-05-26 18:47:58 +02:00
tilesetPath = " / " . join ( input . split ( " / " ) [ : - nbRetour ] ) + " / " + nameTileset + " .json "
2021-08-22 02:39:01 +02:00
tileset = open ( tilesetPath , " r " )
2021-07-31 03:40:14 +02:00
data_tileset = json . load ( tileset )
2022-01-22 17:12:24 +01:00
tileset_size = data_tileset . get ( " columns " )
2021-07-31 03:40:14 +02:00
tileset . close ( )
tile_value = { }
2022-03-22 23:16:37 +01:00
tile_type = {
" air " : TILE_AIR ,
" solid " : TILE_SOLID ,
" door_in " : TILE_DOOR_IN ,
" door_out " : TILE_DOOR_OUT ,
" talkable " : TILE_TALKABLE ,
" bridge " : TILE_BRIDGE ,
" teleporter " : TILE_TELEPORTER ,
" grass " : TILE_GRASS ,
" ice " : TILE_ICE
}
2021-08-27 02:11:05 +02:00
#create a dictionnary {tile id:type}
2021-07-31 03:40:14 +02:00
for i in data_tileset [ " tiles " ] :
2021-08-27 02:11:05 +02:00
id = i [ " id " ] + 1
type = i [ " type " ]
2022-03-22 23:16:37 +01:00
value = tile_type . get ( type ) if type in tile_type else TILE_AIR
2021-08-27 02:11:05 +02:00
tile_value [ id ] = value
#Extract from the json the width, height
2021-08-17 22:19:19 +02:00
w , h = data [ " width " ] , data [ " height " ]
2021-07-31 03:40:14 +02:00
2021-08-27 02:11:05 +02:00
#nbTileLayer is the number of "true" layers (without ObjectsLayer)
2022-01-18 18:59:09 +01:00
nbTilelayer = [ " data " in i for i in data [ " layers " ] ] . count ( True )
objectLayers = data [ " layers " ] [ nbTilelayer : len ( data [ " layers " ] ) ]
2021-08-26 01:17:48 +02:00
2022-01-18 18:59:09 +01:00
nbDialog = 0
2022-01-18 23:43:48 +01:00
nbTelep = 0
2022-02-17 00:02:00 +01:00
nbZone = 0
2021-08-26 01:17:48 +02:00
structMap = fxconv . Structure ( )
dialogs = fxconv . Structure ( )
2022-01-18 23:43:48 +01:00
teleporter = fxconv . Structure ( )
2022-02-17 00:02:00 +01:00
zone = fxconv . Structure ( )
2021-08-26 01:17:48 +02:00
2022-05-22 16:46:31 +02:00
try :
idmap = data [ " properties " ] [ 0 ] [ " value " ]
except KeyError :
raise Exception ( " La carte n ' a pas d ' identifiant " )
2022-01-18 18:59:09 +01:00
for layer in objectLayers :
if layer . get ( " name " ) == DIALOG_LAYOUT :
nbDialog = len ( layer [ " objects " ] )
2022-05-22 23:58:00 +02:00
dialogs = parseDialog ( layer , idmap )
2022-01-18 23:43:48 +01:00
elif layer . get ( " name " ) == TELEPORTER_LAYOUT :
nbTelep = len ( layer [ " objects " ] )
teleporter = parseTeleporter ( layer )
2022-02-17 00:02:00 +01:00
elif layer . get ( " name " ) == ZONE_LAYOUT :
nbZone = len ( layer [ " objects " ] )
2022-05-22 16:46:31 +02:00
zone = parseZone ( layer , idmap )
2022-01-18 18:59:09 +01:00
else :
2022-03-22 23:16:37 +01:00
print ( " UNKNOWN LAYER FOUND : " + layer . get ( " name " ) )
2022-01-18 18:59:09 +01:00
2022-02-17 00:02:00 +01:00
structMap + = fxconv . u32 ( w ) + fxconv . u32 ( h ) + fxconv . u32 ( nbTilelayer ) + fxconv . u32 ( nbDialog ) + fxconv . u32 ( nbTelep ) + fxconv . u32 ( nbZone )
2022-01-18 18:59:09 +01:00
structMap + = fxconv . ref ( f " img_ { nameTilesetFree } " )
2022-01-22 17:12:24 +01:00
structMap + = fxconv . u32 ( tileset_size )
2021-08-26 01:17:48 +02:00
structMap + = fxconv . ptr ( dialogs )
2022-01-18 23:43:48 +01:00
structMap + = fxconv . ptr ( teleporter )
2022-02-17 00:02:00 +01:00
structMap + = fxconv . ptr ( zone )
2021-07-31 03:40:14 +02:00
2021-08-18 02:10:31 +02:00
#generation of the collision map (take the maximum of the layer except for bridges)
#bridges are always walkable
info_map = bytes ( )
maxValue = 0
bridge = False
for x in range ( w * h ) :
2021-08-26 01:17:48 +02:00
for i in range ( nbTilelayer ) :
2021-08-18 02:10:31 +02:00
value = tile_value . get ( data [ " layers " ] [ i ] [ " data " ] [ x ] )
2022-05-03 00:40:09 +02:00
#attention : priorité aux valeurs hautes : un bloc d'herbe sera prioritaire sur un bloc solide
2021-08-18 02:10:31 +02:00
if value == None : value = TILE_AIR
if value > maxValue : maxValue = value
if value == TILE_BRIDGE :
maxValue = TILE_AIR
bridge = True
if bridge :
if value != TILE_AIR :
maxValue = value
info_map + = fxconv . u16 ( maxValue )
maxValue = 0
bridge = False
2021-08-27 02:11:05 +02:00
structMap + = fxconv . ptr ( info_map )
2021-08-18 02:10:31 +02:00
#generate the array of tiles from the layer
2021-08-26 01:17:48 +02:00
for i in range ( nbTilelayer ) :
2021-08-18 02:10:31 +02:00
layer_data = bytes ( )
2021-08-26 01:17:48 +02:00
layer = data [ " layers " ] [ i ]
2021-08-18 02:10:31 +02:00
for tile in layer [ " data " ] :
layer_data + = fxconv . u16 ( tile )
2021-08-26 01:17:48 +02:00
2021-08-27 02:11:05 +02:00
structMap + = fxconv . ptr ( layer_data )
2021-07-29 18:33:22 +02:00
2021-08-15 03:10:05 +02:00
#generate !
2022-01-18 18:59:09 +01:00
fxconv . elf ( structMap , output , " _ " + params [ " name " ] , * * target )
2022-05-22 23:58:00 +02:00
def parseDialog ( layer , idmap ) :
2022-01-18 18:59:09 +01:00
dialogs = fxconv . Structure ( )
2022-05-22 23:58:00 +02:00
idDialog = 0
base_dialog = [
" Encore toi ? Tu n ' as pas quelque chose d ' autre à faire ? " ,
" Mais... Tu vas me lacher oui ? " ,
" re-bonjour, comment vas-tu depuis la dernière fois ? " ,
" Tu reviens me voir après tout ce temps ? " ,
" Toujours un plaisir de te revoir. " ,
" La vie est pleine de surprise, je ne m ' attendais pas à te revoir ! " ,
" Salut ! Belle journée n ' est-ce pas ? " ,
" Il faut savoir apprécier les bonnes choses de la vie. " ,
" La dernière fois je suis tombé sur une horde de monstre, quelle panique ! " ,
" As-tu visité notre belle région depuis la dernière fois ? " ,
" Prend le temps, on n ' a qu ' une seule vie n ' est-ce pas ! " ,
" Pour être honnête, je ne t ' apprécie pas beaucoup. "
]
2022-01-18 18:59:09 +01:00
for i in layer [ " objects " ] :
dialogs + = fxconv . u32 ( int ( i [ " x " ] / i [ " width " ] ) )
#Tiled seem to start at the bottom y of the object
dialogs + = fxconv . u32 ( int ( i [ " y " ] / i [ " width " ] ) - 1 )
try :
2022-05-22 23:58:00 +02:00
dialogs + = fxconv . u32 ( int ( f " { idmap } { idDialog } { idmap } " ) )
listProper = set ( ( a [ ' name ' ] ) for a in i [ " properties " ] )
idDialog + = 1
stoText = " "
2022-01-18 18:59:09 +01:00
for j in i [ " properties " ] :
2022-05-22 23:58:00 +02:00
if ( j [ " name " ] == " name " ) : dialogs + = fxconv . string ( j [ " value " ] )
if ( j [ " name " ] == " text " ) :
dialogs + = fxconv . string ( j [ " value " ] )
stoText = j [ " value " ]
if ( j [ " name " ] == " text2 " ) : dialogs + = fxconv . string ( j [ " value " ] )
if not " text2 " in listProper :
if " ~ " in stoText : dialogs + = fxconv . string ( base_dialog [ randint ( 0 , len ( base_dialog ) - 1 ) ] )
else : dialogs + = fxconv . string ( " " )
if ( " exclusive " in listProper ) :
for j in i [ " properties " ] :
if ( j [ " name " ] == " exclusive " ) :
if j [ " value " ] : dialogs + = fxconv . u32 ( 1 )
else : dialogs + = fxconv . u32 ( 0 )
else :
if " ~ " in stoText : dialogs + = fxconv . u32 ( 1 )
else : dialogs + = fxconv . u32 ( 0 )
2022-01-18 18:59:09 +01:00
except KeyError :
dialogs + = fxconv . string ( " default name " )
dialogs + = fxconv . string ( " default text " )
2022-05-22 23:58:00 +02:00
dialogs + = fxconv . string ( " default text2 " )
dialogs + = fxconv . u32 ( 0 )
2022-01-18 23:43:48 +01:00
return dialogs
def parseTeleporter ( layer ) :
teleporter = fxconv . Structure ( )
for i in layer [ " objects " ] :
teleporter + = fxconv . u32 ( int ( i [ " x " ] / i [ " width " ] ) )
#Tiled seem to start at the bottom y of the object
teleporter + = fxconv . u32 ( int ( i [ " y " ] / i [ " width " ] ) - 1 )
try :
if len ( i [ " properties " ] ) < 2 :
raise Exception ( " parseTeleporter() : Un téléporteur est mal configuré " )
if len ( i [ " properties " ] ) == 2 :
print ( " parseTeleporter() : passage automatique idMap = -1 sur téléporteur x = " + str ( i [ " properties " ] [ 0 ] [ " value " ] ) + " , y = " + str ( i [ " properties " ] [ 1 ] [ " value " ] ) )
2022-04-18 02:14:07 +02:00
teleporter + = fxconv . u32 ( - 1 )
2022-01-18 23:43:48 +01:00
for j in i [ " properties " ] :
teleporter + = fxconv . u32 ( j [ " value " ] )
except KeyError :
raise Exception ( " parseTeleporter() : Un téléporteur est mal configuré " )
2022-01-24 15:15:12 +01:00
return teleporter
2022-05-22 16:46:31 +02:00
def parseZone ( layer , idmap ) :
2022-02-17 00:02:00 +01:00
zone = fxconv . Structure ( )
2022-05-22 16:46:31 +02:00
idZone = 0
2022-02-17 00:02:00 +01:00
for i in layer [ " objects " ] :
origin = ( int ( i [ ' x ' ] / 16 ) , int ( i [ ' y ' ] / 16 ) )
to = ( int ( origin [ 0 ] + i [ ' width ' ] / 16 ) - 1 , int ( origin [ 1 ] + i [ ' height ' ] / 16 ) - 1 )
2022-05-22 16:46:31 +02:00
if len ( i [ " properties " ] [ 0 ] [ " value " ] ) != 0 :
zone + = fxconv . u32 ( int ( f " { idmap } { idZone } { idmap } " ) ) #id zone is {mapid}{idzone}{mapid}
idZone + = 1
else : zone + = fxconv . u32 ( 0 )
2022-02-17 00:02:00 +01:00
zone + = fxconv . u32 ( origin [ 0 ] )
zone + = fxconv . u32 ( origin [ 1 ] )
zone + = fxconv . u32 ( to [ 0 ] )
zone + = fxconv . u32 ( to [ 1 ] )
2022-05-11 00:37:56 +02:00
2022-05-22 16:46:31 +02:00
2022-05-11 00:37:56 +02:00
event = bytes ( i [ " properties " ] [ 0 ] [ " value " ] , " utf-8 " )
event + = bytes ( 128 - len ( event ) )
zone + = event #event
2022-02-17 00:02:00 +01:00
2022-02-19 01:21:38 +01:00
monsters = bytes ( )
2022-04-23 01:53:08 +02:00
zone + = fxconv . u32 ( int ( i [ " properties " ] [ 1 ] [ " value " ] ) if i [ " properties " ] [ 1 ] [ " value " ] != " " else - 1 ) #level
monster_list_raw = [ ]
if i [ " properties " ] [ 2 ] [ " value " ] != " " : monster_list_raw = i [ " properties " ] [ 2 ] [ " value " ] . split ( " ; " ) #monster list
monster_list = [ ]
#x-y notation generate an array
for i in monster_list_raw :
if " - " in i :
a = i . split ( " - " )
monster_list . extend ( list ( range ( int ( a [ 0 ] ) , int ( a [ 1 ] ) + 1 ) ) )
else :
monster_list . append ( int ( i ) )
zone + = fxconv . u32 ( len ( monster_list ) )
for j in monster_list :
monsters + = fxconv . u16 ( int ( j ) )
2022-02-19 01:21:38 +01:00
zone + = fxconv . ptr ( monsters )
2022-02-17 00:02:00 +01:00
return zone
2022-01-24 15:15:12 +01:00
def convert_capa ( input , output , params , target ) :
2022-02-17 21:26:33 +01:00
liste_file = list ( pathlib . Path ( input ) . parent . glob ( ' *.json ' ) )
capacities = fxconv . Structure ( )
capacities + = fxconv . u32 ( len ( liste_file ) )
for f in liste_file :
file = open ( f , " r " )
data = json . load ( file )
move = fxconv . Structure ( )
try :
2022-04-16 01:06:24 +02:00
categorie = data [ " categorie " ]
id_categorie = [ " STATUT " , " PHYSICAL " , " SPECIAL " ]
2022-02-17 21:26:33 +01:00
move + = fxconv . string ( data [ " name " ] )
2022-05-11 00:37:56 +02:00
move + = fxconv . string ( data [ " type " ] )
2022-02-17 21:26:33 +01:00
move + = fxconv . u32 ( data [ " id " ] )
2022-04-16 01:06:24 +02:00
move + = fxconv . u32 ( id_categorie . index ( categorie ) )
2022-02-17 21:26:33 +01:00
move + = fxconv . u32 ( data [ " pp " ] )
move + = fxconv . u32 ( data [ " pp " ] )
2022-02-18 15:44:41 +01:00
2022-04-16 01:06:24 +02:00
if categorie == " PHYSICAL " or categorie == " SPECIAL " :
2022-02-18 15:44:41 +01:00
move + = fxconv . u32 ( data [ " atk " ] )
move + = fxconv . u32 ( data [ " precision " ] )
move + = fxconv . u32 ( 0 ) + fxconv . u32 ( 0 ) + fxconv . u32 ( 0 )
elif categorie == " STATUT " :
move + = fxconv . u32 ( 0 ) + fxconv . u32 ( 100 )
move + = fxconv . u32 ( data [ " boost_atk " ] )
move + = fxconv . u32 ( data [ " boost_def " ] )
move + = fxconv . u32 ( data [ " boost_hp " ] )
2022-02-17 21:26:33 +01:00
except KeyError :
raise Exception ( f " convert_capa() : La capacité { data [ ' name ' ] } est mal configurée " )
capacities + = fxconv . ptr ( move )
2022-01-24 15:15:12 +01:00
fxconv . elf ( capacities , output , " _ " + params [ " name " ] , * * target )
2022-02-10 15:20:42 +01:00
def convert_monster ( input , output , params , target ) :
2022-02-19 01:21:38 +01:00
liste_file = list ( pathlib . Path ( input ) . parent . glob ( ' *.json ' ) )
monsters = fxconv . Structure ( )
monsters + = fxconv . u32 ( len ( liste_file ) )
for f in liste_file :
file = open ( f , " r " )
data = json . load ( file )
stats = fxconv . Structure ( )
2022-04-16 01:06:24 +02:00
if len ( data [ " stats " ] ) != 6 : raise Exception ( f " convert_monster : Les statistiques de { data [ ' name ' ] } sont mauvaises " )
2022-05-11 00:37:56 +02:00
stats + = fxconv . string ( data [ " type " ] )
2022-02-19 01:21:38 +01:00
stats + = fxconv . u32 ( data [ " stats " ] [ " atk " ] )
stats + = fxconv . u32 ( data [ " stats " ] [ " def " ] )
stats + = fxconv . u32 ( data [ " stats " ] [ " pv " ] )
2022-04-16 01:06:24 +02:00
stats + = fxconv . u32 ( data [ " stats " ] [ " spe_atk " ] )
stats + = fxconv . u32 ( data [ " stats " ] [ " spe_def " ] )
stats + = fxconv . u32 ( 1 ) # level, will be calculated later
2022-02-19 01:21:38 +01:00
stats + = fxconv . u32 ( data [ " stats " ] [ " xp " ] )
stats + = fxconv . u32 ( data [ " stats " ] [ " pv " ] )
moves = bytes ( )
for i in data [ " moves " ] :
moves + = fxconv . u16 ( i )
monster = fxconv . Structure ( )
monster + = fxconv . string ( data [ " name " ] )
monster + = fxconv . ptr ( f " img_ { data [ ' sprite ' ] } " )
monster + = fxconv . u32 ( data [ " id " ] )
monster + = fxconv . u32 ( len ( data [ " moves " ] ) )
monster + = fxconv . ptr ( stats )
monster + = fxconv . ptr ( moves )
monsters + = fxconv . ptr ( monster )
fxconv . elf ( monsters , output , " _ " + params [ " name " ] , * * target )
2022-03-23 01:16:24 +01:00
def convert_player_moves ( input , output , params , target ) :
levelupplayer = fxconv . Structure ( )
data = open ( input , ' r ' ) . readlines ( )
levelupplayer + = fxconv . u32 ( len ( data ) )
for i in data :
levelup = fxconv . Structure ( )
levelup + = fxconv . u32 ( int ( i . split ( " : " ) [ 0 ] ) )
levelup + = fxconv . u32 ( int ( i . split ( " : " ) [ 1 ] ) )
levelupplayer + = fxconv . ptr ( levelup )
2022-04-16 02:21:07 +02:00
fxconv . elf ( levelupplayer , output , " _ " + params [ " name " ] , * * target )
def convert_items ( input , output , params , target ) :
liste_file = list ( pathlib . Path ( input ) . parent . glob ( ' *.json ' ) )
items = fxconv . Structure ( )
items + = fxconv . u32 ( len ( liste_file ) )
for f in liste_file :
file = open ( f , " r " )
data = json . load ( file )
item = fxconv . Structure ( )
2022-04-18 02:14:07 +02:00
try :
item + = fxconv . string ( data [ " name " ] )
item + = fxconv . u32 ( data [ " id " ] )
item + = fxconv . string ( data [ " description " ] )
item + = fxconv . ptr ( f " img_ { data [ ' sprite ' ] } " )
2022-04-22 00:32:31 +02:00
item + = fxconv . string ( " ; " . join ( data [ " action " ] ) )
2022-04-18 02:14:07 +02:00
items + = fxconv . ptr ( item )
except KeyError :
raise Exception ( f " convert_items() : L ' item { data [ ' name ' ] } est mal configuré " )
2022-04-16 02:21:07 +02:00
2022-05-03 00:40:09 +02:00
fxconv . elf ( items , output , " _ " + params [ " name " ] , * * target )
def convert_table_type ( input , output , params , target ) :
data = csv . DictReader ( open ( input , ' r ' ) )
table_type = fxconv . Structure ( )
for i in data :
type = fxconv . Structure ( )
type + = fxconv . string ( i [ " type " ] )
type + = fxconv . u32 ( list ( i ) . index ( i [ " type " ] ) )
2022-05-16 23:57:25 +02:00
taille = len ( i ) - 1 #-1 because of the "color" column
2022-05-03 00:40:09 +02:00
b , l , n = [ ] , [ ] , [ ]
for j in i :
id = list ( i ) . index ( j )
if ( i [ j ] == " 2 " ) : b . append ( id )
if ( i [ j ] == " 0,5 " ) : l . append ( id )
if ( i [ j ] == " 0 " ) : n . append ( id )
2022-05-16 23:57:25 +02:00
if ( j == " Couleur " ) : color = i [ j ]
2022-05-03 00:40:09 +02:00
for a in range ( len ( b ) , taille ) : b . append ( 0 )
for a in range ( len ( l ) , taille ) : l . append ( 0 )
for a in range ( len ( n ) , taille ) : n . append ( 0 )
2022-05-16 23:57:25 +02:00
if ( color == None ) :
raise Exception ( f " Pas de couleur pour le type: { i [ ' type ' ] } " )
if ( len ( color . strip ( ) ) != 5 ) :
raise Exception ( f " Mauvaise couleur pour le type { i [ ' type ' ] } : { color } " )
color = int ( color . strip ( ) [ 1 : ] , 16 )
2022-05-03 00:40:09 +02:00
type + = b " " . join ( fxconv . u32 ( value ) for value in b )
type + = b " " . join ( fxconv . u32 ( value ) for value in l )
type + = b " " . join ( fxconv . u32 ( value ) for value in n )
2022-05-16 23:57:25 +02:00
type + = fxconv . u16 ( color )
2022-05-03 00:40:09 +02:00
table_type + = fxconv . ptr ( type )
fxconv . elf ( table_type , output , " _ " + params [ " name " ] , * * target )