mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-30 17:22:22 +00:00
preprocess map into binary data
This commit is contained in:
@@ -1,13 +1,7 @@
|
||||
import {Jimp as JimpType, JimpConstructors} from '@jimp/core';
|
||||
import 'jimp';
|
||||
import {TerrainTile} from '../../generated/protos';
|
||||
import {Cell} from './Game';
|
||||
|
||||
declare const Jimp: JimpType & JimpConstructors;
|
||||
|
||||
import binAsString from "!!binary-loader!../../resources/WorldSmall.bin";
|
||||
|
||||
export class TerrainMap {
|
||||
|
||||
constructor(public readonly tiles: Terrain[][]) { }
|
||||
|
||||
terrain(cell: Cell): Terrain {
|
||||
@@ -30,64 +24,56 @@ export enum TerrainType {
|
||||
|
||||
export class Terrain {
|
||||
public shoreline: boolean = false
|
||||
public magnitude: number = 0
|
||||
constructor(public type: TerrainType) { }
|
||||
}
|
||||
|
||||
export async function loadTerrainMap(): Promise<TerrainMap> {
|
||||
const imageModule = await import(`../../resources/maps/World.png`);
|
||||
const imageUrl = imageModule.default;
|
||||
const image = await Jimp.read(imageUrl)
|
||||
const {width, height} = image.bitmap;
|
||||
export function loadTerrainMap(): TerrainMap {
|
||||
const fileData = binAsString;
|
||||
|
||||
console.log(`Loaded data length: ${fileData.length} bytes`);
|
||||
|
||||
// Extract width and height from the first 4 bytes
|
||||
const width = (fileData.charCodeAt(1) << 8) | fileData.charCodeAt(0);
|
||||
const height = (fileData.charCodeAt(3) << 8) | fileData.charCodeAt(2);
|
||||
|
||||
console.log(`Decoded dimensions: ${width}x${height}`);
|
||||
|
||||
// Log the first 100 bytes of data (including the width and height bytes)
|
||||
logBinaryAsAscii(fileData, 100);
|
||||
|
||||
// Check if the data length matches the expected size
|
||||
if (fileData.length != width * height + 4) { // +4 for the width and height bytes
|
||||
throw new Error(`Invalid data: buffer size ${fileData.length} incorrect for ${width}x${height} terrain plus 4 bytes for dimensions.`);
|
||||
}
|
||||
|
||||
const terrain: Terrain[][] = Array(width).fill(null).map(() => Array(height).fill(null));
|
||||
|
||||
image.scan(0, 0, width, height, function (x: number, y: number, idx: number) {
|
||||
const t: TerrainTile = new TerrainTile()
|
||||
const red = this.bitmap.data[idx + 0];
|
||||
// Start from the 5th byte (index 4) when processing terrain data
|
||||
for (let x = 0; x < width; x++) {
|
||||
for (let y = 0; y < height; y++) {
|
||||
const packedByte = fileData.charCodeAt(4 + y * width + x); // +4 to skip dimension bytes
|
||||
const type = (packedByte & 0b10000000) ? TerrainType.Land : TerrainType.Water;
|
||||
const shoreline = !!(packedByte & 0b01000000);
|
||||
const magnitude = packedByte & 0b00111111;
|
||||
|
||||
if (red > 100) {
|
||||
terrain[x][y] = new Terrain(TerrainType.Land)
|
||||
} else {
|
||||
terrain[x][y] = new Terrain(TerrainType.Water);
|
||||
terrain[x][y] = new Terrain(type);
|
||||
terrain[x][y].shoreline = shoreline;
|
||||
terrain[x][y].magnitude = magnitude;
|
||||
}
|
||||
})
|
||||
|
||||
process(terrain)
|
||||
}
|
||||
|
||||
return new TerrainMap(terrain);
|
||||
}
|
||||
|
||||
function process(map: Terrain[][]) {
|
||||
for (let x = 0; x < map.length; x++) {
|
||||
for (let y = 0; y < map[0].length; y++) {
|
||||
const terrain = map[x][y]
|
||||
const ns = neighbors(x, y, map)
|
||||
if (terrain.type == TerrainType.Land) {
|
||||
if (ns.filter(t => t.type == TerrainType.Water).length > 0) {
|
||||
terrain.shoreline = true
|
||||
}
|
||||
} else {
|
||||
if (ns.filter(t => t.type == TerrainType.Land).length > 0) {
|
||||
terrain.shoreline = true
|
||||
}
|
||||
}
|
||||
function logBinaryAsAscii(data: string, length: number = 8) {
|
||||
console.log('Binary data (1 = set bit, 0 = unset bit):');
|
||||
for (let i = 0; i < Math.min(length, data.length); i++) {
|
||||
let byte = data.charCodeAt(i);
|
||||
let byteString = '';
|
||||
for (let j = 7; j >= 0; j--) {
|
||||
byteString += (byte & (1 << j)) ? '1' : '0';
|
||||
}
|
||||
console.log(`Byte ${i}: ${byteString}`);
|
||||
}
|
||||
}
|
||||
|
||||
function neighbors(x: number, y: number, map: Terrain[][]): Terrain[] {
|
||||
const ns: Terrain[] = []
|
||||
if (x > 0) {
|
||||
ns.push(map[x - 1][y])
|
||||
}
|
||||
if (x < map.length - 1) {
|
||||
ns.push(map[x + 1][y])
|
||||
}
|
||||
if (y > 0) {
|
||||
ns.push(map[x][y - 1])
|
||||
}
|
||||
if (y < map[0].length - 1) {
|
||||
ns.push(map[x][y + 1])
|
||||
}
|
||||
return ns
|
||||
}
|
||||
Reference in New Issue
Block a user