namespace AcDream.Core.Physics; /// /// Reconstructs the 32-bit retail MotionCommand value from a 16-bit wire /// value broadcast in InterpretedMotionState.Commands[]. /// /// /// The server serializes MotionCommands as u16 (ACE /// InterpretedMotionState.cs:139), truncating the class byte (Style / /// SubState / Modifier / Action / ChatEmote / UI / Toggle / Mappable / /// Command — see r03 §3.1). The client must re-attach the class byte before /// routing the command into the motion table, because the same low 16 bits /// can map to different classes (e.g. 0x0003 is Ready as a SubState, /// but there's no other 0x0003). /// /// /// /// As of the L.1b command-catalog slice, this static facade delegates to a /// single shared instance — the /// runtime-default catalog built from the DatReaderWriter /// MotionCommand enum (matches ACE + the local DATs). All ~10 /// existing runtime callers (AnimationCommandRouter, /// CombatAnimationPlanner, 8x GameWindow) are unaffected by /// this refactor — the public signature and behavior for the ACE/runtime /// path is unchanged. A second catalog, /// , is available for /// conformance/reference work against the Sept 2013 EoR decomp's own /// (differently-numbered) command table; callers that need that catalog /// must construct it directly via the /// seam — this facade only ever returns ACE/runtime values. /// /// /// /// Cited references: /// /// /// references/ACE/Source/ACE.Server/Network/Motion/InterpretedMotionState.cs::Write /// L138-L144 — writer emits u16 for every command field. /// /// /// references/ACE/Source/ACE.Entity/Enum/CommandMasks.cs — the /// class bit assignments: 0x80=Style, 0x40=SubState, 0x20=Modifier, /// 0x10=Action, 0x13 and 0x12=ChatEmote (with Mappable set), etc. /// /// /// docs/research/deepdives/r03-motion-animation.md §3 — complete /// command catalogue. /// /// /// docs/research/2026-06-26-ace-vs-2013-motion-command-gap.md — /// the ACE-vs-2013 catalog divergence that motivated the dual-catalog /// seam (the shift begins at SnowAngelState, 0x43000115 -> /// 0x43000118, not at AllegianceHometownRecall). /// /// /// /// public static class MotionCommandResolver { private static readonly AceModernCommandCatalog s_aceModern = new(); /// /// Given a 16-bit wire value, return the full 32-bit MotionCommand /// (class byte restored) per the ACE/runtime catalog. Returns 0 if no /// matching value exists. /// public static uint ReconstructFullCommand(ushort wireCommand) { return s_aceModern.ReconstructFullCommand(wireCommand); } }