225 lines
6.3 KiB
TypeScript
225 lines
6.3 KiB
TypeScript
// level-names-zh.ts — 关卡/场景的中文显示名(用于页面上的三级选择器)
|
||
//
|
||
// 出处说明(重要,避免误认为官方本地化):
|
||
// 这批译名是**社区通用译名**,由本项目手工整理;英文原名取自 `Levels.txt` 的 `LevelName`
|
||
// 列(例如 1 = "Rogue Encampment"、33 = "Cathedral"),中文对照按国内玩家习惯写法。
|
||
// 我们这份安装包里的 `data\local\LNG\CHI\string.tbl` 解出来是乱码(`.tbl` 解码器只对夹具
|
||
// 验证过,尚未对真文件校准),所以**没有**直接采用官方简中字符串表;等 `.tbl` 解码对齐后
|
||
// 可以换成官方译名,届时只需替换本表。
|
||
//
|
||
// 键是 `Levels.txt` 的 `Id`;页面从 pack 索引条目的 `slug`(形如 `33-act-1-cathedral`)里
|
||
// 取第一个数字段就能对上。查不到时回退到索引里的英文 `levelName`。
|
||
|
||
/** 五个 act 的中文名,下标即 act 号。 */
|
||
export const ACT_NAMES_ZH: Readonly<Record<number, string>> = {
|
||
1: '第一章',
|
||
2: '第二章',
|
||
3: '第三章',
|
||
4: '第四章',
|
||
5: '第五章',
|
||
}
|
||
|
||
/** `Levels.txt` 的 `Id` → 中文场景名。 */
|
||
export const LEVEL_NAMES_ZH: Readonly<Record<number, string>> = {
|
||
// Act 1
|
||
1: '罗格营地',
|
||
2: '鲜血荒地',
|
||
3: '冰冷之原',
|
||
4: '石块旷野',
|
||
5: '黑暗森林',
|
||
6: '黑色荒地',
|
||
7: '泰摩高地',
|
||
8: '邪恶洞窟',
|
||
9: '洞穴一层',
|
||
10: '地下通道一层',
|
||
11: '窟窿一层',
|
||
12: '深坑一层',
|
||
13: '洞穴二层',
|
||
14: '地下通道二层',
|
||
15: '窟窿二层',
|
||
16: '深坑二层',
|
||
17: '埋骨之地',
|
||
18: '大陵寝',
|
||
19: '灵庙',
|
||
20: '遗忘之塔',
|
||
21: '塔地窖一层',
|
||
22: '塔地窖二层',
|
||
23: '塔地窖三层',
|
||
24: '塔地窖四层',
|
||
25: '塔地窖五层',
|
||
26: '修道院大门',
|
||
27: '外回廊',
|
||
28: '军营',
|
||
29: '监牢一层',
|
||
30: '监牢二层',
|
||
31: '监牢三层',
|
||
32: '内回廊',
|
||
33: '大教堂',
|
||
34: '地下墓穴一层',
|
||
35: '地下墓穴二层',
|
||
36: '地下墓穴三层',
|
||
37: '地下墓穴四层',
|
||
38: '崔斯特瑞姆',
|
||
39: '奶牛关',
|
||
|
||
// Act 2
|
||
40: '鲁高因',
|
||
41: '碎石荒地',
|
||
42: '干燥高地',
|
||
43: '遥远绿洲',
|
||
44: '遗失的城市',
|
||
45: '群蛇峡谷',
|
||
46: '术士峡谷',
|
||
47: '下水道一层',
|
||
48: '下水道二层',
|
||
49: '下水道三层',
|
||
50: '后宫一层',
|
||
51: '后宫二层',
|
||
52: '皇宫地牢一层',
|
||
53: '皇宫地牢二层',
|
||
54: '皇宫地牢三层',
|
||
55: '石制古墓一层',
|
||
56: '死亡之殿一层',
|
||
57: '死亡之殿二层',
|
||
58: '利爪蝮蛇神殿一层',
|
||
59: '石制古墓二层',
|
||
60: '死亡之殿三层',
|
||
61: '利爪蝮蛇神殿二层',
|
||
62: '蛆虫巢穴一层',
|
||
63: '蛆虫巢穴二层',
|
||
64: '蛆虫巢穴三层',
|
||
65: '古代通道',
|
||
66: '塔·拉夏古墓 (1)',
|
||
67: '塔·拉夏古墓 (2)',
|
||
68: '塔·拉夏古墓 (3)',
|
||
69: '塔·拉夏古墓 (4)',
|
||
70: '塔·拉夏古墓 (5)',
|
||
71: '塔·拉夏古墓 (6)',
|
||
72: '塔·拉夏古墓 (7)',
|
||
73: '都瑞尔的巢穴',
|
||
74: '秘法圣所',
|
||
|
||
// Act 3
|
||
75: '库拉斯特码头',
|
||
76: '蜘蛛森林',
|
||
77: '庞大湿地',
|
||
78: '剥皮丛林',
|
||
79: '库拉斯特下层',
|
||
80: '库拉斯特商场',
|
||
81: '库拉斯特上层',
|
||
82: '库拉斯特堤道',
|
||
83: '崔凡克',
|
||
84: '蜘蛛巢穴',
|
||
85: '蜘蛛洞窟',
|
||
86: '沼泽地坑一层',
|
||
87: '沼泽地坑二层',
|
||
88: '剥皮地牢一层',
|
||
89: '剥皮地牢二层',
|
||
90: '沼泽地坑三层',
|
||
91: '剥皮地牢三层',
|
||
92: '下水道一层',
|
||
93: '下水道二层',
|
||
94: '废弃神殿',
|
||
95: '荒废神庙',
|
||
96: '遗忘圣物室',
|
||
97: '遗忘神殿',
|
||
98: '废弃神庙',
|
||
99: '荒废圣物室',
|
||
100: '憎恨囚牢一层',
|
||
101: '憎恨囚牢二层',
|
||
102: '憎恨囚牢三层',
|
||
|
||
// Act 4
|
||
103: '群魔堡垒',
|
||
104: '郊外大草原',
|
||
105: '绝望平原',
|
||
106: '神罚之城',
|
||
107: '火焰之河',
|
||
108: '混沌避难所',
|
||
|
||
// Act 5
|
||
109: '哈洛加斯',
|
||
110: '血腥丘陵',
|
||
111: '冰冻高地',
|
||
112: '亚瑞特高原',
|
||
113: '水晶通道',
|
||
114: '冰河',
|
||
115: '冰河路径',
|
||
116: '漂泊者洞穴',
|
||
117: '冰冻苔原',
|
||
118: '冰窖',
|
||
119: '痛苦之厅',
|
||
120: '岩石之巅',
|
||
121: '尼拉塞克神殿',
|
||
122: '悲痛之厅',
|
||
123: '死者呼唤之厅',
|
||
124: '沃特厅',
|
||
125: '艾巴当',
|
||
126: '阿克隆地道',
|
||
127: '炼狱地坑',
|
||
128: '世界之石要塞一层',
|
||
129: '世界之石要塞二层',
|
||
130: '世界之石要塞三层',
|
||
131: '毁灭王座',
|
||
132: '世界之石大殿',
|
||
133: '遗忘之沙',
|
||
134: '巨窟',
|
||
135: '苦痛熔炉',
|
||
136: '混沌崔斯特瑞姆',
|
||
}
|
||
|
||
/**
|
||
* DS1 变体后缀 → 方位名。
|
||
*
|
||
* 这些后缀是 D2 自己的命名习惯:城镇/回廊/鲁高因的 DS1 以 `N`/`E`/`S`/`W` 结尾
|
||
* (`TownN1`、`CourtW`、`LutN`…)。**只白名单这几个**,不做"末尾字母是方位"的猜测:
|
||
* `CryptCountess1` 末尾也是 `s`,按猜测会错成"南"。
|
||
*/
|
||
const DIRECTION_SUFFIXES: Readonly<Record<string, string>> = {
|
||
townn1: '北',
|
||
towne1: '东',
|
||
towns1: '南',
|
||
townw1: '西',
|
||
courtn: '北',
|
||
courte: '东',
|
||
courtw: '西',
|
||
lutn: '北',
|
||
lutw: '西',
|
||
}
|
||
|
||
/**
|
||
* 把一个变体后缀变成显示用的中文(拿不准就原样返回 DS1 名)。
|
||
*
|
||
* @param suffix - the part of the pack label after the level slug, e.g. `towns1` or `var1`.
|
||
* @returns the label to show in the third selector.
|
||
*/
|
||
export function variantLabelZh(suffix: string): string {
|
||
const match = /^var(\d+)$/i.exec(suffix)
|
||
if (match) return `变体 ${match[1]}`
|
||
return DIRECTION_SUFFIXES[suffix.toLowerCase()] ?? suffix
|
||
}
|
||
|
||
/**
|
||
* 从 pack 索引条目的 `slug` 里取 `Levels.txt` 的关卡 Id。
|
||
*
|
||
* @param slug - e.g. `33-act-1-cathedral`.
|
||
* @returns the id, or null when the slug does not start with one.
|
||
*/
|
||
export function levelIdOfSlug(slug: string): number | null {
|
||
const match = /^(\d+)-/.exec(slug)
|
||
return match?.[1] === undefined ? null : Number(match[1])
|
||
}
|
||
|
||
/**
|
||
* 一个场景的中文名,取不到就回退调用方给的英文名。
|
||
*
|
||
* @param slug - the scene slug from the pack index.
|
||
* @param fallback - the English name from the pack index.
|
||
* @returns the display name.
|
||
*/
|
||
export function sceneNameZh(slug: string, fallback: string): string {
|
||
const id = levelIdOfSlug(slug)
|
||
if (id === null) return fallback
|
||
return LEVEL_NAMES_ZH[id] ?? fallback
|
||
}
|