Files
ark-stronghold-protocol/test/content/feedback6-apoptosis-sp.test.js
T

66 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// PR #262 (#261 its closed duplicate): an operator's 凋亡 burst — PRTS 元素 "立即获得等时长的阻回、静默,该阻回、静默持续期间
// 每秒损失1点技力并受到100点无来源法术持续伤害" — drains the official 技力, stored charges included: PRTS 技能 可充能 "当持有者
// 的技力流失时,充能次数也会实时降低". The drain took only the SP towards the next charge, so a full skill (sp = cost with
// every charge stored) kept all its charges — a one-charge skill stayed ready through the whole burst. An active timed
// skill is left alone (its SP was spent at the cast; Skill.setSpTotal leaves it too).
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, chessRec, checkInvariants } from '../helpers/battleHarness.js';
import { hasGeneratedData } from '../../server/sim/simdata.js';
const REAL = { skip: !hasGeneratedData() };
const SNOW = 'chess_char_3_11_b'; // 精锐 雪猎: S2 风雪连弩, MANUAL, 可充能2次, 14 SP per charge
function arena(units, defs = {}) {
const h = makeBattle({ defs, units, autoFinish: false, timeLimit: 120, hooks: ['spGain', 'damaged'] });
h.step();
return h;
}
const burst = (h, u) => {
h.b.dealDamage(null, u, { type: 'element', element: 'apoptosis', amount: u.gaugeMax });
assert.ok(u.findBuff('apoptosisBurst'), '凋亡 bursts');
};
test('PR #262: 凋亡 drains a charge skill\'s stored charges — 精锐 雪猎 with both charges loses one at the first second and is empty after 15', REAL, () => {
const h = arena([{ chessId: SNOW, row: 10, col: 4 }]);
const u = h.unit(SNOW), sk = u.skill;
assert.equal(sk.maxCharges, 2);
const cost = sk.spCost;
sk.setSpTotal(2 * cost);
assert.deepEqual([sk.charges, sk.sp, sk.spTotal], [2, cost, 2 * cost], 'both charges stored');
burst(h, u);
h.run(1.01);
assert.deepEqual([sk.charges, sk.sp, sk.spTotal], [1, cost - 1, 2 * cost - 1], 'one second: −1 技力, the second charge goes');
assert.equal(sk.ready, true, 'one charge left');
h.run(14);
// (the burst ends with its 15th second: the time SP of the ticks since then is back)
assert.equal(sk.charges, 0, '15 seconds: −15 技力 — the last charge gone too');
assert.ok(Math.abs(sk.spTotal - (2 * cost - 15)) < 0.1, `${sk.spTotal} ≈ ${2 * cost - 15}`);
assert.equal(sk.ready, false);
assert.equal(sk.activations, 0, '静默: no cast through the burst');
assert.ok(!u.findBuff('apoptosisBurst'), 'the burst is over');
checkInvariants(h.b);
});
test('PR #262: a full one-charge skill is no longer ready after the first second of 凋亡; an active timed skill keeps its state', () => {
const op = chessRec({ id: 't_apo', stats: { maxHp: 1e5, spRecovery: 0 }, skill: { spCost: 20, initSp: 0, duration: 30, durationType: 'NONE' } });
const h = arena([{ chessId: 't_apo', row: 10, col: 4, uid: 1 }, { chessId: 't_apo', row: 10, col: 6, uid: 2 }], { chess: { t_apo: op } });
const a = h.unit(1), b = h.unit(2);
a.skill.setSpTotal(20);
assert.equal(a.skill.ready, true);
burst(h, a);
h.run(1.01);
assert.deepEqual([a.skill.charges, a.skill.sp, a.skill.ready], [0, 19, false], 'the ready charge is part of the 技力 it loses');
h.run(14);
assert.equal(a.skill.spTotal, 5, '−15 技力 in all');
assert.equal(h.hooksOf('spGain').length, 0, 'the drain is no SP gain (no spGain hook)');
// a running timed skill: its SP was spent at the cast — nothing to drain, and it runs on (the burst silences new casts only)
b.skill.setSpTotal(20);
assert.ok(b.skill.activate('test'));
const before = [b.skill.active, b.skill.charges, b.skill.sp];
burst(h, b);
h.run(3);
assert.deepEqual([b.skill.active, b.skill.charges, b.skill.sp], before);
checkInvariants(h.b);
});