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

@ -76,9 +76,11 @@ public class KeyBindingsRetailTests
{
var b = KeyBindings.RetailDefaults();
var binds = b.ForAction(InputAction.MovementWalkMode).ToList();
Assert.NotEmpty(binds);
Assert.All(binds, x => Assert.Equal(ActivationType.Hold, x.Activation));
Assert.Contains(binds, x => x.Chord.Key == Key.ShiftLeft);
Binding binding = Assert.Single(binds);
Assert.Equal(ActivationType.Hold, binding.Activation);
Assert.Equal(
new KeyChord(Key.ShiftLeft, ModifierMask.None),
binding.Chord);
}
[Fact]
@ -135,14 +137,15 @@ public class KeyBindingsRetailTests
}
[Fact]
public void QuickSlot_5_bareUsesAndCtrlSelects()
public void QuickSlot_5_BareAndCtrlBothUseRetailAction()
{
var b = KeyBindings.RetailDefaults();
var bare = b.Find(new KeyChord(Key.Number5, ModifierMask.None), ActivationType.Press);
var ctrl = b.Find(new KeyChord(Key.Number5, ModifierMask.Ctrl), ActivationType.Press);
Assert.Equal(InputAction.UseQuickSlot_5, bare?.Action);
Assert.Equal(InputAction.SelectQuickSlot_5, ctrl?.Action);
Assert.Equal(InputAction.UseQuickSlot_5, ctrl?.Action);
Assert.Empty(b.ForAction(InputAction.SelectQuickSlot_5));
}
[Fact]
@ -216,6 +219,18 @@ public class KeyBindingsRetailTests
var binds = b.ForAction(InputAction.CameraActivateAlternateMode).ToList();
Assert.Contains(binds, x => x.Chord == new KeyChord(Key.F2, ModifierMask.None));
Assert.Contains(binds, x => x.Chord == new KeyChord(Key.KeypadDivide, ModifierMask.None));
Assert.All(binds, x => Assert.Equal(ActivationType.Hold, x.Activation));
}
[Theory]
[InlineData(InputAction.CombatAimLow)]
[InlineData(InputAction.CombatAimMedium)]
[InlineData(InputAction.CombatAimHigh)]
public void Missile_aim_actions_use_retail_press_and_release_edges(InputAction action)
{
var binding = Assert.Single(KeyBindings.RetailDefaults().ForAction(action));
Assert.Equal(ActivationType.Hold, binding.Activation);
Assert.Equal(InputScope.MissileCombat, binding.Scope);
}
[Fact]