[Parity][render][S2][R] 相机 Y 偏 −16 与输入 / 拾取坐标反算不一致;拾取圆 36 px 忽略 monstats2 / objects.txt 的选择框 #610

Open
opened 2026-10-02 11:42:46 +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#10 — [S2][R] 相机 Y 偏 −16 与输入 / 拾取坐标反算不一致;拾取圆 36 px 忽略 monstats2 / objects.txt 的选择框

  • 位置:src/client/scene/world-renderer.ts:1052(camY = playerWorld.y - 16,:1212 小地图同样使用);src/client/view/scene-source.ts:320-323(cameraTopLeft 不减 16)、:422-482(pickUnitAtScreen);src/client/view/viewport-profile.ts:223-234(screenToWorld)、:305-319(screenToSubTile,都假设玩家在 h/2);render/renderer.ts:163(u_camera 是屏幕中心)
  • 代码:
    const camY = snapshot.playerWorld.y - 16
    const dyBody = clickWorld.y - (u.worldY - 24)   // 半径 hitRadiusPx = 36
    if (u.isCorpse && u.unitKind === 'monster') continue
    
  • 原版:
    • 渲染和输入必须使用同一个视图原点(原版的具体偏移见待确认 #3)。
    • 选择框来自 V-data monstats2.txt 的 htTop / htLeft / htWidth / htHeight / noGfxHitTest / isSel / noSel / corpseSel(例如 #0 skeleton1、#5 zombie1 corpseSel=1),以及 objects.txt 的 Selectable0-7(例如 #30 Inifuss Selectable0=1,#59 TP Selectable0=0)。烘焙器已经导出 hitBox(baker/packers/pack-animdata.ts:252-258),但客户端没有任何地方使用。
  • 影响:
    • 画面比输入坐标整体下移 16 px:点地移动的落点、点怪的命中判定都偏离光标约 16 px(向下,正好是 1 个 sub-tile 菱形的高度)。
    • 拾取用固定的圆,大型怪 / 小型怪 / 物体的可点区域都不对;不可选的单位也能点到;可选的尸体(corpseSel,用于 Corpse Explosion、Revive 等)永远点不到。
  • 建议:相机偏移与 screenToWorld / screenToSubTile / cameraTopLeft 统一成一个常量(先确定原版值);拾取改为按 monstats2 ht* 的矩形(noGfxHitTest=0 时按帧像素),并遵守 isSel / noSel / corpseSel / Selectable。
  • 已有 issue:#557 / #542 是大于 800×600 时 UI 坐标偏移的问题;本条是世界视图的 16 px,属于新问题
> **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#10` — [S2][R] 相机 Y 偏 −16 与输入 / 拾取坐标反算不一致;拾取圆 36 px 忽略 monstats2 / objects.txt 的选择框 - 位置:`src/client/scene/world-renderer.ts:1052`(`camY = playerWorld.y - 16`,`:1212` 小地图同样使用);`src/client/view/scene-source.ts:320-323`(`cameraTopLeft` 不减 16)、`:422-482`(`pickUnitAtScreen`);`src/client/view/viewport-profile.ts:223-234`(`screenToWorld`)、`:305-319`(`screenToSubTile`,都假设玩家在 `h/2`);`render/renderer.ts:163`(`u_camera` 是屏幕中心) - 代码: ```ts const camY = snapshot.playerWorld.y - 16 const dyBody = clickWorld.y - (u.worldY - 24) // 半径 hitRadiusPx = 36 if (u.isCorpse && u.unitKind === 'monster') continue ``` - 原版: - 渲染和输入必须使用同一个视图原点(原版的具体偏移见待确认 #3)。 - 选择框来自 V-data `monstats2.txt` 的 htTop / htLeft / htWidth / htHeight / noGfxHitTest / isSel / noSel / corpseSel(例如 #0 skeleton1、#5 zombie1 corpseSel=1),以及 `objects.txt` 的 Selectable0-7(例如 #30 Inifuss Selectable0=1,#59 TP Selectable0=0)。烘焙器已经导出 `hitBox`(`baker/packers/pack-animdata.ts:252-258`),但客户端没有任何地方使用。 - 影响: - 画面比输入坐标整体下移 16 px:点地移动的落点、点怪的命中判定都偏离光标约 16 px(向下,正好是 1 个 sub-tile 菱形的高度)。 - 拾取用固定的圆,大型怪 / 小型怪 / 物体的可点区域都不对;不可选的单位也能点到;可选的尸体(corpseSel,用于 Corpse Explosion、Revive 等)永远点不到。 - 建议:相机偏移与 `screenToWorld` / `screenToSubTile` / `cameraTopLeft` 统一成一个常量(先确定原版值);拾取改为按 monstats2 ht* 的矩形(noGfxHitTest=0 时按帧像素),并遵守 isSel / noSel / corpseSel / Selectable。 - 已有 issue:#557 / #542 是大于 800×600 时 UI 坐标偏移的问题;本条是世界视图的 16 px,属于新问题
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#610
No description provided.