const DATA_START = 140; const RECORD_SIZE = 408; const STAT_KEYS = ["strength", "stamina", "intellect", "wisdom", "agility", "health", "mana"]; /** Players use FixArgTableID = 1; each vocation has two adjacent source records. */ export function vocationGrowth(buffer, classIndex) { const recordId = 301000 + classIndex * 2 + 1; const offset = DATA_START + (classIndex * 2 + 1) * RECORD_SIZE; if (offset + RECORD_SIZE > buffer.length || buffer.readInt32LE(offset) !== recordId || buffer.readInt32LE(offset + 4) !== recordId) { throw new Error(`Player vocation ${classIndex} record sentinel drifted.`); } const values = Array.from({ length: 21 }, (_, index) => { const value = buffer.readFloatLE(offset + 8 + index * 4); if (!Number.isFinite(value)) throw new Error(`Player vocation ${classIndex} has invalid growth.`); return Number(value.toFixed(5)); }); return Object.fromEntries(STAT_KEYS.map((key, index) => [key, { levelOne: values[index], flatGrowth: values[index + 7], percentGrowth: values[index + 14], }])); }