feat: 重构卡牌描述渲染系统,实现动态富文本展示

1. 新增SkillDescSet配置商店技能与药水模板,补充6201-6206范围攻击与6502-6511计时强化技能配置
2. 替换原有单/多文本标签为富文本组件,统一使用buildCardDescRich生成描述
3. 简化物品商店与卡牌组件的描述渲染逻辑,移除冗余的getDescription方法
4. 为药水卡片移除硬编码描述,改为从技能模板动态生成,自动高亮数值与持续时间
5. 实现附加概率后缀自动生成,支持暴击/冰冻/击晕/击退概率动态展示
This commit is contained in:
pan
2026-07-31 16:02:47 +08:00
parent f058d02ad9
commit a06c2c0e31
7 changed files with 1480 additions and 1104 deletions

View File

@@ -33,6 +33,7 @@ import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
import { BuffList } from "./BuffSet";
import { Attrs } from "./HeroAttrs";
import { CardConfig } from "./CardSet";
/**
* 生成器入参窄接口:只约束实际读取的字段。
@@ -91,6 +92,9 @@ const RICH_NAME_COLOR = "#2E86C1";
/** 技能名「」匹配模式(仅本模块行首/行中技能名片段使用) */
const SKILL_NAME_PATTERN = /「([^」]*)」/g;
/** "持续X秒"匹配模式(卡片描述后处理:把持续时间数值也高亮) */
const DURATION_PATTERN = /持续(\d+)秒/g;
/** 解析目标描述文本(与战斗 SCastSystem 目标选取语义严格一致) */
function buildTargetDesc(skill: SkillConfig): string {
switch (skill.TGroup) {
@@ -374,3 +378,92 @@ export function buildEquipRich(fieldUuids: number[]): string {
}
return lines.length > 0 ? lines.join("\n") : "无词条";
}
/**
* 把"持续X秒"中的 X 也包裹绿色高亮(卡片描述后处理)。
* Why: 计时模板 {dur} 不在 \x01\x02 高亮标记内renderLineRich 仅高亮主数值;
* 持续时间对药水/计时 buff 同样关键,这里补充高亮,保证视觉一致。
*/
function highlightDuration(text: string): string {
return text.replace(DURATION_PATTERN, `持续<color=${RICH_VALUE_COLOR}>$1</color>秒`);
}
/**
* 结构化行 → 富文本串(技能名蓝色、数值绿色)。
* buildEquipRich / buildCardDescRich 共用,保证渲染规则唯一。
*/
function renderLineRich(line: ISkillLine): string {
const prefix = line.prefix.replace(SKILL_NAME_PATTERN, `「<color=${RICH_NAME_COLOR}>$1</color>」`);
return line.value
? `${prefix}<color=${RICH_VALUE_COLOR}>${line.value}</color>${line.suffix}`
: `${prefix}${line.suffix}`;
}
/**
* 扫描合并后技能的附加概率字段crt/frz/stun/bck非零的拼为高亮后缀。
* Why: 模板不再硬编码"有概率击晕"等文案,由实际配置驱动,避免描述与数值漂移。
* @returns 形如 ",30%击晕,20%冰冻";全为 0 时返回 ""
*/
function buildChanceSuffix(skill: SkillConfig): string {
const items: string[] = [];
const push = (val: number | undefined, label: string) => {
if (val && val > 0) items.push(`附加<color=${RICH_VALUE_COLOR}>${val}</color>%${label}`);
};
push(skill.crt, "暴击");
push(skill.frz, "冰冻");
push(skill.stun, "击晕");
push(skill.bck, "击退");
return items.length > 0 ? `,${items.join(",")}` : "";
}
/**
* 商店卡片描述富文本SCardComp / ItemListComp 用BBCode
*
* Why: 卡片 info 为手写文案,与 SkillSet/BuffList 数值易漂移。
* 本函数从 CardConfig.skill + overrides 合并后的实时配置生成描述,
* 数值随档位(如高级药水 buff_value自动同步数值绿色高亮、技能名蓝色。
*
* 描述规则:
* - 药品/技能卡card.skill 有效)→ 查 SkillDescSet 模板渲染(计时模式取 BuffList 默认值兜底);
* 未入表技能回退 SkillSet.info / card.info整行不高亮。
* - 装备卡card.field 有效)→ 复用 buildEquipRich 逐词条渲染。
* - 触发节奏t_times/t_inv融入单行描述定时触发"每M秒释放一次「技能名」xxx共N次";即时触发仅显示效果。
*
* @param card 卡片配置SCardSet 技能卡 / ICardSet 药品卡 / EquipSet 装备卡)
* @returns 多行富文本串;无可描述内容时回退 card.info
*/
export function buildCardDescRich(card: CardConfig): string {
// 装备卡:逐词条渲染驻场光环
if (card.field && card.field.length > 0) {
return buildEquipRich(card.field);
}
// 药品/技能卡:合并覆写后按 SkillDescSet 模板渲染
const base = card.skill ? SkillSet[card.skill] : undefined;
if (base) {
const skill = mergeSkillParams(base, card.overrides);
const line = buildEffectLine("", skill);
// 未入表技能回退链SkillSet.info → card.info
if (!line.value && !SkillDescSet[skill.uuid]) {
return String(skill.info || card.info || "");
}
// 触发节奏融入描述:定时触发"每M秒释放一次「技能名」xxx共N次";即时触发直接描述
const tTimes = card.t_times ?? 1;
const tInv = card.t_inv ?? 0;
const isInstant = card.is_inst || tInv <= 0;
// 附加概率后缀(暴击/冰冻/击晕/击退),由实际配置驱动
const suffix = buildChanceSuffix(skill);
const rich = highlightDuration(renderLineRich(line)) + suffix;
if (isInstant) {
return rich;
}
const rhythm = `每<color=${RICH_VALUE_COLOR}>${tInv}</color>秒释放一次「<color=${RICH_NAME_COLOR}>${skill.name}</color>」`;
const times = `,共<color=${RICH_VALUE_COLOR}>${tTimes}</color>次`;
return `${rhythm}${rich}${times}`;
}
return card.info || "";
}

View File

@@ -33,24 +33,24 @@ interface ItemCardRaw {
const ItemCardData: ItemCardRaw[] = [
// ==================== 一次性回血(计时性 HoT5s ====================
{ uuid: 9101, skill: 6502, icon: "Sub_Item-FA_WP_Sub_Potion_001_Green", name: "再生药水", info: "全体友方每秒回复生命,持续 5 秒", cost: 0, weight: 20 },
{ uuid: 9101, skill: 6502, icon: "Sub_Item-FA_WP_Sub_Potion_001_Green", name: "再生药水", info: "全体友方持续回复生命", cost: 0, weight: 20 },
// ==================== 计时性强化(统一 5s ====================
{ uuid: 9102, skill: 6503, icon: "Sub_Item-FA_WP_Sub_Potion_001_Red", name: "攻击药水", info: "全体友方攻击力提升 50%,持续 5 秒", cost: 0, weight: 15 },
{ uuid: 9103, skill: 6504, icon: "Sub_Item-FA_WP_Sub_Potion_001_Yellow", name: "暴击药水", info: "全体友方暴击率提升 30%,持续 5 秒", cost: 0, weight: 15 },
{ uuid: 9104, skill: 6505, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "击退药水", info: "全体友方击退概率提升 30%,持续 5 秒", cost: 0, weight: 12 },
{ uuid: 9105, skill: 6506, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "穿透药水", info: "全体友方穿透概率提升 30%,持续 5 秒", cost: 0, weight: 12 },
{ uuid: 9106, skill: 6507, icon: "Sub_Item-FA_WP_Sub_Potion_001_Red", name: "攻速药水", info: "全体友方攻击速度提升 40%,持续 5 秒", cost: 0, weight: 15 },
{ uuid: 9107, skill: 6508, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "风怒药水", info: "全体友方风怒概率提升 20%,持续 5 秒", cost: 0, weight: 12 },
{ uuid: 9108, skill: 6509, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "击晕药水", info: "全体友方击晕概率提升 30%,持续 5 秒", cost: 0, weight: 12 },
{ uuid: 9109, skill: 6510, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "击晕抗性药水", info: "全体友方击晕抗性提升 50%,持续 5 秒", cost: 4, weight: 10 },
{ uuid: 9110, skill: 6511, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "冰冻抗性药水", info: "全体友方冰冻抗性提升 50%,持续 5 秒", cost: 4, weight: 10 },
{ uuid: 9102, skill: 6503, icon: "Sub_Item-FA_WP_Sub_Potion_001_Red", name: "攻击药水", info: "全体友方攻击力提升", cost: 0, weight: 15 },
{ uuid: 9103, skill: 6504, icon: "Sub_Item-FA_WP_Sub_Potion_001_Yellow", name: "暴击药水", info: "全体友方暴击率提升", cost: 0, weight: 15 },
{ uuid: 9104, skill: 6505, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "击退药水", info: "全体友方击退概率提升", cost: 0, weight: 12 },
{ uuid: 9105, skill: 6506, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "穿透药水", info: "全体友方穿透概率提升", cost: 0, weight: 12 },
{ uuid: 9106, skill: 6507, icon: "Sub_Item-FA_WP_Sub_Potion_001_Red", name: "攻速药水", info: "全体友方攻击速度提升", cost: 0, weight: 15 },
{ uuid: 9107, skill: 6508, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "风怒药水", info: "全体友方风怒概率提升", cost: 0, weight: 12 },
{ uuid: 9108, skill: 6509, icon: "Sub_Item-FA_WP_Sub_Potion_001_Purple", name: "击晕药水", info: "全体友方击晕概率提升", cost: 0, weight: 12 },
{ uuid: 9109, skill: 6510, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "击晕抗性药水", info: "全体友方击晕抗性提升", cost: 4, weight: 10 },
{ uuid: 9110, skill: 6511, icon: "Sub_Item-FA_WP_Sub_Potion_001_Blue", name: "冰冻抗性药水", info: "全体友方冰冻抗性提升", cost: 4, weight: 10 },
// ==================== 高级档buff_value 覆写,复用同一技能底座) ====================
{ uuid: 9201, skill: 6502, icon: "Sub_Item-FA_WP_Sub_Potion_002_Green", name: "高级再生药水", info: "全体友方每秒回复 25 生命,持续 5 秒", cost: 0, weight: 8, overrides: { buff_value: 25 } },
{ uuid: 9202, skill: 6503, icon: "Sub_Item-FA_WP_Sub_Potion_002_Red", name: "高级攻击药水", info: "全体友方攻击力提升 80%,持续 5 秒", cost: 0, weight: 8, overrides: { buff_value: 80 } },
{ uuid: 9203, skill: 6504, icon: "Sub_Item-FA_WP_Sub_Potion_002_Yellow", name: "高级暴击药水", info: "全体友方暴击率提升 50%,持续 5 秒", cost: 0, weight: 8, overrides: { buff_value: 50 } },
{ uuid: 9206, skill: 6507, icon: "Sub_Item-FA_WP_Sub_Potion_002_Red", name: "高级攻速药水", info: "全体友方攻击速度提升 70%,持续 5 秒", cost: 0, weight: 8, overrides: { buff_value: 70 } },
{ uuid: 9201, skill: 6502, icon: "Sub_Item-FA_WP_Sub_Potion_002_Green", name: "高级再生药水", info: "全体友方持续回复生命", cost: 0, weight: 8, overrides: { buff_value: 25 } },
{ uuid: 9202, skill: 6503, icon: "Sub_Item-FA_WP_Sub_Potion_002_Red", name: "高级攻击药水", info: "全体友方攻击力提升", cost: 0, weight: 8, overrides: { buff_value: 80 } },
{ uuid: 9203, skill: 6504, icon: "Sub_Item-FA_WP_Sub_Potion_002_Yellow", name: "高级暴击药水", info: "全体友方暴击率提升", cost: 0, weight: 8, overrides: { buff_value: 50 } },
{ uuid: 9206, skill: 6507, icon: "Sub_Item-FA_WP_Sub_Potion_002_Red", name: "高级攻速药水", info: "全体友方攻击速度提升", cost: 0, weight: 8, overrides: { buff_value: 70 } },
];
/**

View File

@@ -99,6 +99,86 @@ export const SkillDescSet: Record<number, SkillDescConfig> = {
verb: "", unit: "", permField: "ap",
templPerm: "{target}以{value}%生命复活",
},
// ==================== 技能商店范围攻击卡6201-6206ap = 单段伤害 ====================
// 注:暴击/冰冻/击晕/击退等附加概率由 buildCardDescRich 扫描 crt/frz/stun/bck 动态追加,不在模板写死
6201: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
6202: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
6203: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
6204: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
6205: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
6206: {
verb: "", unit: "", permField: "ap",
templPerm: "每段造成{value}点伤害",
},
// ==================== 计时性强化技能6502-6511药水底座走 timed_buff_id ====================
// 数值取自 BuffList 默认修饰值或药水卡 overrides.buff_value持续时间取 BuffList.duration
6502: {
verb: "", unit: "", permField: "ap", timedField: "buff_value",
templPerm: "{target}回复生命",
templTimed: "{target}每秒回复{value}点生命,持续{dur}秒",
},
6503: {
verb: "攻击力提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6504: {
verb: "暴击率提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6505: {
verb: "击退概率提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6506: {
verb: "穿透概率提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6507: {
verb: "攻击速度提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6508: {
verb: "风怒概率提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6509: {
verb: "击晕概率提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6510: {
verb: "击晕抗性提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
6511: {
verb: "冰冻抗性提升", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}{value}{unit}",
templTimed: "{target}{verb}{value}{unit},持续{dur}秒",
},
};
/**