Initial import
This commit is contained in:
commit
ab891a315c
773 changed files with 257255 additions and 0 deletions
159
src/worldChunking.ts
Normal file
159
src/worldChunking.ts
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import type { JsonObject } from "./editorCore";
|
||||
|
||||
export const WORLD_INDEX_SCHEMA_VERSION = 1;
|
||||
export const WORLD_SCHEMA_VERSION = 1;
|
||||
export const WORLD_CHUNK_SCHEMA_VERSION = 1;
|
||||
export const WORLD_BOOKMARKS_SCHEMA_VERSION = 1;
|
||||
export const DEFAULT_WORLD_CHUNK_SIZE = 32;
|
||||
export const DEFAULT_WORLD_TILE_SIZE = 32;
|
||||
|
||||
export type WorldIndexEntry = {
|
||||
id: string;
|
||||
name: string;
|
||||
worldDir: string;
|
||||
};
|
||||
|
||||
export type WorldIndexPayload = {
|
||||
schemaVersion: number;
|
||||
worlds: WorldIndexEntry[];
|
||||
};
|
||||
|
||||
export type WorldBookmark = {
|
||||
id: string;
|
||||
label: string;
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
|
||||
export type WorldBookmarksPayload = {
|
||||
schemaVersion: number;
|
||||
worldId: string;
|
||||
bookmarks: WorldBookmark[];
|
||||
};
|
||||
|
||||
export type WorldDefinition = {
|
||||
schemaVersion: number;
|
||||
id: string;
|
||||
name: string;
|
||||
chunkWidth: number;
|
||||
chunkHeight: number;
|
||||
tileSize: number;
|
||||
defaultBackgroundTileId: string;
|
||||
spawn: { x: number; y: number };
|
||||
editor?: {
|
||||
defaultZoom?: number;
|
||||
gridVisible?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type WorldChunkLayer = {
|
||||
layer: number;
|
||||
name?: string;
|
||||
rows: string[];
|
||||
instanceIds: string[];
|
||||
};
|
||||
|
||||
export type WorldHeightPatch = {
|
||||
id: string;
|
||||
name?: string;
|
||||
z: number;
|
||||
x: number;
|
||||
y: number;
|
||||
rows: string[];
|
||||
};
|
||||
|
||||
export type WorldChunkInstance = {
|
||||
id: string;
|
||||
templateId?: string;
|
||||
layer: number;
|
||||
x: number;
|
||||
y: number;
|
||||
record: JsonObject;
|
||||
};
|
||||
|
||||
export type WorldChunk = {
|
||||
schemaVersion: number;
|
||||
worldId: string;
|
||||
chunkX: number;
|
||||
chunkY: number;
|
||||
width: number;
|
||||
height: number;
|
||||
backgroundTileId: string;
|
||||
roomLayers: WorldChunkLayer[];
|
||||
heightLayers: WorldHeightPatch[];
|
||||
instances: WorldChunkInstance[];
|
||||
};
|
||||
|
||||
export function normalizeChunkDimension(value: unknown, fallback = DEFAULT_WORLD_CHUNK_SIZE): number {
|
||||
return Math.max(1, Math.floor(Number(value) || fallback));
|
||||
}
|
||||
|
||||
export function buildChunkKey(chunkX: number, chunkY: number): string {
|
||||
return `${Math.floor(chunkX)}:${Math.floor(chunkY)}`;
|
||||
}
|
||||
|
||||
export function buildChunkFileName(chunkX: number, chunkY: number): string {
|
||||
return `${Math.floor(chunkX)}_${Math.floor(chunkY)}.json`;
|
||||
}
|
||||
|
||||
export function worldToChunkCoord(worldCoord: number, chunkSize: number): number {
|
||||
const safeChunkSize = Math.max(1, Math.floor(Number(chunkSize) || DEFAULT_WORLD_CHUNK_SIZE));
|
||||
return Math.floor(Number(worldCoord) / safeChunkSize);
|
||||
}
|
||||
|
||||
export function worldToLocalCoord(worldCoord: number, chunkSize: number): number {
|
||||
const safeChunkSize = Math.max(1, Math.floor(Number(chunkSize) || DEFAULT_WORLD_CHUNK_SIZE));
|
||||
const chunkCoord = worldToChunkCoord(worldCoord, safeChunkSize);
|
||||
return Math.floor(Number(worldCoord) - (chunkCoord * safeChunkSize));
|
||||
}
|
||||
|
||||
export function localToWorldCoord(chunkCoord: number, localCoord: number, chunkSize: number): number {
|
||||
const safeChunkSize = Math.max(1, Math.floor(Number(chunkSize) || DEFAULT_WORLD_CHUNK_SIZE));
|
||||
return (Math.floor(Number(chunkCoord) || 0) * safeChunkSize) + Math.floor(Number(localCoord) || 0);
|
||||
}
|
||||
|
||||
export function resolveWorldChunkAddress(worldX: number, worldY: number, chunkWidth: number, chunkHeight: number) {
|
||||
const safeChunkWidth = normalizeChunkDimension(chunkWidth);
|
||||
const safeChunkHeight = normalizeChunkDimension(chunkHeight);
|
||||
const chunkX = worldToChunkCoord(worldX, safeChunkWidth);
|
||||
const chunkY = worldToChunkCoord(worldY, safeChunkHeight);
|
||||
const localX = worldToLocalCoord(worldX, safeChunkWidth);
|
||||
const localY = worldToLocalCoord(worldY, safeChunkHeight);
|
||||
return {
|
||||
chunkX,
|
||||
chunkY,
|
||||
localX,
|
||||
localY,
|
||||
chunkKey: buildChunkKey(chunkX, chunkY),
|
||||
fileName: buildChunkFileName(chunkX, chunkY),
|
||||
};
|
||||
}
|
||||
|
||||
export function createEmptyChunk(worldId: string, chunkX: number, chunkY: number, backgroundTileId = "", chunkWidth = DEFAULT_WORLD_CHUNK_SIZE, chunkHeight = DEFAULT_WORLD_CHUNK_SIZE): WorldChunk {
|
||||
const width = normalizeChunkDimension(chunkWidth);
|
||||
const height = normalizeChunkDimension(chunkHeight);
|
||||
return {
|
||||
schemaVersion: WORLD_CHUNK_SCHEMA_VERSION,
|
||||
worldId: String(worldId || "").trim(),
|
||||
chunkX: Math.floor(Number(chunkX) || 0),
|
||||
chunkY: Math.floor(Number(chunkY) || 0),
|
||||
width,
|
||||
height,
|
||||
backgroundTileId: String(backgroundTileId || "").trim(),
|
||||
roomLayers: [
|
||||
{
|
||||
layer: 0,
|
||||
rows: Array.from({ length: height }, () => ".".repeat(width)),
|
||||
instanceIds: [],
|
||||
},
|
||||
{
|
||||
layer: 1,
|
||||
rows: Array.from({ length: height }, () => " ".repeat(width)),
|
||||
instanceIds: [],
|
||||
},
|
||||
],
|
||||
heightLayers: [],
|
||||
instances: [],
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue