feedback6: merge R21P — every operator at full potential (潜能 6; GitHub #252, PR #255 by @SpiritedAwayCN, the owner's decision of 2026-10-07)
- tools/build-data.mjs applies every potentialRanks attribute step (COST, RESPAWN_TIME, ATK, MAX_HP, DEF, MAGIC_RESISTANCE, ATTACK_SPEED) to the chess, elites, 补位 and 自选 units and picks talent / trait / module-talent candidates up to requiredPotentialRank 5; summons take the owner's potential for their talents, not its stat steps. data/chess.json, backups.json, tokens.json and the en / ja / ko / zh-TW data translations rebuilt; op-wang.js reads her stock cap (8 at full potential). 刺玫 435 ATK / cost 15, 砾 16 s, 至简 70 s. - No conflicts outside the golden files (regenerated). Golden vs HEAD: roster 49, bonds 46, fields 22, matches 18, diy 133 (standins and diy-012 / diy-135…138 unchanged: no potential ranks or never hit). Union check against the branch and the merge base: every scenario only the branch moved equals the branch, except roster-048 and solo-ABYSS-2: at full potential a 频次 器物 is reached there (roster-048: one more enemy dies instead of leaking, 86 → 87 units), so R21H's hit count (data × hpMul ÷ supplyHpMul) applies where it did not before — with only that rule put back (archetypes.js times as at the merge base) both equal the branch exactly. - Tests: broad node --test 5147 / 5147; lint 0 errors.
This commit is contained in:
commit
b05845f507
178 files changed
+7667
-7317
No files matched your search
@@ -210,7 +210,8 @@ test('纸偶: appear burst = its ATK × damage_scale arts on the 8 surrounding t
|
||||
test('狼群: board piece becomes 伺夜\'s 援军; 2→3 狼影 (block & hits), fatal sheds a shadow, DEF ignore vs blocked, 战术点形态 after the last one', REAL, () => {
|
||||
let wolfHits = 0;
|
||||
const h = makeBattle({
|
||||
defs: { enemies: { enemy_walker: walker({ def: 200, atk: 0 }) } },
|
||||
// DEF 250: above the pack's 200 DEF ignore (its talent at 伺夜's full potential), so a bite shows the partial ignore
|
||||
defs: { enemies: { enemy_walker: walker({ def: 250, atk: 0 }) } },
|
||||
kits: { chess_char_3_19_a: genericNoSkill },
|
||||
// the wolf is listed before its owner (higher row): it must still be linked to 伺夜 (owner-level variant)
|
||||
units: [{ kind: 'token', tokenId: TOKEN_IDS.wolfPack, row: 9, col: 6, uid: 1, ownerUid: 2 }, { chessId: 'chess_char_3_19_b', row: 10, col: 4, uid: 2 }],
|
||||
@@ -228,11 +229,12 @@ test('狼群: board piece becomes 伺夜\'s 援军; 2→3 狼影 (block & hits),
|
||||
assert.equal(wolf.s.blockCnt, 2);
|
||||
const e = h.enemy('enemy_walker');
|
||||
assert.ok(h.runUntil(() => e.blockedBy === wolf && wolfHits >= 2, 30), 'blocks and bites');
|
||||
// DEF ignore: every bite does ATK − (200 − 175)
|
||||
// DEF ignore: every bite does ATK − (250 − 200)
|
||||
assert.equal(tokDef(TOKEN_IDS.wolfPack, 'chess_char_3_19_b').talents[1].bb.def_penetrate_fixed, 200, 'the pack ignores 200 DEF (175 + the potential step)');
|
||||
let dealt = null;
|
||||
h.b.on('damaged', (c) => { if (c.source === wolf && c.type === 'phys') dealt = c.amount; });
|
||||
h.runUntil(() => dealt != null, 5);
|
||||
approx(dealt, wolf.s.atk - (200 - 175), 1e-9, 'def pen');
|
||||
approx(dealt, wolf.s.atk - (250 - 200), 1e-9, 'def pen');
|
||||
h.runUntil(() => wolfShadows(wolf) === 3, 30);
|
||||
assert.equal(wolf.s.blockCnt, 3);
|
||||
assert.equal(wolf.profile.hitsFn(h.b, wolf), 3);
|
||||
@@ -927,7 +929,7 @@ test('every token variant: a spawn with that owner takes the owner-level stats (
|
||||
assert.ok(n >= 38, `variants checked: ${n}`);
|
||||
});
|
||||
|
||||
test('elite numbers: 沙之碑 230 %/1.5 s, 香槟炸弹 170 %, 纸偶 its ATK × 2.7, “耀阳” 100 % + ×1.15 vs blocked, 医疗探机 ATK 114', REAL, () => {
|
||||
test('elite numbers: 沙之碑 230 %/1.5 s, 香槟炸弹 170 %, 纸偶 its ATK × 2.75 (full potential), “耀阳” 100 % + ×1.15 vs blocked, 医疗探机 ATK 114', REAL, () => {
|
||||
const burstOf = (ownerId, tokenId, r, c, ePos) => {
|
||||
const base = ownerId.replace(/_[ab]$/, '_a');
|
||||
const h = makeBattle({ defs: { enemies: { enemy_dummy: dummy() } }, kits: { [base]: genericNoSkill }, units: [{ chessId: ownerId, row: 12, col: 2 }], enemies: [{ key: 'enemy_dummy', pos: ePos }], autoFinish: false, timeLimit: 10 });
|
||||
@@ -951,7 +953,7 @@ test('elite numbers: 沙之碑 230 %/1.5 s, 香槟炸弹 170 %, 纸偶 its ATK
|
||||
{
|
||||
const { t, e } = burstOf('chess_char_2_11_b', TOKEN_IDS.paperDoll, 10, 6, [11, 7]);
|
||||
assert.equal(t.base.atk, 728);
|
||||
approx(1e7 - e.hp, 728 * 2.7, 1e-9, '纸偶 elite');
|
||||
approx(1e7 - e.hp, 728 * 2.75, 1e-9, '纸偶 elite (2.7 + the potential step of 风丸)');
|
||||
}
|
||||
{
|
||||
const { o, e } = burstOf('chess_char_6_17_b', TOKEN_IDS.radiantSword, 10, 6, [10, 7]);
|
||||
@@ -1228,7 +1230,7 @@ test('tactical point: without a board piece the 援军 (狼群) stands on an ene
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
|
||||
test('狼群 (generic 伺夜): 伺夜\'s own attacks on pack-blocked enemies ignore 175 DEF and get the S3 bonus; the pack leaves with 伺夜', REAL, () => {
|
||||
test('狼群 (generic 伺夜): 伺夜\'s own attacks on pack-blocked enemies ignore 200 DEF (full potential) and get the S3 bonus; the pack leaves with 伺夜', REAL, () => {
|
||||
const kit = () => ({ generic: true, talents: [], skill: { kind: 'duration', duration: 60, trigger: 'SP_FULL', spCost: 1, initSp: 1 } });
|
||||
const own = [], bonus = [];
|
||||
// RES 100: the 弱点伤害 garrison keeps the attacks physical (arts would do 5 %)
|
||||
@@ -1244,8 +1246,8 @@ test('狼群 (generic 伺夜): 伺夜\'s own attacks on pack-blocked enemies ign
|
||||
assert.ok(h.runUntil(() => own.some((x) => x.blocked) && bonus.some((x) => x.src === 'chess_char_3_19_a'), 30), 'owner hits a pack-blocked enemy');
|
||||
const hit = own.find((x) => x.blocked);
|
||||
assert.equal(hit.type, 'phys');
|
||||
// tactician trait ×1.5 vs enemies its 援军 blocks; DEF 300 − 175
|
||||
approx(hit.amount, vigil.s.atk * 1.5 - (300 - 175), 1e-6, 'DEF ignore on 伺夜\'s attack');
|
||||
// tactician trait ×1.5 vs enemies its 援军 blocks; DEF 300 − 200
|
||||
approx(hit.amount, vigil.s.atk * 1.5 - (300 - 200), 1e-6, 'DEF ignore on 伺夜\'s attack');
|
||||
approx(bonus.find((x) => x.src === 'chess_char_3_19_a').amount, vigil.s.atk * 0.2 * 0.05, 1e-6, 'S3 bonus: 20 % ATK arts vs RES 100 (5 % floor)');
|
||||
assert.ok(bonus.some((x) => x.src === TOKEN_IDS.wolfPack), 'the pack\'s bites carry the bonus too');
|
||||
// the 援军 leaves with its tactician (no respawn afterwards)
|
||||
|
||||
Reference in new issue
Block a user