feedback1e WP: review fixes — 信仰搅拌机 S3 ignores 攻击距离, bounded range mini-map

- 信仰搅拌机 S3 退休前布道 attacks / counters on 3-13 exactly: SPT-Y's 攻击距离+1
  does not reach it (PRTS 技能3 备注 "此技能的攻击范围不受“攻击距离”属性影响";
  PRTS 修正 of the module text "(部分技能不受此影响)"). New SkillSpec flag
  targeting.noRangeExtend, read by Battle._refreshRange; S1 / S2 keep the +1.
- The detail card's 攻击范围 draws a grid larger than its box (远牙 S3's
  21-tile line) with smaller cells in the box's own space (rangeGridStyle,
  RANGE_FIT 6 columns × 7 rows), so the live stats beside it stay readable.
- 荒芜拉普兰德 S1's whole-field grid only selects targets (no rangeId, no 攻击范围
  text): targeting.showOwnRange keeps her 3-1 on the card.
- 烛煌 S3's bonus on burning enemies is dealt before the attack's damage
  (备注 "于攻击造成伤害前判定元素爆发并造成元素伤害"), main and splash.
- liveRangeGrid is the grid itself when nothing extends it (no copy per refresh).
- Audit test: 攻击距离加长 / 缩短 (深巡 S2, 山 S2) and every module of the loadout;
  real BattleSpec for 信仰搅拌机 SPT-Y.
This commit is contained in:
sganggs committed 2026-10-03 05:46:04 +08:00
1 parent 8b0e672bb8
commit 5963a40d2d
11 files changed
+276 -58

No files matched your search

+6 -3
View File
@@ -32,7 +32,8 @@
// instant (onStart + optional one-shot attack override for the next attack), charges (= instant with charges),
// passive (always on from deployment, no SP), toggle (stays on until death once activated).
// SkillSpec fields (all optional): kind, duration, ammo, spCost, initSp, charges, spType, trigger,
// mods, flags, targeting {maxTargets, rangeGrid, priority, allInRange, rangeExtend},
// mods, flags, targeting {maxTargets, rangeGrid, priority, allInRange, rangeExtend, noRangeExtend (the range ignores
// the unit's 攻击距离), showOwnRange (rangeGrid only selects targets: the detail card keeps the unit's own range)},
// attack {dmgType, atkScale, splashRadius, splashScale, hits, projectile, maxTargets, dmgMul, onHit, heal…},
// heal (bool: heal-type skill for the trigger rule), onStart(ctx), onEnd(ctx), onHit(ctx), onAttack(ctx), onTick(ctx).
// ctx passed to spec callbacks: { battle, unit, skill, bb, target?, dealt?, targets?, dt?, reason? }; onAttack's ctx
@@ -43,6 +44,8 @@ import { absoluteRangeKeys, canTargetEnemy } from './targeting.js';
import { AUTO_OP_COOLDOWN, COLS, ROWS } from './constants.js';
const TICK_RULES = new Set(['SP_FULL', 'SEARCH', 'CUSTOM_RANGE', 'SKILL_RANGE', 'GDGLOW_SKILL_2']);
/** True when a SkillSpec `targeting` changes the unit's range while the skill runs (Battle._refreshRange). */
const changesRange = (tg) => !!(tg && (tg.rangeGrid || tg.rangeExtend || tg.noRangeExtend));
/** Enemies that satisfy a content trigger range (any targetable enemy, flyers included). */
const TRIGGER_PROFILE = Object.freeze({ canHitFly: true });
/** Every tile of the stage (GDGLOW_SKILL_2: the whole field). */
@@ -194,12 +197,12 @@ export class SkillRuntime {
if (s.mods || s.flags) {
this.battle.addBuff(this.unit, { key: this._buffKey, mods: s.mods || null, flags: s.flags || null, tags: ['skill'] });
}
if (s.targeting && (s.targeting.rangeGrid || s.targeting.rangeExtend)) this.battle._refreshRange(this.unit);
if (changesRange(s.targeting)) this.battle._refreshRange(this.unit);
}
_removeMods() {
this.battle.removeBuff(this.unit, this._buffKey);
if (this.spec.targeting && (this.spec.targeting.rangeGrid || this.spec.targeting.rangeExtend)) this.battle._refreshRange(this.unit);
if (changesRange(this.spec.targeting)) this.battle._refreshRange(this.unit);
}
/** Add SP (fires the `spGain` hook). Ignored while a duration/ammo/toggle skill runs (its bar shows the skill). */