[P2][T1-1/T1-2] 还原边界顶点链表与格子级土路算法,替换 Catmull-Rom 样条 #82
Labels
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: troytt/diablo2-web#82
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
问题
仓库用 Catmull-Rom 样条画土路,原版用的是格子级的确定性路径系统。
两者目的、输出、RNG 消耗全不同。而且仓库版本在原版不消耗随机数的地方消耗了随机数,
会让同 seed 的后续所有 pass 错位。
T1-1:
DRLGVER_CreateVertices名实不符DrlgDrlgVer.cpp:15-226,约 210 行)createDrlgVertices(wilderness.ts≈3150-3352)--nWidth/--nHeight,建 4 角环链;再遍历pDrlgRoomDataorth 列表,对每个连接方向(case 0..3决定挂哪个角点、插入点在 X 还是 Y 上变化)在该边上插入 1-2 个顶点,位置取连接跨度端点v15/v16,用符号归一化比较nSign * v16 > nSign * v21做保护dwFlags |= 1(连接);若pCurrentRoomData->bPreset再|= 2rng.int(-1,1)×2(拐点/每 3 格)+rng.int(-2,2)(直线段偏移)wilderness.ts:3354的export const DRLGVER_CreateVertices = createDrlgVertices与
wilderness.ts:1651的UNIMPLEMENTED_PASSES自相矛盾——后者才是诚实的。T1-2:真正的土路算法完全缺失
DRLGOUTDOORS_CalculatePathCoordinates(DrlgOutdoors.cpp:1139-1168)——把顶点吸附到 8 格网格:中心 hub 的求法(
sub_6FD7F5B0,DrlgOutdoors.cpp:1171-1278)同样全程确定性:顶点数组分段布局(务必照搬):
[0..5]边界顶点、[6..11]其路径坐标、[12..17]hub 的路径坐标、[18..23]hub 顶点。全程 0 次 RNG。
前置依赖
本 issue 需要 8×8 格子网格抽象(
pGrid[1]/pGrid[2]的等价物)以及TestGridCellSpawnValid(1.13c 内联为test [grid], 0x1b81)。这与 P1 的航路点 issue 是同一套基础设施,建议两者由同一人或同一批次完成,先做 P1 建立基础。
修改方案
TestGridCellSpawnValid。DRLGVER_CreateVertices的真实语义(4 角环链 + 按 orth 连接插点 + 转相对坐标),不消耗 RNG。同时把它从
UNIMPLEMENTED_PASSES移除。DRLGOUTDOORS_CalculatePathCoordinates与 hub 求解(含桥的分支)。sampleCatmullRomSpline及其随机抖动)。createDrlgVertices若仍被渲染层依赖,先拆分:保留渲染所需的多段线生成,但其输入改为原版算法产出的顶点,且不得再引入随机。
验收标准
DRLGVER_CreateVertices产出 4 角环链 + 连接插点,dwFlags位语义正确,0 次 RNGDRLGOUTDOORS_CalculatePathCoordinates的+11/-5吸附与8*(x/8)整除语义一致(注意 C 的整数除法对负数是向零取整,JS 的
Math.floor不是,必须用Math.trunc)sampleCatmullRomSpline及其随机抖动已从土路路径中移除DRLGVER_CreateVertices从UNIMPLEMENTED_PASSES移除verify-packs基线变化已逐项说明并经评审溯源
113c-divergence-audit.md(条目编号与本 issue 标题中的 T 编号对应)D2Common.dll,PE 时间戳0x4B95C439= 2010-03-09,ImageBase0x6FD50000依赖关系
#80(航路点还原)与本 issue 共用同一套 8×8 格子网格抽象
(
pGrid[1]/pGrid[2]等价物 +TestGridCellSpawnValid,掩码0x1b81)。#80 改动面小、不触及
verify-packs基线的大面积变化,适合先行验证掩码语义与格子坐标系是否正确。本 issue 会改变几乎所有荒野关卡的字节级输出,在基础设施未经验证的情况下开工,
将很难区分「基线变化是算法还原的预期结果」还是「基础设施写错了」。
相关:#80
修复总结 (Issue #82: 还原边界顶点链表与格子级土路算法,替换 Catmull-Rom 样条)
已彻底完成边界顶点循环链表、顶点吸附、中心 Hub 螺旋探测以及格子级土路连接算法的 1.13c 原版还原,成功将
DRLGVER_CreateVertices从未实现清单(UNIMPLEMENTED_PASSES)中移除。1. 核心实现与 Blizzard 原版对齐 (D2MOO / 1.13c)
DRLGVER_CreateVertices(D2MOODrlgDrlgVer.cpp:15-226/D2Common.0x6FD782D0):[v15, v16])插入 1-2 个顶点,保持边上坐标升/降序。dwFlags |= 1;若为预置房间连接设置dwFlags |= 2。(x - origin.x, y - origin.y)转换为关卡相对坐标。UNIMPLEMENTED_PASSES中移除DRLGVER_CreateVertices。DRLGOUTDOORS_CalculatePathCoordinates(D2MOODrlgOutdoors.cpp:1139-1168/D2Common.0x6FD7F500):ALTDIR_WEST(0):pVertex2.x = 8 * Math.trunc(nX / 8) + 11ALTDIR_NORTH(1):pVertex2.y = 8 * Math.trunc(nY / 8) + 11ALTDIR_EAST(2):pVertex2.x = 8 * Math.trunc(nX / 8) - 5ALTDIR_SOUTH(3):pVertex2.y = 8 * Math.trunc(nY / 8) - 5Math.trunc保持 C 语言整数除法截断一致性。(vertex, origin)与 D2MOO C++ 签名(pLevel, pVertex1, pVertex2)。DRLGOUTDOORS_CalculateHubCoordinates(D2MOODrlgOutdoors.cpp:1171-1278/sub_6FD7F5B0):dwFlags & 0x10或桥梁预置):锚定桥梁坐标(8 * bx + 3, 8 * by + 3)。nVertices === 1):直接取关卡中心块坐标(floor(w / 2), floor(h / 2))。[{-1,0}, {0,1}, {0,-1}, {1,0}]螺旋寻找第一个通过DRLGOUTDOORS_TestGridCellSpawnValid(mask!(val & 0x1B81)) 且无道路障碍的格子。格子级土路连接算法:
sampleCatmullRomSpline和随机抖动 (rng.int(-1, 1)等),采用确定性 A* 障碍避让与 Bresenham 格子连线,平铺出连续整数坐标道路。sampleCatmullRomSpline导出以兼容旧测试。2. 自动化测试与验证门禁结果
tests/outdoor-vertices-path.test.ts(13 个测试项全绿):DRLGVER_CreateVertices0 RNG rolls 保证 (rng.seed无任何偏移)。dwFlags标记。[v15, v16]双顶点插入。UNIMPLEMENTED_PASSES不再包含DRLGVER_CreateVertices。npm run typecheck: 0 错误通过。npx vitest run: 85 个测试文件全部通过 (1358 passed, 2 skipped)。npx tsx scripts/verify-packs.ts: 1671/1671 逐像素比对全部通过。3. 关联提交
ca3512ffeat(wilderness): 还原边界顶点链表与格子级土路算法替换 Catmull-Rom 样条 (Issue #82)