Let charged guardian heals act without enemies and fix mixed S2 triggers (#406)
This commit is contained in:
1 parent
c9481c40bb
commit
e86c7c8304
9 files changed
+155
-50
No files matched your search
@@ -101,6 +101,13 @@ export function updateAlly(b, u, dt) {
|
||||
// (a 秘术师's `canAttack` is its own target rule: false = no valid target — 深靛's bound enemies, 维伊's marked ones)
|
||||
if (prof.canAttack && !prof.canAttack(b, u)) { if (prof.storeEnergy) { u.trait.hadTarget = false; storeEnergy(b, u, prof); } return; }
|
||||
let targets = acquireTargets(b, u, prof);
|
||||
// A DEFAULT charged heal can replace this attack with an eligible ally even when no enemy exists.
|
||||
// Run after cooldown/control checks so silence, disarm and the exact attack cadence still apply (#406).
|
||||
if (!targets.length && sk?.triggerAllies && sk.onAboutToAttack()) {
|
||||
prof = effectiveProfile(u);
|
||||
if (prof.noAttack || !u.alive) return;
|
||||
targets = acquireTargets(b, u, prof);
|
||||
}
|
||||
if (!targets.length) { u.trait.hadTarget = false; storeEnergy(b, u, prof); return; }
|
||||
u.trait.hadTarget = true;
|
||||
if (sk && sk.onAboutToAttack()) {
|
||||
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
// 塞雷娅 — S2 药物配置 (instant, time SP): heals every ally in the skill range for heal_scale × ATK (cast when one is
|
||||
// injured). T1 莱茵充能护服: every 20 s on the field ATK +5 % / DEF +4 % (×5). T2 精神回复: +1 SP to every ally she heals.
|
||||
// Module (elite): heals on allies below 50 % ×1.15.
|
||||
// S1 急救 (instant / 2 charges elite, 自动触发: cast at her attack when an ally of the skill area 周围 is at ≤ half HP):
|
||||
// S1 急救 (instant / 2 charges elite, 自动触发: cast at her attack interval when an ally of the skill area 周围 is at ≤ half HP):
|
||||
// that attack is instead a heal of the lowest such ally for heal_scale × ATK.
|
||||
// S3 钙质化 (duration; the 重装 strategy TAKE_DAMAGE): allies in the skill area heal
|
||||
// attack@heal_scale × ATK per second; enemies there take arts ×demkni_s_3.damage_scale and move −60 %.
|
||||
@@ -46,10 +46,9 @@ export default {
|
||||
return {
|
||||
skills: lazySkills({
|
||||
skchr_demkni_1: () => ({
|
||||
// 自动触发: its own rule, no 技能策略 — PRTS 备注 "此技能仅在周围有符合血量条件的友方单位时可触发,触发时会替换当次
|
||||
// 攻击" and the corrected text "血量小于等于一半": checked when she is about to attack (an enemy target, the basic
|
||||
// rule), an ally of the skill area at ≤ half HP casts it and that attack becomes the heal (unlike 古米's 备用军粮,
|
||||
// no heal mode is left waiting: the engine withdraws a cast whose ally was healed before the attack)
|
||||
// AUTO: PRTS limits this charged heal to a healable ally at ≤ half HP; it replaces that attack.
|
||||
// It uses her attack interval even without an enemy. If the patient recovers before the attack,
|
||||
// the engine withdraws the cast and refunds its charge.
|
||||
kind: instantKind(chess, def),
|
||||
trigger: { rule: 'DEFAULT', grid, allies: true, hpAtMost: HALF_HP },
|
||||
targeting: { rangeGrid: grid },
|
||||
|
||||
@@ -268,6 +268,8 @@ export default {
|
||||
[S1]: { kind: 'duration', mods: { atkPct: num(b1.atk), aspd: num(b1.attack_speed) } },
|
||||
[S2]: {
|
||||
kind: 'ammo',
|
||||
// The larger active range contains attack targets as well as patients (#406).
|
||||
trigger: { rule: 'ACTIVE_RANGE', grid: s2?.rangeGrid, enemies: true },
|
||||
ammo: Math.max(1, Math.floor(num(b2['attack@trigger_time'], 10))),
|
||||
mods: { atkPct: num(b2.atk) },
|
||||
targeting: s2?.rangeGrid ? { rangeGrid: s2.rangeGrid } : undefined,
|
||||
|
||||
@@ -101,8 +101,9 @@ export class SkillRuntime {
|
||||
if (this.rule.startsWith('CUSTOM_RANGE')) this.rule = 'CUSTOM_RANGE';
|
||||
this.triggerGrid = trig.grid ?? trig.rangeGrid ?? d.trigger?.grid ?? null;
|
||||
// kit options: an injured, healable ally of the trigger grid with an HP ratio of at most `hpAtMost` (SKILL_RANGE:
|
||||
// instead of an enemy; DEFAULT: in addition to the basic rule)
|
||||
// instead of an enemy; DEFAULT: a heal target at the normal attack cadence)
|
||||
this.triggerAllies = !!trig.allies;
|
||||
this.triggerEnemies = !!trig.enemies; // mixed attack/heal skills may also open for a selectable enemy
|
||||
this.triggerHpAtMost = Number.isFinite(+trig.hpAtMost) && +trig.hpAtMost > 0 ? +trig.hpAtMost : 1;
|
||||
this.healSkill = s.heal ?? (unit.profile && unit.profile.dmgType === 'heal' && !!unit.profile.heal);
|
||||
// the official skill strategies automate the manual 开启: only MANUAL skills wait for the operation cooldown
|
||||
@@ -483,7 +484,8 @@ export class SkillRuntime {
|
||||
if (b.rangeChanged(u)) b._refreshRange(u);
|
||||
const keys = range || u.baseRangeKeys || u.rangeKeys;
|
||||
if (keys) {
|
||||
if (this.healSkill) return b.injuredAlliesInKeys(keys, u).length > 0;
|
||||
if (this.healSkill) return b.injuredAlliesInKeys(keys, u).length > 0
|
||||
|| (this.triggerEnemies && b.enemiesInKeys(keys, u, TRIGGER_PROFILE).length > 0);
|
||||
if (b.enemiesInKeys(keys, u, u.profile).length > 0 || this._allyTargetIn(keys)) return true;
|
||||
}
|
||||
// the enemies a unit blocks are always its targets (Battle.blockedTargets), in range or not — PRTS 卫戍协议/帮助
|
||||
@@ -498,8 +500,8 @@ export class SkillRuntime {
|
||||
if (this.active && this.isTimed) return false;
|
||||
if (this.rule === 'TAKE_DAMAGE' || this.rule === 'NEVER' || TICK_RULES.has(this.rule)) return false;
|
||||
if (this.pending || this._opCooling()) return false;
|
||||
if (!this._defaultCondition()) return false;
|
||||
if (this.triggerAllies && !this._allyTriggerSatisfied()) return false;
|
||||
// Guardian charged heals supply their own attack target; no enemy is required (#406).
|
||||
if (this.triggerAllies ? !this._allyTriggerSatisfied() : !this._defaultCondition()) return false;
|
||||
this._beforeAttack = true; // the attack follows this cast in the same check (ai.js updateAlly): attacks pace it
|
||||
try { return this.activate('DEFAULT'); } finally { this._beforeAttack = false; }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user