feedback1 final: six 重装 skills cast with an enemy in range, a deliberate deviation from the official TAKE_DAMAGE row (GitHub issue #4, PR #12)

The owner's decision (2026-10-03, after community feedback): 深巡 S2 行动能力剥夺, 雷蛇 S2 反击电弧, 号角 S2 暴风号令
and S3 终极防线, 灰毫 S1 攻击力强化·γ型 and S2 专注轰击 take the basic strategy (DEFAULT) instead of the 下半 TANK class
row's TAKE_DAMAGE. Every other MANUAL 重装 skill, 深巡 S1 included, still waits for a hit.

- tools/build-data.mjs TRIGGER_DEVIATIONS: a small table keyed by the normal chess id and the skill id (the elite
  follows through baseId), never by the skill id alone - 灰毫 S1 is the generic skcom_atk_up[3]. resolveTrigger applies
  it last; rawRule keeps the official TAKE_DAMAGE; validateAll fails the build when an entry no longer meets a
  TAKE_DAMAGE row. data/chess.json rebuilt with --offline: exactly the 12 records' rule changes.
- PR #12's kit lines (trigger 'DEFAULT' on 深巡 / 雷蛇 S2) stay and agree with the data; their comments and tests now
  give this reason instead of the community summary.
- Tests: test/sim/feedback1-tank-triggers.test.js (the data, kit = data, a real battle on 战场#01(下半) in which each of
  the six casts with an enemy in range before any hit and each of the other 46 MANUAL 重装 records casts on the first
  hit); data.test.js trigger expectations; the 灰毫 / 号角 kit tests follow; docs-consistency.
- Docs: DESIGN §21.29 (new), §5.6, §19.2, §20.2, §21.20 (settled row), §21.23; DATA, SIM, PLAYING, CHANGELOG 0.1.1;
  research 03 §1.4 drops the arknights.wiki.gg "offensive / defensive" summary and records the activity_table history
  (上半 had no TANK row, 下半 added it) and this deviation; research 00-INDEX.
This commit is contained in:
sganggs committed 2026-10-03 19:13:35 +08:00
1 parent e6ab4e1ff8
commit 2dba6da598
20 files changed
+325 -58

No files matched your search

+6 -5
View File
@@ -527,18 +527,19 @@ test('号角 S1 照明榴弹 (自动触发 ⇒ DEFAULT): the next ranged shot de
}
});
test('号角 S2 暴风号令: 10 rounds of attack@s2.atk_scale × ATK splash; the second half adds magic_atk_scale × ATK arts (过载)', () => {
test('号角 S2 暴风号令: cast with an enemy in range (DEFAULT, DESIGN §21.29); 10 rounds of attack@s2.atk_scale × ATK splash; the second half adds magic_atk_scale × ATK arts (过载)', () => {
for (const id of pair('08')) {
const h = run({ defs: { enemies: { enemy_dummy: dummy('enemy_dummy') } }, units: [entry(id, 'skchr_horn_2', { row: 10, col: 2 })], enemies: [{ key: 'enemy_dummy', pos: [10, 6] }] });
const u = sel(h, id, 'skchr_horn_2');
const bb = bbOf(u);
const e = h.b.enemies[0];
h.step();
// the owner's deliberate deviation from the 重装 TAKE_DAMAGE row (DESIGN §21.29): cast with an enemy in range
assert.equal(u.skill.rule, 'DEFAULT');
u.skill.gainSp(1000);
h.run(1);
assert.equal(u.skill.activations, 0, '重装 TAKE_DAMAGE: not before a hit');
h.b.dealDamage(e, u, { amount: 10, type: 'phys' });
assert.equal(u.skill.activations, 1, 'cast by the hit');
assert.ok(h.runUntil(() => u.skill.activations === 1, 3), 'cast with the enemy in range');
assert.equal(h.hooksOf('skillStart').find((c) => c.unit === u).reason, 'DEFAULT');
assert.ok(!h.hooksOf('damaged').some((c) => c.target === u), 'no hit needed');
assert.equal(u.skill.kind, 'ammo');
assert.equal(u.skill.ammoLeft + h.hooksOf('ammoUsed').filter((c) => c.unit === u).length, bb['attack@s2.trigger_time']);
assert.ok(h.runUntil(() => !u.skill.active, 60));