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

@ -262,7 +262,8 @@ internal sealed class GameplayInputActionRouter : IDisposable
return;
if (activation is not ActivationType.Press
and not ActivationType.DoubleClick)
and not ActivationType.DoubleClick
and not ActivationType.Click)
{
return;
}

View file

@ -73,9 +73,16 @@ internal sealed class SelectionInteractionController
case InputAction.SelectLeft:
PickAndStoreSelection(useImmediately: false);
return true;
case InputAction.SelectRight:
PickSelectAndExamine();
return true;
case InputAction.SelectDblLeft:
PickAndStoreSelection(useImmediately: true);
return true;
case InputAction.SelectionExamine:
_items.ExamineSelectedOrEnterMode(
_selection.SelectedObjectId ?? 0u);
return true;
case InputAction.UseSelected:
UseCurrentSelection();
return true;
@ -181,6 +188,25 @@ internal sealed class SelectionInteractionController
});
}
/// <summary>
/// Retail SmartBox right-click path:
/// <c>UIElement_SmartBoxWrapper::MouseUp @ 0x004E5820</c> chooses
/// <c>sr_Examine</c>, then
/// <c>RecvNotice_SmartBoxObjectFound @ 0x004E5AD0</c> pulses, selects,
/// and calls <c>ClientUISystem::ExamineObject</c>. Empty space is a no-op,
/// and this path does not consume a left-click target mode.
/// </summary>
public void PickSelectAndExamine()
{
uint? picked = _query.PickAtCursor(includeSelf: false);
if (picked is not uint guid)
return;
_query.BeginLightingPulse(guid);
_selection.Select(guid, SelectionChangeSource.World);
_items.ExamineSelectedOrEnterMode(guid);
}
public void UseCurrentSelection()
{
if (_selection.SelectedObjectId is not uint selected)