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:
Erik 2026-07-21 09:01:02 +02:00
parent d2bb5af453
commit 5acc3f01cf
23 changed files with 2635 additions and 168 deletions

View file

@ -72,6 +72,38 @@ public sealed class RetailItemConfirmationControllerTests
Assert.Equal(0, items.BusyCount);
}
[Fact]
public void PositiveConfirmationRechecksGlobalInventoryGateBeforeUse()
{
var objects = BuildObjects(PublicWeenieFlags.VolatileRare);
var uses = new List<uint>();
var messages = new List<string>();
var items = new ItemInteractionController(
objects,
playerGuid: () => Player,
sendUse: uses.Add,
sendUseWithTarget: null,
sendWield: null,
sendDrop: null,
placeInBackpack: static (_, _, _) => { },
systemMessage: messages.Add,
nowMs: () => 1000L);
var root = new UiRoot { Width = 800f, Height = 600f };
ImportedLayout? shown = null;
var factory = new RetailDialogFactory(root, _ =>
shown = FixtureLoader.LoadConfirmationDialog());
using var confirmations = new RetailItemConfirmationController(factory, items);
Assert.True(items.ActivateItem(Rare));
Assert.True(items.PlaceWorldItemInBackpack(0x70000001u));
Assert.IsType<UiButton>(shown!.FindElement(
RetailConfirmationDialogView.AcceptButtonId)).OnClick!();
Assert.Empty(uses);
Assert.Equal(0, items.BusyCount);
Assert.Equal(new[] { ItemInteractionController.InventoryRequestBusyMessage }, messages);
}
private static ClientObjectTable BuildObjects(PublicWeenieFlags flags)
{
var objects = new ClientObjectTable();