/* eslint-disable @typescript-eslint/ban-ts-comment */ // @ts-nocheck import { BlurFilter, Sprite, Texture } from "pixi.js"; import { getWorldBorderThickness, parseHexColor } from "./pixiSurfaceHelpers"; function createBorderSprite(x, y, width, height, tint, alpha) { const border = new Sprite(Texture.WHITE); border.x = x; border.y = y; border.width = width; border.height = height; border.tint = tint; border.alpha = alpha; return border; } export function rebuildHeightOverlay(state, scope, helpers) { if (!helpers.isReady() || !state.heightOverlayRoot) { return; } const overlayMode = scope.isEditingHeightLayer && scope.isEditingHeightLayer() ? "height" : ""; const activeEntry = scope.getActiveHeightLayer ? scope.getActiveHeightLayer() : null; const activeId = String(activeEntry?.id || "").trim(); if ( !state.dirty && state.lastHeightLayersRef === scope.heightLayers && state.lastHeightOverlayMode === overlayMode && state.lastHeightActiveId === activeId && state.lastHeightTileSize === scope.tileSize ) { return; } state.heightPatchEntries.forEach((entry) => { helpers.destroyHeightPatchEntry(entry); }); state.heightPatchEntries.clear(); state.heightOverlayRoot.removeChildren(); state.lastHeightLayersRef = scope.heightLayers; state.lastHeightOverlayMode = overlayMode; state.lastHeightActiveId = activeId; state.lastHeightTileSize = scope.tileSize; if (overlayMode !== "height" || !activeEntry) { state.heightOverlayRoot.visible = false; return; } state.heightOverlayRoot.visible = true; const activeZ = Math.max(1, Number(activeEntry.z) || 1); const visibleEntries = (Array.isArray(scope.heightLayers) ? scope.heightLayers : []) .filter((entry) => Math.max(1, Number(entry?.z) || 1) === activeZ); const borderThickness = getWorldBorderThickness(scope.tileSize); visibleEntries.forEach((entry) => { const entryId = String(entry?.id || "").trim(); if (!entryId) { return; } const isActive = entryId === activeId; const patchContainer = new helpers.Container(); patchContainer.label = `height_${entryId}`; patchContainer.x = Math.max(0, Number(entry?.x) || 0); patchContainer.y = Math.max(0, Number(entry?.y) || 0); patchContainer.alpha = isActive ? 0.92 : 0.56; patchContainer.roundPixels = true; state.heightOverlayRoot.addChild(patchContainer); const rows = Array.isArray(entry?.rows) ? entry.rows : []; let patchWidth = 0; rows.forEach((rawRow, localY) => { const row = String(rawRow || ""); patchWidth = Math.max(patchWidth, row.length); for (let localX = 0; localX < row.length; localX += 1) { const symbol = String(row.charAt(localX) || " ").charAt(0) || " "; if (symbol === " " || symbol === ".") { continue; } const sprite = new Sprite(helpers.getTileTexture(symbol)); sprite.x = localX; sprite.y = localY; sprite.width = 1; sprite.height = 1; sprite.roundPixels = true; patchContainer.addChild(sprite); if (isActive) { const shade = new Sprite(Texture.WHITE); shade.x = localX; shade.y = localY; shade.width = 1; shade.height = 1; shade.tint = parseHexColor("#9198A8", 0x9198A8); shade.alpha = 0.28; shade.roundPixels = true; patchContainer.addChild(shade); } } }); if (patchWidth > 0 && rows.length > 0) { const drawW = patchWidth; const drawH = rows.length; const tint = isActive ? parseHexColor("#FFEB8C", 0xFFEB8C) : parseHexColor("#6EA0EB", 0x6EA0EB); const alpha = isActive ? 0.92 : 0.55; patchContainer.addChild(createBorderSprite(0, 0, drawW, borderThickness, tint, alpha)); patchContainer.addChild(createBorderSprite(0, drawH - borderThickness, drawW, borderThickness, tint, alpha)); patchContainer.addChild(createBorderSprite(0, 0, borderThickness, drawH, tint, alpha)); patchContainer.addChild(createBorderSprite(drawW - borderThickness, 0, borderThickness, drawH, tint, alpha)); } state.heightPatchEntries.set(entryId, { id: entryId, container: patchContainer, }); }); } export function resetSceneRoots(state, scope) { if (!state.backgroundSprite || !state.baseWorldRoot) { state.backgroundSprite = new Sprite(Texture.WHITE); state.backgroundSprite.zIndex = -1; state.backgroundSprite.roundPixels = true; } state.backgroundSprite.tint = parseHexColor(scope.normalizeMapBackgroundColor(scope.backgroundColor)); state.backgroundSprite.width = Math.max(1, Number(scope.width) || 1); state.backgroundSprite.height = Math.max(1, Number(scope.height) || 1); if (state.backgroundSprite.parent !== state.baseWorldRoot) { state.baseWorldRoot.addChildAt(state.backgroundSprite, 0); } if (state.heightOverlayRoot?.parent !== state.worldContainer) { state.worldContainer.addChild(state.heightOverlayRoot); } } export function syncHeightFocusEffect(state, scope) { if (!state.baseWorldRoot) { return; } const activeHeightLayer = scope.getActiveHeightLayer ? scope.getActiveHeightLayer() : null; const activeHeightZ = Math.max(0, Number(activeHeightLayer?.z) || 0); const isHeightModeActive = !!(scope.isEditingHeightLayer && scope.isEditingHeightLayer()) && activeHeightZ > 0; const blurStep = Math.max( 0, Math.min( 1, Number(scope.getEffectiveHeightBlurStep?.() ?? scope.heightBlurStep ?? scope.heightDetailStep) || 0.1, ), ); const tileReferenceSize = Math.max(8, Number(scope.baseTileSize) || Number(scope.tileSize) || 32); const nextBlurStrength = isHeightModeActive ? Math.min(8, activeHeightZ * blurStep * (tileReferenceSize / 4)) : 0; if (!state.heightFocusBlurFilter) { state.heightFocusBlurFilter = new BlurFilter({ strength: 0, quality: 2, kernelSize: 5 }); state.heightFocusBlurFilter.repeatEdgePixels = true; } if (isHeightModeActive) { if (!state.heightFocusCacheEnabled || Math.abs(nextBlurStrength - state.heightFocusBlurStrength) > 0.001) { state.heightFocusBlurFilter.strength = nextBlurStrength; state.baseWorldRoot.filters = [state.heightFocusBlurFilter]; state.heightFocusCacheEnabled = true; state.heightFocusBlurStrength = nextBlurStrength; } } else if (state.heightFocusCacheEnabled) { state.baseWorldRoot.filters = []; state.heightFocusCacheEnabled = false; state.heightFocusBlurStrength = 0; } state.baseWorldRoot.alpha = isHeightModeActive ? Math.max(0.92, 1 - (activeHeightZ * 0.015)) : 1; }