fix(client): restore retail interaction parity
All checks were successful
CI / linux-portable (push) Successful in 3m27s
CI / windows-gate (push) Successful in 6m42s
CI / release (push) Successful in 2m12s

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:
Erik 2026-08-26 20:45:11 +02:00
parent 0c699240e0
commit f6fe0f2a4f
151 changed files with 10162 additions and 1211 deletions

View file

@ -94,6 +94,8 @@ public class SelectedObjectControllerTests
public readonly Dictionary<uint, bool> HasHealthMap = new();
public readonly Dictionary<uint, float> ManaMap = new();
public readonly Dictionary<uint, uint> StackMap = new();
public readonly Dictionary<uint, bool> CoinstackMap = new();
public int CoinTotal;
// Slice 6.2: vendor-owned split-exempt predicate — see
// SelectedObjectController.Bind's isVendorSplitExempt parameter.
public readonly Dictionary<uint, bool> VendorSplitExemptMap = new();
@ -139,7 +141,9 @@ public class SelectedObjectControllerTests
{
if (ObjectUpdatedHandler == h) ObjectUpdatedHandler = null;
},
isVendorSplitExempt: g => VendorSplitExemptMap.TryGetValue(g, out var v) && v);
isVendorSplitExempt: g => VendorSplitExemptMap.TryGetValue(g, out var v) && v,
isCoinstack: g => CoinstackMap.TryGetValue(g, out var v) && v,
coinTotal: () => CoinTotal);
}
// ── B1: Bind initialisation ──────────────────────────────────────────────
@ -165,6 +169,25 @@ public class SelectedObjectControllerTests
Assert.True(nameEl.ZOrder > 1000, "name element must be floated above the overlay/meter z-order");
}
[Fact]
public void OwnedCoinstack_usesRetailsExactStackNameAndTotalFormat()
{
var (layout, nameEl, _, _) = FakeLayout();
var h = new Harness { CoinTotal = 12_345 };
const uint coins = 0x50000111u;
h.NameMap[coins] = "Pyreals";
h.StackMap[coins] = 2_345u;
h.OwnedMap[coins] = true;
h.CoinstackMap[coins] = true;
h.Bind(layout);
h.FireSelection(coins);
Assert.Equal(
"2345 Pyreals (of 12345)",
nameEl.Children.OfType<UiText>().First().LinesProvider().Single().Text);
}
[Fact]
public void Bind_nameLinesProvider_yieldsEmpty_whenNothingSelected()
{