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
|
|
@ -144,13 +144,22 @@ public sealed class ItemRepository
|
|||
/// Raises ItemPropertiesUpdated whenever the item is found (matching the
|
||||
/// UpdateProperties convention — it fires on found regardless of whether a field
|
||||
/// actually changed) so bound widgets (the toolbar) re-render.
|
||||
/// <para>
|
||||
/// D.5.1 (2026-06-17): also accepts <paramref name="iconOverlayId"/> and
|
||||
/// <paramref name="iconUnderlayId"/> from the extended WeenieHeader tail. Both
|
||||
/// default to 0 (not sent by server). IconComposer.GetIcon already composites
|
||||
/// underlay/base/overlay in the correct retail layer order and early-returns on 0.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool EnrichItem(uint objectId, uint iconId, string name, ItemType type)
|
||||
public bool EnrichItem(uint objectId, uint iconId, string name, ItemType type,
|
||||
uint iconOverlayId = 0, uint iconUnderlayId = 0)
|
||||
{
|
||||
if (!_items.TryGetValue(objectId, out var item)) return false;
|
||||
if (iconId != 0) item.IconId = iconId;
|
||||
if (!string.IsNullOrEmpty(name)) item.Name = name;
|
||||
if (type != default) item.Type = type;
|
||||
if (iconOverlayId != 0) item.IconOverlayId = iconOverlayId;
|
||||
if (iconUnderlayId != 0) item.IconUnderlayId = iconUnderlayId;
|
||||
ItemPropertiesUpdated?.Invoke(item);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue