Port D2Common 0x6FD5CF40 (dir64 from two points via the 0x6FDDD470 octant table) and D2CMP #10020 (dir64 -> clip direction rows at 0x6FE2F4D8) as dir64FromPoints / dir64ToClipDirection, with binary parity tests against the shipped 1.13c DLLs and a guard that every baked character/entity sheet uses a direction count the D2CMP table supports. |
||
|---|---|---|
| .. | ||
| data | ||
| drlg | ||
| formats | ||
| i18n | ||
| items | ||
| mpq | ||
| pack-contract | ||
| rng | ||
| skills | ||
| units | ||
| world | ||
| README.md | ||
| env.d.ts | ||
README.md
src/common — 纯 TypeScript 共享底座模块
src/common 是 Diablo II: Lord of Destruction (v1.13c) Web 移植版的纯计算与数据结构底座,1:1 对齐原版 D2Common.dll、Storm.dll 与 D2Lang.dll 的核心逻辑。
1. 模块职责与架构边界
- 对应原版 DLL:
D2Common.dll(DRLG 地图生成、数据表、碰撞掩码、单位/技能/物品基础公式、64 位随机数)、Storm.dll(MPQ 归档解析与 PKWARE/Huffman/Adpcm 解压)、D2Lang.dll(.tbl字符串表与本地化)。 - TypeScript 工程约束(
tsconfig.common.json):lib: ["ES2022"],types: []—— 零 DOM 依赖、零 Node.js API 依赖、零外部运行时依赖。- 严禁依赖
src/client、src/server、src/baker或src/netproto(由tests/arch/boundaries.test.ts强制门禁校验)。 - 所有文件 I/O 均通过依赖注入的
ArchiveSource接口完成,确保本模块可在浏览器主线程、WebWorker 与 Node.js 离线工具中无差别运行。
2. 目录结构
src/common/
├── mpq/ # Storm.dll MPQ 归档读取器、Hash/Block 表解密、多算法解压扇区
├── formats/ # 原生二进制格式解析器 (DC6, DCC, DT1, DS1, COF, PL2, PAL, CEL, PCX, TBL, AnimData, Bitstream)
├── data/ # D2DataRegistry 数据表注册中心与 TXT/JSON 数据模型定义
├── drlg/ # D2Common.dll 1.13c DRLG 随机地图生成器与碰撞/光照网格
├── world/ # 跨端共享的地图/关卡几何拓扑与寻路网格辅助计算
├── items/ # 物品基础属性、词缀、品质、孔数与符文之语公共计算逻辑
├── skills/ # 技能基础公式、协同加成 (Synergy) 与等级曲线解析
├── units/ # 单位属性 (StatList)、帧率驱动、状态位 (States) 与怪物基础数据
├── i18n/ # D2Lang.dll 字符串哈希与中英文双语 TBL 查找表
├── rng/ # D2Rng (64-bit Carry-Multiply 0x6FDAA9E0) 与 SplitMix64 空间哈希
└── pack-contract/ # 烘焙管线 (Baker) 与客户端 (Client) 共享的离线资产包 Schema 及校验契约
3. 核心子系统详解
3.1 MPQ 与二进制格式解析 (mpq/, formats/)
mpq-reader.ts:完整实现 MPQ v1 归档格式解析,支持 Hash Table / Block Table 加密种子计算、单文件与多扇区 PKWARE DCL / Zlib / Huffman 组合解压。dc6-parser.ts/dcc-parser.ts:解析 UI/物品/怪物/角色序列帧图像及方向图层数据,还原 DCC 变长比特流(Cell 缓冲与 EqualCells/PixelMask 双阶段编码)。dt1-parser.ts/ds1-parser.ts:解析地面/墙壁/屋顶瓦片(256×128 Isometric Diamond 与 RLE 子块)以及预制地图块(Floor/Wall/Shadow/Object/Substitution 图层与 NPC 巡逻路径)。cof-parser.ts/animdata-parser.ts:解析复合对象动画帧数、16 图层优先级组合顺序、关键帧触发事件(攻击命中、投射物释放、音效帧)及AnimData.d2动画速度表。pl2-parser.ts/pal-parser.ts:解析各幕 256 色调色板、光照衰减表、阴影混合表与色彩变换矩阵(染色/冰冻/毒素/暗金变色)。
3.2 数据注册中心 (data/)
D2DataRegistry(data/index.ts):集中加载并索引Levels.txt、LvlTypes.txt、LvlPrest.txt、LvlMaze.txt、LvlSub.txt、MonStats.txt、MonStats2.txt、SuperUniques.txt、Missiles.txt、Overlays.txt、Objects.txt、Skills.txt、Armor/Weapons/Misc.txt等全量 1.13c 数据表。- 支持注入内存 JSON 快照或基于
ArchiveSource的 MPQ 实时解析。
3.3 1.13c DRLG 地图生成引擎 (drlg/)
严格复刻 D2Common.dll 的确定性关卡生成流水线:
- 通用 DT1 强制加载 (
drlg-room-tiles.ts):遵循DRLGROOM_LoadDt1Files(0x6fdb8400),所有关卡无条件挂载Act1/Outdoors/Blank.dt1、InvisWal.dt1(含style=49, sequence=7隐形碰撞地板)与Warp.dt1。 - 三种生成拓扑:
drlg-preset.ts:固定预设关卡(如罗格营地、鲁·高因、崔斯特瑞姆、混沌避难所等)。drlg-maze.ts:地牢迷宫房间拼接算法(如墓穴、修道院地下城、塔拉夏古墓、憎恨囚牢等)。drlg-outdoors.ts:野外随机边界、道路、河流、预设营地塞入与主题墙壁围合(如鲜血荒地、冰冷之原、库拉斯特丛林等)。
- 变体选择与碰撞构建 (
tile-library.ts,collision.ts):- 使用 SplitMix64 空间哈希
pickVariant(worldX, worldY, orient, style, seq)彻底消除 45° 机械条纹伪影。 - 稀疏/未填充子格严格打上
COLLIDE_MASK_INVALID(COLLIDE_BLANK | COLLIDE_WALL),防止角色出生或穿墙掉入虚空。
- 使用 SplitMix64 空间哈希
3.4 确定性随机数 (rng/)
D2Rng(rng/d2-rng.ts):1:1 复刻D2Common.dll64 位进位乘法 PRNG(seed = (0x6AC690C5 * low32 + carry) >>> 0),保证给定相同的 32 位地图种子与难度,生成的地图拓扑与原生 C++ D2GS 完全一致。
3.5 离线资产契约 (pack-contract/)
schemas.ts/validators.ts:定义public/act-packs/下所有离线资产包(tiles、entities、missiles、overlays、ui、frontend、animdata)的 JSON Schema 与 Fail-Fast 校验器(强制要求missingFiles === 0且三大通用 DT1 齐全)。
4. 常用验证命令
# 单独对 src/common 进行严格无 DOM / 无 Node 类型检查
npx tsc -p tsconfig.common.json --noEmit
# 运行架构边界与 DRLG / 格式解析单元测试
npx vitest run tests/arch/boundaries.test.ts tests/drlg/