feat(D.5.4): PlayerDescription = membership manifest; drop WeenieClassId=ContainerType misuse

The old seeding block set WeenieClassId = inv.ContainerType (a 0/1/2
container-kind discriminator, not a weenie class id) and used MoveItem
for the equipped block. Replace both loops with RecordMembership calls:
inventory guids get a bare stub (WeenieClassId stays 0); equipped guids
get the equip slot set directly. Weenie data arrives via CreateObject /
ObjectTableWiring, not PlayerDescription.

New test PlayerDescription_SeedsMembership_NotWeenieClassIdMisuse proves:
(a) inv guid is registered, (b) WeenieClassId==0 not ContainerType, and
(c) equipped guid CurrentlyEquippedLocation is set to MeleeWeapon.
No existing tests pinned the old behavior; all 15 GameEventWiringTests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-18 16:38:54 +02:00
parent 82f5968316
commit cbbfe4cd49
2 changed files with 59 additions and 32 deletions

View file

@ -400,40 +400,15 @@ public static class GameEventWiring
Console.WriteLine($"vitals: PD-ench spell={ench.SpellId} layer={ench.Layer} bucket={ench.Bucket} key={ench.StatModKey} val={ench.StatModValue}");
}
// Issue #13 — register inventory entries with ClientObjectTable so
// panels (inventory, paperdoll, hotbars) light up after login.
// Equipped entries share the same ObjectId as inventory entries
// (an equipped item is also in inventory) — register both, but
// the equipped record carries the slot mask which we surface via
// MoveItem so paperdoll can render.
// D.5.4: PlayerDescription is a membership MANIFEST, not the data
// source. Record existence (+ equip slot); CreateObject fills the
// actual weenie data via ObjectTableWiring. (Previously this seeded
// stubs with WeenieClassId = ContainerType, a misuse — ContainerType
// is a 0/1/2 container-kind discriminator, not a weenie class id.)
foreach (var inv in p.Value.Inventory)
{
if (items.Get(inv.Guid) is null)
{
items.AddOrUpdate(new ClientObject
{
ObjectId = inv.Guid,
WeenieClassId = inv.ContainerType,
});
}
}
items.RecordMembership(inv.Guid);
foreach (var eq in p.Value.Equipped)
{
if (items.Get(eq.Guid) is null)
{
items.AddOrUpdate(new ClientObject
{
ObjectId = eq.Guid,
WeenieClassId = 0,
});
}
// Reflect the equip slot — paperdoll uses CurrentlyEquippedLocation.
items.MoveItem(
itemId: eq.Guid,
newContainerId: 0,
newSlot: -1,
newEquipLocation: (EquipMask)eq.EquipLocation);
}
items.RecordMembership(eq.Guid, equip: (EquipMask)eq.EquipLocation);
// D.5.1 Task 4: forward shortcut bar entries to the caller so the
// toolbar can read them without holding a parser reference.