using AcDream.Core.Items;
namespace AcDream.Core.Net;
///
/// 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).
///
public static class ObjectTableWiring
{
///
/// Subscribe to the three object-lifecycle events
/// on . Call this BEFORE the render handler subscribes
/// to EntitySpawned so the table is populated before the render path runs.
///
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);
};
}
/// Translate the wire spawn into the table's merge patch.
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);
}