[P1][T09] 加载 UniqueItems.txt(401 行 × 70 列,enabled=1 仅 385) #97

Closed
opened 2026-09-18 10:50:47 +00:00 by troytt · 1 comment
Owner

问题

暗金物品是品质判定(T-14)判到 unique(7) 之后的落点。没有这张表,判定出 unique 也无物可掉。

金标准数据

401 真实行(403 原始行 − 1 行 Expansion − 1 行 index 空)× 70 列,其中 enabled=1 只有 385 行。

列头:

index | version | enabled | ladder | rarity | nolimit | lvl | lvl req | code | *type | *uber |
carry1 | cost mult | cost add | chrtransform | invtransform | flippyfile | invfile | dropsound |
dropsfxframe | usesound | prop1..prop12 各带 par/min/max(12 组 × 4 = 48 列)| *eol

真实样例:

The Gnasher    enabled=1 rarity=1 lvl=7  lvl req=5  code=hax *type=Hand Axe
               cost mult=5 cost add=5000 chrtransform=dyel invfile=invhaxu
               prop1=str 8/8  prop2=openwounds 50/50  prop3=crush 20/20  prop4=dmg% 60/70
Bverrit Keep   enabled=1 rarity=1 lvl=26 lvl req=19 code=tow *type=Tower Shield
               prop1=ac 30/30 prop2=res-fire 75/75 prop3=str 5/5 prop4=red-mag 5/5
               prop5=ac% 80/120 prop6=block 10/10 prop7=dur 80/100
Nature's Peace version=100 enabled=1 ladder=1 rarity=3 lvl=77 lvl req=69 code=rin *type=ring
               prop1=noheal prop2=rip prop3=red-dmg 7/11 prop4=res-pois 20/30
               prop5=charged par5="Oak Sage" min5=27 max5=5

关键列:

列 用途
index 主键,同时是 string.tbl 的 key(T-20)
code 绑定的基础物品码
enabled 0 = 永不生成(16 行)
ladder 仅 ladder
rarity 同 code 下多个暗金之间的权重
lvl qlvl,要求 ilvl >= lvl
lvl req 穿戴等级
nolimit / carry1 携带限制
prop1-12 + par/min/max → Properties.code;par 是技能名 / 技能页参数
chrtransform / invtransform 染色

实现要求

  1. 加载表,剔除 Expansion 与 index 为空的行。
  2. 建 code → [UniqueItem] 的多值索引(一个基底可能对应多个暗金,按 rarity 加权选)。
  3. prop1-12 解析成 Property 引用;par 可能是字符串(技能名,如 "Oak Sage")也可能是数字,要兼容。
  4. 保留 index 字符串供 T-20 查 tbl。
  5. 生成时过滤:enabled=1、ilvl >= lvl、(非 ladder 环境下)ladder != 1。

陷阱

[!WARNING]
enabled=0 的 16 行必须排除在生成池外,但仍要加载(存档里可能有,要能显示)。

[!CAUTION]
parN 是异构字段 —— 可能是技能名字符串("Oak Sage")、技能页号、或空。不能无脑 parseInt。

[!NOTE]
.d2s 给 unique id 留 12 bit(0xFFF = 无),401 行安全。但要确认 id 的编号口径是行号还是别的 —— 需与 T-17 的存档实测对齐。

验收标准

  • 401 行全部解析,其中 enabled=1 恰好 385
  • code → [UniqueItem] 索引建立,每个 code 都能在全局物品码表里找到
  • 所有 propN 都能在 Properties 里解析到
  • parN 的字符串 / 数字两种形态都有测试覆盖
  • 抽样核对:The Gnasher(code=hax, lvl=7, 4 条属性) / Nature's Peace(ladder=1, charged + par 字符串)
  • npm run typecheck 0 error
  • npx vitest run 全绿
  • npx tsx scripts/verify-items.ts 新增断言通过

溯源

金标准(数据) 1.13c MPQ data\global\excel\ 下的 UniqueItems.txt(本机 /usr/local/google/home/taodao/d2-data,挂载序 d2data → d2exp → Patch_D2,Patch_D2 优先)
本 issue 结论强度 本机 1.13c 实测确证

[!WARNING]
D2MOO 是 1.10f,不是本项目的金标准。 它只能作线索使用。任何涉及常量、列序、整数截断位置或 RNG 消耗次数的结论,都必须回到 1.13c 的表格或 DLL 复核后再落地。

## 问题 暗金物品是品质判定(T-14)判到 `unique(7)` 之后的落点。没有这张表,判定出 unique 也无物可掉。 ## 金标准数据 **401 真实行**(403 原始行 − 1 行 `Expansion` − 1 行 index 空)× **70 列**,其中 **`enabled=1` 只有 385 行**。 列头: ``` index | version | enabled | ladder | rarity | nolimit | lvl | lvl req | code | *type | *uber | carry1 | cost mult | cost add | chrtransform | invtransform | flippyfile | invfile | dropsound | dropsfxframe | usesound | prop1..prop12 各带 par/min/max(12 组 × 4 = 48 列)| *eol ``` 真实样例: ``` The Gnasher enabled=1 rarity=1 lvl=7 lvl req=5 code=hax *type=Hand Axe cost mult=5 cost add=5000 chrtransform=dyel invfile=invhaxu prop1=str 8/8 prop2=openwounds 50/50 prop3=crush 20/20 prop4=dmg% 60/70 Bverrit Keep enabled=1 rarity=1 lvl=26 lvl req=19 code=tow *type=Tower Shield prop1=ac 30/30 prop2=res-fire 75/75 prop3=str 5/5 prop4=red-mag 5/5 prop5=ac% 80/120 prop6=block 10/10 prop7=dur 80/100 Nature's Peace version=100 enabled=1 ladder=1 rarity=3 lvl=77 lvl req=69 code=rin *type=ring prop1=noheal prop2=rip prop3=red-dmg 7/11 prop4=res-pois 20/30 prop5=charged par5="Oak Sage" min5=27 max5=5 ``` 关键列: | 列 | 用途 | |---|---| | `index` | 主键,**同时是 string.tbl 的 key**(T-20) | | `code` | 绑定的基础物品码 | | `enabled` | 0 = 永不生成(**16 行**) | | `ladder` | 仅 ladder | | `rarity` | 同 `code` 下多个暗金之间的权重 | | `lvl` | qlvl,要求 `ilvl >= lvl` | | `lvl req` | 穿戴等级 | | `nolimit` / `carry1` | 携带限制 | | `prop1-12` + `par/min/max` | → `Properties.code`;`par` 是技能名 / 技能页参数 | | `chrtransform` / `invtransform` | 染色 | ## 实现要求 1. 加载表,剔除 `Expansion` 与 index 为空的行。 2. 建 `code → [UniqueItem]` 的多值索引(一个基底可能对应多个暗金,按 `rarity` 加权选)。 3. `prop1-12` 解析成 Property 引用;`par` 可能是**字符串**(技能名,如 `"Oak Sage"`)也可能是数字,要兼容。 4. 保留 `index` 字符串供 T-20 查 tbl。 5. 生成时过滤:`enabled=1`、`ilvl >= lvl`、(非 ladder 环境下)`ladder != 1`。 ## 陷阱 > [!WARNING] > **`enabled=0` 的 16 行必须排除在生成池外**,但仍要加载(存档里可能有,要能显示)。 > [!CAUTION] > `parN` 是**异构字段** —— 可能是技能名字符串(`"Oak Sage"`)、技能页号、或空。不能无脑 `parseInt`。 > [!NOTE] > `.d2s` 给 unique id 留 **12 bit**(`0xFFF` = 无),401 行安全。但要确认 id 的编号口径是**行号**还是别的 —— 需与 T-17 的存档实测对齐。 ## 验收标准 - [ ] 401 行全部解析,其中 `enabled=1` 恰好 **385** - [ ] `code → [UniqueItem]` 索引建立,每个 `code` 都能在全局物品码表里找到 - [ ] 所有 `propN` 都能在 Properties 里解析到 - [ ] `parN` 的字符串 / 数字两种形态都有测试覆盖 - [ ] 抽样核对:`The Gnasher`(code=hax, lvl=7, 4 条属性) / `Nature's Peace`(ladder=1, charged + par 字符串) - [ ] `npm run typecheck` 0 error - [ ] `npx vitest run` 全绿 - [ ] `npx tsx scripts/verify-items.ts` 新增断言通过 --- ### 溯源 | | | |---|---| | 金标准(数据) | 1.13c MPQ `data\global\excel\` 下的 `UniqueItems.txt`(本机 `/usr/local/google/home/taodao/d2-data`,挂载序 d2data → d2exp → Patch_D2,**Patch_D2 优先**) | | 本 issue 结论强度 | **本机 1.13c 实测确证** | > [!WARNING] > **D2MOO 是 1.10f,不是本项目的金标准。** 它只能作线索使用。任何涉及常量、列序、整数截断位置或 RNG 消耗次数的结论,都必须回到 1.13c 的表格或 DLL 复核后再落地。
troytt added this to the [M10] 真实物品系统:500 基础物品、1000 词缀、TreasureClassEx 掉落树 milestone 2026-09-18 10:50:47 +00:00
Author
Owner

已完成并通过 1.13c MPQ 真实表验证(401 行暗金表,385 行 enabled,Oak Sage 字符串异构参数,code->[UniqueItem] 索引),合并入 main。

已完成并通过 1.13c MPQ 真实表验证(401 行暗金表,385 行 enabled,Oak Sage 字符串异构参数,code->[UniqueItem] 索引),合并入 main。
Sign in to join this conversation.
No Label
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#97
No description provided.