feedback1 integrate: 卢西恩 and 锏 cast their area skills only with someone they can hurt (QA)

卢西恩's 【aoe】 and 锏's CircleAttack counted every ally in their radius, so an airborne 蒂比 alone in range set them off
and the blast skipped her. They count only allies a ground enemy does not evade (evadesGround).
This commit is contained in:
sganggs committed 2026-10-03 17:47:19 +08:00
1 parent 43ef50ece7
commit 791640e717
3 files changed
+34 -2

No files matched your search

+3 -1
View File
@@ -922,7 +922,9 @@ function lucienCore(ab, e) {
dealt(c, b, e2) { elem(b, e2, c.target, 'neural', e2.s.atk * epr); },
},
s && {
cd: s.cd, icd: s.icd, cond: (b) => b.alliesInRadius(e.x, e.y, LUCIEN_AOE_RADIUS).length > 0,
// cast only with someone the blast can hurt: an airborne (起飞) operator evades a ground leader (对地规避 — the
// blast skips her in damage.js; counting her spent the skill on nobody)
cd: s.cd, icd: s.icd, cond: (b) => b.alliesInRadius(e.x, e.y, LUCIEN_AOE_RADIUS).some((u) => !evadesGround(e, u)),
fire(b, e2) {
b.fx('explode', { x: e2.x, y: e2.y, r: LUCIEN_AOE_RADIUS, kind: 'crimsonAoe' });
for (const u of b.alliesInRadius(e2.x, e2.y, LUCIEN_AOE_RADIUS)) { hurt(b, e2, u, e2.s.atk * (s.bb.atk_scale ?? 0), 'phys'); elem(b, e2, u, 'neural', e2.s.atk * (s.bb.ep_damage_ratio ?? 0)); }
+2 -1
View File
@@ -2168,7 +2168,8 @@ function kitMace(ab) {
b.fx('explode', { x: e.x, y: e.y, r, kind: 'blizzard', id: e.id });
for (const u of b.alliesInRadius(e.x, e.y, r)) hurt(b, e, u, e.s.atk * (s.bb.atk_scale ?? 1), 'phys');
};
const inR = (b, e, s) => b.alliesInRadius(e.x, e.y, (s && s.bb.range_radius) || 0).length > 0;
// someone the circle can hurt: an airborne (起飞) operator evades a ground enemy (对地规避; damage.js skips her)
const inR = (b, e, s) => b.alliesInRadius(e.x, e.y, (s && s.bb.range_radius) || 0).some((u) => !evadesGround(e, u));
return [resist(), {
hitOut(c, b, e) { const p = penOn(c, e); if (c.dmg.isAttack && p > 0) c.dmg.defIgnorePct = Math.min(1, (c.dmg.defIgnorePct || 0) + p); },
taken(c, b, e) { // 【瞬息杀机】 every hp_ratio of max HP lost (second form)
+29
View File
@@ -425,3 +425,32 @@ test('F3 review 2: a debuff a ground enemy put on 蒂比 before she took off kee
done(h);
}
});
// QA after the integration: two ground enemies decided to cast an area skill by counting every ally in its radius —
// 卢西恩,“猩红血钻”'s 【aoe】 (radius 2) and 锏's CircleAttack (first form, radius 1.5) — so an airborne 蒂比 alone in
// range set it off and the blast, which skips her (对地规避), was spent on nobody (6 casts in 60 s, 0 hits). They count
// only the allies the blast can hurt now. The `liftoff` flag on 角峰 stands for 蒂比's 起飞 (targeting.js evadesGround
// reads the flag), so no skill of hers takes off or lands in the middle of the count.
test('F3 QA: 卢西恩\'s 【aoe】 and 锏\'s CircleAttack are not cast for an airborne operator alone in range; they are once it lands', REAL, () => {
for (const [key, kind, radius] of [['enemy_2016_csphtm', 'crimsonAoe', 2], ['enemy_1525_blkswb', 'blizzard', 1.5]]) {
const h = makeBattle({
stageId: 'flat', seed: 3, autoFinish: false, timeLimit: 400,
units: [{ chessId: BAIT, row: 10, col: 5 }],
enemies: [{ key, pos: [10, 6], mods: { hpMul: 1e3, speedMul: 0, atkMul: 0.01 } }],
});
h.step();
const u = h.unit(BAIT);
const e = h.b.enemies.find((x) => x.alive && x.defId === key);
assert.ok(e && Math.hypot(e.x - u.x, e.y - u.y) <= radius, `${key}: 角峰 inside the radius`);
h.b.addBuff(u, { key: 'test:liftoff', persist: true, flags: { liftoff: true, blockFly: true } });
let casts = 0;
const fx0 = h.b.fx.bind(h.b);
h.b.fx = (k, p) => { if (k === 'explode' && p && p.kind === kind) casts++; return fx0(k, p); };
h.run(40);
assert.equal(casts, 0, `${key}: no ${kind} while the only ally in range is airborne`);
h.b.removeBuff(u, 'test:liftoff');
h.run(2);
assert.equal(casts, 1, `${key}: cast at once when a target it can hurt is there (the skill was ready all along)`);
done(h);
}
});