feedback7: merge fb7-gh-sim — PR #348 (take-the-highest chains), PR #293 (REA-Y in the engine), #329 ports (异客 13 tiles, 歌蕾蒂娅 net radius 1, 搅拌机 latest first, 大帝 uncapped), PR #365 (骨刺 forms + PRTS targeting), #298 (instant non-attack skills recast at most once per attack interval, attacks untouched), #364 (先兆者 shell 3×3), #220 (速射手 air first), 余 skips noStack bonds (owner)
- Conflict: docs/PLAYING.md 技能自动释放 bullet — both insertions kept (the 铁钳号 rule from fb7-owner-sim, the #298
pacing sentence).
- Grok review: MERGE AFTER FIXES — the HIGH #298 finding (the cast replaced the due attack) fixed on the branch
(db29acf9: per-skill nextCastAt; golden of #298 alone shrank from 84 scenarios to 2).
- Golden union: 4 matches differ from HEAD though the branch alone left them (coop2-NORMAL-3, coop4-ABYSS-7,
coop2-NORMAL-8-serverrun, solo-HARD-9-boosted): HEAD's side had moved all four (#333's shop RNG …) and on those new
bot paths the merged rules apply — the diffs are in-battle layer gains / damage (卡西米尔 50 → 45, 精准 80 → 76,
叙拉古 176 → 168, kills ±2, solo-HARD-9 LP 397 → 399), no outcome change.
- Broad node --test 5571 (5570 pass, 0 fail, 1 skipped); lint 0 errors; typecheck.
This commit is contained in:
commit
52f56319ac
41 files changed
+2065
-648
No files matched your search
@@ -235,6 +235,41 @@ export class SpineActor {
|
||||
else if (this.mode === 'stun' && this.has(this.roles.stun?.loop)) this._play(this.roles.stun.loop, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-pose on the clip set in force right after an immediate form switch (render/units.js STEALTH_FORMS: 假想敌:骨刺's
|
||||
* stealth bit; PR #365): a running attack goes on in the new set's attack clip at the same point relative to its
|
||||
* strike frame (a pending wind-up still strikes at windUntil), a stun / the resting state restarts on the new set's
|
||||
* clip without a crossfade, and the skeleton is posed at once — also while a freeze holds it (`frozen`).
|
||||
*/
|
||||
syncFormPose() {
|
||||
if (this.dead) return;
|
||||
if (this.mode === 'attack') {
|
||||
const track = this.spine.state.tracks[0];
|
||||
const clip = this._attackClip();
|
||||
if (!track || !clip) return;
|
||||
const dur = this.dur(clip.loop);
|
||||
const oldHit = this._hitTime(this.current, this.dur(this.current));
|
||||
const hit = this._hitTime(clip.loop, dur);
|
||||
const start = clampN(track.trackTime + hit - oldHit, 0, dur);
|
||||
const lead = this.wound && this.windUntil != null
|
||||
? Math.max(0, this.windUntil - this.clock) : 0;
|
||||
const ts = lead > 0 ? Math.max(0, hit - start) / lead : track.timeScale;
|
||||
const tailTs = lead > 0 ? this.windTs : ts;
|
||||
this._play(clip.loop, track.loop, { start, timeScale: ts, mix: 0 });
|
||||
this.attackUntil = this.clock + lead +
|
||||
Math.max(0, dur - (lead > 0 ? hit : start)) / tailTs;
|
||||
} else if (this.mode === 'stun') {
|
||||
const name = this.has(this.roles.stun?.loop) ? this.roles.stun.loop : this._baseName();
|
||||
this._play(name, true, { mix: 0 });
|
||||
} else if (this.mode === 'base') {
|
||||
this._play(this._baseName(), true, { mix: 0 });
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
// Apply the new attachments even when normal updates are frozen.
|
||||
this.spine.update(0);
|
||||
}
|
||||
|
||||
/** Play a form's transition clip once; attacks and the resting state wait for it (mode 'change'). */
|
||||
_change(clip) {
|
||||
if (this.mode !== 'change') this.stunWanted = this.mode === 'stun';
|
||||
|
||||
Reference in new issue
Block a user