- Shared card pool and item stock as in the official mode (the owner's request, from the 路标档案馆 video and public notes): solo low-tier exceptions, co-op operators x2, shared item stock with special-item exceptions, normal / advanced occupancy 1 / 2, re-check on buy, 机变 exhaustion, release on consume / destroy / elimination; 整备 never exceeds stock; invariant held <= cap. - 突袭: one taunt-first reselect right after a revive (the owner's rule); ordinary polls and redeploys keep the 0.2.3 rule; a revive on an enemy's tile stays. #475: online boss / hidden-boss Raid may land on the empty half (owner-limited scope). - 浊心斯卡蒂 S1 x 坚守 no longer bounce redirected damage, and the two shares conserve the hit (idea of PR #464 by @HappyTanuki). - Operator fixes adapted from PRs by @Xinglan233 (#459 哈洛德 S2 elemental trigger, #460 涤火杰西卡 shield on the four adjacent tiles, #461 家族徽章 first hit after stealth, #462 松果 S2 regrow per deploy); 克莱门莎 S2 splash 1.1 / 100% ATK and air auto-trigger (#467); 白面 copying 歌蕾蒂娅 / 余 skips the three-member condition (#473, the owner's video). - 香槟炸弹 is not chosen by friendly auras / heals (PR #468 / #476 by @Siornya); 琳琅诗怀雅 coin balance (PR #450 by @IceCodeNew); Touch prep display (PR #451 by @YinqiMargatroid); lobby header (PR #471 by @YuriRestia); Japanese UI terms (PR #448 by @scutkane). - AI-only boss countdown grace, render-failure cache / recovery without restarting a battle, device units kept on a same-field re-entry, DIY detail / skill previews, large-text result buttons. - golden: battle families equal 0.2.3 except diy-135 / diy-136 (克莱门莎); all 18 release matches move through the shared pool, every flip named in docs/history/0.2.4.md §29.12; two coverage scenarios added.
60 lines
3.0 KiB
JavaScript
60 lines
3.0 KiB
JavaScript
// server/sim/content/kits/ops/chess_char_3_10-pinecn.js — 松果 (char_440_pinecn) kit, tier 3.
|
||
// Conventions of the tier-3 kits: ../shared/tier3.js; kit contract and rules: ../README.md.
|
||
|
||
import { num, defOf, talentBb, selectedId, altSkills, instantKindOf, copyGrid } from '../shared/tier3.js';
|
||
|
||
export default {
|
||
// ---- 3_10 松果 · 散射手 — S2 电能过载: ATK + growing with each use (a→d), shorter range; 便携电源: SP regen for 60 s
|
||
chess_char_3_10_a: (bb, chess, def) => {
|
||
const d = defOf(chess, def);
|
||
const t0 = talentBb(d, 0);
|
||
const sel = selectedId(chess, d);
|
||
const steps = Object.keys(bb).filter((k) => /\[[a-z]\]\.atk$/.test(k)).sort().map((k) => num(bb[k]));
|
||
if (!steps.length) steps.push(num(bb.atk));
|
||
const skillGrid = copyGrid(d.skill?.rangeGrid);
|
||
const kit = {
|
||
skill: {
|
||
kind: 'duration',
|
||
onStart({ battle, unit }) {
|
||
const uses = unit.mem.pinecnS2Uses ?? 0;
|
||
unit.mem.pinecnS2Uses = uses + 1;
|
||
const atk = steps[Math.min(steps.length - 1, uses)];
|
||
battle.addBuff(unit, { key: 'skill:pinecn_atk', mods: { atkPct: atk } });
|
||
},
|
||
onEnd({ battle, unit }) { battle.removeBuff(unit, 'skill:pinecn_atk'); },
|
||
},
|
||
// S1 RMA长钉 (charges): "立即以165%的攻击力进行一次攻击,无视敌人180的防御力" — an extra shot fired at once (all
|
||
// enemies in range, front-row × of the trait), on top of the normal attack it was cast before
|
||
skills: altSkills(chess, d, bb, {
|
||
skchr_pinecn_1: (s) => ({
|
||
kind: instantKindOf(s),
|
||
// (the DEF ignore rides on the shots' tag: they land after the instant skill has ended)
|
||
attack: { atkScale: num(s.bb.atk_scale, 1), tags: ['skill', 'pinecnSpike'] },
|
||
onStart({ battle, unit }) { battle.forceAttack(unit); },
|
||
}),
|
||
}),
|
||
talents: [{ install(battle, unit) {
|
||
battle.on('deploy', (ctx) => {
|
||
if (ctx.unit !== unit) return;
|
||
// PRTS 松果: count skill uses since this deployment; the runtime's activation identity stays cumulative.
|
||
unit.mem.pinecnS2Uses = 0;
|
||
battle.addBuff(unit, { key: 'talent:pinecn_power', duration: num(t0.duration, 60), mods: { spRecoveryFlat: num(t0.sp_recovery_per_sec) } });
|
||
}, { owner: unit });
|
||
} }],
|
||
};
|
||
if (sel === 'skchr_pinecn_1') {
|
||
const pen = num(bb.def_penetrate_fixed, 0);
|
||
kit.install = (battle, unit) => battle.on('hit', (ctx) => {
|
||
if (ctx.source === unit && pen > 0 && ctx.dmg.tags?.includes('pinecnSpike')) ctx.dmg.defIgnoreFlat += pen;
|
||
}, { owner: unit });
|
||
}
|
||
if (skillGrid) {
|
||
kit.skill.targeting = { rangeGrid: skillGrid };
|
||
// "攻击范围缩短": offensive skills fire with an enemy inside the SKILL range (research 03 §1.4) — with the
|
||
// initial (wider) range she would open the skill on enemies the shortened range cannot reach
|
||
kit.skill.trigger = { rule: 'CUSTOM_RANGE', grid: skillGrid };
|
||
}
|
||
return kit;
|
||
},
|
||
};
|