feat(R2-Q4): adapter cutover — SetCycle/PlayAction rehosted on PerformMovement; Fix B / fast-path / stop-anim fallback / G17 gate DELETED
AnimationSequencer becomes a thin shim over the verbatim R2 stack:
SetCycle dispatches the style change (Branch 1) then the motion (Branch
2/3/4) through MotionTableManager.PerformMovement; PlayAction is the
same dispatch (actions rebuild via Branch 3; modifiers are Branch 4
physics-only combine_motion — the AP-73 turn-blend mechanism now runs
for real). CurrentStyle/CurrentMotion/CurrentSpeedMod are read-only
mirrors of MotionState (post-adjust_motion, signed mod). Lazy
initialize_state on first drive (retail lazy-create analog) keeps
undriven sequencers do-nothing.
DELETED legacy inventions (net -648 lines): the adapter fast-path
(replaced by Branch-2 fast re-speed: change_cycle_speed +
subtract/combine_motion), Fix B + IsLocomotionCycleLowByte (replaced by
remove_redundant_links on the pending queue — the retail mechanism the
2026-05-03 cdb trace pointed at), the stop-anim low-byte fallback
(replaced by get_link's reversed-key double-hop — retail's actual
backward-walk settle plays the windup link REVERSED), GetLink/BuildNode/
EnqueueMotionData + the G17 HasVelocity/HasOmega gate (add_motion sets
unconditionally), MultiplyCyclicFramerate + the G13 composite,
PlayAction's insert-before-tail machinery, SCFAST/SCFULL diagnostics.
KEPT at the adapter (register rows): the boundary adjust_motion remap +
locomotion velocity/omega synthesis (AP-75, retire R3-W6/R6), K-fix18
skip-link as post-dispatch RemoveAllLinkAnimations (AP-74, retire
R3-W4 when LeaveGround fires it).
GameWindow queue-drain wiring (the §4 G6 seam): each drained AnimDone
hook → manager.AnimationDone(true) (retail AnimDoneHook::Execute
0x00526c20 → Hook_AnimDone 0x0050fda0 chain), UseTime once per tick
(0x00517d57/0x00517d67); IMotionDoneSink bound to an
ACDREAM_DUMP_MOTION recorder (AD-36 — R3 rebinds to
MotionInterpreter.MotionDone).
Conformance: the 11-scenario pre-cutover trace suite (a6235a36) replays
green with six EXPECTED-DIFF annotations (double-hop walk-run routing,
reversed settle links, Branch-4 physics-only modifiers, Branch-1
style-change links, post-adjust mirrors) — everything unannotated is
byte-identical. Legacy suites repaired by a dedicated agent (fixtures
gain the retail-mandatory StyleDefaults + class-bit-tagged ids;
reflection state-poking replaced with real dispatch; zero category-D
regressions — the suspected cursor bug was a fixture class-bit gap),
plus two vacuously-passing tests fixed. Register: stale IA-4 deleted
(R1-P1 ported the negative-factor swap).
Full suite green: 3,458 passed (374+425+713+1946).
Closes H6, H7, H8, H9, H10-adapter, H16-wiring (r2-port-plan.md §3 Q4).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
cd0289bea2
commit
3b9d9bb6be
6 changed files with 562 additions and 646 deletions
|
|
@ -9875,10 +9875,33 @@ public sealed class GameWindow : IDisposable
|
|||
}
|
||||
seqFrames = ae.Sequencer.Advance(dt);
|
||||
|
||||
// R2-Q4: bind the MotionDone diagnostic recorder once per
|
||||
// sequencer (the IMotionDoneSink seam's interim consumer —
|
||||
// R3 binds MotionInterpreter.MotionDone here instead).
|
||||
if (ae.Sequencer.MotionDoneTarget is null)
|
||||
{
|
||||
uint mdGuid = serverGuid;
|
||||
ae.Sequencer.MotionDoneTarget = (m, ok) =>
|
||||
{
|
||||
if (System.Environment.GetEnvironmentVariable("ACDREAM_DUMP_MOTION") == "1")
|
||||
System.Console.WriteLine(
|
||||
$"[MOTIONDONE] guid={mdGuid:X8} motion=0x{m:X8} success={ok}");
|
||||
};
|
||||
}
|
||||
|
||||
// Phase E.1: drain animation hooks (footstep sounds, attack
|
||||
// damage frames, particle spawns, part swaps, etc.) and fan
|
||||
// them out to registered subsystems via the hook router.
|
||||
// Mirrors ACE's PhysicsObj.add_anim_hook dispatch path.
|
||||
//
|
||||
// R2-Q4 queue-drain wiring (r2-port-plan.md §4, the G6 seam;
|
||||
// per-tick PLACEMENT provisional until R6 installs retail's
|
||||
// UpdateObjectInternal order): each drained AnimDone hook
|
||||
// advances the entity's MotionTableManager countdown
|
||||
// (retail AnimDoneHook::Execute 0x00526c20 → Hook_AnimDone
|
||||
// 0x0050fda0 → CPartArray::AnimationDone(1)), and UseTime
|
||||
// runs once per tick to sweep zero-tick queue entries
|
||||
// (retail call sites 0x00517d57/0x00517d67).
|
||||
var hooks = ae.Sequencer.ConsumePendingHooks();
|
||||
if (hooks.Count > 0)
|
||||
{
|
||||
|
|
@ -9888,8 +9911,11 @@ public sealed class GameWindow : IDisposable
|
|||
var hook = hooks[hi];
|
||||
if (hook is null) continue;
|
||||
_hookRouter.OnHook(ae.Entity.Id, worldPos, hook);
|
||||
if (hook is DatReaderWriter.Types.AnimationDoneHook)
|
||||
ae.Sequencer.Manager.AnimationDone(success: true);
|
||||
}
|
||||
}
|
||||
ae.Sequencer.Manager.UseTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue