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

@ -1,6 +1,7 @@
using System.Numerics;
using AcDream.App.Input;
using AcDream.App.Rendering;
using AcDream.Core.Rendering;
using AcDream.UI.Abstractions.Input;
using Silk.NET.Input;
@ -175,31 +176,63 @@ public sealed class CameraPointerInputControllerTests
Assert.Equal(flyBefore * 1.2f, fixture.Owner.ActiveSensitivity, 5);
}
[Fact]
public void ChaseMouseWheel_RetainsExtendedZoomOutRange()
{
var fixture = Create([new RawSurface()]);
var legacy = new ChaseCamera();
var retail = new RetailChaseCamera();
fixture.Mode.IsPlayerMode = true;
fixture.Chase.Legacy = legacy;
fixture.Chase.Retail = retail;
fixture.Camera.EnterChaseMode(legacy, retail);
float before = CameraDiagnostics.UseRetailChaseCamera
? retail.Distance
: legacy.Distance;
fixture.Owner.HandleScroll(InputAction.ScrollDown);
float afterOne = CameraDiagnostics.UseRetailChaseCamera
? retail.Distance
: legacy.Distance;
for (int i = 0; i < 100; i++)
fixture.Owner.HandleScroll(InputAction.ScrollDown);
float afterMany = CameraDiagnostics.UseRetailChaseCamera
? retail.Distance
: legacy.Distance;
Assert.Equal(before + 0.8f, afterOne, 5);
Assert.Equal(40f, afterMany, 5);
}
private static Fixture Create(IReadOnlyList<RawSurface> surfaces)
{
var camera = new CameraController(new OrbitCamera(), new FlyCamera());
var capture = new Capture();
var mouse = new Mouse();
var cursor = new Cursor();
var mode = new LocalPlayerModeState();
var chase = new ChaseCameraInputState();
var owner = new CameraPointerInputController(
surfaces,
cursor,
new HostQuiescenceGate(),
capture,
new LocalPlayerModeState(),
mode,
camera,
new ChaseCameraInputState(),
chase,
mouse,
new PointerPositionState(),
new Clock());
return new Fixture(owner, camera, capture, cursor);
return new Fixture(owner, camera, capture, cursor, mode, chase);
}
private sealed record Fixture(
CameraPointerInputController Owner,
CameraController Camera,
Capture Capture,
Cursor Cursor);
Cursor Cursor,
LocalPlayerModeState Mode,
ChaseCameraInputState Chase);
private sealed class RawSurface : IRawPointerSurface
{
@ -282,6 +315,7 @@ public sealed class CameraPointerInputControllerTests
{
public void Tick() { }
public void HandleMovementInput(InputAction action, ActivationType activation) { }
public void AbortAutomaticAttack() { }
public bool HandleInputAction(InputAction action, ActivationType activation) => false;
}
}