refactor: 重构多语言处理逻辑,统一配置与显示分离

1. 新增LangUtil工具类实现统一的多语言映射与参数替换
2. 移除各配置文件中的硬编码多语言包装类,替换为直接中文文本
3. 更新zh.json补充成就相关多语言词条
4. 重构HighlightSet适配新的多语言调用规范
This commit is contained in:
panw
2026-05-15 15:44:32 +08:00
parent a16fe4bff7
commit 4f8a955506
5 changed files with 368 additions and 226 deletions

View File

@@ -1,54 +1,51 @@
/**
* @file HighlightSet.ts
* @description 亮点成就配置文件
*
*
* 定义所有亮点成就的等级、触发条件、加分以及称号描述。
* 每个亮点都包含5个递进等级奖励分随等级增加。
*
* uuid 分组规则90 + 类型序号(1~9) + 等级(1~5)
* 9011~9015 = CritMaster 暴击大师
* 9021~9025 = DeathExpert 送死达人
* 9031~9035 = IronWall 铁壁铜墙
* 9041~9045 = WindStorm 风暴之王
* 9051~9055 = OneHitKill 一击必杀
* 9061~9065 = HealingLight 治愈之光
* 9071 = PerfectClear 完美通关
* 9081~9085 = LuckyKing 欧皇附体
* 9091~9095 = ThriftyPlayer 节俭玩家
*
* 多语言调用方式(与英雄/技能统一):
* import { lang, langf } from "../common/LangUtil";
* lang("hl_title", 9011) // → "初级暴击者"
* langf("hl_desc", 9011, 20) // → "暴击20次"
*/
import { oops } from "db://oops-framework/core/Oops"
class I18nString {
constructor(private key: string, private params?: any[]) {}
private getTranslated(): string {
let str = oops.language.getLangByID(this.key) || this.key;
if (this.params && this.params.length > 0) {
for (let i = 0; i < this.params.length; i++) {
str = str.replace(`{${i}}`, String(this.params[i]));
}
}
return str;
}
toString() { return this.getTranslated(); }
valueOf() { return this.getTranslated(); }
toJSON() { return this.getTranslated(); }
get length() { return this.toString().length; }
}
const t = (key: string, ...params: any[]) => new I18nString(key, params) as unknown as string;
export enum HighlightType {
CritMaster = "CritMaster", // 暴击大师
DeathExpert = "DeathExpert", // 送死达人
IronWall = "IronWall", // 铁壁铜墙
WindStorm = "WindStorm", // 风暴之王
OneHitKill = "OneHitKill", // 一击必杀
HealingLight = "HealingLight", // 治愈之光
PerfectClear = "PerfectClear", // 完美通关 (特殊,只有一档或布尔判定)
LuckyKing = "LuckyKing", // 欧皇附体
ThriftyPlayer = "ThriftyPlayer" // 节俭玩家
CritMaster = "CritMaster",
DeathExpert = "DeathExpert",
IronWall = "IronWall",
WindStorm = "WindStorm",
OneHitKill = "OneHitKill",
HealingLight = "HealingLight",
PerfectClear = "PerfectClear",
LuckyKing = "LuckyKing",
ThriftyPlayer = "ThriftyPlayer"
}
export interface HighlightLevel {
level: number; // 成就等级 (1-5)
threshold: number; // 达成阈值 (如暴击40次)
scoreBonus: number; // 额外加分
title: string; // 成就称号
desc: string; // 成就描述模板
uuid: number;
level: number;
threshold: number;
scoreBonus: number;
title: string;
desc: string;
}
export interface HighlightConfig {
type: HighlightType;
icon: string; // 显示前缀icon如 "🔥"
icon: string;
levels: HighlightLevel[];
}
@@ -57,95 +54,95 @@ export const HighlightSet: Record<HighlightType, HighlightConfig> = {
type: HighlightType.CritMaster,
icon: "🔥",
levels: [
{ level: 1, threshold: 20, scoreBonus: 50, title: t("hl_title_CritMaster_1"), desc: t("hl_desc_CritMaster", 20) },
{ level: 2, threshold: 40, scoreBonus: 100, title: t("hl_title_CritMaster_2"), desc: t("hl_desc_CritMaster", 40) },
{ level: 3, threshold: 60, scoreBonus: 150, title: t("hl_title_CritMaster_3"), desc: t("hl_desc_CritMaster", 60) },
{ level: 4, threshold: 80, scoreBonus: 200, title: t("hl_title_CritMaster_4"), desc: t("hl_desc_CritMaster", 80) },
{ level: 5, threshold: 100, scoreBonus: 300, title: t("hl_title_CritMaster_5"), desc: t("hl_desc_CritMaster", 100) },
{ uuid: 9011, level: 1, threshold: 20, scoreBonus: 50, title: "初级暴击者", desc: "暴击20次" },
{ uuid: 9012, level: 2, threshold: 40, scoreBonus: 100, title: "暴击大师", desc: "暴击40次" },
{ uuid: 9013, level: 3, threshold: 60, scoreBonus: 150, title: "致命猎手", desc: "暴击60次" },
{ uuid: 9014, level: 4, threshold: 80, scoreBonus: 200, title: "无情处决", desc: "暴击80次" },
{ uuid: 9015, level: 5, threshold: 100, scoreBonus: 300, title: "刀刀烈火", desc: "暴击100次" },
]
},
[HighlightType.DeathExpert]: {
type: HighlightType.DeathExpert,
icon: "💀",
levels: [
{ level: 1, threshold: 15, scoreBonus: 50, title: t("hl_title_DeathExpert_1"), desc: t("hl_desc_DeathExpert", 15) },
{ level: 2, threshold: 25, scoreBonus: 100, title: t("hl_title_DeathExpert_2"), desc: t("hl_desc_DeathExpert", 25) },
{ level: 3, threshold: 40, scoreBonus: 150, title: t("hl_title_DeathExpert_3"), desc: t("hl_desc_DeathExpert", 40) },
{ level: 4, threshold: 60, scoreBonus: 200, title: t("hl_title_DeathExpert_4"), desc: t("hl_desc_DeathExpert", 60) },
{ level: 5, threshold: 80, scoreBonus: 300, title: t("hl_title_DeathExpert_5"), desc: t("hl_desc_DeathExpert", 80) },
{ uuid: 9021, level: 1, threshold: 15, scoreBonus: 50, title: "不怕死", desc: "死亡触发15次" },
{ uuid: 9022, level: 2, threshold: 25, scoreBonus: 100, title: "送死达人", desc: "死亡触发25次" },
{ uuid: 9023, level: 3, threshold: 40, scoreBonus: 150, title: "亡灵舞者", desc: "死亡触发40次" },
{ uuid: 9024, level: 4, threshold: 60, scoreBonus: 200, title: "向死而生", desc: "死亡触发60次" },
{ uuid: 9025, level: 5, threshold: 80, scoreBonus: 300, title: "不死灾厄", desc: "死亡触发80次" },
]
},
[HighlightType.IronWall]: {
type: HighlightType.IronWall,
icon: "🛡️",
levels: [
{ level: 1, threshold: 15, scoreBonus: 50, title: t("hl_title_IronWall_1"), desc: t("hl_desc_IronWall", 15) },
{ level: 2, threshold: 30, scoreBonus: 100, title: t("hl_title_IronWall_2"), desc: t("hl_desc_IronWall", 30) },
{ level: 3, threshold: 50, scoreBonus: 150, title: t("hl_title_IronWall_3"), desc: t("hl_desc_IronWall", 50) },
{ level: 4, threshold: 70, scoreBonus: 200, title: t("hl_title_IronWall_4"), desc: t("hl_desc_IronWall", 70) },
{ level: 5, threshold: 100, scoreBonus: 300, title: t("hl_title_IronWall_5"), desc: t("hl_desc_IronWall", 100) },
{ uuid: 9031, level: 1, threshold: 15, scoreBonus: 50, title: "坚固盾牌", desc: "格挡15次" },
{ uuid: 9032, level: 2, threshold: 30, scoreBonus: 100, title: "铁壁铜墙", desc: "格挡30次" },
{ uuid: 9033, level: 3, threshold: 50, scoreBonus: 150, title: "叹息之墙", desc: "格挡50次" },
{ uuid: 9034, level: 4, threshold: 70, scoreBonus: 200, title: "不破之阵", desc: "格挡70次" },
{ uuid: 9035, level: 5, threshold: 100, scoreBonus: 300, title: "绝对防御", desc: "格挡100次" },
]
},
[HighlightType.WindStorm]: {
type: HighlightType.WindStorm,
icon: "⚡",
levels: [
{ level: 1, threshold: 10, scoreBonus: 50, title: t("hl_title_WindStorm_1"), desc: t("hl_desc_WindStorm", 10) },
{ level: 2, threshold: 20, scoreBonus: 100, title: t("hl_title_WindStorm_2"), desc: t("hl_desc_WindStorm", 20) },
{ level: 3, threshold: 35, scoreBonus: 150, title: t("hl_title_WindStorm_3"), desc: t("hl_desc_WindStorm", 35) },
{ level: 4, threshold: 50, scoreBonus: 200, title: t("hl_title_WindStorm_4"), desc: t("hl_desc_WindStorm", 50) },
{ level: 5, threshold: 70, scoreBonus: 300, title: t("hl_title_WindStorm_5"), desc: t("hl_desc_WindStorm", 70) },
{ uuid: 9041, level: 1, threshold: 10, scoreBonus: 50, title: "迅捷之风", desc: "风怒10次" },
{ uuid: 9042, level: 2, threshold: 20, scoreBonus: 100, title: "风暴之王", desc: "风怒20次" },
{ uuid: 9043, level: 3, threshold: 35, scoreBonus: 150, title: "狂风骤雨", desc: "风怒35次" },
{ uuid: 9044, level: 4, threshold: 50, scoreBonus: 200, title: "无影之手", desc: "风怒50次" },
{ uuid: 9045, level: 5, threshold: 70, scoreBonus: 300, title: "神速幻影", desc: "风怒70次" },
]
},
[HighlightType.OneHitKill]: {
type: HighlightType.OneHitKill,
icon: "🎯",
levels: [
{ level: 1, threshold: 100, scoreBonus: 50, title: t("hl_title_OneHitKill_1"), desc: t("hl_desc_OneHitKill", 100) },
{ level: 2, threshold: 200, scoreBonus: 100, title: t("hl_title_OneHitKill_2"), desc: t("hl_desc_OneHitKill", 200) },
{ level: 3, threshold: 400, scoreBonus: 150, title: t("hl_title_OneHitKill_3"), desc: t("hl_desc_OneHitKill", 400) },
{ level: 4, threshold: 800, scoreBonus: 200, title: t("hl_title_OneHitKill_4"), desc: t("hl_desc_OneHitKill", 800) },
{ level: 5, threshold: 1500, scoreBonus: 300, title: t("hl_title_OneHitKill_5"), desc: t("hl_desc_OneHitKill", 1500) },
{ uuid: 9051, level: 1, threshold: 100, scoreBonus: 50, title: "重击", desc: "单次伤害100" },
{ uuid: 9052, level: 2, threshold: 200, scoreBonus: 100, title: "一击必杀", desc: "单次伤害200" },
{ uuid: 9053, level: 3, threshold: 400, scoreBonus: 150, title: "毁天灭地", desc: "单次伤害400" },
{ uuid: 9054, level: 4, threshold: 800, scoreBonus: 200, title: "核弹打击", desc: "单次伤害800" },
{ uuid: 9055, level: 5, threshold: 1500, scoreBonus: 300, title: "弑神一击", desc: "单次伤害1500" },
]
},
[HighlightType.HealingLight]: {
type: HighlightType.HealingLight,
icon: "💊",
levels: [
{ level: 1, threshold: 200, scoreBonus: 50, title: t("hl_title_HealingLight_1"), desc: t("hl_desc_HealingLight", 200) },
{ level: 2, threshold: 500, scoreBonus: 100, title: t("hl_title_HealingLight_2"), desc: t("hl_desc_HealingLight", 500) },
{ level: 3, threshold: 1000, scoreBonus: 150, title: t("hl_title_HealingLight_3"), desc: t("hl_desc_HealingLight", 1000) },
{ level: 4, threshold: 2000, scoreBonus: 200, title: t("hl_title_HealingLight_4"), desc: t("hl_desc_HealingLight", 2000) },
{ level: 5, threshold: 4000, scoreBonus: 300, title: t("hl_title_HealingLight_5"), desc: t("hl_desc_HealingLight", 4000) },
{ uuid: 9061, level: 1, threshold: 200, scoreBonus: 50, title: "急救员", desc: "治疗总量200" },
{ uuid: 9062, level: 2, threshold: 500, scoreBonus: 100, title: "治愈之光", desc: "治疗总量500" },
{ uuid: 9063, level: 3, threshold: 1000, scoreBonus: 150, title: "生命之泉", desc: "治疗总量1000" },
{ uuid: 9064, level: 4, threshold: 2000, scoreBonus: 200, title: "起死回生", desc: "治疗总量2000" },
{ uuid: 9065, level: 5, threshold: 4000, scoreBonus: 300, title: "移动泉水", desc: "治疗总量4000" },
]
},
[HighlightType.PerfectClear]: {
type: HighlightType.PerfectClear,
icon: "🏆",
levels: [
{ level: 1, threshold: 1, scoreBonus: 500, title: t("hl_title_PerfectClear_1"), desc: t("hl_desc_PerfectClear") },
{ uuid: 9071, level: 1, threshold: 1, scoreBonus: 500, title: "完美通关", desc: "20回合全胜且全存活" },
]
},
[HighlightType.LuckyKing]: {
type: HighlightType.LuckyKing,
icon: "🎲",
levels: [
{ level: 1, threshold: 0.6, scoreBonus: 50, title: t("hl_title_LuckyKing_1"), desc: t("hl_desc_LuckyKing", 60) },
{ level: 2, threshold: 0.7, scoreBonus: 100, title: t("hl_title_LuckyKing_2"), desc: t("hl_desc_LuckyKing", 70) },
{ level: 3, threshold: 0.8, scoreBonus: 150, title: t("hl_title_LuckyKing_3"), desc: t("hl_desc_LuckyKing", 80) },
{ level: 4, threshold: 0.9, scoreBonus: 200, title: t("hl_title_LuckyKing_4"), desc: t("hl_desc_LuckyKing", 90) },
{ level: 5, threshold: 1.0, scoreBonus: 300, title: t("hl_title_LuckyKing_5"), desc: t("hl_desc_LuckyKing", 100) },
{ uuid: 9081, level: 1, threshold: 0.6, scoreBonus: 50, title: "手气不错", desc: "刷新命中率60%" },
{ uuid: 9082, level: 2, threshold: 0.7, scoreBonus: 100, title: "心想事成", desc: "刷新命中率70%" },
{ uuid: 9083, level: 3, threshold: 0.8, scoreBonus: 150, title: "欧皇附体", desc: "刷新命中率80%" },
{ uuid: 9084, level: 4, threshold: 0.9, scoreBonus: 200, title: "天选之子", desc: "刷新命中率90%" },
{ uuid: 9085, level: 5, threshold: 1.0, scoreBonus: 300, title: "言出法随", desc: "刷新命中率100%" },
]
},
[HighlightType.ThriftyPlayer]: {
type: HighlightType.ThriftyPlayer,
icon: "💰",
levels: [
{ level: 1, threshold: 0.75, scoreBonus: 50, title: t("hl_title_ThriftyPlayer_1"), desc: t("hl_desc_ThriftyPlayer", 75) },
{ level: 2, threshold: 0.85, scoreBonus: 100, title: t("hl_title_ThriftyPlayer_2"), desc: t("hl_desc_ThriftyPlayer", 85) },
{ level: 3, threshold: 0.95, scoreBonus: 150, title: t("hl_title_ThriftyPlayer_3"), desc: t("hl_desc_ThriftyPlayer", 95) },
{ level: 4, threshold: 0.98, scoreBonus: 200, title: t("hl_title_ThriftyPlayer_4"), desc: t("hl_desc_ThriftyPlayer", 98) },
{ level: 5, threshold: 1.00, scoreBonus: 300, title: t("hl_title_ThriftyPlayer_5"), desc: t("hl_desc_ThriftyPlayer", 100) },
{ uuid: 9091, level: 1, threshold: 0.75, scoreBonus: 50, title: "精打细算", desc: "金币使用率75%" },
{ uuid: 9092, level: 2, threshold: 0.85, scoreBonus: 100, title: "勤俭持家", desc: "金币使用率85%" },
{ uuid: 9093, level: 3, threshold: 0.95, scoreBonus: 150, title: "节俭玩家", desc: "金币使用率95%" },
{ uuid: 9094, level: 4, threshold: 0.98, scoreBonus: 200, title: "一毛不拔", desc: "金币使用率98%" },
{ uuid: 9095, level: 5, threshold: 1.00, scoreBonus: 300, title: "理财大师", desc: "金币使用率100%" },
]
}
};