fix(D.2b): correct EquipMask to canonical retail INVENTORY_LOC + numeric-pin test
The old enum invented two phantom bits (HandArmor=0x2000, FootArmor=0x10000) and used non-retail names (Necklace, LeftBracelet, RightBracelet, LeftRing, RightRing, AetheriaRed/Yellow/Blue), shifting every slot above 0x1000 out of alignment with retail INVENTORY_LOC (acclient.h:3193) and ACE EquipMask. Replace the enum body with verbatim retail values. Add EquipMaskTests to numeric-pin every member so future renumbering breaks at compile/test time. Existing consumers (ClientObjectTable, InventoryController, GameEventWiringTests, ClientObjectTableTests) only reference EquipMask.MeleeWeapon and EquipMask.None -- both present at their correct retail values -- so no call sites needed updating. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bd4b49f810
commit
1810c71f5c
2 changed files with 90 additions and 36 deletions
54
tests/AcDream.Core.Tests/Items/EquipMaskTests.cs
Normal file
54
tests/AcDream.Core.Tests/Items/EquipMaskTests.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using AcDream.Core.Items;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.Core.Tests.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Pins every EquipMask member to the verbatim retail INVENTORY_LOC value
|
||||
/// (docs/research/named-retail/acclient.h:3193). The wire delivers these exact bits
|
||||
/// (ACE EquipMask == retail INVENTORY_LOC); any drift desyncs the paperdoll element-id→mask
|
||||
/// map and the GetAndWieldItem wire. This test is the anti-regression lock.
|
||||
/// </summary>
|
||||
public sealed class EquipMaskTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(0x00000000u, EquipMask.None)]
|
||||
[InlineData(0x00000001u, EquipMask.HeadWear)]
|
||||
[InlineData(0x00000002u, EquipMask.ChestWear)]
|
||||
[InlineData(0x00000004u, EquipMask.AbdomenWear)]
|
||||
[InlineData(0x00000008u, EquipMask.UpperArmWear)]
|
||||
[InlineData(0x00000010u, EquipMask.LowerArmWear)]
|
||||
[InlineData(0x00000020u, EquipMask.HandWear)]
|
||||
[InlineData(0x00000040u, EquipMask.UpperLegWear)]
|
||||
[InlineData(0x00000080u, EquipMask.LowerLegWear)]
|
||||
[InlineData(0x00000100u, EquipMask.FootWear)]
|
||||
[InlineData(0x00000200u, EquipMask.ChestArmor)]
|
||||
[InlineData(0x00000400u, EquipMask.AbdomenArmor)]
|
||||
[InlineData(0x00000800u, EquipMask.UpperArmArmor)]
|
||||
[InlineData(0x00001000u, EquipMask.LowerArmArmor)]
|
||||
[InlineData(0x00002000u, EquipMask.UpperLegArmor)]
|
||||
[InlineData(0x00004000u, EquipMask.LowerLegArmor)]
|
||||
[InlineData(0x00008000u, EquipMask.NeckWear)]
|
||||
[InlineData(0x00010000u, EquipMask.WristWearLeft)]
|
||||
[InlineData(0x00020000u, EquipMask.WristWearRight)]
|
||||
[InlineData(0x00040000u, EquipMask.FingerWearLeft)]
|
||||
[InlineData(0x00080000u, EquipMask.FingerWearRight)]
|
||||
[InlineData(0x00100000u, EquipMask.MeleeWeapon)]
|
||||
[InlineData(0x00200000u, EquipMask.Shield)]
|
||||
[InlineData(0x00400000u, EquipMask.MissileWeapon)]
|
||||
[InlineData(0x00800000u, EquipMask.MissileAmmo)]
|
||||
[InlineData(0x01000000u, EquipMask.Held)]
|
||||
[InlineData(0x02000000u, EquipMask.TwoHanded)]
|
||||
[InlineData(0x04000000u, EquipMask.TrinketOne)]
|
||||
[InlineData(0x08000000u, EquipMask.Cloak)]
|
||||
[InlineData(0x10000000u, EquipMask.SigilOne)]
|
||||
[InlineData(0x20000000u, EquipMask.SigilTwo)]
|
||||
[InlineData(0x40000000u, EquipMask.SigilThree)]
|
||||
public void Member_has_canonical_retail_value(uint expected, EquipMask member)
|
||||
=> Assert.Equal(expected, (uint)member);
|
||||
|
||||
[Fact]
|
||||
public void Weapon_ready_slot_composite_is_0x3500000() // acclient.h:3235 WEAPON_READY_SLOT_LOC
|
||||
=> Assert.Equal(0x3500000u,
|
||||
(uint)(EquipMask.MeleeWeapon | EquipMask.MissileWeapon | EquipMask.Held | EquipMask.TwoHanded));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue