acdream/tests/AcDream.Core.Tests/Properties/WeenieErrorConformanceTests.cs
Erik f27ad9ee43 feat(core): adopt retail's full WeenieError code table
acdream carried 16 status codes, curated by hand out of the CMotionInterp
and MoveToManager decompilation passes. The other 362 were unnamed, which
made every one of them a cast site waiting to happen. This slice takes the
whole table: 372 values under 378 names.

The oracle set is finally complete. All six vendored reference repos were
empty when the 2026-07-29 enum campaign ran, which is why it deferred this
decision; they are re-cloned now, so ACE's WeenieError could be read
directly instead of leaning on the UtilityBelt catalog alone.

The two agree without a single conflict. ACE has 369 members, no internal
value collisions. The catalog has 372, shares all 369 ACE names, and
disagrees on none of their values. Its three extras -- IsNowOpenFellowship
(0x050B), IsNowClosedFellowship (0x050C), LockedFellowshipCannotRecruit
(0x0518) -- each turn up in ACE's separate WeenieErrorWithString enum with
a `_` marking the interpolated name, so the catalog is just the less-split
view of the same client enum. All three are adopted on agreement between
two oracles, not on one.

Retail cannot arbitrate any of this. acclient.h has no counterpart enum;
its charError (26) is character-creation only. Recorded, not guessed
around.

Six values keep two names. acdream's NotGrounded, CrouchInCombatStance,
SitInCombatStance, SleepInCombatStance, ChatEmoteOutsideNonCombat and
ActionDepthExceeded are each anchored to a retail decompilation site, where
ACE's names for those values are server-side coinages. Rather than pick,
both are declared, acdream's first so ToString() is untouched.

Behaviour is unchanged, and there is no way for it not to be: nothing in
the tree branches on a WeenieError member. MotionInterpreter's switch is on
a motion type and merely returns one of these; WeenieErrorText.For switches
on a raw uint; the chat translation table WeenieErrorMessages is keyed on
uint throughout, so naming a code does not make it render. The one site
that moved is RemoteTeleportHook, where the (WeenieError)0x3Cu cast becomes
the now-named WeenieError.ITeleported at the same value.

Register row AP-15 is narrowed rather than retired. Its code-catalog caveat
is superseded -- an unnamed code is no longer a way for it to bite -- but
the sentences are still ACE's doc comments rather than retail's
string_table.bin, and that part stands.

The enum moved out of MotionInterpreter.cs into its own file at the same
namespace. At 372 members it does not belong inside a physics class file.

Core tests 3903 passed / 2 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 07:33:27 +02:00

497 lines
21 KiB
C#

// <auto-generated-source>
// Golden conformance table for WeenieError. Regenerated by the 2026-07-29
// full-adoption slice; see docs/research/2026-07-29-enum-verification-campaign.md.
// </auto-generated-source>
using System;
using System.Linq;
using AcDream.Core.Physics;
using Xunit;
namespace AcDream.Core.Tests.Properties;
/// <summary>
/// Pins every member of <see cref="WeenieError"/> to its wire value. The table is
/// the verbatim cross-check of ACE <c>ACE.Entity.Enum.WeenieError</c> (369 members)
/// against the UtilityBelt client-side catalog <c>StatusMessage</c> (372) — the two
/// agree on every shared name with zero value conflicts, and the catalog is a strict
/// superset whose three extra codes are confirmed against ACE's separate
/// <c>WeenieErrorWithString</c>. Retail <c>acclient.h</c> has no counterpart enum, so
/// it cannot arbitrate; that is recorded rather than guessed around.
///
/// <para>Six values carry two names: the acdream-local name anchored to a retail
/// decompilation site, plus the ACE/catalog name. Both are pinned.</para>
/// </summary>
public sealed class WeenieErrorConformanceTests
{
private static readonly (string Name, uint Value)[] Golden =
[
("None", 0x0000),
("NoMem", 0x0001),
("BadParam", 0x0002),
("DivZero", 0x0003),
("SegV", 0x0004),
("Unimplemented", 0x0005),
("UnknownMessageType", 0x0006),
("NoAnimationTable", 0x0007),
("NoPhysicsObject", 0x0008),
("NoBookieObject", 0x0009),
("NoWslObject", 0x000A),
("NoMotionInterpreter", 0x000B),
("UnhandledSwitch", 0x000C),
("DefaultConstructorCalled", 0x000D),
("InvalidCombatManeuver", 0x000E),
("BadCast", 0x000F),
("MissingQuality", 0x0010),
("MissingDatabaseObject", 0x0012),
("NoCallbackSet", 0x0013),
("CorruptQuality", 0x0014),
("BadContext", 0x0015),
("NoEphseqManager", 0x0016),
("BadMovementEvent", 0x0017),
("CannotCreateNewObject", 0x0018),
("NoControllerObject", 0x0019),
("CannotSendEvent", 0x001A),
("PhysicsCantTransition", 0x001B),
("PhysicsMaxDistanceExceeded", 0x001C),
("YoureTooBusy", 0x001D),
("CannotSendMessage", 0x001F),
("IllegalInventoryTransaction", 0x0020),
("ExternalWeenieObject", 0x0021),
("InternalWeenieObject", 0x0022),
("MotionFailure", 0x0023),
("NotGrounded", 0x0024),
("YouCantJumpWhileInTheAir", 0x0024),
("InqCylSphereFailure", 0x0025),
("ThatIsNotAValidCommand", 0x0026),
("CarryingItem", 0x0027),
("Frozen", 0x0028),
("Stuck", 0x0029),
("YouAreTooEncumbered", 0x002A),
("BadContain", 0x002C),
("BadParent", 0x002D),
("BadDrop", 0x002E),
("BadRelease", 0x002F),
("MsgBadMsg", 0x0030),
("MsgUnpackFailed", 0x0031),
("MsgNoMsg", 0x0032),
("MsgUnderflow", 0x0033),
("MsgOverflow", 0x0034),
("MsgCallbackFailed", 0x0035),
("ActionCancelled", 0x0036),
("ObjectGone", 0x0037),
("NoObject", 0x0038),
("CantGetThere", 0x0039),
("Dead", 0x003A),
("ILeftTheWorld", 0x003B),
("ITeleported", 0x003C),
("YouChargedTooFar", 0x003D),
("YouAreTooTiredToDoThat", 0x003E),
("CrouchInCombatStance", 0x003F),
("CantCrouchInCombat", 0x003F),
("SitInCombatStance", 0x0040),
("CantSitInCombat", 0x0040),
("SleepInCombatStance", 0x0041),
("CantLieDownInCombat", 0x0041),
("ChatEmoteOutsideNonCombat", 0x0042),
("CantChatEmoteInCombat", 0x0042),
("NoMtableData", 0x0043),
("CantChatEmoteNotStanding", 0x0044),
("ActionDepthExceeded", 0x0045),
("TooManyActions", 0x0045),
("Hidden", 0x0046),
("GeneralMovementFailure", 0x0047),
("YouCantJumpFromThisPosition", 0x0048),
("CantJumpLoadedDown", 0x0049),
("YouKilledYourself", 0x004A),
("MsgResponseFailure", 0x004B),
("ObjectIsStatic", 0x004C),
("InvalidPkStatus", 0x004D),
("InvalidXpAmount", 0x03E9),
("InvalidPpCalculation", 0x03EA),
("InvalidCpCalculation", 0x03EB),
("UnhandledStatAnswer", 0x03EC),
("HeartAttack", 0x03ED),
("TheContainerIsClosed", 0x03EE),
("InvalidInventoryLocation", 0x03F0),
("ChangeCombatModeFailure", 0x03F1),
("FullInventoryLocation", 0x03F2),
("ConflictingInventoryLocation", 0x03F3),
("ItemNotPending", 0x03F4),
("BeWieldedFailure", 0x03F5),
("BeDroppedFailure", 0x03F6),
("YouAreTooFatiguedToAttack", 0x03F7),
("YouAreOutOfAmmunition", 0x03F8),
("YourAttackMisfired", 0x03F9),
("YouveAttemptedAnImpossibleSpellPath", 0x03FA),
("MagicIncompleteAnimList", 0x03FB),
("MagicInvalidSpellType", 0x03FC),
("MagicInqPositionAndVelocityFailure", 0x03FD),
("YouDontKnowThatSpell", 0x03FE),
("IncorrectTargetType", 0x03FF),
("YouDontHaveAllTheComponents", 0x0400),
("YouDontHaveEnoughManaToCast", 0x0401),
("YourSpellFizzled", 0x0402),
("YourSpellTargetIsMissing", 0x0403),
("YourProjectileSpellMislaunched", 0x0404),
("MagicSpellbookAddSpellFailure", 0x0405),
("MagicTargetOutOfRange", 0x0406),
("YourSpellCannotBeCastOutside", 0x0407),
("YourSpellCannotBeCastInside", 0x0408),
("MagicGeneralFailure", 0x0409),
("YouAreUnpreparedToCastASpell", 0x040A),
("YouveAlreadySwornAllegiance", 0x040B),
("CantSwearAllegianceInsufficientXp", 0x040C),
("AllegianceIgnoringRequests", 0x040D),
("AllegianceSquelched", 0x040E),
("AllegianceMaxDistanceExceeded", 0x040F),
("AllegianceIllegalLevel", 0x0410),
("AllegianceBadCreation", 0x0411),
("AllegiancePatronBusy", 0x0412),
("YouAreNotInAllegiance", 0x0414),
("AllegianceRemoveHierarchyFailure", 0x0415),
("FellowshipIgnoringRequests", 0x0417),
("FellowshipSquelched", 0x0418),
("FellowshipMaxDistanceExceeded", 0x0419),
("FellowshipMember", 0x041A),
("FellowshipIllegalLevel", 0x041B),
("FellowshipRecruitBusy", 0x041C),
("YouMustBeLeaderOfFellowship", 0x041D),
("YourFellowshipIsFull", 0x041E),
("FellowshipNameIsNotPermitted", 0x041F),
("LevelTooLow", 0x0420),
("LevelTooHigh", 0x0421),
("ThatChannelDoesntExist", 0x0422),
("YouCantUseThatChannel", 0x0423),
("YouAreAlreadyOnThatChannel", 0x0424),
("YouAreNotOnThatChannel", 0x0425),
("AttunedItem", 0x0426),
("YouCannotMergeDifferentStacks", 0x0427),
("YouCannotMergeEnchantedItems", 0x0428),
("YouMustControlAtLeastOneStack", 0x0429),
("CurrentlyAttacking", 0x042A),
("MissileAttackNotOk", 0x042B),
("TargetNotAcquired", 0x042C),
("ImpossibleShot", 0x042D),
("BadWeaponSkill", 0x042E),
("UnwieldFailure", 0x042F),
("LaunchFailure", 0x0430),
("ReloadFailure", 0x0431),
("UnableToMakeCraftReq", 0x0432),
("CraftAnimationFailed", 0x0433),
("YouCantCraftWithThatNumberOfItems", 0x0434),
("CraftGeneralErrorUiMsg", 0x0435),
("CraftGeneralErrorNoUiMsg", 0x0436),
("YouDoNotPassCraftingRequirements", 0x0437),
("YouDoNotHaveAllTheNecessaryItems", 0x0438),
("NotAllTheItemsAreAvailable", 0x0439),
("YouMustBeInPeaceModeToTrade", 0x043A),
("YouAreNotTrainedInThatTradeSkill", 0x043B),
("YourHandsMustBeFree", 0x043C),
("YouCannotLinkToThatPortal", 0x043D),
("YouHaveSolvedThisQuestTooRecently", 0x043E),
("YouHaveSolvedThisQuestTooManyTimes", 0x043F),
("QuestUnknown", 0x0440),
("QuestTableCorrupt", 0x0441),
("QuestBad", 0x0442),
("QuestDuplicate", 0x0443),
("QuestUnsolved", 0x0444),
("ItemRequiresQuestToBePickedUp", 0x0445),
("QuestSolvedTooLongAgo", 0x0446),
("TradeIgnoringRequests", 0x044C),
("TradeSquelched", 0x044D),
("TradeMaxDistanceExceeded", 0x044E),
("TradeAlreadyTrading", 0x044F),
("TradeBusy", 0x0450),
("TradeClosed", 0x0451),
("TradeExpired", 0x0452),
("TradeItemBeingTraded", 0x0453),
("TradeNonEmptyContainer", 0x0454),
("TradeNonCombatMode", 0x0455),
("TradeIncomplete", 0x0456),
("TradeStampMismatch", 0x0457),
("TradeUnopened", 0x0458),
("TradeEmpty", 0x0459),
("TradeAlreadyAccepted", 0x045A),
("TradeOutOfSync", 0x045B),
("PKsMayNotUsePortal", 0x045C),
("NonPKsMayNotUsePortal", 0x045D),
("HouseAbandoned", 0x045E),
("HouseEvicted", 0x045F),
("HouseAlreadyOwned", 0x0460),
("HouseBuyFailed", 0x0461),
("HouseRentFailed", 0x0462),
("Hooked", 0x0463),
("MagicInvalidPosition", 0x0465),
("YouMustHaveDarkMajestyToUsePortal", 0x0466),
("InvalidAmmoType", 0x0467),
("SkillTooLow", 0x0468),
("YouHaveUsedAllTheHooks", 0x0469),
("TradeAiDoesntWant", 0x046A),
("HookHouseNotOwned", 0x046B),
("YouMustCompleteQuestToUsePortal", 0x0474),
("HouseNoAllegiance", 0x047E),
("YouMustOwnHouseToUseCommand", 0x047F),
("YourMonarchDoesNotOwnAMansionOrVilla", 0x0480),
("YourMonarchsHouseIsNotAMansionOrVilla", 0x0481),
("YourMonarchHasClosedTheMansion", 0x0482),
("YouMustBeMonarchToPurchaseDwelling", 0x048A),
("AllegianceTimeout", 0x048D),
("YourOfferOfAllegianceWasIgnored", 0x048E),
("ConfirmationInProgress", 0x048F),
("YouMustBeAMonarchToUseCommand", 0x0490),
("YouMustSpecifyCharacterToBoot", 0x0491),
("YouCantBootYourself", 0x0492),
("ThatCharacterDoesNotExist", 0x0493),
("ThatPersonIsNotInYourAllegiance", 0x0494),
("CantBreakFromPatronNotInAllegiance", 0x0495),
("YourAllegianceHasBeenDissolved", 0x0496),
("YourPatronsAllegianceHasBeenBroken", 0x0497),
("YouHaveMovedTooFar", 0x0498),
("TeleToInvalidPosition", 0x0499),
("MustHaveDarkMajestyToUse", 0x049A),
("YouFailToLinkWithLifestone", 0x049B),
("YouWanderedTooFarToLinkWithLifestone", 0x049C),
("YouSuccessfullyLinkWithLifestone", 0x049D),
("YouMustLinkToLifestoneToRecall", 0x049E),
("YouFailToRecallToLifestone", 0x049F),
("YouFailToLinkWithPortal", 0x04A0),
("YouSuccessfullyLinkWithPortal", 0x04A1),
("YouFailToRecallToPortal", 0x04A2),
("YouMustLinkToPortalToRecall", 0x04A3),
("YouFailToSummonPortal", 0x04A4),
("YouMustLinkToPortalToSummonIt", 0x04A5),
("YouFailToTeleport", 0x04A6),
("YouHaveBeenTeleportedTooRecently", 0x04A7),
("YouMustBeAnAdvocateToUsePortal", 0x04A8),
("PortalAisNotAllowed", 0x04A9),
("PlayersMayNotUsePortal", 0x04AA),
("YouAreNotPowerfulEnoughToUsePortal", 0x04AB),
("YouAreTooPowerfulToUsePortal", 0x04AC),
("YouCannotRecallPortal", 0x04AD),
("YouCannotSummonPortal", 0x04AE),
("LockAlreadyUnlocked", 0x04AF),
("YouCannotLockOrUnlockThat", 0x04B0),
("YouCannotLockWhatIsOpen", 0x04B1),
("KeyDoesntFitThisLock", 0x04B2),
("LockUsedTooRecently", 0x04B3),
("YouArentTrainedInLockpicking", 0x04B4),
("AllegianceInfoEmptyName", 0x04B5),
("AllegianceInfoSelf", 0x04B6),
("AllegianceInfoTooRecent", 0x04B7),
("AbuseNoSuchCharacter", 0x04B8),
("AbuseReportedSelf", 0x04B9),
("AbuseComplaintHandled", 0x04BA),
("YouDoNotOwnThatSalvageTool", 0x04BD),
("YouDoNotOwnThatItem", 0x04BE),
("MaterialCannotBeCreated", 0x04C1),
("ItemsAttemptingToSalvageIsInvalid", 0x04C2),
("YouCannotSalvageItemsInTrading", 0x04C3),
("YouMustBeHouseGuestToUsePortal", 0x04C4),
("YourAllegianceRankIsTooLowToUseMagic", 0x04C5),
("YourArcaneLoreIsTooLowToUseMagic", 0x04C7),
("ItemDoesntHaveEnoughMana", 0x04C8),
("YouHaveBeenInPKBattleTooRecently", 0x04CC),
("TradeAiRefuseEmote", 0x04CD),
("YouFailToAlterSkill", 0x04D0),
("FellowshipDeclined", 0x04DB),
("FellowshipTimeout", 0x04DC),
("YouHaveFailedToAlterAttributes", 0x04DD),
("CannotTransferAttributesWhileWieldingItem", 0x04E0),
("YouHaveSucceededTransferringAttributes", 0x04E1),
("HookIsDuplicated", 0x04E2),
("ItemIsWrongTypeForHook", 0x04E3),
("HousingChestIsDuplicated", 0x04E4),
("HookWillBeDeleted", 0x04E5),
("HousingChestWillBeDeleted", 0x04E6),
("CannotSwearAllegianceWhileOwningMansion", 0x04E7),
("YouCantDoThatWhileInTheAir", 0x04EB),
("CannotChangePKStatusWhileRecovering", 0x04EC),
("AdvocatesCannotChangePKStatus", 0x04ED),
("LevelTooLowToChangePKStatusWithObject", 0x04EE),
("LevelTooHighToChangePKStatusWithObject", 0x04EF),
("YouFeelAHarshDissonance", 0x04F0),
("YouArePKAgain", 0x04F1),
("YouAreTemporarilyNoLongerPK", 0x04F2),
("PKLiteMayNotUsePortal", 0x04F3),
("YouArentTrainedInHealing", 0x04FC),
("YouDontOwnThatHealingKit", 0x04FD),
("YouCantHealThat", 0x04FE),
("YouArentReadyToHeal", 0x0500),
("YouCanOnlyHealPlayers", 0x0501),
("LifestoneMagicProtectsYou", 0x0502),
("PortalEnergyProtectsYou", 0x0503),
("YouAreNonPKAgain", 0x0504),
("YoureTooCloseToYourSanctuary", 0x0505),
("CantDoThatTradeInProgress", 0x0506),
("OnlyNonPKsMayEnterPKLite", 0x0507),
("YouAreNowPKLite", 0x0508),
("IsNowOpenFellowship", 0x050B),
("IsNowClosedFellowship", 0x050C),
("YouDoNotBelongToAFellowship", 0x050F),
("UsingMaxHooksSilent", 0x0511),
("YouAreNowUsingMaxHooks", 0x0512),
("YouAreNoLongerUsingMaxHooks", 0x0513),
("YouAreNotPermittedToUseThatHook", 0x0516),
("LockedFellowshipCannotRecruit", 0x0518),
("LockedFellowshipCannotRecruitYou", 0x0519),
("ActivationNotAllowedNotOwner", 0x051A),
("TurbineChatIsEnabled", 0x051D),
("YouCannotAddPeopleToHearList", 0x0520),
("YouAreNowDeafTo_Screams", 0x0523),
("YouCanHearAllPlayersOnceAgain", 0x0524),
("YouChickenOut", 0x0526),
("YouCanPossiblySucceed", 0x0527),
("FellowshipIsLocked", 0x0528),
("TradeComplete", 0x0529),
("NotASalvageTool", 0x052A),
("CharacterNotAvailable", 0x052B),
("YouMustWaitToPurchaseHouse", 0x0532),
("YouDoNotHaveAuthorityInAllegiance", 0x0535),
("YouHaveMaxAccountsBanned", 0x0540),
("YouHaveMaxAllegianceOfficers", 0x0545),
("YourAllegianceOfficersHaveBeenCleared", 0x0546),
("YouCannotJoinChannelsWhileGagged", 0x0548),
("YouAreNoLongerAllegianceOfficer", 0x054A),
("YourAllegianceDoesNotHaveHometown", 0x054C),
("HookItemNotUsable_CannotOpen", 0x054E),
("HookItemNotUsable_CanOpen", 0x054F),
("MissileOutOfRange", 0x0550),
("MustPurchaseThroneOfDestinyToUseFunction", 0x0552),
("MustPurchaseThroneOfDestinyToUseItem", 0x0553),
("MustPurchaseThroneOfDestinyToUsePortal", 0x0554),
("MustPurchaseThroneOfDestinyToAccessQuest", 0x0555),
("YouFailedToCompleteAugmentation", 0x0556),
("AugmentationUsedTooManyTimes", 0x0557),
("AugmentationTypeUsedTooManyTimes", 0x0558),
("AugmentationNotEnoughExperience", 0x0559),
("ExitTrainingAcademyToUseCommand", 0x055D),
("OnlyPKsMayUseCommand", 0x055F),
("OnlyPKLiteMayUseCommand", 0x0560),
("MaxFriendsExceeded", 0x0561),
("ThatCharacterNotOnYourFriendsList", 0x0563),
("OnlyHouseOwnerCanUseCommand", 0x0564),
("InvalidAllegianceNameCantBeEmpty", 0x0565),
("InvalidAllegianceNameTooLong", 0x0566),
("InvalidAllegianceNameBadCharacters", 0x0567),
("InvalidAllegianceNameInappropriate", 0x0568),
("InvalidAllegianceNameAlreadyInUse", 0x0569),
("AllegianceNameCleared", 0x056B),
("InvalidAllegianceNameSameName", 0x056C),
("InvalidOfficerLevel", 0x056F),
("AllegianceOfficerTitleIsNotAppropriate", 0x0570),
("AllegianceNameIsTooLong", 0x0571),
("AllegianceOfficerTitlesCleared", 0x0572),
("AllegianceTitleHasIllegalChars", 0x0573),
("YouHaveNotPreApprovedVassals", 0x0579),
("YouHaveClearedPreApprovedVassal", 0x057C),
("CharIsAlreadyGagged", 0x057D),
("CharIsNotCurrentlyGagged", 0x057E),
("YourAllegianceChatPrivilegesRestored", 0x0581),
("TooManyUniqueItems", 0x0584),
("HeritageRequiresSpecificArmor", 0x0585),
("ArmorRequiresSpecificHeritage", 0x0586),
("OlthoiCannotInteractWithThat", 0x0587),
("OlthoiCannotUseLifestones", 0x0588),
("OlthoiVendorLooksInHorror", 0x0589),
("OlthoiCannotJoinFellowship", 0x058B),
("OlthoiCannotJoinAllegiance", 0x058C),
("YouCannotUseThatItem", 0x058D),
("ThisPersonWillNotInteractWithYou", 0x058E),
("OnlyOlthoiMayUsePortal", 0x058F),
("OlthoiMayNotUsePortal", 0x0590),
("YouMayNotUsePortalWithVitae", 0x0591),
("YouMustBeTwoWeeksOldToUsePortal", 0x0592),
("OlthoiCanOnlyRecallToLifestone", 0x0593),
("ContractError", 0x0594),
];
/// <summary>The 16 members that predate the 2026-07-29 full adoption. Their
/// values are load-bearing for the CMotionInterp / MoveToManager port and must
/// not move when the catalog grows.</summary>
private static readonly (string Name, uint Value)[] PreAdoption =
[
("None", 0x0000),
("NoPhysicsObject", 0x0008),
("NoMotionInterpreter", 0x000B),
("NotGrounded", 0x0024),
("ActionCancelled", 0x0036),
("ObjectGone", 0x0037),
("NoObject", 0x0038),
("YouChargedTooFar", 0x003D),
("CrouchInCombatStance", 0x003F),
("SitInCombatStance", 0x0040),
("SleepInCombatStance", 0x0041),
("ChatEmoteOutsideNonCombat", 0x0042),
("ActionDepthExceeded", 0x0045),
("GeneralMovementFailure", 0x0047),
("YouCantJumpFromThisPosition", 0x0048),
("CantJumpLoadedDown", 0x0049),
];
[Fact]
public void EveryGoldenMemberHasItsExactValue()
{
foreach (var (name, value) in Golden)
{
Assert.True(Enum.IsDefined(typeof(WeenieError), name),
$"WeenieError.{name} is missing");
Assert.Equal(value, (uint)Enum.Parse<WeenieError>(name));
}
}
[Fact]
public void DeclaresNothingOutsideTheGoldenTable()
{
var expected = Golden.Select(g => g.Name).OrderBy(n => n, StringComparer.Ordinal);
var actual = Enum.GetNames<WeenieError>().OrderBy(n => n, StringComparer.Ordinal);
Assert.Equal(expected, actual);
}
[Fact]
public void CatalogHoldsTheFullRetailCodeSpace()
{
Assert.Equal(378, Enum.GetNames<WeenieError>().Length);
Assert.Equal(372, Enum.GetValues<WeenieError>().Cast<uint>().Distinct().Count());
}
[Fact]
public void PreAdoptionMembersKeepTheirValues()
{
foreach (var (name, value) in PreAdoption)
Assert.Equal(value, (uint)Enum.Parse<WeenieError>(name));
}
/// <summary>The six values that carry both an acdream-local and an ACE name.
/// Nothing else may be aliased — a duplicate value elsewhere means the adoption
/// picked up a name collision.</summary>
[Fact]
public void OnlyTheSixDecompAnchoredValuesAreAliased()
{
(uint Value, string Local, string Ace)[] expected =
[
(0x0024, "NotGrounded", "YouCantJumpWhileInTheAir"),
(0x003F, "CrouchInCombatStance", "CantCrouchInCombat"),
(0x0040, "SitInCombatStance", "CantSitInCombat"),
(0x0041, "SleepInCombatStance", "CantLieDownInCombat"),
(0x0042, "ChatEmoteOutsideNonCombat", "CantChatEmoteInCombat"),
(0x0045, "ActionDepthExceeded", "TooManyActions"),
];
var actual = Enum.GetValues<WeenieError>()
.Cast<uint>()
.Distinct()
.Where(v => Golden.Count(g => g.Value == v) > 1)
.OrderBy(v => v)
.ToArray();
Assert.Equal(expected.Select(e => e.Value).OrderBy(v => v), actual);
foreach (var (value, local, ace) in expected)
{
Assert.Equal(value, (uint)Enum.Parse<WeenieError>(local));
Assert.Equal(value, (uint)Enum.Parse<WeenieError>(ace));
// Enum.GetName is documented to return an arbitrary one of the
// names sharing a value, so only membership is pinned here.
Assert.Contains(Enum.GetName(typeof(WeenieError), value), new[] { local, ace });
}
}
}