Files
2026-10-30 23:54:07 +07:00

54 lines
2.5 KiB
JavaScript

// Writes resources/grid_fight/chimera.json from the decoded 4.6.54 Beast Garden
// tables (GridFightChimeraInfoConfigRow, GridFightChimeraShopPoolConfigRow).
// Input: a directory holding the two decoded *.jsonl files (CW-SPECIAL-PROOF G1,
// cwsp/tables.mjs output). Every FixPoint of the 4.6.54 tables is 4x its real
// value (CW-SPECIAL-PROOF G2), so EffectParamList is divided by 4 here; the
// integer columns (IDs, Star, RoleID, LimitNum, Param) are copied as they are.
//
// node tools/gridfight-extract-node/chimera.mjs --tables <dir> --output resources/grid_fight/chimera.json
import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
function arg(name) {
const i = process.argv.indexOf('--' + name);
if (i < 0 || i + 1 >= process.argv.length) throw new Error('missing --' + name);
return process.argv[i + 1];
}
function rows(file) {
return fs.readFileSync(file, 'utf8').split('\n').filter(Boolean).map((line) => JSON.parse(line));
}
const dir = arg('tables');
const out = arg('output');
const infoFile = path.join(dir, 'GridFightChimeraInfoConfigRow.jsonl');
const poolFile = path.join(dir, 'GridFightChimeraShopPoolConfigRow.jsonl');
const text = (s) => (typeof s === 'string' ? s.replace(/^T:/, '') : '');
// 0.1 steps survive the /4: round to 6 places to drop float noise.
const real = (v) => Math.round((v / 4) * 1e6) / 1e6;
const info = rows(infoFile).map((r) => ({
id: r.ID,
star: r.Star,
role_id: r.RoleID ?? 0,
limit: r.LimitNum ?? 0,
params: (r.EffectParamList ?? []).map(real),
name: text(r.NameDesc),
}));
info.sort((a, b) => a.id - b.id || a.star - b.star);
const pool = rows(poolFile).map((r) => ({ id: r.ID, type: r.Type, param: r.Param }));
pool.sort((a, b) => a.id - b.id);
const sha = (f) => crypto.createHash('sha256').update(fs.readFileSync(f)).digest('hex');
const doc = {
provenance: {
source: 'RPG.GameCore.GridFightChimeraInfoConfigRow / GridFightChimeraShopPoolConfigRow, client OSBETAWin4.6.54 (BakedConfig/ExcelOutput/GridFightChimeraInfo.bytes, GridFightChimeraShopPool.bytes)',
note: 'params are the table FixPoints divided by 4 (CW-SPECIAL-PROOF G2); limit = LimitNum (cap of owned copies at that star); pool type 1 chimera, 2 consumable item, 3 gold; the pool has no weight column',
info_sha256: sha(infoFile),
pool_sha256: sha(poolFile),
},
info,
pool,
};
fs.writeFileSync(out, JSON.stringify(doc, null, 2) + '\n');
console.log(`chimera.json: ${info.length} info rows, ${pool.length} pool rows`);