diff --git a/XIVComboExpanded/CooldownData.cs b/XIVComboExpanded/CooldownData.cs index 64867d3c..fee4d32d 100644 --- a/XIVComboExpanded/CooldownData.cs +++ b/XIVComboExpanded/CooldownData.cs @@ -1,5 +1,7 @@ using System.Runtime.InteropServices; +using FFXIVClientStructs.FFXIV.Client.Game; + namespace XIVComboExpandedPlugin; /// @@ -21,39 +23,23 @@ internal struct CooldownData private readonly float cooldownTotal; /// - /// Gets a value indicating whether the action is on cooldown. - /// - public bool IsCooldown - { - get - { - var (cur, max) = Service.ComboCache.GetMaxCharges(this.ActionID); - if (cur == max) - return this.isCooldown; - - return this.cooldownElapsed < this.CooldownTotal; - } - } - - /// - /// Gets the action ID on cooldown. + /// Gets the base cooldown time in seconds. /// - public uint ActionID => this.actionID; + public float BaseCooldown => ActionManager.GetAdjustedRecastTime(ActionType.Action, this.ActionID) / 1000f; /// - /// Gets the elapsed cooldown time. + /// Gets the total cooldown calculated from AdjustedRecastTime in seconds. /// - public float CooldownElapsed + public float TotalBaseCooldown { get { - if (this.cooldownElapsed == 0) - return 0; + var (cur, max) = Service.ComboCache.GetMaxCharges(this.ActionID); - if (this.cooldownElapsed > this.CooldownTotal) - return 0; + // Rebase to the current charge count + var total = this.BaseCooldown / max * cur; - return this.cooldownElapsed; + return total * cur; } } @@ -82,9 +68,68 @@ public float CooldownTotal } /// - /// Gets the cooldown time remaining. + /// Gets a value indicating whether the action is on cooldown. /// - public float CooldownRemaining => this.IsCooldown ? this.CooldownTotal - this.CooldownElapsed : 0; + public bool IsCooldown + { + get + { + return this.cooldownElapsed < this.BaseCooldown; + } + } + + /// + /// Gets a value indicating whether all charges are capped. + /// + public bool IsCapped + { + get + { + return this.cooldownElapsed == 0; + } + } + + /// + /// Gets the action ID on cooldown. + /// + public uint ActionID => this.actionID; + + /// + /// Gets the elapsed cooldown time limited to an active charge (0 if a charge is available). + /// + public float CooldownElapsed + { + get + { + if (this.cooldownElapsed > this.BaseCooldown) + return 0; + + return this.cooldownElapsed; + } + } + + /// + /// Gets the elapsed cooldown time across the total cooldown (total cooldown time - total cooldown already regained). + /// + public float TotalCooldownElapsed => this.cooldownElapsed; + + /// + /// Gets the cooldown time remaining until all charges are replenished. + /// + public float TotalCooldownRemaining => this.TotalBaseCooldown - this.TotalCooldownElapsed; + + /// + /// Gets the cooldown time remaining until the current cooldown has recovered. + /// + public float CooldownRemaining + { + get + { + var (cur, _) = Service.ComboCache.GetMaxCharges(this.ActionID); + + return this.TotalCooldownRemaining % (this.TotalBaseCooldown / cur); + } + } /// /// Gets the maximum number of charges for an action at the current level. @@ -106,13 +151,25 @@ public ushort RemainingCharges { var (cur, _) = Service.ComboCache.GetMaxCharges(this.ActionID); - if (!this.IsCooldown) - return cur; + if (this.TotalCooldownElapsed == 0) + { + return this.MaxCharges; + } - return (ushort)(this.CooldownElapsed / (this.CooldownTotal / this.MaxCharges)); + return (ushort)(this.TotalCooldownElapsed / (this.TotalBaseCooldown / this.MaxCharges)); } } + /// + /// Gets a value indicating whether gets value indicating whether this action has at least one charge out of however many it has total, even if it can only have one "charge". + /// + public bool Available => this.CooldownRemaining == 0 || this.RemainingCharges > 0; + + /// + /// Gets the time since the cooldown was spent in seconds (only fuctional if actionID is not charge based). + /// + public float CooldownDuration => this.BaseCooldown - this.CooldownRemaining; + /// /// Gets the cooldown time remaining until the next charge. /// @@ -120,12 +177,39 @@ public float ChargeCooldownRemaining { get { - if (!this.IsCooldown) - return 0; - var (cur, _) = Service.ComboCache.GetMaxCharges(this.ActionID); - return this.CooldownRemaining % (this.CooldownTotal / cur); + return this.TotalCooldownRemaining % (this.TotalBaseCooldown / cur); } } -} + + /// + /// Gets the recovery time in seconds if action is used when cooldown is off. + /// + public float RecoveryTime => this.CooldownRemaining + this.BaseCooldown; + + /// + /// Gets the time until another charge is available after using the currently refreshing charge. + /// + public float ChargeRecoveryTime + { + get + { + if ((this.RemainingCharges - 1) >= 0) + { + return this.ChargeCooldownRemaining; + } + + return this.ChargeCooldownRemaining + this.BaseCooldown; + } + } + + /// + /// Gets the cooldown time remaining until all charges of ability are replenished. + /// + public float TotalChargeCooldownRemaining => this.MaxCharges - this.RemainingCharges > 0 + ? this.MaxCharges - this.RemainingCharges == 1 + ? this.ChargeCooldownRemaining + : (this.BaseCooldown * ((this.MaxCharges - this.RemainingCharges) - 1)) + this.ChargeCooldownRemaining + : 0; +} \ No newline at end of file