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

@ -167,6 +167,14 @@ public sealed class MoveToManager
/// </summary>
public Action<WeenieError>? MoveToComplete { get; set; }
/// <summary>
/// CLIENT ADDITION — cancellation companion to <see cref="MoveToComplete"/>.
/// Fires only when <see cref="CancelMoveTo"/> actually tears down an
/// active move. It never changes retail movement behavior; App owners use
/// it to withdraw presentation state which was waiting for natural arrival.
/// </summary>
public Action<WeenieError>? MoveToCancelled { get; set; }
/// <summary>Retail <c>Timer::cur_time</c> — injectable clock (tests drive
/// this explicitly; production binds to the real wall/game clock).
/// Defaults to a monotonically-increasing stub if not overridden via the
@ -1455,18 +1463,18 @@ public sealed class MoveToManager
/// <see cref="_pendingActions"/>, <see cref="CleanUp"/>, then
/// StopCompletely. The <paramref name="error"/> argument is NEVER READ
/// in retail's body (every call site's error code is dropped in this
/// build, decomp §7c) — kept for parity/logging/tests only; NO behavior
/// depends on its value.
/// build, decomp §7c). The retail body remains independent of it; only the
/// documented client-addition <see cref="MoveToCancelled"/> observes it
/// after teardown so App presentation can classify the cancellation.
/// </summary>
public void CancelMoveTo(WeenieError error)
{
_ = error; // retail: never read in the body (decomp §7c) — kept for parity/logging.
if (MovementTypeState == MovementType.Invalid) return;
_pendingActions.Clear();
CleanUp();
if (HasPhysicsObj) _stopCompletely();
MoveToCancelled?.Invoke(error);
}
/// <summary>