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;