feedback7 R22-RENDER: an attack seen late plays its whole clip from the wind-up when the rhythm leaves room for it — 重犯's iron ball lifts before the slam (#246 by @TsangAsuna, accepted by the owner); golden: unchanged

SpineActor.attack() starts an attack that was not wound up (no look-ahead: a batch that arrived late) on its strike
frame — right for a quick rhythm, but for a slow clip-per-attack enemy the wind-up was cut out: 重犯 (Attack_grey
2.333 s, strike at 1.0 s, attacks every 3 s) showed the slam without the ball ever rising, and only 1.33 s of the clip.
The owner's decision of 2026-10-07 on #246: re-implement on the current spine.js so that, when the attack interval
leaves room for the whole clip, it plays once completely from the start. A clip-per-attack actor (enemies) with
interval ≥ the clip now plays it from 0 at its own speed for the whole clip, the strike landing a little late; a
quicker rhythm keeps the strike-frame start, and operators' looping attacks are unchanged (the PR's condition had it
the other way round: it changed the looping attacks and left out the clip-per-attack enemies it was written for).

Tests: test/render/feedback2-enemy-attack-clip.test.js (+1: 重犯 plays the whole clip from its wind-up, a quicker rhythm
and an operator start on the strike frame) 5/5; render eyemask, unitview, texas skill clip, skill idle 51/51.
This commit is contained in:
sganggs committed 2026-10-08 19:20:55 +08:00
1 parent 1e78648ad4
commit 6326dd4d0b
2 files changed
+28 -3

No files matched your search

+7 -3
View File
@@ -367,9 +367,13 @@ export class SpineActor {
this.windUntil = null;
this.wound = false;
if (!wasAttacking) {
// not wound up (no look-ahead, e.g. a batch that arrived late): the sim already resolved the hit, so show
// the strike frame now
this._play(clip.loop, !single, { timeScale: ts, start: hit, mix: 0.06 });
// not wound up (no look-ahead, e.g. a batch that arrived late): the sim already resolved the hit, so show the
// strike frame now — unless a clip-per-attack actor's rhythm leaves room for the whole clip (interval ≥ clip):
// then the clip plays complete from its wind-up at its own speed, the strike a little late (重犯's iron ball
// lifts before the slam; #246 by @TsangAsuna, accepted by the owner on 2026-10-07)
const whole = per && this.interval >= loopDur;
if (whole) this.attackUntil = this.clock + loopDur / ts;
this._play(clip.loop, !single, { timeScale: ts, start: whole ? 0 : hit, mix: 0.06 });
} else if (single) {
const e = this.spine.state.tracks[0];
if (e) e.timeScale = ts;