patchwork-mapconverter
Version:
Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator
246 lines • 23.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerrainTranslator = void 0;
const HexBuffer_1 = require("../HexBuffer");
const W3Buffer_1 = require("../W3Buffer");
function splitLargeArrayIntoWidthArrays(array, width) {
const rows = [];
for (let i = 0; i < array.length / width; i++) {
rows.push(array.slice(i * width, (i + 1) * width));
}
return rows;
}
class TerrainTranslator {
constructor() { }
static getInstance() {
if (!this.instance) {
this.instance = new this();
}
return this.instance;
}
static jsonToWar(terrain) {
return this.getInstance().jsonToWar(terrain);
}
static warToJson(buffer) {
return this.getInstance().warToJson(buffer);
}
jsonToWar(terrainJson) {
const outBufferToWar = new HexBuffer_1.HexBuffer();
/*
* Header
*/
outBufferToWar.addChars('W3E!'); // file id
outBufferToWar.addInt(12); // file version
outBufferToWar.addChar(terrainJson.tileset); // base tileset
outBufferToWar.addInt(+terrainJson.customTileset); // 1 = using custom tileset, 0 = not
/*
* Tiles
*/
outBufferToWar.addInt(terrainJson.tilePalette?.length || 0);
terrainJson.tilePalette?.forEach((tile) => {
outBufferToWar.addChars(tile);
});
/*
* Cliffs
*/
outBufferToWar.addInt(terrainJson.cliffTilePalette?.length || 0);
terrainJson.cliffTilePalette?.forEach((cliffTile) => {
outBufferToWar.addChars(cliffTile);
});
/*
* Map size data
*/
outBufferToWar.addInt(terrainJson.map.width + 1);
outBufferToWar.addInt(terrainJson.map.height + 1);
/*
* Map offset
*/
outBufferToWar.addFloat(terrainJson.map.offset.x);
outBufferToWar.addFloat(terrainJson.map.offset.y);
/*
* Tile points
*/
// Partition the terrainJson masks into "chunks" (i.e. rows) of (width+1) length,
// reverse that list of rows (due to vertical flipping), and then write the rows out
const rows = {
groundHeight: splitLargeArrayIntoWidthArrays(terrainJson.groundHeight, terrainJson.map.width + 1),
waterHeight: splitLargeArrayIntoWidthArrays(terrainJson.waterHeight, terrainJson.map.width + 1),
boundaryFlag: splitLargeArrayIntoWidthArrays(terrainJson.boundaryFlag, terrainJson.map.width + 1),
flags: splitLargeArrayIntoWidthArrays(terrainJson.flags, terrainJson.map.width + 1),
groundTexture: splitLargeArrayIntoWidthArrays(terrainJson.groundTexture, terrainJson.map.width + 1),
groundVariation: splitLargeArrayIntoWidthArrays(terrainJson.groundVariation, terrainJson.map.width + 1),
cliffVariation: splitLargeArrayIntoWidthArrays(terrainJson.cliffVariation, terrainJson.map.width + 1),
cliffTexture: splitLargeArrayIntoWidthArrays(terrainJson.cliffTexture, terrainJson.map.width + 1),
layerHeight: splitLargeArrayIntoWidthArrays(terrainJson.layerHeight, terrainJson.map.width + 1),
tileset: '',
customTileset: false,
tilePalette: [],
cliffTilePalette: [],
};
rows.groundHeight.reverse();
rows.waterHeight.reverse();
rows.boundaryFlag.reverse();
rows.flags.reverse();
rows.groundTexture.reverse();
rows.groundVariation.reverse();
rows.cliffVariation.reverse();
rows.cliffTexture.reverse();
rows.layerHeight.reverse();
for (let i = 0; i < rows.groundHeight.length; i++) {
for (let j = 0; j < rows.groundHeight[i].length; j++) {
// these bit operations are based off documentation from https://github.com/stijnherfst/HiveWE/wiki/war3map.w3e-Terrain
const groundHeight = rows.groundHeight[i][j];
const waterHeight = rows.waterHeight[i][j];
const boundaryFlag = rows.boundaryFlag[i][j];
const flags = rows.flags[i][j];
const groundTexture = rows.groundTexture[i][j];
const groundVariation = rows.groundVariation[i][j];
const cliffVariation = rows.cliffVariation[i][j];
const cliffTexture = rows.cliffTexture[i][j];
const layerHeight = rows.layerHeight[i][j];
const hasBoundaryFlag = boundaryFlag ? 0x4000 : 0;
outBufferToWar.addShort(groundHeight);
outBufferToWar.addShort(waterHeight | hasBoundaryFlag);
outBufferToWar.addShort((flags << 2) | groundTexture);
outBufferToWar.addByte(groundVariation | cliffVariation);
outBufferToWar.addByte(cliffTexture | layerHeight);
}
}
return {
errors: [],
buffer: outBufferToWar.getBuffer()
};
}
warToJson(buffer) {
// create buffer
const result = {
tileset: '',
customTileset: false,
tilePalette: [],
cliffTilePalette: [],
map: {
width: 1,
height: 1,
offset: {
x: 0,
y: 0
}
},
groundHeight: [],
waterHeight: [],
boundaryFlag: [],
flags: [],
groundTexture: [],
groundVariation: [],
cliffVariation: [],
cliffTexture: [],
layerHeight: []
};
const outBufferToJSON = new W3Buffer_1.W3Buffer(buffer);
/**
* Header
*/
const w3eHeader = outBufferToJSON.readChars(4); // W3E!
const version = outBufferToJSON.readInt(); // 0C 00 00 00
const tileset = outBufferToJSON.readChars(1); // tileset
const customTileset = (outBufferToJSON.readInt() === 1);
result.tileset = tileset;
result.customTileset = customTileset;
/**
* Tiles
*/
const numTilePalettes = outBufferToJSON.readInt();
const tilePalettes = [];
for (let i = 0; i < numTilePalettes; i++) {
tilePalettes.push(outBufferToJSON.readChars(4));
}
result.tilePalette = tilePalettes;
/**
* Cliffs
*/
const numCliffTilePalettes = outBufferToJSON.readInt();
const cliffPalettes = [];
for (let i = 0; i < numCliffTilePalettes; i++) {
const cliffPalette = outBufferToJSON.readChars(4);
cliffPalettes.push(cliffPalette);
}
result.cliffTilePalette = cliffPalettes;
/**
* map dimensions
*/
const width = outBufferToJSON.readInt() - 1;
const height = outBufferToJSON.readInt() - 1;
result.map = { width, height, offset: { x: 0, y: 0 } };
const offsetX = outBufferToJSON.readFloat();
const offsetY = outBufferToJSON.readFloat();
result.map.offset = { x: offsetX, y: offsetY };
/**
* map tiles
*/
const arrGroundHeight = [];
const arrWaterHeight = [];
const arrBoundaryFlag = [];
const arrFlags = [];
const arrGroundTexture = [];
const arrGroundVariation = [];
const arrCliffVariation = [];
const arrCliffTexture = [];
const arrLayerHeight = [];
while (!outBufferToJSON.isExhausted()) {
const groundHeight = outBufferToJSON.readShort();
const waterHeightAndBoundary = outBufferToJSON.readShort();
const waterHeight = waterHeightAndBoundary & 32767;
const boundaryFlag = (waterHeightAndBoundary & 0x4000) === 0x4000;
let flags;
let groundTexture;
if (version >= 12) {
const flagsAndGroundTexture = outBufferToJSON.readShort();
flags = (flagsAndGroundTexture & 0xFFC0) >> 2;
groundTexture = flagsAndGroundTexture & 0x3F;
}
else {
const flagsAndGroundTexture = outBufferToJSON.readByte();
flags = flagsAndGroundTexture & 0xF0;
groundTexture = flagsAndGroundTexture & 0x0F;
}
const groundAndCliffVariation = outBufferToJSON.readByte();
const cliffTextureAndLayerHeight = outBufferToJSON.readByte();
const groundVariation = groundAndCliffVariation & 0xF8;
const cliffVariation = groundAndCliffVariation & 0x07;
const cliffTexture = cliffTextureAndLayerHeight & 0XF0;
const layerHeight = cliffTextureAndLayerHeight & 0x0F;
arrGroundHeight.push(groundHeight);
arrWaterHeight.push(waterHeight);
arrBoundaryFlag.push(boundaryFlag);
arrFlags.push(flags); //TODO: properly parse flags
arrGroundTexture.push(groundTexture);
arrGroundVariation.push(groundVariation);
arrCliffVariation.push(cliffVariation);
arrCliffTexture.push(cliffTexture);
arrLayerHeight.push(layerHeight);
}
function convertArrayOfArraysIntoFlatArray(arr) {
return arr.reduce((a, b) => {
return [...a, ...b];
});
}
// The map was read in "backwards" because wc3 maps have origin (0,0)
// at the bottom left instead of top left as we desire. Flip the rows
// vertically to fix this.
result.groundHeight = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrGroundHeight, result.map.width + 1).reverse());
result.waterHeight = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrWaterHeight, result.map.width + 1).reverse());
result.boundaryFlag = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrBoundaryFlag, result.map.width + 1).reverse());
result.flags = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrFlags, result.map.width + 1).reverse());
result.groundTexture = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrGroundTexture, result.map.width + 1).reverse());
result.groundVariation = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrGroundVariation, result.map.width + 1).reverse());
result.cliffVariation = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrCliffVariation, result.map.width + 1).reverse());
result.cliffTexture = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrCliffTexture, result.map.width + 1).reverse());
result.layerHeight = convertArrayOfArraysIntoFlatArray(splitLargeArrayIntoWidthArrays(arrLayerHeight, result.map.width + 1).reverse());
return {
errors: [],
json: result
};
}
}
exports.TerrainTranslator = TerrainTranslator;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGVycmFpblRyYW5zbGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvd2MzbWFwdHJhbnNsYXRvci90cmFuc2xhdG9ycy9UZXJyYWluVHJhbnNsYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0Q0FBeUM7QUFDekMsMENBQXVDO0FBS3ZDLFNBQVMsOEJBQThCLENBQUMsS0FBZ0IsRUFBRSxLQUFhO0lBQ25FLE1BQU0sSUFBSSxHQUFnQixFQUFFLENBQUM7SUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7S0FDdEQ7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBRUQsTUFBYSxpQkFBaUI7SUFJMUIsZ0JBQXVCLENBQUM7SUFFakIsTUFBTSxDQUFDLFdBQVc7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1NBQzlCO1FBQ0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFFTSxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQWdCO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRU0sTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFjO1FBQ2xDLE9BQU8sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRU0sU0FB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