You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/docs/方案-战斗表现数据驱动.md

142 lines
12 KiB

3 weeks ago
# 方案:战斗表现数据驱动
> 状态:落地中
> 日期:2026-08-31
> 关联:[方案-战斗技能逻辑层.md](./方案-战斗技能逻辑层.md)、[`assets/script/battle/docs/需求说明.md`](../assets/script/battle/docs/需求说明.md)
## 1. 目标
普攻 / 英雄主动 / 武器主动均为 **Skill 表** 条目(仅归属槽不同)。表现按 `Skill.atk_type` 统一播控;Hero / Weapon 只提供外形与动画通道。策划改 `atk_id` / `act_skill` / `Weapon.act_skill` 即可改效果与表现。
局外按 `Hero.weapon` ↔ `Weapon.type` 限制装备;战斗侧不写死装备规则。
## 2. 配表与三槽
```
Hero.atk_id[level-1] → Skill.id (普攻)
Hero.act_skill[level-1] → Skill.id (英雄主动,可空)
Weapon.act_skill → Skill.id (武器技能,可空)
```
逻辑构建见 [方案-战斗技能逻辑层.md](./方案-战斗技能逻辑层.md)。
## 3. 正交维度
| 维度 | 来源 | 决定 |
|------|------|------|
| skillKind | 槽位 `normal` / `hero` / `weapon` | Ability id、触发、cue |
| atk_type | Skill 行 | 索敌(逻辑)+ 表现如何对齐 `hit()` |
| 视觉通道 | HeroSkin / HeroWeaponMount | 播哪套 Spine;**不改变** atk_type |
`Skill.type` 多用于主动/被动语义;普攻触发以 **槽位=normal → OnTick** 为准,勿与表行 `type` 混淆。
## 4. 表现管线
```
PlayPresentation cue
→ SkillController.onAttack / onSkill / onWeaponSkill
→ SkillPresenterRouter.dispatch(ctx)
→ skillId 特殊注册?
→ 否则 atk_type 通用 Presenter
→ 否则 warn + 纯逻辑 hit/finish
```
### 4.1 必读 params
`skillId`、`skillKind`、`atkType` / `atkTypeHead`、`atkPara`、`animation`、`fly`、`showeffect`、`composeLevel`、`weaponId`、`heroId`、目标快照。
### 4.2 视觉通道
| 通道 | 条件 | 职责 |
|------|------|------|
| 字形 | 所有英雄 | 播「攻击」 |
| 武器 | 组合英雄且有 weaponId | 激活后常驻挂 `weaponType*`(首字格中心偏左);攻击跟播 `Skill.animation`(缺省「攻击」);**字形与武器都播完才 finish**。弓:藏 `weaponType4`,显 `武器弓-攻击` 播「攻击」,拉满发射「投掷物」;`拉弓动画` 与 `投掷物/anim` 皮肤=当前 `Weapon.skin`。玉帝飞剑:不播原武器攻击,直接隐藏,飞剑播预制体默认「玉帝普攻」。**主动技能(hero/weapon)动画倍速固定 1;普攻跟攻速**。悟空主动 `Skill.animation=悟空技能`:武器不瞄准,沿组合两字包围盒中心椭圆绕一圈(长半径=挂点 X 到中心,短半径=半格,时长=该动画时长-0.2s) |
### 4.3 atk_type 通用
| atk_type | 表现 |
|----------|------|
| 1 / 3 / 6 / 7 / 15 | 通道播动画 → drain hit(15:逻辑已锁主目标圆内目标) |
2 weeks ago
| 2 / 5 / 14 / 16 | 朝向 + 动画(5 直线多段、14 为 360° 圈内多段 hit、16 扇形多段 hit) |
3 weeks ago
| 10 | 连砸:开战锁最多 N 个;每次独立克隆武器播 `Skill.animation`,砸出帧起按间隔 `hit()` |
| 4 | 弓「箭」抛物线;非弓隐藏原武器且不播原武器攻击,飞「玉帝飞剑」(皮肤=Weapon.skin,动画=「玉帝普攻」,朝向切线);不读 Skill.fly;**伤害对齐箭/飞剑落地**(出弦不扣血;落地后动画结束不得再 drain,避免近距两段伤) |
| 12 | 直线散射穿透:中线对准目标,左右按夹角扇出;飞距=射程×2 |
2 weeks ago
| 17 | 散射扇出同 12;不穿透,首中即结算并回收表现箭(`launchScatterArrows`) |
3 weeks ago
| 13 | 连发:锁首发目标,间隔再射,落地才伤;中直线 / 左外弯 / 右外弯三弹道循环 |
| 8 / 11 | 武器按待机角播 `Skill.animation` 后 hit → `SummonFromSkill`;`atk_para` 第 4 段 1=施法处出现后跳入进路 / 2=自身周围 |
未实现 type:`console.warn` + 逻辑结算。
### 4.4 特殊覆盖
仅按 **skillId** 注册。禁止按 heroId 绑整套技能流程。
`Skill.skill` 额外效果头优先于 `atk_type`(见 [方案-Skill额外效果.md](./方案-Skill额外效果.md))。type 1 哪吒冲锋由 `NezhaChargePresenter` 播控。玲珑宝塔 `Skill.id=20509`:主目标处播 `prefab/skill/宝塔` 的「宝塔砸地技能2」,播完回池;命中与施法锁仍走 atk_type=3(武器通道 `宝塔砸地技能1`)。
2 weeks ago
例外:`atk_type=16` 注册 `FanMultiHitAtkPresenter`(覆盖内置)——宿主为 `Gun`(棍)时播「英雄棍-攻击」攻效(`Gun.presentFanMultiHit`,按段间隔逐段 hit);其余宿主走通用多段表现。棍普攻 skill id 已不再固定(Hero 3 现指 100003),无法按 skillId 注册。
例外:`atk_type` 12/17 注册 `BowScatterAtkPresenter`(覆盖内置)——宿主为 `Gong`(弓字形塔,未挂武器通道)时委托 `Gong.presentScatterAttack`,用自身「英雄弓-攻击/投掷物」扇出直线箭;其余宿主走通用 `launchScatterArrows`。
棍环形刀光 `Skill.id=200005` 注册 `GunRingAtkPresenter`:宿主为 `Gun` 时播「英雄棍-攻击/攻击2」攻效,攻效开播延迟 0.5s 后从字的位置逆时针链式发射龙影(`prefab/skill/棍`,上一支飞出 200px 发下一支);数量=360/角度间隔 均分整圆(起始角/角度间隔为代码约定 `RING_START_DEG`/`RING_STEP_DEG`,上限 18),伤害系数取 `atk_para` 第 3 段;龙影走体盒弹道,首中即结算消耗,无怪飞满距离消失;`atk_type` 保留 14 多段配置但表现不 drain 延迟段(无双伤),伤害全在弹道;攻效播完即收招(不等字形攻击动画)。其余宿主逻辑结算。
3 weeks ago
## 5. 代码位置
| 模块 | 路径 |
|------|------|
| Router / Presenter | `assets/script/battle/presentation/` |
| 视觉通道 | 同上 `SkillVisualChannel` |
| 英雄壳 | `HeroActor` 统一;仅枪/棍/弓为子类(节点结构特殊),表现按 **skillId** 注册。成将格:`heroTemplate` 盖住该格才藏 `textGrid.skin`;未盖住仍显示单字。营是无攻击功能字,不进 `heroTemplate`,由 `TextGrid` 挂 `营.prefab`。背包重建不得 `setData` 地图格;单格升级/落子只写绑定期变化的槽/格。`setData` 会拆营并重置英雄对账,已绑定则禁止再调。地图交换飞行用透明度藏起落点两侧 HeroActor(不关节点,弓 onDisable 会拆表现且不回待机),留下的字格开皮。**一格一块 TextGrid**:已占格禁止 spawn/挂入;真身在飞禁止按 session 再造一块;合成飞入不挂到目标格,留下格上真身、材料回池 |
| 英雄品质框 | 组合英雄预制体节点 `品质框`;`HeroSkin` 按 `Hero.quality` 加载 `battleGame/texture/英雄品质_{n}`。已去掉地图层 Graphics 绘制框 |
| 预兆特效 | `Skill.showeffect`:释放后延迟 `x` 秒,在组合两字中间(英雄坐标,`getCompositionWorldCenter`)播 `prefab/skill/{名}` 默认动画;**起播后 `PRES_HIT_AT_BASE`(0.33s)施加命中 / atk_buff / extra 3/4/6**(`召唤哮天犬` 等播完再施加),动画继续播完再停 1 秒回池。无配置则仍按 `PRES_HIT_AT_BASE` 命中 |
| 武器挂载 | `view/HeroWeaponMount.ts` |
特殊 skillId 注册见 `SpecialSkillPresenters.ts`(枪戳刺、弓拉弦、玲珑宝塔砸地)。
## 6. 验收
- 只改 `Hero.atk_id[i]` → 普攻形态/动画/buff 随 Skill 变
- 只改 `Hero.act_skill[i]` / `Weapon.act_skill` → 主动随表变
- 合成等级切换后 Ability 重建;共享 `ability_norm_*` 无串台
- Presenter 纯 `ctx` 驱动,无单例脏状态
## 7. 修订记录
| 日期 | 说明 |
|------|------|
| 2026-08-31 | 初版:三槽同一 Skill、skillKind⊥atk_type、视觉通道 |
| 2026-08-31 | 全表英雄 HeroActor;枪/弓/阎王/李靖仅子类 + skillId Presenter |
| 2026-09-02 | atk_type=4 投掷物改为弓「箭」,不读 Skill.fly |
| 2026-09-02 | atk_type=12/13:散射穿透与连发落地伤 |
| 2026-09-02 | 组合英雄预制体 `品质框` 按 Hero.quality 动态换图 |
| 2026-09-02 | 去掉地图层 Graphics 组合品质框(ComposedUnitFrame*) |
| 2026-09-02 | Skill.showeffect 预兆特效 |
| 2026-09-03 | Skill.skill type 1 哪吒反向冲锋 |
| 2026-09-04 | 玲珑宝塔 20509:目标处播宝塔砸地技能2 |
| 2026-09-04 | 跟随武器释放:字形与武器都播完才 finish(玉帝普攻 0.5s 不再掐断字形攻击 1s) |
| 2026-09-04 | atk_type=4 非弓:隐藏原武器且不播原武器攻击,飞「玉帝飞剑」(皮肤=当前武器,动画=玉帝普攻,朝向切线) |
| 2026-09-04 | 去掉老项目李靖砸塔/召唤;李靖走通用 HeroActor,塔仅为玲珑宝塔武器 20509 |
| 2026-09-04 | 去掉老项目阎王锁链/牢笼;阎王走通用 HeroActor,主动走 atk_type 7 + extra type 4 |
| 2026-09-07 | Skill.showeffect:预兆起播后 0.33s 施加命中与额外效果(阎王生死簿、悟空定身术等) |
| 2026-09-07 | Skill.showeffect 挂点改为组合第一个字格(不再用组合中心上方) |
| 2026-09-07 | atk_type=14:360° 范围多段伤害(定身术 10116~10118) |
| 2026-09-08 | atk_type=15:目标圆形(奔波儿灞 30105) |
| 2026-09-09 | atk_type=10:最近 N 个(如意金箍棒 20501)走瞬时通道播 `Skill.animation` |
| 2026-09-11 | atk_type=10:改为连砸(次数,间隔秒,伤害万分比);金箍棒技能只播一次,砸出帧对齐命中 |
| 2026-09-11 | atk_type=10:每次砸单独 `getNode` 武器实例,原武器隐藏至全部实例结束 |
| 2026-09-12 | atk_type=10:从原武器拉伸瞄准;按砸出帧 `击中光` 距离拉到目标,避免远处伸不到 |
| 2026-09-09 | Skill.showeffect 挂点改为组合两字中间(英雄坐标,与技能名飘字一致) |
| 2026-09-10 | 悟空主动「悟空技能」:武器沿组合两字椭圆绕一圈(长半径=挂点X到组合中心,短半径=半格,时长=动画时长-0.2s);多段 hit 不得早于动画 finish,绕圈未完不收招 |
| 2026-09-11 | 杨戬 atk_type=8 类型1:`召唤哮天犬` 播完后在预兆点上偏 45px 出现,0→0.5 再停 1s 跳入横向进路(无则用出怪口跳跃落点),停顿+跳跃放到 1 倍 |
| 2026-09-11 | 成将格 ensureBagGlyphVisible 不对账外强行开皮;地图交换飞行藏两侧 HeroActor,留下的字格开皮 |
| 2026-09-11 | 交换飞行藏 HeroActor 改透明度,不关 `node.active`:避免弓 teardown 后落地空约 1 秒 |
| 2026-09-11 | 飞行透明隐藏仍算英雄盖住格子;弓连击中 onIdle 不回待机字,避免字与拉弓叠在一起 |
| 2026-09-12 | 背包重建不得 setData 地图格;落子/升级/合成只写绑定期变化的槽/格,禁止扫场 setData |
| 2026-09-12 | 叠字根因:合成把飞来块挂到已占格、飞行中按空格 spawn、rebuild 按 weapon2 把别格字拽过来。禁止造第二块,不靠事后清 |
| 2026-09-12 | atk_type=4 弓:落地后保持「等箭落地」标记到收招,近距箭先落地时动画结束不再 drain 第二段(嫦娥普攻) |
2 weeks ago
| 2026-09-30 | atk_type=16:扇形多段 hit(复用 5/14 多段表现通道,100001~100005) |
| 2026-09-30 | atk_type=16 棍:FanMultiHitAtkPresenter 覆盖内置,Gun 宿主播「英雄棍-攻击」攻效;攻效播完即解锁收招(Hero 3 atk_id → 100003) |
| 2026-09-30 | atk_type=17 不穿透散射箭:散射扇出同 12,首中即结算并当场回收表现箭(400002/400003) |
| 2026-09-30 | 修复弓字形塔散射不发射:Gong 宿主 12/17 委托自身「英雄弓-攻击/投掷物」扇出(BowScatterAtkPresenter),result 10 覆盖普攻形态同步分流 |
| 2026-09-30 | 补注册 atk_type=11 召唤(10051~10055)→ SummonAtkPresenter;表内 1~17 表现已全覆盖,仅 9(将武器形 30406)按兜底结算待策划定义攻效 |
| 2026-09-30 | 棍 200005 环形刀光:GunRingAtkPresenter,攻效播完从字位置按 atk_para(起始角,角度间隔,伤害系数)逆时针发射龙影(prefab/skill/棍),体盒弹道首中即消耗;atk_type 改 17(锁单体、伤害全在弹道) |