The report's 退行的潮涌者 is the 巢涌者 (深溟 / 富营养的巢涌者 in this mode): no normal attack, its talent hurts every operator in range once a second. Official (ArknightsGameData buff_template_data): its pulse is an AdvancedApplyDamage with the enemy as source (enemy_dsubrl_aoe[aura]); the counters fire on ON_TAKE_DAMAGE — philae_s_2 with no filter, inverse_damage (星熊 S2), inverse_damage[magic] + nian_s_2 (年 S2), bubble_s_2 / bubble_t_1 (泡泡), vendla_s_2 (刺玫), yu_s_1[inverse_damage] (余 S1), hsgma2_s_1 / hsgma2_e_003_tr_take (斩业星熊), mlynar_t_2[inverse] (玛恩纳) on a source of the other side; 棘刺 S2 (普通伤害 filter) and 信仰搅拌机 S3 already took any damage. Cause: the kits required dmg.isAttack. Now kits/shared/tier1.js byEnemyAttack = any enemy damage instance but a 流失, an element 损伤, 无来源 damage or another counter / reflection (tags 'counter' / 'reflect'); 菲莱 S2 any instance but a 流失 or a counter. test/content/op_nian.test.js pinned "a non-attack hit returns nothing" for 年 S2 — updated on purpose (answered now; a 流失 still is not). Golden: 19 scenarios where an enemy's non-attack damage (skills, pulses, areas) reached one of these operators — their counter now answers it (more damage, fx thorns / aoe): roster-002, -005, -008, -010, -012, -016, -033, -044; bond-lateranoShip-low; fields boss-boss_2-solo, boss-boss_4-pair, boss-boss_4-solo, hidden-boss_8-pair, hidden-boss_8-solo; matches solo-FUNNY-1, solo-FUNNY-2, coop4-ABYSS-7, coop2-ABYSS-10-boosted; diy-051. Tests: test/sim/feedback5-counters-any-damage.test.js (6; 5 fail on the parent, the first checks the 巢涌者 never attacks). Docs: docs/SIM.md (re-entrancy rule).
35 lines
2.1 KiB
JavaScript
35 lines
2.1 KiB
JavaScript
// server/sim/content/kits/ops/chess_char_2_08-bubble.js — 泡泡 (char_381_bubble) kit, tier 2.
|
||
// Conventions of the tier-2 kits: ../shared/tier2.js; kit contract and rules: ../README.md.
|
||
|
||
import { num, talentBb, traitBb, byEnemyAttack, onDamagedOn, toggleBuff } from '../shared/tier1.js';
|
||
import { onDefaultSkill } from '../shared/tier2.js';
|
||
|
||
export default {
|
||
// ---------------------------------------------------------------------------------------------------------------
|
||
// 2_08 泡泡 “挨打”: stops attacking; DEF +def, taunt +taunt_level, each enemy damage instance received (its attack or not:
|
||
// the official bubble_s_2 / bubble_t_1 fire on ON_TAKE_DAMAGE — tier1 byEnemyAttack) returns atk_scale × DEF phys damage
|
||
// to its source. 尖刺盾: that source gets ATK −atk for `duration` s. Elite module (PRO-X): DEF +def while blocking.
|
||
// S1 防御力强化·β型 (alt, TAKE_DAMAGE from data): DEF +def for its duration; the counter belongs to “挨打” only.
|
||
chess_char_2_08_a: (bb, chess) => {
|
||
const t = talentBb(chess, 0);
|
||
const tb = traitBb(chess);
|
||
const s2 = onDefaultSkill(chess);
|
||
return {
|
||
skill: { kind: 'duration', mods: { defPct: num(bb.def), taunt: num(bb.taunt_level) }, attack: { noAttack: true } },
|
||
skills: { 'skcom_def_up[2]': { kind: 'duration', mods: { defPct: num(bb.def) } } },
|
||
talents: [{ install(battle, unit) {
|
||
onDamagedOn(battle, unit, (ctx) => {
|
||
if (!byEnemyAttack(ctx) || !unit.alive) return;
|
||
const src = ctx.source;
|
||
if (s2 && unit.skill?.active && src.alive) {
|
||
battle.dealDamage(unit, src, { amount: unit.s.def * num(bb.atk_scale), type: 'phys', isSkill: true, canDodge: false, tags: ['counter'] });
|
||
battle.fx('counter', { x: src.x, y: src.y, id: unit.id });
|
||
}
|
||
if (num(t.atk) < 0 && src.alive) battle.addBuff(src, { key: 'bubble:spike', duration: num(t.duration, 5), mods: { atkPct: num(t.atk) }, refresh: 'extend', source: unit });
|
||
});
|
||
if (num(tb.def)) toggleBuff(battle, unit, 'bubble:guard', () => unit.blocking.length > 0, { defPct: num(tb.def) });
|
||
} }],
|
||
};
|
||
},
|
||
};
|