using FFXIVClientStructs.FFXIV.Client.Game; using System; namespace HSUI.Helpers { internal class SpellHelper { #region Singleton private static Lazy _lazyInstance = new Lazy(() => new SpellHelper()); public static SpellHelper Instance => _lazyInstance.Value; ~SpellHelper() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(bool disposing) { if (!disposing) { return; } _lazyInstance = new Lazy(() => new SpellHelper()); } #endregion private readonly unsafe ActionManager* _actionManager; public unsafe SpellHelper() { _actionManager = ActionManager.Instance(); } public unsafe uint GetSpellActionId(uint actionId) => _actionManager->GetAdjustedActionId(actionId); public unsafe float GetRecastTimeElapsed(uint actionId) => _actionManager->GetRecastTimeElapsed(ActionType.Action, GetSpellActionId(actionId)); public unsafe float GetRealRecastTimeElapsed(uint actionId) => _actionManager->GetRecastTimeElapsed(ActionType.Action, actionId); public unsafe float GetRecastTime(uint actionId) => _actionManager->GetRecastTime(ActionType.Action, GetSpellActionId(actionId)); public unsafe float GetRealRecastTime(uint actionId) => _actionManager->GetRecastTime(ActionType.Action, actionId); public unsafe uint GetLastUsedActionId() => _actionManager->Combo.Action; public float GetSpellCooldown(uint actionId) => Math.Abs(GetRecastTime(GetSpellActionId(actionId)) - GetRecastTimeElapsed(GetSpellActionId(actionId))); public float GetRealSpellCooldown(uint actionId) => Math.Abs(GetRealRecastTime(actionId) - GetRealRecastTimeElapsed(actionId)); public int GetSpellCooldownInt(uint actionId) { int cooldown = (int)Math.Ceiling(GetSpellCooldown(actionId) % GetRecastTime(actionId)); return Math.Max(0, cooldown); } public int GetStackCount(int maxStacks, uint actionId) { int cooldown = GetSpellCooldownInt(actionId); float recastTime = GetRecastTime(actionId); if (cooldown <= 0 || recastTime == 0) { return maxStacks; } return maxStacks - (int)Math.Ceiling(cooldown / (recastTime / maxStacks)); } public unsafe bool IsActionHighlighted(uint actionId, ActionType type = ActionType.Action) => _actionManager->IsActionHighlighted(type, actionId); } }