feat(input): assess world objects on right click

Port SmartBox's release-completed sr_Examine gesture through the configurable SelectRight binding. Cancel camera drags at the shared retail three-pixel threshold, then reuse the canonical picker, selection pulse, and appraisal request path without inventing another wire or UI owner.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-24 05:42:28 +02:00
parent 6718ee45a0
commit 5ad32d5753
16 changed files with 394 additions and 13 deletions

View file

@ -223,6 +223,65 @@ public sealed class SelectionInteractionControllerTests
Assert.Null(h.Selection.SelectedObjectId);
}
[Fact]
public void RightClickPulsesSelectsAndExaminesPickedWorldObject()
{
var h = new Harness();
h.Query.Picked = Target;
Assert.True(h.Controller.HandleInputAction(InputAction.SelectRight));
Assert.False(h.Query.LastIncludeSelf);
Assert.Equal(Target, h.Selection.SelectedObjectId);
Assert.Equal(new[] { "pick", "pulse", "examine" }, h.Query.Events);
Assert.Equal(new[] { Target }, h.Examines);
}
[Fact]
public void RightClickEmptyWorldIsANoOp()
{
var h = new Harness();
Assert.True(h.Controller.HandleInputAction(InputAction.SelectRight));
Assert.Equal(new[] { "pick" }, h.Query.Events);
Assert.Null(h.Selection.SelectedObjectId);
Assert.Empty(h.Examines);
Assert.Empty(h.Toasts);
}
[Fact]
public void RightClickExaminesWithoutConsumingLeftClickTargetMode()
{
var h = new Harness();
h.Query.Picked = Target;
h.Items.InteractionState.EnterUse();
h.Controller.HandleInputAction(InputAction.SelectRight);
Assert.Equal(InteractionModeKind.Use, h.Items.InteractionState.Current.Kind);
Assert.Equal(Target, h.Selection.SelectedObjectId);
Assert.Equal(new[] { Target }, h.Examines);
}
[Fact]
public void ExamineActionUsesSelectionOrEntersTargetMode()
{
var selected = new Harness();
selected.Selection.Select(Target, SelectionChangeSource.World);
Assert.True(selected.Controller.HandleInputAction(
InputAction.SelectionExamine));
Assert.Equal(new[] { Target }, selected.Examines);
var empty = new Harness();
Assert.True(empty.Controller.HandleInputAction(
InputAction.SelectionExamine));
Assert.Equal(
InteractionModeKind.Examine,
empty.Items.InteractionState.Current.Kind);
}
[Fact]
public void ClosestTargetInputMutatesSelectionOnce()
{