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:
1 parent
a009d77d71
commit
8f62f3e360
11 files changed
+354
-214
No files matched your search
+27
-10
@@ -24,7 +24,10 @@
|
||||
// skipEnemy(enemy) → bool (an enemy the unit never selects — targeting.js canTargetEnemy; 嵯峨 "不攻击重伤单位")
|
||||
// healThrough(healer, ally) → bool (a healer that selects and heals that ally through its 禁疗 — Battle
|
||||
// injuredAlliesInKeys, damage.js heal; 凯尔希 on her Mon3tr)
|
||||
// hitsFn(battle, unit) → n install(battle, unit) — per-unit hooks, called once at setup
|
||||
// hitsFn(battle, unit, info) → n (info: the hit's { isSkill, index, attackId, energy })
|
||||
// install(battle, unit) — per-unit hooks, called once at setup
|
||||
// storeEnergy(battle, unit) → bool / releaseEnergy(battle, unit) → n (秘术师: the attack check found no valid target ⇒
|
||||
// store one energy, false when full; the energies leaving with an attack — installMystic)
|
||||
// dollNoAttack bool (傀儡师: its <替身> makes no normal attack and casts no skill — 归溟幽灵鲨, kit trait)
|
||||
// tb — the unit's trait blackboard (data `trait.bb`), used for tunables (module upgrades included on elites)
|
||||
// Behaviour per subprofession is documented in docs/SIM.md §Professions. Front / side tests use the unit's direction
|
||||
@@ -362,16 +365,23 @@ const installFunnel = (battle, unit) => {
|
||||
unit.trait.funnelScale = unit.profile.funnel?.init ?? 0.2;
|
||||
};
|
||||
|
||||
/**
|
||||
* 秘术师 (mystic) trait "攻击造成法术伤害,在找不到攻击目标时可以将攻击能量储存起来之后一齐发射(最多3个)" (bb times; 深靛's
|
||||
* MSC-X 4) with the branch rules of PRTS 分支特性信息 秘术师: "能量储存与攻击占用相同的攻击间隔:在进行攻击判定时,若范围内存在
|
||||
* 有效目标,则进行普通攻击;若无有效目标且能量储存数未满,则改为储存一份攻击能量(属于攻击行为);仅没有有效目标,且能量储存数已满的
|
||||
* 情况下才进入待机状态". The attack loop (ai.js updateAlly) calls the profile's `storeEnergy` at its attack check — the attack
|
||||
* ready, the unit able to act and not disarmed (PRTS 异常效果 缴械 "秘术师储存能量同样无法进行") — when it finds no valid target
|
||||
* (no target, or the profile's `canAttack` false: a 秘术师 kit's own target rule — 深靛 never picks a bound enemy, so a bind
|
||||
* on her only target is no valid target); a stored energy restarts the attack interval, a full store idles (the next
|
||||
* valid target is attacked at once). The energies leave with the next attack that happens (`releaseEnergy`, called by
|
||||
* performAttack after `beforeAttack`: "攻击被打断且弹道未能成功生成的情况下,储存的能量不会被消耗") with its main target and land
|
||||
* with its main hit, one damage instance each (`hitsFn`; "由储存能量形成的弹道造成攻击力100%的法术普通伤害" — each as the
|
||||
* main hit). [ASSUMED] a redeployment holds no energy (a free move — 乌尔比安 S3 — keeps them). Kits with their own store
|
||||
* (维伊's 转置能量, 黑键's elite energies) replace `storeEnergy` and release theirs from an `attack` hook.
|
||||
*/
|
||||
const installMystic = (battle, unit) => {
|
||||
unit.trait.stored = 0;
|
||||
const max = unit.profile.storeMax ?? 3;
|
||||
battle.on('tick', () => {
|
||||
if (!unit.canAct) return;
|
||||
if (unit.atkCd <= 0 && !unit.trait.hadTarget && unit.trait.stored < max) {
|
||||
unit.trait.storeAcc = (unit.trait.storeAcc ?? 0) + battle.dt;
|
||||
if (unit.trait.storeAcc >= unit.s.interval) { unit.trait.storeAcc = 0; unit.trait.stored++; }
|
||||
}
|
||||
}, { owner: unit });
|
||||
battle.on('deploy', (ctx) => { if (ctx.unit === unit && !ctx.move) unit.trait.stored = 0; }, { owner: unit });
|
||||
};
|
||||
|
||||
/** Refresh period / lifetime (s) of a bard trait's 生命回复速度 buff: it lapses within BARD_REGEN_DUR once the bard stops. */
|
||||
@@ -480,7 +490,14 @@ export const SUB = Object.freeze({
|
||||
return unit.trait.funnelScale;
|
||||
} }),
|
||||
mystic: P({ install: installMystic,
|
||||
hitsFn: (battle, unit) => { const n = 1 + (unit.trait.stored ?? 0); unit.trait.stored = 0; return n; } }),
|
||||
storeEnergy: (battle, unit) => {
|
||||
const n = unit.trait.stored ?? 0;
|
||||
if (n >= (unit.profile.storeMax ?? 3)) return false;
|
||||
unit.trait.stored = n + 1;
|
||||
return true;
|
||||
},
|
||||
releaseEnergy: (battle, unit) => { const n = unit.trait.stored ?? 0; unit.trait.stored = 0; return n; },
|
||||
hitsFn: (battle, unit, info) => 1 + (info?.energy ?? 0) }),
|
||||
phalanx: P({ noAttackUnlessSkill: true, rangeAoe: true, install: installPhalanx }),
|
||||
primcaster: P({}),
|
||||
corecaster: P({}),
|
||||
|
||||
Reference in new issue
Block a user