fix(drop): 修正打怪掉落间距过大、掉落物与背包丢弃物元数据不一致、背包丢弃物品重叠三大问题 #479

Closed
opened 2026-09-26 04:20:45 +00:00 by troytt · 0 comments
Owner

问题描述

  1. 打怪掉落的物品图标间隔太大,和原版不符合

    • 原版 D2 v1.13c (COLLISION_GetFreeCoordinatesImpl @ 0x6FD9D140 / D2GAME_DropItem @ 0x6FC45670) 中,地面掉落物按 子格 (sub-tile, 16×8 px) 菱形晶格就近散落。
    • 当前 GameEngine.triggerMonsterDrop 和 net-scene.ts 将怪物死亡坐标通过 worldToCell 转为 宏格子 (80×40 px = 5×5 子格) 并调用 findSafeDropPosition,每次步进整整一个 80×40 地板宏格,导致掉落物间距比原版放大了 5 倍。
  2. 打怪掉落物品和从身上扔下来的物品逻辑不一致(比如名字一个是纯英文一个是中英)

    • 怪物掉落通过 createDroppedItem 生成的原始 Item 只有纯英文 name、无 nameZh,且符文的 quality 为数值 ItemQuality.NORMAL (2)。
    • 从背包/身上扔下的物品经过 itemToUiInventoryItem 转换后包含中英双语 nameZh(如 "轻度治疗药剂 (Light Healing Potion)")以及字符串品质(如符文为 rune)。
    • resolveGroundItemMetadata 直接回退到 item.nameZh ?? item.name,导致怪物掉落显示纯英文、符文显示白字,而从身上扔下显示中英双语、符文显示橙字。
  3. 身上扔下来的不同物品图标不应该叠在一起(比如血瓶)

    • act-scene.ts 的 onDropItemToGround 调用 findSafeDropPosition 时未传入第 5 个参数 occupied(当前地面物品列表),永远返回玩家脚下 Ring 0 坐标,随后将固定的 playerCell.x, playerCell.y 显式传给 engine.dropItem。
    • engine.dropItem 中 const cx = cellX ?? dropPos.cellX 被传入的 playerCell 覆盖,导致已散落物品记录的 cellX/cellY 始终停留在玩家原点,后续扔出的第 2~N 个血瓶/物品全部叠在同一个 Ring 1 坐标上。

修复方案

  • 统一 GameEngine.triggerMonsterDrop、GameEngine.dropItem、GameEngine.dropGold 及 net-scene.ts 使用 findIsometricDropPosition (16×8 px 子格菱形晶格散落 + COLLIDE_MASK_SPAWN / COLLIDE_MASK_SPAWN_LOS 碰撞与视线校验)。
  • 在 resolveGroundItemMetadata 中统一双语名称构建逻辑 (formatBilingualGroundItemName) 与符文品质识别 (isRuneCode -> rune),保证怪物掉落与玩家丢弃的地面物品名称、品质颜色、音效与贴图元数据完全一致。
  • 移除 act-scene.ts 中多余的无占用预寻点与 cellX/cellY 覆盖,使玩家连续丢弃物品时按 16×8 子格螺旋散开,绝不重叠。
## 问题描述 1. **打怪掉落的物品图标间隔太大,和原版不符合** - 原版 D2 v1.13c (`COLLISION_GetFreeCoordinatesImpl` @ `0x6FD9D140` / `D2GAME_DropItem` @ `0x6FC45670`) 中,地面掉落物按 **子格 (sub-tile, `16×8` px)** 菱形晶格就近散落。 - 当前 `GameEngine.triggerMonsterDrop` 和 `net-scene.ts` 将怪物死亡坐标通过 `worldToCell` 转为 **宏格子 (`80×40` px = 5×5 子格)** 并调用 `findSafeDropPosition`,每次步进整整一个 `80×40` 地板宏格,导致掉落物间距比原版放大了 5 倍。 2. **打怪掉落物品和从身上扔下来的物品逻辑不一致(比如名字一个是纯英文一个是中英)** - 怪物掉落通过 `createDroppedItem` 生成的原始 `Item` 只有纯英文 `name`、无 `nameZh`,且符文的 `quality` 为数值 `ItemQuality.NORMAL (2)`。 - 从背包/身上扔下的物品经过 `itemToUiInventoryItem` 转换后包含中英双语 `nameZh`(如 `"轻度治疗药剂 (Light Healing Potion)"`)以及字符串品质(如符文为 `rune`)。 - `resolveGroundItemMetadata` 直接回退到 `item.nameZh ?? item.name`,导致怪物掉落显示纯英文、符文显示白字,而从身上扔下显示中英双语、符文显示橙字。 3. **身上扔下来的不同物品图标不应该叠在一起(比如血瓶)** - `act-scene.ts` 的 `onDropItemToGround` 调用 `findSafeDropPosition` 时未传入第 5 个参数 `occupied`(当前地面物品列表),永远返回玩家脚下 Ring 0 坐标,随后将固定的 `playerCell.x, playerCell.y` 显式传给 `engine.dropItem`。 - `engine.dropItem` 中 `const cx = cellX ?? dropPos.cellX` 被传入的 `playerCell` 覆盖,导致已散落物品记录的 `cellX/cellY` 始终停留在玩家原点,后续扔出的第 2~N 个血瓶/物品全部叠在同一个 Ring 1 坐标上。 ## 修复方案 - 统一 `GameEngine.triggerMonsterDrop`、`GameEngine.dropItem`、`GameEngine.dropGold` 及 `net-scene.ts` 使用 `findIsometricDropPosition` (`16×8` px 子格菱形晶格散落 + `COLLIDE_MASK_SPAWN` / `COLLIDE_MASK_SPAWN_LOS` 碰撞与视线校验)。 - 在 `resolveGroundItemMetadata` 中统一双语名称构建逻辑 (`formatBilingualGroundItemName`) 与符文品质识别 (`isRuneCode` -> `rune`),保证怪物掉落与玩家丢弃的地面物品名称、品质颜色、音效与贴图元数据完全一致。 - 移除 `act-scene.ts` 中多余的无占用预寻点与 `cellX/cellY` 覆盖,使玩家连续丢弃物品时按 `16×8` 子格螺旋散开,绝不重叠。
Sign in to join this conversation.
No Label
No Milestone
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#479
No description provided.