diff --git a/src/AcDream.App/Rendering/RemoteMotionSink.cs b/src/AcDream.App/Rendering/RemoteMotionSink.cs index 1eb473ad..bdf1efaf 100644 --- a/src/AcDream.App/Rendering/RemoteMotionSink.cs +++ b/src/AcDream.App/Rendering/RemoteMotionSink.cs @@ -61,24 +61,33 @@ internal sealed class RemoteMotionSink : IInterpretedMotionSink return; } - var route = AnimationCommandRouter.Classify(motion); - if (route is AnimationCommandRouteKind.Action - or AnimationCommandRouteKind.Modifier - or AnimationCommandRouteKind.ChatEmote) - { - // Overlay (attack swings, emotes): append over the current - // cyclic tail immediately — the substate cycle is unaffected - // (retail Action branch of GetObjectSequence). The funnel's - // contact gate already filtered airborne cases. - AnimationCommandRouter.RouteFullCommand( - _sequencer, _style, motion, speed <= 0f ? 1f : speed); - return; - } - + // Turn/sidestep FIRST: they are Modifier-class (0x65xxxxxx), so the + // generic overlay classification below would swallow them — that + // exact ordering bug shipped in the first S2b cut and killed + // turn-in-place animation + the ObservedOmega seed (S2 smoke, + // 2026-07-02: 30 [TURN_WIRE] events, zero turn SetCycles). They are + // cycle-axis candidates for the single-cycle pick, not overlays. uint low = motion & 0xFFu; bool isTurn = low is 0x0D or 0x0E && (motion & 0xFF000000u) == 0x65000000u; bool isSidestep = low is 0x0F or 0x10 && (motion & 0xFF000000u) == 0x65000000u; + if (!isTurn && !isSidestep) + { + var route = AnimationCommandRouter.Classify(motion); + if (route is AnimationCommandRouteKind.Action + or AnimationCommandRouteKind.Modifier + or AnimationCommandRouteKind.ChatEmote) + { + // Overlay (attack swings, emotes): append over the current + // cyclic tail immediately — the substate cycle is unaffected + // (retail Action branch of GetObjectSequence). The funnel's + // contact gate already filtered airborne cases. + AnimationCommandRouter.RouteFullCommand( + _sequencer, _style, motion, speed <= 0f ? 1f : speed); + return; + } + } + if (isTurn) { _turn = motion;