v1.0.8.14: Mouse GCD Indicator (ring around cursor)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
using HSUI.Config;
|
||||
using HSUI.Config.Attributes;
|
||||
using HSUI.Enums;
|
||||
using System.Numerics;
|
||||
|
||||
namespace HSUI.Interface.GeneralElements
|
||||
{
|
||||
[DisableParentSettings("Position")]
|
||||
[Section("Other Elements")]
|
||||
[SubSection("Mouse GCD Indicator", 0)]
|
||||
public class MouseGCDIndicatorConfig : MovablePluginConfigObject
|
||||
{
|
||||
[Checkbox("Always Show")]
|
||||
[Order(3)]
|
||||
public bool AlwaysShow = false;
|
||||
|
||||
[ColorEdit4("Background Color")]
|
||||
[Order(16)]
|
||||
public PluginConfigColor BackgroundColor = new PluginConfigColor(new Vector4(0f / 255f, 0f / 255f, 0f / 255f, 50f / 100f));
|
||||
|
||||
[ColorEdit4("Color")]
|
||||
[Order(17)]
|
||||
public PluginConfigColor FillColor = new PluginConfigColor(new(220f / 255f, 220f / 255f, 220f / 255f, 100f / 100f));
|
||||
|
||||
[Checkbox("Show Border")]
|
||||
[Order(18)]
|
||||
public bool ShowBorder = true;
|
||||
|
||||
[Checkbox("Instant GCDs only", spacing = true)]
|
||||
[Order(19)]
|
||||
public bool InstantGCDsOnly = false;
|
||||
|
||||
[Checkbox("Only show when under GCD Threshold", spacing = true)]
|
||||
[Order(20)]
|
||||
public bool LimitGCDThreshold = false;
|
||||
|
||||
[DragFloat("GCD Threshold", velocity = 0.01f)]
|
||||
[Order(21, collapseWith = nameof(LimitGCDThreshold))]
|
||||
public float GCDThreshold = 1.50f;
|
||||
|
||||
[Checkbox("Show GCD Queue Indicator", spacing = true)]
|
||||
[Order(24)]
|
||||
public bool ShowGCDQueueIndicator = true;
|
||||
|
||||
[ColorEdit4("GCD Queue Color")]
|
||||
[Order(25, collapseWith = nameof(ShowGCDQueueIndicator))]
|
||||
public PluginConfigColor QueueColor = new PluginConfigColor(new(13f / 255f, 207f / 255f, 31f / 255f, 100f / 100f));
|
||||
|
||||
[DragInt("Radius")]
|
||||
[Order(35)]
|
||||
public int CircleRadius = 40;
|
||||
|
||||
[DragInt("Thickness")]
|
||||
[Order(40)]
|
||||
public int CircleThickness = 10;
|
||||
|
||||
[DragInt("Start Angle", min = 0, max = 359)]
|
||||
[Order(45)]
|
||||
public int CircleStartAngle = 0;
|
||||
|
||||
[Checkbox("Rotate CCW")]
|
||||
[Order(50)]
|
||||
public bool RotateCCW = false;
|
||||
|
||||
[DragInt2("Cursor Center Offset", min = -64, max = 64)]
|
||||
[Order(55)]
|
||||
public Vector2 CursorCenterOffset = new Vector2(8, 16);
|
||||
|
||||
[NestedConfig("Visibility", 70)]
|
||||
public VisibilityConfig VisibilityConfig = new VisibilityConfig();
|
||||
|
||||
public new static MouseGCDIndicatorConfig DefaultConfig() { return new MouseGCDIndicatorConfig() { Enabled = false, Strata = StrataLevel.MID_HIGH }; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using HSUI.Helpers;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using HSUI.Config;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace HSUI.Interface.GeneralElements
|
||||
{
|
||||
public class MouseGCDIndicatorHud : DraggableHudElement, IHudElementWithActor, IHudElementWithVisibilityConfig
|
||||
{
|
||||
private MouseGCDIndicatorConfig Config => (MouseGCDIndicatorConfig)_config;
|
||||
public VisibilityConfig VisibilityConfig => Config.VisibilityConfig;
|
||||
|
||||
public IGameObject? Actor { get; set; } = null;
|
||||
|
||||
private float _lastTotalCastTime = 0;
|
||||
|
||||
public MouseGCDIndicatorHud(MouseGCDIndicatorConfig config, string displayName) : base(config, displayName) { }
|
||||
|
||||
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
|
||||
{
|
||||
return (new List<Vector2>(), new List<Vector2>());
|
||||
}
|
||||
|
||||
protected override void DrawDraggableArea(Vector2 origin)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void DrawChildren(Vector2 origin)
|
||||
{
|
||||
if (!Config.Enabled || Actor == null || Actor is not IPlayerCharacter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GCDHelper.GetGCDInfo((IPlayerCharacter)Actor, out var elapsed, out var total);
|
||||
|
||||
if (!Config.AlwaysShow && total == 0)
|
||||
{
|
||||
_lastTotalCastTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastTotalCastTime == 0 && Utils.IsActorCasting(Actor))
|
||||
{
|
||||
_lastTotalCastTime = ((IBattleChara)Actor).TotalCastTime;
|
||||
}
|
||||
|
||||
var scale = elapsed / total;
|
||||
if (scale <= 0)
|
||||
{
|
||||
_lastTotalCastTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bool instantGCDsOnly = Config.InstantGCDsOnly && _lastTotalCastTime != 0;
|
||||
bool thresholdGCDs = Config.LimitGCDThreshold && _lastTotalCastTime > Config.GCDThreshold;
|
||||
|
||||
if (instantGCDsOnly || thresholdGCDs)
|
||||
{
|
||||
if (Config.AlwaysShow)
|
||||
{
|
||||
elapsed = 0;
|
||||
total = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 center = ImGui.GetMousePos() + Config.CursorCenterOffset;
|
||||
AddDrawAction(_config.StrataLevel, () =>
|
||||
{
|
||||
DrawCircularIndicator(center, Config.CircleRadius, elapsed, total);
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawCircularIndicator(Vector2 position, float radius, float current, float total)
|
||||
{
|
||||
total = Config.AlwaysShow && total == 0 ? 1 : total;
|
||||
current = Config.AlwaysShow && current == 0 ? total : current;
|
||||
|
||||
var size = new Vector2(radius * 2);
|
||||
DrawHelper.DrawInWindow(ID, position - size / 2, size, false, (drawList) =>
|
||||
{
|
||||
current = Math.Min(current, total);
|
||||
|
||||
const int segments = 100;
|
||||
const float queueTime = 0.5f;
|
||||
float startAngle = 0f;
|
||||
float endAngle = 2f * (float)Math.PI;
|
||||
float offset = (float)(-Math.PI / 2f + (Config.CircleStartAngle * (Math.PI / 180f)));
|
||||
|
||||
if (Config.RotateCCW)
|
||||
{
|
||||
startAngle *= -1;
|
||||
endAngle *= -1;
|
||||
}
|
||||
|
||||
if (Config.AlwaysShow && current == total)
|
||||
{
|
||||
drawList.PathArcTo(position, radius, startAngle + offset, endAngle + offset, segments);
|
||||
drawList.PathStroke(Config.FillColor.Base, ImDrawFlags.None, Config.CircleThickness);
|
||||
}
|
||||
else
|
||||
{
|
||||
float progressAngle = Math.Min(current, total - (Config.ShowGCDQueueIndicator ? queueTime : 0f)) / total * endAngle;
|
||||
|
||||
drawList.PathArcTo(position, radius, startAngle + offset, progressAngle + offset, segments);
|
||||
drawList.PathStroke(Config.FillColor.Base, ImDrawFlags.None, Config.CircleThickness);
|
||||
|
||||
if (Config.ShowGCDQueueIndicator && current > total - queueTime)
|
||||
{
|
||||
float oldAngle = progressAngle - 0.0003f * total * endAngle;
|
||||
progressAngle = current / total * endAngle;
|
||||
drawList.PathArcTo(position, radius, oldAngle + offset, progressAngle + offset, segments);
|
||||
drawList.PathStroke(Config.QueueColor.Base, ImDrawFlags.None, Config.CircleThickness);
|
||||
}
|
||||
|
||||
drawList.PathArcTo(position, radius, progressAngle + offset, endAngle + offset, segments);
|
||||
drawList.PathStroke(Config.BackgroundColor.Base, ImDrawFlags.None, Config.CircleThickness);
|
||||
}
|
||||
|
||||
if (Config.ShowBorder)
|
||||
{
|
||||
drawList.PathArcTo(position, radius - Config.CircleThickness / 2f, 0, endAngle, segments);
|
||||
drawList.PathStroke(0xFF000000, ImDrawFlags.None, 1);
|
||||
|
||||
drawList.PathArcTo(position, radius + Config.CircleThickness / 2f, 0, endAngle, segments);
|
||||
drawList.PathStroke(0xFF000000, ImDrawFlags.None, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,6 +379,11 @@ namespace HSUI.Interface
|
||||
_hudElements.Add(gcdIndicatorConfig, gcdIndicator);
|
||||
_hudElementsUsingPlayer.Add(gcdIndicator);
|
||||
|
||||
var mouseGcdIndicatorConfig = ConfigurationManager.Instance.GetConfigObject<MouseGCDIndicatorConfig>();
|
||||
var mouseGcdIndicator = new MouseGCDIndicatorHud(mouseGcdIndicatorConfig, "Mouse GCD Indicator");
|
||||
_hudElements.Add(mouseGcdIndicatorConfig, mouseGcdIndicator);
|
||||
_hudElementsUsingPlayer.Add(mouseGcdIndicator);
|
||||
|
||||
var mpTickerConfig = ConfigurationManager.Instance.GetConfigObject<MPTickerConfig>();
|
||||
var mpTicker = new MPTickerHud(mpTickerConfig, "MP Ticker");
|
||||
_hudElements.Add(mpTickerConfig, mpTicker);
|
||||
|
||||
Reference in New Issue
Block a user