feat(items): port retail external-container looting
Add the ClientUISystem ground-object lifecycle, authoritative root and nested ViewContents projections, replacement and close semantics, and the DAT-authored gmExternalContainerUI strip for chests and corpses. Route double-click loot and full or partial drag transfers through the shared retail item policy without optimistic external ownership. Remove the incorrect NoLongerViewingContents behavior from owned side packs and retire AP-106/#196. Release build succeeds and all 5,875 tests pass with five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
48a118db91
commit
20ce67b625
27 changed files with 1750 additions and 45 deletions
|
|
@ -79,7 +79,8 @@ public static class GameEventWiring
|
|||
SquelchState? squelch = null,
|
||||
Action<IReadOnlyList<(uint Id, uint Amount)>>? onDesiredComponents = null,
|
||||
Action<uint /*options1*/, uint /*options2*/>? onCharacterOptions = null,
|
||||
Func<double>? clientTime = null)
|
||||
Func<double>? clientTime = null,
|
||||
ExternalContainerState? externalContainers = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(dispatcher);
|
||||
ArgumentNullException.ThrowIfNull(items);
|
||||
|
|
@ -364,6 +365,7 @@ public static class GameEventWiring
|
|||
p.Value.Items[i].Guid,
|
||||
p.Value.Items[i].ContainerType);
|
||||
items.ReplaceContents(p.Value.ContainerGuid, entries);
|
||||
externalContainers?.ApplyViewContents(p.Value.ContainerGuid);
|
||||
});
|
||||
|
||||
// B-Wire: InventoryPutObjectIn3D (0x019A) — server confirms an item dropped
|
||||
|
|
@ -412,13 +414,15 @@ public static class GameEventWiring
|
|||
chat.OnSystemMessage(WeenieErrorText.For(err.Value), chatType: 0);
|
||||
});
|
||||
|
||||
// B-Wire: CloseGroundContainer (0x0052) — server closed a ground-container
|
||||
// view. No table change (the view is UI-only, wired in container-open); log.
|
||||
// CloseGroundContainer (0x0052): clear ClientUISystem::groundObject and
|
||||
// retire the root plus nested temporary ViewContents projections. Child
|
||||
// objects remain until authoritative move/delete wire says otherwise.
|
||||
dispatcher.Register(GameEventType.CloseGroundContainer, e =>
|
||||
{
|
||||
var guid = GameEvents.ParseCloseGroundContainer(e.Payload.Span);
|
||||
if (guid is not null)
|
||||
Console.WriteLine($"[B-Wire] CloseGroundContainer guid=0x{guid.Value:X8}");
|
||||
if (guid is null) return;
|
||||
externalContainers?.ApplyClose(guid.Value);
|
||||
items.StopViewingContentsTree(guid.Value);
|
||||
});
|
||||
|
||||
dispatcher.Register(GameEventType.IdentifyObjectResponse, e =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue