1
0
forked from noxious/server

#169 : Fixed command for tile bleeding

This commit is contained in:
Dennis Postma 2024-09-30 20:22:41 +02:00
parent 3a83f2c1ff
commit 70d8c43350
2 changed files with 44 additions and 136 deletions

View File

@ -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)
}

44
src/commands/tiles.ts Normal file
View File

@ -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.');
}