infinity expantion
This commit is contained in:
parent
c523bf4380
commit
ea0067dc0a
10 changed files with 2792 additions and 70 deletions
100
worldMap.js
Normal file
100
worldMap.js
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import { MAP_H, MAP_W, SIZE } from "./mapUtils.js";
|
||||
|
||||
export const DEFAULT_WORLD_PADDING_X = MAP_W;
|
||||
export const DEFAULT_WORLD_PADDING_Y = MAP_H;
|
||||
|
||||
const NEGATIVE_ONE_FIELDS = new Set([
|
||||
"adminId",
|
||||
"prefectureRegionId",
|
||||
"regionId",
|
||||
"municipalityId",
|
||||
]);
|
||||
|
||||
function isCellField(value) {
|
||||
return ArrayBuffer.isView(value) && typeof value.length === "number" && value.length === SIZE;
|
||||
}
|
||||
|
||||
function defaultForField(name, Constructor) {
|
||||
if (name === "sea") return 1;
|
||||
if (name === "elevation") return 0.08;
|
||||
if (name === "seaLevel") return undefined;
|
||||
if (NEGATIVE_ONE_FIELDS.has(name)) return -1;
|
||||
if (Constructor === Float32Array || Constructor === Float64Array) return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function makeWorldField(name, source, worldWidth, worldHeight, originX, originY) {
|
||||
const Constructor = source.constructor;
|
||||
const out = new Constructor(worldWidth * worldHeight);
|
||||
const fallback = defaultForField(name, Constructor);
|
||||
if (fallback !== 0) out.fill(fallback);
|
||||
|
||||
for (let y = 0; y < MAP_H; y++) {
|
||||
const srcRow = y * MAP_W;
|
||||
const dstRow = (originY + y) * worldWidth + originX;
|
||||
for (let x = 0; x < MAP_W; x++) out[dstRow + x] = source[srcRow + x];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function createWorldMap(initialMap, options = {}) {
|
||||
const paddingX = Number.isFinite(options.paddingX) ? Math.max(0, Math.floor(options.paddingX)) : DEFAULT_WORLD_PADDING_X;
|
||||
const paddingY = Number.isFinite(options.paddingY) ? Math.max(0, Math.floor(options.paddingY)) : DEFAULT_WORLD_PADDING_Y;
|
||||
const worldWidth = MAP_W + paddingX * 2;
|
||||
const worldHeight = MAP_H + paddingY * 2;
|
||||
const originX = paddingX;
|
||||
const originY = paddingY;
|
||||
const fields = {};
|
||||
|
||||
for (const [name, value] of Object.entries(initialMap || {})) {
|
||||
if (isCellField(value)) fields[name] = makeWorldField(name, value, worldWidth, worldHeight, originX, originY);
|
||||
}
|
||||
|
||||
if (!fields.sea) {
|
||||
fields.sea = new Uint8Array(worldWidth * worldHeight);
|
||||
fields.sea.fill(1);
|
||||
}
|
||||
if (!fields.elevation) {
|
||||
fields.elevation = new Float32Array(worldWidth * worldHeight);
|
||||
fields.elevation.fill(0.08);
|
||||
}
|
||||
|
||||
return {
|
||||
seed: initialMap?.seed ?? 0,
|
||||
width: worldWidth,
|
||||
height: worldHeight,
|
||||
originX,
|
||||
originY,
|
||||
sourceWidth: initialMap?.width || MAP_W,
|
||||
sourceHeight: initialMap?.height || MAP_H,
|
||||
sourceMap: initialMap,
|
||||
fields,
|
||||
invalidatedRects: [],
|
||||
humanPatchHistory: [],
|
||||
generatedRects: [{
|
||||
x0: originX,
|
||||
y0: originY,
|
||||
x1: originX + MAP_W,
|
||||
y1: originY + MAP_H,
|
||||
terrainType: initialMap?.terrainTemplate?.terrainType || initialMap?.terrainDebug?.terrainType || "auto",
|
||||
label: initialMap?.terrainTemplate?.terrainTypeLabel || initialMap?.terrainDebug?.terrainTypeLabel || "Initial generation",
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
export function createInitialCamera(world) {
|
||||
return {
|
||||
x: world?.originX || 0,
|
||||
y: world?.originY || 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function clampCameraToWorld(camera, world, viewWidth = MAP_W, viewHeight = MAP_H) {
|
||||
if (!camera || !world) return { x: 0, y: 0 };
|
||||
const maxX = Math.max(0, world.width - viewWidth);
|
||||
const maxY = Math.max(0, world.height - viewHeight);
|
||||
return {
|
||||
x: Math.min(Math.max(Math.round(camera.x || 0), 0), maxX),
|
||||
y: Math.min(Math.max(Math.round(camera.y || 0), 0), maxY),
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue