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.
81 lines
4.6 KiB
JavaScript
81 lines
4.6 KiB
JavaScript
// server/sim/content/kits/ops/chess_char_3_08-mint.js — 薄绿 (char_388_mint) kit, tier 3.
|
||
// Conventions of the tier-3 kits: ../shared/tier3.js; kit contract and rules: ../README.md.
|
||
|
||
import { num, defOf, talentBb, traitBb, altSkills, gridKeys, fx, copyGrid, enemiesOn, aura } from '../shared/tier3.js';
|
||
|
||
export default {
|
||
// ---- 3_08 薄绿 · 阵法术师 — S2 聚能涡旋: each attack strikes every enemy on her range (the trait's 群体法术伤害) and
|
||
// pushes each one towards her, end-of-skill burst on
|
||
// every enemy in range; 地质学者: DEF aura (skill off) / less likely targeted (skill on);
|
||
// 精锐 module PLX-X: keeps part of the guard (DEF/RES) while the skill runs
|
||
// S1 风语: wider range (skill grid), attacks every enemy on it at attack@atk_scale. Auto-cast: the official
|
||
// rule is the 阵法术师 row SEARCH (PRTS 卫戍协议/帮助 "不受基础策略影响,在初始攻击范围内存在敌人时释放技能"; it covers
|
||
// every MANUAL skill of the class — user playtest #6) = an enemy inside her INITIAL range, never any enemy on the
|
||
// field (she would burn the skill on enemies that just spawned). Since 0.2.0 the owner's ACTIVE_RANGE rule
|
||
// (2026-10-05) widens it: the S1 x-2 strictly contains her x-1, so the data rule is ACTIVE_RANGE on the x-2 (rawRule
|
||
// SEARCH) — an enemy she can target inside the x-2, every tick — which this spec reads. S2 keeps SEARCH (no range
|
||
// change).
|
||
chess_char_3_08_a: (bb, chess, def) => {
|
||
const d = defOf(chess, def);
|
||
const t0 = talentBb(d, 0);
|
||
const tb = traitBb(d);
|
||
const tGrid = copyGrid(d.talents?.[0]?.rangeGrid) ?? [[1, 0], [0, -1], [0, 0], [0, 1], [-1, 0]];
|
||
const pullForce = num(bb['attack@force'], num(bb.force, 0));
|
||
const endScale = num(bb.atk_scale, 0);
|
||
const keepDef = num(tb['soil_e_002[buff].def'], 0), keepRes = num(tb['soil_e_002[buff].magic_resistance'], 0);
|
||
// every skill: PLX-X keeps part of the guard, 地质学者 taunt −1 while it runs, DEF aura only while it does not
|
||
const guardOn = ({ battle, unit }) => {
|
||
if (keepDef || keepRes) battle.addBuff(unit, { key: 'trait:mint_keep', mods: { defPct: keepDef, resFlat: keepRes } });
|
||
battle.addBuff(unit, { key: 'talent:mint_taunt', mods: { taunt: num(t0.taunt_level, -1) } });
|
||
unit.mem.mintAura?.();
|
||
};
|
||
const guardOff = ({ battle, unit }) => {
|
||
battle.removeBuff(unit, 'trait:mint_keep');
|
||
battle.removeBuff(unit, 'talent:mint_taunt');
|
||
unit.mem.mintAura?.();
|
||
};
|
||
return {
|
||
skills: altSkills(chess, d, bb, {
|
||
skchr_mint_1: (s) => {
|
||
const grid = copyGrid(s.rangeGrid);
|
||
return {
|
||
kind: 'duration',
|
||
attack: { atkScale: num(s.bb['attack@atk_scale'], num(s.bb.atk_scale, 1)) },
|
||
...(grid ? { targeting: { rangeGrid: grid } } : {}),
|
||
onStart: guardOn,
|
||
onEnd: guardOff,
|
||
};
|
||
},
|
||
}),
|
||
skill: {
|
||
kind: 'duration',
|
||
attack: {
|
||
atkScale: num(bb['attack@atk_scale'], 1),
|
||
onHit({ battle, unit, target }) {
|
||
if (!target || !target.alive || target.side !== 'enemy') return;
|
||
// PRTS 备注: "此技能的“拖拽”机制实际为反方向(指向薄绿方向)的推开" — a radial push towards her by the
|
||
// official 力度 − 重量 push distance (小力 vs weight 1: 0.44 tiles), never past her (Battle.push inward). Her
|
||
// attack reaches air units (阵法术师 "攻击时可对空"), but the drones of the mode are 静态刚体 (PRTS 特殊机制): hit,
|
||
// never dragged (player report after 0.1.0, "飞机可以被薄绿的技能拉走")
|
||
if (battle.push(target, pullForce, { from: unit, inward: true }) > 0) fx(battle, 'pull', target, { src: unit.id });
|
||
},
|
||
},
|
||
onStart: guardOn,
|
||
onEnd(ctx) {
|
||
const { battle, unit, reason } = ctx;
|
||
if (reason !== 'death' && unit.alive && endScale > 0) {
|
||
for (const e of enemiesOn(battle, unit, unit.rangeKeys)) battle.dealDamage(unit, e, { amount: unit.s.atk * endScale, type: 'arts', isSkill: true, tags: ['skill', 'burst'] });
|
||
fx(battle, 'aoe', unit, { radius: 2, dmgType: 'arts', skill: 'mint_2' });
|
||
}
|
||
guardOff(ctx);
|
||
},
|
||
},
|
||
talents: [{ install(battle, unit) {
|
||
unit.mem.mintAura = aura(battle, unit, {
|
||
key: 'talent:mint_geo', side: 'ally', tiles: () => gridKeys(tGrid, unit), active: () => !unit.skill?.active, mods: { defPct: num(t0.def) },
|
||
});
|
||
} }],
|
||
};
|
||
},
|
||
};
|