You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
3.6 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import type { Locale } from './index';
import { ENEMY_TYPE_LABELS } from './enemyTypeLabels';
/** Stable keys aligned with backend migrations / model constants. */
export const WANDERING_MERCHANT_NPC_KEY = 'npc.wandering_merchant.v1';
export const WANDERING_MERCHANT_DIALOGUE_KEY = 'npc.wandering_merchant.dialogue.v1';
type Bilingual = { en: string; ru: string };
const TOWNS: Record<string, Bilingual> = {
'town.willowdale.v1': { en: 'Willowdale', ru: 'Ивадол' },
'town.thornwatch.v1': { en: 'Thornwatch', ru: 'Тернозорь' },
'town.ashengard.v1': { en: 'Ashengard', ru: 'Пепельный гард' },
'town.redcliff.v1': { en: 'Redcliff', ru: 'Красная скала' },
'town.boghollow.v1': { en: 'Boghollow', ru: 'Торфяная низина' },
'town.cinderkeep.v1': { en: 'Cinderkeep', ru: 'Зола-крепость' },
'town.starfall.v1': { en: 'Starfall', ru: 'Звездопад' },
'town.mossharbor.v1': { en: 'Mossharbor', ru: 'Мшистая гавань' },
'town.emberwell.v1': { en: 'Emberwell', ru: 'Угольный колодец' },
'town.frostmark.v1': { en: 'Frostmark', ru: 'Морозная метка' },
'town.duskwatch.v1': { en: 'Duskwatch', ru: 'Сумеречный дозор' },
};
const NPCS: Record<string, Bilingual> = {
'npc.elder_maren.v1': { en: 'Elder Maren', ru: 'Старейшина Марен' },
'npc.peddler_finn.v1': { en: 'Peddler Finn', ru: 'Бродячий торговец Финн' },
'npc.sister_asha.v1': { en: 'Sister Asha', ru: 'Сестра Аша' },
'npc.guard_halric.v1': { en: 'Guard Halric', ru: 'Страж Халрик' },
'npc.trader_wynn.v1': { en: 'Trader Wynn', ru: 'Торговец Винн' },
'npc.scholar_orin.v1': { en: 'Scholar Orin', ru: 'Учёный Орин' },
'npc.bone_merchant.v1': { en: 'Bone Merchant', ru: 'Торговец костями' },
'npc.priestess_liora.v1': { en: 'Priestess Liora', ru: 'Жрица Лиора' },
[WANDERING_MERCHANT_NPC_KEY]: { en: 'Wandering Merchant', ru: 'Бродячий торговец' },
};
const DIALOGUES: Record<string, Bilingual> = {
[WANDERING_MERCHANT_DIALOGUE_KEY]: {
en: 'A hooded merchant blocks your path, jingling a pouch of odd trinkets.',
ru: 'В капюшоне торговец преграждает путь, звеня мешочком с безделушками.',
},
};
function pick(locale: Locale, b: Bilingual): string {
return locale === 'ru' ? b.ru : b.en;
}
export function townLabel(locale: Locale, key: string | undefined, fallback: string): string {
if (!key) return fallback;
const b = TOWNS[key];
return b ? pick(locale, b) : fallback;
}
export function npcLabel(locale: Locale, key: string | undefined, fallback: string): string {
if (!key) return fallback;
const b = NPCS[key];
return b ? pick(locale, b) : fallback;
}
export function dialogueText(locale: Locale, key: string | undefined, fallback: string): string {
if (!key) return fallback;
const b = DIALOGUES[key];
return b ? pick(locale, b) : fallback;
}
/**
* Display name for an enemy template: optional i18n by `enemies.type`, else DB name, else slug.
* @param enemyTypeSlug - value of `enemies.type` / API `enemy.type`
* @param dbName - `enemies.name` from API (English); used when no entry in ENEMY_TYPE_LABELS
*/
export function enemyFamilyLabel(locale: Locale, enemyTypeSlug: string, dbName: string): string {
const slug = enemyTypeSlug?.trim() ?? '';
const b = slug && slug in ENEMY_TYPE_LABELS ? ENEMY_TYPE_LABELS[slug] : undefined;
if (b) return pick(locale, b);
const name = dbName?.trim();
if (name) return name;
return slug || dbName;
}