const ITEM_CLASS_FIELD = 68; const ITEM_SUBCLASS_MASK_FIELD = 69; const ITEM_INVENTORY_MASK_FIELD = 70; /** Read equipped-item metadata from a client Spell.dbc using its fixed fields. */ export function spellDbcEquipmentMetadata(buffer) { if (!Buffer.isBuffer(buffer) || buffer.toString("ascii", 0, 4) !== "WDBC") { throw new Error("Spell.dbc is not WDBC data"); } const recordCount = buffer.readUInt32LE(4); const fieldCount = buffer.readUInt32LE(8); const recordSize = buffer.readUInt32LE(12); if (fieldCount <= ITEM_INVENTORY_MASK_FIELD || recordSize < fieldCount * 4 || buffer.length < 20 + recordCount * recordSize) { throw new Error("Spell.dbc has an unsupported equipped-item schema"); } const rows = new Map(); for (let index = 0; index < recordCount; index += 1) { const base = 20 + index * recordSize; const id = buffer.readUInt32LE(base); if (rows.has(id)) throw new Error(`Spell.dbc repeats spell ID ${id}`); rows.set(id, { equippedItemClass: buffer.readInt32LE(base + ITEM_CLASS_FIELD * 4), equippedItemSubclassMask: buffer.readInt32LE(base + ITEM_SUBCLASS_MASK_FIELD * 4), equippedItemInventoryMask: buffer.readUInt32LE(base + ITEM_INVENTORY_MASK_FIELD * 4), }); } return rows; }