From 70d8c433504e3308dd2054d7a324169f720918d6 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Mon, 30 Sep 2024 20:22:41 +0200
Subject: [PATCH] #169 : Fixed command for tile bleeding

---
 src/commands/extrudeTiles.ts | 136 -----------------------------------
 src/commands/tiles.ts        |  44 ++++++++++++
 2 files changed, 44 insertions(+), 136 deletions(-)
 delete mode 100644 src/commands/extrudeTiles.ts
 create mode 100644 src/commands/tiles.ts

diff --git a/src/commands/extrudeTiles.ts b/src/commands/extrudeTiles.ts
deleted file mode 100644
index 6739934..0000000
--- a/src/commands/extrudeTiles.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import { Server } from 'socket.io'
-import ZoneManager from '../managers/zoneManager'
-import sharp from 'sharp'
-import path from 'path'
-import fs from 'fs'
-import { commandLogger } from '../utilities/logger'
-
-type CommandInput = string[]
-
-/**
- * Extrude tiles command
- * This command will get all the tiles inside process.cwd() > public > tiles
- * And overwrite the existing tiles.
- * @param input
- * @param io
- */
-export default async function extrudeTiles(input: CommandInput, io: Server) {
-  const [tileWidth, tileHeight, extrusion = '1', color = '0xffffff00'] = input
-
-  if (!tileWidth || !tileHeight) {
-    console.log('Missing tileWidth or tileHeight! Usage: extrudeTiles <tileWidth> <tileHeight> [extrusion] [color]')
-    return
-  }
-
-  const options = {
-    tileWidth: parseInt(tileWidth),
-    tileHeight: parseInt(tileHeight),
-    extrusion: parseInt(extrusion),
-    color: parseInt(color, 16)
-  }
-
-  const tilesDir = path.join(process.cwd(), 'public', 'tiles')
-  const files = fs.readdirSync(tilesDir).filter(file => file.endsWith('.png'))
-
-  for (const file of files) {
-    const inputPath = path.join(tilesDir, file)
-    const outputPath = path.join(tilesDir, `${path.parse(file).name}.png`)
-
-    try {
-      await extrudeTile(
-        options.tileWidth,
-        options.tileHeight,
-        inputPath,
-        outputPath,
-        options.extrusion,
-        options.color
-      )
-      commandLogger.info(`Extruded tile ${file}`)
-    } catch (error: any) {
-      console.log(error)
-      commandLogger.error('Error extruding tile:', error.message)
-    }
-  }
-}
-
-async function extrudeTile(
-  tileWidth: number,
-  tileHeight: number,
-  inputPath: string,
-  outputPath: string,
-  extrusion: number,
-  backgroundColor: number
-) {
-  const borderWidth = 4; // You can adjust this value to change the border width
-
-  const image = sharp(inputPath)
-  const metadata = await image.metadata()
-
-  if (!metadata.width || !metadata.height) {
-    throw new Error('Unable to get image dimensions')
-  }
-
-  const tilesX = Math.floor(metadata.width / tileWidth)
-  const tilesY = Math.floor(metadata.height / tileHeight)
-
-  // Use borderWidth in the new dimensions calculation
-  const newWidth = metadata.width + (tilesX + 1) * extrusion + tilesX * borderWidth * 2
-  const newHeight = metadata.height + (tilesY + 1) * extrusion + tilesY * borderWidth * 2
-
-  const background = {
-    r: (backgroundColor >> 24) & 0xff,
-    g: (backgroundColor >> 16) & 0xff,
-    b: (backgroundColor >> 8) & 0xff,
-    alpha: backgroundColor & 0xff
-  }
-
-  const newImage = sharp({
-    create: {
-      width: newWidth,
-      height: newHeight,
-      channels: 4,
-      background
-    }
-  })
-
-  const compositeOperations = []
-
-  for (let y = 0; y < tilesY; y++) {
-    for (let x = 0; x < tilesX; x++) {
-      const tileBuffer = await image
-        .extract({
-          left: x * tileWidth,
-          top: y * tileHeight,
-          width: tileWidth,
-          height: tileHeight
-        })
-        .extend({
-          top: borderWidth,
-          bottom: borderWidth,
-          left: borderWidth,
-          right: borderWidth,
-          background: { r: 0, g: 0, b: 0, alpha: 0 }
-        })
-        .raw()
-        .toBuffer()
-
-      compositeOperations.push({
-        input: tileBuffer,
-        // Use borderWidth in positioning calculation
-        left: x * (tileWidth + extrusion + borderWidth * 2),
-        top: y * (tileHeight + extrusion + borderWidth * 2),
-        raw: {
-          width: tileWidth + borderWidth * 2,
-          height: tileHeight + borderWidth * 2,
-          channels: 4
-        }
-      })
-    }
-  }
-
-  await newImage
-    // @ts-ignore
-    .composite(compositeOperations)
-    .png()
-    .toFile(outputPath)
-}
\ No newline at end of file
diff --git a/src/commands/tiles.ts b/src/commands/tiles.ts
new file mode 100644
index 0000000..feb317a
--- /dev/null
+++ b/src/commands/tiles.ts
@@ -0,0 +1,44 @@
+import path from 'path'
+import fs from 'fs'
+import sharp from 'sharp'
+import { commandLogger } from '../utilities/logger'
+
+export default async function tiles() {
+  // Get all tiles
+  const tilesDir = path.join(process.cwd(), 'public', 'tiles');
+  const tiles = fs.readdirSync(tilesDir).filter((file) => file.endsWith('.png'));
+
+  // Create output directory if it doesn't exist
+  if (!fs.existsSync(tilesDir)) {
+    fs.mkdirSync(tilesDir, { recursive: true });
+  }
+
+  for (const tile of tiles) {
+    // Check if tile is already 66x34
+    const metadata = await sharp(path.join(tilesDir, tile)).metadata();
+    if (metadata.width === 66 && metadata.height === 34) {
+      commandLogger.info(`Tile ${tile} already processed`);
+      continue;
+    }
+
+    const inputPath = path.join(tilesDir, tile);
+    const outputPath = path.join(tilesDir, tile);
+
+    try {
+      await sharp(inputPath)
+        .resize({
+          width: 66,
+          height: 34,
+          fit: 'fill',
+          kernel: 'nearest'
+        })
+        .toFile(outputPath);
+
+      commandLogger.info(`Processed: ${tile}`);
+    } catch (error) {
+      console.error(`Error processing ${tile}:`, error);
+    }
+  }
+
+  commandLogger.info('Tile processing completed.');
+}
\ No newline at end of file