fix(items): complete retail corpse looting feedback
Route corpse Use through the shared ItemHolder policy so Stuck corpses open instead of being sent as pickup requests. Restore the framed, horizontally resizable external-container strip and use a compact initial width. Port retail's target-list pending item projection so loot is marked in the chosen inventory slot without changing canonical ownership before the server confirms. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
20ce67b625
commit
d51a0fc825
13 changed files with 275 additions and 102 deletions
|
|
@ -45,6 +45,12 @@ Cross-references:
|
|||
|
||||
The strip is LayoutDesc `0x21000008`, selected root `0x10000063`
|
||||
(`0,400`, `800 x 110`) rather than a synthetic inventory window.
|
||||
The root's own DirectState is only the tiled center surface `0x06004CC2`; the
|
||||
common floating-window nine-slice supplies the missing outer bevel. The authored
|
||||
Left/Right edge rules stretch the two horizontal lists and scrollbar while
|
||||
pinning the close button, so the mounted strip resizes horizontally only. The
|
||||
modern retained mount starts at a compact 700-pixel content width and may be
|
||||
resized from either side up to the viewport edge.
|
||||
|
||||
| Element | Purpose | Authored bounds |
|
||||
|---|---|---|
|
||||
|
|
@ -67,6 +73,12 @@ UseWorldObject(objectId):
|
|||
expectedExternalRoot = objectId
|
||||
send Use(objectId)
|
||||
|
||||
UseCorpse(corpseId):
|
||||
// A corpse is a TYPE_CONTAINER carrying BF_STUCK | BF_CORPSE.
|
||||
// BF_STUCK excludes DetermineUseResult's PlaceInBackpack branch.
|
||||
classify through ItemHolder::UseObject
|
||||
send Use(corpseId), never PutItemInContainer(corpseId)
|
||||
|
||||
OnViewContents(containerId, orderedEntries):
|
||||
// Always update the projection: ACE sends nested-container snapshots too.
|
||||
objectTable.ReplaceContents(containerId, orderedEntries)
|
||||
|
|
@ -132,9 +144,21 @@ DragExternalItemToOwnedInventory(itemId, placement, splitAmount):
|
|||
send StackableSplitToContainer(itemId, player/openOwnedBag,
|
||||
placement, splitAmount)
|
||||
else:
|
||||
destinationList.InsertItem(itemId, placement)
|
||||
destinationList.pendingItem.SetWaitingState(true)
|
||||
send PutItemInContainer(itemId, player/openOwnedBag, placement)
|
||||
do not mutate canonical ownership before the server response
|
||||
|
||||
OnServerMoveItem(itemId):
|
||||
if destinationList.pendingItem.itemId == itemId:
|
||||
clear pendingItem
|
||||
rebuild the list from authoritative placement
|
||||
|
||||
OnInventoryServerSaveFailed(itemId):
|
||||
if destinationList.pendingItem.itemId == itemId:
|
||||
remove the pending copy
|
||||
leave the source ownership unchanged
|
||||
|
||||
DragOwnedItemToExternalContainer(itemId, placement, splitAmount):
|
||||
if splitAmount < full stack:
|
||||
send StackableSplitToContainer(itemId, currentExternalSubcontainer,
|
||||
|
|
@ -157,6 +181,10 @@ DragOwnedItemToExternalContainer(itemId, placement, splitAmount):
|
|||
projection owner.
|
||||
- `ExternalContainerController` owns the authored strip, range/close behavior,
|
||||
nested-list selection, selection, and drag/drop presentation.
|
||||
- `InventoryController` owns retail `UIElement_ItemList::m_pendingItem`: a
|
||||
destination-only waiting projection at the exact chosen slot. It subscribes
|
||||
to authoritative move and failure notices and never rewrites external-item
|
||||
ownership while the request is in flight.
|
||||
- `ItemInteractionController` remains the only interpreter of retail item-use
|
||||
and placement policy. It gains explicit adapters for `SetGroundObject` and
|
||||
`PlaceInContainer`; panels do not reimplement those decisions.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue