[Fools-YesHealMePlugin] Removed unused parts in the helper functions.

This commit is contained in:
Bernardo Lopes 2023-03-27 07:33:41 -03:00
parent 81aacb56ee
commit b77bf380f2
9 changed files with 104 additions and 170 deletions

View file

@ -1,31 +1,9 @@
using System.Numerics; using System.Numerics;
using ImGuiNET;
namespace Dalamud.Fools.Helper.YesHealMe; namespace Dalamud.Fools.Helper.YesHealMe;
public static class Colors public static class Colors
{ {
public static Vector4 Purple = new(176 / 255.0f, 38 / 255.0f, 236 / 255.0f, 1.0f); public static readonly Vector4 White = new(1.0f, 1.0f, 1.0f, 1.0f);
public static Vector4 Blue = new(37 / 255.0f, 168 / 255.0f, 1.0f, 1.0f); public static readonly Vector4 Black = new(0.0f, 0.0f, 0.0f, 1.0f);
public static Vector4 ForestGreen = new(0.133f, 0.545f, 0.1333f, 1.0f);
public static Vector4 White = new(1.0f, 1.0f, 1.0f,1.0f);
public static Vector4 Red = new(1.0f, 0.0f, 0.0f, 1.0f);
public static Vector4 Green = new(0.0f, 1.0f, 0.0f, 1.0f);
public static Vector4 Black = new(0.0f, 0.0f, 0.0f, 1.0f);
public static Vector4 HealerGreen = new(33 / 255f, 193 / 255f, 0, 1.0f);
public static Vector4 DPSRed = new(210/255f, 42/255f, 43/255f, 1.0f);
public static Vector4 SoftRed = new(0.8f, 0.2f, 0.2f, 1.0f);
public static Vector4 Grey = new(0.6f, 0.6f, 0.6f, 1.0f);
public static Vector4 LightGrey = new(220/250.0f, 220/250.0f, 220/250f, 1.0f);
public static Vector4 Orange = new(1.0f, 165.0f / 255.0f, 0.0f, 1.0f);
public static Vector4 SoftGreen = new(0.2f, 0.8f, 0.2f, 1.0f);
public static Vector4 FatePink = new(0.58f, 0.388f, 0.827f, 0.33f);
public static Vector4 FateDarkPink = new(0.58f, 0.388f, 0.827f, 1.0f);
public static Vector4 MapTextBrown = new(0.655f, 0.396f, 0.149f, 1.0f);
public static Vector4 BabyBlue = new(0.537f, 0.812f, 0.941f, 1.0f);
}
public static class ColorExtensions
{
public static uint ToU32(this Vector4 color) => ImGui.GetColorU32(color);
} }

View file

@ -1,13 +1,13 @@
using System; using System;
using System.Numerics; using System.Numerics;
using ImGuiNET; using ImGuiNET;
using KamiLib.Caching;
namespace Dalamud.Fools.Helper.YesHealMe; namespace Dalamud.Fools.Helper.YesHealMe;
internal static class DrawUtilities internal static class DrawUtilities
{ {
public static void TextOutlined(FontManager fontManager, Vector2 startingPosition, string text, float scale, Vector4 color) public static void TextOutlined(
FontManager fontManager, Vector2 startingPosition, string text, float scale, Vector4 color)
{ {
startingPosition = startingPosition.Ceil(); startingPosition = startingPosition.Ceil();
@ -29,40 +29,44 @@ internal static class DrawUtilities
DrawText(fontManager, startingPosition, text, color, scale); DrawText(fontManager, startingPosition, text, color, scale);
} }
public static void DrawIconWithName(FontManager fontManager, Vector2 drawPosition, uint iconID, string name, float iconScale, float textScale, bool drawText = true) public static void DrawIconWithName(
FontManager fontManager, Vector2 drawPosition, uint iconID, string name, float iconScale, float textScale)
{ {
if (!fontManager.GameFont.Available) return; if (!fontManager.GameFont.Available)
{
return;
}
var icon = IconCache.Instance.GetIcon(iconID); var icon = IconCache.Instance.GetIcon(iconID);
if (icon != null) if (icon != null)
{ {
var drawList = ImGui.GetBackgroundDrawList(); var drawList = ImGui.GetBackgroundDrawList();
var imagePadding = new Vector2(20.0f, 10.0f) * iconScale; var imagePadding = new Vector2(20.0f, 10.0f) * iconScale;
var imageSize = new Vector2(50.0f, 50.0f) * iconScale; var imageSize = new Vector2(50.0f, 50.0f) * iconScale;
drawPosition += imagePadding; drawPosition += imagePadding;
drawList.AddImage(icon.ImGuiHandle, drawPosition, drawPosition + imageSize); drawList.AddImage(icon.ImGuiHandle, drawPosition, drawPosition + imageSize);
if (drawText) drawPosition.X += imageSize.X / 2.0f;
{ drawPosition.Y += imageSize.Y + (2.0f * iconScale);
drawPosition.X += imageSize.X / 2.0f;
drawPosition.Y += imageSize.Y + 2.0f * iconScale; var textSize = CalculateTextSize(fontManager, name, textScale / 2.75f);
var textOffset = new Vector2(0.0f, 5.0f) * iconScale;
var textSize = CalculateTextSize(fontManager, name, textScale / 2.75f);
var textOffset = new Vector2(0.0f, 5.0f) * iconScale; drawPosition.X -= textSize.X / 2.0f;
drawPosition.X -= textSize.X / 2.0f; TextOutlined(fontManager, drawPosition + textOffset, name, textScale / 2.75f, Colors.White);
TextOutlined(fontManager, drawPosition + textOffset, name, textScale / 2.75f, Colors.White);
}
} }
} }
public static Vector2 CalculateTextSize(FontManager fontManager, string text, float scale) public static Vector2 CalculateTextSize(FontManager fontManager, string text, float scale)
{ {
if(!fontManager.GameFont.Available) return Vector2.Zero; if (!fontManager.GameFont.Available)
{
return Vector2.Zero;
}
var fontSize = fontManager.GameFont.ImFont.FontSize; var fontSize = fontManager.GameFont.ImFont.FontSize;
var textSize = ImGui.CalcTextSize(text); var textSize = ImGui.CalcTextSize(text);
@ -73,18 +77,16 @@ internal static class DrawUtilities
return new Vector2(textWidth, fontSize) * scale; return new Vector2(textWidth, fontSize) * scale;
} }
private static void DrawText(FontManager fontManager, Vector2 drawPosition, string text, Vector4 color, float scale, bool debug = false) private static void DrawText(FontManager fontManager, Vector2 drawPosition, string text, Vector4 color, float scale)
{ {
if (!fontManager.GameFont.Available) return; if (!fontManager.GameFont.Available)
{
return;
}
var font = fontManager.GameFont.ImFont; var font = fontManager.GameFont.ImFont;
var drawList = ImGui.GetBackgroundDrawList(); var drawList = ImGui.GetBackgroundDrawList();
var stringSize = CalculateTextSize(fontManager, text, scale);
if (debug)
{
drawList.AddRect(drawPosition, drawPosition + stringSize, ImGui.GetColorU32(Colors.Green));
}
drawList.AddText(font, font.FontSize * scale, drawPosition, ImGui.GetColorU32(color), text); drawList.AddText(font, font.FontSize * scale, drawPosition, ImGui.GetColorU32(color), text);
} }

View file

@ -6,13 +6,13 @@ namespace Dalamud.Fools.Helper.YesHealMe;
public class FontManager : IDisposable public class FontManager : IDisposable
{ {
public GameFontHandle GameFont { get; }
public FontManager(UiBuilder uiBuilder) public FontManager(UiBuilder uiBuilder)
{ {
this.GameFont = uiBuilder.GetGameFontHandle( new GameFontStyle( GameFontFamily.Axis, 52.0f ) ); this.GameFont = uiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamily.Axis, 52.0f));
} }
public GameFontHandle GameFont { get; }
public void Dispose() public void Dispose()
{ {
this.GameFont.Dispose(); this.GameFont.Dispose();

View file

@ -1,40 +1,34 @@
using Dalamud; using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using FFXIVClientStructs.FFXIV.Client.UI.Agent; using FFXIVClientStructs.FFXIV.Client.UI.Agent;
namespace NoTankYou.Utilities; namespace Dalamud.Fools.Helper.YesHealMe;
public static unsafe class HudHelper public static unsafe class HudHelper
{ {
private static AgentHUD* AgentHud => AgentModule.Instance()->GetAgentHUD(); private static AgentHUD* AgentHud => AgentModule.Instance()->GetAgentHUD();
public static PlayerCharacter? GetPlayerCharacter(int index) public static PlayerCharacter? GetPlayerCharacter(int index)
{ {
// Sorta temporary, waiting for ClientStructs to merge a fixed size array for this element // Sorta temporary, waiting for ClientStructs to merge a fixed size array for this element
var partyMemberList = AgentHud->PartyMemberList; var partyMemberList = AgentHud->PartyMemberList;
var targetOffset = index * sizeof(HudPartyMember); var targetOffset = index * sizeof(HudPartyMember);
var targetAddress = partyMemberList + targetOffset; var targetAddress = partyMemberList + targetOffset;
var hudData = (HudPartyMember*) targetAddress; var hudData = (HudPartyMember*)targetAddress;
var targetPlayer = hudData->ObjectId; var targetPlayer = hudData->ObjectId;
return GetPlayer(targetPlayer); return GetPlayer(targetPlayer);
} }
public static PlayerCharacter? GetAllianceMember(int index)
{
var targetPlayer = AgentHud->RaidMemberIds[index];
return GetPlayer(targetPlayer);
}
private static PlayerCharacter? GetPlayer(uint objectId) private static PlayerCharacter? GetPlayer(uint objectId)
{ {
var result = Service<ObjectTable>.Get().SearchById(objectId); var result = Service<ObjectTable>.Get().SearchById(objectId);
if (result?.GetType() == typeof(PlayerCharacter)) if (result?.GetType() == typeof(PlayerCharacter))
{
return result as PlayerCharacter; return result as PlayerCharacter;
}
return null; return null;
} }

View file

@ -1,70 +1,71 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud;
using Dalamud.Data; using Dalamud.Data;
using Dalamud.Logging; using Dalamud.Logging;
using Dalamud.Utility; using Dalamud.Utility;
using ImGuiScene; using ImGuiScene;
namespace KamiLib.Caching; namespace Dalamud.Fools.Helper.YesHealMe;
public class IconCache : IDisposable public class IconCache : IDisposable
{ {
private readonly Dictionary<uint, TextureWrap?> iconTextures = new();
private const string IconFilePath = "ui/icon/{0:D3}000/{1:D6}_hr1.tex"; private const string IconFilePath = "ui/icon/{0:D3}000/{1:D6}_hr1.tex";
private static IconCache? _instance; private static IconCache? internalInstance;
public static IconCache Instance => _instance ??= new IconCache(); private readonly Dictionary<uint, TextureWrap?> iconTextures = new();
public static IconCache Instance => internalInstance ??= new IconCache();
public static void Cleanup()
public void Dispose()
{ {
_instance?.Dispose(); foreach (var texture in this.iconTextures.Values)
}
public void Dispose()
{
foreach (var texture in iconTextures.Values)
{ {
texture?.Dispose(); texture?.Dispose();
} }
iconTextures.Clear(); this.iconTextures.Clear();
} }
private void LoadIconTexture(uint iconId) public static void Cleanup()
{ {
Task.Run(() => internalInstance?.Dispose();
}
private void LoadIconTexture(uint iconId)
{
Task.Run(() =>
{ {
try try
{ {
var path = IconFilePath.Format(iconId / 1000, iconId); var path = IconFilePath.Format(iconId / 1000, iconId);
var tex = Service<DataManager>.Get().GetImGuiTexture(path); var tex = Service<DataManager>.Get().GetImGuiTexture(path);
if (tex is not null && tex.ImGuiHandle != nint.Zero) if (tex is not null && tex.ImGuiHandle != nint.Zero)
{ {
iconTextures[iconId] = tex; this.iconTextures[iconId] = tex;
} }
else else
{ {
tex?.Dispose(); tex?.Dispose();
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
PluginLog.LogError($"Failed loading texture for icon {iconId} - {ex.Message}"); PluginLog.LogError($"Failed loading texture for icon {iconId} - {ex.Message}");
} }
}); });
} }
public TextureWrap? GetIcon(uint iconId) public TextureWrap? GetIcon(uint iconId)
{ {
if (iconTextures.TryGetValue(iconId, out var value)) return value; if (this.iconTextures.TryGetValue(iconId, out var value))
{
return value;
}
iconTextures.Add(iconId, null); this.iconTextures.Add(iconId, null);
LoadIconTexture(iconId); this.LoadIconTexture(iconId);
return iconTextures[iconId]; return this.iconTextures[iconId];
} }
} }

View file

@ -2,66 +2,57 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
using Dalamud;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
using NoTankYou.DataModels;
using NoTankYou.Utilities;
namespace NoTankYou.System; namespace Dalamud.Fools.Helper.YesHealMe;
public unsafe class PartyListAddon : IEnumerable<PartyListAddonData>, IDisposable public unsafe class PartyListAddon : IEnumerable<PartyListAddonData>, IDisposable
{ {
public record PartyFramePositionInfo(Vector2 Position, Vector2 Size, Vector2 Scale);
public IEnumerator<PartyListAddonData> GetEnumerator() => addonData.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private static AddonPartyList* PartyList => (AddonPartyList*) Service<GameGui>.Get()?.GetAddonByName("_PartyList");
public static bool DataAvailable => PartyList != null && PartyList->AtkUnitBase.RootNode != null;
private readonly List<PartyListAddonData> addonData = new(); private readonly List<PartyListAddonData> addonData = new();
public PartyListAddon() public PartyListAddon()
{ {
Service<Framework>.Get().Update += OnFrameworkUpdate; Service<Framework>.Get().Update += this.OnFrameworkUpdate;
} }
private static AddonPartyList* PartyList => (AddonPartyList*)Service<GameGui>.Get()?.GetAddonByName("_PartyList");
private static bool DataAvailable => PartyList != null && PartyList->AtkUnitBase.RootNode != null;
public void Dispose() public void Dispose()
{ {
Service<Framework>.Get().Update -= OnFrameworkUpdate; Service<Framework>.Get().Update -= this.OnFrameworkUpdate;
}
public IEnumerator<PartyListAddonData> GetEnumerator()
{
return this.addonData.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
} }
private void OnFrameworkUpdate(Framework framework) private void OnFrameworkUpdate(Framework framework)
{ {
addonData.Clear(); this.addonData.Clear();
if (!DataAvailable) return; if (!DataAvailable || PartyList->MemberCount <= 0)
if (PartyList->MemberCount <= 0) return; {
return;
}
foreach (var index in Enumerable.Range(0, PartyList->MemberCount)) foreach (var index in Enumerable.Range(0, PartyList->MemberCount))
{ {
var playerCharacter = HudHelper.GetPlayerCharacter(index); var playerCharacter = HudHelper.GetPlayerCharacter(index);
var userInterface = PartyList->PartyMember[index]; var userInterface = PartyList->PartyMember[index];
addonData.Add(new PartyListAddonData this.addonData.Add(new PartyListAddonData
{ {
PlayerCharacter = playerCharacter, PlayerCharacter = playerCharacter,
UserInterface = userInterface, UserInterface = userInterface,
}); });
} }
} }
public static PartyFramePositionInfo GetPositionInfo()
{
// Resource Node (id 9) contains a weird offset for the actual list elements
var rootNode = PartyList->AtkUnitBase.RootNode;
var addonBasePosition = new Vector2(rootNode->X, rootNode->Y);
var scale = new Vector2(rootNode->ScaleX, rootNode->ScaleY);
var partyListNode = PartyList->AtkUnitBase.GetNodeById(9);
var partyListPositionOffset = new Vector2(partyListNode->X, partyListNode->Y) * scale;
var partyListSize = new Vector2(partyListNode->Width, partyListNode->Height);
return new PartyFramePositionInfo(addonBasePosition + partyListPositionOffset, partyListSize * scale, scale);
}
} }

View file

@ -1,37 +1,10 @@
using System; using Dalamud.Game.ClientState.Objects.SubKinds;
using System.Collections.Generic;
using System.Diagnostics;
using Dalamud.Game.ClientState.Objects.SubKinds;
using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Client.UI;
namespace NoTankYou.DataModels; namespace Dalamud.Fools.Helper.YesHealMe;
public readonly unsafe struct PartyListAddonData public readonly struct PartyListAddonData
{ {
private static readonly Dictionary<uint, Stopwatch> TimeSinceLastTargetable = new();
public AddonPartyList.PartyListMemberStruct UserInterface { get; init; } public AddonPartyList.PartyListMemberStruct UserInterface { get; init; }
public PlayerCharacter? PlayerCharacter { get; init; } public PlayerCharacter? PlayerCharacter { get; init; }
}
private bool Targetable => UserInterface.PartyMemberComponent->OwnerNode->AtkResNode.Color.A != 0x99;
public bool IsTargetable()
{
if (PlayerCharacter is null) return false;
TimeSinceLastTargetable.TryAdd(PlayerCharacter.ObjectId, Stopwatch.StartNew());
var stopwatch = TimeSinceLastTargetable[PlayerCharacter.ObjectId];
if (Targetable)
{
// Returns true if the party member has been targetable for 2second or more
return stopwatch.Elapsed >= TimeSpan.FromSeconds(2);
}
else
{
// Returns false, and continually resets the stopwatch
stopwatch.Restart();
return false;
}
}
}

View file

@ -1,6 +1,5 @@
using Dalamud.Fools.Helper.YesHealMe; using Dalamud.Fools.Helper.YesHealMe;
using Dalamud.Interface; using Dalamud.Interface;
using NoTankYou.System;
namespace Dalamud.Fools.Plugins; namespace Dalamud.Fools.Plugins;
@ -22,6 +21,7 @@ public class YesHealMePlugin : IFoolsPlugin
{ {
this.fontManager.Dispose(); this.fontManager.Dispose();
this.partyListAddon.Dispose(); this.partyListAddon.Dispose();
IconCache.Cleanup();
} }
public void DrawUi() public void DrawUi()

View file

@ -1,16 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Dalamud.Data;
using Dalamud.Fools.Helper.YesHealMe; using Dalamud.Fools.Helper.YesHealMe;
using Dalamud.Game.ClientState; using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface.Components;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using ImGuiNET; using ImGuiNET;
using NoTankYou.System;
namespace Dalamud.Fools.Plugins; namespace Dalamud.Fools.Plugins;
@ -84,7 +79,7 @@ public static class YesHealMePluginWindow
var textSize = DrawUtilities.CalculateTextSize(fontManager, hurtingCharacter.Name.TextValue, Scale); var textSize = DrawUtilities.CalculateTextSize(fontManager, hurtingCharacter.Name.TextValue, Scale);
var namePosition = new Vector2 var namePosition = new Vector2
{ {
X = healMePosition.X - textSize.X / 2.0f, X = healMePosition.X - (textSize.X / 2.0f),
Y = healMePosition.Y + textSize.Y, Y = healMePosition.Y + textSize.Y,
}; };
DrawUtilities.TextOutlined( DrawUtilities.TextOutlined(