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:
parent
d2bb5af453
commit
5acc3f01cf
23 changed files with 2635 additions and 168 deletions
|
|
@ -13081,12 +13081,7 @@ public sealed class GameWindow : IDisposable
|
|||
private void OnUiDragReleasedOutside(object payload, int x, int y)
|
||||
{
|
||||
if (payload is AcDream.App.UI.ItemDragPayload itemPayload)
|
||||
{
|
||||
uint target = PickWorldGuidAt(x, y, includeSelf: true) ?? 0u;
|
||||
if (target != 0u)
|
||||
BeginSelectionLightingPulse(target);
|
||||
_itemInteractionController?.PlaceIn3D(itemPayload, target);
|
||||
}
|
||||
_selectionInteractions?.PlaceDraggedItem(itemPayload, x, y);
|
||||
}
|
||||
|
||||
// L.0 follow-up: persisted-settings cache populated by
|
||||
|
|
@ -13746,15 +13741,8 @@ public sealed class GameWindow : IDisposable
|
|||
return _worldSelectionQuery?.GetCombatCameraTargetPoint(selected);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Phase B.4b — outbound Use handler. Wires three input actions
|
||||
// (LMB click select, LMB-double-click select+use, R hotkey
|
||||
// use-selected) through WorldPicker into InteractRequests.BuildUse.
|
||||
// The inbound reply (SetState 0xF74B) lands via L.2g slice 1.
|
||||
// ============================================================
|
||||
|
||||
/// <summary>
|
||||
/// Shared world pick at the current cursor. The renderer supplies the
|
||||
/// Item-target-mode world pick at the current cursor. The renderer supplies the
|
||||
/// exact visible CPhysicsPart equivalents and RetailWorldPicker performs
|
||||
/// retail's drawing-sphere broadphase followed by flat visual-polygon
|
||||
/// intersection. <paramref name="includeSelf"/> allows item target-use to
|
||||
|
|
@ -13764,13 +13752,6 @@ public sealed class GameWindow : IDisposable
|
|||
=> _selectionInteractions?.PickAtCursor(includeSelf)
|
||||
?? _worldSelectionQuery?.PickAtCursor(includeSelf);
|
||||
|
||||
private uint? PickWorldGuidAt(float mouseX, float mouseY, bool includeSelf)
|
||||
=> _selectionInteractions?.PickAt(mouseX, mouseY, includeSelf)
|
||||
?? _worldSelectionQuery?.PickAt(mouseX, mouseY, includeSelf);
|
||||
|
||||
private void BeginSelectionLightingPulse(uint serverGuid)
|
||||
=> _worldSelectionQuery?.BeginLightingPulse(serverGuid);
|
||||
|
||||
// Contained/toolbar activation is not a world-selection interaction: it
|
||||
// sends directly without speculative TurnToObject/MoveToObject.
|
||||
private void UseItemByGuid(uint guid)
|
||||
|
|
@ -13818,33 +13799,6 @@ public sealed class GameWindow : IDisposable
|
|||
private AcDream.App.UI.Layout.VividTargetInfo? ResolveVividTargetInfo(uint guid)
|
||||
=> _worldSelectionQuery?.ResolveVividTargetInfo(guid);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 2026-05-16 — retail-faithful port of
|
||||
/// <c>SmartBox::GetObjectBoundingBox</c> (decomp <c>0x00452e20</c>)
|
||||
/// using <c>CPhysicsObj::GetSelectionSphere</c> (<c>0x0050ea40</c>)
|
||||
/// → <c>CPartArray::GetSelectionSphere</c> (<c>0x00518b80</c>).
|
||||
///
|
||||
/// <para>
|
||||
/// Retail's VividTargetIndicator does NOT use a per-mesh AABB —
|
||||
/// it uses the Setup's <c>selection_sphere</c> field (a single
|
||||
/// sphere encompassing the entire entity, baked at Setup-creation
|
||||
/// time). The sphere is scaled by the part-array scale
|
||||
/// (component-wise on center, Z-scale on radius — retail's exact
|
||||
/// formula at <c>0x00518ba6–0x00518be3</c>) and rotated by entity
|
||||
/// orientation. The screen indicator rect is the projection of
|
||||
/// the camera-aligned BBox of this sphere — i.e. a screen circle
|
||||
/// of radius <c>worldRadius * focalLength / depth</c>.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Result: the indicator rect MATCHES the Setup's intended
|
||||
/// "selectable extent" — which is typically larger than the mesh
|
||||
/// AABB by design (Setups bake a slightly oversized selection
|
||||
/// sphere so far targets still get pickable indicators). That's
|
||||
/// why our previous mesh-AABB indicator was smaller than retail's.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
private void TogglePlayerMode()
|
||||
{
|
||||
// Phase B.2 guard: only active when a live session is in-world.
|
||||
|
|
@ -14084,7 +14038,11 @@ public sealed class GameWindow : IDisposable
|
|||
Console.WriteLine($"[autowalk-end] reason=complete err={err}");
|
||||
if (err == AcDream.Core.Physics.WeenieError.None)
|
||||
OnAutoWalkArrivedSendDeferredAction();
|
||||
else
|
||||
_selectionInteractions?.OnMoveToCancelled(err);
|
||||
};
|
||||
playerMoveTo.MoveToCancelled = err =>
|
||||
_selectionInteractions?.OnMoveToCancelled(err);
|
||||
|
||||
// R5-V3 (#171, retires TS-39 — player side): bind the sticky
|
||||
// seams to the player host's PositionManager (same trio as the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue