refactor(field): 重构驻场光环数据结构,分离元数据与数值
1. 新增FieldEntry类型,将驻场词条的uuid与生效数值分离 2. 重构FieldSkillSet,移除各档位重复配置,仅保留基础元数据 3. 更新所有使用驻场词条的业务代码,适配新的数据结构 4. 修复数值渲染逻辑,使用词条携带的实际数值而非配置固化值
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file HeroSkillDesc.ts
|
||||
* @description 英雄技能/能力描述的【唯一文字表达标准层】
|
||||
*
|
||||
@@ -28,7 +28,7 @@
|
||||
* - SkillDescSet:结构化描述模板
|
||||
* - FieldSkillSet(驻场技能)、BuffList(计时 buff 默认值兜底)、Attrs(属性枚举)
|
||||
*/
|
||||
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, getTriggerSkillName, HGrowType, calcGrowBonus } from "./heroSet";
|
||||
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, FieldEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv, getTriggerSkillName, HGrowType, calcGrowBonus } from "./heroSet";
|
||||
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
|
||||
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
|
||||
import { BuffList } from "./BuffSet";
|
||||
@@ -242,26 +242,26 @@ function buildEffectLine(head: string, skill: SkillConfig): ISkillLine {
|
||||
* @param showName 是否在行中包含「技能名」片段(英雄面板需要,装备商店不需要)
|
||||
* @param nameOverride 技能名覆盖(英雄语境传入 heroSet 语境专属命名,缺省用 FieldSkillSet 通用名)
|
||||
*/
|
||||
function buildFieldLine(head: string, uuid: number, showName: boolean = true, nameOverride?: string): ISkillLine | null {
|
||||
const fs = FieldSkillSet[uuid];
|
||||
function buildFieldLine(head: string, entry: FieldEntry, showName: boolean = true, nameOverride?: string): ISkillLine | null {
|
||||
const fs = FieldSkillSet[entry.uuid];
|
||||
if (!fs) return null;
|
||||
const desc = FieldDescSet[fs.type];
|
||||
const nameSeg = showName ? `「${nameOverride ?? fs.name}」 ` : "";
|
||||
// 未入表类型回退基础备注 info,整行不高亮
|
||||
if (!desc) return { prefix: `${head}${nameSeg}${fs.info}`, value: "", suffix: "" };
|
||||
|
||||
// 数值按格式渲染为高亮片段
|
||||
// 数值按格式渲染为高亮片段(数值取自词条自身 value)
|
||||
let valueText: string;
|
||||
switch (desc.fmt) {
|
||||
case FieldValueFmt.Percent:
|
||||
valueText = `+${Math.round(fs.value * 100)}%`;
|
||||
valueText = `+${Math.round(entry.value * 100)}%`;
|
||||
break;
|
||||
case FieldValueFmt.IntMinus:
|
||||
valueText = `-${fs.value}`;
|
||||
valueText = `-${entry.value}`;
|
||||
break;
|
||||
case FieldValueFmt.Int:
|
||||
default:
|
||||
valueText = `+${fs.value}`;
|
||||
valueText = `+${entry.value}`;
|
||||
break;
|
||||
}
|
||||
return { prefix: `${head}${nameSeg}${desc.verb}`, value: valueText, suffix: "" };
|
||||
@@ -433,8 +433,8 @@ function buildSkillLines(source: ISkillDescSource, showName: boolean = true, sho
|
||||
if (fieldEntries?.length) {
|
||||
const tpl = SkillTriggerName[SkillTriggerType.Field] ?? "光环";
|
||||
if (!showLocked) {
|
||||
for (const uuid of resolveFieldByLv(fieldEntries, lv)) {
|
||||
const line = buildFieldLine(`${tpl}:`, uuid, showName);
|
||||
for (const entry of resolveFieldByLv(fieldEntries, lv)) {
|
||||
const line = buildFieldLine(`${tpl}:`, entry, showName);
|
||||
if (line) lines.push(line);
|
||||
}
|
||||
} else {
|
||||
@@ -444,15 +444,15 @@ function buildSkillLines(source: ISkillDescSource, showName: boolean = true, sho
|
||||
let activeTier: LvFieldEntry | undefined;
|
||||
for (const tier of sorted) { if (tier.lv <= lv) activeTier = tier; }
|
||||
if (activeTier) {
|
||||
for (const uuid of activeTier.uuids) {
|
||||
const line = buildFieldLine(`Lv${activeTier.lv}: ${tpl} `, uuid, showName);
|
||||
for (const entry of activeTier.uuids) {
|
||||
const line = buildFieldLine(`Lv${activeTier.lv}: ${tpl} `, entry, showName);
|
||||
if (line) lines.push(line);
|
||||
}
|
||||
}
|
||||
for (const tier of sorted) {
|
||||
if (tier.lv <= lv) continue;
|
||||
for (const uuid of tier.uuids) {
|
||||
const line = buildFieldLine(`Lv${tier.lv}: ${tpl} `, uuid, showName);
|
||||
for (const entry of tier.uuids) {
|
||||
const line = buildFieldLine(`Lv${tier.lv}: ${tpl} `, entry, showName);
|
||||
if (!line) continue;
|
||||
line.locked = true;
|
||||
lines.push(line);
|
||||
@@ -525,15 +525,15 @@ export function buildSingleSkillRich(skillUuid: number, overrides?: SkillOverrid
|
||||
|
||||
/**
|
||||
* 装备/驻场光环详情富文本:展示全部词条,数值绿色高亮。
|
||||
* @param fieldUuids FieldSkillSet 驻场光环 UUID 数组
|
||||
* @param showName 是否包含「技能名」片段(英雄面板 true,装备商店 false)
|
||||
* @returns 多行富文本串,每行一个词条
|
||||
* @param entries 驻场光环词条数组(uuid 指向 FieldSkillSet 底座,value 为生效数值)
|
||||
* @param showName 是否包含「技能名」片段(英雄面板 true,装备商店 false)
|
||||
* @returns 多行富文本串,每行一个词条
|
||||
*/
|
||||
export function buildEquipRich(fieldUuids: number[], showName: boolean = false): string {
|
||||
if (!fieldUuids?.length) return "无词条";
|
||||
export function buildEquipRich(entries: FieldEntry[], showName: boolean = false): string {
|
||||
if (!entries?.length) return "无词条";
|
||||
const lines: string[] = [];
|
||||
for (const uuid of fieldUuids) {
|
||||
const line = buildFieldLine("", uuid, showName);
|
||||
for (const entry of entries) {
|
||||
const line = buildFieldLine("", entry, showName);
|
||||
if (!line) continue;
|
||||
const prefix = line.prefix.replace(SKILL_NAME_PATTERN, (m, g1) => skillNameRich(g1));
|
||||
const text = line.value
|
||||
@@ -604,14 +604,18 @@ export function buildSkillDescMoreRich(source: ISkillDescSource): string {
|
||||
}
|
||||
}
|
||||
|
||||
// 驻场光环(field):技能名按档位带数字后缀(如 [攻击光环1]/[攻击光环2]),便于玩家识别成长
|
||||
// 驻场光环(field):技能名带档位数字后缀(按 lv 档升序,1 起始),便于玩家识别成长
|
||||
const fieldEntries = source[SkillTriggerType.Field] as LvFieldEntry[] | undefined;
|
||||
if (fieldEntries?.length) {
|
||||
for (const uuid of resolveFieldByLv(fieldEntries, lv)) {
|
||||
// uuid 百位编码档位:7002 基础(0)=1、7202 +(2)=2、7402 ++(4)=3
|
||||
const tier = Math.floor((uuid % 1000) / 100) / 2 + 1;
|
||||
const baseName = getTriggerSkillName(SkillTriggerType.Field, uuid);
|
||||
const line = buildFieldLine("", uuid, true, `${baseName}${tier}`);
|
||||
// 按 lv 升序确定当前生效档的序号(1 起始),作为技能名后缀
|
||||
const sorted = [...fieldEntries].sort((a, b) => a.lv - b.lv);
|
||||
let tier = 1;
|
||||
for (let i = 0; i < sorted.length; i++) {
|
||||
if (sorted[i].lv <= lv) tier = i + 1;
|
||||
}
|
||||
for (const entry of resolveFieldByLv(fieldEntries, lv)) {
|
||||
const baseName = getTriggerSkillName(SkillTriggerType.Field, entry.uuid);
|
||||
const line = buildFieldLine("", entry, true, `${baseName}${tier}`);
|
||||
if (line) lines.push(effectRich(line));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user