import { JsonAsset, resources } from 'cc'; const META_PATH = 'theme/tile-display-meta'; export interface TileDisplayEntry { width: number; height: number; pivotX: number; pivotY: number; ppu?: number; /** 相对格子宽度的额外缩放(默认 1,snow kuai11 可略大于 1 以贴满格) */ fitMul?: number; } type ThemeTileMap = Record; let themeTiles: Record = {}; let loadPromise: Promise | null = null; function ingest(data: { themes?: Record }) { themeTiles = { ...(data.themes ?? {}) }; } export function loadTileDisplayMeta(): Promise { if (loadPromise) return loadPromise; loadPromise = new Promise((resolve) => { resources.load(META_PATH, JsonAsset, (err, asset) => { if (err || !asset?.json) { console.warn('[TileDisplayMeta] 未找到 tile-display-meta.json', err); themeTiles = {}; } else { ingest(asset.json as { themes?: Record }); } resolve(); }); }); return loadPromise; } export function reloadTileDisplayMeta(): Promise { themeTiles = {}; loadPromise = null; return new Promise((resolve) => { resources.release(META_PATH); loadTileDisplayMeta().then(resolve); }); } function normalizeThemeKey(theme?: string): string | undefined { if (theme == null) return undefined; const t = (typeof theme === 'string' ? theme : String(theme)).trim(); if (!t) return undefined; if (t === 'redArmy') return 'redarmy'; return t; } export function getThemeTileDisplayEntry(theme: string | undefined, tileName: string): TileDisplayEntry | null { const key = normalizeThemeKey(theme); if (!key) return null; const map = themeTiles[key]; if (!map) return null; return map[tileName] ?? null; } export function getThemeTileSize( theme: string | undefined, tileName: string, fallback: { width: number; height: number }, ): { width: number; height: number } { const entry = getThemeTileDisplayEntry(theme, tileName); if (!entry) return fallback; return { width: entry.width, height: entry.height }; } export function getThemeTilePivot( theme: string | undefined, tileName: string, fallback: { x: number; y: number }, ): { x: number; y: number } { const entry = getThemeTileDisplayEntry(theme, tileName); if (!entry) return fallback; return { x: entry.pivotX, y: entry.pivotY }; } export function getThemeTileFitMul(theme: string | undefined, tileName: string): number { const entry = getThemeTileDisplayEntry(theme, tileName); const mul = entry?.fitMul ?? 1; return Number.isFinite(mul) && mul > 0 ? mul : 1; }