feedback3 WF: a 联防 阿戈尔 who enters down keeps the revive slot their position earned (the forced exit is not a 击倒); helper order ranks the layers the combat reached; a 替身 switch is 禁疗, so a self-heal does not land

This commit is contained in:
sganggs committed 2026-10-04 20:27:14 +08:00
1 parent ca3d0572ad
commit bc721b4981
6 files changed
+53 -12

No files matched your search

+10 -4
View File
@@ -461,7 +461,7 @@ test('阿戈尔 5 + the devour chain (GitHub #33): the devour knocks out the foo
}
});
test('阿戈尔 5 beneficiaries: fixed at battle start — a 联防 member entering down is none (the next on the field is), a 调和 member is one, the mirrored boss side counts from its own left', () => {
test('阿戈尔 5 beneficiaries: fixed at battle start — a 联防 member entering down keeps the slot, a 调和 member is one, the mirrored boss side counts from its own left', () => {
const list = [['g0_a', ['egirShip']], ['g1_a', ['egirShip']], ['g2_a', ['egirShip']], ['g3_a', ['egirShip']], ['g4_a', ['egirShip']], ['mani_a', ['maniShip']]];
// five members in five columns (one per column, nobody in front of anybody): g0 col 3 … g4 col 7
const units = list.slice(0, 5).map(([chessId], i) => ({ chessId, row: 9 + (i % 2) * 3, col: 3 + i }));
@@ -470,14 +470,20 @@ test('阿戈尔 5 beneficiaries: fixed at battle start — a 联防 member enter
h.b.dealDamage(null, u, { amount: 1e9, type: 'true' });
return u.alive;
};
// 联防: g0 entered down (forced out before battleStart) — g1, g2, g3 hold the revives
// 联防: g0 entered down (forced out before battleStart). The slots stay the first 3 by position — g0, g1, g2.
// The forced exit is not a 击倒, so g0's charge waits until they stand back up. g3 is not promoted into it.
const hu = makeBattle({
kind: 'unite', defs: defsOf(list), autoFinish: false, timeLimit: 60, bonds: { egirShip: bondOn(5, 0, null, [3, 5]) },
units: units.map((u, i) => (i === 0 ? { ...u, carryState: { down: true } } : u)),
});
hu.step(1);
assert.ok(!hu.unit('g0_a').alive, 'g0 forced out');
assert.deepEqual(['g4_a', 'g1_a', 'g2_a', 'g3_a'].map((id) => revives(hu, id)), [false, true, true, true]);
const g0 = hu.unit('g0_a');
assert.ok(!g0.alive, 'g0 forced out');
assert.deepEqual(['g4_a', 'g3_a', 'g1_a', 'g2_a'].map((id) => revives(hu, id)), [false, false, true, true]);
assert.ok(hu.runUntil(() => g0.alive && g0.deployed, 25), 'g0 stands back up inside the redeploy time');
assert.equal(revives(hu, 'g0_a'), true, 'g0 still held the first slot');
hu.b.dealDamage(null, g0, { amount: 1e9, type: 'true' });
assert.ok(!g0.alive, 'g0 has no second revive');
checkInvariants(hu.b);
// 调和 (an active 调和 member enjoys the core bonds) in the first column: one of the 3
const hm = makeBattle({
+13
View File
@@ -99,6 +99,19 @@ test('联防 helpers follow unite.helperOrder (units > active bond > standing >
const c = player('c', 2, 2, 5, true); // most units + an active bond
const order = helperOrder(m, [a, b, c], new Map()).map((p) => p.playerId);
assert.deepEqual(order, ['c', 'b'], 'LP never decides; the first helper (right-hand field) is c');
// the tie-break is the layers the 联防 will fight with: stored plus this round's pending gains, capped at 999
const reached = (playerId, seat, stored, pending) => ({
playerId, seat, lp: 10, deployCount: 4, board: new Map(),
layers: { bond_x: stored },
pendingLayerGains: pending,
bonds: { bond_x: { active: true, layers: stored } },
});
const hi = reached('A', 0, 200, { bond_x: 50 }); // fights at 250
const lo = reached('B', 1, 230, null); // fights at 230
assert.deepEqual(helperOrder(m, [lo, hi], new Map()).map((p) => p.playerId), ['A', 'B']);
const capped = reached('C', 2, 990, { bond_x: 50 }); // 999, not 1040
const under = reached('D', 3, 995, null);
assert.deepEqual(helperOrder(m, [under, capped], new Map()).map((p) => p.playerId), ['C', 'D']);
assert.ok(!/highest LP, then seat/.test(DESIGN), 'DESIGN §6.1 no longer picks helpers by LP');
assert.match(DESIGN, /helperOrder/);
assert.match(META, /unite\.js helperOrder/);
+4
View File
@@ -175,6 +175,10 @@ test('dollkeeper: fatal damage ⇒ a 1 s switch, 20 s as the substitute (block 0
assert.equal(h.b.applyStatus(u, 'stun', { duration: 5 }), false, '眩晕 immune');
h.b.loseHp(u, 1e5);
assert.ok(u.alive && u.trait.doll && u.hp >= 1, '不死');
const low = u.hp;
assert.ok(u.s.flags.noHeal && u.s.flags.healFree, '禁疗 during the switch');
assert.equal(h.b.heal(u, u, 500), 0, 'a self-heal does not land');
approx(u.hp, low);
u.hp = 2000;
h.run(1.05);
assert.ok(u.trait.doll && !u.trait.dollSwitching, 'fighting as the substitute');