Fix: 深巡 / 雷蛇 S2 fire with an enemy in range, not only when hit

Both 哨戒铁卫 S2s (深巡 行动能力剥夺, 雷蛇 反击电弧) are OFFENSIVE skills but waited for a hit: the official
技能策略 row `TANK | | | 0 | TAKE_DAMAGE` is documented for skillIndex 0, and reading it as a wildcard for
every index handed TAKE_DAMAGE to these two skillIndex-1 skills (issue #4).

The mode's rule (docs/research/03-operators.md §1.4, quoting the in-game help) is "offensive skills activate
when an enemy is in their skill range; defensive skills activate when the unit is receiving damage", so both
take the basic strategy instead.

- kits/tier1.js: `trigger: 'DEFAULT'` on 深巡's default S2 and on 雷蛇's. Only the rule changes — spCost /
  initSp / spType still come from data. The defensive S1s (深巡 侵袭破坏应对, 雷蛇 充能防御) keep theirs.
- tests: the two 雷蛇 tests that pinned the hit-gated cast now assert the basic strategy, and their enemy
  stands two tiles away so it never touches her; 深巡's test drops its forced dealDamage hit; a new test covers
  all four records (normal + elite of both).

node --test: 2888 tests, 2871 pass, 0 fail, 17 skipped.
This commit is contained in:
shanzhaikabi committed 2026-10-03 12:08:55 +08:00
1 parent 7f134737ce
commit 60db22ed67
3 files changed
+35 -6

No files matched your search

+4 -3
View File
@@ -673,11 +673,12 @@ test('1_20 雷蛇 反击电弧: attack interval +70 % of the base (PRTS 增大(+
for (const id of pair('20')) {
const bb = raw(id).skill.bb;
assert.equal(raw(id).skill.skillId, 'skchr_liskam_2');
// 重装 S2: TAKE_DAMAGE (the enemy has to hit her)
const h = run({ defs: { enemies: { e: dummy('e', { atk: 300, bat: 1 }) }, chess: noGarrison(id) }, units: [{ chessId: id, row: 9, col: 4, carryState: READY }], enemies: [{ key: 'e', pos: [9, 4] }] });
// 重装 S2 反击电弧 is an OFFENSIVE skill: the basic strategy casts it with an enemy in the skill range (issue #4) —
// the enemy here stands two tiles ahead and, being a speed-0 dummy, never touches her
const h = run({ defs: { enemies: { e: dummy('e', { atk: 300, bat: 1 }) }, chess: noGarrison(id) }, units: [{ chessId: id, row: 9, col: 4, carryState: READY }], enemies: [{ key: 'e', pos: [9, 6] }] });
const u = h.unit(id);
assert.ok(h.runUntil(() => u.skill.active, 5));
assert.equal(started(h, u)[0].reason, 'TAKE_DAMAGE');
assert.equal(started(h, u)[0].reason, 'DEFAULT');
approx(u.s.interval, u.base.bat * (1 + bb.base_attack_time) * 100 / u.s.aspd, `${id} interval ×${1 + bb.base_attack_time}`);
h.runUntil(() => !u.skill.active, 30);
approx(u.s.interval, u.base.bat * 100 / u.s.aspd, 'restored');