feat(core): adopt the retail members the equipment and physics enums were missing

With the two wrong enums corrected, the remaining wire-adjacent families diff
cleanly against the retail header - same values everywhere they overlap, just
fewer members on our side. This adopts the gaps.

EquipMask gains retail's eleven INVENTORY_LOC composite slot groups (acclient.h:
3193). The 32 primitive slots were already exact and stay pinned by EquipMaskTests;
what was missing were the groups the wire and the UI actually reason in - Armor,
Jewelry, ReadySlot, Weapon, WeaponReadySlot, the wrist/finger/sigil pairs, and
All. These are transcribed as literals, not derived, for the reason the previous
commit documents at length.

That transcription immediately earned itself. A type remark on EquipMask claimed
retail's CLOTHING_LOC composite "also sets bit 31, 0x80000000, which is not a
named INVENTORY_LOC primitive". It does not. CLOTHING_LOC is 0x080001FF: the nine
wear slots plus bit 27, which is the perfectly well-named Cloak slot. No
INVENTORY_LOC member touches bit 31 at all - ALL_LOC stops at bit 30. The remark
is corrected and a test now asserts the actual decomposition.

TransientStateFlags gains WaterContact (0x8) and CheckEthereal (0x100), the two
retail bits acdream's transition never declared. Neither is produced or consumed
yet; they are named so those slots cannot be quietly reused for an acdream-local
flag and then collide.

PhysicsStateFlags gains ReservedUnused1 (0x2) and ReservedUnused2 (0x2000), which
retail declares as UNUSED1_PS/UNNUSED2_PS. Same reasoning: reserved is a fact
worth recording.

AttackHeight gains Undef = 0. The three real heights are 1-based and were already
right; retail reserves 0 and the wire sends it, so it is now named instead of
arriving as an undefined cast. The numeric values are unchanged, so this renames
nothing at runtime.

Also checked and found already correct, so left alone: ObjectInfoState (matches
ObjectInfoEnum exactly, None being DEFAULT_OI), AttackType (every primitive plus
both composites - Unarmed 0x19 and MultiStrike 0x79E0 - land on retail's
literals), RadarBlipShape, RadarBehavior, MovementType, HoldKey, ParticleType, and
PhysicsDescriptionFlag. AttackType is worth calling out because the campaign's
extraction tooling reported it as a conflict; the tool reads one line per member
and had truncated a multi-line composite. The enum was fine.

RetailEnumConformanceTests grows tables for each of the above, each citing its
acclient.h line.

Core tests 3,785 -> 3,836. Full suite 9,701 passed / 5 skipped, no failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-29 01:27:57 +02:00
parent f3e95a3ebd
commit 8ccaf72ae7
4 changed files with 173 additions and 2 deletions

View file

@ -79,8 +79,10 @@ public enum ItemType : uint
/// (docs/research/named-retail/acclient.h:3193; identical to ACE's EquipMask).
/// The wire (ValidLocations / CurrentWieldedLocation / WieldObject EquipLoc) delivers
/// these exact bits. Pinned by EquipMaskTests — do NOT renumber.
/// (The header's <c>CLOTHING_LOC</c> composite also sets bit 31, 0x80000000, which is
/// not a named INVENTORY_LOC primitive and has no member here; <c>ALL_LOC</c> tops out at bit 30.)
/// (A remark here used to claim the header's <c>CLOTHING_LOC</c> composite sets an
/// unnamed bit 31. It does not: <c>CLOTHING_LOC</c> is 0x080001FF, the nine wear slots
/// plus bit 27, which is the named <see cref="EquipMask.Cloak"/> slot. <c>ALL_LOC</c>
/// tops out at bit 30, so no INVENTORY_LOC member uses bit 31 at all.)
/// </summary>
[Flags]
public enum EquipMask : uint
@ -117,6 +119,23 @@ public enum EquipMask : uint
SigilOne = 0x10000000,
SigilTwo = 0x20000000,
SigilThree = 0x40000000,
// Retail's composite slot groups, transcribed verbatim from the same header
// block rather than recomputed from the primitives above. Clothing in
// particular is not the union of the wear slots — it also carries the cloak
// slot (bit 27).
Clothing = 0x080001FF, // CLOTHING_LOC: the nine wear slots | Cloak
Armor = 0x00007E00, // ARMOR_LOC
Jewelry = 0x7C0F8000, // JEWELRY_LOC
WristWear = 0x00030000, // WRIST_WEAR_LOC
FingerWear = 0x000C0000, // FINGER_WEAR_LOC
Sigil = 0x70000000, // SIGIL_LOC
ReadySlot = 0x03F00000, // READY_SLOT_LOC
Weapon = 0x02500000, // WEAPON_LOC
WeaponReadySlot = 0x03500000, // WEAPON_READY_SLOT_LOC
All = 0x7FFFFFFF, // ALL_LOC
/// <summary>Retail gives CAN_GO_IN_READY_SLOT_LOC the same value as ALL_LOC.</summary>
CanGoInReadySlot = 0x7FFFFFFF,
}
/// <summary>