77 lines
2.1 KiB
C#
77 lines
2.1 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|