fix(skill): 修复九头海蛇 (Hydra #62) 缺失海蛇实体与动画 (仅显示三个色块黄点) 以及未实装最大召唤数量上限缺陷 #436

Closed
opened 2026-09-24 08:21:39 +00:00 by troytt · 0 comments
Owner

1. 缺陷概述 (Issue Summary)

当前网页端实现中,女巫 30 级核心火焰召唤技能 九头海蛇 (Hydra, Skill ID: 62) 存在两项破坏游戏表现与机制平衡的严重缺陷:

  1. 缺失海蛇实体与动画,仅呈现三个简陋黄点:在目标地点施展九头海蛇后,地面上仅出现三个用代码纯色块绘制的小黄点(renderer.drawSolid 矩形),完全没有原版标志性的从地表岩浆火坑中破土钻出的三头火蛇实体、摇曳身躯以及张嘴喷射火弹的完整 DCC 动画;
  2. 完全缺失最大召唤上限控制 (Summon Cap):当前释放九头海蛇时,没有对场上已有的海蛇数量进行任何上限检查,也无先进先出(FIFO)淘汰机制,玩家可以无休止地连续召唤几十甚至上百条海蛇,破坏游戏平衡并造成实体堆积与性能隐患。

2. Diablo II v1.13c Ground Truth 权威数据与机制分析

严格依据暗黑破坏神 II v1.13c 官方数据表(Skills.txt, Overlay.txt, MonStats.txt, PetType.txt)及底层召唤物管线:

2.1 Skills.txt (Row 62: Hydra)

  • summon: hydra1(对应的召唤物生物代码)
  • pettype: hydra(宠物/召唤物分组类型)
  • petmax: 权威上限参数
  • summode: S2(召唤出现模式为 S2: Special 2 - 钻出地表动画)
  • monanim: S1
  • delay: 40 (1.6s 施法延迟), Param1: 250 (持续时间 10 秒)

2.2 Overlay.txt (Rows 174 ~ 182) 地表岩浆火坑特效

原版九头海蛇生成时,地面三个蛇头基座位置有完整的岩浆火焰 Overlay:

  • hydra_start1..3: CelFile HydraGroundFireStart (16 帧,地表裂开喷火)
  • hydra_loop1..3: CelFile HydraGroundFire (20 帧,持续循环地表岩浆烈火)
  • hydra_end1..3: CelFile HydraGroundFireEnd (16 帧,地表火焰熄灭闭合)
  • 相对基准坐标偏移:Head 1: (-6, -11),Head 2: (0, -7),Head 3: (+4, -15)

2.3 MonStats.txt / 召唤物动画模态 (DCC Models)

在原版中,海蛇由三只独立的蛇头怪组成:

  • hydra1 (Token: HX), hydra2 (Token: 21), hydra3 (Token: HZ)
  • 包含 4 个核心动画阶段:
    1. Mode S2 (Emergence): 从地底钻出的破土动画;
    2. Mode NU (Neutral/Idle): 在地面上昂首摇弋探视的待机动画;
    3. Mode A1 (Attack): 发现 480px 内敌人时前倾张口喷吐 hydra (firebolt) 火弹;
    4. Mode DT (Death): 10 秒时间结束或被替换时缩回地底/化作灰烬。

2.4 上限规则与 FIFO 淘汰机制 (Summon Cap & FIFO Eviction)

  • 在原版及现代暗黑2体系(如 D2R 2.4、Project Diablo 2 等标准设定)中,九头海蛇均设有明确的最大同时存活上限(通常设定为 6 组海蛇,共 18 个蛇头,部分模式为 4~6 组);
  • 当召唤新的一组海蛇导致总量超过上限时,系统必须自动触发 先进先出 (FIFO) 淘汰,将场上最老的一组海蛇提前结束生命周期(缩回地底/销毁)。

3. 当前代码根因剖析 (Root Cause Analysis)

3.1 渲染管线使用占位 drawSolid 硬编码色块替代了动画

在 src/scene/act-scene.ts(第 4420–4432 行):

if (shot.isTurret || shot.missileType === 'hydra_turret') {
  // Authentic stationary hydra head turret plume
  const wobble = Math.sin((shot.ageTicks ?? 0) * 0.3 + (shot.headIndex ?? 0) * 1.5) * 2.5
  // Soft outer fire aura
  renderer.drawSolid(x - 12, y - 12 + wobble * 0.5, 24, 24, [1.0, 0.32, 0.05, 0.35])
  // Mid fire core
  renderer.drawSolid(x - 8, y - 8 + wobble, 16, 16, [1.0, 0.65, 0.12, 0.65])
  // Inner hot core
  renderer.drawSolid(x - 4, y - 4 + wobble, 8, 8, [1.0, 0.92, 0.3, 0.9])
  // White flame peak
  renderer.drawSolid(x - 2, y - 6 + wobble, 4, 6, [1.0, 1.0, 0.85, 0.95])
}
  • 此处直接使用了 4 层纯色小方块矩形叠放在一起,代表一个蛇头。
  • 三个蛇头在画面上表现出来的就是三个不断上下抖动的小黄色色块,没有任何海蛇身体、蛇头朝向、喷火动作或地底岩浆特效。

3.2 施法逻辑绕过召唤物管理,无上限与淘汰检测

在 src/scene/act-scene.ts(第 1827–1845 行):

for (let i = 0; i < offsets.length; i++) {
  const off = offsets[i]!
  engine.projectiles.push({
    skillId: '62',
    x: targetX + off.dx,
    y: targetY + off.dy,
    vx: 0,
    vy: 0,
    damage: hydraDamage,
    ttl: 250, // 10 seconds at 25 fps
    fromPlayer: true,
    missileType: 'hydra_turret',
    isTurret: true,
    fireCadenceTicks: 25,
    headIndex: i,
    spawnMissileType: 'hydra',
    pierce: false,
  })
}
  • 施法逻辑未接入 src/game/engine/summon-manager.ts(其内部原本具备完整的 petmax 与 FIFO 淘汰机制),而是把海蛇当作 3 个匿名的普通投射物硬塞进 engine.projectiles;
  • 每次施法直接 push,从未检查场上已存在的 isTurret 或 hydra_turret 数量,因此完全没有最大数量上限限制,老海蛇也不会被替换淘汰。

4. 修复与对齐方案设计 (Proposed Architecture & Implementation Plan)

4.1 引入海蛇实体外观与地表火 Overlay 表现

  1. 地表火孔 Overlay 支持:
    • 挂载 Overlay.txt 中定义的 hydra_loop1..3(或 HydraGroundFire)循环底座特效,锚定在三个偏移点 (-6, -11), (0, -7), (+4, -15);
  2. 海蛇蛇头 Sprite 动画支持:
    • 引入海蛇精灵帧动画(包含朝向瞄准目标的 Direction 帧与喷吐动作帧),替换简陋的 renderer.drawSolid 占位色块,真实还原暗黑2经典海蛇视觉体验。

4.2 实装最大召唤上限与先进先出 (FIFO) 淘汰机制

  1. 定义海蛇最大存活组数上限:
    • 设定权威常量 MAX_ACTIVE_HYDRAS = 6(即最大 6 组,共 18 个活动蛇头);
  2. 施法前数量审计与逐组淘汰:
    • 统计当前 engine.projectiles 中标记为 missileType === 'hydra_turret' 的海蛇,按施放批次(或组 ID)排序;
    • 当海蛇组数达到或超过 MAX_ACTIVE_HYDRAS 时,找到最老的一组海蛇(3 个蛇头),将其 ttl 立即置为 0(或标记过期退出),完成 FIFO 淘汰;
    • 确保场上同时活跃的海蛇总组数严格不超过上限。

4.3 单元测试与验证计划 (Verification Plan)

  1. 上限与 FIFO 单元测试:
    • 扩展 tests/hydra-missile-113c.test.ts,连续执行 7 次 castSkill(62, ...);
    • 断言:场上海蛇总发射头数量被严格限制在 6 * 3 = 18 个,第 1 次施放的海蛇在第 7 次施放后被正确淘汰销毁。
  2. 画面实机验证:
    • 施放九头海蛇,确认地面不再显示三个简陋黄色纯色块,具备完整地底烈火与海蛇身躯;
    • 快速连续施展,观察旧海蛇按顺序自然消亡,数量上限稳定生效。
### 1. 缺陷概述 (Issue Summary) 当前网页端实现中,女巫 30 级核心火焰召唤技能 **九头海蛇 (Hydra, Skill ID: 62)** 存在两项破坏游戏表现与机制平衡的严重缺陷: 1. **缺失海蛇实体与动画,仅呈现三个简陋黄点**:在目标地点施展九头海蛇后,地面上仅出现三个用代码纯色块绘制的小黄点(`renderer.drawSolid` 矩形),完全没有原版标志性的从地表岩浆火坑中破土钻出的三头火蛇实体、摇曳身躯以及张嘴喷射火弹的完整 DCC 动画; 2. **完全缺失最大召唤上限控制 (Summon Cap)**:当前释放九头海蛇时,没有对场上已有的海蛇数量进行任何上限检查,也无先进先出(FIFO)淘汰机制,玩家可以无休止地连续召唤几十甚至上百条海蛇,破坏游戏平衡并造成实体堆积与性能隐患。 --- ### 2. Diablo II v1.13c Ground Truth 权威数据与机制分析 严格依据暗黑破坏神 II v1.13c 官方数据表(`Skills.txt`, `Overlay.txt`, `MonStats.txt`, `PetType.txt`)及底层召唤物管线: #### 2.1 `Skills.txt` (Row 62: Hydra) - **summon**: `hydra1`(对应的召唤物生物代码) - **pettype**: `hydra`(宠物/召唤物分组类型) - **petmax**: 权威上限参数 - **summode**: `S2`(**召唤出现模式为 S2: Special 2 - 钻出地表动画**) - **monanim**: `S1` - **delay**: `40` (1.6s 施法延迟), **Param1**: `250` (持续时间 10 秒) #### 2.2 `Overlay.txt` (Rows 174 ~ 182) 地表岩浆火坑特效 原版九头海蛇生成时,地面三个蛇头基座位置有完整的岩浆火焰 Overlay: - **`hydra_start1..3`**: CelFile `HydraGroundFireStart` (16 帧,地表裂开喷火) - **`hydra_loop1..3`**: CelFile `HydraGroundFire` (20 帧,持续循环地表岩浆烈火) - **`hydra_end1..3`**: CelFile `HydraGroundFireEnd` (16 帧,地表火焰熄灭闭合) - 相对基准坐标偏移:Head 1: `(-6, -11)`,Head 2: `(0, -7)`,Head 3: `(+4, -15)` #### 2.3 `MonStats.txt` / 召唤物动画模态 (DCC Models) 在原版中,海蛇由三只独立的蛇头怪组成: - `hydra1` (Token: `HX`), `hydra2` (Token: `21`), `hydra3` (Token: `HZ`) - 包含 4 个核心动画阶段: 1. **Mode S2 (Emergence)**: 从地底钻出的破土动画; 2. **Mode NU (Neutral/Idle)**: 在地面上昂首摇弋探视的待机动画; 3. **Mode A1 (Attack)**: 发现 480px 内敌人时前倾张口喷吐 `hydra` (`firebolt`) 火弹; 4. **Mode DT (Death)**: 10 秒时间结束或被替换时缩回地底/化作灰烬。 #### 2.4 上限规则与 FIFO 淘汰机制 (Summon Cap & FIFO Eviction) - 在原版及现代暗黑2体系(如 D2R 2.4、Project Diablo 2 等标准设定)中,九头海蛇均设有明确的最大同时存活上限(通常设定为 **6 组海蛇,共 18 个蛇头**,部分模式为 4~6 组); - 当召唤新的一组海蛇导致总量超过上限时,系统必须自动触发 **先进先出 (FIFO)** 淘汰,将场上最老的一组海蛇提前结束生命周期(缩回地底/销毁)。 --- ### 3. 当前代码根因剖析 (Root Cause Analysis) #### 3.1 渲染管线使用占位 `drawSolid` 硬编码色块替代了动画 在 [`src/scene/act-scene.ts`](file:///usr/local/google/home/taodao/diablo2-web/src/scene/act-scene.ts)(第 4420–4432 行): ```typescript if (shot.isTurret || shot.missileType === 'hydra_turret') { // Authentic stationary hydra head turret plume const wobble = Math.sin((shot.ageTicks ?? 0) * 0.3 + (shot.headIndex ?? 0) * 1.5) * 2.5 // Soft outer fire aura renderer.drawSolid(x - 12, y - 12 + wobble * 0.5, 24, 24, [1.0, 0.32, 0.05, 0.35]) // Mid fire core renderer.drawSolid(x - 8, y - 8 + wobble, 16, 16, [1.0, 0.65, 0.12, 0.65]) // Inner hot core renderer.drawSolid(x - 4, y - 4 + wobble, 8, 8, [1.0, 0.92, 0.3, 0.9]) // White flame peak renderer.drawSolid(x - 2, y - 6 + wobble, 4, 6, [1.0, 1.0, 0.85, 0.95]) } ``` - 此处直接使用了 4 层纯色小方块矩形叠放在一起,代表一个蛇头。 - 三个蛇头在画面上表现出来的就是**三个不断上下抖动的小黄色色块**,没有任何海蛇身体、蛇头朝向、喷火动作或地底岩浆特效。 #### 3.2 施法逻辑绕过召唤物管理,无上限与淘汰检测 在 [`src/scene/act-scene.ts`](file:///usr/local/google/home/taodao/diablo2-web/src/scene/act-scene.ts)(第 1827–1845 行): ```typescript for (let i = 0; i < offsets.length; i++) { const off = offsets[i]! engine.projectiles.push({ skillId: '62', x: targetX + off.dx, y: targetY + off.dy, vx: 0, vy: 0, damage: hydraDamage, ttl: 250, // 10 seconds at 25 fps fromPlayer: true, missileType: 'hydra_turret', isTurret: true, fireCadenceTicks: 25, headIndex: i, spawnMissileType: 'hydra', pierce: false, }) } ``` - 施法逻辑未接入 [`src/game/engine/summon-manager.ts`](file:///usr/local/google/home/taodao/diablo2-web/src/game/engine/summon-manager.ts)(其内部原本具备完整的 `petmax` 与 FIFO 淘汰机制),而是把海蛇当作 3 个匿名的普通投射物硬塞进 `engine.projectiles`; - 每次施法直接 `push`,从未检查场上已存在的 `isTurret` 或 `hydra_turret` 数量,因此完全没有最大数量上限限制,老海蛇也不会被替换淘汰。 --- ### 4. 修复与对齐方案设计 (Proposed Architecture & Implementation Plan) #### 4.1 引入海蛇实体外观与地表火 Overlay 表现 1. **地表火孔 Overlay 支持**: - 挂载 `Overlay.txt` 中定义的 `hydra_loop1..3`(或 `HydraGroundFire`)循环底座特效,锚定在三个偏移点 `(-6, -11)`, `(0, -7)`, `(+4, -15)`; 2. **海蛇蛇头 Sprite 动画支持**: - 引入海蛇精灵帧动画(包含朝向瞄准目标的 Direction 帧与喷吐动作帧),替换简陋的 `renderer.drawSolid` 占位色块,真实还原暗黑2经典海蛇视觉体验。 #### 4.2 实装最大召唤上限与先进先出 (FIFO) 淘汰机制 1. **定义海蛇最大存活组数上限**: - 设定权威常量 `MAX_ACTIVE_HYDRAS = 6`(即最大 6 组,共 18 个活动蛇头); 2. **施法前数量审计与逐组淘汰**: - 统计当前 `engine.projectiles` 中标记为 `missileType === 'hydra_turret'` 的海蛇,按施放批次(或组 ID)排序; - 当海蛇组数达到或超过 `MAX_ACTIVE_HYDRAS` 时,找到最老的一组海蛇(3 个蛇头),将其 `ttl` 立即置为 0(或标记过期退出),完成 FIFO 淘汰; - 确保场上同时活跃的海蛇总组数严格不超过上限。 #### 4.3 单元测试与验证计划 (Verification Plan) 1. **上限与 FIFO 单元测试**: - 扩展 `tests/hydra-missile-113c.test.ts`,连续执行 7 次 `castSkill(62, ...)`; - 断言:场上海蛇总发射头数量被严格限制在 `6 * 3 = 18` 个,第 1 次施放的海蛇在第 7 次施放后被正确淘汰销毁。 2. **画面实机验证**: - 施放九头海蛇,确认地面不再显示三个简陋黄色纯色块,具备完整地底烈火与海蛇身躯; - 快速连续施展,观察旧海蛇按顺序自然消亡,数量上限稳定生效。
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#436
No description provided.