145 lines
5.5 KiB
TypeScript
145 lines
5.5 KiB
TypeScript
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
// @ts-nocheck
|
|
|
|
import { rebuildChunkEntrySurface } from "./pixiChunkSurfaceHelpers";
|
|
|
|
function buildChunkSurfaceOptions(state, scope, helpers) {
|
|
return {
|
|
baseTileSize: scope.baseTileSize,
|
|
chunkSize: state.chunkSize,
|
|
getTileOpacity: helpers.getTileOpacity,
|
|
getTileSurface: helpers.getTileSurface,
|
|
syncChunkEntryDimensions: helpers.syncChunkEntryDimensions,
|
|
tileSize: scope.tileSize,
|
|
};
|
|
}
|
|
|
|
export function rebuildSceneFromWorldChunks(state, scope, helpers) {
|
|
const worldContext = helpers.getWorldChunkRenderContext();
|
|
if (!worldContext) {
|
|
return false;
|
|
}
|
|
helpers.resetSceneRoots();
|
|
const chunkSurfaceOptions = buildChunkSurfaceOptions(state, scope, helpers);
|
|
const desiredKeys = new Set();
|
|
const activeLayerNumbers = new Set();
|
|
worldContext.chunks.forEach((chunk) => {
|
|
const chunkX = Math.floor(Number(chunk?.chunkX) || 0);
|
|
const chunkY = Math.floor(Number(chunk?.chunkY) || 0);
|
|
const tileX = (chunkX - worldContext.originChunkX) * worldContext.chunkWidth;
|
|
const tileY = (chunkY - worldContext.originChunkY) * worldContext.chunkHeight;
|
|
const roomLayers = Array.isArray(chunk?.roomLayers) ? chunk.roomLayers : [];
|
|
roomLayers.forEach((layerObj) => {
|
|
const layerNumber = Number(layerObj?.layer) || 0;
|
|
activeLayerNumbers.add(layerNumber);
|
|
const layerRoot = helpers.getOrCreateLayerRoot(layerNumber);
|
|
layerRoot.visible = scope.isLayerRendered(layerNumber);
|
|
const chunkKey = helpers.buildLayerChunkKey(layerNumber, chunkX, chunkY);
|
|
desiredKeys.add(chunkKey);
|
|
let entry = state.chunkEntries.get(chunkKey) || null;
|
|
if (!entry) {
|
|
entry = helpers.createChunkEntry(layerNumber, chunkX, chunkY, {
|
|
tileX,
|
|
tileY,
|
|
tileWidth: worldContext.chunkWidth,
|
|
tileHeight: worldContext.chunkHeight,
|
|
});
|
|
}
|
|
if (entry.tileX !== tileX || entry.tileY !== tileY) {
|
|
entry.tileX = tileX;
|
|
entry.tileY = tileY;
|
|
entry.sprite.x = tileX;
|
|
entry.sprite.y = tileY;
|
|
}
|
|
if (entry.tileWidth !== worldContext.chunkWidth || entry.tileHeight !== worldContext.chunkHeight) {
|
|
entry.tileWidth = worldContext.chunkWidth;
|
|
entry.tileHeight = worldContext.chunkHeight;
|
|
}
|
|
const hasContent = rebuildChunkEntrySurface(
|
|
entry,
|
|
(localX, localY) => helpers.resolveWorldChunkLayerSymbol(chunk, layerObj, localX, localY),
|
|
worldContext.chunkWidth,
|
|
worldContext.chunkHeight,
|
|
String(chunk?.backgroundTileId || ""),
|
|
chunkSurfaceOptions,
|
|
);
|
|
if (!hasContent && layerNumber > 0) {
|
|
helpers.destroyChunkEntry(entry);
|
|
desiredKeys.delete(chunkKey);
|
|
}
|
|
});
|
|
});
|
|
Array.from(state.chunkEntries.entries()).forEach(([key, entry]) => {
|
|
if (!desiredKeys.has(key)) {
|
|
helpers.destroyChunkEntry(entry);
|
|
}
|
|
});
|
|
Array.from(state.layerRoots.entries()).forEach(([layerNumber, layerRoot]) => {
|
|
if (!activeLayerNumbers.has(layerNumber)) {
|
|
state.npcSpritesById.forEach((sprite, npcId) => {
|
|
if (sprite?.parent && sprite.parent === state.entityLayerRoots.get(layerNumber)) {
|
|
state.npcSpritesById.delete(npcId);
|
|
}
|
|
});
|
|
state.entityLayerRoots.delete(layerNumber);
|
|
layerRoot.removeFromParent();
|
|
layerRoot.destroy({ children: true });
|
|
state.layerRoots.delete(layerNumber);
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
|
|
export function rebuildSceneFromRoomLayers(state, scope, helpers) {
|
|
state.chunkEntries.forEach((entry) => {
|
|
helpers.destroyChunkEntry(entry);
|
|
});
|
|
state.chunkEntries.clear();
|
|
state.layerRoots.forEach((layerRoot) => {
|
|
layerRoot.removeFromParent();
|
|
layerRoot.destroy({ children: true });
|
|
});
|
|
state.layerRoots.clear();
|
|
state.entityLayerRoots.clear();
|
|
state.npcSpritesById.clear();
|
|
|
|
helpers.resetSceneRoots();
|
|
|
|
const chunkSurfaceOptions = buildChunkSurfaceOptions(state, scope, helpers);
|
|
const layers = Array.isArray(scope.roomLayers)
|
|
? [...scope.roomLayers].sort((a, b) => (Number(a.layer) || 0) - (Number(b.layer) || 0))
|
|
: [];
|
|
layers.forEach((layerObj) => {
|
|
const layerNumber = Number(layerObj?.layer) || 0;
|
|
const layerRoot = helpers.getOrCreateLayerRoot(layerNumber);
|
|
layerRoot.visible = scope.isLayerRendered(layerNumber);
|
|
const chunkStartsX = Math.ceil(Math.max(1, Number(scope.width) || 1) / state.chunkSize);
|
|
const chunkStartsY = Math.ceil(Math.max(1, Number(scope.height) || 1) / state.chunkSize);
|
|
for (let chunkY = 0; chunkY < chunkStartsY; chunkY += 1) {
|
|
for (let chunkX = 0; chunkX < chunkStartsX; chunkX += 1) {
|
|
const baseTileX = chunkX * state.chunkSize;
|
|
const baseTileY = chunkY * state.chunkSize;
|
|
const tileWidth = Math.max(1, Math.min(state.chunkSize, Math.max(0, Number(scope.width) || 0) - baseTileX));
|
|
const tileHeight = Math.max(1, Math.min(state.chunkSize, Math.max(0, Number(scope.height) || 0) - baseTileY));
|
|
const chunkEntry = helpers.getOrCreateChunkEntry(layerNumber, chunkX, chunkY, {
|
|
tileX: baseTileX,
|
|
tileY: baseTileY,
|
|
tileWidth,
|
|
tileHeight,
|
|
});
|
|
const hasContent = rebuildChunkEntrySurface(
|
|
chunkEntry,
|
|
(localX, localY) => helpers.resolveStoredTileSymbol(layerObj, baseTileX + localX, baseTileY + localY),
|
|
tileWidth,
|
|
tileHeight,
|
|
String(layerNumber),
|
|
chunkSurfaceOptions,
|
|
);
|
|
if (!hasContent) {
|
|
helpers.destroyChunkEntry(chunkEntry);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return true;
|
|
}
|