diff --git a/src/map-parser.ts b/src/map-parser.ts index 307c707..41293a6 100644 --- a/src/map-parser.ts +++ b/src/map-parser.ts @@ -150,7 +150,11 @@ export class MapParser { let skybox: Jimp | undefined; if (this.config.parseSkybox && mapInfo?.atmosphere?.skyBox) { - skybox = await this.parseSkybox(tempArchiveDir, mapInfo.atmosphere.skyBox); + try { + skybox = await this.parseSkybox(tempArchiveDir, mapInfo.atmosphere.skyBox); + } catch (err) { + console.warn(`Error parsing skybox for "${mapInfo.atmosphere.skyBox}":`, err); + } } await this.cleanup(tempArchiveDir); @@ -362,41 +366,47 @@ export class MapParser { const dxt1Size = Math.pow(mipmapSize, 2) / 2; const rowLength = mipmapSize * 4; - const refTiles: Buffer[][] = []; - for (let i=0; i= refTiles.length) { + throw new Error(`Tile index ${refIndex} out of range (0..${refTiles.length - 1}) at position ${tileIdx}`); + } + const refTile = refTiles[refIndex]; + const tileX = tileIdx % tilesWide; + const tileY = Math.floor(tileIdx / tilesWide); + const destXByte = tileX * mipmapSize * 4; + const destYRow = tileY * mipmapSize; + + for (let row = 0; row < mipmapSize; row++) { + const srcOffset = row * rowLength; + const destOffset = (destYRow + row) * outputStride + destXByte; + refTile.copy(output, destOffset, srcOffset, srcOffset + rowLength); } - const textureStrip = this.joinTilesHorizontally(tileStrip, mipmapSize); - tileStrips.push(textureStrip); } return new Jimp({ - data: Buffer.concat(tileStrips), - width: mipmapSize * mapWidthUnits * 32, - height: mipmapSize * mapHeightUnits * 32 + data: output, + width: outputWidth, + height: outputHeight }).background(0x000000); } @@ -500,26 +510,6 @@ export class MapParser { }; } - protected cloneTile(tile: Buffer[]) : Buffer[] { - const clone: Buffer[] = []; - for (const row of tile) { - clone.push(Buffer.from(row)); - } - return clone; - } - - protected joinTilesHorizontally(tiles: Buffer[][], mipmapSize: 4 | 8 | 16 | 32) : Buffer { - const tileRows: Buffer[] = []; - for (let y=0; y= 0) { // water level is always at 0, so if minDepth is above 0 then map has no water