Files
ark-stronghold-protocol/server/sim/content/kits/ops/chess_char_5_20-aglina.js
T
sganggs 383fe4a49e 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.
2026-10-05 18:45:13 +08:00

74 lines
4.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// server/sim/content/kits/ops/chess_char_5_20-aglina.js — 安洁莉娜 (char_291_aglina) kit, tier 5.
// Conventions of the tier-5 kits: ../shared/tier5.js; kit contract and rules: ../README.md.
import {
AURA_IV, AURA_DUR, num, talent, skillGrid, batPct, mods, selectedId, lazySkills, whileOn,
} from '../shared/tier5.js';
/** 安洁莉娜 S3 失重: weight (massLevel) reduction while weightless. PRTS: "重量下降一个等级". */
const WEIGHTLESS_MASS = 1;
/** "攻击范围内存在敌人时,技力自然恢复速度+X/秒" (modules DEC-X). */
function enemySpUp(battle, unit, key, sp) {
if (!(sp > 0)) return;
whileOn(battle, unit, AURA_IV, () => {
if (battle.enemiesInKeys(unit.rangeKeys, unit, { canHitFly: true }).length) battle.addBuff(unit, { key, duration: AURA_DUR, mods: { spRecoveryFlat: sp } });
});
}
export default {
// ---------------------------------------------------------------------------------------------------------------
// 安洁莉娜 — slower (no normal attack while the skill is off). S3 秘杖·反重力模式 (14/18 s; her SEARCH row widened to
// ACTIVE_RANGE on its y-4 by the owner's rule of 2026-10-05: an enemy inside the y-4 casts it): every enemy on the
// field is weightless, skill range, ATK +, 4/5 targets. T1 加速力场: all allies ASPD +7. T2 兼职工作: while the skill is
// off, all allies regenerate 20 HP/s. Module (elite): longer sluggish (trait bb, profession tunables).
// S1 秘杖·速充模式 (duration, attack SP): ATK +; she attacks normally with S1 ("技能未开启时无法普通攻击" is only in the
// S2/S3 texts). S2 秘杖·微粒模式 (duration, SEARCH): attack interval ×base_attack_time ("极大幅度缩短": a positive value
// described as a shortening is the new interval ratio, the shared/tier1.js batMod convention), each attack damage_scale × ATK arts.
// Module DEC-X (elite): SP +0.2/s with an enemy in range.
chess_char_5_20_a: (bb, chess, def) => {
const t0 = talent(chess, 0), t1 = talent(chess, 1), tm = talent(chess, -1);
const sid = selectedId(chess, def);
const ratioBat = (v) => (num(v) > 0 && num(v) < 1 ? num(v) - 1 : batPct(v, chess));
const weightless = (battle, unit) => {
const left = Math.max(0.1, num(unit.skill?.timeLeft, 1));
for (const e of battle.enemies) {
if (!e.alive || e.findBuff('aglina:weightless')) continue;
// 失重: weight −1 level (engine mod `massFlat`; massLevel never drops below 0)
battle.addBuff(e, { key: 'aglina:weightless', status: 'weightless', visible: true, duration: left, data: { src: unit }, mods: { massFlat: -WEIGHTLESS_MASS } });
}
};
return {
skills: lazySkills({
skchr_aglina_1: () => ({ kind: 'duration', mods: mods({ atkPct: num(bb.atk) }) }),
skchr_aglina_2: () => ({ kind: 'duration', mods: mods({ batPct: ratioBat(bb.base_attack_time) }), attack: { atkScale: num(bb.damage_scale, 1) } }),
}),
skill: {
kind: 'duration',
mods: mods({ atkPct: num(bb.atk) }),
targeting: skillGrid(chess, def) ? { rangeGrid: skillGrid(chess, def) } : undefined,
attack: { maxTargets: Math.max(1, num(bb['attack@max_target'], 1)) },
onStart({ battle, unit }) { unit.mem.aglAcc = 0; weightless(battle, unit); battle.fx('weightless', { x: unit.x, y: unit.y, id: unit.id }); },
onTick({ battle, unit, dt }) { unit.mem.aglAcc += dt; if (unit.mem.aglAcc >= AURA_IV) { unit.mem.aglAcc = 0; weightless(battle, unit); } },
onEnd({ battle, unit }) {
for (const e of battle.enemies) { const b = e.findBuff('aglina:weightless'); if (b && b.data.src === unit) battle.removeBuff(e, b); }
},
},
trait: sid === 'skchr_aglina_1' ? undefined : { noAttackUnlessSkill: true },
install(battle, unit) { enemySpUp(battle, unit, 'aglina:module', num(tm.sp_recovery_per_sec)); },
talents: [
{ install(battle, unit) { // 加速力场
const aspd = num(t0.attack_speed);
if (aspd) whileOn(battle, unit, AURA_IV, () => { for (const a of battle.alliesFor(unit)) battle.addBuff(a, { key: 'aglina:field', duration: AURA_DUR, mods: { aspd } }); });
} },
{ install(battle, unit) { // 兼职工作
const hp = num(t1.hp_recovery_per_sec);
// an HP-regeneration attribute, so 禁疗 does not stop it — PRTS 备注 "生命回复的提供方式为增加目标的'生命回复速度'属性,
// 不受治疗加成和禁疗影响" (异常效果 禁疗: "增减生命回复速度…的效果不会被识别为治疗类能力"); a 孤立 unit (炎佑) is not
// selected (Battle.alliesFor)
if (hp > 0) whileOn(battle, unit, AURA_IV, () => { if (!unit.skill?.active) for (const a of battle.alliesFor(unit)) battle.addBuff(a, { key: 'aglina:parttime', duration: AURA_DUR, mods: { hpRegen: hp } }); });
} },
],
};
},
};