fix(items): preserve wand stance and corpse use order

Keep active-combat AutoWield intent through ACE's pre-wield transition and queued trailing peace notice, while allowing explicit combat input to supersede it.

Queue one-shot item interactions until the frame's movement edge has been serialized, so a movement release cannot cancel ACE's server-side corpse approach callback.

Release build succeeds and all 5,890 runnable tests pass with five intentional skips.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-17 19:32:01 +02:00
parent 0392c6d721
commit e6dd8bf6fa
10 changed files with 303 additions and 22 deletions

View file

@ -516,15 +516,15 @@ optimistic pre-confirm projection instead of treating equipment as backpack
contents. The connected gate completed NonCombat → Missile → NonCombat →
Missile, including a Jump press, without a server rejection.
**2026-07-17 active-switch follow-up:** A connected Magic wand -> missile
weapon trace exposed ACE's queued `Magic -> Melee -> NonCombat -> Missile ->
NonCombat` tail. `AutoWieldController` now retains the desired ready mode
through every confirmed blocker move and, only for a transaction that began
in active combat, arms settlement on authoritative `WieldObject`. An already-
correct first mode notice clears it; ACE's observed `NonCombat -> Missile ->
NonCombat` sequence sends the normal mode request from its trailing notice,
after the queued callback that caused that notice.
This keeps the missile bar present while retaining
**2026-07-17 active-switch follow-up:** Connected primary-weapon replacement
traces exposed ACE's queued old-stance transition and trailing `NonCombat`.
`AutoWieldController` now retains the desired ready mode through every
confirmed blocker move and, only for a transaction that began in active
combat, arms settlement on authoritative `WieldObject`. It recognizes both a
pre-wield transition followed by `ready -> NonCombat` and a wholly post-wield
`NonCombat -> ready -> NonCombat` tail, then sends the normal mode request from
the trailing notice after the queued callback that caused it. An explicit user
combat request cancels settlement. This keeps the correct missile or magic bar present while retaining
ACE ownership of every state and motion; peace-mode switching is unchanged.
The narrow ACE compatibility difference is registered as AP-118.
@ -2319,6 +2319,15 @@ request now retires the previous ground-object presentation immediately, as
retail `SetGroundObject` does. This removes the stale range watcher whose close
Use canceled ACE's active MoveTo chain before the new corpse could open.
**2026-07-17 input-order follow-up:** A second connected trace showed the
remaining far-R failure as `UseDone(0)` with no `ViewContents`. Silk delivered
R before the object phase had serialized a preceding movement-key release, so
ACE received `Use` and then `MoveToState`; ACE correctly cancelled the
Use-created MoveTo callback while acdream's local MoveTo kept walking. The new
`OutboundInteractionQueue` drains keyboard Use, world double-click, and pickup
immediately after the same frame's movement output and before inbound dispatch.
The flow still sends exactly one request and relies on ACE's arrival callback.
**Acceptance:** replacement sends `NoLongerViewingContents` once; authored close/range sends `Use` once and waits for `0x0052`; owned main/side-pack navigation sends neither; root/nested projections retire without deleting objects; corpse Use never attempts to pick up the corpse; a full-stack loot drop immediately shows a ghosted pending copy at the chosen destination slot and confirmation/failure clears it; canonical transfers remain server-authoritative. Focused Core, Core.Net, and App tests pin each path; visual acceptance remains the normal user gate.
---