[Parity][render][S1][R] 自造施法光源(effectiveMode === 10 || unit.castState)导致怪物 MonMode 10 (S3) 也触发强光 #605

Closed
opened 2026-10-02 11:42:45 +00:00 by troytt · 0 comments
Owner

1.13c 客户端保真度审计立项(基准快照:7bd1090 / main @ 77a20c7)

证据标记说明:V-data = 1.13c MPQ 数据表 (.txt / animdata.d2 / .tbl / pal.pl2);V-src = D2MOO 逆向源码;V-bin = 1.13c DLL 反汇编;K = 1.13c 公认行为。

来源审计项:render#4 — [S1][R] 施法 overlay 的兜底路径用全局 tick 当帧号,停在最后一帧;自造施法光,怪物 mode 10(S3)也会触发

注:本条前半部分(Math.floor(tick) 导致施法兜底叠加层卡在末帧)已在 62663c4 修复;后半部分自造施法光源仍在 main 上成立。

  • 位置:src/client/view/unit-drawables.ts:581-629(activeCastState 分支);绘制端在 world-renderer.ts:993-994
  • 代码:
    const frame = Math.min(totalFrames - 1, Math.max(0, Math.floor(tick)))   // L591,tick 是全局游戏 tick
    overlayId: activeCastState.skillId || 1000,                             // L595
    } else if (effectiveMode === 10) { pointLights.push({ radius: 10, intensity: 210, r: 255, g: 195, b: 110 }) }  // L619-628
    
  • 原版:施法 overlay 从施法开始的第 0 帧播放,按 overlay.txt 的 Frames / AnimRate 播完就消失(例如 V-data overlay.txt #29 fire_cast_1:14 帧,AnimRate 16,Trans 3,Radius 9,255,178,64)。施法时的光照来自 overlay 行本身的 Radius/RGB,原版没有"任意施法都发出的 10 半径暖光"。另外 MonMode 10 是 S3,不是施法(V-data monmode.txt #10 skill3 S3;#7 才是 SC)。
  • 影响:
    • client-world 挂上的一次性施法 overlay 过了 maxTicks 被移除后,只要 castState 还在,这条路径就会重新插入一个 overlay,帧号 = min(total-1, tick),也就是最后一帧,于是这一帧一直静止挂在单位身上。其他单位的 castState 只有在移动时才清除(client-world.ts:1859-1874),站着施法的怪物或玩家会长时间顶着这张静止图和它的光。
    • 没有 castOverlay 的技能会落到 effectiveMode===10 分支,给施法者加一盏自造的暖光;怪物 mode 10(S3 技能,比如某些远程或特殊攻击)也会误触发。
    • 光照半径还被 max(12, radius) 抬高(见 S1「光源」条)。
  • 建议:施法 overlay 只由 client-world 的一次性条目驱动(它已按 ageTicks 推进),删掉这条兜底路径和 mode 10 自造光;castState 的生命周期按 #546 处理。
  • 已有 issue:#546(castState 不过期是根因之一;本条的"帧号=全局 tick"和"自造施法光"是渲染侧独立的问题)
> **1.13c 客户端保真度审计立项**(基准快照:`7bd1090` / `main @ 77a20c7`) > 证据标记说明:`V-data` = 1.13c MPQ 数据表 (`.txt` / `animdata.d2` / `.tbl` / `pal.pl2`);`V-src` = D2MOO 逆向源码;`V-bin` = 1.13c DLL 反汇编;`K` = 1.13c 公认行为。 ### 来源审计项:`render#4` — [S1][R] 施法 overlay 的兜底路径用全局 tick 当帧号,停在最后一帧;自造施法光,怪物 mode 10(S3)也会触发 > 注:本条前半部分(`Math.floor(tick)` 导致施法兜底叠加层卡在末帧)已在 `62663c4` 修复;后半部分自造施法光源仍在 `main` 上成立。 - 位置:`src/client/view/unit-drawables.ts:581-629`(`activeCastState` 分支);绘制端在 `world-renderer.ts:993-994` - 代码: ```ts const frame = Math.min(totalFrames - 1, Math.max(0, Math.floor(tick))) // L591,tick 是全局游戏 tick overlayId: activeCastState.skillId || 1000, // L595 } else if (effectiveMode === 10) { pointLights.push({ radius: 10, intensity: 210, r: 255, g: 195, b: 110 }) } // L619-628 ``` - 原版:施法 overlay 从施法开始的第 0 帧播放,按 overlay.txt 的 Frames / AnimRate 播完就消失(例如 V-data `overlay.txt` #29 fire_cast_1:14 帧,AnimRate 16,Trans 3,Radius 9,255,178,64)。施法时的光照来自 overlay 行本身的 Radius/RGB,原版没有"任意施法都发出的 10 半径暖光"。另外 MonMode 10 是 S3,不是施法(V-data `monmode.txt` #10 skill3 S3;#7 才是 SC)。 - 影响: - client-world 挂上的一次性施法 overlay 过了 `maxTicks` 被移除后,只要 `castState` 还在,这条路径就会重新插入一个 overlay,帧号 = `min(total-1, tick)`,也就是最后一帧,于是这一帧一直静止挂在单位身上。其他单位的 `castState` 只有在移动时才清除(`client-world.ts:1859-1874`),站着施法的怪物或玩家会长时间顶着这张静止图和它的光。 - 没有 castOverlay 的技能会落到 `effectiveMode===10` 分支,给施法者加一盏自造的暖光;怪物 mode 10(S3 技能,比如某些远程或特殊攻击)也会误触发。 - 光照半径还被 `max(12, radius)` 抬高(见 S1「光源」条)。 - 建议:施法 overlay 只由 client-world 的一次性条目驱动(它已按 ageTicks 推进),删掉这条兜底路径和 mode 10 自造光;`castState` 的生命周期按 #546 处理。 - 已有 issue:#546(castState 不过期是根因之一;本条的"帧号=全局 tick"和"自造施法光"是渲染侧独立的问题)
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#605
No description provided.