CreateObject ingestion moves to Core.Net; GameWindow drops the EnrichItem call + inline 0x02CE handler. Fixes the Coldeve blank-icon root cause: items with no PD stub are now created, not dropped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
2.3 KiB
C#
57 lines
2.3 KiB
C#
using AcDream.Core.Items;
|
|
|
|
namespace AcDream.Core.Net;
|
|
|
|
/// <summary>
|
|
/// Wires WorldSession GameMessage-level object events into the client object
|
|
/// table: CreateObject (0xF745) = canonical merge-upsert, DeleteObject (0xF747)
|
|
/// = evict, PublicUpdatePropertyInt (0x02CE) UiEffects = live icon re-composite.
|
|
/// Keeps object ingestion in Core.Net (pure data, no GL) and off GameWindow.
|
|
/// Retail: ACCObjectMaint::CreateObject / DeleteObject (the weenie_object_table side).
|
|
/// </summary>
|
|
public static class ObjectTableWiring
|
|
{
|
|
/// <summary>
|
|
/// Subscribe <paramref name="table"/> to the three object-lifecycle events
|
|
/// on <paramref name="session"/>. Call this BEFORE the render handler subscribes
|
|
/// to EntitySpawned so the table is populated before the render path runs.
|
|
/// </summary>
|
|
public static void Wire(WorldSession session, ClientObjectTable table)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(session);
|
|
ArgumentNullException.ThrowIfNull(table);
|
|
|
|
session.EntitySpawned += s => table.Ingest(ToWeenieData(s));
|
|
session.EntityDeleted += d => table.Remove(d.Guid);
|
|
session.ObjectIntPropertyUpdated += u =>
|
|
{
|
|
if (u.Property == ClientObjectTable.UiEffectsPropertyId)
|
|
table.UpdateIntProperty(u.Guid, u.Property, u.Value);
|
|
};
|
|
}
|
|
|
|
/// <summary>Translate the wire spawn into the table's merge patch.</summary>
|
|
public static WeenieData ToWeenieData(WorldSession.EntitySpawn s) => new(
|
|
Guid: s.Guid,
|
|
Name: s.Name,
|
|
Type: s.ItemType is { } it ? (ItemType)it : (ItemType?)null,
|
|
WeenieClassId: s.WeenieClassId,
|
|
IconId: s.IconId,
|
|
IconOverlayId: s.IconOverlayId,
|
|
IconUnderlayId: s.IconUnderlayId,
|
|
Effects: s.UiEffects,
|
|
Value: s.Value,
|
|
StackSize: s.StackSize,
|
|
StackSizeMax: s.StackSizeMax,
|
|
Burden: s.Burden,
|
|
ContainerId: s.ContainerId,
|
|
WielderId: s.WielderId,
|
|
ValidLocations: s.ValidLocations,
|
|
CurrentWieldedLocation: s.CurrentWieldedLocation,
|
|
Priority: s.Priority,
|
|
ItemsCapacity: s.ItemsCapacity,
|
|
ContainersCapacity: s.ContainersCapacity,
|
|
Structure: s.Structure,
|
|
MaxStructure: s.MaxStructure,
|
|
Workmanship: s.Workmanship);
|
|
}
|