fix(ui): port exact paperdoll body selection
Resolve and sample retail's authored nine-color paperdoll click map, preserve local click coordinates, and select the stable highest-priority worn item with the player fallback. Keep targeted-use body clicks routed to self and pin both synthetic and live-DAT conformance. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
2644d1d527
commit
0b74d19475
16 changed files with 490 additions and 32 deletions
|
|
@ -40,11 +40,19 @@ public sealed class UiButton : UiElement, IUiGlobalTimeListener, IUiDatStateful
|
|||
private bool _selected;
|
||||
private bool _hotClicking;
|
||||
private bool _suppressNextClick;
|
||||
private int _pointerX;
|
||||
private int _pointerY;
|
||||
private double _nextHotClickTime = double.NaN;
|
||||
|
||||
/// <summary>Optional click handler. Wired by the controller (e.g. chat Submit, ToggleMaximize).</summary>
|
||||
public Action? OnClick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional position-aware click handler. Coordinates are local pixels in this button,
|
||||
/// matching retail's <c>UIElementMessageInfo.ptWindow</c> paperdoll hit-test input.
|
||||
/// </summary>
|
||||
public Action<int, int>? OnClickAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional item-drop target callbacks. Retail uses ordinary buttons as drop surfaces
|
||||
/// in a few panels (notably gmToolbarUI's inventory button), so this belongs on the
|
||||
|
|
@ -265,12 +273,15 @@ public sealed class UiButton : UiElement, IUiGlobalTimeListener, IUiDatStateful
|
|||
UpdateVisualState();
|
||||
return true;
|
||||
case UiEventType.MouseDown:
|
||||
_pointerX = e.Data1;
|
||||
_pointerY = e.Data2;
|
||||
_pointerOver = ContainsLocal(e.Data1, e.Data2);
|
||||
_pressed = true;
|
||||
UpdateVisualState();
|
||||
if (HotClickEnabled && Enabled)
|
||||
{
|
||||
OnClick?.Invoke();
|
||||
OnClickAt?.Invoke(_pointerX, _pointerY);
|
||||
_hotClicking = true;
|
||||
_nextHotClickTime = double.NaN;
|
||||
}
|
||||
|
|
@ -278,12 +289,16 @@ public sealed class UiButton : UiElement, IUiGlobalTimeListener, IUiDatStateful
|
|||
case UiEventType.MouseMove:
|
||||
if (_pressed)
|
||||
{
|
||||
_pointerX = e.Data1;
|
||||
_pointerY = e.Data2;
|
||||
_pointerOver = ContainsLocal(e.Data1, e.Data2);
|
||||
UpdateVisualState();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case UiEventType.MouseUp:
|
||||
_pointerX = e.Data1;
|
||||
_pointerY = e.Data2;
|
||||
_pointerOver = ContainsLocal(e.Data1, e.Data2);
|
||||
_suppressNextClick = _hotClicking && _pointerOver;
|
||||
_hotClicking = false;
|
||||
|
|
@ -301,7 +316,8 @@ public sealed class UiButton : UiElement, IUiGlobalTimeListener, IUiDatStateful
|
|||
return true;
|
||||
}
|
||||
OnClick?.Invoke();
|
||||
return OnClick is not null;
|
||||
OnClickAt?.Invoke(e.Data1, e.Data2);
|
||||
return OnClick is not null || OnClickAt is not null;
|
||||
case UiEventType.DragEnter:
|
||||
_itemDragAcceptance = e.Payload is ItemDragPayload payload
|
||||
? OnItemDragOver?.Invoke(payload) ?? ItemDragAcceptance.None
|
||||
|
|
@ -348,6 +364,7 @@ public sealed class UiButton : UiElement, IUiGlobalTimeListener, IUiDatStateful
|
|||
if (_pointerOver && nowSeconds >= _nextHotClickTime)
|
||||
{
|
||||
OnClick?.Invoke();
|
||||
OnClickAt?.Invoke(_pointerX, _pointerY);
|
||||
_nextHotClickTime += HotClickRepeatInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue