Files
pixelheros/docs/superpowers/specs/2026-07-30-herobox-skill-desc-design.md
panFD 04f39217ac feat(heroBox): 实现当前等级技能描述面板功能
1. 新增SkillDescSet结构化技能描述配置表,实现配置驱动的文案生成
2. 改造HeroSkillDesc生成器,支持静态heroInfo和运行时HeroAttrsComp两种数据源
3. 为HeroAttrsComp新增evolve配置快照字段,用于展示等级成长属性
4. 在HeroBoxComp中集成技能描述UI组件,动态渲染当前英雄等级的技能效果
5. 新增设计文档说明方案细节,确保可维护性和可扩展性
2026-07-30 22:30:26 +08:00

5.9 KiB
Raw Blame History

HeroBox 当前等级技能信息面板设计(方案 B独立 SkillDescSet 表)

背景与目标

HeroBoxComp 当前只展示数值属性AP/HP/暴击/攻速…),没有技能信息区。需要在面板中加入当前英雄当前等级的技能描述。

关键诉求(用户已确认):

  • 抛弃 heroSet 的手写 infos[] 文案,改用结构化字段 + overrides 动态拼描述,杜绝"数值改了忘改文案"的漂移。
  • 描述必须反映运行时当前等级evolve 已应用的最终配置),而非 1 级静态配置。
  • 数据与展示分离不侵入战斗配置SkillSet/FieldSkillSet 一行不动)。

现状分析(已验证)

  • HeroSkillDesc.buildSkillDesc(hero) 已存在,且触发框架已通用:按触发类型遍历 → 查 SkillSetmergeSkillParams 合并 overrides → 拼行。
  • buildEffectDescSkillKind 硬编码 if-else且 Support 类直接复用 skill.info 写死的数值文案 → 这是唯一不通用的点,也是漂移根因
  • HeroAttrsComp 运行时持有应用 evolve 后的当前等级最终触发配置Hero.ts 中 base → 逐级 evolve 覆盖),字段结构与 heroInfo 完全一致。
  • buildSkillDesc 现有 2 个调用方HersListComp:205、HInfoComp:448都传静态 heroInfo(卡池/商店场景,无运行时 model签名不能粗暴改成只收 model

方案 B 总体形态

三层都通用,纯配置驱动:

  1. 触发框架:不动(已通用)。
  2. 技能数值不动SkillSet + overrides
  3. 效果文案:新增 SkillDescSet 独立表,把硬编码 if-else 变成"结构化配置 + 占位符模板"。

结果:buildSkillDesc(source) 成为纯渲染器。新增英雄 = 纯配置,零代码;新增技能 = 补一行 SkillDescSet 配置。

设计细节

1. 生成器入参抽象(兼容两种数据源)

抽取窄接口,heroInfoHeroAttrsComp 天然都满足(字段名、结构一致):

export interface ISkillDescSource {
    call?:     { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    dead?:     { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    fstart?:   { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    fend?:     { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    atking?:   { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    atked?:    { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
    field?:    number[];
    revive?:   { s_uuid: number; r_num: number; upr: number };
}
// buildSkillDesc(source: ISkillDescSource): string
  • HeroBoxComp 传 this.model → 显示当前等级。
  • 卡池/商店传 heroInfo → 显示 1 级(无 model 场景),老调用方零改动。

2. SkillDescSet 结构化描述表(核心)

新文件 assets/script/game/common/config/SkillDescSet.ts,与 SkillSet 同 key、纯 UI 用,只覆盖需要描述的触发技能(普攻/怪物技能跳过):

export interface SkillDescConfig {
    /** 效果动词,如 "攻击力"/"暴击率"/"护盾" */
    verb: string;
    /** 单位,如 ""/"%"/"次" */
    unit: string;
    /** 永久模式取值字段overrides 直接改写),通常 "ap" */
    permField: keyof SkillOverrides;
    /** 计时模式取值字段overrides 走 timed_buff_id通常 "buff_value" */
    timedField?: keyof SkillOverrides;
    /** 永久模式文案模板 */
    templPerm: string;
    /** 计时模式文案模板(含 {dur}),不填则该技能不支持计时模式 */
    templTimed?: string;
}

模板占位符:{target} {value} {unit} {verb} {dur}

渲染逻辑(生成器内统一处理):

  • targetTGroup.Self→"自身"Team+hit_count>1→"随机{hit_count}名队友"Team/Ally→"全体友方"Enemy→"敌方"。
  • 计时判定:合并后 skill 存在 timed_buff_id → 用 templTimed+timedField;否则 templPerm+permField
  • value:从合并后 skill 对应字段取值;durbuff_duration 值。
  • 查不到 SkillDescSet 条目 → 回退旧 skill.info(保证未迁移技能不报错、渐进迁移)。

3. HeroSkillDesc 改造

  • 入参从 heroInfo 改为 ISkillDescSource
  • 删除 buildEffectDesc 的 SkillKind 硬编码分支,改为查 SkillDescSet[uuid] 渲染。
  • field(驻场)继续直接读 FieldSkillSet[uuid].info(已结构化 type+value无需改造
  • revive 用 6501 的模板渲染复活血量百分比。

4. HeroBoxComp 集成 + 迁移范围

HeroBoxComp 改动

  • 新增 @property(Label) 技能描述节点(单 Label 多行,与 HInfoComp 一致;放属性栏下方)。
  • refresh() 追加:skill_label.string = buildSkillDesc(this.model)
  • applyEmpty() 清空该 label。
  • 展示范围仅触发技能atking/atked/dead/fstart/fend/field/revive。普攻不展示——AP/攻速已由数值栏体现,触发技能才是英雄身份核心。

迁移范围(首批)

  • SkillDescSet 首批覆盖现役英雄涉及的 ~10 个触发技能6301/6302/6401/6402/6403/6404/6405/6501 + fstart 用的 7111计时
  • infos[] 字段保留但不再在面板使用(卡池/详情页后续统一迁移,本次不动)。

UI 取向(默认,可覆盖)

  • 格式:单个多行 Label最省改动与 HInfoComp 一致)。
  • 范围:仅触发技能,不含普攻。

涉及文件

文件 动作
assets/script/game/common/config/SkillDescSet.ts 新建
assets/script/game/common/config/HeroSkillDesc.ts 改造(入参抽象 + 查表渲染)
assets/script/game/map/HeroBoxComp.ts 集成技能描述 Label

非目标YAGNI

  • 不改造 SkillSet/FieldSkillSet 结构。
  • 不做图标/富文本富 UI本次纯文本
  • 不迁移卡池/详情页的 infos[] 展示。
  • 普攻技能不做描述。