Release 1.0.5.0: World Object Tooltip (hover tooltip, detach option), version bump, pluginmaster
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility;
|
||||
using HSUI.Config;
|
||||
@@ -6,6 +8,7 @@ using HSUI.Interface.GeneralElements;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
|
||||
namespace HSUI.Helpers
|
||||
{
|
||||
@@ -124,6 +127,109 @@ namespace HSUI.Helpers
|
||||
Plugin.Logger.Information($"[HSUI Tooltip DBG] ShowTooltip: title='{title}' textLen={text?.Length ?? 0} textPreview='{(text != null && text.Length > 80 ? text[..80] + "..." : text ?? "")}' pos=({_position.X:F0},{_position.Y:F0})");
|
||||
}
|
||||
|
||||
private WorldObjectTooltipConfig? _worldTooltipConfig;
|
||||
|
||||
/// <summary>
|
||||
/// Shows a tooltip for the game object the mouse is hovering over in the 3D world.
|
||||
/// Call this each frame before Draw().
|
||||
/// </summary>
|
||||
public void ShowWorldObjectTooltip()
|
||||
{
|
||||
try
|
||||
{
|
||||
_worldTooltipConfig ??= ConfigurationManager.Instance.GetConfigObject<WorldObjectTooltipConfig>();
|
||||
if (_worldTooltipConfig == null || !_worldTooltipConfig.Enabled)
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Config not ready yet or not found - silently skip
|
||||
if (_config.DebugTooltips)
|
||||
Plugin.Logger.Warning($"[HSUI Tooltip] WorldObjectTooltipConfig not available: {ex.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
IGameObject? mouseOverTarget = Plugin.TargetManager.MouseOverTarget;
|
||||
if (mouseOverTarget == null)
|
||||
return;
|
||||
|
||||
// Don't show tooltip for ourselves
|
||||
if (mouseOverTarget.GameObjectId == Plugin.ObjectTable.LocalPlayer?.GameObjectId)
|
||||
return;
|
||||
|
||||
string name = mouseOverTarget.Name.ToString();
|
||||
if (string.IsNullOrEmpty(name))
|
||||
name = "Unknown";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
// Free Company tag for players
|
||||
if (_worldTooltipConfig.ShowTitle && mouseOverTarget is IPlayerCharacter player)
|
||||
{
|
||||
string fcTag = player.CompanyTag.ToString();
|
||||
if (!string.IsNullOrEmpty(fcTag))
|
||||
sb.AppendLine($"«{fcTag}»");
|
||||
}
|
||||
|
||||
// Level
|
||||
if (_worldTooltipConfig.ShowLevel && mouseOverTarget is ICharacter charLevel)
|
||||
{
|
||||
byte level = charLevel.Level;
|
||||
if (level > 0)
|
||||
sb.AppendLine($"Level {level}");
|
||||
}
|
||||
|
||||
// Job (for players)
|
||||
if (_worldTooltipConfig.ShowJob && mouseOverTarget is IPlayerCharacter playerJob)
|
||||
{
|
||||
uint jobId = playerJob.ClassJob.RowId;
|
||||
if (jobId > 0 && JobsHelper.JobNames.TryGetValue(jobId, out string? jobName))
|
||||
sb.AppendLine($"Job: {jobName}");
|
||||
}
|
||||
|
||||
// HP
|
||||
if (_worldTooltipConfig.ShowHP && mouseOverTarget is ICharacter charHp)
|
||||
{
|
||||
uint currentHp = charHp.CurrentHp;
|
||||
uint maxHp = charHp.MaxHp;
|
||||
if (maxHp > 0)
|
||||
{
|
||||
float pct = (float)currentHp / maxHp * 100f;
|
||||
sb.AppendLine($"HP: {currentHp:N0} / {maxHp:N0} ({pct:F0}%)");
|
||||
}
|
||||
}
|
||||
|
||||
// Distance
|
||||
if (_worldTooltipConfig.ShowDistance)
|
||||
{
|
||||
var localPlayer = Plugin.ObjectTable.LocalPlayer;
|
||||
if (localPlayer != null)
|
||||
{
|
||||
float dist = Vector3.Distance(localPlayer.Position, mouseOverTarget.Position);
|
||||
sb.AppendLine($"Distance: {dist:F1}y");
|
||||
}
|
||||
}
|
||||
|
||||
// Object ID (debug)
|
||||
if (_worldTooltipConfig.ShowObjectId)
|
||||
{
|
||||
sb.AppendLine($"ID: {mouseOverTarget.GameObjectId}");
|
||||
}
|
||||
|
||||
string body = sb.ToString().TrimEnd('\r', '\n');
|
||||
if (string.IsNullOrEmpty(body))
|
||||
body = "(No info)";
|
||||
|
||||
if (_worldTooltipConfig.DetachFromCursor)
|
||||
{
|
||||
ShowTooltip(body, _worldTooltipConfig.Position, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowTooltipOnCursor(body, name);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveTooltip()
|
||||
{
|
||||
_dataIsValid = false;
|
||||
@@ -305,4 +411,43 @@ namespace HSUI.Helpers
|
||||
Thickness = thickness;
|
||||
}
|
||||
}
|
||||
|
||||
[Section("Misc")]
|
||||
[SubSection("World Tooltip", 0)]
|
||||
public class WorldObjectTooltipConfig : PluginConfigObject
|
||||
{
|
||||
public new static WorldObjectTooltipConfig DefaultConfig() { return new WorldObjectTooltipConfig(); }
|
||||
|
||||
[Checkbox("Detach from Cursor", spacing = true)]
|
||||
[Order(1)]
|
||||
public bool DetachFromCursor = false;
|
||||
|
||||
[DragFloat2("Position (when detached)", min = -4000f, max = 4000f)]
|
||||
[Order(2, collapseWith = nameof(DetachFromCursor))]
|
||||
public Vector2 Position = new Vector2(100, 100);
|
||||
|
||||
[Checkbox("Show Level", spacing = true)]
|
||||
[Order(5)]
|
||||
public bool ShowLevel = true;
|
||||
|
||||
[Checkbox("Show HP")]
|
||||
[Order(10)]
|
||||
public bool ShowHP = true;
|
||||
|
||||
[Checkbox("Show Job (Players)")]
|
||||
[Order(15)]
|
||||
public bool ShowJob = true;
|
||||
|
||||
[Checkbox("Show FC Tag (Players)")]
|
||||
[Order(20)]
|
||||
public bool ShowTitle = false;
|
||||
|
||||
[Checkbox("Show Distance")]
|
||||
[Order(25)]
|
||||
public bool ShowDistance = true;
|
||||
|
||||
[Checkbox("Show Object ID")]
|
||||
[Order(30)]
|
||||
public bool ShowObjectId = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user