93 lines
6.9 KiB
Markdown
93 lines
6.9 KiB
Markdown
## 暗黑破坏神 II (v1.13c) 施法视觉效果 (Cast Overlay) 底层调查与实现设计规范
|
||
|
||
### 一、 机制调查与 1.13c 真实底层数据 (Ground Truth Invariant)
|
||
|
||
在暗黑破坏神 II v1.13c 引擎体系(`D2Common.dll`、`D2Client.dll`)中,释放法术时角色脚下涌现并包裹全身的动画效果并非角色自身动作(Action Frame)或飞弹(Missile),而是属于 **Unit Overlay(单位覆盖动画系统)**。
|
||
|
||
#### 1. 数据驱动关系
|
||
1. **`Skills.txt`**:包含列 **`castoverlay`**,定义技能施展时触发的覆盖效果标识(例如技能 36 火弹绑定 `fire_cast_1`)。
|
||
2. **`Overlay.txt`**:集中定义所有覆盖效果的物理与渲染属性:
|
||
- **`Filename`**:指向 DCC 动画资源路径(位于 `d2data.mpq: data/global/overlays/{Filename}.dcc`)。
|
||
- **`Frames`**:动画总帧数。
|
||
- **`AnimRate`**:动画播放速率。法术施法特效原版均为 **16**(代表在 25 FPS 逻辑刻下,每 25 tick 播放 16 帧动画,即步长 `16 / 25 = 0.64` 帧/刻,总时长约 0.88 秒)。
|
||
- **`Trans`**:混合渲染模式。原版为 **3**(**Additive Blending / 增色叠加混合**),呈现火焰、电光与寒冰的自发光半透明视觉质感。
|
||
- **`PreDraw`**:渲染层级。原版均为 **0**(**Foreground / 前景层**),先绘制施法者角色精灵,再在前景叠加该 Overlay,形成火焰包裹躯干的立体层次。
|
||
- **`Xoffset` / `Yoffset` / `Height1..4`**:均为 **0**,严格以施法者单位脚底地面中心点 `(0, 0)` 为基准。
|
||
- **`InitRadius` / `Radius` / `Red, Green, Blue`**:动态点光源参数(半径均为 9 个子网格)。Overlay 激活期间会在角色周围投射对应属性的动态光晕。
|
||
|
||
---
|
||
|
||
### 二、 核心法术原版 Overlay 映射与 DCC 规格表
|
||
|
||
经解析 `samples/d2/Patch_D2.mpq` 与 `d2data.mpq`,法师三大元素系法术完整映射如下:
|
||
|
||
| 技能类别 | 技能名称 (Id) | `Skills.txt` `castoverlay` | DCC 文件名 (`data/global/overlays/`) | 帧数 | DCC 碰撞盒 (Left, Top, W, H) | 光照颜色 (R, G, B, Radius) | 视觉特征 |
|
||
| :--- | :--- | :--- | :--- | :---: | :--- | :--- | :--- |
|
||
| **火焰系** | **火弹 Fire Bolt (36)** | `fire_cast_1` | `FireCast_for_Sorceress.dcc` | 14 | `[-55, -127, 117, 164]` | (255, 178, 64, 9) | **从脚底升腾直窜头顶的火焰柱 (即 Issue 附件效果)** |
|
||
| **火焰系** | 火球 (47), 强化/火焰强化 (46), 火墙 (51), 陨石 (56), 九头海蛇 (62) | `fire_cast_2` | `FireCast2.dcc` | 16 | `[-74, -89, 145, 133]` | (255, 178, 64, 9) | 范围更大、旋转包裹的炽热烈焰 |
|
||
| **冰霜系** | 冰弹 (39), 冰封甲 (40), 冰风暴 (45) | `ice_cast_1` | `IceCastNew01.dcc` | 15 | `[-49, -90, 97, 55]` | (81, 81, 255, 9) | 脚下微弱旋起的寒冰碎屑与白霜冷雾 |
|
||
| **冰霜系** | 霜之新星 (44), 碎冰甲 (50), 冰尖柱 (55) | `ice_cast_2` | `IceCastNew02.dcc` | 15 | `[-58, -100, 115, 123]` | (81, 81, 255, 9) | 向上旋转升腾的深蓝冰柱与霜雾 |
|
||
| **冰霜系** | 暴风雪 (59), 寒冰甲 (60), 冰封球 (64) | `ice_cast_3` | `IceCastNew03.dcc` | 16 | `[-63, -113, 127, 148]` | (81, 81, 255, 9) | 强烈的暴风雪霜华与立体冰凌环绕 |
|
||
| **闪电系** | 充能弹 (38), 静电场 (42), 新星 (48), 闪电 (49), 连锁闪电 (53) | `light_cast_1` | `LightningCast.dcc` | 10 | `[-79, -107, 164, 144]` | (255, 255, 255, 9) | 脚底向外炸裂并包裹全身的电弧跳跃 |
|
||
| **闪电系** | 心灵传动 (43), 雷云风暴 (57), 能量护盾 (58) | `light_cast_2` | `LightningCastRunesFront.dcc` | 10 | `[-73, -154, 147, 190]` | (255, 255, 255, 9) | 闪电符文闪耀与高耸电光柱 |
|
||
| **特殊** | 传送 Teleport (54) | `teleport` | `Teleport.dcc` | 18 | `[-61, -108, 136, 154]` | (255, 255, 200, 5) | 金黄色空间坍缩与残影粒子 |
|
||
|
||
---
|
||
|
||
### 三、 系统架构与实现方案 (diablo2-web)
|
||
|
||
遵循项目 **Zero Runtime MPQ Invariant** 及 **Anti-Silent Failures** 原则:
|
||
|
||
#### 1. 离线资源烘焙流水线 (`scripts/pack-overlays.ts`)
|
||
- 提取 `d2data.mpq` 中上述 8 个关键施法 Overlay DCC 精灵文件。
|
||
- 读取 `data/global/palette/ACT1/pal.pl2` 进行真实调色板色彩映射。
|
||
- 将单向动画打包成 PNG 纹理图集并导出 JSON 元数据至 `public/overlays/` 与 `samples/d2-packs/overlays/`。
|
||
- 自动生成类型定义 `src/render/overlays-meta.ts`,提供精确的 `box.left, box.top, width, height, animRate, trans` 常量。
|
||
|
||
#### 2. 运行时数据契约与实体抽象 (`src/game/skills.ts` & `src/game/engine.ts`)
|
||
- 扩展 `SkillDef` 接口,包含 `castOverlay?: string`。
|
||
- 建立 `CANONICAL_113C_OVERLAYS` 真值表,包含 overlay 标识到对应资源与物理属性的映射。
|
||
- 在 `GameEngine` 中引入 `ActiveOverlay` 活跃实体管理:
|
||
```typescript
|
||
export interface ActiveOverlay {
|
||
readonly id: string
|
||
readonly overlayName: string
|
||
readonly casterId: string
|
||
x: number
|
||
y: number
|
||
frame: number
|
||
readonly maxFrames: number
|
||
readonly animRate: number
|
||
readonly preDraw: boolean
|
||
readonly trans: number
|
||
readonly lightRadius: number
|
||
readonly lightColor: readonly [number, number, number]
|
||
expired: boolean
|
||
}
|
||
```
|
||
- **生命周期规则**:
|
||
- 玩家或怪物在 `executePlayerSkillCast` 触发施法动作时,根据技能 `castoverlay` 生成 `ActiveOverlay`。
|
||
- 每个逻辑 tick(25 FPS):`overlay.frame += overlay.animRate / 25`。
|
||
- 当 `Math.floor(overlay.frame) >= overlay.maxFrames` 时,标记 `expired = true` 并在 tick 结束时销毁(单次播放不循环)。
|
||
- Overlay 坐标实时同步施法者当前脚下位置 `(caster.x, caster.y)`。
|
||
|
||
#### 3. 渲染管线集成 (`src/scene/act-scene.ts`)
|
||
- 资源载入:通过 `loadOverlayArtMap` 预载 `overlays/*.png`。
|
||
- 深度层级(Z-Order):
|
||
- 角色绘制完成后、飞弹绘制前,执行前景 Overlay 渲染。
|
||
- 混合模式(Blend Mode):
|
||
- 遇到 `trans === 3`,切换 Canvas2D `ctx.globalCompositeOperation = 'lighter'` 或 WebGL Additive 混合状态,绘制完成后恢复 `source-over`。
|
||
- 锚点投影(Anchor Projection):
|
||
- 精确应用 DCC 包围盒偏移:`drawX = overlay.x + frameMeta.anchorX`,`drawY = overlay.y + frameMeta.anchorY`。
|
||
- 动态光照反馈:
|
||
- 在 Overlay 存活期间,将其注册为动态点光源(如火焰投射 9 码的 RGB(255, 178, 64) 暖黄光晕)。
|
||
|
||
---
|
||
|
||
### 四、 验证与回归测试策略
|
||
|
||
1. **表格对齐测试**:验证 `parseSkillsTxt` 与 `Skills.txt`、`Overlay.txt` 的 `castoverlay` 字段及参数完全一致。
|
||
2. **生命周期测试**:验证 14 帧的 `fire_cast_1` 在 25 FPS 模拟下,在第 22 个 tick 精确结束并移除。
|
||
3. **渲染与图集测试**:验证 `FireCast_for_Sorceress`、`IceCastNew01`、`LightningCast` 纹理图集无缺失、锚点边界无裁切、Additive 模式下正确渲染。
|
||
4. **全场景稳定性**:自动化 Headless 运行,保障全 136 个关卡环境施法 Overlay 无跨法术贴图污染或未定义崩溃。
|