Tooltip adjustments
This commit is contained in:
parent
7b9c0d5c8a
commit
7b4ff19b01
4 changed files with 127 additions and 6 deletions
|
|
@ -21,6 +21,17 @@ public static class DossierAvatar
|
|||
|
||||
public static bool UsingVanilla => _usingVanilla;
|
||||
|
||||
/// <summary>True if <paramref name="screenPoint"/> is inside the live portrait rect.</summary>
|
||||
public static bool ContainsScreenPoint(Vector2 screenPoint)
|
||||
{
|
||||
if (_host == null || !_host.gameObject.activeInHierarchy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return RectTransformUtility.RectangleContainsScreenPoint(_host, screenPoint, null);
|
||||
}
|
||||
|
||||
public static void ResetHost()
|
||||
{
|
||||
_template = null;
|
||||
|
|
|
|||
77
IdleSpectator/FocusTooltipPatches.cs
Normal file
77
IdleSpectator/FocusTooltipPatches.cs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
using HarmonyLib;
|
||||
|
||||
namespace IdleSpectator;
|
||||
|
||||
/// <summary>
|
||||
/// Idle pins <see cref="UnitSelectionEffect.last_actor"/> so relationship arrows draw.
|
||||
/// That same pin would always show the focus unit tip via
|
||||
/// <see cref="CursorTooltipHelper.updateGameplayTooltip"/>.
|
||||
/// Allow tips for a real cursor unit or the dossier live sprite; suppress the pin tip on empty world / dossier chrome.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(CursorTooltipHelper), nameof(CursorTooltipHelper.updateGameplayTooltip))]
|
||||
internal static class FocusTooltipPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
private static bool Prefix(ref bool __result, ref Actor __state)
|
||||
{
|
||||
__state = null;
|
||||
if (!SpectatorMode.Active)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Live sprite: tip for the focused unit (last_actor is already pinned).
|
||||
if (WatchCaption.IsPointerOverAvatar())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Dossier chrome (not the sprite): no tip.
|
||||
if (WatchCaption.IsPointerOverPanel())
|
||||
{
|
||||
Tooltip.hideTooltip();
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
Actor near = GetActorNearCursorSafe();
|
||||
if (near != null && near.isAlive())
|
||||
{
|
||||
// Real world hover: briefly use that unit for the tip, then restore the pin.
|
||||
__state = UnitSelectionEffect.last_actor;
|
||||
UnitSelectionEffect.setLastActor(near);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Empty world (grass, water, etc.): do not leak the idle focus tip.
|
||||
Tooltip.hideTooltip();
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
private static void Postfix(Actor __state)
|
||||
{
|
||||
if (__state != null)
|
||||
{
|
||||
UnitSelectionEffect.setLastActor(__state);
|
||||
}
|
||||
}
|
||||
|
||||
private static Actor GetActorNearCursorSafe()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (World.world == null || ControllableUnit.isControllingUnit())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return World.world.getActorNearCursor();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ public static class WatchCaption
|
|||
private const float HistoryIcon = 10f;
|
||||
private const float HistoryColMinW = 118f;
|
||||
private const float PadX = 4f;
|
||||
/// <summary>Inset from the canvas top-right corner (grows left via pivot).</summary>
|
||||
private const float ScreenInset = 12f;
|
||||
private const float PadTop = 4f;
|
||||
private const float HeaderH = 18f;
|
||||
private const float BodyH = 44f;
|
||||
|
|
@ -133,6 +135,23 @@ public static class WatchCaption
|
|||
return pixelRect.width > 8f && pixelRect.height > 8f;
|
||||
}
|
||||
|
||||
/// <summary>True if the mouse is over the dossier panel (including the live sprite).</summary>
|
||||
public static bool IsPointerOverPanel()
|
||||
{
|
||||
if (_rootRt == null || _root == null || !_root.activeInHierarchy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return RectTransformUtility.RectangleContainsScreenPoint(_rootRt, Input.mousePosition, null);
|
||||
}
|
||||
|
||||
/// <summary>True if the mouse is over the dossier live sprite only.</summary>
|
||||
public static bool IsPointerOverAvatar()
|
||||
{
|
||||
return DossierAvatar.ContainsScreenPoint(Input.mousePosition);
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
_current = null;
|
||||
|
|
@ -770,6 +789,7 @@ public static class WatchCaption
|
|||
float height = Mathf.Max(HeaderH + PadTop * 2f, y + PadTop - Gap);
|
||||
if (_rootRt != null)
|
||||
{
|
||||
ApplyRootPlacement();
|
||||
_rootRt.sizeDelta = new Vector2(_panelWidth, height);
|
||||
LastPanelSize = _rootRt.sizeDelta;
|
||||
}
|
||||
|
|
@ -1159,11 +1179,8 @@ public static class WatchCaption
|
|||
_root.transform.SetParent(canvas.transform, false);
|
||||
|
||||
_rootRt = _root.GetComponent<RectTransform>();
|
||||
_rootRt.anchorMin = new Vector2(0f, 1f);
|
||||
_rootRt.anchorMax = new Vector2(0f, 1f);
|
||||
_rootRt.pivot = new Vector2(0f, 1f);
|
||||
ApplyRootPlacement();
|
||||
_rootRt.sizeDelta = new Vector2(LiveMax + PadX * 2f, HeaderH + PadTop * 2f);
|
||||
_rootRt.anchoredPosition = new Vector2(12f, -12f);
|
||||
|
||||
Image bg = _root.GetComponent<Image>();
|
||||
bg.raycastTarget = false;
|
||||
|
|
@ -1250,6 +1267,22 @@ public static class WatchCaption
|
|||
LogService.LogInfo("[IdleSpectator] Dossier HUD ready (nametag chips + mini history)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pin the card to the canvas top-right. Pivot (1,1) so width growth expands left and stays on-screen.
|
||||
/// </summary>
|
||||
private static void ApplyRootPlacement()
|
||||
{
|
||||
if (_rootRt == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_rootRt.anchorMin = new Vector2(1f, 1f);
|
||||
_rootRt.anchorMax = new Vector2(1f, 1f);
|
||||
_rootRt.pivot = new Vector2(1f, 1f);
|
||||
_rootRt.anchoredPosition = new Vector2(-ScreenInset, -ScreenInset);
|
||||
}
|
||||
|
||||
private static void PlaceLine(RectTransform lineRt, float yFromTop, float height, float left)
|
||||
{
|
||||
if (lineRt == null)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "IdleSpectator",
|
||||
"author": "dazed",
|
||||
"version": "0.9.28",
|
||||
"description": "AFK Idle Spectator (I) + Chronicle (F9). Dossier grows wide before history wraps.",
|
||||
"version": "0.9.31",
|
||||
"description": "AFK Idle Spectator (I) + Chronicle (F9). Dossier top-right; tip on world hover or live sprite.",
|
||||
"GUID": "com.dazed.idlespectator"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue