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
|
|
@ -294,6 +294,15 @@ public sealed class WorldSession : IDisposable
|
|||
/// PropertyInt updated on the player. B-Wire routes EncumbranceVal (5) to the burden bar.</summary>
|
||||
public event Action<PlayerIntPropertyUpdate>? PlayerIntPropertyUpdated;
|
||||
|
||||
/// <summary>Payload for <see cref="PlayerInt64PropertyUpdated"/>: a signed
|
||||
/// 64-bit quality change on the player's own object. Retail sends Total XP
|
||||
/// (1) and Available XP (2) through PrivateUpdatePropertyInt64 (0x02CF).</summary>
|
||||
public readonly record struct PlayerInt64PropertyUpdate(uint Property, long Value);
|
||||
|
||||
/// <summary>Fires after parsing retail PrivateUpdatePropertyInt64 (0x02CF).
|
||||
/// The wire carries no guid because the local player is implicit.</summary>
|
||||
public event Action<PlayerInt64PropertyUpdate>? PlayerInt64PropertyUpdated;
|
||||
|
||||
/// <summary>Payload for <see cref="StackSizeUpdated"/>: SetStackSize (0x0197) — a stack's
|
||||
/// count + value after a merge / split.</summary>
|
||||
public readonly record struct StackSizeUpdate(uint Guid, int StackSize, int Value);
|
||||
|
|
@ -1078,6 +1087,15 @@ public sealed class WorldSession : IDisposable
|
|||
PlayerIntPropertyUpdated?.Invoke(
|
||||
new PlayerIntPropertyUpdate(p.Value.Property, p.Value.Value));
|
||||
}
|
||||
else if (op == PrivateUpdatePropertyInt64.Opcode)
|
||||
{
|
||||
// Retail CM_Qualities::DispatchUI_PrivateUpdateInt64 @ 0x006AEAD0.
|
||||
// TotalExperience (1) and AvailableExperience (2) both arrive here.
|
||||
var p = PrivateUpdatePropertyInt64.TryParse(body);
|
||||
if (p is not null)
|
||||
PlayerInt64PropertyUpdated?.Invoke(
|
||||
new PlayerInt64PropertyUpdate(p.Value.Property, p.Value.Value));
|
||||
}
|
||||
else if (op == SetStackSize.Opcode)
|
||||
{
|
||||
var p = SetStackSize.TryParse(body);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue