fix(interaction): close selection lifecycle review gaps
Bind queued actions and pending inventory requests to exact live incarnations, separate optimistic placement from authoritative responses, and serialize retail-style inventory ownership across UI surfaces. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
d2bb5af453
commit
5acc3f01cf
23 changed files with 2635 additions and 168 deletions
|
|
@ -263,4 +263,81 @@ public sealed class ExternalContainerControllerTests
|
|||
Assert.Equal(Player, h.Objects.Get(Item)!.ContainerId);
|
||||
Assert.Empty(h.Puts);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PendingPickupRejectsOwnedDropIntoChest()
|
||||
{
|
||||
using var h = new Harness();
|
||||
h.Open();
|
||||
h.Objects.AddOrUpdate(new ClientObject { ObjectId = Item, Type = ItemType.Misc });
|
||||
h.Objects.MoveItem(Item, Player, 0);
|
||||
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
|
||||
source.SetItem(Item, 0u);
|
||||
|
||||
Assert.True(h.Interaction.PlaceWorldItemInBackpack(0x70000A01u));
|
||||
h.Controller.HandleDropRelease(
|
||||
h.Contents,
|
||||
h.Contents.GetItem(0)!,
|
||||
new ItemDragPayload(Item, ItemDragSource.Inventory, 0, source));
|
||||
|
||||
Assert.Empty(h.Puts);
|
||||
Assert.Equal(Player, h.Objects.Get(Item)!.ContainerId);
|
||||
Assert.True(h.Interaction.TryGetPendingBackpackPlacement(0x70000A01u, out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PendingPickupRejectsPartialStackSplitIntoChest()
|
||||
{
|
||||
using var h = new Harness();
|
||||
h.Open();
|
||||
h.Objects.AddOrUpdate(new ClientObject
|
||||
{
|
||||
ObjectId = Item,
|
||||
StackSize = 5,
|
||||
StackSizeMax = 100,
|
||||
Type = ItemType.Misc,
|
||||
});
|
||||
h.Objects.MoveItem(Item, Player, 0);
|
||||
h.Selection.Select(Item, SelectionChangeSource.Inventory);
|
||||
h.Split.Reset(5u, 2u);
|
||||
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
|
||||
source.SetItem(Item, 0u);
|
||||
|
||||
Assert.True(h.Interaction.PlaceWorldItemInBackpack(0x70000A02u));
|
||||
h.Controller.HandleDropRelease(
|
||||
h.Contents,
|
||||
h.Contents.GetItem(0)!,
|
||||
new ItemDragPayload(Item, ItemDragSource.Inventory, 0, source));
|
||||
|
||||
Assert.Empty(h.Splits);
|
||||
Assert.Equal(Player, h.Objects.Get(Item)!.ContainerId);
|
||||
Assert.True(h.Interaction.TryGetPendingBackpackPlacement(0x70000A02u, out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExternalPutOwnsGlobalGateUntilMatchingServerMove()
|
||||
{
|
||||
using var h = new Harness();
|
||||
const uint pickup = 0x70000A03u;
|
||||
h.Open();
|
||||
h.Objects.AddOrUpdate(new ClientObject { ObjectId = Item, Type = ItemType.Misc });
|
||||
h.Objects.MoveItem(Item, Player, 0);
|
||||
var source = new UiItemSlot { SourceKind = ItemDragSource.Inventory };
|
||||
source.SetItem(Item, 0u);
|
||||
|
||||
h.Controller.HandleDropRelease(
|
||||
h.Contents,
|
||||
h.Contents.GetItem(0)!,
|
||||
new ItemDragPayload(Item, ItemDragSource.Inventory, 0, source));
|
||||
Assert.True(h.Interaction.TryGetPendingInventoryRequest(out var pending));
|
||||
Assert.Equal(Item, pending.ItemId);
|
||||
|
||||
Assert.True(h.Interaction.PlaceWorldItemInBackpack(pickup));
|
||||
Assert.Empty(h.Pickups);
|
||||
|
||||
h.Objects.ApplyConfirmedServerMove(Item, Chest, 0u, 0);
|
||||
Assert.False(h.Interaction.TryGetPendingInventoryRequest(out _));
|
||||
Assert.True(h.Interaction.PlaceWorldItemInBackpack(pickup));
|
||||
Assert.Equal(new uint[] { pickup }, h.Pickups);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue