feat(heroBox): 实现当前等级技能描述面板功能
1. 新增SkillDescSet结构化技能描述配置表,实现配置驱动的文案生成 2. 改造HeroSkillDesc生成器,支持静态heroInfo和运行时HeroAttrsComp两种数据源 3. 为HeroAttrsComp新增evolve配置快照字段,用于展示等级成长属性 4. 在HeroBoxComp中集成技能描述UI组件,动态渲染当前英雄等级的技能效果 5. 新增设计文档说明方案细节,确保可维护性和可扩展性
This commit is contained in:
118
docs/superpowers/specs/2026-07-30-herobox-skill-desc-design.md
Normal file
118
docs/superpowers/specs/2026-07-30-herobox-skill-desc-design.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# HeroBox 当前等级技能信息面板设计(方案 B:独立 SkillDescSet 表)
|
||||
|
||||
## 背景与目标
|
||||
|
||||
HeroBoxComp 当前只展示数值属性(AP/HP/暴击/攻速…),没有技能信息区。需要在面板中加入**当前英雄当前等级**的技能描述。
|
||||
|
||||
关键诉求(用户已确认):
|
||||
- 抛弃 `heroSet` 的手写 `infos[]` 文案,改用**结构化字段 + overrides 动态拼描述**,杜绝"数值改了忘改文案"的漂移。
|
||||
- 描述必须反映**运行时当前等级**(evolve 已应用的最终配置),而非 1 级静态配置。
|
||||
- 数据与展示分离,不侵入战斗配置(SkillSet/FieldSkillSet 一行不动)。
|
||||
|
||||
## 现状分析(已验证)
|
||||
|
||||
- `HeroSkillDesc.buildSkillDesc(hero)` 已存在,且**触发框架已通用**:按触发类型遍历 → 查 `SkillSet` → `mergeSkillParams` 合并 overrides → 拼行。
|
||||
- 其 `buildEffectDesc` 按 `SkillKind` 硬编码 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. 生成器入参抽象(兼容两种数据源)
|
||||
|
||||
抽取窄接口,`heroInfo` 与 `HeroAttrsComp` 天然都满足(字段名、结构一致):
|
||||
|
||||
```ts
|
||||
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 用,只覆盖需要描述的触发技能(普攻/怪物技能跳过):
|
||||
|
||||
```ts
|
||||
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}`。
|
||||
|
||||
渲染逻辑(生成器内统一处理):
|
||||
- `target`:TGroup.Self→"自身";Team+hit_count>1→"随机{hit_count}名队友";Team/Ally→"全体友方";Enemy→"敌方"。
|
||||
- 计时判定:合并后 skill 存在 `timed_buff_id` → 用 `templTimed`+`timedField`;否则 `templPerm`+`permField`。
|
||||
- `value`:从合并后 skill 对应字段取值;`dur`:`buff_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[]` 展示。
|
||||
- 普攻技能不做描述。
|
||||
Reference in New Issue
Block a user