UNPKG

patchwork-mapconverter

Version:

Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator

246 lines 23.6 kB
"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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