fix: complete retail parity stability pass
All checks were successful
CI / linux-portable (push) Successful in 3m41s
CI / windows-gate (push) Successful in 6m49s
CI / release (push) Successful in 3m22s

This commit is contained in:
Erik 2026-08-28 20:01:39 +02:00
parent d3df4cb20a
commit f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions

View file

@ -2290,6 +2290,7 @@ public sealed class LiveEntityHydrationControllerTests
Assert.True(fixture.Runtime.TryGetRecord(splitResultGuid, out LiveEntityRecord record));
Assert.NotNull(record.WorldEntity);
Assert.Equal(1, fixture.Resources.RegisterCount);
Assert.Equal(splitResultGuid, drop.Selection.SelectedObjectId);
}
[Fact]
@ -2372,6 +2373,7 @@ public sealed class LiveEntityHydrationControllerTests
Assert.False(secondRecovered);
Assert.False(fixture.Runtime.TryGetSnapshot(secondUnknown, out _));
Assert.True(fixture.Runtime.TryGetSnapshot(firstUnknown, out _));
Assert.Equal(firstUnknown, drop.Selection.SelectedObjectId);
Assert.Equal(1, fixture.Resources.RegisterCount);
}
@ -2476,7 +2478,7 @@ public sealed class LiveEntityHydrationControllerTests
public readonly ItemInteractionController Interaction;
public readonly InventoryWorldDropProjectionController Projection;
public readonly StackSplitQuantityState SplitQuantity = new();
public uint SelectedObject;
public readonly AcDream.Core.Selection.SelectionState Selection = new();
public DropHarness(Fixture fixture)
{
@ -2498,7 +2500,7 @@ public sealed class LiveEntityHydrationControllerTests
sendWield: null,
sendDrop: _ => { },
sendSplitToWorld: (_, _) => { },
selectedObjectId: () => SelectedObject,
selectedObjectId: () => Selection.SelectedObjectId ?? 0u,
stackSplitQuantity: SplitQuantity,
playerOnGround: () => true);
Projection = new InventoryWorldDropProjectionController(
@ -2506,12 +2508,15 @@ public sealed class LiveEntityHydrationControllerTests
fixture.Objects,
fixture.Runtime,
fixture.Controller,
Selection,
() => 100.0);
}
public bool DispatchSplit(uint itemGuid, uint stackSize, uint splitAmount)
{
SelectedObject = itemGuid;
Selection.Select(
itemGuid,
AcDream.Core.Selection.SelectionChangeSource.Inventory);
SplitQuantity.Reset(stackSize);
SplitQuantity.SetValue(splitAmount);
var payload = new ItemDragPayload(

View file

@ -28,12 +28,13 @@ internal static class LiveEntityTestFixture
WorldSession.EntitySpawn spawn,
Func<uint, WorldEntity>? factory = null,
LiveEntityProjectionKind projectionKind = LiveEntityProjectionKind.World,
Action<LiveEntityRecord>? initializeProjection = null)
Action<LiveEntityRecord>? initializeProjection = null,
bool isLocalPlayer = false)
{
ArgumentNullException.ThrowIfNull(runtime);
LiveEntityRegistrationResult registration =
runtime.RegisterLiveEntity(spawn);
runtime.RegisterLiveEntity(spawn, isLocalPlayer);
RuntimeEntityRecord canonical = registration.Canonical
?? throw new InvalidOperationException(
"The fixture cannot materialize a stale CreateObject.");

View file

@ -356,6 +356,48 @@ public sealed class RuntimePlacementPresentationSinkTests
Assert.Equal(priorVisible, record.IsSpatiallyVisible);
}
[Fact]
public void ExecutorCompleted_PoseOnlySupersessionDoesNotSnapSidecarBack()
{
Fixture fixture = Fixture.Create();
LiveEntityRecord record = fixture.Materialize(Spawn(Guid, 1, SourceCell));
WorldEntity entity = record.WorldEntity!;
var body = new PhysicsBody
{
Position = entity.Position,
Orientation = entity.Rotation,
};
record.Canonical.SetPhysicsBody(body);
RuntimePlacementProjectionSnapshot stale = Placement(
fixture,
record,
RuntimePlacementProjectionKind.ExecutorCompleted,
body.Position,
body.Orientation);
// #323: StoreAcceptedDestinationPose has this exact shape — it moves
// the retained body without changing cell or PlacementCommitVersion.
// A delayed initial-create receipt must acknowledge without restoring
// the older pose to the graphical sidecar.
var currentPosition = body.Position + new Vector3(25f, 10f, 3f);
Quaternion currentOrientation = Quaternion.CreateFromAxisAngle(
Vector3.UnitZ,
0.75f);
body.Position = currentPosition;
body.Orientation = currentOrientation;
entity.SetPosition(currentPosition);
entity.Rotation = currentOrientation;
Assert.True(fixture.Sink.TryApply(in stale));
Assert.Equal(currentPosition, entity.Position);
Assert.Equal(currentOrientation, entity.Rotation);
Assert.Equal(stale.Token.ExactCellId, record.FullCellId);
Assert.Equal(
stale.Token.PlacementCommitVersion,
record.Canonical.PlacementCommitVersion);
}
[Fact]
public void Place_RejectsStaleCanonicalVersionsWithoutChangingSidecar()
{