feedback5 WE1: 秘术师 stores its energy at the attack check, not one interval later (GitHub #181)

PRTS 分支特性信息 秘术师: "能量储存与攻击占用相同的攻击间隔:在进行攻击判定时…若无有效目标且能量储存数未满,则改为储存一份
攻击能量(属于攻击行为);仅没有有效目标,且能量储存数已满的情况下才进入待机状态", "攻击被打断且弹道未能成功生成的情况下,储存的
能量不会被消耗"; PRTS 异常效果 缴械 "秘术师储存能量同样无法进行".

- ai.js updateAlly: a ready unit (able to act, not disarmed) whose attack check finds no valid target — no target, or
  its profile's canAttack false (a 秘术师 kit's target rule: 深靛's bound enemies, 维伊's marked ones) — calls the
  profile's storeEnergy; a stored energy restarts the attack interval, a full store idles with the attack ready. A
  DEFAULT cast at the check that leaves no target stores in the same check.
- professions.js mystic: storeEnergy (up to bb times), releaseEnergy (performAttack, after beforeAttack: a cancelled
  shot keeps them) and hitsFn(b, u, info) — the energies leave with the attack and land with its main hit; the old
  separate store timer (it started only once the attack was ready and never restarted the interval) is gone.
  [ASSUMED] a redeployment holds no energy.
- 维伊 / 黑键 kits: their own tick stores become the kit's storeEnergy on the shared check; 深靛 / 维伊 no longer write
  hadTarget themselves.

Golden: roster-003, roster-021, roster-022, bond-preciShip-high (深靛 stores at her check); matches solo-FUNNY-1,
solo-NORMAL-2, solo-HARD-2, solo-ABYSS-1, solo-ABYSS-2, coop2-NORMAL-3, coop2-HARD-4, coop4-FUNNY-6, coop4-ABYSS-7,
coop2-NORMAL-8-serverrun, solo-HARD-9-boosted, coop2-ABYSS-10-boosted, coop2-NORMAL-14-standins (each fields 深靛);
diy-032 (维伊) and diy-114 (黑键): the first store after a redeployment comes at the next tick's attack check instead of
the end of the redeploy tick (with the old tick store added back as a fallback the diy family matches the old digests).
fields, standins unchanged.

Tests: test/sim/feedback5-mystic-store.test.js (new, 4); op_veen, op_ebnhlz, kits_t1t2, kits_alt_t1 pass unchanged.
Docs: SIM.md §Professions (mystic row, profile hooks).
This commit is contained in:
sganggs committed 2026-10-06 14:53:56 +08:00
1 parent a009d77d71
commit 8f62f3e360
11 files changed
+354 -214

No files matched your search

@@ -11,7 +11,8 @@ export default {
// 柔光缚目: attacks bind the target `duration` s with `prob`; bound enemies are never chosen as targets.
// Alternate S1 灯塔守卫者: for `duration` s the skill range (4-1), attack interval ×(1 + base_attack_time) (PRTS:
// "大幅度缩短(-80%)" ⇒ ×0.2 — a flat −0.8 s on 3 s would be less than S2's "略微缩短 ×0.7"), every attack hits for
// attack@atk_scale × ATK arts. Elite module MSC-X (store 4) is the mystic profile of the module trait (TUNE.mystic).
// attack@atk_scale × ATK arts. Elite module MSC-X (store 4) is the mystic profile of the module trait (TUNE.mystic);
// the store itself is the shared 秘术师 profile (professions.js installMystic: at the attack check, PRTS 分支特性信息).
chess_char_1_17_a: (bb, chess, def) => {
const t = talentBb(chess, 0);
const dScale = num(bb['indigo_s_2[damage].atk_scale']);
@@ -28,12 +29,11 @@ export default {
},
},
trait: {
// with only bound enemies in range (or blocked by her — always her targets, Battle.blockedTargets) she holds her
// fire (the mystic trait stores the energy meanwhile)
// with only bound enemies in range (or blocked by her — always her targets, Battle.blockedTargets) she has no valid
// target: she holds her fire and the mystic trait stores an energy at the attack check (professions.js
// installMystic; a bind on her only target included)
canAttack(battle, u) {
const ok = battle.enemiesInKeys(u.rangeKeys, u, u.profile).some((e) => !bound(e)) || battle.blockedTargets(u, u.profile).some((e) => !bound(e));
if (!ok) u.trait.hadTarget = false;
return ok;
return battle.enemiesInKeys(u.rangeKeys, u, u.profile).some((e) => !bound(e)) || battle.blockedTargets(u, u.profile).some((e) => !bound(e));
},
afterHit(battle, u, target) {
if (!target || !target.alive || target.side !== 'enemy') return;