Files
ark-stronghold-protocol/test/sim/feedback4-restart-in-end.test.js

52 lines
3.0 KiB
JavaScript

// A skill restarted inside its own end (0.1.4 release review): 耀骑士临光 S2 retreats when its duration ends and 不屈
// redeploys her inside that call, starting the deploy-timed skill again (PR #109) — the new cast keeps its effects and
// the client never sees it off; 伊内丝 S3's recall still finds its 影哨 when 不屈 redeploys her at once.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, enemyRec } from '../helpers/battleHarness.js';
const bond = (tier, layers = 0, count = 3) => ({ count, active: tier > 0, tier, layers });
test('耀骑士临光 S2 restarted by 不屈 inside its duration end keeps 骑士戒律 and stays on for the client', () => {
const NEARL = 'chess_char_6_17_a';
const ends = [];
const h = makeBattle({
seed: 1, autoFinish: false, timeLimit: 220, flags: { dpInit: 99 },
bonds: { kazimierzShip: bond(1, 0), indomShip: bond(1, 999) },
defs: { enemies: { enemy_hit: enemyRec({ key: 'enemy_hit', hp: 10, atk: 0, speed: 0 }) } },
units: [{ chessId: NEARL, row: 10, col: 5, dir: 'RIGHT', skillIndex: 1, items: ['chess_item_6_10_e_a', 'chess_item_4_07_e_a'] }],
setup(b) { b.on('skillEnd', (c) => { if (c.unit?.defId === NEARL) ends.push({ active: c.skill.active, reason: c.reason }); }); },
});
const u = h.unit(NEARL);
const combo = () => u.buffs.some((x) => x.key.endsWith(':combo'));
h.run(0.3);
assert.ok(u.skill.active && combo(), 'the first cast runs with its combo');
h.runUntil(() => u.alive && u.skill.activations >= 2 && u.skill.active, 60);
h.run(0.3);
assert.ok(u.skill.active, 'the second cast runs');
assert.ok(combo(), 'the restarted cast keeps 骑士戒律');
assert.ok(ends.every((e) => !e.active), 'no skillEnd fires for a skill that is running again');
const own = h.eventsOf('skill').filter((e) => e[1] === u.id).map((e) => e[2]);
assert.equal(own.at(-1), 1, 'the client sees the skill on');
});
test('伊内丝 S3: knocked out mid-battle, 不屈\'s immediate redeploy recalls the 影哨 she leaves', () => {
const INES = 'chess_char_4_04_a';
const h = makeBattle({
seed: 1, autoFinish: false, timeLimit: 10, flags: { dpInit: 99 },
bonds: { indomShip: bond(1, 999) },
defs: { enemies: { enemy_ines: enemyRec({ key: 'enemy_ines', hp: 80000, speed: 0, atk: 0, def: 0 }) } },
units: [{ chessId: INES, row: 10, col: 5, dir: 'RIGHT', skillIndex: 2 }],
enemies: [{ key: 'enemy_ines', time: 0, pos: [10, 6] }],
});
h.step(1);
const u = h.unit(INES), e = h.enemies()[0];
const recalls = [];
h.b.on('damaged', (c) => { if (c.source === u && (c.dmg?.tags || []).includes('sentryRecall')) recalls.push(c.amount); });
h.b.dealDamage(e, u, { amount: u.s.maxHp * 10, type: 'true', canDodge: false }); // knocked out: 不屈 redeploys at once
h.step(0.2);
assert.ok(u.alive && u.deployed, 'redeployed by 不屈');
assert.equal(recalls.length, 1, 'the redeploy\'s S3 recalls the 影哨 left at her fall');
assert.equal(u.mem.sentry, null, 'and the 影哨 is spent');
});