fix: complete retail parity stability pass
This commit is contained in:
parent
d3df4cb20a
commit
f7aa8e0eb7
131 changed files with 7765 additions and 1190 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue