Move map metadata to map manifest (#1262)

## Description:

To simply the map binary data, remove height & width data to the
manifest

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:
evan
This commit is contained in:
evanpelle
2025-06-23 14:50:18 -07:00
committed by GitHub
parent ecabdfe4bc
commit 1ce282d41b
89 changed files with 1523 additions and 1259 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ export class MapDisplay extends LitElement {
const mapValue = GameMapType[this.mapKey as keyof typeof GameMapType];
const data = terrainMapFileLoader.getMapData(mapValue);
this.mapWebpPath = await data.webpPath();
this.mapName = (await data.nationMap()).name;
this.mapName = (await data.manifest()).name;
} catch (error) {
console.error("Failed to load map data:", error);
} finally {
+1 -1
View File
@@ -55,7 +55,7 @@ export async function createGameRunner(
const nations = gameStart.config.disableNPCs
? []
: gameMap.nationMap.nations.map(
: gameMap.manifest.nations.map(
(n) =>
new Nation(
new Cell(n.coordinates[0], n.coordinates[1]),
+4 -4
View File
@@ -1,10 +1,10 @@
import { GameMapType } from "./Game";
import { NationMap } from "./TerrainMapLoader";
import { MapManifest } from "./TerrainMapLoader";
interface MapData {
mapBin: () => Promise<string>;
miniMapBin: () => Promise<string>;
nationMap: () => Promise<NationMap>;
manifest: () => Promise<MapManifest>;
webpPath: () => Promise<string>;
}
@@ -13,7 +13,7 @@ export interface BinModule {
}
interface NationMapModule {
default: NationMap;
default: MapManifest;
}
class GameMapLoader {
@@ -57,7 +57,7 @@ class GameMapLoader {
) as Promise<BinModule>
).then((m) => m.default),
),
nationMap: this.createLazyLoader(() =>
manifest: this.createLazyLoader(() =>
(
import(
`../../../resources/maps/${fileName}/manifest.json`
+35 -29
View File
@@ -3,15 +3,23 @@ import { GameMap, GameMapImpl } from "./GameMap";
import { terrainMapFileLoader } from "./TerrainMapFileLoader";
export type TerrainMapData = {
nationMap: NationMap;
manifest: MapManifest;
gameMap: GameMap;
miniGameMap: GameMap;
};
const loadedMaps = new Map<GameMapType, TerrainMapData>();
export interface NationMap {
export interface MapMetadata {
width: number;
height: number;
num_land_tiles: number;
}
export interface MapManifest {
name: string;
map: MapMetadata;
mini_map: MapMetadata;
nations: Nation[];
}
@@ -29,10 +37,17 @@ export async function loadTerrainMap(
if (cached !== undefined) return cached;
const mapFiles = terrainMapFileLoader.getMapData(map);
const gameMap = await genTerrainFromBin(await mapFiles.mapBin());
const miniGameMap = await genTerrainFromBin(await mapFiles.miniMapBin());
const manifest = await mapFiles.manifest();
const gameMap = await genTerrainFromBin(
manifest.map,
await mapFiles.mapBin(),
);
const miniGameMap = await genTerrainFromBin(
manifest.mini_map,
await mapFiles.miniMapBin(),
);
const result = {
nationMap: await mapFiles.nationMap(),
manifest: await mapFiles.manifest(),
gameMap: gameMap,
miniGameMap: miniGameMap,
};
@@ -40,38 +55,29 @@ export async function loadTerrainMap(
return result;
}
export async function genTerrainFromBin(data: string): Promise<GameMap> {
const width = (data.charCodeAt(1) << 8) | data.charCodeAt(0);
const height = (data.charCodeAt(3) << 8) | data.charCodeAt(2);
if (data.length !== width * height + 4) {
export async function genTerrainFromBin(
mapData: MapMetadata,
data: string,
): Promise<GameMap> {
if (data.length !== mapData.width * mapData.height) {
throw new Error(
`Invalid data: buffer size ${data.length} incorrect for ${width}x${height} terrain plus 4 bytes for dimensions.`,
`Invalid data: buffer size ${data.length} incorrect for ${mapData.width}x${mapData.height} terrain plus 4 bytes for dimensions.`,
);
}
// Store raw data in Uint8Array
const rawData = new Uint8Array(width * height);
let numLand = 0;
const rawData = new Uint8Array(mapData.width * mapData.height);
// Copy data starting after the header
for (let i = 0; i < width * height; i++) {
const packedByte = data.charCodeAt(i + 4);
for (let i = 0; i < mapData.width * mapData.height; i++) {
const packedByte = data.charCodeAt(i);
rawData[i] = packedByte;
if (packedByte & 0b10000000) numLand++;
}
return new GameMapImpl(width, height, rawData, numLand);
}
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++) {
const byte = data.charCodeAt(i);
let byteString = "";
for (let j = 7; j >= 0; j--) {
byteString += byte & (1 << j) ? "1" : "0";
}
console.log(`Byte ${i}: ${byteString}`);
}
return new GameMapImpl(
mapData.width,
mapData.height,
rawData,
mapData.num_land_tiles,
);
}