/** * 内置回退贴图(themes-database.json 未加载或未配置时使用) */ import { Direction } from '../core/Define'; import { getThemeTextureFolder, isThemeDatabaseReady } from '../theme/ThemeRegistry'; export interface ThemeEntityTextureSet { playerFront: string[]; playerBack: string[]; shipNorth: string[]; shipEast: string[]; shipSouth: string[]; shipWest: string[]; /** @deprecated 等同 shipSouth */ shipFront: string[]; /** @deprecated 等同 shipNorth */ shipBack: string[]; } const THEME_TEXTURE_FOLDER: Record = { default: 'default', silu: 'silu', SILU: 'silu', chinese: 'chinese', redArmy: 'redArmy', redarmy: 'redArmy', numMan: 'numMan', snow: 'snow', sanxing: 'sanxing', }; const THEME_CANONICAL_KEY: Record = { default: 'default', silu: 'silu', SILU: 'silu', chinese: 'chinese', redArmy: 'redArmy', redarmy: 'redArmy', numMan: 'numMan', snow: 'snow', sanxing: 'sanxing', }; function shipFourWay(folder: string, prefix: string): Pick< ThemeEntityTextureSet, 'shipNorth' | 'shipEast' | 'shipSouth' | 'shipWest' | 'shipFront' | 'shipBack' > { const base = `textures/${folder}/${prefix}`; return { shipNorth: [`${base}_N`, `${base}_B`], shipEast: [`${base}_E`], shipSouth: [`${base}_S`, `${base}_F`], shipWest: [`${base}_W`], shipFront: [`${base}_S`, `${base}_F`], shipBack: [`${base}_N`, `${base}_B`], }; } const SILU_SHIP = shipFourWay('silu', 'siluShip'); const SILU_FALLBACK: ThemeEntityTextureSet = { playerFront: ['textures/silu/skin/待机正面/1'], playerBack: ['textures/silu/skin/待机背面/1'], ...SILU_SHIP, }; export const THEME_ENTITY_TEXTURES: Record = { default: { playerFront: ['textures/default/player_F'], playerBack: ['textures/default/player_B'], ...shipFourWay('default', 'ship'), }, silu: { ...SILU_FALLBACK }, chinese: { playerFront: ['textures/chinese/skin/待机正面/1', 'textures/chinese/chineseShip_F'], playerBack: ['textures/chinese/skin/待机背面/1', 'textures/chinese/chineseShip_B'], ...shipFourWay('chinese', 'chineseShip'), }, redArmy: { playerFront: ['textures/redArmy/skin/待机正面/1'], playerBack: ['textures/redArmy/skin/待机背面/1'], ...shipFourWay('redArmy', 'redArmyShip'), }, numMan: { playerFront: ['textures/numMan/skin/待机正面/1'], playerBack: ['textures/numMan/skin/待机背面/1'], ...shipFourWay('numMan', 'numManShip'), }, snow: { playerFront: ['textures/snow/skin/待机正面/1'], playerBack: ['textures/snow/skin/待机背面/1'], ...shipFourWay('snow', 'snowShip'), }, sanxing: { playerFront: ['textures/sanxing/skin/待机正面/1'], playerBack: ['textures/sanxing/skin/待机背面/1'], ...shipFourWay('sanxing', 'sanxingShip'), }, }; export function canonicalThemeKey(theme: string | undefined): string { if (!theme) return 'silu'; return THEME_CANONICAL_KEY[theme] ?? theme; } export function resolveThemeFolder(theme: string | undefined): string { if (!theme) return 'silu'; if (isThemeDatabaseReady()) return getThemeTextureFolder(theme); return THEME_TEXTURE_FOLDER[theme] ?? theme; } export function getThemeEntityTextures(theme: string | undefined): ThemeEntityTextureSet { const key = canonicalThemeKey(theme); return THEME_ENTITY_TEXTURES[key] ?? SILU_FALLBACK; } export type VehicleSpriteRole = 'shipNorth' | 'shipEast' | 'shipSouth' | 'shipWest'; export type EntitySpriteRole = 'playerFront' | 'playerBack' | VehicleSpriteRole | 'shipFront' | 'shipBack'; export function vehicleSpriteRoleForDirection(direction: Direction): VehicleSpriteRole { switch (direction) { case Direction.North: return 'shipNorth'; case Direction.East: return 'shipEast'; case Direction.South: return 'shipSouth'; case Direction.West: return 'shipWest'; default: return 'shipNorth'; } } export function vehicleThemeFieldForDirection(direction: Direction): keyof import('../theme/ThemeTypes').ThemeEntityConfig { switch (direction) { case Direction.North: return 'vehicleNorth'; case Direction.East: return 'vehicleEast'; case Direction.South: return 'vehicleSouth'; case Direction.West: return 'vehicleWest'; default: return 'vehicleNorth'; } } export function entityTextureCandidates( theme: string | undefined, role: EntitySpriteRole, ): string[] { const set = getThemeEntityTextures(theme); const primary = [...(set[role] ?? [])]; const fb = SILU_FALLBACK[role as keyof ThemeEntityTextureSet]; if (fb) { for (const p of fb) { if (!primary.includes(p)) primary.push(p); } } return primary; } /** 预加载某主题载具四向贴图主路径 */ export function allVehicleDirectionTextureCandidates(theme: string | undefined): string[] { const out: string[] = []; for (let d = Direction.North; d <= Direction.West; d++) { for (const p of entityTextureCandidates(theme, vehicleSpriteRoleForDirection(d))) { if (!out.includes(p)) out.push(p); } } return out; }