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
|
|
@ -950,6 +950,45 @@ public sealed class GameEventWiringTests
|
|||
Assert.Equal(0u, items.Get(0x50000A01u)!.ContainerId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireAll_ExternalContainer_FiltersNestedViewsAndAppliesAuthoritativeClose()
|
||||
{
|
||||
var dispatcher = new GameEventDispatcher();
|
||||
var items = new ClientObjectTable();
|
||||
var external = new ExternalContainerState();
|
||||
GameEventWiring.WireAll(
|
||||
dispatcher,
|
||||
items,
|
||||
new CombatState(),
|
||||
new Spellbook(),
|
||||
new ChatLog(),
|
||||
externalContainers: external);
|
||||
external.RequestOpen(0x70000001u);
|
||||
|
||||
DispatchViewContents(
|
||||
dispatcher,
|
||||
0x70000001u,
|
||||
new uint[] { 0x60000001u, 0x70000002u });
|
||||
DispatchViewContents(dispatcher, 0x70000002u, new uint[] { 0x60000002u });
|
||||
|
||||
Assert.Equal(0x70000001u, external.CurrentContainerId);
|
||||
Assert.Equal(
|
||||
new uint[] { 0x60000001u, 0x70000002u },
|
||||
items.GetContents(0x70000001u));
|
||||
Assert.Equal(new uint[] { 0x60000002u }, items.GetContents(0x70000002u));
|
||||
|
||||
byte[] closePayload = new byte[4];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(closePayload, 0x70000001u);
|
||||
var close = GameEventEnvelope.TryParse(
|
||||
WrapEnvelope(GameEventType.CloseGroundContainer, closePayload));
|
||||
dispatcher.Dispatch(close!.Value);
|
||||
|
||||
Assert.Equal(0u, external.CurrentContainerId);
|
||||
Assert.Empty(items.GetContents(0x70000001u));
|
||||
Assert.NotNull(items.Get(0x60000001u));
|
||||
Assert.Empty(items.GetContents(0x70000002u));
|
||||
}
|
||||
|
||||
private static void DispatchViewContents(GameEventDispatcher d, uint containerGuid, uint[] itemGuids)
|
||||
{
|
||||
byte[] payload = new byte[8 + itemGuids.Length * 8];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue