fix(ui): port live experience quality updates (#217)
Parse retail PrivateUpdatePropertyInt64 and route authoritative Total/Available Experience through both local-player projections so Attributes, the level meter, and Skills refresh together. Preserve the existing retail XP curve and right-align the Total XP value. Close the user-confirmed item-give gate for #216 and record the named-retail/ACE/holtburger conformance evidence. Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
parent
30d294506c
commit
84b7d2d7cd
15 changed files with 391 additions and 29 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Player;
|
||||
|
||||
namespace AcDream.Core.Net;
|
||||
|
||||
|
|
@ -6,8 +7,9 @@ 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) = live int apply, PrivateUpdatePropertyInt
|
||||
/// (0x02CD) = player int (burden), SetStackSize (0x0197) = stack count, InventoryRemoveObject
|
||||
/// (0x0024) = inventory-view removal.
|
||||
/// (0x02CD) = player int (burden), PrivateUpdatePropertyInt64 (0x02CF) = player
|
||||
/// 64-bit qualities (experience), SetStackSize (0x0197) = stack count,
|
||||
/// InventoryRemoveObject (0x0024) = inventory-view removal.
|
||||
/// Keeps object ingestion in Core.Net (pure data, no GL) and off GameWindow.
|
||||
/// Retail: ACCObjectMaint::CreateObject / DeleteObject (the weenie_object_table side).
|
||||
/// </summary>
|
||||
|
|
@ -18,7 +20,11 @@ public static class ObjectTableWiring
|
|||
/// 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, Func<uint>? playerGuid = null)
|
||||
public static void Wire(
|
||||
WorldSession session,
|
||||
ClientObjectTable table,
|
||||
Func<uint>? playerGuid = null,
|
||||
LocalPlayerState? localPlayer = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(session);
|
||||
ArgumentNullException.ThrowIfNull(table);
|
||||
|
|
@ -50,6 +56,14 @@ public static class ObjectTableWiring
|
|||
table.UpdateIntProperty(playerGuid(), u.Property, u.Value);
|
||||
};
|
||||
|
||||
// Retail's qualities system owns one local-player value and notifies every
|
||||
// registered panel. acdream currently exposes that value through two projections:
|
||||
// ClientObjectTable (retained UI) and LocalPlayerState (Core consumers/fallback).
|
||||
// Apply the authoritative 0x02CF update to both in this one wiring owner so they
|
||||
// cannot drift after the login PlayerDescription snapshot.
|
||||
session.PlayerInt64PropertyUpdated += u => ApplyPlayerInt64PropertyUpdate(
|
||||
table, localPlayer, playerGuid?.Invoke() ?? 0u, u);
|
||||
|
||||
// B-Wire: SetStackSize (0x0197) — update the object's stack count + value.
|
||||
session.StackSizeUpdated += u => table.UpdateStackSize(u.Guid, u.StackSize, u.Value);
|
||||
|
||||
|
|
@ -58,6 +72,18 @@ public static class ObjectTableWiring
|
|||
session.InventoryObjectRemoved += guid => table.Remove(guid);
|
||||
}
|
||||
|
||||
/// <summary>Shared application step kept internal for byte-to-state conformance tests.</summary>
|
||||
internal static void ApplyPlayerInt64PropertyUpdate(
|
||||
ClientObjectTable table,
|
||||
LocalPlayerState? localPlayer,
|
||||
uint playerGuid,
|
||||
WorldSession.PlayerInt64PropertyUpdate update)
|
||||
{
|
||||
if (playerGuid != 0u)
|
||||
table.UpdateInt64Property(playerGuid, update.Property, update.Value);
|
||||
localPlayer?.OnInt64PropertyUpdate(update.Property, update.Value);
|
||||
}
|
||||
|
||||
/// <summary>Translate the wire spawn into the table's merge patch.</summary>
|
||||
public static WeenieData ToWeenieData(WorldSession.EntitySpawn s) => new(
|
||||
Guid: s.Guid,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue