diff --git a/XIVSlothCombo/Combos/JobHelpers/RDM.cs b/XIVSlothCombo/Combos/JobHelpers/RDM.cs
index d52550a74..fd47b8978 100644
--- a/XIVSlothCombo/Combos/JobHelpers/RDM.cs
+++ b/XIVSlothCombo/Combos/JobHelpers/RDM.cs
@@ -9,7 +9,7 @@ internal class RDM
static float GetBuffRemainingTime(ushort effectid) => CustomComboFunctions.GetBuffRemainingTime(effectid);
static bool LevelChecked(uint id) => CustomComboFunctions.LevelChecked(id);
static float GetActionCastTime(uint actionID) => CustomComboFunctions.GetActionCastTime(actionID);
- static ushort GetRemainingCharges(uint actionID) => CustomComboFunctions.GetRemainingCharges(actionID);
+ static uint GetRemainingCharges(uint actionID) => CustomComboFunctions.GetRemainingCharges(actionID);
static float GetCooldownRemainingTime(uint actionID) => CustomComboFunctions.GetCooldownRemainingTime(actionID);
static bool ActionReady(uint id) => CustomComboFunctions.ActionReady(id);
static bool CanSpellWeave(uint id) => CustomComboFunctions.CanSpellWeave(id);
diff --git a/XIVSlothCombo/Combos/PvE/BRD.cs b/XIVSlothCombo/Combos/PvE/BRD.cs
index 019867966..52d3df5af 100644
--- a/XIVSlothCombo/Combos/PvE/BRD.cs
+++ b/XIVSlothCombo/Combos/PvE/BRD.cs
@@ -654,7 +654,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim
if (LevelChecked(Bloodletter) && ((!openerFinished && IsOnCooldown(RagingStrikes)) || openerFinished))
{
- ushort bloodletterCharges = GetRemainingCharges(Bloodletter);
+ uint bloodletterCharges = GetRemainingCharges(Bloodletter);
if (IsEnabled(CustomComboPreset.BRD_Simple_Pooling) && LevelChecked(WanderersMinuet))
{
diff --git a/XIVSlothCombo/CustomCombo/Functions/Cooldown.cs b/XIVSlothCombo/CustomCombo/Functions/Cooldown.cs
index 5debbfc13..728f9b843 100644
--- a/XIVSlothCombo/CustomCombo/Functions/Cooldown.cs
+++ b/XIVSlothCombo/CustomCombo/Functions/Cooldown.cs
@@ -50,7 +50,7 @@ internal abstract partial class CustomComboFunctions
/// Get the current number of charges remaining for an action.
/// Action ID to check.
/// Number of charges.
- public static ushort GetRemainingCharges(uint actionID) => GetCooldown(actionID).RemainingCharges;
+ public static uint GetRemainingCharges(uint actionID) => GetCooldown(actionID).RemainingCharges;
/// Get the maximum number of charges for an action.
/// Action ID to check.
diff --git a/XIVSlothCombo/Data/CooldownData.cs b/XIVSlothCombo/Data/CooldownData.cs
index 2e836f964..5e27d87a7 100644
--- a/XIVSlothCombo/Data/CooldownData.cs
+++ b/XIVSlothCombo/Data/CooldownData.cs
@@ -1,114 +1,55 @@
-using System.Runtime.InteropServices;
+using FFXIVClientStructs.FFXIV.Client.Game;
using XIVSlothCombo.Services;
namespace XIVSlothCombo.Data
{
- /// Internal cooldown data.
- [StructLayout(LayoutKind.Explicit)]
- internal struct CooldownData
+ internal class CooldownData
{
- [FieldOffset(0x0)]
- private readonly bool isCooldown;
-
- [FieldOffset(0x4)]
- private readonly uint actionID;
-
- [FieldOffset(0x8)]
- private readonly float cooldownElapsed;
-
- [FieldOffset(0xC)]
- private float cooldownTotal;
-
/// Gets a value indicating whether the action is on cooldown.
- public readonly bool IsCooldown
+ public bool IsCooldown
{
get
{
- var (cur, max) = Service.ComboCache.GetMaxCharges(ActionID);
- return cur == max
- ? isCooldown
- : cooldownElapsed < CooldownTotal;
+ return RemainingCharges == MaxCharges
+ ? false
+ : CooldownElapsed < CooldownTotal;
}
}
/// Gets the action ID on cooldown.
- public readonly uint ActionID => actionID;
+ public uint ActionID;
/// Gets the elapsed cooldown time.
- public readonly float CooldownElapsed
- {
- get
- {
- if (cooldownElapsed == 0)
- return 0;
-
- if (cooldownElapsed > CooldownTotal)
- return 0;
-
- return cooldownElapsed;
- }
- }
+ public unsafe float CooldownElapsed => ActionManager.Instance()->GetRecastGroupDetail(ActionManager.Instance()->GetRecastGroup(1, ActionID))->Elapsed;
/// Gets the total cooldown time.
- public float CooldownTotal
- {
- readonly get
- {
- if (cooldownTotal == 0)
- return 0;
-
- var (cur, max) = Service.ComboCache.GetMaxCharges(ActionID);
-
- if (cur == max)
- return cooldownTotal;
-
- // Rebase to the current charge count
- float total = cooldownTotal / max * cur;
-
- return cooldownElapsed > total
- ? 0
- : total;
- }
- set
- {
- cooldownTotal = value;
- }
- }
+ public unsafe float CooldownTotal => (ActionManager.GetAdjustedRecastTime(ActionType.Action, ActionID) / 1000f) * MaxCharges;
/// Gets the cooldown time remaining.
- public readonly float CooldownRemaining => IsCooldown ? CooldownTotal - CooldownElapsed : 0;
+ public unsafe float CooldownRemaining => CooldownTotal - CooldownElapsed;
/// Gets the maximum number of charges for an action at the current level.
/// Number of charges.
- public readonly ushort MaxCharges => Service.ComboCache.GetMaxCharges(ActionID).Current;
+ public ushort MaxCharges => Service.ComboCache.GetMaxCharges(ActionID);
/// Gets a value indicating whether the action has charges, not charges available.
- public readonly bool HasCharges => MaxCharges > 1;
+ public bool HasCharges => MaxCharges > 1;
/// Gets the remaining number of charges for an action.
- public readonly ushort RemainingCharges
- {
- get
- {
- var (cur, _) = Service.ComboCache.GetMaxCharges(ActionID);
-
- return !IsCooldown
- ? cur
- : (ushort)(CooldownElapsed / (CooldownTotal / MaxCharges));
- }
- }
+ public unsafe uint RemainingCharges => ActionManager.Instance()->GetCurrentCharges(ActionID);
/// Gets the cooldown time remaining until the next charge.
- public readonly float ChargeCooldownRemaining
+ public float ChargeCooldownRemaining
{
get
{
if (!IsCooldown)
return 0;
- var (cur, _) = Service.ComboCache.GetMaxCharges(ActionID);
+ var maxCharges = ActionManager.GetMaxCharges(ActionID, 100);
+ var timePerCharge = CooldownTotal / maxCharges;
- return CooldownRemaining % (CooldownTotal / cur);
+ return CooldownRemaining % (CooldownTotal / MaxCharges);
}
}
}
diff --git a/XIVSlothCombo/Data/CustomComboCache.cs b/XIVSlothCombo/Data/CustomComboCache.cs
index 7a3bb7aac..c49e564d4 100644
--- a/XIVSlothCombo/Data/CustomComboCache.cs
+++ b/XIVSlothCombo/Data/CustomComboCache.cs
@@ -81,46 +81,18 @@ internal unsafe CooldownData GetCooldown(uint actionID)
if (actionManager == null)
return cooldownCache[actionID] = default;
- byte cooldownGroup = GetCooldownGroup(actionID);
-
- RecastDetail* cooldownPtr = actionManager->GetRecastGroupDetail(cooldownGroup - 1);
- if (cooldownPtr is null)
+ CooldownData data = new()
{
- CooldownData data = new()
- {
- CooldownTotal = -1
- };
-
- return cooldownCache[actionID] = data;
- }
+ ActionID = actionID,
+ };
- cooldownPtr->ActionId = actionID;
-
- return cooldownCache[actionID] = *(CooldownData*)cooldownPtr;
+ return cooldownCache[actionID] = data;
}
/// Get the maximum number of charges for an action.
/// Action ID to check.
- /// Max number of charges at current and max level.
- internal unsafe (ushort Current, ushort Max) GetMaxCharges(uint actionID)
- {
- IPlayerCharacter? player = Service.ClientState.LocalPlayer;
- if (player == null)
- return (0, 0);
-
- uint job = player.ClassJob.Id;
- byte level = player.Level;
- if (job == 0 || level == 0)
- return (0, 0);
-
- var key = (actionID, job, level);
- if (chargesCache.TryGetValue(key, out var found))
- return found;
-
- ushort cur = ActionManager.GetMaxCharges(actionID, 0);
- ushort max = ActionManager.GetMaxCharges(actionID, 90);
- return chargesCache[key] = (cur, max);
- }
+ /// Max number of charges at current level.
+ internal unsafe ushort GetMaxCharges(uint actionID) => ActionManager.GetMaxCharges(actionID, 0);
/// Get the resource cost of an action.
/// Action ID to check.
diff --git a/XIVSlothCombo/Window/Tabs/Debug.cs b/XIVSlothCombo/Window/Tabs/Debug.cs
index 0af885d6d..d6daf94d1 100644
--- a/XIVSlothCombo/Window/Tabs/Debug.cs
+++ b/XIVSlothCombo/Window/Tabs/Debug.cs
@@ -5,6 +5,7 @@
using System.Linq;
using System.Numerics;
using XIVSlothCombo.Combos;
+using XIVSlothCombo.Combos.PvE;
using XIVSlothCombo.CustomComboNS;
using XIVSlothCombo.CustomComboNS.Functions;
using XIVSlothCombo.Data;