using AcDream.Core.Physics; using Xunit; namespace AcDream.Core.Tests.Physics; /// /// R3-W1 — pins 's numeric values against the /// definitive retail table in /// docs/research/2026-07-02-r3-motioninterp/W0-pins.md §A10 (an exhaustive /// sweep of every return <code> site across raw 304908-306277 + /// 300150-300540: 19 return sites + 1 store site, all attributed). These /// codes are local-only (never on the wire), so the renumber from the /// pre-R3 shuffled names is a safe rename — this test is the single /// source of truth that a future edit can't silently un-pin. /// public sealed class WeenieErrorCodeTableTests { [Fact] public void None_Is0x00() => Assert.Equal(0x00u, (uint)WeenieError.None); [Fact] public void NoPhysicsObject_Is0x08() => Assert.Equal(0x08u, (uint)WeenieError.NoPhysicsObject); /// /// 0x0B — NoMotionInterpreter. R4-V1 addition (M12), per /// docs/research/2026-07-03-r4-moveto/r4-moveto-decomp.md §12 constants /// inventory row (8, 0xb, 0x36, 0x37, 0x38, 0x3d, 0x47). /// [Fact] public void NoMotionInterpreter_Is0x0B() => Assert.Equal(0x0Bu, (uint)WeenieError.NoMotionInterpreter); [Fact] public void NotGrounded_Is0x24() => Assert.Equal(0x24u, (uint)WeenieError.NotGrounded); [Fact] public void CrouchInCombatStance_Is0x3f() => Assert.Equal(0x3fu, (uint)WeenieError.CrouchInCombatStance); [Fact] public void SitInCombatStance_Is0x40() => Assert.Equal(0x40u, (uint)WeenieError.SitInCombatStance); [Fact] public void SleepInCombatStance_Is0x41() => Assert.Equal(0x41u, (uint)WeenieError.SleepInCombatStance); [Fact] public void ChatEmoteOutsideNonCombat_Is0x42() => Assert.Equal(0x42u, (uint)WeenieError.ChatEmoteOutsideNonCombat); /// /// 0x36 — ActionCancelled. R4-V1 addition (M12). Site: /// MoveToManager::PerformMovement (§3a @0052a901) — every new /// moveto cancels the previous one with this code before dispatching; /// also CPhysicsObj::interrupt_current_movement's /// MovementManager::CancelMoveTo(0x36) call (§9e). Per §7c, the /// arg is NEVER READ inside MoveToManager::CancelMoveTo's body in /// this build — kept for parity/logging, not behavior. /// [Fact] public void ActionCancelled_Is0x36() => Assert.Equal(0x36u, (uint)WeenieError.ActionCancelled); /// /// 0x37 — ObjectGone. R4-V1 addition (M12). Site: /// MoveToManager::HandleUpdateTarget (§6d @307866-307867) — /// retarget delivery with a non-OK target status. /// [Fact] public void ObjectGone_Is0x37() => Assert.Equal(0x37u, (uint)WeenieError.ObjectGone); /// /// 0x38 — NoObject. R4-V1 addition (M12). Site: /// MoveToManager::HandleUpdateTarget (§6d @307857-307858) — the /// FIRST target callback arrives with a non-OK status (target never /// resolved). /// [Fact] public void NoObject_Is0x38() => Assert.Equal(0x38u, (uint)WeenieError.NoObject); [Fact] public void ActionDepthExceeded_Is0x45() => Assert.Equal(0x45u, (uint)WeenieError.ActionDepthExceeded); [Fact] public void GeneralMovementFailure_Is0x47() => Assert.Equal(0x47u, (uint)WeenieError.GeneralMovementFailure); [Fact] public void YouCantJumpFromThisPosition_Is0x48() => Assert.Equal(0x48u, (uint)WeenieError.YouCantJumpFromThisPosition); [Fact] public void CantJumpLoadedDown_Is0x49() => Assert.Equal(0x49u, (uint)WeenieError.CantJumpLoadedDown); /// /// 0x3D — YouChargedTooFar. R4-V1 addition (M12). Site: /// MoveToManager::HandleMoveToPosition Phase 2 arrival check — /// fail_distance exceeded (r4-moveto-decomp.md §6b). /// [Fact] public void YouChargedTooFar_Is0x3D() => Assert.Equal(0x3Du, (uint)WeenieError.YouChargedTooFar); /// /// Every code in the A10 table in one pass — guards against a /// future partial edit desyncing an individual test above from the /// enum declaration. /// [Theory] [InlineData(WeenieError.None, 0x00u)] [InlineData(WeenieError.NoPhysicsObject, 0x08u)] [InlineData(WeenieError.NoMotionInterpreter, 0x0Bu)] [InlineData(WeenieError.NotGrounded, 0x24u)] [InlineData(WeenieError.ActionCancelled, 0x36u)] [InlineData(WeenieError.ObjectGone, 0x37u)] [InlineData(WeenieError.NoObject, 0x38u)] [InlineData(WeenieError.CrouchInCombatStance, 0x3fu)] [InlineData(WeenieError.SitInCombatStance, 0x40u)] [InlineData(WeenieError.SleepInCombatStance, 0x41u)] [InlineData(WeenieError.ChatEmoteOutsideNonCombat, 0x42u)] [InlineData(WeenieError.ActionDepthExceeded, 0x45u)] [InlineData(WeenieError.GeneralMovementFailure, 0x47u)] [InlineData(WeenieError.YouCantJumpFromThisPosition, 0x48u)] [InlineData(WeenieError.CantJumpLoadedDown, 0x49u)] [InlineData(WeenieError.YouChargedTooFar, 0x3Du)] public void A10Table_EveryCode_MatchesRetailNumericValue(WeenieError code, uint expected) => Assert.Equal(expected, (uint)code); }