feedback5: 焰狐龙梓兰 leaves the 自选 pool as a collab operator (MH05, a Monster Hunter 联动寻访 whose team reserve6 names no collab: DIY_EXCLUDED_NUMBER_PREFIXES MH / RS / AM / PS / DD next to the team list — the owner's decision of 2026-10-05; reported by O6) — 71 owned picks; 「攻击范围改为」 is an attack-range change (黑 S3 was SKILL_RANGE, now DEFAULT; 远牙 S3 keeps its own CUSTOM_RANGE row); data and the EN overlay regenerated offline, chess.json unchanged; golden unchanged
This commit is contained in:
1 parent
85e75500b4
commit
8287422d6d
9 files changed
+28
-20
No files matched your search
@@ -1,7 +1,7 @@
|
||||
// test/backups.test.js — the data of 补位 (stand-ins) and 自选 (DIY slots): chess.json `backup` and data/backups.json
|
||||
// (docs/DATA.md §18; tools/build-data.mjs buildBackups; shared/standIn.js, shared/diy.js). These tests pin the data the
|
||||
// gameplay reads: the 133 base chess and their types, the 17 stand-in characters and their forms, every NORMAL chess
|
||||
// resolving to its stand-in, the 4 DIY slots, the legal picks (the 72 owned 6★ with their forms and summons, the
|
||||
// resolving to its stand-in, the 4 DIY slots, the legal picks (the 71 owned 6★ with their forms and summons, the
|
||||
// prototypes and their locked selections) and the faction bonds.
|
||||
// With the official-data cache (.cache/gamedata) the backup fields, the stand-in numbers and the bond derivation are
|
||||
// re-derived from the raw tables.
|
||||
@@ -234,9 +234,9 @@ test('DIY: prototype picks — the 9 elites at tiers 5 and 6, six 4★ reserves
|
||||
assert.equal(diyRecord(chess.chess_char_5_01_a, 'char_608_acpion', backups, { skillIndex: 2 }), null, 'not a DIY slot');
|
||||
});
|
||||
|
||||
test('DIY: the 72 owned 6★ picks — a form at every slot status with all three skills, every module at stage 1 and 3, their summons', () => {
|
||||
test('DIY: the 71 owned 6★ picks — a form at every slot status with all three skills, every module at stage 1 and 3, their summons', () => {
|
||||
const { ownedPool } = backups.diy;
|
||||
assert.equal(ownedPool.length, 72);
|
||||
assert.equal(ownedPool.length, 71);
|
||||
let summoners = 0;
|
||||
for (const id of ownedPool) {
|
||||
const u = backups.units[id];
|
||||
@@ -308,7 +308,7 @@ test('DIY: prototype picks carry the skill / module of their 补位 rows at the
|
||||
test('DIY: the owned-6★ pool and the faction → bond rule (mainPower + every subPower vs powerIdList, else 协防干员)', () => {
|
||||
const { ownedPool, operators, prototypes } = backups.diy;
|
||||
const roster = new Set(base.map((c) => c.charId).filter(Boolean));
|
||||
assert.equal(ownedPool.length, 72);
|
||||
assert.equal(ownedPool.length, 71);
|
||||
for (const id of ownedPool) {
|
||||
assert.ok(!roster.has(id), `${id}: a roster operator is never a pick`);
|
||||
assert.deepEqual([operators[id].rarity, operators[id].obtainable], [6, true], id);
|
||||
@@ -322,11 +322,11 @@ test('DIY: the owned-6★ pool and the faction → bond rule (mainPower + every
|
||||
}
|
||||
const tally = {};
|
||||
for (const id of ownedPool) { const k = operators[id].bonds.join('+'); tally[k] = (tally[k] || 0) + 1; }
|
||||
assert.deepEqual(tally, { emptyShip: 39, yanShip: 14, victoriaShip: 8, sargonShip: 4, siracusaShip: 4, lateranoShip: 1, kazimierzShip: 1, 'yanShip+victoriaShip': 1 });
|
||||
assert.deepEqual(tally, { emptyShip: 38, yanShip: 14, victoriaShip: 8, sargonShip: 4, siracusaShip: 4, lateranoShip: 1, kazimierzShip: 1, 'yanShip+victoriaShip': 1 });
|
||||
// the collab operators are out of the data and the pool (the owner's decision of 2026-10-05: copyright)
|
||||
assert.deepEqual(backups.diy.excluded.map((id) => [id, backups.units[id], operators[id]]),
|
||||
['char_456_ash', 'char_1029_yato2', 'char_4123_ela', 'char_4141_marcil', 'char_4182_oblvns', 'char_4217_makoto'].map((id) => [id, undefined, undefined]),
|
||||
'灰烬, 麒麟R夜刀, 艾拉, 玛露西尔, 丰川祥子, 结城理');
|
||||
['char_456_ash', 'char_1029_yato2', 'char_1048_orchd2', 'char_4123_ela', 'char_4141_marcil', 'char_4182_oblvns', 'char_4217_makoto'].map((id) => [id, undefined, undefined]),
|
||||
'灰烬, 麒麟R夜刀, 焰狐龙梓兰 (MH05: a 联动寻访, by its display number), 艾拉, 玛露西尔, 丰川祥子, 结城理');
|
||||
assert.deepEqual(operators.char_017_huang.bonds, ['yanShip', 'victoriaShip'], '煌: 炎 + 维多利亚 from her subPower (mainPower rhodes / elite)');
|
||||
for (const id of [...prototypes['5'], ...prototypes['6']]) assert.deepEqual(operators[id].bonds, ['emptyShip'], `${id}: no faction`);
|
||||
});
|
||||
@@ -335,7 +335,8 @@ test('DIY: powers and the owned pool re-derived from character_table', { skip: !
|
||||
const CT = raw('character_table');
|
||||
const act = raw('activity_table').activity.AUTOCHESS_SEASON.act2autochess;
|
||||
const roster = new Set(Object.values(act.charShopChessDatas).map((r) => r.charId).filter(Boolean));
|
||||
const collab = (c) => [c.mainPower, ...(c.subPower || [])].some((p) => ['rainbow', 'action4', 'mujica', 'sees', 'laios'].includes(p?.teamId));
|
||||
const collab = (c) => [c.mainPower, ...(c.subPower || [])].some((p) => ['rainbow', 'action4', 'mujica', 'sees', 'laios'].includes(p?.teamId))
|
||||
|| /^(?:MH|RS|AM|PS|DD)\d/.test(c.displayNumber || '');
|
||||
const legal = Object.entries(CT).filter(([id, c]) => id.startsWith('char_') && c.rarity === 'TIER_6' && !['TOKEN', 'TRAP'].includes(c.profession) && !c.isNotObtainable && !roster.has(id));
|
||||
assert.equal(legal.length, 78, 'the excel\'s 78 obtainable 6★ outside the chess pool');
|
||||
assert.deepEqual([...backups.diy.ownedPool].sort(), legal.filter(([, c]) => !collab(c)).map(([id]) => id).sort());
|
||||
|
||||
+2
-2
@@ -34,11 +34,11 @@ test('slots: two per tier (5, 6), each with its elite twin', () => {
|
||||
assert.equal(diyTokenOwner(SIEGE, chess.chess_char_6_diy1_b.status), 'char_112_siege@2/60/7/3');
|
||||
});
|
||||
|
||||
test('diyPool: tier 5 = 15 prototypes + 72 owned 6★, tier 6 = 9 + 72; no preset, no collab; with the kit registry only kitted operators', () => {
|
||||
test('diyPool: tier 5 = 15 prototypes + 71 owned 6★, tier 6 = 9 + 71; no preset, no collab; with the kit registry only kitted operators', () => {
|
||||
const p5 = diyPool(5, { data: DATA }), p6 = diyPool(6, { data: DATA });
|
||||
assert.deepEqual(p5, [...RESERVES5, ...ELITES, ...ownedPool]);
|
||||
assert.deepEqual(p6, [...ELITES, ...ownedPool]);
|
||||
assert.deepEqual([p5.length, p6.length], [87, 81]);
|
||||
assert.deepEqual([p5.length, p6.length], [86, 80]);
|
||||
const roster = new Set(Object.values(chess).map((c) => c.charId).filter(Boolean));
|
||||
for (const id of p5) assert.ok(!roster.has(id) && !COLLAB.includes(id), id);
|
||||
assert.deepEqual(diyPool(4, { data: DATA }), [], 'no 自选 slot at tier 4');
|
||||
|
||||
@@ -95,7 +95,7 @@ test('data/i18n/en.json: shape, the 盟约 season of the EN build, coverage and
|
||||
assert.equal(OVERLAY.version, 1);
|
||||
assert.equal(OVERLAY.lang, 'en');
|
||||
assert.equal(OVERLAY.meta.source.season, 'act2autochess', 'built from an EN client that has 卫戍协议:盟约 下半');
|
||||
// the 自选 data (0.2.0) brings 72 owned 6★, some of them (and some newer modules) not in the EN client yet: their
|
||||
// the 自选 data (0.2.0) brings 71 owned 6★, some of them (and some newer modules) not in the EN client yet: their
|
||||
// names, skills, talents and modules stay Chinese — measured 97.6 % in all, skills 95.9 / talents 95.1 % (2026-10-05)
|
||||
assert.ok(OVERLAY.meta.totals.pct >= 97, `coverage ${OVERLAY.meta.totals.pct} %`);
|
||||
for (const kind of ['operators', 'skills', 'talents', 'modules', 'traits', 'enemies', 'bonds', 'items', 'effects', 'bands', 'garrisons', 'stages', 'tokens', 'choices', 'config']) {
|
||||
|
||||
Reference in new issue
Block a user