fix(client): restore retail interaction parity
Harden keyboard and camera routing, inventory and vendor interactions, chat/emotes, relog portal flow, and paperdoll rendering. Add retail research, connected gate coverage, and release-gate validation.
This commit is contained in:
parent
0c699240e0
commit
f6fe0f2a4f
151 changed files with 10162 additions and 1211 deletions
|
|
@ -16,6 +16,8 @@ public sealed class ChatCommandTargetState : IDisposable
|
|||
private readonly object _gate = new();
|
||||
private string? _lastIncomingTellSender;
|
||||
private string? _lastOutgoingTellTarget;
|
||||
private string? _lastMonarchSender;
|
||||
private string? _lastPatronSender;
|
||||
private bool _disposed;
|
||||
|
||||
public ChatCommandTargetState(ChatLog chat)
|
||||
|
|
@ -42,6 +44,26 @@ public sealed class ChatCommandTargetState : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Most recent sender of an incoming retail <c>@m</c> broadcast.</summary>
|
||||
public string? LastMonarchSender
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_gate)
|
||||
return _lastMonarchSender;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Most recent sender of an incoming retail <c>@p</c> broadcast.</summary>
|
||||
public string? LastPatronSender
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_gate)
|
||||
return _lastPatronSender;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDisposed
|
||||
{
|
||||
get
|
||||
|
|
@ -61,6 +83,8 @@ public sealed class ChatCommandTargetState : IDisposable
|
|||
{
|
||||
_lastIncomingTellSender = null;
|
||||
_lastOutgoingTellTarget = null;
|
||||
_lastMonarchSender = null;
|
||||
_lastPatronSender = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,17 +101,34 @@ public sealed class ChatCommandTargetState : IDisposable
|
|||
|
||||
private void OnEntryAppended(ChatEntry entry)
|
||||
{
|
||||
if (entry.Kind != ChatKind.Tell || string.IsNullOrEmpty(entry.Sender))
|
||||
if (string.IsNullOrEmpty(entry.Sender))
|
||||
return;
|
||||
|
||||
lock (_gate)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
if (entry.SenderGuid != 0u)
|
||||
_lastIncomingTellSender = entry.Sender;
|
||||
else
|
||||
_lastOutgoingTellTarget = entry.Sender;
|
||||
if (entry.Kind == ChatKind.Tell)
|
||||
{
|
||||
if (entry.SenderGuid != 0u)
|
||||
_lastIncomingTellSender = entry.Sender;
|
||||
else
|
||||
_lastOutgoingTellTarget = entry.Sender;
|
||||
return;
|
||||
}
|
||||
|
||||
// gmCCommunicationSystem keeps independent reply targets for the
|
||||
// legacy Monarch (0x4000) and Patron (0x2000) broadcasts. The
|
||||
// legacy 0x0147 wire payload has no sender GUID, so its committed
|
||||
// ChatEntry correctly carries zero even for an incoming speaker.
|
||||
// Local channel echoes have an empty Sender and were rejected at
|
||||
// the top of this method; the non-empty name is the discriminator.
|
||||
if (entry.Kind != ChatKind.Channel)
|
||||
return;
|
||||
if (entry.ChannelId == 0x00004000u)
|
||||
_lastMonarchSender = entry.Sender;
|
||||
else if (entry.ChannelId == 0x00002000u)
|
||||
_lastPatronSender = entry.Sender;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,18 +33,19 @@ public static class InventoryFailureMessages
|
|||
string itemName,
|
||||
uint weenieError)
|
||||
{
|
||||
// ServerSaysAttemptFailed's verb switch. acdream has no latched kind
|
||||
// for retail's IR_MOVE ("moved") or IR_WIELD ("wielded") today —
|
||||
// wields ride AutoWieldController without the single-request gate —
|
||||
// so those rows are absent rather than guessed onto a wrong kind.
|
||||
// ServerSaysAttemptFailed's complete verb switch. The enum values are
|
||||
// named by operation rather than retail's numeric IR_* values, but the
|
||||
// wording and NAME_PLURAL/NAME_APPROPRIATE choice are verbatim.
|
||||
string? verb = kind switch
|
||||
{
|
||||
InventoryRequestKind.Merge => "merged",
|
||||
InventoryRequestKind.SplitToContainer => "split",
|
||||
InventoryRequestKind.SplitToWorld => "split",
|
||||
InventoryRequestKind.Move => "moved",
|
||||
InventoryRequestKind.Pickup => "picked up",
|
||||
InventoryRequestKind.PutInContainer => "put in the container",
|
||||
InventoryRequestKind.DropToWorld => "dropped",
|
||||
InventoryRequestKind.Wield => "wielded",
|
||||
InventoryRequestKind.Give => "given",
|
||||
_ => null,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue