feat(D.5.4): ObjectTableWiring (CreateObject=upsert, Delete=evict, 0x02CE) off GameWindow

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>
This commit is contained in:
Erik 2026-06-18 16:24:58 +02:00
parent 2e3f209707
commit 82f5968316
3 changed files with 158 additions and 15 deletions

View file

@ -2357,6 +2357,10 @@ public sealed class GameWindow : IDisposable
private void WireLiveSessionEvents(AcDream.Core.Net.WorldSession session)
{
_liveSession = session;
// D.5.4: ingest CreateObject into the object table (upsert) and wire Delete +
// UiEffects live update. Wire BEFORE EntitySpawned += OnLiveEntitySpawned so
// the table is populated before the render handler runs.
AcDream.Core.Net.ObjectTableWiring.Wire(session, Objects);
_liveSession.EntitySpawned += OnLiveEntitySpawned;
_liveSession.EntityDeleted += OnLiveEntityDeleted;
_liveSession.MotionUpdated += OnLiveMotionUpdated;
@ -2632,13 +2636,6 @@ public sealed class GameWindow : IDisposable
_liveSession.VitalCurrentUpdated += v =>
LocalPlayer.OnVitalCurrent(v.VitalId, v.Current);
// D.5.2: live PublicUpdatePropertyInt(0x02CE). Route UiEffects (18) to the item
// repository so a draining/charging item re-composites its icon in real time.
_liveSession.ObjectIntPropertyUpdated += u =>
{
if (u.Property == AcDream.Core.Items.ClientObjectTable.UiEffectsPropertyId)
Objects.UpdateIntProperty(u.Guid, u.Property, u.Value);
};
}
/// <summary>
@ -2648,14 +2645,6 @@ public sealed class GameWindow : IDisposable
/// </summary>
private void OnLiveEntitySpawned(AcDream.Core.Net.WorldSession.EntitySpawn spawn)
{
// D.5.1: enrich a known inventory/equipped item (stubbed from PlayerDescription)
// with the icon/name/type its CreateObject carries, so the toolbar can render it.
// D.5.1 (2026-06-17): also pass overlay/underlay ids from the extended
// WeenieHeader tail so IconComposer composites all icon layers.
Objects.EnrichItem(spawn.Guid, spawn.IconId, spawn.Name ?? string.Empty,
(AcDream.Core.Items.ItemType)(spawn.ItemType ?? 0),
spawn.IconOverlayId, spawn.IconUnderlayId, spawn.UiEffects);
// Phase A.1 hotfix: live CreateObject handler reads dats extensively
// (Setup, GfxObj, Surface, SurfaceTexture) to hydrate the spawned
// entity. All of it must run under the dat lock so it doesn't race