fix(packer): 修正 monsters 前缀长度,恢复全部 NPC 美术解析 (refs #6)
打包器在切分 MPQ 成员名时,objects 走 `OBJECT_PREFIX.length`,
monsters 却硬编码了一个手数的 `22`。`data\global\monsters\` 的真实
长度是 **21**,于是每个怪物 token 都被多切掉一个字符:
slice(21) -> "DC" (正确)
slice(22) -> "C" (实际发生的)
`monsterMembers` 因此以 `C`/`E`/`R`/`S`/`J` 这些残缺 token 建索引,
而查表时用的是正确的 `DC`/`JE`/`XR`/`XS`/`0J`,导致**每一次 NPC 美术
查找都必然落空**。由于代码里对"找不到"是静默跳过,这个缺陷不会报错,
只会让 NPC 全部变成没有贴图的空对象——在真实 MPQ 到位之前完全无法察觉。
改为引入 `MONSTER_PREFIX` 常量并由 `.length` 推导,消除手数魔数。
实测(覆盖全部 365 个 scene.json):
NPC 实例总数 103 103
其中解析出 COF 成员 0 -> 103
其中解析出精灵帧 0 -> 103
按 token 分解,修复后全部满额:
0J 82/82、DC 4/4、HR 2/2、JE 4/4、XR 2/2、XS 9/9。
抽查:Deckard Cain 现在解析到
`data\global\monsters\DC\TR\DCTRLITNUHTH.dcc`,帧 43x75,偏移 (-45,-54)。
普通场景物件仍走 `objects\`,未受影响。
This commit is contained in:
parent
cd87c2c5fa
commit
68c7890eee
|
|
@ -64,6 +64,8 @@ const PAGE_SIZE = 2048
|
|||
const HOT_RADIUS_CELLS = 8
|
||||
/** Where object art lives. */
|
||||
const OBJECT_PREFIX = 'data\\global\\objects\\'
|
||||
/** Where monster and town-NPC art lives. */
|
||||
const MONSTER_PREFIX = 'data\\global\\monsters\\'
|
||||
/**
|
||||
* Mode directories tried in order when picking an object's art.
|
||||
*
|
||||
|
|
@ -347,9 +349,12 @@ const objectMembers = new Map<string, Map<string, string[]>>()
|
|||
const monsterMembers = new Map<string, Map<string, string[]>>()
|
||||
for (const name of allNames) {
|
||||
const isObj = name.toLowerCase().startsWith(OBJECT_PREFIX.toLowerCase())
|
||||
const isMon = name.toLowerCase().startsWith('data\\global\\monsters\\')
|
||||
const isMon = name.toLowerCase().startsWith(MONSTER_PREFIX.toLowerCase())
|
||||
if (!isObj && !isMon) continue
|
||||
const prefixLen = isObj ? OBJECT_PREFIX.length : 22 // 'data\\global\\monsters\\'.length
|
||||
// Derive the length; a hand-counted magic number here was off by one (22 vs
|
||||
// the real 21), which sliced the first letter off every monster token and
|
||||
// silently broke all NPC art lookups.
|
||||
const prefixLen = isObj ? OBJECT_PREFIX.length : MONSTER_PREFIX.length
|
||||
const rest = name.slice(prefixLen).split('\\')
|
||||
if (rest.length < 3) continue
|
||||
const token = (rest[0] ?? '').toUpperCase()
|
||||
|
|
|
|||
Loading…
Reference in New Issue