From 92737631876c80c227e4a200bd805859f82e6eaa Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 24 Jul 2024 23:49:23 -0400 Subject: [PATCH] feat: more progress --- Plugin.cs | 188 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 162 insertions(+), 26 deletions(-) diff --git a/Plugin.cs b/Plugin.cs index c5f358d..5092c84 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,9 +1,21 @@ -using Dalamud.IoC; +using System.Diagnostics; +using System.Globalization; +using System.Numerics; +using Dalamud.Game.Addon.Lifecycle; +using Dalamud.Game.Addon.Lifecycle.AddonArgTypes; +using Dalamud.IoC; +using Dalamud.Memory; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Group; +using FFXIVClientStructs.FFXIV.Client.Game.UI; +using FFXIVClientStructs.FFXIV.Client.Graphics; using FFXIVClientStructs.FFXIV.Client.UI; +using FFXIVClientStructs.FFXIV.Client.UI.Agent; +using FFXIVClientStructs.FFXIV.Client.UI.Info; using FFXIVClientStructs.FFXIV.Component.GUI; +using ImGuiNET; namespace PartyDamage; @@ -11,25 +23,91 @@ public class Plugin : IDalamudPlugin { [PluginService] internal static IPluginLog Log { get; private set; } + [PluginService] + private IAddonLifecycle AddonLifecycle { get; init; } + [PluginService] private IClientState ClientState { get; init; } [PluginService] private IFramework Framework { get; init; } + [PluginService] + private IPartyList PartyList { get; init; } + + [PluginService] + private IDalamudPluginInterface Interface { get; init; } + private Client Client { get; } public Plugin() { this.Client = new Client(); - this.Framework!.Update += this.OnFramework; + this.AddonLifecycle!.RegisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList); + // this.Interface!.UiBuilder.Draw += this.Draw; } public void Dispose() { - this.Framework!.Update -= this.OnFramework; + // this.Interface.UiBuilder.Draw -= this.Draw; + this.AddonLifecycle.UnregisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList); this.Client.Dispose(); } - private unsafe void OnFramework(IFramework framework) { + private unsafe void Draw() { + if (this.Client.Data is not { } data) { + return; + } + + var names = new List(); + foreach (var member in AgentHUD.Instance()->PartyMembers) { + if (member.Name == null) { + continue; + } + + var name = MemoryHelper.ReadStringNullTerminated((nint) member.Name); + names.Add(name); + } + + var list = (AddonPartyList*) AtkStage.Instance()->RaptureAtkUnitManager->GetAddonByName("_PartyList"); + foreach (var combatant in data.Combatants.Values) { + var idx = combatant.Name == "YOU" + ? 0 + : names.IndexOf(combatant.Name); + if (idx == -1) { + continue; + } + + var dpsText = combatant.EncDps switch { + float.NaN => "?", + float.PositiveInfinity => "0", + float.NegativeInfinity => "0", + < 1_000 => combatant.EncDps.ToString("N1"), + < 1_000_000 => $"{combatant.EncDps / 1_000:N1}K", + < 1_000_000_000 => $"{combatant.EncDps / 1_000_000:N1}M", + _ => combatant.EncDps.ToString("N1"), + }; + + var gauge = list->PartyMembers[idx].MPGaugeBar->OwnerNode; + var pos = new Vector2( + gauge->ScreenX + gauge->Width, + gauge->ScreenY + gauge->Height / 2f + 8 + ); + var size = ImGui.CalcTextSize(dpsText); + ImGui.GetBackgroundDrawList().AddRectFilled( + pos - Vector2.One * 2, + pos + size + Vector2.One * 2, + 0xFF000000 + ); + ImGui.GetBackgroundDrawList().AddText( + pos, + 0xFFFFFFFF, + dpsText + ); + } + } + + private Stopwatch Watch { get; } = Stopwatch.StartNew(); + + private unsafe void UpdateList(AddonEvent type, AddonArgs args) { if (this.Client.Data is not { } data) { return; } @@ -38,25 +116,35 @@ public class Plugin : IDalamudPlugin { return; } - var list = (AddonPartyList*) AtkStage.Instance()->RaptureAtkUnitManager->GetAddonByName("_PartyList"); + var chara = (Character*) player.Address; - var names = new List(); - var group = GroupManager.Instance()->GetGroup(); - if (group == null) { - Plugin.Log.Info("group null"); + var list = (AddonPartyList*) AtkStage.Instance()->RaptureAtkUnitManager->GetAddonByName("_PartyList"); + if (list->HoveredIndex >= 0 || list->TargetedIndex >= 0) { + return; } - for (var i = 0; i < group->MemberCount; i++) { - names.Add(group->PartyMembers[i].NameString); + var names = new List(); + foreach (var member in AgentHUD.Instance()->PartyMembers) { + if (member.Name == null) { + continue; + } + + // controller soft target not handled by hoveredindex above + if (chara->GetSoftTargetId() == member.EntityId) { + return; + } + + var name = MemoryHelper.ReadStringNullTerminated((nint) member.Name); + names.Add(name); } var numPlayers = list->PartyMembers.Length; foreach (var combatant in data.Combatants.Values) { if (combatant.Name.EndsWith(" (YOU)")) { var name = combatant.Name[..^6]; - var nameNode = list->Pet.Name; - if (nameNode != null && nameNode->NodeText.ToString() == name) { - this.UpdateMember(list->Pet, combatant); + var chocoboName = UIState.Instance()->Buddy.CompanionInfo.NameString; + if (chocoboName == name) { + this.UpdateMember(list->Chocobo, data.Encounter, combatant); continue; } } @@ -68,21 +156,69 @@ public class Plugin : IDalamudPlugin { continue; } - this.UpdateMember(list->PartyMembers[idx], combatant); + this.UpdateMember(list->PartyMembers[idx], data.Encounter, combatant); } } - private unsafe void UpdateMember(AddonPartyList.PartyListMemberStruct member, Combatant combatant) { - var dpsText = combatant.EncDps switch { - float.NaN => "?", - float.PositiveInfinity => "0", - float.NegativeInfinity => "0", - < 1_000 => combatant.EncDps.ToString("N1"), - < 1_000_000 => $"{combatant.EncDps / 1_000:N1}K", - < 1_000_000_000 => $"{combatant.EncDps / 1_000_000:N1}M", - _ => combatant.EncDps.ToString("N1"), - }; + private unsafe void UpdateMember(AddonPartyList.PartyListMemberStruct member, Encounter encounter, Combatant combatant) { + member.TargetGlow->ToggleVisibility(true); + member.TargetGlow->SetAlpha(128); + member.TargetGlow->SetScaleX( + encounter.EncDps == 0 + ? 0 + : combatant.EncDps / encounter.EncDps + ); - member.Name->SetText(dpsText); + var left = (AtkTextNode*) member.MPGaugeBar->GetTextNodeById(2); + var right = (AtkTextNode*) member.MPGaugeBar->GetTextNodeById(3); + + if (this.Watch.Elapsed.Seconds % 6 < 3) { + left->TextColor = new ByteColor { + RGBA = 0xFFFFFFFF, + }; + right->TextColor = left->TextColor; + + return; + } + + left->TextColor = new ByteColor { + RGBA = 0xedffecff, + }; + right->TextColor = left->TextColor; + + if (combatant.EncDps == 0 || float.IsInfinity(combatant.EncDps) || float.IsNaN(combatant.EncDps)) { + left->SetText("0."); + right->SetText("00"); + } else if (combatant.EncDps < 1_000) { + var dps = Math.Round(combatant.EncDps * 100).ToString(CultureInfo.InvariantCulture); + left->SetText($"{dps[..^2]}."); + right->SetText(dps[^2..]); + } else if (combatant.EncDps < 1_000_000) { + var dps = Math.Round(combatant.EncDps / 100).ToString(CultureInfo.InvariantCulture); + left->SetText($"{dps[..^1]}."); + right->SetText($"{dps[^1..]}K"); + } + + // var dpsText = combatant.EncDps switch { + // float.NaN => "?", + // float.PositiveInfinity => "0", + // float.NegativeInfinity => "0", + // < 1_000 => combatant.EncDps.ToString("N1"), + // < 1_000_000 => $"{combatant.EncDps / 1_000:N1}K", + // < 1_000_000_000 => $"{combatant.EncDps / 1_000_000:N1}M", + // _ => combatant.EncDps.ToString("N1"), + // }; + + // if (!member.CastingProgressBar->IsVisible()) { + // member.CastingActionName->ToggleVisibility(true); + // member.CastingActionName->SetText(dpsText); + // float x, y; + // member.CastingActionName->GetPositionFloat(&x, &y); + // member.CastingActionName->SetPositionFloat(200, 32); + // member.CastingActionName->AlignmentType = AlignmentType.Left; + // } else { + // member.CastingActionName->AlignmentType = AlignmentType.Right; + // member.CastingActionName->SetPositionFloat(0, 10); + // } } }