98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
const portraitModules = import.meta.glob('../../assets/images/portraits/*.png', {
|
|
eager: true,
|
|
import: 'default'
|
|
}) as Record<string, string>;
|
|
|
|
const legacyPortraitSlugs: Record<string, string> = {
|
|
liuBei: 'liu-bei',
|
|
guanYu: 'guan-yu',
|
|
zhangFei: 'zhang-fei',
|
|
zhugeLiang: 'zhuge-liang',
|
|
zhaoYun: 'zhao-yun',
|
|
jiangWei: 'jiang-wei',
|
|
simaYi: 'sima-yi'
|
|
};
|
|
|
|
const speakerPortraitKeys: Record<string, string> = {
|
|
유비: 'liuBei',
|
|
관우: 'guanYu',
|
|
장비: 'zhangFei',
|
|
제갈량: 'zhugeLiang',
|
|
조운: 'zhaoYun',
|
|
강유: 'jiangWei',
|
|
사마의: 'simaYi',
|
|
미축: 'mi-zhu',
|
|
간옹: 'jian-yong',
|
|
손건: 'sun-qian',
|
|
마량: 'ma-liang',
|
|
방통: 'pang-tong',
|
|
법정: 'fa-zheng',
|
|
황충: 'huang-zhong',
|
|
위연: 'wei-yan',
|
|
마초: 'ma-chao',
|
|
마대: 'ma-dai',
|
|
왕평: 'wang-ping',
|
|
이엄: 'li-yan',
|
|
오의: 'wu-yi',
|
|
이적: 'yi-ji',
|
|
공지: 'gong-zhi',
|
|
엄안: 'yan-yan',
|
|
황권: 'huang-quan',
|
|
맹획: 'meng-huo',
|
|
주유: 'zhou-yu',
|
|
조조: 'cao-cao'
|
|
};
|
|
|
|
function fileSlugFromPath(path: string) {
|
|
const fileName = path.split('/').pop() ?? path;
|
|
return fileName.replace(/\.png$/i, '');
|
|
}
|
|
|
|
function camelToKebab(value: string) {
|
|
return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
}
|
|
|
|
export const portraitAssets: Record<string, string> = Object.fromEntries(
|
|
Object.entries(portraitModules).map(([path, url]) => [fileSlugFromPath(path), url])
|
|
);
|
|
|
|
export type PortraitAssetEntry = {
|
|
textureKey: string;
|
|
url: string;
|
|
};
|
|
|
|
export function portraitSlugForKey(key: string) {
|
|
return legacyPortraitSlugs[key] ?? camelToKebab(key);
|
|
}
|
|
|
|
export function portraitTextureKey(key: string) {
|
|
const slug = portraitSlugForKey(key);
|
|
return portraitAssets[slug] ? `portrait-${slug}` : undefined;
|
|
}
|
|
|
|
export function portraitAssetEntriesForKey(key: string): PortraitAssetEntry[] {
|
|
const slug = portraitSlugForKey(key);
|
|
const prefix = `${slug}-`;
|
|
return Object.keys(portraitAssets)
|
|
.filter((candidate) => candidate === slug || candidate.startsWith(prefix))
|
|
.sort()
|
|
.map((candidate) => ({
|
|
textureKey: `portrait-${candidate}`,
|
|
url: portraitAssets[candidate]
|
|
}));
|
|
}
|
|
|
|
export function portraitTextureKeysForKey(key: string) {
|
|
const slug = portraitSlugForKey(key);
|
|
const prefix = `${slug}-`;
|
|
const slugs = Object.keys(portraitAssets)
|
|
.filter((candidate) => candidate === slug || candidate.startsWith(prefix))
|
|
.sort();
|
|
|
|
return Array.from(new Set(slugs.map((candidate) => `portrait-${candidate}`)));
|
|
}
|
|
|
|
export function portraitKeyForSpeaker(speaker?: string) {
|
|
return speaker ? speakerPortraitKeys[speaker] : undefined;
|
|
}
|