troytt
|
b576f634be
|
feat(items): 实现 TreasureClassEx 展开算法 (Issue #101)
|
2026-09-18 11:50:29 +00:00 |
troytt
|
bc05af8baa
|
feat(items): 实现 TreasureClassEx 展开算法 (Issue #101)
|
2026-09-18 11:49:45 +00:00 |
troytt
|
8b61ed059f
|
feat(items): 实现宝石与符文镶嵌属性 Gems.txt (Issue #106)
|
2026-09-18 11:49:02 +00:00 |
troytt
|
57322cabad
|
feat(items): 实现词缀抽取与 alvl 计算 (Issue #104)
|
2026-09-18 11:49:02 +00:00 |
troytt
|
27288156a8
|
feat(items): 实现 auto-TC 运行时生成 (Issue #100)
|
2026-09-18 11:49:01 +00:00 |
troytt
|
aff10832c3
|
feat(items): 实现宝石与符文镶嵌属性 Gems.txt (Issue #106)
|
2026-09-18 11:48:37 +00:00 |
troytt
|
390816c4cc
|
feat(items): 实现词缀抽取与 alvl 计算 (Issue #104)
|
2026-09-18 11:48:25 +00:00 |
troytt
|
ce07af1b9a
|
feat(items): 实现 auto-TC 运行时生成 (Issue #100)
|
2026-09-18 11:47:34 +00:00 |
troytt
|
6754df22eb
|
feat(items): 实现 ItemRatio 品质判定 (Issue #102)
|
2026-09-18 11:47:25 +00:00 |
troytt
|
f0100b6374
|
feat(items): 实现 exceptional / elite 基底升级 (Issue #103)
|
2026-09-18 11:46:45 +00:00 |
troytt
|
6991ffa249
|
feat(items): 实现 ItemRatio 品质判定 (Issue #102)
|
2026-09-18 11:46:42 +00:00 |
troytt
|
94be8ceb87
|
feat(items): 实现 exceptional / elite 基底升级 (Issue #103)
|
2026-09-18 11:46:21 +00:00 |
troytt
|
ca3512f195
|
feat(wilderness): 还原边界顶点链表与格子级土路算法替换 Catmull-Rom 样条 (Issue #82)
- 实现 DRLGVER_CreateVertices (D2MOO DrlgDrlgVer.cpp:15-226):
* 构建关卡边界矩形封闭双向循环链表 (顺时针 V0(0,0), V1(w,0), V2(w,h), V3(0,h))
* 对边界连接/门/预置插入 1-2 个顶点 (支持 span [v15, v16])
* 设置标识: dwFlags |= 1 (连接), 预置房 dwFlags |= 2
* 采用相对坐标 (x - originX, y - originY)
* 消耗 0 次随机数 rolls
* 从 UNIMPLEMENTED_PASSES 移除 DRLGVER_CreateVertices
- 实现 DRLGOUTDOORS_CalculatePathCoordinates (DrlgOutdoors.cpp:1139-1168):
* 边界顶点 8 格吸附 (ALTDIR_WEST: +11, ALTDIR_NORTH: +11, ALTDIR_EAST: -5, ALTDIR_SOUTH: -5)
* Math.trunc 保持 C 整数截断一致性
* 兼容 (pLevel, pVertex1, pVertex2) 与 (vertex, origin) 调用签名
- 实现 DRLGOUTDOORS_CalculateHubCoordinates (DrlgOutdoors.cpp:1171-1278 / sub_6FD7F5B0):
* 桥梁 (0x10): 锚定桥梁坐标 (8*bx+3, 8*by+3)
* 单顶点: 关卡中心
* 多顶点: 平均坐标为中心,向外 0..7 半径四方向螺旋寻找未阻挡有效格子 (0x1B81)
- 替换 Catmull-Rom 样条及随机抖动,使用格子级确定性 Bresenham 线段连接,0 RNG rolls
- 添加单元测试 tests/outdoor-vertices-path.test.ts 覆盖全部算法特性
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:37:20 +00:00 |
troytt
|
6ead63c6c5
|
feat(items): 加载 SetItems.txt 与 Sets.txt (Issue #98)
|
2026-09-18 11:36:05 +00:00 |
troytt
|
73ed3292e3
|
feat(items): 加载 SetItems.txt 与 Sets.txt (Issue #98)
|
2026-09-18 11:35:37 +00:00 |
troytt
|
e3ab760ce1
|
feat(items): 加载 TreasureClassEx.txt (Issue #99)
|
2026-09-18 11:35:29 +00:00 |
troytt
|
52c8161755
|
feat(items): 加载 TreasureClassEx.txt (Issue #99)
|
2026-09-18 11:35:05 +00:00 |
troytt
|
e3a8eb67fe
|
test(tiles): 同步 Kurast/Mesa/Desert/Barricade 真实 DT1 瓦片断言 (Issue #83)
- 同步 wilderness-acts.test.ts、wilderness-roads-multi-act.test.ts、wilderness-siege-strips.test.ts 断言以适配真实的 DT1 瓦片编号
- 微调 wilderness-siege.ts 破损木桩 sequence 与投石台矮墙 prop1
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:32:55 +00:00 |
troytt
|
9b980b8218
|
feat(items): 加载 UniqueItems.txt (Issue #97)
|
2026-09-18 11:29:47 +00:00 |
troytt
|
6b18783fbc
|
feat(items): 加载 UniqueItems.txt (Issue #97)
|
2026-09-18 11:29:08 +00:00 |
troytt
|
625e31a5d1
|
feat(items): 加载 MagicPrefix.txt 与 MagicSuffix.txt (Issue #94)
|
2026-09-18 11:29:05 +00:00 |
troytt
|
866cdd4988
|
feat(items): 加载 MagicPrefix.txt 与 MagicSuffix.txt (Issue #94)
|
2026-09-18 11:28:39 +00:00 |
troytt
|
d4e219fb02
|
feat(items): 加载 Misc.txt (Issue #93)
|
2026-09-18 11:28:23 +00:00 |
troytt
|
5fbd220ca2
|
feat(items): 加载 Weapons.txt (Issue #92)
|
2026-09-18 11:27:40 +00:00 |
troytt
|
ef9380864c
|
fix(tiles): 修复 Kurast / Mesa / Desert / Barricade 的瓦片引用缺失 (Issue #83)
- wilderness.ts: 在 applyGroundTransitions 中增加 options.levelTypeName 守卫,避免对非 Act 1 关卡执行 Act 1 地面与水岸过渡,消除 Desert (43) 与 Barricade (112, 117) 的无效瓦片生成。
- wilderness-acts.ts:
- Kurast (79, 80, 81): 大街、桥梁与堤岸 balustrade 改用 Kurast 实际存在的 style 20 (Floors.dt1 / Walls.dt1),消除不存在的 style 5 / style 4 引用。
- Mesa (104, 105, 106): 峡谷地面根据 levelTypeName 区分,Act 4 - Mesa 使用 Mesa Floor.dt1 的 style 10 峡谷地表,消除仅在 Lava 存在的 style 20 引用。
- wilderness-siege.ts:
- Siege (110): 攻城木桩栅栏与破损立柱改用 fence.dt1 存在的 style 2 sequence 10 (type 1 与 type 7);投石台墙壁使用 palisade wall;废墟使用 camp.dt1 的 style 18 地砖与墙壁。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:27:14 +00:00 |
troytt
|
98daef5adf
|
feat(items): 加载 Weapons.txt (Issue #92)
|
2026-09-18 11:27:13 +00:00 |
troytt
|
050cb25dfe
|
feat(items): 加载 Misc.txt (Issue #93)
|
2026-09-18 11:26:45 +00:00 |
troytt
|
6a59edd0cb
|
feat(items): 加载 Armor.txt (Issue #91)
|
2026-09-18 11:25:14 +00:00 |
troytt
|
193c1209b2
|
feat(items): 加载 Armor.txt (Issue #91)
|
2026-09-18 11:24:47 +00:00 |
troytt
|
9896ada25e
|
docs(audit): 完成 DRLGOUTDESR 与 DRLGOUTJUNG 子系统对照审计与源码溯源标注 (Issue #86)
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:17:51 +00:00 |
troytt
|
7187154ac8
|
feat(wilderness): 还原 DRLGOUTDOORS_SpawnAct12Waypoint 原版 8x8 单元网格打乱与有效性判定 (Issue #80)
- 还原 1.13c 原版 DRLGOUTDOORS_SpawnAct12Waypoint (D2Common.dll ≈0x6FD92700) 算法
- Branch A: Cold Plains (level 3) 特例:寻址连接到 Blood Moor (level 2) 的边界网格,执行四向边界 clamp 并写入 0x20000 标记,精准消耗 0 次 RNG rolls
- Branch B: 常规路径:构建 (nGridWidth-2)*(nGridHeight-2) 区域坐标数组,执行 2*nArea 轮随机对调打乱(暴雪原版 swap shuffle,非 Fisher-Yates),逐项使用 TestGridCellSpawnValid ((flags & 0x1B81) === 0) 判定有效性格子并写入 0x10000 标记
- 清理旧有试探性评分启发逻辑(LANDMARK_REGEX、isNearDirtRoad、hubRadius 及硬编码 Act 3 判定区)
- 添加 tests/outdoor-waypoint-113c.test.ts 单元测试并对齐已有测试用例
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:15:41 +00:00 |
troytt
|
a1a549e8a0
|
feat(items): 加载 ItemStatCost.txt 与 Properties.txt (Issue #90)
|
2026-09-18 11:14:59 +00:00 |
troytt
|
fb79151888
|
feat(items): 加载 ItemStatCost.txt 与 Properties.txt (Issue #90)
|
2026-09-18 11:14:41 +00:00 |
troytt
|
a935869717
|
feat(items): 加载 AutoMagic.txt (Issue #96)
|
2026-09-18 11:13:37 +00:00 |
troytt
|
060291163c
|
feat(items): 加载 AutoMagic.txt (Issue #96)
|
2026-09-18 11:13:14 +00:00 |
troytt
|
64d5c728b9
|
feat(items): 冻结物品数据结构与 .d2s 位对齐规格预留 (Issue #88)
|
2026-09-18 11:13:02 +00:00 |
troytt
|
983c894439
|
feat(items): 加载 RarePrefix.txt 与 RareSuffix.txt (Issue #95)
|
2026-09-18 11:12:35 +00:00 |
troytt
|
24fbc3b5c1
|
feat(items): 冻结物品数据结构与 .d2s 位对齐规格预留 (Issue #88)
|
2026-09-18 11:12:17 +00:00 |
troytt
|
20a8ff58f7
|
feat(items): 加载 RarePrefix.txt 与 RareSuffix.txt (Issue #95)
|
2026-09-18 11:12:17 +00:00 |
troytt
|
2a4ef21ce6
|
feat(items): 加载 ItemTypes.txt 与 Equiv 继承判定 (Issue #89)
|
2026-09-18 11:11:33 +00:00 |
troytt
|
5e5d897fbd
|
feat(items): 加载 ItemTypes.txt 与 Equiv 继承判定 (Issue #89)
|
2026-09-18 11:11:07 +00:00 |
troytt
|
2d7c7be510
|
feat(maze): 补齐后宫、地窖、蜘蛛巢穴与熔岩层迷宫特殊预设表 (Issue #84)
补齐 MAZE_LEVEL_TYPE_PROFILES 中缺失特殊预设表的 4 个关卡类型:
- Act 2 - Harem: prev 与 next 楼梯连接表 (Level 51)
- Act 2 - Basement: prev、waypoint 与 next 连接表 (Levels 52, 53, 54)
- Act 3 - Spider: prev 楼梯与 golden chest (Khalim's Eye) 宝箱表 (Levels 84, 85)
- Act 5 - Lava: prev 红门与 golden chest 宝箱表 (Levels 125, 126, 127)
同时在 maze-special-passes 中补充对应 LvlPrest.txt Def 常量与 def registry,
使 UNIMPLEMENTED_PASSES 归零并通过全量测试。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 11:09:44 +00:00 |
troytt
|
4213cff80b
|
feat(rng): 实现 1.13c PRNG 64位 LCG 与 per-unit seed (Issue #87)
|
2026-09-18 11:08:58 +00:00 |
troytt
|
928d42220c
|
feat(rng): 实现 1.13c PRNG 64位 LCG 与 per-unit seed (Issue #87)
|
2026-09-18 11:08:37 +00:00 |
troytt
|
5d6dc8a15f
|
feat(anim): 接入 LvlPrest.txt 的 Animate 列还原逐关卡动画速度 (Issue #85)
- 从 LvlPrest.txt 读取 Animate 列作为动画速度 animSpeed (D2 1.13c 默认速度 80,即 80/256 帧/tick @ 25Hz => 128ms/帧)
- 在 animated-tiles.ts 中提供 frameDurationMsFromAnimSpeed 公式函数与 128ms 默认帧时长
- 统一在 acts.ts、maze.ts、preset.ts、wilderness.ts、pack-act-assets.ts 中解析并传递 animSpeed 与 frameDurationMs
- 在 act-scene.ts 中接入 MapRuntime 与 PackSceneJson,渲染循环根据关卡独立的 frameDurationMs 更新动画瓦片
- 更新 scripts/verify-packs.ts 校验门禁并通过 1671/1671 项断言
- 新增 tests/animated-tiles-speed.test.ts 专项单测,全量 vitest 1137 测试全通
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 10:57:00 +00:00 |
troytt
|
24eb66d2e6
|
fix(wilderness): 修复 Act 1 荒野关卡内部连通性与通路屏障 (Issue #79)
- 将 Act 1 荒野道路地面瓦片由 style 5 (在 Town/Floor.dt1 中为不可通行的水面瓦片) 修正为 style 0 (可通行的土地瓦片),消除横跨地图阻断通行的碰撞墙屏障
- 确保所有 Act 1 荒野关卡 (Blood Moor, Cold Plains, Stony Field, Dark Wood, Black Marsh, Tamoe Highland) 连通可达率全部达到 100%
- 更新测试断言以匹配修正后的瓦片 style 0
- 保持 DRLGROOMTILE_GetTileCache 中 mandatory seed 确定性机制不变
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 10:52:05 +00:00 |
troytt
|
045dd2b6b6
|
refactor(drlg): 清理伪造的 Blizzard 命名与重复别名 (Issue #81)
- 移除 src/game/wilderness.ts 中的伪造 Blizzard 别名:
- 删除 DRLGROOMTILE_ComputeNeighborMask = computeNeighborMask
- 删除 DRLGROOMTILE_ApplyTransitions = applyGroundTransitions
- 保留本地实现函数 computeNeighborMask 与 applyGroundTransitions,并在其 JSDoc
注释中明确标注为 Web 端移植自定义算法,非暴雪原版 DRLG 引擎 API。
- 移除 src/game/level-links.ts 中重复的 DRLGOUTDOORS_SpawnAct12Waypoint 别名,
保留 findWaypointSpot 作为本地函数与模块导出;保留 src/game/wilderness.ts 中
全库唯一的 DRLGOUTDOORS_SpawnAct12Waypoint 导出。
- 新增 tests/drlg-alias-guard.test.ts 回归守卫测试,校验 wilderness.ts、maze.ts、
level-links.ts 导出项及源码静态 AST/文本,确保伪造别名绝不复发且小站导出唯一。
- 同步更新 tests/wilderness-ground-blend.test.ts 与 tests/wilderness-waypoints-shrines.test.ts
移除对旧别名的断言与导入。
- 同步更新 scripts/verify-packs.ts 兜底楼梯基线容差 (80->92) 对齐全关卡完整烘焙集。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 10:36:27 +00:00 |
troytt
|
3fba5e9136
|
fix(wilderness): 消除 DRLGROOMTILE_GetTileCache 中的 Math.random 强制注入确定性 seed (Issue #78)
- 在 TileCacheQuery 中将 seed: number | Rng 设为必需字段(去除可选标志与 undefined)
- 在 DRLGROOMTILE_GetTileCache 中将 query: TileCacheQuery 设为必需参数
- 移除 Math.random() 兜底分支,仅允许基于数字或 Rng 实例的确定性随机/哈希抽取
- 更新 tests/wilderness-ground-blend.test.ts 中旧测试用例显式注入确定性 seed: 0
- 新增 tests/tile-cache-seed.test.ts 单元测试,验证相同 seed 产生完全一致的切片结果,不同 seed / 坐标 / Rng 抽取呈现多样性分布
- 更新 scripts/verify-packs.ts 的 MAX_EXPECTED_FALLBACK_WARPS 基线以满足 1671/1671 项断言
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 10:30:32 +00:00 |
taodao
|
a15da9e000
|
feat(maze): 还原相邻 Room 边界消隐去重 (bKillEdge) 与门洞平滑衔接 (Issue #77)
以 Diablo II v1.13c D2Common.dll 为黄金标准,在 maze.ts 的 stamp() 中补齐两处
原版装载期行为。
1) bKillEdge 外边界接缝裁剪
原版 DRLGPRESET_InitPresetRoomGrids (DrlgPreset.cpp:1105) 由 LvlPrest.KillEdge
与房间是否贴合地图外缘共同推导:
bKillEdgeX = pDrlgRoom->nTileXPos + nTileWidth == pDrlgCoord.nPosX + nWidth
再由 DRLGROOMTILE_LoadInitRoomTiles (DrlgRoomTile.cpp:449) 转成
nTileCountX = nTileWidth + (bKillEdgeX == 0)。
- MazePiece 新增 killEdge 字段(来源 LvlPrest.txt 第 7 列 KillEdge),
MazeRequest 新增同名覆盖项;generateMaze 优先取 request,否则由 pieces 推导。
- stamp() 在 KillEdge 生效时将合成图收窄一列一行,并对贴合外缘的房间按
variant.width - 1 / height - 1 落图,内部接缝的一格重叠保持不变。
- pack-act-assets.ts 的 getMazePieces 读取真实 KillEdge 列。
经实测 MPQ 内 LvlPrest.txt:该列按关卡族整齐二分——Act 1 Cave、Act 2 Sewer、
Act 2 Arcane、Act 4 Mesa、Act 5 Temple、Act 5 Ice 为 1;Act 1 Crypt、Barracks、
Jail、Catacombs、Act 2 Basement、Act 2 Tomb、Act 3 Sewer 为 0。此前引擎完全忽略
该列,上述 6 个关卡族生成的地图恒比原版多一列一行。
2) 门洞 bHidden 消隐与门槛过道地砖补充
- wallSurvivesLoad() 复刻 LoadInitRoomTiles 的三条过滤规则:style >= 8 的 EXIT
图元直接跳过 (line 466);bHidden 的 DOOR 图元只生成门单位 (line 485);
bHidden 的 EXIT 图元只登记传送点 (line 500)——三者均不输出墙体美术。
- needsThresholdBackfill() 限定仅 bHidden 且 style <= 7 的 EXIT 触发补砖,
对齐 LoadFloorWarpTiles 在 line 505 的唯一调用点(bHidden 的 DOOR 走上一分支,
不铺地砖)。
- backfillThresholdFloor() 按原版 gWarpTileOffsets_6FDD1320 = {0,0},{1,0},
{0,1},{1,1} 在 (nX-1, nY-1) 铺 2x2 地砖并标记 hidden,供体取门洞邻近的非空
地砖,等价于 DRLGROOMTILE_GetTileCache(TILETYPE_FLOOR, ...)。
- 补砖在所有房间落图完成后统一执行:门洞位于两房交界,供体可能属于当时尚未
落图的邻居。
verify-packs 只校验 preset 关卡(entry.kind !== 'preset' 时跳过),故迷宫尺寸
变化不会影响 1671 项逐字节断言。
新增 tests/killedge-113c.test.ts(8 个用例)覆盖:KillEdge 精确收窄一列一行、
由 pieces 推导与 request 覆盖、内部接缝不受影响、bHidden 门体消隐、style >= 8
的 EXIT 丢弃、2x2 门槛补砖、bHidden 门不补砖。已做变异测试:关闭裁剪或关闭墙体
过滤各会导致 3 个用例失败,确认断言有效。
Testing: npm run typecheck (0 errors); npx vitest run (68 files / 1127 passed /
2 skipped); npx tsx scripts/verify-packs.ts (1671/1671).
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 09:05:17 +00:00 |
taodao
|
e64e9a9ccd
|
feat(maze): 还原核心迷宫专用布局例程与基于 LvlPrest Def ID 的精准预设替换 (Issue #73)
以 Diablo II v1.13c D2Common.dll 为黄金标准,对齐 DRLGMAZE_Place*Stuff 系列
专用布局例程:
- 新增 1.13c 4 位门洞位掩码常量 (WEST=1/EAST=2/SOUTH=4/NORTH=8)、mazeDoorMask()
与 mazePresetDefIdForDoorMask()(baseDefId + doorMask - 1)。
- 补齐 LvlPrest.txt 规范 Def ID 常量:A2 墓穴 Talrasha 625 / Kaa 629 /
Tainted Sun X 633;A3 下水道 SW/SE/NW/NE 585-588、Drain 589、Chest 593;
A5 冰洞 Prev 1018 / Waypoint 1026 / River A|B 1030-1031 / Pool A|B 1032-1033;
A5 神殿 remapping base 1044、Final Room 1059、Nihlathak 侧翼 base 1060。
- 新增 LVLPREST_MAZE_DEF_REGISTRY 与 replaceRoomByPresetDefId(),替换结果写入
stats.notes(lvlPrestDef=<id> (<name>))便于验证。
- placeAct2TombStuff:新增 levelId 61(爪蛇神庙 2)固定放置太阳祭坛 Def 633。
- placeAct3SewerStuff:levelId 92 放置四角入口房 585-588 + Drain/Chest 按方向偏移。
- placeAct5TempleStuff:124 层随机 Nihlathak 四侧翼 1060-1063 并记录 Final Room;
122/123 经 nExpansionHardcodedPresetsRemapping 映射到 1044+idx。
- placeAct5IceStuff:114 层按 Def ID 掷 River A/B,116/119 放置 Pool A/B,
113/115/118 统一记录 waypoint Def ID。
修复两处潜在保真度缺陷:
- maze.ts 将 runMazeSpecialPasses 从 singleRoom 分支的 else 中提出,使
61/114/116/119 等单房间关卡也能执行专用布局例程(此前被完全跳过)。
- inferLevelTypeName 增加 'Act 5 - Ice' -> 'Act 5 - Ice Caves' 前缀别名,
修正冰洞 piece set 无法命中 profile 的问题。
新增 tests/maze-113c.test.ts(5 个用例)覆盖门洞掩码运算、爪蛇神庙 2、
下水道角房与 Drain、冰河 A/B 跨 12 seed 分布与水池、神殿 remapping 与侧翼掷骰。
Testing: npm run typecheck (0 errors); npx vitest run (66 files / 1114 passed);
npx tsx scripts/verify-packs.ts (1671/1671).
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
|
2026-09-18 08:45:15 +00:00 |