2D_Engine_C/assets/maps/tiled-extensions/json_export_tool.mjs

323 lines
10 KiB
JavaScript

function stringifyFloat(floatNumber)
{
if(floatNumber == Math.trunc(floatNumber))
return String(floatNumber) + ".0"
return String(floatNumber);
}
function writeLayerContent(output_file, layer)
{
for(let cell_y = 0; cell_y < layer.height; ++cell_y)
{
output_file.write(" ");
for(let cell_x = 0; cell_x < layer.width; ++cell_x)
{
output_file.file.write(" " + layer.cellAt(cell_x, cell_y).tileId)
if(cell_x < layer.width - 1 || cell_y < layer.height - 1)
output_file.file.write(",");
}
output_file.file.writeLine("");
}
}
function writeEntities(output_file, entitieslayer)
{
let entities = [];
for(let i = 0; i < entitieslayer.objectCount; i++)
{
let entity = entitieslayer.objectAt(i);
if(entity.name)
{
entities.push(entity);
}
}
entities.sort((a, b) => {
if(Number(a.name) > Number(b.name))
return 1;
return -1;
});
for(let i = 0; i < entities.length; i++)
{
let entity = entities[i];
output_file.writeLine("{");
output_file.indent_add(2);
output_file.writeLine("\"ID\":" + entity.name + ",");
output_file.writeLine("\"Components\": [");
let components = entity.properties()["components"];
let nb_components = Object.keys(components).length;
output_file.indent_add(2);
for(let j = 0; j < nb_components; j++)
{
let component = components[j];
let component_type = component[0];
output_file.writeLine("{");
output_file.indent_add(2);
output_file.write("\"Type\": \"" + component_type + "\"");
if(component.length > 1)
{
output_file.file.writeLine(",");
output_file.writeLine("\"Attributes\": [");
}
// Write atributes, speciale cases need speciale treatment.
if(component_type == "TRANSFORM_COMPONENT")
{
output_file.file.writeLine(",");
output_file.writeLine("\"Attributes\": [");
output_file.writeLine(" " + stringifyFloat(entity.x) + ",");
output_file.writeLine(" " + stringifyFloat(entity.y) + ",");
output_file.writeLine(" " + stringifyFloat(entity.width) + ",");
output_file.writeLine(" " + stringifyFloat(entity.height));
output_file.writeLine("]");
}
else if(component_type == "HITBOX_COMPONENT")
{
let hitbox;
for(let k = 0; k < entitieslayer.objectCount; k++)
{
hitbox = entitieslayer.objectAt(k);
if(hitbox.id === component[1].id)
break;
}
let x = (hitbox.x - entity.x) / entity.width;
let y = (hitbox.y - entity.y) / entity.height;
let width = hitbox.width / entity.width;
let height = hitbox.height / entity.height;
output_file.writeLine(" " + stringifyFloat(x) + ",");
output_file.writeLine(" " + stringifyFloat(y) + ",");
output_file.writeLine(" " + stringifyFloat(width) + ",");
output_file.writeLine(" " + stringifyFloat(height));
}
else if(component_type == "INTERACT_COMPONENT")
{
let interact_box;
for(let k = 0; k < entitieslayer.objectCount; k++)
{
interact_box = entitieslayer.objectAt(k);
if(interact_box.id === component[1].id)
break;
}
let x = (interact_box.x - entity.x) / entity.width;
let y = (interact_box.y - entity.y) / entity.height;
let width = interact_box.width / entity.width;
let height = interact_box.height / entity.height;
output_file.writeLine(" " + stringifyFloat(x) + ",");
output_file.writeLine(" " + stringifyFloat(y) + ",");
output_file.writeLine(" " + stringifyFloat(width) + ",");
output_file.writeLine(" " + stringifyFloat(height) + ",");
output_file.writeLine(" " + component[2] + ",");
output_file.writeLine(" " + component[3] + ",");
output_file.writeLine(" " + component[4]);
}
else if(component_type == "SPRITE_COMPONENT")
{
output_file.writeLine(" \"" + component[1] + "\"");
}
else if(component_type == "ANIMATION_SYSTEM")
{
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2] + ",");
output_file.writeLine(" " + stringifyFloat(component[3]) + ",");
output_file.writeLine(" " + component[4] + ",");
output_file.writeLine(" " + component[5] + ",");
output_file.writeLine(" " + component[6]);
}
else if(component_type == "LEVER_COMPONENT")
{
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2]);
}
else if(component_type == "DOOR_COMPONENT")
{
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2]);
}
else
{
throw new Error("Component type not supported for exporting : " + component_type);
}
if(component.length > 1)
output_file.writeLine("]");
output_file.indent_remove(2);
if(j == nb_components - 1)
output_file.writeLine("}");
else
output_file.writeLine("},");
}
output_file.indent_remove(2);
output_file.writeLine("]");
output_file.indent_remove(2);
if(i == entities.length - 1)
output_file.writeLine("}");
else
output_file.writeLine("},");
}
}
var customMapFormat = {
name: "Custom MAP format",
extension: "map",
write: function(map, fileName)
{
let output_file = {
file: new TextFile(fileName, TextFile.WriteOnly),
indent: "",
indent_add: function(nb)
{
this.indent += " ".repeat(nb);
},
indent_remove: function(nb)
{
this.indent = this.indent.substring(0, this.indent.length - nb);
},
write: function(content)
{
this.file.write(this.indent);
this.file.write(content);
},
writeLine: function(content)
{
this.file.write(this.indent);
this.file.writeLine(content);
},
commit: function()
{
this.file.commit();
}
};
output_file.file.writeLine("{");
output_file.indent_add(2);
output_file.writeLine("\"MapWidth\": " + map.width + ",");
output_file.writeLine("\"MapHeight\": " + map.height + ",");
output_file.file.writeLine("");
let backgroundlayers = [];
let foregroundlayer = null;
let hitboxes = null;
let entitieslayer = null;
for(let i = 0; i < map.layerCount; i++)
{
let layer = map.layerAt(i);
if(layer.isTileLayer)
{
if(layer.name.startsWith("Background"))
{
backgroundlayers.push(layer);
}
else if(layer.name.startsWith("Foreground"))
{
foregroundlayer = layer;
}
else if(layer.name == "Hitboxes")
{
hitboxes = layer;
}
else
{
throw new Error("Invalid layer name for a tile layer : " + layer.name);
}
}
else if(layer.isObjectLayer)
{
if(layer.name == "Entities")
{
if(entitieslayer)
throw new Error("There cannot be multiple entity layers.");
entitieslayer = layer;
}
else
{
throw new Error("Invalid layer name for an object layer : " + layer.name);
}
}
}
if(backgroundlayers.length == 0)
{
throw new Error("At least one background layer is needed.");
}
if(foregroundlayer == null)
{
throw new Error("A foreground layer is needed.");
}
backgroundlayers.sort((a, b) => {
if(Number(a.name[a.name.length - 1]) > Number(b.name[b.name.length - 1]))
return 1;
return -1;
});
output_file.writeLine("\"BackgroundLayers\": [");
output_file.indent_add(2);
for(let i = 0; i < backgroundlayers.length; i++)
{
const layer = backgroundlayers[i];
output_file.writeLine("[");
writeLayerContent(output_file, layer);
if(i == backgroundlayers.length - 1)
output_file.writeLine("]");
else
output_file.writeLine("],");
};
output_file.indent_remove(2);
output_file.writeLine("],");
output_file.writeLine("\"ForegroundLayer\": [");
writeLayerContent(output_file, foregroundlayer);
output_file.writeLine("],");
output_file.writeLine("\"Entities\": [");
output_file.indent_add(2);
if(entitieslayer)
writeEntities(output_file, entitieslayer);
output_file.indent_remove(2);
output_file.writeLine("]");
output_file.indent_remove(2);
output_file.write("}");
output_file.commit();
}
}
tiled.registerMapFormat("custom", customMapFormat)