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>
This commit is contained in:
Erik 2026-07-29 07:33:27 +02:00
parent 6530585309
commit f27ad9ee43
6 changed files with 1149 additions and 149 deletions

View file

@ -10,7 +10,9 @@ namespace AcDream.App.Physics;
/// </summary>
public static class RemoteTeleportHook
{
private const WeenieError TeleportCancelContext = (WeenieError)0x3Cu;
// 0x3C had no name until the 2026-07-29 WeenieError adoption; the cast it
// needed is gone, the value is unchanged.
private const WeenieError TeleportCancelContext = WeenieError.ITeleported;
public static bool Execute(
RemoteTeleportHookActions actions,

View file

@ -157,142 +157,9 @@ public enum MovementType
TurnToHeading = 9,
}
/// <summary>
/// WeenieError-shaped codes returned by CMotionInterp methods. Values are
/// the hex constants used directly in the decompiled C code.
///
/// <para>
/// <b>R3-W1 renumber (closes J16-codes/A10).</b> Prior to this slice, the
/// names were shuffled relative to retail's actual numeric semantics
/// (<c>GeneralMovementFailure</c> was assigned 0x24 and used at the
/// airborne-jump gate, but retail's 0x24 means "not grounded / no contact"
/// and retail's 0x47 is the general-movement-failure code; 0x48 meant
/// "cannot jump while in the air" here, but retail's 0x48 means "jump
/// blocked by the CURRENT MOTION OR POSITION" — a blocklist check
/// (<c>motion_allows_jump</c>), not an airborne check). Renumbered per the
/// definitive, exhaustively-swept table in
/// <c>docs/research/2026-07-02-r3-motioninterp/W0-pins.md</c> §A10 (19
/// return sites + 1 store site over raw 304908-306277 + 300150-300540).
/// These codes are LOCAL-ONLY — never serialized to the wire — so the
/// renumber is safe (verified: no consumer outside
/// <c>MotionInterpreter.cs</c> pattern-matches on the numeric value).
/// </para>
/// </summary>
public enum WeenieError : uint
{
/// <summary>0x00 — success.</summary>
None = 0x00,
/// <summary>
/// 0x08 — no <c>physics_obj</c>. Sites (A10): StopCompletely @305214;
/// DoInterpretedMotion @305579; StopInterpretedMotion @305639;
/// StopMotion @305680; jump @305798; DoMotion @306165.
/// </summary>
NoPhysicsObject = 0x08,
/// <summary>
/// 0x0B — NoMotionInterpreter. R4-V1 addition (M12), per
/// docs/research/2026-07-03-r4-moveto/r4-moveto-decomp.md §12 constants
/// inventory (<c>8, 0xb, 0x36, 0x37, 0x38, 0x3d, 0x47</c>). ACE name;
/// the retail sites that store this code were not individually
/// extracted in the R4 pass (no MoveToManager consumer in this slice —
/// V1 pins the numeric value only).
/// </summary>
NoMotionInterpreter = 0x0B,
/// <summary>
/// 0x24 — not grounded / no contact. Sites (A10):
/// <c>jump_is_allowed</c> @305570 (gravity-active creature without
/// Contact+OnWalkable; also the <c>physics_obj == null</c> case, which
/// falls out to this same code per the A10 note — NOT 8);
/// <c>DoInterpretedMotion</c> @305622-305623 (action-class motion
/// blocked by <c>contact_allows_move</c>).
/// </summary>
NotGrounded = 0x24,
/// <summary>
/// 0x3f — Crouch (0x41000012) rejected while in combat stance. Site:
/// DoMotion @306196.
/// </summary>
CrouchInCombatStance = 0x3f,
/// <summary>
/// 0x40 — Sitting (0x41000013) rejected while in combat stance. Site:
/// DoMotion @306199.
/// </summary>
SitInCombatStance = 0x40,
/// <summary>
/// 0x41 — Sleeping (0x41000014) rejected while in combat stance. Site:
/// DoMotion @306202.
/// </summary>
SleepInCombatStance = 0x41,
/// <summary>
/// 0x42 — <c>motion &amp; 0x2000000</c> (the chat-emote bit) rejected
/// outside NonCombat (0x8000003d). Site: DoMotion @306205.
/// </summary>
ChatEmoteOutsideNonCombat = 0x42,
/// <summary>
/// 0x36 — ActionCancelled. R4-V1 addition (M12). Site:
/// <c>MoveToManager::PerformMovement</c> (r4-moveto-decomp.md §3a
/// @0052a901) — every new moveto cancels the previous one with this
/// code before dispatching; also <c>CPhysicsObj::interrupt_current_movement</c>
/// → <c>MovementManager::CancelMoveTo(0x36)</c> (§9e — the TS-36 cancel
/// entry). Per §7c, <c>MoveToManager::CancelMoveTo</c>'s WeenieError arg
/// is NEVER READ in this build's body — kept for parity/logging only.
/// </summary>
ActionCancelled = 0x36,
/// <summary>
/// 0x37 — ObjectGone. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleUpdateTarget</c> (§6d @307866-307867) — a
/// RETARGET delivery arrives with a non-OK target status (the target
/// object was already being tracked, then went away).
/// </summary>
ObjectGone = 0x37,
/// <summary>
/// 0x38 — NoObject. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleUpdateTarget</c> (§6d @307857-307858) — the
/// FIRST target callback arrives with a non-OK status (the target never
/// resolved in the first place).
/// </summary>
NoObject = 0x38,
/// <summary>
/// 0x45 — action-queue depth cap: an action-class motion (bit
/// 0x10000000) with <c>GetNumActions() &gt;= 6</c> pending. Site:
/// DoMotion @306209.
/// </summary>
ActionDepthExceeded = 0x45,
/// <summary>
/// 0x47 — general movement failure. Sites (A10):
/// <c>jump_is_allowed</c> @305525 (<c>IsFullyConstrained</c>);
/// @305549+305556 (<c>JumpStaminaCost</c> refusal);
/// <c>CMotionInterp::PerformMovement</c> @306227 (dispatch type-1 &gt; 4);
/// <c>MovementManager::PerformMovement</c> @300201 (dispatch type-1 &gt; 8).
/// </summary>
GeneralMovementFailure = 0x47,
/// <summary>
/// 0x48 — jump BLOCKED by the current motion or position (A1: the
/// <c>motion_allows_jump</c> literal-range blocklist — NOT an airborne
/// check; airborne is 0x24). Sites (A10):
/// <c>motion_allows_jump</c> @304930; <c>jump_charge_is_allowed</c>
/// @304948 (Fallen or Crouch..Sleeping); <c>charge_jump</c> @305459
/// (same predicate); STORED (not returned) as the queue node's
/// <c>jump_error_code</c> in <c>DoInterpretedMotion</c> @305605 when
/// <c>disable_jump_during_link</c> is set.
/// </summary>
YouCantJumpFromThisPosition = 0x48,
/// <summary>
/// 0x49 — the weenie's <c>CanJump(jump_extent)</c> virtual refused
/// (e.g. stamina/burden gate). Sites: <c>jump_charge_is_allowed</c>
/// @304941; <c>charge_jump</c> @305454.
/// </summary>
CantJumpLoadedDown = 0x49,
/// <summary>
/// 0x3D — YouChargedTooFar. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleMoveToPosition</c> Phase 2 arrival check
/// (r4-moveto-decomp.md §6b) — the <c>fail_distance</c> progress gate
/// exceeded (<c>CheckProgressMade</c> §5b failing for &gt;1s AND the
/// mover overshot <c>fail_distance</c>). NOTE: numerically out of A10's
/// increasing order (0x3D &lt; 0x3F/0x40/0x41/0x42/0x45) because it was
/// not part of the CMotionInterp jump-family sweep this code sits
/// beside — it belongs to the MoveToManager family instead (§7c, §12).
/// </summary>
YouChargedTooFar = 0x3D,
}
// The WeenieError catalog moved to its own file on 2026-07-29 when it grew
// from the 16-member CMotionInterp/MoveToManager subset to retail's full
// 372-code table: src/AcDream.Core/Physics/WeenieError.cs (same namespace).
// ── Motion state structs ───────────────────────────────────────────────────────

View file

@ -0,0 +1,563 @@
// <auto-adopted from the oracle set — see the summary below. Hand edits are
// fine; keep members ordered by value and keep the conformance test in sync.>
namespace AcDream.Core.Physics;
/// <summary>
/// Retail's single client-side status-code enum, as carried on the wire by
/// <c>WeenieError</c> (0x028A) and <c>WeenieErrorWithString</c> (0x028B), and
/// returned locally by <c>CMotionInterp</c> / <c>MoveToManager</c> methods.
///
/// <para>
/// <b>2026-07-29 full adoption.</b> The catalog was a curated 16-member subset
/// until this slice; it now carries all 372 codes. Oracles, in the order they
/// decided: ACE <c>ACE.Entity.Enum.WeenieError</c> (369 members) and the
/// UtilityBelt client-side catalog <c>StatusMessage</c> (372) — the two agree
/// on every one of the 369 names ACE has, with zero value conflicts, and the
/// catalog is a strict superset. The catalog's three extra codes (0x050B,
/// 0x050C, 0x0518) are confirmed against ACE's separate
/// <c>WeenieErrorWithString</c> enum, which holds them with a <c>_</c>
/// placeholder marking the interpolated name. Retail <c>acclient.h</c> has no
/// counterpart to arbitrate — its <c>charError</c> (26 members) is
/// character-creation only — so the two C# oracles carry these alone.
/// </para>
///
/// <para>
/// Six values additionally keep an acdream-local name alongside the ACE one,
/// because the local name is anchored to a retail decompilation site and the
/// ACE name is not. Both names denote the same value; the local name is
/// declared first so <c>ToString()</c> is unchanged by this adoption.
/// </para>
///
/// <para>
/// This enum is the code catalog only. The human-readable sentences live in
/// <c>AcDream.Core.Chat.WeenieErrorMessages</c>, which is keyed on the raw
/// <c>uint</c> and is unaffected by the members named here; register row
/// AP-15 tracks that table's coverage separately.
/// </para>
///
/// <para>
/// The paragraph that follows is the original R3-W1 note, written when this
/// enum held nothing but the <c>CMotionInterp</c> / <c>MoveToManager</c>
/// family. Its "these codes" means that family, which is still local-only.
/// The 362 codes adopted on 2026-07-29 are wire codes and are not covered by
/// it.
/// </para>
///
/// WeenieError-shaped codes returned by CMotionInterp methods. Values are
/// the hex constants used directly in the decompiled C code.
///
/// <para>
/// <b>R3-W1 renumber (closes J16-codes/A10).</b> Prior to this slice, the
/// names were shuffled relative to retail's actual numeric semantics
/// (<c>GeneralMovementFailure</c> was assigned 0x24 and used at the
/// airborne-jump gate, but retail's 0x24 means "not grounded / no contact"
/// and retail's 0x47 is the general-movement-failure code; 0x48 meant
/// "cannot jump while in the air" here, but retail's 0x48 means "jump
/// blocked by the CURRENT MOTION OR POSITION" — a blocklist check
/// (<c>motion_allows_jump</c>), not an airborne check). Renumbered per the
/// definitive, exhaustively-swept table in
/// <c>docs/research/2026-07-02-r3-motioninterp/W0-pins.md</c> §A10 (19
/// return sites + 1 store site over raw 304908-306277 + 300150-300540).
/// These codes are LOCAL-ONLY — never serialized to the wire — so the
/// renumber is safe (verified: no consumer outside
/// <c>MotionInterpreter.cs</c> pattern-matches on the numeric value).
/// </para>
/// </summary>
public enum WeenieError : uint
{
/// <summary>0x00 — success.</summary>
None = 0x0000,
NoMem = 0x0001,
BadParam = 0x0002,
DivZero = 0x0003,
SegV = 0x0004,
Unimplemented = 0x0005,
UnknownMessageType = 0x0006,
NoAnimationTable = 0x0007,
/// <summary>
/// 0x08 — no <c>physics_obj</c>. Sites (A10): StopCompletely @305214;
/// DoInterpretedMotion @305579; StopInterpretedMotion @305639;
/// StopMotion @305680; jump @305798; DoMotion @306165.
/// </summary>
NoPhysicsObject = 0x0008,
NoBookieObject = 0x0009,
NoWslObject = 0x000A,
/// <summary>
/// 0x0B — NoMotionInterpreter. R4-V1 addition (M12), per
/// docs/research/2026-07-03-r4-moveto/r4-moveto-decomp.md §12 constants
/// inventory (<c>8, 0xb, 0x36, 0x37, 0x38, 0x3d, 0x47</c>). ACE name;
/// the retail sites that store this code were not individually
/// extracted in the R4 pass (no MoveToManager consumer in this slice —
/// V1 pins the numeric value only).
/// </summary>
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,
/// <summary>
/// 0x24 — not grounded / no contact. Sites (A10):
/// <c>jump_is_allowed</c> @305570 (gravity-active creature without
/// Contact+OnWalkable; also the <c>physics_obj == null</c> case, which
/// falls out to this same code per the A10 note — NOT 8);
/// <c>DoInterpretedMotion</c> @305622-305623 (action-class motion
/// blocked by <c>contact_allows_move</c>).
/// </summary>
NotGrounded = 0x0024,
/// <summary>ACE/catalog name for 0x0024; alias of <see cref="NotGrounded"/>.</summary>
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,
/// <summary>
/// 0x36 — ActionCancelled. R4-V1 addition (M12). Site:
/// <c>MoveToManager::PerformMovement</c> (r4-moveto-decomp.md §3a
/// @0052a901) — every new moveto cancels the previous one with this
/// code before dispatching; also <c>CPhysicsObj::interrupt_current_movement</c>
/// → <c>MovementManager::CancelMoveTo(0x36)</c> (§9e — the TS-36 cancel
/// entry). Per §7c, <c>MoveToManager::CancelMoveTo</c>'s WeenieError arg
/// is NEVER READ in this build's body — kept for parity/logging only.
/// </summary>
ActionCancelled = 0x0036,
/// <summary>
/// 0x37 — ObjectGone. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleUpdateTarget</c> (§6d @307866-307867) — a
/// RETARGET delivery arrives with a non-OK target status (the target
/// object was already being tracked, then went away).
/// </summary>
ObjectGone = 0x0037,
/// <summary>
/// 0x38 — NoObject. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleUpdateTarget</c> (§6d @307857-307858) — the
/// FIRST target callback arrives with a non-OK status (the target never
/// resolved in the first place).
/// </summary>
NoObject = 0x0038,
CantGetThere = 0x0039,
Dead = 0x003A,
ILeftTheWorld = 0x003B,
ITeleported = 0x003C,
/// <summary>
/// 0x3D — YouChargedTooFar. R4-V1 addition (M12). Site:
/// <c>MoveToManager::HandleMoveToPosition</c> Phase 2 arrival check
/// (r4-moveto-decomp.md §6b) — the <c>fail_distance</c> progress gate
/// exceeded (<c>CheckProgressMade</c> §5b failing for &gt;1s AND the
/// mover overshot <c>fail_distance</c>). NOTE: numerically out of A10's
/// increasing order (0x3D &lt; 0x3F/0x40/0x41/0x42/0x45) because it was
/// not part of the CMotionInterp jump-family sweep this code sits
/// beside — it belongs to the MoveToManager family instead (§7c, §12).
/// </summary>
YouChargedTooFar = 0x003D,
YouAreTooTiredToDoThat = 0x003E,
/// <summary>
/// 0x3f — Crouch (0x41000012) rejected while in combat stance. Site:
/// DoMotion @306196.
/// </summary>
CrouchInCombatStance = 0x003F,
/// <summary>ACE/catalog name for 0x003F; alias of <see cref="CrouchInCombatStance"/>.</summary>
CantCrouchInCombat = 0x003F,
/// <summary>
/// 0x40 — Sitting (0x41000013) rejected while in combat stance. Site:
/// DoMotion @306199.
/// </summary>
SitInCombatStance = 0x0040,
/// <summary>ACE/catalog name for 0x0040; alias of <see cref="SitInCombatStance"/>.</summary>
CantSitInCombat = 0x0040,
/// <summary>
/// 0x41 — Sleeping (0x41000014) rejected while in combat stance. Site:
/// DoMotion @306202.
/// </summary>
SleepInCombatStance = 0x0041,
/// <summary>ACE/catalog name for 0x0041; alias of <see cref="SleepInCombatStance"/>.</summary>
CantLieDownInCombat = 0x0041,
/// <summary>
/// 0x42 — <c>motion &amp; 0x2000000</c> (the chat-emote bit) rejected
/// outside NonCombat (0x8000003d). Site: DoMotion @306205.
/// </summary>
ChatEmoteOutsideNonCombat = 0x0042,
/// <summary>ACE/catalog name for 0x0042; alias of <see cref="ChatEmoteOutsideNonCombat"/>.</summary>
CantChatEmoteInCombat = 0x0042,
NoMtableData = 0x0043,
CantChatEmoteNotStanding = 0x0044,
/// <summary>
/// 0x45 — action-queue depth cap: an action-class motion (bit
/// 0x10000000) with <c>GetNumActions() &gt;= 6</c> pending. Site:
/// DoMotion @306209.
/// </summary>
ActionDepthExceeded = 0x0045,
/// <summary>ACE/catalog name for 0x0045; alias of <see cref="ActionDepthExceeded"/>.</summary>
TooManyActions = 0x0045,
Hidden = 0x0046,
/// <summary>
/// 0x47 — general movement failure. Sites (A10):
/// <c>jump_is_allowed</c> @305525 (<c>IsFullyConstrained</c>);
/// @305549+305556 (<c>JumpStaminaCost</c> refusal);
/// <c>CMotionInterp::PerformMovement</c> @306227 (dispatch type-1 &gt; 4);
/// <c>MovementManager::PerformMovement</c> @300201 (dispatch type-1 &gt; 8).
/// </summary>
GeneralMovementFailure = 0x0047,
/// <summary>
/// 0x48 — jump BLOCKED by the current motion or position (A1: the
/// <c>motion_allows_jump</c> literal-range blocklist — NOT an airborne
/// check; airborne is 0x24). Sites (A10):
/// <c>motion_allows_jump</c> @304930; <c>jump_charge_is_allowed</c>
/// @304948 (Fallen or Crouch..Sleeping); <c>charge_jump</c> @305459
/// (same predicate); STORED (not returned) as the queue node's
/// <c>jump_error_code</c> in <c>DoInterpretedMotion</c> @305605 when
/// <c>disable_jump_during_link</c> is set.
/// </summary>
YouCantJumpFromThisPosition = 0x0048,
/// <summary>
/// 0x49 — the weenie's <c>CanJump(jump_extent)</c> virtual refused
/// (e.g. stamina/burden gate). Sites: <c>jump_charge_is_allowed</c>
/// @304941; <c>charge_jump</c> @305454.
/// </summary>
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,
}