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

67 lines
3.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import * as r from './rewards.mjs';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
const fix = n => ({wire: BigInt(Math.round(n * 4294967296))});
test('fixed decodes Q32.32 and rounds the float noise of the client', () => {
assert.equal(r.fixed({wire: 4294967300}), 1);
assert.equal(r.fixed({wire: 343597384}), 0.08);
assert.equal(r.fixed({wire: 103079215104}), 24);
assert.equal(r.fixed(undefined), 0);
});
test('elite resource: ids follow family*100+quality and tables are sorted', () => {
const out = r.eliteResource({
GridFightBinaryNodeRuleConfigRow: [{ID: 10302, Quality: 2, PerformLevel: 2}, {ID: 1, Quality: 1, PerformLevel: 1}, {ID: 10301, Quality: 1, PerformLevel: 1}],
GridFightBinaryDiffAddRuleConfigRow: [{ID: 2, Quality: 1}, {ID: 1, Quality: 2, EnemyDifficultyAddValue: 5}],
GridFightEnemyDifficultyLvConfigRow: [{ChapterID: 2, EnemyDifficultyLevel: 1, HPRatio: fix(4.16)}, {ChapterID: 1, HPRatio: fix(4)}]
});
assert.deepEqual(out.node_rules.map(x => [x.id, x.family, x.quality]), [[1, 0, 1], [10301, 103, 1], [10302, 103, 2]]);
assert.deepEqual(out.diff_add, [{rule: 1, quality: 2, add: 5}, {rule: 2, quality: 1, add: 0}]);
assert.deepEqual(out.difficulty.map(x => [x.chapter, x.level, x.hp]), [[1, 0, 4], [2, 1, 4.16]]);
assert.throws(() => r.eliteResource({
GridFightBinaryNodeRuleConfigRow: [{ID: 10399, Quality: 2}],
GridFightBinaryDiffAddRuleConfigRow: [],
GridFightEnemyDifficultyLvConfigRow: []
}), /family\*100\+quality/);
});
test('goods resource keeps only SpecialGoods projections and classifies series', () => {
const out = r.goodsResource({
GridFightProjectionConfigRow: [
{ID: 1509, RoleID: 1509, Rarity: 2, MazebuffID: 35610001, UnlockType: 1, ParamList: [{wire: 343597384}]},
{ID: 7, RoleID: 7, UnlockType: 0}
],
GridFightSpecialGoodsConfigRow: [
{ID: 401, GroupID: 3, Quality: 1, LowerGoodID: 301, JsonPath: 'Config/Level/GridFight/SpecialGoods/Aha/GridFightAhaGoods401.json', EffectParamList: [{wire: 51539607552}]},
{ID: 101, GroupID: 1, Cost: 24, Quality: 1, JsonPath: 'Config/Level/GridFight/SpecialGoods/Cyrene/GridFightCyreneGoods101.json'}
]
});
assert.deepEqual(out.projections, [{id: 1509, role_id: 1509, rarity: 2, mazebuff_id: 35610001, params: [0.08]}]);
assert.deepEqual(out.special_goods.map(g => [g.id, g.series, g.cost, g.lower_good_id, g.params]), [[101, 'Cyrene', 24, 0, []], [401, 'Aha', 0, 301, [12]]]);
assert.equal(out.unlock_case, 1684);
assert.deepEqual(out.grants, []);
assert.throws(() => r.goodsResource({
GridFightProjectionConfigRow: [],
GridFightSpecialGoodsConfigRow: [{ID: 1, GroupID: 9, JsonPath: 'Config/Other/x.json'}]
}), /Unknown SpecialGoods series/);
});
test('installed resources agree with the extractor contract', () => {
const dir = path.join(ROOT, 'resources/grid_fight');
const elite = JSON.parse(fs.readFileSync(path.join(dir, 'elite_rewards.json'), 'utf8'));
const goods = JSON.parse(fs.readFileSync(path.join(dir, 'projection_goods.json'), 'utf8'));
assert.equal(elite.node_rules.length, 44);
assert.equal(elite.diff_add.length, 8);
assert.equal(elite.difficulty.length, 903);
for (const rule of elite.node_rules) assert.equal(rule.id, rule.family ? rule.family * 100 + rule.quality : rule.quality);
assert.deepEqual(goods.projections.map(p => p.id), [1508, 1509]);
assert.equal(goods.special_goods.length, 164);
assert.equal(elite.source.dump_sha256, goods.source.dump_sha256);
});