feedback5 WF: ACTIVE_RANGE also replaces the SEARCH row and covers 深巡 S2 — a skill whose running range strictly contains the own one casts with an enemy inside it (the owner's decisions of 2026-10-05)
tools/build-data.mjs resolveTrigger: a MANUAL operator skill on DEFAULT (no row, or a DEFAULT entry of the deviation
tables) or on the SEARCH row ("在初始攻击范围内存在敌人时释放技能": 解放者 / 阵法术师 / 安洁莉娜 — ACTIVE_RANGE_OVER) whose
running range strictly contains its own is ACTIVE_RANGE on that range, rawRule the official row; validateAll accepts a
DEFAULT deviation resolved to ACTIVE_RANGE (chess and stand-in tables) and ACTIVE_RANGE over SEARCH. Data rebuilt
offline, JSON-compared: only skills[].trigger rule / customRangeGrid of 薄绿 S1 (x-2), 蜜蜡 S1 (x-2), 卡涅利安 S3 (x-2),
玛恩纳 S2 (2-3), 安洁莉娜 S3 (y-4) — rawRule SEARCH — and 深巡 S2 (3-2, rawRule TAKE_DAMAGE), normal + elite (32
leaves); backups.json unchanged. Kits: 薄绿 S1 drops its DEFAULT trigger and 深巡 S2 PR #12's DEFAULT line, both read the
data now (雷蛇 S2 keeps PR #12's line). The sim needs no change (SEARCH was the DEFAULT condition on the initial range
every tick; ACTIVE_RANGE is the same on the running range). Docs: DESIGN §5.6 and the §21.20 flip row, DATA, SIM,
PLAYING, kits README, shared tier comments, skills.js header.
Tests: data (78 records / 39 skills, the five from SEARCH, the SEARCH skills that stay), feedback5-active-range (安洁莉娜
S3 on its y-4, S2 keeps SEARCH), feedback1-tank-triggers and kits_t1t2 (深巡 S2 on its 3-2, before any hit), kits_alt_t3
(薄绿 S1 on its x-2), feedback1f-fence (the idle measure uses the interval of the cooldown still running: the S2 now casts
between two attacks), docs-consistency (one PR #12 kit line left).
Golden: roster-001 / 002 (深巡), roster-016 / 044 (玛恩纳, 安洁莉娜), roster-026 / 027 (薄绿), roster-041 / 042 (卡涅利安),
bond-egirShip-low / bond-suntShip-high (深巡), boss-boss_2-pair / boss-boss_6-pair (玛恩纳, 安洁莉娜), matches solo-NORMAL-1,
coop2-NORMAL-3, coop4-FUNNY-6, coop2-NORMAL-8-serverrun — each fields one of the six skills, which now casts when an
enemy enters its running range.
This commit is contained in:
1 parent
65ac4afbd8
commit
383fe4a49e
27 files changed
+463
-383
No files matched your search
@@ -40,14 +40,16 @@ const laneDirs = (st, r, c) => DIRS.filter((d) => [[0, 1], [0, 2]].some(([dr, dc
|
||||
/**
|
||||
* One battle: the operator alone on (r, c) facing `dir` against a real round template. Returns its attacks, the ticks a
|
||||
* targetable enemy stood on its range tiles, the longest wait for an attack while one did and it could act (seconds
|
||||
* beyond its attack interval) and the ticks it blocked anything.
|
||||
* beyond its attack interval — the longer of the interval when the wait began and now: her S2 casts on its 3-2 between
|
||||
* two attacks since 0.2.0, the owner's ACTIVE_RANGE rule, and its ASPD shortens the interval while the cooldown the
|
||||
* last attack set still runs) and the ticks it blocked anything.
|
||||
*/
|
||||
function watch(stageId, chessId, r, c, dir, { template = 'act1autochess_02', seconds = 45 } = {}) {
|
||||
const h = makeBattle({ stageId, waveTemplate: template, units: [{ chessId, row: r, col: c, dir }], seed: 5 });
|
||||
h.step(1);
|
||||
const u = h.unit(chessId);
|
||||
assert.ok(u && u.deployed && u.tileR === r && u.tileC === c, `${stageId} (${r},${c}) deployed`);
|
||||
let attacks = 0, inRange = 0, blocked = 0, waitFrom = null, worst = 0;
|
||||
let attacks = 0, inRange = 0, blocked = 0, waitFrom = null, waitIv = 0, worst = 0;
|
||||
h.b.on('attack', (ctx) => { if (ctx.attacker === u) { attacks++; waitFrom = null; } });
|
||||
for (let i = 0; i < seconds * 30 && !h.b.finished; i++) {
|
||||
h.step(1);
|
||||
@@ -58,8 +60,8 @@ function watch(stageId, chessId, r, c, dir, { template = 'act1autochess_02', sec
|
||||
const target = h.b.enemies.some((e) => e.alive && e.deployed && canTargetEnemy(u, e, prof) && bodyInKeys(e, set));
|
||||
if (!target) { waitFrom = null; continue; }
|
||||
inRange++;
|
||||
if (waitFrom == null) waitFrom = h.b.time;
|
||||
worst = Math.max(worst, h.b.time - waitFrom - u.s.interval);
|
||||
if (waitFrom == null) { waitFrom = h.b.time; waitIv = u.s.interval; }
|
||||
worst = Math.max(worst, h.b.time - waitFrom - Math.max(waitIv, u.s.interval));
|
||||
}
|
||||
return { attacks, inRange, blocked, worst };
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user