diff --git a/Dalamud/Fools/Helper/YesHealMe/Colors.cs b/Dalamud/Fools/Helper/YesHealMe/Colors.cs index 9828fe54b..ab2473199 100644 --- a/Dalamud/Fools/Helper/YesHealMe/Colors.cs +++ b/Dalamud/Fools/Helper/YesHealMe/Colors.cs @@ -1,31 +1,9 @@ using System.Numerics; -using ImGuiNET; namespace Dalamud.Fools.Helper.YesHealMe; public static class Colors { - public static Vector4 Purple = new(176 / 255.0f, 38 / 255.0f, 236 / 255.0f, 1.0f); - public static Vector4 Blue = new(37 / 255.0f, 168 / 255.0f, 1.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); + public static readonly Vector4 White = new(1.0f, 1.0f, 1.0f, 1.0f); + public static readonly Vector4 Black = new(0.0f, 0.0f, 0.0f, 1.0f); } diff --git a/Dalamud/Fools/Helper/YesHealMe/DrawUtilities.cs b/Dalamud/Fools/Helper/YesHealMe/DrawUtilities.cs index 38bc401ad..b9a571d9c 100644 --- a/Dalamud/Fools/Helper/YesHealMe/DrawUtilities.cs +++ b/Dalamud/Fools/Helper/YesHealMe/DrawUtilities.cs @@ -1,13 +1,13 @@ using System; using System.Numerics; using ImGuiNET; -using KamiLib.Caching; namespace Dalamud.Fools.Helper.YesHealMe; 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(); @@ -29,40 +29,44 @@ internal static class DrawUtilities 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); if (icon != null) { var drawList = ImGui.GetBackgroundDrawList(); - + var imagePadding = new Vector2(20.0f, 10.0f) * iconScale; var imageSize = new Vector2(50.0f, 50.0f) * iconScale; - + drawPosition += imagePadding; - + drawList.AddImage(icon.ImGuiHandle, drawPosition, drawPosition + imageSize); - - if (drawText) - { - 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; - - drawPosition.X -= textSize.X / 2.0f; - - TextOutlined(fontManager, drawPosition + textOffset, name, textScale / 2.75f, Colors.White); - } + + 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; + + drawPosition.X -= textSize.X / 2.0f; + + TextOutlined(fontManager, drawPosition + textOffset, name, textScale / 2.75f, Colors.White); } } 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 textSize = ImGui.CalcTextSize(text); @@ -73,18 +77,16 @@ internal static class DrawUtilities 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 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); } diff --git a/Dalamud/Fools/Helper/YesHealMe/FontManager.cs b/Dalamud/Fools/Helper/YesHealMe/FontManager.cs index d7ea88fd0..7c7244ba9 100644 --- a/Dalamud/Fools/Helper/YesHealMe/FontManager.cs +++ b/Dalamud/Fools/Helper/YesHealMe/FontManager.cs @@ -6,13 +6,13 @@ namespace Dalamud.Fools.Helper.YesHealMe; public class FontManager : IDisposable { - public GameFontHandle GameFont { get; } - 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() { this.GameFont.Dispose(); diff --git a/Dalamud/Fools/Helper/YesHealMe/HudHelper.cs b/Dalamud/Fools/Helper/YesHealMe/HudHelper.cs index 6de258c6e..1c11ee84c 100644 --- a/Dalamud/Fools/Helper/YesHealMe/HudHelper.cs +++ b/Dalamud/Fools/Helper/YesHealMe/HudHelper.cs @@ -1,40 +1,34 @@ -using Dalamud; -using Dalamud.Game.ClientState.Objects; +using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.SubKinds; using FFXIVClientStructs.FFXIV.Client.UI.Agent; -namespace NoTankYou.Utilities; +namespace Dalamud.Fools.Helper.YesHealMe; public static unsafe class HudHelper { private static AgentHUD* AgentHud => AgentModule.Instance()->GetAgentHUD(); - + public static PlayerCharacter? GetPlayerCharacter(int index) { // Sorta temporary, waiting for ClientStructs to merge a fixed size array for this element var partyMemberList = AgentHud->PartyMemberList; var targetOffset = index * sizeof(HudPartyMember); var targetAddress = partyMemberList + targetOffset; - var hudData = (HudPartyMember*) targetAddress; - + var hudData = (HudPartyMember*)targetAddress; + var targetPlayer = hudData->ObjectId; return GetPlayer(targetPlayer); } - - public static PlayerCharacter? GetAllianceMember(int index) - { - var targetPlayer = AgentHud->RaidMemberIds[index]; - - return GetPlayer(targetPlayer); - } private static PlayerCharacter? GetPlayer(uint objectId) { var result = Service.Get().SearchById(objectId); if (result?.GetType() == typeof(PlayerCharacter)) + { return result as PlayerCharacter; + } return null; } diff --git a/Dalamud/Fools/Helper/YesHealMe/IconCache.cs b/Dalamud/Fools/Helper/YesHealMe/IconCache.cs index 0a64d030e..6f82b0d7f 100644 --- a/Dalamud/Fools/Helper/YesHealMe/IconCache.cs +++ b/Dalamud/Fools/Helper/YesHealMe/IconCache.cs @@ -1,70 +1,71 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Dalamud; using Dalamud.Data; using Dalamud.Logging; using Dalamud.Utility; using ImGuiScene; -namespace KamiLib.Caching; +namespace Dalamud.Fools.Helper.YesHealMe; public class IconCache : IDisposable { - private readonly Dictionary iconTextures = new(); - private const string IconFilePath = "ui/icon/{0:D3}000/{1:D6}_hr1.tex"; - - private static IconCache? _instance; - public static IconCache Instance => _instance ??= new IconCache(); - - public static void Cleanup() + + private static IconCache? internalInstance; + private readonly Dictionary iconTextures = new(); + public static IconCache Instance => internalInstance ??= new IconCache(); + + public void Dispose() { - _instance?.Dispose(); - } - - public void Dispose() - { - foreach (var texture in iconTextures.Values) + foreach (var texture in this.iconTextures.Values) { 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 { var path = IconFilePath.Format(iconId / 1000, iconId); var tex = Service.Get().GetImGuiTexture(path); - if (tex is not null && tex.ImGuiHandle != nint.Zero) + if (tex is not null && tex.ImGuiHandle != nint.Zero) { - iconTextures[iconId] = tex; - } - else + this.iconTextures[iconId] = tex; + } + else { tex?.Dispose(); } - } - catch (Exception ex) + } + catch (Exception ex) { 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); - LoadIconTexture(iconId); + this.iconTextures.Add(iconId, null); + this.LoadIconTexture(iconId); - return iconTextures[iconId]; + return this.iconTextures[iconId]; } } diff --git a/Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs b/Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs index a2b106b40..29af9e483 100644 --- a/Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs +++ b/Dalamud/Fools/Helper/YesHealMe/PartyListAddon.cs @@ -2,66 +2,57 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Numerics; -using Dalamud; using Dalamud.Game; using Dalamud.Game.Gui; using FFXIVClientStructs.FFXIV.Client.UI; -using NoTankYou.DataModels; -using NoTankYou.Utilities; -namespace NoTankYou.System; +namespace Dalamud.Fools.Helper.YesHealMe; public unsafe class PartyListAddon : IEnumerable, IDisposable { - public record PartyFramePositionInfo(Vector2 Position, Vector2 Size, Vector2 Scale); - public IEnumerator GetEnumerator() => addonData.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - private static AddonPartyList* PartyList => (AddonPartyList*) Service.Get()?.GetAddonByName("_PartyList"); - public static bool DataAvailable => PartyList != null && PartyList->AtkUnitBase.RootNode != null; - private readonly List addonData = new(); public PartyListAddon() { - Service.Get().Update += OnFrameworkUpdate; + Service.Get().Update += this.OnFrameworkUpdate; } + private static AddonPartyList* PartyList => (AddonPartyList*)Service.Get()?.GetAddonByName("_PartyList"); + private static bool DataAvailable => PartyList != null && PartyList->AtkUnitBase.RootNode != null; + public void Dispose() { - Service.Get().Update -= OnFrameworkUpdate; + Service.Get().Update -= this.OnFrameworkUpdate; + } + + public IEnumerator GetEnumerator() + { + return this.addonData.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); } private void OnFrameworkUpdate(Framework framework) { - addonData.Clear(); - if (!DataAvailable) return; - if (PartyList->MemberCount <= 0) return; + this.addonData.Clear(); + if (!DataAvailable || PartyList->MemberCount <= 0) + { + return; + } foreach (var index in Enumerable.Range(0, PartyList->MemberCount)) { var playerCharacter = HudHelper.GetPlayerCharacter(index); var userInterface = PartyList->PartyMember[index]; - addonData.Add(new PartyListAddonData + this.addonData.Add(new PartyListAddonData { PlayerCharacter = playerCharacter, 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); - } } diff --git a/Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs b/Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs index b9989ab0b..0dbdd3913 100644 --- a/Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs +++ b/Dalamud/Fools/Helper/YesHealMe/PartyListAddonData.cs @@ -1,37 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using Dalamud.Game.ClientState.Objects.SubKinds; +using Dalamud.Game.ClientState.Objects.SubKinds; 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 TimeSinceLastTargetable = new(); - public AddonPartyList.PartyListMemberStruct UserInterface { 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; - } - } -} \ No newline at end of file +} diff --git a/Dalamud/Fools/Plugins/YesHealMePlugin.cs b/Dalamud/Fools/Plugins/YesHealMePlugin.cs index b33d24e0e..3e2b2c213 100644 --- a/Dalamud/Fools/Plugins/YesHealMePlugin.cs +++ b/Dalamud/Fools/Plugins/YesHealMePlugin.cs @@ -1,6 +1,5 @@ using Dalamud.Fools.Helper.YesHealMe; using Dalamud.Interface; -using NoTankYou.System; namespace Dalamud.Fools.Plugins; @@ -22,6 +21,7 @@ public class YesHealMePlugin : IFoolsPlugin { this.fontManager.Dispose(); this.partyListAddon.Dispose(); + IconCache.Cleanup(); } public void DrawUi() diff --git a/Dalamud/Fools/Plugins/YesHealMePluginWindow.cs b/Dalamud/Fools/Plugins/YesHealMePluginWindow.cs index 36dfc2a44..4bb30ab0d 100644 --- a/Dalamud/Fools/Plugins/YesHealMePluginWindow.cs +++ b/Dalamud/Fools/Plugins/YesHealMePluginWindow.cs @@ -1,16 +1,11 @@ using System.Collections.Generic; using System.Linq; using System.Numerics; -using Dalamud.Data; using Dalamud.Fools.Helper.YesHealMe; using Dalamud.Game.ClientState; 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 ImGuiNET; -using NoTankYou.System; namespace Dalamud.Fools.Plugins; @@ -84,7 +79,7 @@ public static class YesHealMePluginWindow var textSize = DrawUtilities.CalculateTextSize(fontManager, hurtingCharacter.Name.TextValue, Scale); var namePosition = new Vector2 { - X = healMePosition.X - textSize.X / 2.0f, + X = healMePosition.X - (textSize.X / 2.0f), Y = healMePosition.Y + textSize.Y, }; DrawUtilities.TextOutlined(