feat: add clearing settings
This commit is contained in:
parent
867203a86c
commit
e471548e81
@ -24,6 +24,8 @@ public class Configuration : IPluginConfiguration {
|
|||||||
public int TextMulRed = 100;
|
public int TextMulRed = 100;
|
||||||
public int TextMulGreen = 100;
|
public int TextMulGreen = 100;
|
||||||
public int TextMulBlue = 100;
|
public int TextMulBlue = 100;
|
||||||
|
public bool ClearResultsOnInactive = true;
|
||||||
|
public float ClearDelaySeconds = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MeterMode {
|
public enum MeterMode {
|
||||||
|
124
Plugin.cs
124
Plugin.cs
@ -3,11 +3,14 @@ using System.Globalization;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Dalamud.Game.Addon.Lifecycle;
|
using Dalamud.Game.Addon.Lifecycle;
|
||||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||||
|
using Dalamud.Game.Gui.ContextMenu;
|
||||||
|
using Dalamud.Game.Text;
|
||||||
using Dalamud.IoC;
|
using Dalamud.IoC;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Group;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
@ -37,14 +40,21 @@ public class Plugin : IDalamudPlugin {
|
|||||||
[PluginService]
|
[PluginService]
|
||||||
internal ICommandManager CommandManager { get; init; }
|
internal ICommandManager CommandManager { get; init; }
|
||||||
|
|
||||||
|
[PluginService]
|
||||||
|
internal IContextMenu ContextMenu { get; init; }
|
||||||
|
|
||||||
internal Configuration Config { get; }
|
internal Configuration Config { get; }
|
||||||
private Client Client { get; }
|
private Client Client { get; }
|
||||||
internal PluginUi Ui { get; }
|
internal PluginUi Ui { get; }
|
||||||
private Commands Commands { get; }
|
private Commands Commands { get; }
|
||||||
|
|
||||||
private Stopwatch Watch { get; } = Stopwatch.StartNew();
|
private Stopwatch AlternateWatch { get; } = Stopwatch.StartNew();
|
||||||
|
private Stopwatch DelayWatch { get; } = new();
|
||||||
private bool _ranLastTick;
|
private bool _ranLastTick;
|
||||||
private bool _showDps = true;
|
private bool _showDps = true;
|
||||||
|
private bool _reset;
|
||||||
|
private bool _wasActive;
|
||||||
|
private bool _manuallyReset = true;
|
||||||
|
|
||||||
private readonly byte[] _manaUsers = [
|
private readonly byte[] _manaUsers = [
|
||||||
6, // cnj
|
6, // cnj
|
||||||
@ -70,9 +80,11 @@ public class Plugin : IDalamudPlugin {
|
|||||||
this.Commands = new Commands(this);
|
this.Commands = new Commands(this);
|
||||||
|
|
||||||
this.AddonLifecycle!.RegisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList);
|
this.AddonLifecycle!.RegisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList);
|
||||||
|
this.ContextMenu!.OnMenuOpened += this.MenuOpened;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
|
this.ContextMenu.OnMenuOpened -= this.MenuOpened;
|
||||||
this.AddonLifecycle.UnregisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList);
|
this.AddonLifecycle.UnregisterListener(AddonEvent.PostUpdate, "_PartyList", this.UpdateList);
|
||||||
this.Commands.Dispose();
|
this.Commands.Dispose();
|
||||||
this.Ui.Dispose();
|
this.Ui.Dispose();
|
||||||
@ -83,24 +95,114 @@ public class Plugin : IDalamudPlugin {
|
|||||||
this.Interface.SavePluginConfig(this.Config);
|
this.Interface.SavePluginConfig(this.Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private unsafe void MenuOpened(IMenuOpenedArgs args) {
|
||||||
|
var add = args.AddonName == "_PartyList";
|
||||||
|
if (!add) {
|
||||||
|
var ctx = AgentContext.Instance();
|
||||||
|
if (args.AgentPtr != (nint) ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetId = ctx->TargetObjectId.ObjectId;
|
||||||
|
if (targetId == 0xE000_0000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.ClientState.LocalPlayer is { } player && player.GameObjectId == targetId) {
|
||||||
|
add = true;
|
||||||
|
} else {
|
||||||
|
var group = GroupManager.Instance()->GetGroup();
|
||||||
|
if (group != null && group->GetPartyMemberByEntityId(targetId) != null) {
|
||||||
|
add = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!add) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.AddMenuItem(new MenuItem {
|
||||||
|
Name = "Clear parse results",
|
||||||
|
Prefix = SeIconChar.BoxedLetterP,
|
||||||
|
PrefixColor = 37,
|
||||||
|
IsEnabled = this.Client.Data?.IsActive == false,
|
||||||
|
OnClicked = _ => {
|
||||||
|
this._reset = true;
|
||||||
|
this._manuallyReset = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private unsafe void UpdateList(AddonEvent type, AddonArgs args) {
|
private unsafe void UpdateList(AddonEvent type, AddonArgs args) {
|
||||||
var ranLast = this._ranLastTick;
|
var ranLast = this._ranLastTick;
|
||||||
this._ranLastTick = false;
|
this._ranLastTick = false;
|
||||||
var list = (AddonPartyList*) AtkStage.Instance()->RaptureAtkUnitManager->GetAddonByName("_PartyList");
|
var list = (AddonPartyList*) AtkStage.Instance()->RaptureAtkUnitManager->GetAddonByName("_PartyList");
|
||||||
if (!this.UpdateListInner(list) && ranLast) {
|
if (list == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shouldUpdate = false;
|
||||||
|
|
||||||
|
var wasActive = this._wasActive;
|
||||||
|
var becameInactive = false;
|
||||||
|
if (this.Client.Data is { } data) {
|
||||||
|
if (wasActive && !data.IsActive) {
|
||||||
|
becameInactive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._wasActive = data.IsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Client.Data is { IsActive: true }) {
|
||||||
|
shouldUpdate = true;
|
||||||
|
this._manuallyReset = false;
|
||||||
|
} else if (becameInactive) {
|
||||||
|
if (this.Config.ClearResultsOnInactive) {
|
||||||
|
this.DelayWatch.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Config.ClearResultsOnInactive && this.DelayWatch.IsRunning && this.DelayWatch.Elapsed >= TimeSpan.FromSeconds(this.Config.ClearDelaySeconds)) {
|
||||||
|
this.DelayWatch.Reset();
|
||||||
|
this._reset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._reset && !this._manuallyReset) {
|
||||||
|
// only do these checks if we shouldn't reset and if we're waiting for active data
|
||||||
|
|
||||||
|
// keep running if we're in the delay period
|
||||||
|
if (this.DelayWatch.IsRunning) {
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep running if the user wants to manually clear results
|
||||||
|
if (!this.Config.ClearResultsOnInactive) {
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._reset) {
|
||||||
|
this.DelayWatch.Reset();
|
||||||
|
this._reset = false;
|
||||||
|
this._manuallyReset = true;
|
||||||
|
this.ResetMembers(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldUpdate && this.UpdateListInner(list) && ranLast) {
|
||||||
this.ResetMembers(list);
|
this.ResetMembers(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the party list.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the list should be reset immediately</returns>
|
||||||
private unsafe bool UpdateListInner(AddonPartyList* list) {
|
private unsafe bool UpdateListInner(AddonPartyList* list) {
|
||||||
if (this.Client.Data is not { } data) {
|
if (this.Client.Data is not { } data) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.IsActive) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.ClientState.LocalPlayer is not { } player) {
|
if (this.ClientState.LocalPlayer is not { } player) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -109,7 +211,7 @@ public class Plugin : IDalamudPlugin {
|
|||||||
var playerName = player.Name.TextValue;
|
var playerName = player.Name.TextValue;
|
||||||
|
|
||||||
if (list->HoveredIndex >= 0 || list->TargetedIndex >= 0) {
|
if (list->HoveredIndex >= 0 || list->TargetedIndex >= 0) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var names = new List<(string, int)>();
|
var names = new List<(string, int)>();
|
||||||
@ -122,7 +224,7 @@ public class Plugin : IDalamudPlugin {
|
|||||||
|
|
||||||
// controller soft target not handled by hoveredindex above
|
// controller soft target not handled by hoveredindex above
|
||||||
if (chara->GetSoftTargetId() == member.EntityId) {
|
if (chara->GetSoftTargetId() == member.EntityId) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = MemoryHelper.ReadStringNullTerminated((nint) member.Name);
|
var name = MemoryHelper.ReadStringNullTerminated((nint) member.Name);
|
||||||
@ -131,8 +233,8 @@ public class Plugin : IDalamudPlugin {
|
|||||||
|
|
||||||
this._ranLastTick = true;
|
this._ranLastTick = true;
|
||||||
|
|
||||||
if (this.Watch.Elapsed.TotalMilliseconds > this.Config.AlternateSeconds * 1_000) {
|
if (this.AlternateWatch.Elapsed.TotalMilliseconds > this.Config.AlternateSeconds * 1_000) {
|
||||||
this.Watch.Restart();
|
this.AlternateWatch.Restart();
|
||||||
this._showDps ^= true;
|
this._showDps ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +252,7 @@ public class Plugin : IDalamudPlugin {
|
|||||||
this.UpdateMember(list->PartyMembers[i], member.Object, data.Encounter, combatant);
|
this.UpdateMember(list->PartyMembers[i], member.Object, data.Encounter, combatant);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void ResetMembers(AddonPartyList* list) {
|
private unsafe void ResetMembers(AddonPartyList* list) {
|
||||||
|
@ -75,7 +75,7 @@ public class PluginUi : IDisposable {
|
|||||||
this.Plugin.Config.TextColour = ConvertRgba(textColour);
|
this.Plugin.Config.TextColour = ConvertRgba(textColour);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.TreeNodeEx("Advanced colour options")) {
|
if (ImGui.TreeNodeEx("Advanced colour options##text")) {
|
||||||
using var treePop = new OnDispose(ImGui.TreePop);
|
using var treePop = new OnDispose(ImGui.TreePop);
|
||||||
|
|
||||||
anyChanged |= ImGui.SliderInt("Add red", ref this.Plugin.Config.TextAddRed, 0, 255);
|
anyChanged |= ImGui.SliderInt("Add red", ref this.Plugin.Config.TextAddRed, 0, 255);
|
||||||
@ -86,6 +86,11 @@ public class PluginUi : IDisposable {
|
|||||||
anyChanged |= ImGui.SliderInt("Multiply blue", ref this.Plugin.Config.TextMulBlue, 0, 100);
|
anyChanged |= ImGui.SliderInt("Multiply blue", ref this.Plugin.Config.TextMulBlue, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
anyChanged |= ImGui.Checkbox("Clear results after encounter ends", ref this.Plugin.Config.ClearResultsOnInactive);
|
||||||
|
using (ImGuiHelper.DisabledUnless(this.Plugin.Config.ClearResultsOnInactive)) {
|
||||||
|
anyChanged |= ImGui.SliderFloat("Seconds to delay before clearing", ref this.Plugin.Config.ClearDelaySeconds, 0, 300);
|
||||||
|
}
|
||||||
|
|
||||||
if (anyChanged) {
|
if (anyChanged) {
|
||||||
this.Plugin.SaveConfig();
|
this.Plugin.SaveConfig();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user