diff --git a/.gitignore b/.gitignore index ace3a58..10292e8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ packages/ bin/ obj/ Publish/ -Publish \ No newline at end of file +Publish +*.user diff --git a/BigPlayerDebuffs.cs b/BigPlayerDebuffs.cs index ca5dc1e..3761ba3 100644 --- a/BigPlayerDebuffs.cs +++ b/BigPlayerDebuffs.cs @@ -1,369 +1,311 @@ using System; -using System.Linq; using Dalamud.Plugin; -using System.Reflection; -using FFXIVClientStructs.Attributes; using FFXIVClientStructs.FFXIV.Component.GUI; - -using Dalamud.Hooking; -using Dalamud.Logging; using Dalamud.Game; using Dalamud.Game.Gui; -using Dalamud.Game.ClientState; -using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.Command; -using Dalamud.Game.ClientState.Objects; -using Dalamud.Game.ClientState.Objects.Types; -using Dalamud.Data; - -namespace BigPlayerDebuffs -{ - internal unsafe class Common { - public static DalamudPluginInterface PluginInterface { get; private set; } - public static GameGui GameGui { get; private set; } - - public Common(DalamudPluginInterface pluginInterface, GameGui gameGui) - { - PluginInterface = pluginInterface; - GameGui = gameGui; - } - public static AtkUnitBase* GetUnitBase(string name, int index = 1) - { - return (AtkUnitBase*)GameGui.GetAddonByName(name, index); - } - - public static T* GetUnitBase(string name = null, int index = 1) where T : unmanaged - { - if (string.IsNullOrEmpty(name)) - { - var attr = (Addon)typeof(T).GetCustomAttribute(typeof(Addon)); - if (attr != null) - { - name = attr.AddonIdentifiers.FirstOrDefault(); - } - } - - if (string.IsNullOrEmpty(name)) return null; - - return (T*)GameGui.GetAddonByName(name, index); - } - } +#if DEBUG +using Dalamud.Logging; +#endif - public class BigPlayerDebuffs: IDalamudPlugin { - public string Name => "BigPlayerDebuffs"; - - public static DalamudPluginInterface PluginInterface { get; private set; } - public static ClientState ClientState { get; private set; } - public static TargetManager TargetManager{ get; private set; } - public static Framework Framework { get; private set; } - public static GameGui GameGui { get; private set; } - public static CommandManager CommandManager { get; private set; } - public static ObjectTable Objects { get; private set; } - public static SigScanner SigScanner { get; private set; } - public static DataManager DataManager { get; private set; } - - public BigPlayerDebuffsConfig PluginConfig { get; private set; } - - private bool drawConfigWindow; - - internal Common common; - - int curSecondRowOffset = 41; - int curDebuffs = -1; - - public BigPlayerDebuffs( - DalamudPluginInterface pluginInterface, - ClientState clientState, - CommandManager commandManager, - Framework framework, - ObjectTable objects, - GameGui gameGui, - SigScanner sigScanner, - DataManager dataManager, - TargetManager targets - ) - { - PluginInterface = pluginInterface; - ClientState = clientState; - Framework = framework; - CommandManager = commandManager; - Objects = objects; - SigScanner = sigScanner; - DataManager = dataManager; - TargetManager = targets; - - this.common = new Common(pluginInterface, gameGui); - - this.PluginConfig = (BigPlayerDebuffsConfig)pluginInterface.GetPluginConfig() ?? new BigPlayerDebuffsConfig(); - this.PluginConfig.Init(this, pluginInterface); - - // Upgrade if config is too old - //try - //{ - // Config = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); - //} - //catch (Exception e) - //{ - // PluginLog.LogError("Error loading config", e); - // Config = new Configuration(); - // Config.Save(); - //} - //if (Config.Version == 0) - //{ - // PluginLog.Log("Old config version found"); - // Config = new Configuration(); - // Config.Save(); - //} - - PluginInterface.UiBuilder.Draw += this.BuildUI; - PluginInterface.UiBuilder.OpenConfigUi += this.OnOpenConfig; - Framework.Update += FrameworkOnUpdate; - SetupCommands(); +namespace BigPlayerDebuffs; - } +internal enum ChildEnumMode { + NextNext, + ChildNext, + PrevPrev, + ChildPrev, + ChildPrevPrev +}; - public void InvalidateState() - { - curDebuffs = -1; - curSecondRowOffset = -1; - UpdateTargetStatus(); - } +internal enum ChildEnumOrder { + ZeroForward, + MaxBackward +} +internal enum ElementType { + Status, + FocusStatus, + TargetStatus +} - public void Dispose() { - PluginInterface.UiBuilder.Draw -= this.BuildUI; - PluginInterface.UiBuilder.OpenConfigUi -= OnOpenConfig; +internal unsafe class UiElement { + public readonly string Name; + public readonly ElementType Type; - Framework.Update -= FrameworkOnUpdate; + private AtkUnitBase* element; + private readonly int childListPos; + private readonly ChildEnumMode enumMode; + private readonly ChildEnumOrder enumOrder; + private readonly GameGui gui; - ResetTargetStatus(); + public void Refresh() { + element = (AtkUnitBase*) gui.GetAddonByName(Name); + } - PluginInterface = null; - //Config = null; + public UiElement(string name, ElementType type, int childListIndex, ChildEnumMode mode, ChildEnumOrder order, GameGui gameGui) { + Name = name; + Type = type; + childListPos = childListIndex; + enumMode = mode; + enumOrder = order; + gui = gameGui; + Refresh(); + } - RemoveCommands(); - } + private bool Valid() => element is not null + && element->UldManager.NodeList is not null + && element->UldManager.NodeList[childListPos] is not null + && element->IsVisible; - //public void Initialize(DalamudPluginInterface pluginInterface) { - // this.PluginInterface = pluginInterface; - // this.PluginConfig = (BigPlayerDebuffsConfig) pluginInterface.GetPluginConfig() ?? new BigPlayerDebuffsConfig(); - // this.PluginConfig.Init(this, pluginInterface); + public AtkResNode* StatusList => element->UldManager.NodeList[childListPos]; - // this.common = new Common(pluginInterface); + public AtkResNode*[] Children { + get { + if (!Valid()) { + return new AtkResNode*[0]; + } + + var children = new AtkResNode*[StatusList->ChildCount]; + // TODO: Find a better method for determining child count that applies to both situations + if (children.Length == 0) { + // If the nodelist doesn't have a child count, we assume the res node we were given as our starting point + // is the last node before we begin seeing IconText Component Nodes + var totalCount = element->UldManager.NodeListCount - childListPos - 1; + if (totalCount < 0) { + return new AtkResNode*[0]; + } + else { + children = new AtkResNode*[totalCount]; + } + } + // Separate debuff does it a bit differently :\ + var child = enumMode switch { + ChildEnumMode.NextNext => StatusList->NextSiblingNode, + ChildEnumMode.ChildNext => StatusList->ChildNode, + ChildEnumMode.PrevPrev => StatusList->PrevSiblingNode, + ChildEnumMode.ChildPrev => StatusList->ChildNode, + ChildEnumMode.ChildPrevPrev => StatusList->ChildNode->PrevSiblingNode, + _ => throw new ArgumentOutOfRangeException(nameof(ChildEnumMode), + $"Unexpected enum value: {enumMode}") + }; + + // No children? No problem + if (child is null || (int) child == 0) { + return new AtkResNode*[0]; + } - // PluginInterface.UiBuilder.OnOpenConfigUi += (sender, args) => { - // this.drawConfigWindow = true; - // }; + // Reverse for MaxBackward + var i = enumOrder == ChildEnumOrder.MaxBackward ? children.Length - 1 : 0; - // PluginInterface.UiBuilder.OnBuildUi += this.BuildUI; + // soundness (index out of range) + // will error if the game lies to us about ChildCount + while (child is not null) { + var newIndex = enumOrder == ChildEnumOrder.MaxBackward ? i-- : i++; + #if DEBUG + try { + children[newIndex] = child; + } + catch (IndexOutOfRangeException e) { + PluginLog.Warning($"Index {i} outside of array with length {children.Length-1} for {Name}"); + } + #else + children[newIndex] = child; + #endif + + child = enumMode switch { + ChildEnumMode.NextNext => child->NextSiblingNode, + ChildEnumMode.ChildNext => child->NextSiblingNode, + ChildEnumMode.PrevPrev => child->PrevSiblingNode, + ChildEnumMode.ChildPrev => child->PrevSiblingNode, + ChildEnumMode.ChildPrevPrev => child->PrevSiblingNode, + _ => throw new ArgumentOutOfRangeException(nameof(ChildEnumMode), + $"Unexpected enum value: {enumMode}") + }; + } + // Note: The re-sorting we do here lets us avoid annoyances when iterating later + // because we no longer have to care what nuisances affect accessing the target + return children; + } + } +} - // PluginInterface.Framework.OnUpdateEvent += FrameworkOnUpdate; +// ReSharper disable once ClassNeverInstantiated.Global +public class BigPlayerDebuffs : IDalamudPlugin { + public string Name => "BigPlayerDebuffs"; + + private readonly DalamudPluginInterface pluginInterface; + private readonly Framework framework; + private readonly CommandManager commands; + + private readonly BigPlayerDebuffsConfig pluginConfig; + + private readonly UiElement[] uiElements; + + private bool drawConfigWindow; + + public BigPlayerDebuffs( + DalamudPluginInterface dalamudPluginInterface, + CommandManager commandManager, + Framework dalamudFramework, + GameGui gameGui + ) { + pluginInterface = dalamudPluginInterface; + commands = commandManager; + framework = dalamudFramework; + + pluginConfig = pluginInterface.GetPluginConfig() as BigPlayerDebuffsConfig ?? new BigPlayerDebuffsConfig(); + pluginConfig.Init(this, pluginInterface); + + // We have to supply .gui since unsafe classes are static + uiElements = new[] { + new UiElement("_TargetInfoBuffDebuff", ElementType.TargetStatus, 1, ChildEnumMode.ChildPrev, ChildEnumOrder.MaxBackward, gameGui), + new UiElement("_TargetInfo", ElementType.TargetStatus, 2, ChildEnumMode.NextNext, ChildEnumOrder.ZeroForward, gameGui), + new UiElement("_FocusTargetInfo", ElementType.FocusStatus, 3, ChildEnumMode.NextNext, ChildEnumOrder.ZeroForward, gameGui), + new UiElement("_Status", ElementType.Status, 0, ChildEnumMode.ChildPrev, ChildEnumOrder.MaxBackward, gameGui), + new UiElement("_StatusCustom0", ElementType.Status, 4, ChildEnumMode.PrevPrev, ChildEnumOrder.MaxBackward, gameGui), + new UiElement("_StatusCustom1", ElementType.Status, 4, ChildEnumMode.PrevPrev, ChildEnumOrder.MaxBackward, gameGui), + new UiElement("_StatusCustom2", ElementType.Status, 4, ChildEnumMode.PrevPrev, ChildEnumOrder.MaxBackward, gameGui), + new UiElement("_StatusCustom3", ElementType.Status, 3, ChildEnumMode.PrevPrev, ChildEnumOrder.MaxBackward, gameGui) + }; + + // Wire up + pluginInterface.UiBuilder.Draw += BuildUi; + pluginInterface.UiBuilder.OpenConfigUi += OnOpenConfig; + framework.Update += FrameworkOnUpdate; + SetupCommands(); + } - // SetupCommands(); - //} + public void Dispose() { + // Remove hooks + pluginInterface.UiBuilder.Draw -= BuildUi; + pluginInterface.UiBuilder.OpenConfigUi -= OnOpenConfig; + framework.Update -= FrameworkOnUpdate; + RemoveCommands(); + // Reset changes + ResetTargetStatus(); + } - private void FrameworkOnUpdate(Framework framework) - { + private void FrameworkOnUpdate(Framework _) { #if DEBUG - try - { - UpdateTargetStatus(); - } - catch (Exception ex) - { - PluginLog.Error(ex.ToString()); - } + try { + UpdateTargetStatus(); + } + catch (Exception ex) { + PluginLog.Error(ex.ToString()); + } #else UpdateTargetStatus(); #endif - } + } - private unsafe void UpdateTargetStatus() - { - - //var targetGameObject = TargetManager.Target; - if (TargetManager.Target is BattleChara target) - { - - var playerAuras = 0; - - //PluginLog.Log($"StatusEffects.Length {target.StatusEffects.Length}"); // Always 30 - - var localPlayerId = ClientState.LocalPlayer?.ObjectId; - for (var i = 0; i < 30; i++) - { - if (target.StatusList[i].SourceId == localPlayerId) playerAuras++; - } - //PluginLog.Log($"Player Auras old:{this.curDebuffs} new: {playerAuras}"); - - if (this.curDebuffs != playerAuras) { - - //PluginLog.Log($"Updating..."); - - var playerScale = this.PluginConfig.bScale; - - var targetInfoUnitBase = Common.GetUnitBase("_TargetInfo", 1); - if (targetInfoUnitBase == null) return; - if (targetInfoUnitBase->UldManager.NodeList == null || targetInfoUnitBase->UldManager.NodeListCount < 53) return; - - var targetInfoStatusUnitBase = Common.GetUnitBase("_TargetInfoBuffDebuff", 1); - if (targetInfoStatusUnitBase == null) return; - if (targetInfoStatusUnitBase->UldManager.NodeList == null || targetInfoStatusUnitBase->UldManager.NodeListCount < 32) return; - - this.curDebuffs = playerAuras; - - var adjustOffsetY = -(int)(41 * (playerScale-1.0f)/4.5); - - var xIncrement = (int)((playerScale - 1.0f) * 25); - - // Split Target Frame - - var growingOffsetX = 0; - for (var i = 0; i < 15; i++) - { - var node = targetInfoStatusUnitBase->UldManager.NodeList[31 - i]; - node->X = i * 25 + growingOffsetX; - - if (i < playerAuras) - { - node->ScaleX = playerScale; - node->ScaleY = playerScale; - node->Y = adjustOffsetY; - growingOffsetX += xIncrement; - } - else - { - node->ScaleX = 1.0f; - node->ScaleY = 1.0f; - node->Y = 0; - } - node->Flags_2 |= 0x1; // 0x1 flag i'm guessing recalculates only for this node - } - - // Merged Target Frame - - growingOffsetX = 0; - for (var i = 0; i < 15; i++) - { - var node = targetInfoUnitBase->UldManager.NodeList[32 - i]; - node->X = i * 25 + growingOffsetX; - - if (i < playerAuras) - { - node->ScaleX = playerScale; - node->ScaleY = playerScale; - node->Y = adjustOffsetY; - growingOffsetX += xIncrement; - } - else - { - node->ScaleX = 1.0f; - node->ScaleY = 1.0f; - node->Y = 0; - } - node->Flags_2 |= 0x1; - } - - /////////////////// - - var newSecondRowOffset = (playerAuras > 0) ? (int)(playerScale*41) : 41; - - if (newSecondRowOffset != this.curSecondRowOffset) - { - // Split Target Frame Second Row - for (var i = 16; i >= 2; i--) - { - targetInfoStatusUnitBase->UldManager.NodeList[i]->Y = newSecondRowOffset; - targetInfoStatusUnitBase->UldManager.NodeList[i]->Flags_2 |= 0x1; - } - // Merged Target Frame Second Row - for (var i = 17; i >= 3; i--) - { - targetInfoUnitBase->UldManager.NodeList[i]->Y = newSecondRowOffset; - targetInfoUnitBase->UldManager.NodeList[i]->Flags_2 |= 0x1; - } - this.curSecondRowOffset = newSecondRowOffset; - } - - // Setting 0x4 flag on the root element to recalculate the scales down the tree - targetInfoStatusUnitBase->UldManager.NodeList[1]->Flags_2 |= 0x4; - targetInfoStatusUnitBase->UldManager.NodeList[1]->Flags_2 |= 0x1; - targetInfoUnitBase->UldManager.NodeList[2]->Flags_2 |= 0x4; - targetInfoUnitBase->UldManager.NodeList[2]->Flags_2 |= 0x1; + private unsafe void UpdateTargetStatus() { + // The actual width and height of the tokens don't matter, they're always 25 apart. + // e.g. the aspected benefit icon is 24px wide, but the second slot is still at [25, 41] + const int slotWidth = 25; + const int slotHeight = 41; + + + //PluginLog.Log($"Updating..."); + foreach (var element in uiElements) { + element.Refresh(); + var playerScale = pluginConfig.bScale; + switch (element.Type) { + case ElementType.TargetStatus when pluginConfig.IncludeMainTarget: + break; + case ElementType.FocusStatus when pluginConfig.IncludeFocusTarget: + playerScale = pluginConfig.FocusScale; + break; + case ElementType.Status when pluginConfig.IncludeBuffBar: + playerScale = pluginConfig.BarScale; + break; + default: + continue; + } + var children = element.Children; + var xOffsets = new[] {0f, 0f}; + // Poor man's IEnumerable, but that's life with unsafe + for (var childIndex = 0; childIndex < children.Length; childIndex++) { + var child = children[childIndex]; + var textComponent = (AtkTextNode*) child->GetComponent()->GetTextNodeById(2); + var row = childIndex < 15 ? 0 : 1; + ref var xOffset = ref xOffsets[row]; + // TODO: find a check that isn't a lazy hack + var isOwnStatus = textComponent->TextColor is not {R: 255, G: 255, B: 255, A: 255}; + var scalar = isOwnStatus ? playerScale : 1.0f; + child->ScaleX = scalar; + child->ScaleY = scalar; + child->X = childIndex % 15 * slotWidth; + child->Y = row == 0 ? 0 : slotHeight; + + // Add in our running shift value + child->X += xOffset; + // If we're on the second row, factor in if the first row has shifted + if (row > 0 && xOffset > 0f) { + child->Y *= playerScale; + } + // We bump the Y offset a bit for our changed icons + if (isOwnStatus) { + // Add the difference between an unscaled and a scaled icon to our running total + xOffset += slotWidth * playerScale - slotWidth; + // Y pos gets shifted slightly to match the top part of the unscaled icons + child->Y = (slotHeight * playerScale - slotHeight) / -(slotHeight / 2); } - } + // Set update flag + child->Flags_2 |= 0x1; + // We could step this out but then we have to add null checks and stuff + element.StatusList->Flags_2 |= 0x4; + element.StatusList->Flags_2 |= 0x1; + } } + } - private unsafe void ResetTargetStatus() - { - var targetInfoUnitBase = Common.GetUnitBase("_TargetInfo", 1); - if (targetInfoUnitBase == null) return; - if (targetInfoUnitBase->UldManager.NodeList == null || targetInfoUnitBase->UldManager.NodeListCount < 53) return; - - var targetInfoStatusUnitBase = Common.GetUnitBase("_TargetInfoBuffDebuff", 1); - if (targetInfoStatusUnitBase == null) return; - if (targetInfoStatusUnitBase->UldManager.NodeList == null || targetInfoStatusUnitBase->UldManager.NodeListCount < 32) return; - - for (var i = 0; i < 15; i++) - { - var node = targetInfoStatusUnitBase->UldManager.NodeList[31 - i]; - node->ScaleX = 1.0f; - node->ScaleY = 1.0f; - node->X = i * 25; - node->Y = 0; - node->Flags_2 |= 0x1; - - node = targetInfoUnitBase->UldManager.NodeList[32 - i]; - node->ScaleX = 1.0f; - node->ScaleY = 1.0f; - node->X = i * 25; - node->Y = 0; - node->Flags_2 |= 0x1; - } - for (var i = 17; i >= 2; i--) - { - targetInfoStatusUnitBase->UldManager.NodeList[i]->Y = 41; - targetInfoStatusUnitBase->UldManager.NodeList[i]->Flags_2 |= 0x1; - } - for (var i = 18; i >= 3; i--) - { - targetInfoUnitBase->UldManager.NodeList[i]->Y = 41; - targetInfoUnitBase->UldManager.NodeList[i]->Flags_2 |= 0x1; + public unsafe void ResetTargetStatus() { + foreach (var element in uiElements) { + element.Refresh(); + var children = element.Children; + // Poor man's IEnumerable, but that's life with unsafe + for (var childIndex = 0; childIndex < children.Length; childIndex++) { + var child = children[childIndex]; + child->ScaleX = 1.0f; + child->ScaleY = 1.0f; + child->X = childIndex % 15 * child->Width; + child->Y = childIndex < 15 ? 0 : child->Height; + // Set update flag + child->Flags_2 |= 0x1; } - targetInfoStatusUnitBase->UldManager.NodeList[1]->Flags_2 |= 0x4; - targetInfoUnitBase->UldManager.NodeList[2]->Flags_2 |= 0x4; + element.StatusList->Flags_2 |= 0x4; + element.StatusList->Flags_2 |= 0x1; } + } + private void SetupCommands() { + commands.AddHandler("/bigplayerdebuffs", new CommandInfo(OnConfigCommandHandler) { + HelpMessage = $"Open config window for {Name}", + ShowInHelp = true + }); + } - public void SetupCommands() { - CommandManager.AddHandler("/bigplayerdebuffs", new Dalamud.Game.Command.CommandInfo(OnConfigCommandHandler) { - HelpMessage = $"Open config window for {this.Name}", - ShowInHelp = true - }); - } - - private void OnOpenConfig() - { - drawConfigWindow = true; - } + private void OnOpenConfig() { + drawConfigWindow = true; + } - public void OnConfigCommandHandler(string command, string args) { - drawConfigWindow = !drawConfigWindow; - } + private void OnConfigCommandHandler(string command, string args) { + drawConfigWindow = !drawConfigWindow; + } - public void RemoveCommands() { - CommandManager.RemoveHandler("/bigplayerdebuffs"); - } + private void RemoveCommands() { + commands.RemoveHandler("/bigplayerdebuffs"); + } - private void BuildUI() { - drawConfigWindow = drawConfigWindow && PluginConfig.DrawConfigUI(); - } + private void BuildUi() { + drawConfigWindow = drawConfigWindow && pluginConfig.DrawConfigUi(); } -} +} \ No newline at end of file diff --git a/BigPlayerDebuffs.csproj b/BigPlayerDebuffs.csproj index d03dabf..10142dc 100644 --- a/BigPlayerDebuffs.csproj +++ b/BigPlayerDebuffs.csproj @@ -1,63 +1,63 @@ - - - - 1.1.0.8 - Scales up buffs/debuffs applied by you on Target Status frames - - https://github.com/rgd87/BigPlayerDebuffs - + + + + 1.1.0.8 + Scales up buffs/debuffs applied by you on Target Status frames + + https://github.com/rgd87/BigPlayerDebuffs + - - net7.0 - x64 - enable - latest - true - false - false - true - + + net7.0-windows + x64 + enable + latest + true + false + false + true + - - $(appdata)\XIVLauncher\addon\Hooks\dev\ - + + $(appdata)\XIVLauncher\addon\Hooks\dev\ + - - x64 - + + x64 + - - - - $(DalamudLibPath)FFXIVClientStructs.dll - false - - - $(DalamudLibPath)Newtonsoft.Json.dll - false - - - $(DalamudLibPath)Dalamud.dll - false - - - $(DalamudLibPath)ImGui.NET.dll - false - - - $(DalamudLibPath)ImGuiScene.dll - false - - - $(DalamudLibPath)Lumina.dll - false - - - $(DalamudLibPath)Lumina.Excel.dll - false - - + + + + $(DalamudLibPath)FFXIVClientStructs.dll + false + + + $(DalamudLibPath)Newtonsoft.Json.dll + false + + + $(DalamudLibPath)Dalamud.dll + false + + + $(DalamudLibPath)ImGui.NET.dll + false + + + $(DalamudLibPath)ImGuiScene.dll + false + + + $(DalamudLibPath)Lumina.dll + false + + + $(DalamudLibPath)Lumina.Excel.dll + false + + diff --git a/BigPlayerDebuffsConfig.cs b/BigPlayerDebuffsConfig.cs index 8d65a8e..d8a4477 100644 --- a/BigPlayerDebuffsConfig.cs +++ b/BigPlayerDebuffsConfig.cs @@ -2,66 +2,101 @@ using Dalamud.Plugin; using ImGuiNET; using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Numerics; -using Dalamud.Game.Text; - -namespace BigPlayerDebuffs -{ - public class RouletteConfig { - public bool Enabled; - public bool Tank; - public bool Healer; - public bool DPS; - } - - public class BigPlayerDebuffsConfig : IPluginConfiguration { - [NonSerialized] - private DalamudPluginInterface pluginInterface; - - [NonSerialized] - private BigPlayerDebuffs plugin; - - //[NonSerialized] private bool showWebhookWindow; - public int Version { get; set; } +namespace BigPlayerDebuffs; - public float bScale = 1.4f; - - - public void Init(BigPlayerDebuffs plugin, DalamudPluginInterface pluginInterface) { - this.plugin = plugin; - this.pluginInterface = pluginInterface; - } +public class BigPlayerDebuffsConfig : IPluginConfiguration { + [NonSerialized] private DalamudPluginInterface pluginInterface = null!; - public void Save() { - pluginInterface.SavePluginConfig(this); - plugin.InvalidateState(); - } + [NonSerialized] private BigPlayerDebuffs plugin = null!; - public bool DrawConfigUI() { - var drawConfig = true; + //[NonSerialized] private bool showWebhookWindow; - var scale = ImGui.GetIO().FontGlobalScale; + public int Version { get; set; } - var modified = false; + // What does the 'b' mean? Should be named something like TargetScale but config compatibility /shrug + // ReSharper disable once InconsistentNaming + public float bScale = 1.4f; + public float FocusScale = 1.25f; + public float BarScale = 1.25f; + public bool IncludeMainTarget = true; + public bool IncludeFocusTarget = true; + public bool IncludeBuffBar = false; - ImGui.SetNextWindowSize(new Vector2(500 * scale, 350), ImGuiCond.FirstUseEver); - ImGui.SetNextWindowSizeConstraints(new Vector2(500 * scale, 350), new Vector2(560 * scale, 650)); - ImGui.Begin($"{plugin.Name} Config", ref drawConfig, ImGuiWindowFlags.NoCollapse); + public void Init(BigPlayerDebuffs ownPlugin, DalamudPluginInterface dalamudPluginInterface) { + plugin = ownPlugin; + pluginInterface = dalamudPluginInterface; + } - modified |= ImGui.SliderFloat("Own Buff/Debuff Scale", ref bScale, 1.0F, 2.0F); + private void Save() { + pluginInterface.SavePluginConfig(this); + } - ImGui.End(); + public bool DrawConfigUi() { + var drawConfig = true; + var scale = ImGui.GetIO().FontGlobalScale; - if (modified) - { - Save(); - } + var modified = false; - return drawConfig; + ImGui.SetNextWindowSize(new Vector2(550, 120) * scale, ImGuiCond.FirstUseEver); + ImGui.SetNextWindowSizeConstraints(new Vector2(550, 110), new Vector2(1100, 650) * scale); + ImGui.Begin($"{plugin.Name} Configuration", ref drawConfig, ImGuiWindowFlags.NoCollapse); + + #region Target + + ImGui.BeginGroup(); + modified |= ImGui.Checkbox("##Enable scaling in Target UI", ref IncludeMainTarget); + if (ImGui.IsItemHovered()) { + ImGui.SetTooltip("Enable scaling in target UI"); + } + ImGui.SameLine(); + ImGui.BeginDisabled(!IncludeMainTarget); + modified |= ImGui.SliderFloat("Scale in Target UI", ref bScale, 1.0F, 2.0F, "%.2f"); + ImGui.EndDisabled(); + ImGui.EndGroup(); + + #endregion + #region FocusTarget + + ImGui.BeginGroup(); + modified |= ImGui.Checkbox("##Enable scaling in Focus Target UI", ref IncludeFocusTarget); + if (ImGui.IsItemHovered()) { + ImGui.SetTooltip("Enable scaling in focus target UI"); } + ImGui.SameLine(); + ImGui.BeginDisabled(!IncludeFocusTarget); + modified |= ImGui.SliderFloat("Scale in Focus Target UI", ref FocusScale, 1.0F, 2.0F, "%.2f"); + ImGui.EndDisabled(); + ImGui.EndGroup(); + + #endregion + #region BuffBar + + ImGui.BeginGroup(); + modified |= ImGui.Checkbox("##Enable scaling in own buff/debuff display", ref IncludeBuffBar); + if (ImGui.IsItemHovered()) { + ImGui.SetTooltip("Enable scaling in own buff/debuff display"); + } + ImGui.SameLine(); + ImGui.BeginDisabled(!IncludeBuffBar); + modified |= ImGui.SliderFloat("Scale in self buff bar", ref BarScale, 1.0F, 2.0F, "%.2f"); + ImGui.EndDisabled(); + ImGui.EndGroup(); + + #endregion + + // Hint and end + ImGui.Text("Hint: Ctrl+Click a slider to input a number directly"); + ImGui.End(); + + + if (modified) { + plugin.ResetTargetStatus(); + Save(); + } + + return drawConfig; } } \ No newline at end of file diff --git a/packages.lock.json b/packages.lock.json index ce366a3..2426061 100644 --- a/packages.lock.json +++ b/packages.lock.json @@ -1,7 +1,7 @@ { "version": 1, "dependencies": { - "net7.0": { + "net7.0-windows7.0": { "DalamudPackager": { "type": "Direct", "requested": "[2.1.10, )",