[Asset/Render Parity] 超大护身符 (Grand Charm) 地面掉落图标误配为毁灭小护身符 (flpmss),应修正为 flpchm3 #452

Closed
opened 2026-09-24 12:35:48 +00:00 by troytt · 0 comments
Owner

1. 问题描述 (Bug Description)

在当前游戏中,当玩家将超大护身符 (Grand Charm / code: cm3,如各类职业技能板、普通超大护身符、基德的运气等) 从背包丢弃到地面,或怪物击杀掉落时:

  • 其地面小图标 (Ground Sprite / Flippy 动画静止帧) 被错误渲染为一颗微小的深黑色椭圆小石头。
  • 经核对,该贴图实际上是暗金小护身符 毁灭 (Annihilus / 墨菲斯托灵魂石 flpmss,9x4 px) 的地面素材,而非超大护身符的长条形地面积木符文石。

这导致地面上的超大护身符视觉比例严重失真(只有 9x4 像素,比 1x1 物品还小),且外观与小护身符混淆,严重违背暗黑 2 原版掉落外观。


2. 原版 Diablo II v1.13c 核心机制规范 (Ground Truth Invariants)

依据官方 MPQ 数据表 (Misc.txt / UniqueItems.txt) 与 DC6 精灵资产:

  1. 小型护身符 (Small Charm, code: cm1, 1x1):

    • 基础地面素材 (flippyfile) 为 flpchm1 (13x5 px);
    • 特例:仅暗金小护身符 毁灭 (Annihilus, code: anni) 在 UniqueItems.txt 中指定 flippyfile = flpmss (使用灵魂石地面贴图)。
  2. 大型护身符 (Large Charm, code: cm2, 1x2):

    • 基础地面素材 (flippyfile) 为 flpchm2 (13x6 px);
    • 特例:仅暗金大护身符 地狱火炬 (Hellfire Torch, code: torch) 指定 flippyfile = flptrch。
  3. 超大型护身符 (Grand Charm, code: cm3, 1x3):

    • 基础地面素材 (flippyfile) 必须为 flpchm3 (21x6 px 的长条形符文石);
    • 暗金超大护身符 基德的运气 (Gheed's Fortune, code: gheeds) 依据 UniqueItems.txt 同样使用标准超大护身符地面贴图 flpchm3,绝不能使用 flpmss!

3. 缺陷代码定位与根因分析 (Root Cause Analysis)

  1. scripts/pack-ui.ts 中硬编码映射错误:
    在 scripts/pack-ui.ts 第 739–745 行:

    codeToFlippyFile['cm1'] = 'flpmss'
    codeToFlippyFile['cm2'] = 'flptrch'
    codeToFlippyFile['cm3'] = 'flpmss' // 错误:将超大护身符硬编码为了灵魂石/毁灭
    codeToFlippyFile['gheeds'] = 'flpmss' // 错误:将基德的运气也硬编码为了灵魂石/毁灭
    codeToFlippyFile["Gheed's Fortune"] = 'flpmss'
    
  2. 生成的元数据 src/ui/baked-ui-meta.ts 固化了该错误:
    第 2589–2591 行及第 3297 行:

    "cm1": "flpmss",
    "cm2": "flptrch",
    "cm3": "flpmss",
    "Gheed's Fortune": "flpmss",
    "gheeds": "flpmss",
    

    而 src/ui/baked-ui-meta.ts 的 flippyRects 中实际上完整包含了正规的 flpchm1, flpchm2, flpchm3 贴图(第 7677–7694 行),但由于 codeToFlippyFile 映射被篡改,resolveGroundItemSpriteRect 取到了 flpmss。


4. 修复方案 (Proposed Implementation)

  1. 修正 scripts/pack-ui.ts:
    将护身符的 codeToFlippyFile 恢复为 1.13c 真实规范:
    codeToFlippyFile['cm1'] = 'flpchm1'
    codeToFlippyFile['cm2'] = 'flpchm2'
    codeToFlippyFile['cm3'] = 'flpchm3'
    codeToFlippyFile['gheeds'] = 'flpchm3'
    codeToFlippyFile["Gheed's Fortune"] = 'flpchm3'
    codeToFlippyFile['anni'] = 'flpmss'
    codeToFlippyFile['Annihilus'] = 'flpmss'
    codeToFlippyFile['torch'] = 'flptrch'
    codeToFlippyFile['Hellfire Torch'] = 'flptrch'
    
  2. 同步更��� src/ui/baked-ui-meta.ts 中的 codeToFlippyFile 对应键值。
  3. 在 src/ui/inventory.ts 的 resolveGroundItemSpriteRect 中补全护身符显式防回退逻辑:
    在查表前增加针对 cm1, cm2, cm3 及其中文名称(超大护身符、超大型护身符、grand charm)的断言与定向解析,确保任何途径生成的超大护身符都能百分之百精准命中 flpchm3。

5. 验收标准 (Acceptance Criteria)

  1. 普通超大护身符、技能板、基德的运气扔在地上时,地面图标正确显示为 21x6 px 的长条形超大护身符精灵 (flpchm3)。
  2. 普通小护身符显示为 flpchm1 (13x5 px),毁灭小护身符保留 flpmss (9x4 px)。
  3. 普通大护身符显示为 flpchm2 (13x6 px),地狱火炬保留 flptrch。
  4. 构建与测试 (npm run typecheck, npm test) 100% 绿色通过。
### 1. 问题描述 (Bug Description) 在当前游戏中,当玩家将**超大护身符 (Grand Charm / code: `cm3`,如各类职业技能板、普通超大护身符、基德的运气等)** 从背包丢弃到地面,或怪物击杀掉落时: - 其地面小图标 (Ground Sprite / Flippy 动画静止帧) 被错误渲染为一颗微小的深黑色椭圆小石头。 - 经核对,该贴图实际上是暗金小护身符 **毁灭 (Annihilus / 墨菲斯托灵魂石 `flpmss`,9x4 px)** 的地面素材,而非超大护身符的长条形地面积木符文石。 这导致地面上的超大护身符视觉比例严重失真(只有 9x4 像素,比 1x1 物品还小),且外观与小护身符混淆,严重违背暗黑 2 原版掉落外观。 --- ### 2. 原版 Diablo II v1.13c 核心机制规范 (Ground Truth Invariants) 依据官方 MPQ 数据表 (`Misc.txt` / `UniqueItems.txt`) 与 DC6 精灵资产: 1. **小型护身符 (Small Charm, code: `cm1`, 1x1)**: - 基础地面素材 (`flippyfile`) 为 **`flpchm1`** (13x5 px); - 特例:仅暗金小护身符 **毁灭 (Annihilus, code: `anni`)** 在 `UniqueItems.txt` 中指定 `flippyfile = flpmss` (使用灵魂石地面贴图)。 2. **大型护身符 (Large Charm, code: `cm2`, 1x2)**: - 基础地面素材 (`flippyfile`) 为 **`flpchm2`** (13x6 px); - 特例:仅暗金大护身符 **地狱火炬 (Hellfire Torch, code: `torch`)** 指定 `flippyfile = flptrch`。 3. **超大型护身符 (Grand Charm, code: `cm3`, 1x3)**: - 基础地面素材 (`flippyfile`) 必须为 **`flpchm3`** (21x6 px 的长条形符文石); - 暗金超大护身符 **基德的运气 (Gheed's Fortune, code: `gheeds`)** 依据 `UniqueItems.txt` 同样使用标准超大护身符地面贴图 **`flpchm3`**,**绝不能使用 `flpmss`**! --- ### 3. 缺陷代码定位与根因分析 (Root Cause Analysis) 1. **`scripts/pack-ui.ts` 中硬编码映射错误**: 在 `scripts/pack-ui.ts` 第 739–745 行: ```typescript codeToFlippyFile['cm1'] = 'flpmss' codeToFlippyFile['cm2'] = 'flptrch' codeToFlippyFile['cm3'] = 'flpmss' // 错误:将超大护身符硬编码为了灵魂石/毁灭 codeToFlippyFile['gheeds'] = 'flpmss' // 错误:将基德的运气也硬编码为了灵魂石/毁灭 codeToFlippyFile["Gheed's Fortune"] = 'flpmss' ``` 2. **生成的元数据 `src/ui/baked-ui-meta.ts` 固化了该错误**: 第 2589–2591 行及第 3297 行: ```typescript "cm1": "flpmss", "cm2": "flptrch", "cm3": "flpmss", "Gheed's Fortune": "flpmss", "gheeds": "flpmss", ``` 而 `src/ui/baked-ui-meta.ts` 的 `flippyRects` 中实际上完整包含了正规的 `flpchm1`, `flpchm2`, `flpchm3` 贴图(第 7677–7694 行),但由于 `codeToFlippyFile` 映射被篡改,`resolveGroundItemSpriteRect` 取到了 `flpmss`。 --- ### 4. 修复方案 (Proposed Implementation) 1. **修正 `scripts/pack-ui.ts`**: 将护身符的 `codeToFlippyFile` 恢复为 1.13c 真实规范: ```typescript codeToFlippyFile['cm1'] = 'flpchm1' codeToFlippyFile['cm2'] = 'flpchm2' codeToFlippyFile['cm3'] = 'flpchm3' codeToFlippyFile['gheeds'] = 'flpchm3' codeToFlippyFile["Gheed's Fortune"] = 'flpchm3' codeToFlippyFile['anni'] = 'flpmss' codeToFlippyFile['Annihilus'] = 'flpmss' codeToFlippyFile['torch'] = 'flptrch' codeToFlippyFile['Hellfire Torch'] = 'flptrch' ``` 2. **同步更��� `src/ui/baked-ui-meta.ts`** 中的 `codeToFlippyFile` 对应键值。 3. **在 `src/ui/inventory.ts` 的 `resolveGroundItemSpriteRect` 中补全护身符显式防回退逻辑**: 在查表前增加针对 `cm1`, `cm2`, `cm3` 及其中文名称(`超大护身符`、`超大型护身符`、`grand charm`)的断言与定向解析,确保任何途径生成的超大护身符都能百分之百精准命中 `flpchm3`。 --- ### 5. 验收标准 (Acceptance Criteria) 1. 普通超大护身符、技能板、基德的运气扔在地上时,地面图标正确显示为 21x6 px 的长条形超大护身符精灵 (`flpchm3`)。 2. 普通小护身符显示为 `flpchm1` (13x5 px),毁灭小护身符保留 `flpmss` (9x4 px)。 3. 普通大护身符显示为 `flpchm2` (13x6 px),地狱火炬保留 `flptrch`。 4. 构建与测试 (`npm run typecheck`, `npm test`) 100% 绿色通过。
troytt added this to the [M18] 打怪掉落物品:怪物死亡掉落全链路 1.13c 还原 milestone 2026-09-24 12:35:48 +00:00
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#452
No description provided.