feat(D.5.1): parse item IconOverlay/IconUnderlay from CreateObject -> faithful icon overlay layer
The CreateObject optional-tail walker previously stopped at UseRadius (~20 fields before IconOverlay). This left ItemInstance.IconOverlayId/IconUnderlayId always 0, so IconComposer's underlay/overlay layers were never drawn on toolbar icons. Exact field order verified against ACE WorldObject_Networking.cs:87-219 (the serializer is the authority; acdream connects to a local ACE server): UseRadius → TargetType(u32) → UiEffects(u32) → CombatUse(sbyte) → Structure(u16) → MaxStructure(u16) → StackSize(u16) → MaxStackSize(u16) → Container(u32) → Wielder(u32) → ValidLocations(u32) → CurrentlyWieldedLocation(u32) → Priority(u32) → RadarBlipColor(u8) → RadarBehavior(u8) → PScript(u16) → Workmanship(f32) → Burden(u16) → Spell(u16) → HouseOwner(u32) → HouseRestrictions(variable RestrictionDB) → HookItemTypes(u32) → Monarch(u32) → HookType(u16) → IconOverlay(PackedDwordKnownType) ← CAPTURE → IconUnderlay from weenieFlags2 bit 0x01 ← CAPTURE RestrictionDB handled correctly: Version(u32) + OpenStatus(u32) + MonarchId(u32) + count(u16) + numBuckets(u16) + count×8 bytes entries. Length-aware skip, not a fixed constant. weenieFlags2 is now CAPTURED (not skipped) when IncludesSecondHeader (objDescFlags bit 0x04000000) is set, so the IconUnderlay bit can be tested. The entire extended walk is inside try/catch: truncated packets degrade to IconOverlayId=0 / IconUnderlayId=0 (no overlay drawn), never corrupting. Threading: CreateObject.Parsed → WorldSession.EntitySpawn → GameWindow OnLiveEntitySpawned → Items.EnrichItem — both ids thread through all three seams. EnrichItem extended with optional iconOverlayId + iconUnderlayId params (defaulted 0, backward-compatible). No change to IconComposer or ToolbarController (they already consume the ids). Tests: 4 new CreateObject tests (IconOverlay only, overlay+underlay, no-overlay regression, intermediate-fields cursor arithmetic). Full suite: 0 failures, 2636 passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a7cad5566b
commit
8a42066192
5 changed files with 421 additions and 39 deletions
|
|
@ -82,7 +82,13 @@ public sealed class WorldSession : IDisposable
|
|||
uint? Useability = null,
|
||||
float? UseRadius = null,
|
||||
// D.5.1: icon datId from CreateObject WeenieHeader, for toolbar rendering.
|
||||
uint IconId = 0);
|
||||
uint IconId = 0,
|
||||
// D.5.1 (2026-06-17): icon overlay/underlay dat ids from the extended
|
||||
// WeenieHeader optional tail. Gated by WeenieHeaderFlag.IconOverlay
|
||||
// (0x40000000) and WeenieHeaderFlag2.IconUnderlay (0x01) respectively.
|
||||
// Zero when the server did not send the field (common for most entities).
|
||||
uint IconOverlayId = 0,
|
||||
uint IconUnderlayId = 0);
|
||||
|
||||
/// <summary>Fires when the session finishes parsing a CreateObject.</summary>
|
||||
public event Action<EntitySpawn>? EntitySpawned;
|
||||
|
|
@ -719,7 +725,9 @@ public sealed class WorldSession : IDisposable
|
|||
parsed.Value.Elasticity,
|
||||
parsed.Value.Useability,
|
||||
parsed.Value.UseRadius,
|
||||
parsed.Value.IconId));
|
||||
parsed.Value.IconId,
|
||||
parsed.Value.IconOverlayId,
|
||||
parsed.Value.IconUnderlayId));
|
||||
}
|
||||
}
|
||||
else if (op == DeleteObject.Opcode)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue