feedback3 WG: 深溟巢涌者 and 富营养的巢涌者 do not attack — they walk while a 1 s aura pulse hits allies in range, and the pulse pauses while hidden; a revealed unblocked 节日爵士乐手 only attacks what it blocks
The same pass also stops 漩涡形态 attacking and dealing spin damage while it cannot attack, stops 拥霜羽兽 attacking after it loses its egg (and at flyers), and disarms 碎铳之簧 for its dash at the official 0.35 trample radius.
This commit is contained in:
1 parent
d5b945f14b
commit
bedeac6f52
4 files changed
+140
-20
No files matched your search
@@ -127,7 +127,7 @@ const PIPE_STRIKE_GAP = 0.4;
|
||||
const TENTACLE_STUN = 5, TENTACLE_RADIUS = 1;
|
||||
/** 崩坍 delay (PRTS 1 s), targets per growth stage (PRTS 2/4/8) and 物种爆发 delay (PRTS 4 s). */
|
||||
const ROCKFALL_DELAY = 1, ROCKFALL_TARGETS = [2, 4, 8], DOOM_DELAY = 4;
|
||||
/** 铳: minimum attack speed (PRTS "最低20") and charge hit radius (PRTS 0.35). */
|
||||
/** 铳: minimum attack speed (PRTS "最低20") and charge hit radius (PRTS 0.35 — also “碎铳之簧”'s 追逐模式 trample). */
|
||||
const ASPD_FLOOR = 20, CHARGE_RADIUS = 0.35;
|
||||
/** 盲信之誓 link half-width (PRTS 0.5). */
|
||||
const LINK_WIDTH = 0.5;
|
||||
@@ -617,10 +617,11 @@ function kitGun(ab, e, b) {
|
||||
if (s2) list.push({
|
||||
cd: s2.cd, icd: s2.icd, cond: (b2) => b2.enemies.some((o) => o.alive && isSpring(o)),
|
||||
fire(b2, e2) { // 【末日布道】 springs dash to 铳, invulnerable, trampling operators
|
||||
// PRTS “碎铳之簧” 追逐模式 "不进行普通攻击": `disarm` for the dash (until 0.1.3 it kept shooting while it ran)
|
||||
for (const sp of b2.enemies) {
|
||||
if (!sp.alive || !isSpring(sp) || !sp.mem.ab) continue;
|
||||
sp.mem.ab.dash = { until: b2.time + (s2.bb.dog_duration ?? 0), mul: 1 + (s2.bb.move_speed ?? 0), gun: e2, hit: new Set() };
|
||||
b2.addBuff(sp, { key: 'boss:dash', duration: s2.bb.dog_duration ?? 0, visible: true, flags: { invulnerable: true, noMove: true, unblockable: true } });
|
||||
b2.addBuff(sp, { key: 'boss:dash', duration: s2.bb.dog_duration ?? 0, visible: true, flags: { invulnerable: true, noMove: true, unblockable: true, disarm: true } });
|
||||
b2.fx('dash', { x: sp.x, y: sp.y, id: sp.id, tx: e2.x, ty: e2.y });
|
||||
}
|
||||
},
|
||||
@@ -686,7 +687,8 @@ function kitSpring(ab, e) {
|
||||
if (!d) return;
|
||||
const g = d.gun && d.gun.alive ? d.gun : gun(b);
|
||||
const arrived = !g || stepToward(e2, g.x, g.y, e2.s.moveSpeed * d.mul * MOVE_SCALE * dt) || Math.hypot(g.x - e2.x, g.y - e2.y) < 1;
|
||||
for (const u of areaAllies(b, e2, e2.x, e2.y, 0.5)) if (!d.hit.has(u)) { d.hit.add(u); hurt(b, e2, u, e2.s.atk, 'phys'); }
|
||||
// 追逐模式 "对进入自身0.35半径范围内的我方单位(包括飞行单位)造成一次攻击力100%的物理普通伤害" (until 0.1.3: radius 0.5)
|
||||
for (const u of areaAllies(b, e2, e2.x, e2.y, CHARGE_RADIUS)) if (!d.hit.has(u)) { d.hit.add(u); hurt(b, e2, u, e2.s.atk, 'phys'); }
|
||||
if (arrived || b.time >= d.until) { e2.mem.ab.dash = null; b.removeBuff(e2, 'boss:dash'); if (e2.route) e2.route.pts = null; }
|
||||
},
|
||||
},
|
||||
|
||||
@@ -701,11 +701,6 @@ const maxTargets = (n) => ({ spawn(b, e) { if (n > 1) e.profile.maxTargets = n;
|
||||
const ep = (el, ratio, sil = false) => ({ sil, dealt(c, b, e) { if (ratio > 0) elem(b, e, c.target, el, e.s.atk * ratio); } });
|
||||
/** Status on every attack hit. */
|
||||
const onHitStatus = (key, dur, value) => ({ dealt(c, b, e) { if (dur > 0) b.applyStatus(c.target, key, { duration: dur, source: e, value }); } });
|
||||
/**
|
||||
* The attack becomes a hit on every ally within radius r it can select as an area (深溟巢涌者 "令攻击范围内的所有我方单位每秒
|
||||
* 受到…伤害": areaAllies — a 迷彩 ally is hit, an unblocking 隐匿 one not; the attack itself still needs a target).
|
||||
*/
|
||||
const hitAllInRadius = (r) => ({ before(c, b, e) { const l = areaAllies(b, e, e.x, e.y, r); if (l.length) c.targets = byPriority(e, l); } });
|
||||
/**
|
||||
* A normal attack that splashes around its target (PRTS: "对主目标造成…普通伤害,对溅射目标造成…溅射伤害"): 碎骨's grenade,
|
||||
* “巨大的丑东西” / “墓碑”'s unblocked ranged attack, 烹泉 / 沏虹's attack, 集团军重型火炮's shell. Its mode is fixed when the
|
||||
@@ -1369,8 +1364,37 @@ function kitTidmag(ab) {
|
||||
}];
|
||||
}
|
||||
|
||||
/** 深溟巢涌者 / 富营养的巢涌者: one pulse every second (PRTS "每秒"; not its attack interval, so 攻速 changes leave it alone). */
|
||||
const NEST_PULSE_INTERVAL = 1;
|
||||
const NEST_PULSE_TAG = 'nestPulse';
|
||||
/**
|
||||
* 深溟巢涌者 / 富营养的巢涌者 (PRTS 天赋): "不进行普通攻击", 抵抗 (一减状态抵抗率 −0.5) and 停顿免疫; "未处于消失状态时,令攻击范围
|
||||
* 内的所有我方单位每秒受到攻击力100%的无途径法术伤害" and "每次输出伤害时,再造成攻击力5%的神经损伤" (`EpDamage.ep_damage_ratio`).
|
||||
* A talent aura, not an attack: `noAttack`, so it walks on while it hurts (ai.js attackStand holds only attackers — until
|
||||
* 0.1.3 the pulse was its normal attack, which made it stand for its whole 1 s clip whenever an ally was in range:
|
||||
* community report 「…错误的设置了攻击时不移动导致卡在原地」, GitHub #93), needs no target and pauses while it is hidden on a
|
||||
* DISAPPEAR leg (消失). The pulse is an area selection (areaAllies: a 迷彩 ally and a flying one — the 炎佑 dragon — are
|
||||
* hit, a 隐匿 one is not) of radius `rangeRadius` around its centre, like 鼎沸's. [ASSUMED] the pulse can be dodged (闪避:
|
||||
* PRTS names no attack type, which the site reads as 普通伤害 — the 烹泉 splash rule) and a dodged one adds no 神经.
|
||||
*/
|
||||
function kitDsubrl(ab, e) {
|
||||
return [hitAllInRadius(e.base.rangeRadius || 1.6), ep('neural', T(ab, 'EpDamage.ep_damage_ratio') ?? 0), resist(['sluggish'])];
|
||||
const ratio = T(ab, 'EpDamage.ep_damage_ratio') ?? 0;
|
||||
return [resist(['sluggish']), {
|
||||
spawn(b, e2) {
|
||||
e2.profile.noAttack = true;
|
||||
// 每次输出伤害时: every pulse that reaches the unit (not dodged, not cancelled — the old attack's `dealt` rule)
|
||||
if (ratio > 0) b.on('damaged', (c) => { if (c.source === e2 && c.dmg && c.dmg.tags.includes(NEST_PULSE_TAG)) elem(b, e2, c.target, 'neural', e2.s.atk * ratio); }, { owner: e2 });
|
||||
},
|
||||
iv: NEST_PULSE_INTERVAL,
|
||||
tick(b, e2) {
|
||||
if (e2.hidden) return;
|
||||
const r = e2.base.rangeRadius || 1.6;
|
||||
const l = areaAllies(b, e2, e2.x, e2.y, r);
|
||||
if (!l.length) return;
|
||||
b.fx('pulse', { x: e2.x, y: e2.y, r, id: e2.id, element: 'neural' });
|
||||
for (const u of l) hurt(b, e2, u, e2.s.atk, 'arts', { canDodge: true, tags: [NEST_PULSE_TAG] });
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
/** 掠海漂移体 爬行模式: the stun it takes on dropping (PRTS "进入爬行模式并晕眩0.5秒"; not in its blackboard). */
|
||||
@@ -1561,7 +1585,10 @@ function kitJazz(ab, e) {
|
||||
const r = (e.def.raw && e.def.raw.stats && e.def.raw.stats.rawRangeRadius) || 2.5;
|
||||
const revealed = (u) => !enemyStealthed(u); // blocked, 反隐 (its 隐匿 returns 0 s after a block)
|
||||
return [stealth(), {
|
||||
spawn(b, e2) { e2.profile.noAttack = true; },
|
||||
// PRTS 天赋 "隐匿期间不进行普通攻击;未受隐匿影响时进入反击模式:仅进行阻挡攻击,造成100%物理伤害": its normal attack only ever
|
||||
// hits its blocker (`melee`), so a revealed (反隐) unblocked one neither shoots nor stands for its attack clip (until
|
||||
// 0.1.3 it shot everyone within its 2.5 range and stood still while it had a target — ai.js attackStand)
|
||||
spawn(b, e2) { e2.profile.noAttack = true; e2.profile.melee = true; },
|
||||
tick(b, e2) { e2.profile.noAttack = !revealed(e2); }, // 平时不攻击,失去隐匿时反击
|
||||
}, s ? {
|
||||
// 狂欢式演奏 (PRTS 节日爵士乐手, 反击模式): "仅攻击范围内存在我方单位时可触发:锁定目标持续施法,最多持续10.6s,每0.5s对目标
|
||||
@@ -2673,7 +2700,7 @@ export const KITS = Object.freeze({
|
||||
enemy_1389_winbab_2: kitStealth, // 访问团强攻冠军 · stealth (供暖器 priority n/a)
|
||||
enemy_1404_msnip: kitCrossbow, // 重弩突袭者 · stealth + 直击 (row/column bolt: arts + stun, reveals itself)
|
||||
enemy_10031_cnvsld: kitStealth, // 业余竞演者 · stealth
|
||||
enemy_10034_cnvsax: kitJazz, // 节日爵士乐手 · stealth, attacks only when revealed; channel on one target (arts + burn)
|
||||
enemy_10034_cnvsax: kitJazz, // 节日爵士乐手 · stealth; revealed: attacks its blocker only; channel on one target (arts + burn)
|
||||
enemy_10042_prtrop: kitStealth, // 架桥船工 · stealth (bridges n/a)
|
||||
enemy_10042_prtrop_2: kitStealth, // 扶桥老手 · stealth
|
||||
enemy_9008_acbunn: kitBoneSpike, // 假想敌:骨刺 · stealth; hits 3 targets while stealthed
|
||||
@@ -2735,7 +2762,7 @@ export const KITS = Object.freeze({
|
||||
enemy_10067_ftsjc: kitFlameVine, // 灼藤 · ATK ramps until the 1st attack (3×3 arts + burn), burn on hit, ignites 卷心籽
|
||||
|
||||
// --- DOT 持续
|
||||
enemy_1234_dsubrl: kitDsubrl, // 深溟巢涌者 · pulse hits every ally in range + neural; 抵抗, immune 停顿
|
||||
enemy_1234_dsubrl: kitDsubrl, // 深溟巢涌者 · no attack: an arts pulse on every ally in range each second + neural; 抵抗, immune 停顿
|
||||
enemy_1234_dsubrl_2: kitDsubrl, // 富营养的巢涌者 · same
|
||||
enemy_1267_nhpbr: kitPolluted, // 萨卡兹枯朽战士 · death: 污染秽蚀 zone (50 / 25 true per second)
|
||||
enemy_1267_nhpbr_2: kitPolluted, // 萨卡兹枯朽战士组长 · same
|
||||
@@ -2989,10 +3016,16 @@ export const KITS = Object.freeze({
|
||||
sil: true, cd: ab.sk.SwitchModeTrigger ? ab.sk.SwitchModeTrigger.cd : 60, icd: ab.sk.SwitchModeTrigger ? ab.sk.SwitchModeTrigger.icd : 10,
|
||||
fire(b, e, a) { a.until = b.time + (T(ab, 'EndRotate.rotate_duration') ?? 0); b.fx('telegraph', { x: e.x, y: e.y, r: 1, kind: 'spin', id: e.id }); },
|
||||
iv: T(ab, 'RotateDamage.interval') ?? 1,
|
||||
// "每秒对半径1.0范围内的所有我方单位造成…(无视迷彩,不可对空)": an area selection
|
||||
tick(b, e, a) { if (!(a.until > b.time)) return; for (const u of areaAllies(b, e, e.x, e.y, T(ab, 'RotateDamage.attack@range_radius') ?? 1)) hurt(b, e, u, e.s.atk * (T(ab, 'RotateDamage.attack@atk_scale') ?? 1), 'phys'); },
|
||||
// "每秒对半径1.0范围内的所有我方单位造成…(无视迷彩,不可对空),自身受阻止攻击类异常效果影响期间无法造成此伤害": an area
|
||||
// selection, skipped while 晕眩 / 冻结 / 浮空 (flag stun), 沉睡 or 缴械 hold it (PRTS 异常效果 §阻止攻击; until 0.1.3 it spun on)
|
||||
tick(b, e, a) {
|
||||
if (!(a.until > b.time) || e.s.flags.stun || e.s.flags.sleep || e.s.flags.disarm) return;
|
||||
for (const u of areaAllies(b, e, e.x, e.y, T(ab, 'RotateDamage.attack@range_radius') ?? 1)) hurt(b, e, u, e.s.atk * (T(ab, 'RotateDamage.attack@atk_scale') ?? 1), 'phys');
|
||||
},
|
||||
};
|
||||
return [spin, unbalanced((b, e) => { if (spin.until > b.time) { spin.until = 0; b.fx('phase', { x: e.x, y: e.y, id: e.id, kind: 'spinStop' }); } })];
|
||||
// 漩涡形态 "不进行普通攻击" (PRTS 天赋): no blocked attack while it spins (until 0.1.3 its blocker took both)
|
||||
const noAtk = { tick(b, e) { e.profile.noAttack = spin.until > b.time; } };
|
||||
return [spin, noAtk, unbalanced((b, e) => { if (spin.until > b.time) { spin.until = 0; b.fx('phase', { x: e.x, y: e.y, id: e.id, kind: 'spinStop' }); } })];
|
||||
},
|
||||
enemy_10118_ymgprc: (ab) => { // 澪 · double hits; 寒晖: every 4th attack (spCost 3) is a ×1.5 double hit
|
||||
const scale = (ab.sk.PowerAttack && ab.sk.PowerAttack.bb.atk_scale) || 1;
|
||||
@@ -3067,9 +3100,12 @@ export const KITS = Object.freeze({
|
||||
b.fx('explode', { x: e.x, y: e.y, r: 0.4, kind: 'wallHit', id: e.id });
|
||||
hurt(b, null, e, T(ab, 'hitWall.value') ?? 0, 'true', { tags: ['wallHit'] });
|
||||
})],
|
||||
enemy_10141_xdpeng_2: (ab) => [unbalanced((b, e, a) => { // 拥霜羽兽 · unbalanced once ⇒ drops its egg: faster, unblockable
|
||||
// 拥霜羽兽 · PRTS 天赋 "不会攻击飞行单位"; unbalanced once ⇒ 失去蛋的模式 "不进行普通攻击,不可阻挡,移动速度最终提升至200%" (until
|
||||
// 0.1.3 it kept its ranged attack without the egg and stood for each attack clip — ai.js attackStand —, and shot the 炎佑 dragon)
|
||||
enemy_10141_xdpeng_2: (ab) => [noAirTargets(), unbalanced((b, e, a) => {
|
||||
if (a.done) return;
|
||||
a.done = true;
|
||||
e.profile.noAttack = true;
|
||||
b.addBuff(e, { key: 'ab:noEgg', persist: true, visible: true, flags: { unblockable: true }, mods: { moveMul: 1 + (T(ab, 'speed.move_speed') ?? 0) } });
|
||||
})],
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user