[P0][T01] 加载 ItemTypes.txt:类型树、Equiv 继承链、TreasureClass 与 Rarity 列 #89

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

问题

loadActTables 现在只加载 11 张地图 / 怪物表,物品表一张都没有。

ItemTypes.txt 必须最先做,因为它是两件事的共同底座:

  1. auto-TC 生成(T-12)—— TreasureClass=1 的类型会派生出 armo3/weap3 这类虚拟掉落节点
  2. 词缀 itype/etype 匹配(T-06/T-15)—— 白名单黑名单都是按 ItemType code 匹配,且要沿 Equiv 链向上递归

金标准数据

98 行(有 Code 的)× 37 列。原始 104 行里要剔除:2 行 None(索引 0/1)、3 行 Not Used(索引 14/17/23)、1 行 Expansion(索引 58)。

完整列头:

ItemType | Code | Equiv1 | Equiv2 | Repair | Body | BodyLoc1 | BodyLoc2 | Shoots | Quiver |
Throwable | Reload | ReEquip | AutoStack | Magic | Rare | Normal | Charm | Gem | Beltable |
MaxSock1 | MaxSock25 | MaxSock40 | TreasureClass | Rarity | StaffMods | CostFormula | Class |
VarInvGfx | InvGfx1..InvGfx6 | StorePage | *eol

真实样例:

idx2  ItemType=Shield Code=shie Equiv1=shld Body=1 BodyLoc1=rarm BodyLoc2=larm Rare=1
      MaxSock1=3 MaxSock25=3 MaxSock40=4 Rarity=3 CostFormula=1 StorePage=armo
idx3  ItemType=Armor  Code=tors Equiv1=armo BodyLoc1/2=tors Rare=1
      MaxSock1=3 MaxSock25=4 MaxSock40=6 Rarity=3 StorePage=armo
      ItemType=Gold   Code=gold Equiv1=misc Normal=1 MaxSock*=0 CostFormula=0
      ItemType=Wand   Code=wand Equiv1=rod  Rare=1 MaxSock*=2 Rarity=1 StaffMods=nec

⭐ TreasureClass=1 的全部 5 行(auto-TC 的种子)

ItemType Code Rarity Equiv
Bow bow 3 miss
Weapon weap 3 —
Melee Weapon mele 3 weap
Any Armor armo 3 —
Amazon Bow abow 1 bow / amaz

全表就只有这 5 行,T-12 的输入就是它们。

实现要求

  1. 在 loadActTables 里加载 data\global\excel\ItemTypes.txt。
  2. 建 Code → ItemTypeRow 索引。
  3. 实现 Equiv 链向上递归的类型判定:isA(typeCode, ancestorCode) 要能沿 Equiv1/Equiv2 一路向上(例如 shie → shld,mele → weap)。这个函数后面被词缀匹配和 auto-TC 反复调用,必须做记忆化。
  4. 关键列要落到类型对象上:Equiv1/Equiv2、TreasureClass、Rarity、MaxSock1/25/40、Magic/Rare/Normal/Charm/Gem、StaffMods、Body/BodyLoc1/BodyLoc2、Beltable、Class。
  5. MaxSock1|25|40 是按 ilvl 分三段的插槽上限(1-24 / 25-39 / 40+),供 T-18 使用。

陷阱

[!CAUTION]
前两行是 None 占位,索引 0/1 不可用,中间还有 3 行 Not Used(索引 14/17/23)。不能按行号索引这张表,必须按 Code 建字典并跳过空 Code 行。

[!WARNING]
Rarity 列的取值是 3 / 1 / 2 / 空,它是 auto-TC 的权重乘数,不是「稀有度」。别和 Armor/Weapons 里那个同名的 rarity 列混淆 —— 那个是物品自身在桶内的权重。

验收标准

  • 98 行全部解析(跳过 None / Not Used / Expansion)
  • TreasureClass=1 的行恰好 5 个,Code 为 bow / weap / mele / armo / abow
  • Equiv 链递归正确:isA('shie','shld') === true、isA('mele','weap') === true、isA('wand','rod') === true
  • Equiv 链有环保护(理论上不该有环,但要防御)
  • npm run typecheck 0 error
  • npx vitest run 全绿
  • npx tsx scripts/verify-items.ts 新增断言通过

溯源

金标准(数据) 1.13c MPQ data\global\excel\ 下的 ItemTypes.txt(本机 /usr/local/google/home/taodao/d2-data,挂载序 d2data → d2exp → Patch_D2,Patch_D2 优先)
本 issue 结论强度 本机 1.13c 实测确证(行数、列头、5 个 TreasureClass 种子均为实跑结果)

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

## 问题 [`loadActTables`](https://git.projectdiablo2.cn/troytt/diablo2-web/src/branch/main/src/game/acts.ts) 现在只加载 11 张地图 / 怪物表,**物品表一张都没有**。 `ItemTypes.txt` 必须最先做,因为它是两件事的共同底座: 1. **auto-TC 生成**(T-12)—— `TreasureClass=1` 的类型会派生出 `armo3`/`weap3` 这类虚拟掉落节点 2. **词缀 itype/etype 匹配**(T-06/T-15)—— 白名单黑名单都是按 ItemType code 匹配,且要沿 Equiv 链向上递归 ## 金标准数据 **98 行**(有 Code 的)× **37 列**。原始 104 行里要剔除:2 行 `None`(索引 0/1)、3 行 `Not Used`(索引 14/17/23)、1 行 `Expansion`(索引 58)。 完整列头: ``` ItemType | Code | Equiv1 | Equiv2 | Repair | Body | BodyLoc1 | BodyLoc2 | Shoots | Quiver | Throwable | Reload | ReEquip | AutoStack | Magic | Rare | Normal | Charm | Gem | Beltable | MaxSock1 | MaxSock25 | MaxSock40 | TreasureClass | Rarity | StaffMods | CostFormula | Class | VarInvGfx | InvGfx1..InvGfx6 | StorePage | *eol ``` 真实样例: ``` idx2 ItemType=Shield Code=shie Equiv1=shld Body=1 BodyLoc1=rarm BodyLoc2=larm Rare=1 MaxSock1=3 MaxSock25=3 MaxSock40=4 Rarity=3 CostFormula=1 StorePage=armo idx3 ItemType=Armor Code=tors Equiv1=armo BodyLoc1/2=tors Rare=1 MaxSock1=3 MaxSock25=4 MaxSock40=6 Rarity=3 StorePage=armo ItemType=Gold Code=gold Equiv1=misc Normal=1 MaxSock*=0 CostFormula=0 ItemType=Wand Code=wand Equiv1=rod Rare=1 MaxSock*=2 Rarity=1 StaffMods=nec ``` ### ⭐ `TreasureClass=1` 的全部 5 行(auto-TC 的种子) | ItemType | Code | Rarity | Equiv | |---|---|---|---| | Bow | `bow` | 3 | miss | | Weapon | `weap` | 3 | — | | Melee Weapon | `mele` | 3 | weap | | Any Armor | `armo` | 3 | — | | Amazon Bow | `abow` | 1 | bow / amaz | 全表就只有这 5 行,T-12 的输入就是它们。 ## 实现要求 1. 在 `loadActTables` 里加载 `data\global\excel\ItemTypes.txt`。 2. 建 `Code → ItemTypeRow` 索引。 3. 实现 **Equiv 链向上递归**的类型判定:`isA(typeCode, ancestorCode)` 要能沿 `Equiv1`/`Equiv2` 一路向上(例如 `shie → shld`,`mele → weap`)。这个函数后面被词缀匹配和 auto-TC 反复调用,**必须做记忆化**。 4. 关键列要落到类型对象上:`Equiv1/Equiv2`、`TreasureClass`、`Rarity`、`MaxSock1/25/40`、`Magic/Rare/Normal/Charm/Gem`、`StaffMods`、`Body/BodyLoc1/BodyLoc2`、`Beltable`、`Class`。 5. `MaxSock1|25|40` 是**按 ilvl 分三段**的插槽上限(1-24 / 25-39 / 40+),供 T-18 使用。 ## 陷阱 > [!CAUTION] > **前两行是 `None` 占位,索引 0/1 不可用**,中间还有 3 行 `Not Used`(索引 14/17/23)。**不能按行号索引这张表**,必须按 `Code` 建字典并跳过空 Code 行。 > [!WARNING] > `Rarity` 列的取值是 3 / 1 / 2 / 空,它是 **auto-TC 的权重乘数**,不是「稀有度」。别和 Armor/Weapons 里那个同名的 `rarity` 列混淆 —— 那个是物品自身在桶内的权重。 ## 验收标准 - [ ] 98 行全部解析(跳过 None / Not Used / Expansion) - [ ] `TreasureClass=1` 的行**恰好 5 个**,Code 为 `bow` / `weap` / `mele` / `armo` / `abow` - [ ] Equiv 链递归正确:`isA('shie','shld') === true`、`isA('mele','weap') === true`、`isA('wand','rod') === true` - [ ] Equiv 链有环保护(理论上不该有环,但要防御) - [ ] `npm run typecheck` 0 error - [ ] `npx vitest run` 全绿 - [ ] `npx tsx scripts/verify-items.ts` 新增断言通过 --- ### 溯源 | | | |---|---| | 金标准(数据) | 1.13c MPQ `data\global\excel\` 下的 `ItemTypes.txt`(本机 `/usr/local/google/home/taodao/d2-data`,挂载序 d2data → d2exp → Patch_D2,**Patch_D2 优先**) | | 本 issue 结论强度 | **本机 1.13c 实测确证**(行数、列头、5 个 TreasureClass 种子均为实跑结果) | > [!WARNING] > **D2MOO 是 1.10f,不是本项目的金标准。** 它只能作线索使用。任何涉及常量、列序、整数截断位置或 RNG 消耗次数的结论,都必须回到 1.13c 的表格或 DLL 复核后再落地。
troytt added this to the [M10] 真实物品系统:500 基础物品、1000 词缀、TreasureClassEx 掉落树 milestone 2026-09-18 10:50:44 +00:00
Author
Owner

已完成并通过 real MPQ 验证(98行有效类型,5个 auto-TC 种子,Equiv 继承链),合并入 main (commit 5e5d897)。

已完成并通过 real MPQ 验证(98行有效类型,5个 auto-TC 种子,Equiv 继承链),合并入 main (commit 5e5d897)。
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#89
No description provided.