diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index 84d38bc9c..5de0338c8 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -365,19 +365,132 @@ public enum CustomComboPreset // Last value = 1054 #endregion - + #region BLACK MAGE [AutoAction(false, false)] [ReplaceSkill(BLM.Fire)] - [CustomComboInfo("Simple Mode - Single Target", "Replaces Fire with a full one-button single target rotation.\nThis is the ideal option for newcomers to the job.", BLM.JobID, -10)] - BLM_ST_SimpleMode = 2012, + [ConflictingCombos(BLM_ST_AdvancedMode)] + [CustomComboInfo("Simple Mode - Single Target", "Replaces Fire with a full one-button single target rotation.\nThis is the ideal option for newcomers to the job.", BLM.JobID)] + BLM_ST_SimpleMode = 2001, [AutoAction(true, false)] [ReplaceSkill(BLM.Blizzard2, BLM.HighBlizzard2)] - [CustomComboInfo("Simple Mode - AoE", "Replaces Blizzard II with a full one-button AoE rotation.\nThis is the ideal option for newcomers to the job.", BLM.JobID, -8)] - BLM_AoE_SimpleMode = 2008, + [ConflictingCombos(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Simple Mode - AoE", "Replaces Blizzard II with a full one-button AoE rotation.\nThis is the ideal option for newcomers to the job.", BLM.JobID)] + BLM_AoE_SimpleMode = 2002, + + #region Single Target - Advanced + + [AutoAction(false, false)] + [ReplaceSkill(BLM.Fire)] + [ConflictingCombos(BLM_ST_SimpleMode)] + [CustomComboInfo("Advanced Mode - Single Target", "Replaces Fire with a full one-button single target rotation.\nThese features are ideal if you want to customize the rotation.", BLM.JobID)] + BLM_ST_AdvancedMode = 2100, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Level 100 Opener", "Adds the Balance opener to the rotation.", BLM.JobID)] + BLM_ST_Opener = 2101, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Amplifier", "Add Amplifier to the rotation.", BLM.JobID)] + BLM_ST_Amplifier = 2102, + + [ParentCombo(BLM_ST_AdvancedMode)] [CustomComboInfo("Use Leylines", "Add Leylines to the rotation.", BLM.JobID)] + BLM_ST_LeyLines = 2103, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Foul / Xenoglossy", "Add Foul / Xenoglossy to the rotation.", BLM.JobID)] + BLM_ST_UsePolyglot = 2104, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Foul / Xenoglossy for movement", "Add Foul / Xenoglossy to the rotation as movement option.", BLM.JobID)] + BLM_ST_UsePolyglotMoving = 2105, + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Swiftcast", "Add Swiftcast to the rotation.", BLM.JobID)] + BLM_ST_Swiftcast = 2106, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Triplecast", "Add Triplecast to the rotation.", BLM.JobID)] + BLM_ST_Triplecast = 2107, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Manafont", "Add Manafont to the rotation.", BLM.JobID)] + BLM_ST_Manafont = 2108, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Transpose", "Add Transpose to the rotation.", BLM.JobID)] + BLM_ST_Transpose = 2109, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Thunder", "Add Thunder to the rotation.", BLM.JobID)] + BLM_ST_Thunder = 2110, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Despair", "Add Despair to the rotation.", BLM.JobID)] + BLM_ST_Despair = 2111, + + [ParentCombo(BLM_ST_AdvancedMode)] + [CustomComboInfo("Use Flarestar", "Add Flarestar to the rotation.", BLM.JobID)] + BLM_ST_Flarestar = 2112, + + #endregion + + #region AoE - Advanced + + [AutoAction(true, false)] + [ReplaceSkill(BLM.Fire)] + [ConflictingCombos(BLM_AoE_SimpleMode)] + [CustomComboInfo("Advanced Mode - AoE", "Replaces Blizzard II with a full one-button AoE rotation.\nThese features are ideal if you want to customize the rotation.", BLM.JobID)] + BLM_AoE_AdvancedMode = 2200, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Amplifier", "Add Amplifier to the rotation.", BLM.JobID)] + BLM_AoE_Amplifier = 2201, + + [ParentCombo(CustomComboPreset.BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Leylines", "Add Leylines to the rotation.", BLM.JobID)] + BLM_AoE_LeyLines = 2202, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Foul", "Add Foul to the rotation.", BLM.JobID)] + BLM_AoE_UsePolyglot = 2203, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Foul for movement", "Add Foul to the rotation as movement option.", BLM.JobID)] + BLM_AoE_UsePolyglotMoving = 2204, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Swiftcast", "Add Swiftcast to the rotation.", BLM.JobID)] + BLM_AoE_Swiftcast = 2205, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Triplecast", "Add Triplecast to the rotation.", BLM.JobID)] + BLM_AoE_Triplecast = 2206, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Manafont", "Add Manafont to the rotation.", BLM.JobID)] + BLM_AoE_Manafont = 2207, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Transpose", "Add Transpose to the rotation.", BLM.JobID)] + BLM_AoE_Transpose = 2208, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Thunder", "Add Thunder to the rotation.", BLM.JobID)] + BLM_AoE_Thunder = 2209, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Flare", "Add Flare to the rotation.", BLM.JobID)] + BLM_AoE_Flare = 2210, + + [ParentCombo(BLM_AoE_AdvancedMode)] + [CustomComboInfo("Use Flarestar", "Add Flarestar to the rotation.", BLM.JobID)] + BLM_AoE_Flarestar = 2211, + + #endregion + #region Variant [Variant] @@ -399,31 +512,36 @@ public enum CustomComboPreset #region Miscellaneous [ReplaceSkill(BLM.Transpose)] [CustomComboInfo("Umbral Soul/Transpose Feature", "Replaces Transpose with Umbral Soul when Umbral Soul is available.", BLM.JobID)] - BLM_UmbralSoul = 2001, + BLM_UmbralSoul = 2050, [ReplaceSkill(BLM.LeyLines)] [CustomComboInfo("Between the Ley Lines Feature", "Replaces Ley Lines with Between the Lines when Ley Lines is active.", BLM.JobID)] - BLM_Between_The_LeyLines = 2002, + BLM_Between_The_LeyLines = 2051, [ReplaceSkill(BLM.Blizzard, BLM.Freeze)] [CustomComboInfo("Blizzard I/III Feature", "Replaces Blizzard I with Blizzard III when out of Umbral Ice." + "\nReplaces Freeze with Blizzard II when synced below Lv.40.", BLM.JobID)] - BLM_Blizzard_1to3 = 2003, + BLM_Blizzard_1to3 = 2052, [ReplaceSkill(BLM.Scathe)] [CustomComboInfo("Xenoglossy Feature", "Replaces Scathe with Xenoglossy when available.", BLM.JobID)] - BLM_Scathe_Xeno = 2004, + BLM_Scathe_Xeno = 2053, [ReplaceSkill(BLM.Fire)] [CustomComboInfo("Fire I/III Feature", "Replaces Fire I with Fire III outside of Astral Fire or when Firestarter is up.", BLM.JobID)] - BLM_Fire_1to3 = 2005, + BLM_Fire_1to3 = 2054, [ReplaceSkill(BLM.AetherialManipulation)] [CustomComboInfo("Aetherial Manipulation Feature", "Replaces Aetherial Manipulation with Between the Lines when you are out of active Ley Lines and standing still.", BLM.JobID)] - BLM_Aetherial_Manipulation = 2046, + BLM_Aetherial_Manipulation = 2055, + + [ReplaceSkill(BLM.Triplecast)] + [CustomComboInfo("Triplecast Protection", "Replaces Triplecast with Savage Blade when u already have triplecast active.", BLM.JobID)] + BLM_TriplecastProtection = 2056, #endregion - // Last value = 2057 + // Last value ST = 2112 + //Last Value AoE = 2211 #endregion diff --git a/XIVSlothCombo/Combos/JobHelpers/BLM.cs b/XIVSlothCombo/Combos/JobHelpers/BLM.cs deleted file mode 100644 index 89e3a0dc9..000000000 --- a/XIVSlothCombo/Combos/JobHelpers/BLM.cs +++ /dev/null @@ -1,492 +0,0 @@ -using Dalamud.Game.ClientState.JobGauge.Types; -using ECommons.DalamudServices; -using System; -using System.Linq; -using XIVSlothCombo.Combos.JobHelpers.Enums; -using XIVSlothCombo.Combos.PvE; -using XIVSlothCombo.CustomComboNS.Functions; -using XIVSlothCombo.Data; - -namespace XIVSlothCombo.Combos.JobHelpers -{ - internal class BLMOpenerLogic : PvE.BLM - { - private static bool HasCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(Triplecast) < 2) - return false; - if (!CustomComboFunctions.ActionReady(Manafont)) - return false; - if (!CustomComboFunctions.ActionReady(All.Swiftcast)) - return false; - if (!CustomComboFunctions.ActionReady(Amplifier)) - return false; - if (!CustomComboFunctions.ActionReady(All.LucidDreaming) && - Config.BLM_Advanced_OpenerSelection == 1) - return false; - if (!CustomComboFunctions.ActionReady(LeyLines)) - return false; - - return true; - } - - public static bool HasPrePullCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(Sharpcast) < 2) - return false; - - if (CustomComboFunctions.LocalPlayer.CurrentMp < 10000) - return false; - - return true; - } - - private static uint OpenerLevel => 90; - - public uint PrePullStep = 0; - - public uint OpenerStep = 1; - - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; - - private static bool CanOpener => HasCooldowns() && HasPrePullCooldowns() && LevelChecked; - - private OpenerState currentState = OpenerState.PrePull; - - public OpenerState CurrentState - { - get - { - return currentState; - } - set - { - if (value != currentState) - { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } - if (value == OpenerState.InOpener) OpenerStep = 1; - if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) - { - if (value == OpenerState.FailedOpener) - Svc.Log.Information($"Opener Failed at step {OpenerStep}"); - - ResetOpener(); - } - if (value == OpenerState.OpenerFinished) Svc.Log.Information("Opener Finished"); - - currentState = value; - } - } - } - - private bool DoPrePullSteps(ref uint actionID) - { - if (!LevelChecked) return false; - - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } - - if (!HasCooldowns()) - { - PrePullStep = 0; - } - - if (CurrentState == OpenerState.PrePull && PrePullStep > 0) - { - if (CustomComboFunctions.HasEffect(Buffs.Sharpcast) && PrePullStep == 1) PrePullStep++; - else if (PrePullStep == 1) actionID = Sharpcast; - - if (CustomComboFunctions.LocalPlayer.CastActionId == Fire3 && PrePullStep == 2) CurrentState = OpenerState.InOpener; - else if (PrePullStep == 2) actionID = Fire3; - - if (PrePullStep == 2 && !CustomComboFunctions.HasEffect(Buffs.Sharpcast)) - CurrentState = OpenerState.FailedOpener; - - if (PrePullStep > 1 && CustomComboFunctions.GetResourceCost(actionID) > CustomComboFunctions.LocalPlayer.CurrentMp && ActionWatching.TimeSinceLastAction.TotalSeconds >= 2) - CurrentState = OpenerState.FailedOpener; - - if (ActionWatching.CombatActions.Count > 2 && CustomComboFunctions.InCombat()) - CurrentState = OpenerState.FailedOpener; - - return true; - } - - PrePullStep = 0; - return false; - } - - private bool DoOpener(ref uint actionID) - { - if (!LevelChecked) return false; - - if (currentState == OpenerState.InOpener) - { - if (Config.BLM_Advanced_OpenerSelection == 0) - { - if (CustomComboFunctions.LocalPlayer.CastActionId == Thunder3 && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = Thunder3; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 2 && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 1 && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Amplifier) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Amplifier; - - if (CustomComboFunctions.WasLastAction(LeyLines) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = LeyLines; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 0 && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(All.Swiftcast) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = All.Swiftcast; - - if (CustomComboFunctions.WasLastAction(Fire4) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Manafont) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = Manafont; - - if (CustomComboFunctions.WasLastAction(Fire4) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Sharpcast) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = Sharpcast; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Blizzard3) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = Blizzard3; - - if (CustomComboFunctions.WasLastAction(Xenoglossy) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = Xenoglossy; - - if (CustomComboFunctions.WasLastAction(Paradox) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = Paradox; - - if (CustomComboFunctions.LocalPlayer.CastActionId == Blizzard4 && OpenerStep == 19) OpenerStep++; - else if (OpenerStep == 19) actionID = Blizzard4; - - if (CustomComboFunctions.WasLastAction(Thunder3) && OpenerStep == 20) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 20) actionID = Thunder3; - - if (((actionID == Triplecast && CustomComboFunctions.GetRemainingCharges(Triplecast) < 2) || - (actionID == Amplifier && CustomComboFunctions.IsOnCooldown(Amplifier)) || - (actionID == LeyLines && CustomComboFunctions.IsOnCooldown(LeyLines)) || - (actionID == All.LucidDreaming && CustomComboFunctions.IsOnCooldown(All.LucidDreaming)) || - (actionID == Manafont && CustomComboFunctions.IsOnCooldown(Manafont)) || - (actionID == Sharpcast && CustomComboFunctions.GetRemainingCharges(Sharpcast) < 1) || - (actionID == All.Swiftcast && CustomComboFunctions.IsOnCooldown(All.Swiftcast)) || - (actionID == Xenoglossy && Svc.Gauges.Get().PolyglotStacks < 1)) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - CurrentState = OpenerState.FailedOpener; - return false; - } - } - - else - { - - if (CustomComboFunctions.LocalPlayer.CastActionId == Thunder3 && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = Thunder3; - - if (CustomComboFunctions.LocalPlayer.CastActionId == Fire4 && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 2 && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 1 && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Amplifier) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = Amplifier; - - if (CustomComboFunctions.WasLastAction(LeyLines) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeyLines; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 0 && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(All.LucidDreaming) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = All.LucidDreaming; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Manafont) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = Manafont; - - if (CustomComboFunctions.WasLastAction(Fire4) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Sharpcast) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = Sharpcast; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Transpose) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = Transpose; - - if (CustomComboFunctions.WasLastAction(Paradox) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = Paradox; - - if (CustomComboFunctions.WasLastAction(All.Swiftcast) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = All.Swiftcast; - - if (CustomComboFunctions.WasLastAction(Xenoglossy) && OpenerStep == 19) OpenerStep++; - else if (OpenerStep == 19) actionID = Xenoglossy; - - if ((CustomComboFunctions.LocalPlayer.CastActionId == Thunder3 || CustomComboFunctions.WasLastAction(Thunder3)) && OpenerStep == 20) OpenerStep++; - else if (OpenerStep == 20) actionID = Thunder3; - - if (CustomComboFunctions.LocalPlayer.CurrentMp == CustomComboFunctions.LocalPlayer.MaxMp && OpenerStep == 21) OpenerStep++; - else if (OpenerStep == 21) actionID = Blizzard3; - - if (CustomComboFunctions.WasLastAction(Transpose) && OpenerStep == 22) OpenerStep++; - else if (OpenerStep == 22) actionID = Transpose; - - if ((CustomComboFunctions.LocalPlayer.CastActionId == Fire3 || CustomComboFunctions.WasLastAction(Fire3)) && OpenerStep == 23) OpenerStep++; - else if (OpenerStep == 23) actionID = Fire3; - - if ((CustomComboFunctions.LocalPlayer.CastActionId == Fire4 || CustomComboFunctions.WasLastAction(Fire4)) && OpenerStep == 24 && ActionWatching.CombatActions.Count == 24) OpenerStep++; - else if (OpenerStep == 24) actionID = Fire4; - - if ((CustomComboFunctions.LocalPlayer.CastActionId == Fire4 || CustomComboFunctions.WasLastAction(Fire4)) && OpenerStep == 25 && ActionWatching.CombatActions.Count == 25) OpenerStep++; - else if (OpenerStep == 25) actionID = Fire4; - - if ((CustomComboFunctions.LocalPlayer.CastActionId == Fire4 || CustomComboFunctions.WasLastAction(Fire4)) && OpenerStep == 26 && ActionWatching.CombatActions.Count == 26) OpenerStep++; - else if (OpenerStep == 26) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 27) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 27) actionID = Despair; - } - - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; - - if (CustomComboFunctions.GetResourceCost(actionID) > CustomComboFunctions.LocalPlayer.CurrentMp && ActionWatching.TimeSinceLastAction.TotalSeconds >= 2) - CurrentState = OpenerState.FailedOpener; - - if (((actionID == Triplecast && CustomComboFunctions.GetRemainingCharges(Triplecast) < 2) || - (actionID == Amplifier && CustomComboFunctions.IsOnCooldown(Amplifier)) || - (actionID == LeyLines && CustomComboFunctions.IsOnCooldown(LeyLines)) || - (actionID == All.LucidDreaming && CustomComboFunctions.IsOnCooldown(All.LucidDreaming)) || - (actionID == Manafont && CustomComboFunctions.IsOnCooldown(Manafont)) || - (actionID == Sharpcast && CustomComboFunctions.GetRemainingCharges(Sharpcast) < 1) || - (actionID == All.Swiftcast && CustomComboFunctions.IsOnCooldown(All.Swiftcast)) || - (actionID == Xenoglossy && Svc.Gauges.Get().PolyglotStacks < 1)) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - CurrentState = OpenerState.FailedOpener; - return false; - } - - return true; - } - - return false; - } - - private bool DoOpenerSimple(ref uint actionID) - { - if (!LevelChecked) return false; - - if (currentState == OpenerState.InOpener) - { - if (CustomComboFunctions.LocalPlayer.CastActionId == Thunder3 && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = Thunder3; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 2 && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 1 && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Amplifier) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Amplifier; - - if (CustomComboFunctions.WasLastAction(LeyLines) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = LeyLines; - - if (CustomComboFunctions.WasLastAction(Fire4) && CustomComboFunctions.GetBuffStacks(Buffs.Triplecast) == 0 && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(All.Swiftcast) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = All.Swiftcast; - - if (CustomComboFunctions.WasLastAction(Fire4) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Triplecast) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = Triplecast; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Manafont) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = Manafont; - - if (CustomComboFunctions.WasLastAction(Fire4) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = Fire4; - - if (CustomComboFunctions.WasLastAction(Sharpcast) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = Sharpcast; - - if (CustomComboFunctions.WasLastAction(Despair) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = Despair; - - if (CustomComboFunctions.WasLastAction(Blizzard3) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = Blizzard3; - - if (CustomComboFunctions.WasLastAction(Xenoglossy) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = Xenoglossy; - - if (CustomComboFunctions.WasLastAction(Paradox) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = Paradox; - - if (CustomComboFunctions.LocalPlayer.CastActionId == Blizzard4 && OpenerStep == 19) OpenerStep++; - else if (OpenerStep == 19) actionID = Blizzard4; - - if (CustomComboFunctions.WasLastAction(Thunder3) && OpenerStep == 20) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 20) actionID = Thunder3; - - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; - - if (CustomComboFunctions.GetResourceCost(actionID) > CustomComboFunctions.LocalPlayer.CurrentMp && ActionWatching.TimeSinceLastAction.TotalSeconds >= 2) - CurrentState = OpenerState.FailedOpener; - - if (((actionID == Triplecast && CustomComboFunctions.GetRemainingCharges(Triplecast) < 2) || - (actionID == Amplifier && CustomComboFunctions.IsOnCooldown(Amplifier)) || - (actionID == LeyLines && CustomComboFunctions.IsOnCooldown(LeyLines)) || - (actionID == All.LucidDreaming && CustomComboFunctions.IsOnCooldown(All.LucidDreaming)) || - (actionID == Manafont && CustomComboFunctions.IsOnCooldown(Manafont)) || - (actionID == Sharpcast && CustomComboFunctions.GetRemainingCharges(Sharpcast) < 1) || - (actionID == All.Swiftcast && CustomComboFunctions.IsOnCooldown(All.Swiftcast)) || - (actionID == Xenoglossy && Svc.Gauges.Get().PolyglotStacks < 1)) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - CurrentState = OpenerState.FailedOpener; - return false; - } - - return true; - } - - return false; - } - - private void ResetOpener() - { - PrePullStep = 0; - OpenerStep = 0; - } - - public bool DoFullOpener(ref uint actionID, bool simpleMode) - { - if (!LevelChecked) return false; - - if (CurrentState == OpenerState.PrePull) - if (DoPrePullSteps(ref actionID)) return true; - - if (CurrentState == OpenerState.InOpener) - { - if (simpleMode) - { - if (DoOpenerSimple(ref actionID)) return true; - } - else - { - if (DoOpener(ref actionID)) return true; - } - } - - if (!CustomComboFunctions.InCombat()) - { - ResetOpener(); - CurrentState = OpenerState.PrePull; - } - - - return false; - } - } - - internal static class BLMExtensions - { - public static bool HasPolyglotStacks(this BLMGauge gauge) => gauge.PolyglotStacks > 0; - } - - internal class BLMHelper : BLM - { - public static float MPAfterCast() - { - var castedSpell = CustomComboFunctions.LocalPlayer.CastActionId; - var gauge = Svc.Gauges.Get(); - int nextMpGain = gauge.UmbralIceStacks switch - { - 0 => 0, - 1 => 2500, - 2 => 5000, - 3 => 10000, - _ => 0 - }; - if (castedSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) - return Math.Max(CustomComboFunctions.LocalPlayer.MaxMp, CustomComboFunctions.LocalPlayer.CurrentMp + nextMpGain); - - return Math.Max(0, CustomComboFunctions.LocalPlayer.CurrentMp - CustomComboFunctions.GetResourceCost(castedSpell)); - - } - - public static bool DoubleBlizz() - { - var spells = ActionWatching.CombatActions.Where(x => ActionWatching.GetAttackType(x) == ActionWatching.ActionAttackType.Spell && x != CustomComboFunctions.OriginalHook(Thunder) && x != CustomComboFunctions.OriginalHook(Thunder2)).ToList(); - if (spells.Count < 1) return false; - - var firstSpell = spells[^1]; - - if (firstSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) - { - var castedSpell = CustomComboFunctions.LocalPlayer.CastActionId; - if (castedSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) return true; - - if (spells.Count >= 2) - { - var secondSpell = spells[^2]; - if (secondSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) - return true; - } - } - - return false; - - } - } -} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/JobHelpers/Enums/OpenerState.cs b/XIVSlothCombo/Combos/JobHelpers/Enums/OpenerState.cs deleted file mode 100644 index 77dff164c..000000000 --- a/XIVSlothCombo/Combos/JobHelpers/Enums/OpenerState.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace XIVSlothCombo.Combos.JobHelpers.Enums -{ - internal enum OpenerState - { - PrePull, - InOpener, - OpenerFinished, - FailedOpener - } -} diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs deleted file mode 100644 index e62ce9830..000000000 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ /dev/null @@ -1,386 +0,0 @@ -using Dalamud.Game.ClientState.JobGauge.Enums; -using ECommons.DalamudServices; -using XIVSlothCombo.Combos.JobHelpers.Enums; -using XIVSlothCombo.Combos.PvE; -using XIVSlothCombo.Data; -using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; - -namespace XIVSlothCombo.Combos.JobHelpers; - -internal abstract class MNKHelper : MNK -{ - public static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled) - { - if (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist)) - return Gauge.OpoOpoFury == 0 && LevelChecked(DragonKick) - ? DragonKick - : OriginalHook(Bootshine); - - if (HasEffect(Buffs.RaptorForm)) - return Gauge.RaptorFury == 0 && LevelChecked(TwinSnakes) - ? TwinSnakes - : OriginalHook(TrueStrike); - - if (HasEffect(Buffs.CoeurlForm)) - { - if (Gauge.CoeurlFury == 0 && LevelChecked(Demolish)) - { - if (!OnTargetsRear() && - TargetNeedsPositionals() && - !HasEffect(Buffs.TrueNorth) && - ActionReady(TrueNorth) && - useTrueNorthIfEnabled) - return TrueNorth; - - return Demolish; - } - - if (LevelChecked(SnapPunch)) - { - if (!OnTargetsFlank() && - TargetNeedsPositionals() && - !HasEffect(Buffs.TrueNorth) && - ActionReady(TrueNorth) && - useTrueNorthIfEnabled) - return TrueNorth; - - return OriginalHook(SnapPunch); - } - } - - return actionId; - } -} - -internal class MNKOpenerLogic : MNK -{ - private OpenerState currentState = OpenerState.PrePull; - - public uint OpenerStep; - - public uint PrePullStep; - - private static uint OpenerLevel => 100; - - public static bool LevelChecked => LocalPlayer.Level >= OpenerLevel; - - private static bool CanOpener => HasCooldowns() && LevelChecked; - - public OpenerState CurrentState - { - get => currentState; - set - { - if (value != currentState) - { - if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); - if (value == OpenerState.InOpener) OpenerStep = 1; - - if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) - { - if (value == OpenerState.FailedOpener) - Svc.Log.Information($"Opener Failed at step {OpenerStep}"); - - ResetOpener(); - } - if (value == OpenerState.OpenerFinished) Svc.Log.Information("Opener Finished"); - - currentState = value; - } - } - } - - private static bool HasCooldowns() - { - if (GetRemainingCharges(PerfectBalance) < 2) - return false; - - if (!ActionReady(Brotherhood)) - return false; - - if (!ActionReady(RiddleOfFire)) - return false; - - if (!ActionReady(RiddleOfWind)) - return false; - - if (!ActionReady(Meditation) && Gauge.Chakra < 5) - return false; - - if (Gauge.Nadi != Nadi.NONE) - return false; - - if (Gauge.RaptorFury != 0) - return false; - - if (Gauge.CoeurlFury != 0) - return false; - - return true; - } - - private bool DoPrePullSteps(ref uint actionID) - { - if (!LevelChecked) return false; - - if (CanOpener && PrePullStep == 0) PrePullStep = 1; - - if (!HasCooldowns()) PrePullStep = 0; - - if (CurrentState == OpenerState.PrePull && PrePullStep > 0) - { - if (Gauge.Chakra < 5 && PrePullStep == 1) - { - actionID = ForbiddenMeditation; - - return true; - } - - if (!HasEffect(Buffs.FormlessFist) && - !HasEffect(Buffs.RaptorForm) && PrePullStep == 1) - { - actionID = FormShift; - - return true; - } - - if (WasLastAction(DragonKick) && PrePullStep == 1) CurrentState = OpenerState.InOpener; - else if (PrePullStep == 1) actionID = DragonKick; - - if (ActionWatching.CombatActions.Count > 2 && InCombat()) - CurrentState = OpenerState.FailedOpener; - - return true; - } - PrePullStep = 0; - - return false; - } - - private bool DoSlOpener(ref uint actionID) - { - if (!LevelChecked) - return false; - - if (currentState == OpenerState.InOpener) - { - if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && - CanWeave(ActionWatching.LastWeaponskill) && - Gauge.Chakra >= 5 && - OpenerStep > 9) - { - actionID = TheForbiddenChakra; - - return true; - } - - if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) - OpenerStep++; - else if (OpenerStep == 1) actionID = PerfectBalance; - - if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TwinSnakes; - - if (WasLastWeaponskill(Demolish) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = Demolish; - - if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Brotherhood; - - if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = LeapingOpo; - - if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = TheForbiddenChakra; - - if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; - - if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = RisingPhoenix; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; - - if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = WindsReply; - - if (WasLastWeaponskill(FiresReply) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = FiresReply; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; - - if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) - OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; - - if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; - - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; - - if (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || - (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || - (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || - (actionID is Brotherhood && IsOnCooldown(Brotherhood))) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - Svc.Log.Debug($"Failed at {actionID}"); - CurrentState = OpenerState.FailedOpener; - - return false; - } - - return true; - } - - return false; - } - - private bool DoLlOpener(ref uint actionID) - { - if (!LevelChecked) - return false; - - if (currentState == OpenerState.InOpener) - { - if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && - CanWeave(ActionWatching.LastWeaponskill) && - Gauge.Chakra >= 5 && - OpenerStep > 9) - { - actionID = TheForbiddenChakra; - - return true; - } - - if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) - OpenerStep++; - else if (OpenerStep == 1) actionID = PerfectBalance; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = LeapingOpo; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = DragonKick; - - if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Brotherhood; - - if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = LeapingOpo; - - if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = TheForbiddenChakra; - - if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; - - if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = ElixirBurst; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; - - if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = WindsReply; - - if (WasLastWeaponskill(FiresReply) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = FiresReply; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; - - if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) - OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; - - if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; - - if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; - - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; - - if (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || - (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || - (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || - (actionID is Brotherhood && IsOnCooldown(Brotherhood))) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - Svc.Log.Debug($"Failed at {actionID}"); - CurrentState = OpenerState.FailedOpener; - - return false; - } - - return true; - } - - return false; - } - - private void ResetOpener() - { - PrePullStep = 0; - OpenerStep = 0; - } - - public bool DoFullOpener(ref uint actionID, int selectedOpener) - { - if (!LevelChecked) - return false; - - if (CurrentState == OpenerState.PrePull) - if (DoPrePullSteps(ref actionID)) - return true; - - if (CurrentState == OpenerState.InOpener) - switch (selectedOpener) - { - case 0 when DoLlOpener(ref actionID): - - case 1 when DoSlOpener(ref actionID): - return true; - } - - if (!InCombat()) - { - ResetOpener(); - CurrentState = OpenerState.PrePull; - } - - return false; - } -} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/JobHelpers/NIN.cs b/XIVSlothCombo/Combos/JobHelpers/NIN.cs deleted file mode 100644 index 9af849a29..000000000 --- a/XIVSlothCombo/Combos/JobHelpers/NIN.cs +++ /dev/null @@ -1,648 +0,0 @@ -using Dalamud.Game.ClientState.Conditions; -using Dalamud.Game.ClientState.JobGauge.Types; -using ECommons.DalamudServices; -using XIVSlothCombo.Combos.JobHelpers.Enums; -using XIVSlothCombo.CustomComboNS.Functions; -using XIVSlothCombo.Extensions; - -namespace XIVSlothCombo.Combos.JobHelpers -{ - internal class NIN - { - internal class NINHelper : PvE.NIN - { - internal static bool TrickDebuff => TargetHasTrickDebuff(); - private static bool TargetHasTrickDebuff() - { - return CustomComboFunctions.TargetHasEffect(Debuffs.TrickAttack) || CustomComboFunctions.TargetHasEffect(Debuffs.KunaisBane); - } - - internal static bool MugDebuff => TargetHasMugDebuff(); - - private static bool TargetHasMugDebuff() - { - return CustomComboFunctions.TargetHasEffect(Debuffs.Mug) || CustomComboFunctions.TargetHasEffect(Debuffs.Dokumori); - } - - internal static bool InMudra = false; - } - - internal class MudraCasting : PvE.NIN - { - /// Checks if the player is in a state to be able to cast a ninjitsu. - private static bool CanCast() - { - if (NINHelper.InMudra) return true; - var gcd = CustomComboFunctions.GetCooldown(GustSlash).CooldownTotal; - - if (gcd == 0.5) return true; - - if (CustomComboFunctions.GetRemainingCharges(Ten) == 0 && - !CustomComboFunctions.HasEffect(Buffs.Mudra) && - !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) - return false; - - return true; - } - - - private MudraState currentMudra = MudraState.None; - public MudraState CurrentMudra - { - get - { - return currentMudra; - } - set - { - if (value == MudraState.None) - { - justResetMudra = true; - } - else - { - justResetMudra = false; - } - - currentMudra = value; - } - } - - /// Simple method of casting Fuma Shuriken. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastFumaShuriken(ref uint actionID) - { - if (FumaShuriken.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingFumaShuriken) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Ten); - CurrentMudra = MudraState.CastingFumaShuriken; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - - /// Simple method of casting Raiton. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastRaiton(ref uint actionID) - { - if (Raiton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingRaiton) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Chi); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Raiton) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Ten); - CurrentMudra = MudraState.CastingRaiton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Katon. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastKaton(ref uint actionID) - { - if (Katon.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingKaton) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Ten); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Katon) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Chi); - CurrentMudra = MudraState.CastingKaton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Hyoton. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastHyoton(ref uint actionID) - { - if (Hyoton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHyoton) - { - if (!CanCast() || CustomComboFunctions.HasEffect(Buffs.Kassatsu)) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Jin); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Ten); - CurrentMudra = MudraState.CastingHyoton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Huton. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastHuton(ref uint actionID) - { - if (Huton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHuton) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Jin); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) - { - actionID = CustomComboFunctions.OriginalHook(Ten); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Huton) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Chi); - CurrentMudra = MudraState.CastingHuton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Doton. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastDoton(ref uint actionID) - { - if (Doton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingDoton) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Jin); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) - { - actionID = CustomComboFunctions.OriginalHook(Chi); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Doton) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Ten); - CurrentMudra = MudraState.CastingDoton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Suiton. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastSuiton(ref uint actionID) - { - if (Suiton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingSuiton) - { - if (!CanCast()) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Chi); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Raiton) - { - actionID = CustomComboFunctions.OriginalHook(Jin); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is Suiton) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Ten); - CurrentMudra = MudraState.CastingSuiton; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Goka Mekkyaku. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastGokaMekkyaku(ref uint actionID) - { - if (GokaMekkyaku.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingGokaMekkyaku) - { - if (!CanCast() || !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Ten); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is GokaMekkyaku) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Chi); - CurrentMudra = MudraState.CastingGokaMekkyaku; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - /// Simple method of casting Hyosho Ranryu. - /// The actionID from the combo. - /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. - public bool CastHyoshoRanryu(ref uint actionID) - { - if (HyoshoRanryu.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHyoshoRanryu) - { - if (!CanCast() || !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) - { - CurrentMudra = MudraState.None; - return false; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) - { - actionID = CustomComboFunctions.OriginalHook(Jin); - return true; - } - - if (CustomComboFunctions.OriginalHook(Ninjutsu) is HyoshoRanryu) - { - actionID = CustomComboFunctions.OriginalHook(Ninjutsu); - return true; - } - - actionID = CustomComboFunctions.OriginalHook(Chi); - CurrentMudra = MudraState.CastingHyoshoRanryu; - return true; - } - - CurrentMudra = MudraState.None; - return false; - } - - private bool justResetMudra = false; - public bool ContinueCurrentMudra(ref uint actionID) - { - if ((CustomComboFunctions.WasLastAction(FumaShuriken) || - CustomComboFunctions.WasLastAction(Katon) || - CustomComboFunctions.WasLastAction(Raiton) || - CustomComboFunctions.WasLastAction(Hyoton) || - CustomComboFunctions.WasLastAction(Huton) || - CustomComboFunctions.WasLastAction(Doton) || - CustomComboFunctions.WasLastAction(Suiton) || - CustomComboFunctions.WasLastAction(GokaMekkyaku) || - CustomComboFunctions.WasLastAction(HyoshoRanryu)) && - !justResetMudra) - CurrentMudra = MudraState.None; - - - return CurrentMudra switch - { - MudraState.None => false, - MudraState.CastingFumaShuriken => CastFumaShuriken(ref actionID), - MudraState.CastingKaton => CastKaton(ref actionID), - MudraState.CastingRaiton => CastRaiton(ref actionID), - MudraState.CastingHyoton => CastHyoton(ref actionID), - MudraState.CastingHuton => CastHuton(ref actionID), - MudraState.CastingDoton => CastDoton(ref actionID), - MudraState.CastingSuiton => CastSuiton(ref actionID), - MudraState.CastingGokaMekkyaku => CastGokaMekkyaku(ref actionID), - MudraState.CastingHyoshoRanryu => CastHyoshoRanryu(ref actionID), - _ => false, - }; - } - - public enum MudraState - { - None, - CastingFumaShuriken, - CastingKaton, - CastingRaiton, - CastingHyoton, - CastingHuton, - CastingDoton, - CastingSuiton, - CastingGokaMekkyaku, - CastingHyoshoRanryu - - } - } - - internal class NINOpenerLogic : PvE.NIN - { - private static bool HasCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(Ten) < 1) return false; - if (CustomComboFunctions.IsOnCooldown(Mug)) return false; - if (CustomComboFunctions.IsOnCooldown(TenChiJin)) return false; - if (CustomComboFunctions.IsOnCooldown(PhantomKamaitachi)) return false; - if (CustomComboFunctions.IsOnCooldown(Bunshin)) return false; - if (CustomComboFunctions.IsOnCooldown(DreamWithinADream)) return false; - if (CustomComboFunctions.IsOnCooldown(Kassatsu)) return false; - if (CustomComboFunctions.IsOnCooldown(TrickAttack)) return false; - - return true; - } - - private static uint OpenerLevel => 100; - - public uint PrePullStep = 1; - - private uint openerStep = 1; - - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; - - private static bool CanOpener => HasCooldowns() && LevelChecked; - - private OpenerState currentState = OpenerState.OpenerFinished; - - public OpenerState CurrentState - { - get - { - return currentState; - } - set - { - if (value != currentState) - { - if (value == OpenerState.PrePull) PrePullStep = 1; - if (value == OpenerState.InOpener) OpenerStep = 1; - if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { PrePullStep = 0; OpenerStep = 0; } - - currentState = value; - } - } - } - - public uint OpenerStep - { - get => openerStep; set - { - if (value != openerStep) - { - Svc.Log.Debug($"{value}"); - } - openerStep = value; - } - } - - private bool DoPrePullSteps(ref uint actionID, MudraCasting mudraState) - { - if (!LevelChecked) return false; - - if (CanOpener && PrePullStep == 0 && !CustomComboFunctions.InCombat()) { CurrentState = OpenerState.PrePull; } - - if (CurrentState == OpenerState.PrePull) - { - if (CustomComboFunctions.WasLastAction(Suiton) && PrePullStep == 1) CurrentState = OpenerState.InOpener; - else if (PrePullStep == 1) mudraState.CastSuiton(ref actionID); - - ////Failure states - //if (PrePullStep is (1 or 2) && CustomComboFunctions.InCombat()) { mudraState.CurrentMudra = MudraCasting.MudraState.None; ResetOpener(); } - - return true; - - } - - PrePullStep = 0; - return false; - } - - private bool DoOpener(ref uint actionID, MudraCasting mudraState) - { - if (!LevelChecked) return false; - - if (CurrentState == OpenerState.InOpener) - { - bool inLateWeaveWindow = CustomComboFunctions.CanDelayedWeave(GustSlash, 1, 0); - - if (CustomComboFunctions.WasLastAction(Kassatsu) && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = CustomComboFunctions.OriginalHook(Kassatsu); - - if (CustomComboFunctions.WasLastAction(SpinningEdge) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = CustomComboFunctions.OriginalHook(SpinningEdge); - - if (CustomComboFunctions.WasLastAction(GustSlash) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = CustomComboFunctions.OriginalHook(GustSlash); - - if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(Mug)) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = CustomComboFunctions.OriginalHook(Mug); - - if (CustomComboFunctions.WasLastAction(Bunshin) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = CustomComboFunctions.OriginalHook(Bunshin); - - if (CustomComboFunctions.WasLastAction(PhantomKamaitachi) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = CustomComboFunctions.OriginalHook(PhantomKamaitachi); - - if (CustomComboFunctions.WasLastAction(ArmorCrush) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = CustomComboFunctions.OriginalHook(ArmorCrush); - - if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(TrickAttack)) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8 && inLateWeaveWindow) actionID = CustomComboFunctions.OriginalHook(TrickAttack); - - if (CustomComboFunctions.WasLastAction(HyoshoRanryu) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) mudraState.CastHyoshoRanryu(ref actionID); - - if (CustomComboFunctions.WasLastAction(DreamWithinADream) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = CustomComboFunctions.OriginalHook(DreamWithinADream); - - if (CustomComboFunctions.WasLastAction(Raiton) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) mudraState.CastRaiton(ref actionID); - - if (CustomComboFunctions.WasLastAction(TenChiJin) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = CustomComboFunctions.OriginalHook(TenChiJin); - - if (CustomComboFunctions.WasLastAction(TCJFumaShurikenTen) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = CustomComboFunctions.OriginalHook(Ten); - - if (CustomComboFunctions.WasLastAction(TCJRaiton) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = CustomComboFunctions.OriginalHook(Chi); - - if (CustomComboFunctions.WasLastAction(TCJSuiton) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = CustomComboFunctions.OriginalHook(Jin); - - if (CustomComboFunctions.WasLastAction(Meisui) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = CustomComboFunctions.OriginalHook(Meisui); - - if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); - - if (CustomComboFunctions.WasLastAction(ZeshoMeppo) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = CustomComboFunctions.OriginalHook(Bhavacakra); - - if (CustomComboFunctions.WasLastAction(TenriJendo) && OpenerStep == 19) OpenerStep++; - else if (OpenerStep == 19) actionID = CustomComboFunctions.OriginalHook(TenriJendo); - - if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 20) OpenerStep++; - else if (OpenerStep == 20) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); - - if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(Bhavacakra)) && OpenerStep == 21) OpenerStep++; - else if (OpenerStep == 21) actionID = CustomComboFunctions.OriginalHook(Bhavacakra); - - if (CustomComboFunctions.WasLastAction(Raiton) && OpenerStep == 22) OpenerStep++; - else if (OpenerStep == 22) mudraState.CastRaiton(ref actionID); - - if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 23) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 23) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); - - - //Failure states - if ((OpenerStep is 13 or 14 or 15 && CustomComboFunctions.IsMoving) || - (OpenerStep is 8 && !CustomComboFunctions.HasEffect(Buffs.ShadowWalker)) || - (OpenerStep is 18 or 21 && CustomComboFunctions.GetJobGauge().Ninki < 40) || - (OpenerStep is 17 or 20 && !CustomComboFunctions.HasEffect(Buffs.RaijuReady)) || - (OpenerStep is 9 && !CustomComboFunctions.HasEffect(Buffs.Kassatsu))) - ResetOpener(); - - - return true; - } - - return false; - } - - private void ResetOpener() - { - CurrentState = OpenerState.FailedOpener; - } - - private bool openerEventsSetup = false; - - public bool DoFullOpener(ref uint actionID, MudraCasting mudraState) - { - if (!LevelChecked) return false; - - if (!openerEventsSetup) { Svc.Condition.ConditionChange += CheckCombatStatus; openerEventsSetup = true; } - - if (CurrentState == OpenerState.PrePull || CurrentState == OpenerState.FailedOpener) - if (DoPrePullSteps(ref actionID, mudraState)) return true; - - if (CurrentState == OpenerState.InOpener) - if (DoOpener(ref actionID, mudraState)) return true; - - if (CurrentState == OpenerState.OpenerFinished && !CustomComboFunctions.InCombat()) - ResetOpener(); - - return false; - } - - internal void Dispose() - { - Svc.Condition.ConditionChange -= CheckCombatStatus; - } - - private void CheckCombatStatus(ConditionFlag flag, bool value) - { - if (flag == ConditionFlag.InCombat && value == false) ResetOpener(); - } - } - } -} diff --git a/XIVSlothCombo/Combos/PvE/ADV.cs b/XIVSlothCombo/Combos/PvE/ADV.cs deleted file mode 100644 index e0fe12acd..000000000 --- a/XIVSlothCombo/Combos/PvE/ADV.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace XIVSlothCombo.Combos.PvE -{ - internal static class ADV - { - public const byte ClassID = 0; - public const byte JobID = 0; - - public const uint - LucidDreaming = 1204; - - public static class Buffs - { - public const ushort - Placeholder = 0; - } - - public static class Debuffs - { - public const ushort - Placeholder = 0; - } - - public static class Levels - { - public const byte - Placeholder = 0; - } - - } -} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/ADV/ADV.cs b/XIVSlothCombo/Combos/PvE/ADV/ADV.cs new file mode 100644 index 000000000..133dc27ac --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/ADV/ADV.cs @@ -0,0 +1,28 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class ADV +{ + public const byte ClassID = 0; + public const byte JobID = 0; + + public const uint + LucidDreaming = 1204; + + public static class Buffs + { + public const ushort + Placeholder = 0; + } + + public static class Debuffs + { + public const ushort + Placeholder = 0; + } + + public static class Levels + { + public const byte + Placeholder = 0; + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/ADV/ADV_Config.cs b/XIVSlothCombo/Combos/PvE/ADV/ADV_Config.cs new file mode 100644 index 000000000..776db70df --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/ADV/ADV_Config.cs @@ -0,0 +1,17 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class ADV +{ + internal static class Config + { + //Config goes here + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + //Presets + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/ALL.cs b/XIVSlothCombo/Combos/PvE/ALL.cs deleted file mode 100644 index f6d049e16..000000000 --- a/XIVSlothCombo/Combos/PvE/ALL.cs +++ /dev/null @@ -1,252 +0,0 @@ -using ECommons.DalamudServices; -using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; - -namespace XIVSlothCombo.Combos.PvE -{ - internal class All - { - public const byte JobID = 0; - - public const uint - Rampart = 7531, - SecondWind = 7541, - TrueNorth = 7546, - Addle = 7560, - Swiftcast = 7561, - LucidDreaming = 7562, - Resurrection = 173, - Raise = 125, - Provoke = 7533, - Shirk = 7537, - Reprisal = 7535, - Esuna = 7568, - Rescue = 7571, - SolidReason = 232, - AgelessWords = 215, - Sleep = 25880, - WiseToTheWorldMIN = 26521, - WiseToTheWorldBTN = 26522, - LowBlow = 7540, - Bloodbath = 7542, - HeadGraze = 7551, - FootGraze = 7553, - LegGraze = 7554, - Feint = 7549, - Interject = 7538, - Peloton = 7557, - LegSweep = 7863, - Repose = 16560, - Sprint = 3; - private const uint - IsleSprint = 31314; - - public static class Buffs - { - public const ushort - Weakness = 43, - Medicated = 49, - Bloodbath = 84, - Swiftcast = 167, - Rampart = 1191, - Peloton = 1199, - LucidDreaming = 1204, - TrueNorth = 1250, - Sprint = 50; - } - - public static class Debuffs - { - public const ushort - Sleep = 3, - Bind = 13, - Heavy = 14, - Addle = 1203, - Reprisal = 1193, - Feint = 1195; - } - - /// - /// Quick Level, Offcooldown, spellweave, and MP check of Lucid Dreaming - /// - /// action id to check weave - /// Player MP less than Threshold check - /// Spell Weave check by default - /// - public static bool CanUseLucid(uint actionID, int MPThreshold, bool weave = true) => - CustomComboFunctions.ActionReady(LucidDreaming) - && CustomComboFunctions.LocalPlayer.CurrentMp <= MPThreshold - && (!weave || CustomComboFunctions.CanSpellWeave(actionID)); - - internal class ALL_IslandSanctuary_Sprint : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_IslandSanctuary_Sprint; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is Sprint && Svc.ClientState.TerritoryType is 1055) return IsleSprint; - else return actionID; - } - } - - //Tank Features - internal class ALL_Tank_Interrupt : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Tank_Interrupt; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is LowBlow or PLD.ShieldBash) - { - if (CanInterruptEnemy() && ActionReady(Interject)) - return Interject; - if (ActionReady(LowBlow)) - return LowBlow; - if (actionID == PLD.ShieldBash && IsOnCooldown(LowBlow)) - return actionID; - } - - return actionID; - } - } - - internal class ALL_Tank_Reprisal : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Tank_Reprisal; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is Reprisal) - { - if (TargetHasEffectAny(Debuffs.Reprisal) && IsOffCooldown(Reprisal)) - return OriginalHook(11); - } - - return actionID; - } - } - - //Healer Features - internal class ALL_Healer_Raise : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Healer_Raise; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if ((actionID is WHM.Raise or AST.Ascend or SGE.Egeiro) - || (actionID is SCH.Resurrection && LocalPlayer.ClassJob.Id is SCH.JobID)) - { - if (ActionReady(Swiftcast)) - return Swiftcast; - - if (actionID == WHM.Raise && IsEnabled(CustomComboPreset.WHM_ThinAirRaise) && ActionReady(WHM.ThinAir) && !HasEffect(WHM.Buffs.ThinAir)) - return WHM.ThinAir; - - return actionID; - } - - return actionID; - } - } - - //Caster Features - internal class ALL_Caster_Addle : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Caster_Addle; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is Addle) - { - if (TargetHasEffectAny(Debuffs.Addle) && IsOffCooldown(Addle)) - return OriginalHook(11); - } - - return actionID; - } - } - - internal class ALL_Caster_Raise : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Caster_Raise; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if ((actionID is BLU.AngelWhisper or RDM.Verraise) - || (actionID is SMN.Resurrection && LocalPlayer.ClassJob.Id is SMN.JobID)) - { - if (HasEffect(Buffs.Swiftcast) || HasEffect(RDM.Buffs.Dualcast)) - return actionID; - if (IsOffCooldown(Swiftcast)) - return Swiftcast; - if (LocalPlayer.ClassJob.Id is RDM.JobID && - ActionReady(RDM.Vercure)) - return RDM.Vercure; - } - - return actionID; - } - } - - //Melee DPS Features - internal class ALL_Melee_Feint : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Melee_Feint; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is Feint) - { - if (TargetHasEffectAny(Debuffs.Feint) && IsOffCooldown(Feint)) - return OriginalHook(11); - } - - return actionID; - } - } - - internal class ALL_Melee_TrueNorth : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Melee_TrueNorth; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is TrueNorth) - { - if (HasEffect(Buffs.TrueNorth)) - return OriginalHook(11); - } - - return actionID; - } - } - - //Ranged Physical Features - internal class ALL_Ranged_Mitigation : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Ranged_Mitigation; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is BRD.Troubadour or MCH.Tactician or DNC.ShieldSamba) - { - if ((HasEffectAny(BRD.Buffs.Troubadour) || HasEffectAny(MCH.Buffs.Tactician) || HasEffectAny(DNC.Buffs.ShieldSamba)) && IsOffCooldown(actionID)) - return OriginalHook(11); - } - - return actionID; - } - } - - internal class ALL_Ranged_Interrupt : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Ranged_Interrupt; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - return (actionID is FootGraze && CanInterruptEnemy() && ActionReady(HeadGraze)) ? HeadGraze : actionID; - } - } - } -} - diff --git a/XIVSlothCombo/Combos/PvE/ALL/ALL.cs b/XIVSlothCombo/Combos/PvE/ALL/ALL.cs new file mode 100644 index 000000000..4e04b5953 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/ALL/ALL.cs @@ -0,0 +1,253 @@ +using ECommons.DalamudServices; +using XIVSlothCombo.CustomComboNS; +using XIVSlothCombo.CustomComboNS.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class All +{ + public const byte JobID = 0; + + public const uint + Rampart = 7531, + SecondWind = 7541, + TrueNorth = 7546, + Addle = 7560, + Swiftcast = 7561, + LucidDreaming = 7562, + Resurrection = 173, + Raise = 125, + Provoke = 7533, + Shirk = 7537, + Reprisal = 7535, + Esuna = 7568, + Rescue = 7571, + SolidReason = 232, + AgelessWords = 215, + Sleep = 25880, + WiseToTheWorldMIN = 26521, + WiseToTheWorldBTN = 26522, + LowBlow = 7540, + Bloodbath = 7542, + HeadGraze = 7551, + FootGraze = 7553, + LegGraze = 7554, + Feint = 7549, + Interject = 7538, + Peloton = 7557, + LegSweep = 7863, + Repose = 16560, + Sprint = 3; + + private const uint + IsleSprint = 31314; + + /// + /// Quick Level, Offcooldown, spellweave, and MP check of Lucid Dreaming + /// + /// action id to check weave + /// Player MP less than Threshold check + /// Spell Weave check by default + /// + public static bool CanUseLucid(uint actionID, int MPThreshold, bool weave = true) + { + return CustomComboFunctions.ActionReady(LucidDreaming) + && CustomComboFunctions.LocalPlayer.CurrentMp <= MPThreshold + && (!weave || CustomComboFunctions.CanSpellWeave(actionID)); + } + + public static class Buffs + { + public const ushort + Weakness = 43, + Medicated = 49, + Bloodbath = 84, + Swiftcast = 167, + Rampart = 1191, + Peloton = 1199, + LucidDreaming = 1204, + TrueNorth = 1250, + Sprint = 50; + } + + public static class Debuffs + { + public const ushort + Sleep = 3, + Bind = 13, + Heavy = 14, + Addle = 1203, + Reprisal = 1193, + Feint = 1195; + } + + internal class ALL_IslandSanctuary_Sprint : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_IslandSanctuary_Sprint; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Sprint && Svc.ClientState.TerritoryType is 1055 + ? IsleSprint + : actionID; + } + } + + //Tank Features + internal class ALL_Tank_Interrupt : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Tank_Interrupt; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + switch (actionID) + { + case LowBlow or PLD.ShieldBash when CanInterruptEnemy() && ActionReady(Interject): + return Interject; + + case LowBlow or PLD.ShieldBash when ActionReady(LowBlow): + return LowBlow; + + case LowBlow or PLD.ShieldBash when actionID == PLD.ShieldBash && IsOnCooldown(LowBlow): + return actionID; + + default: + return actionID; + } + } + } + + internal class ALL_Tank_Reprisal : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Tank_Reprisal; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Reprisal && TargetHasEffectAny(Debuffs.Reprisal) && IsOffCooldown(Reprisal) + ? OriginalHook(11) + : actionID; + } + } + + //Healer Features + internal class ALL_Healer_Raise : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Healer_Raise; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + switch (actionID) + { + case WHM.Raise or AST.Ascend or SGE.Egeiro: + case SCH.Resurrection when LocalPlayer.ClassJob.Id is SCH.JobID: + { + if (ActionReady(Swiftcast)) + return Swiftcast; + + if (actionID == WHM.Raise && IsEnabled(CustomComboPreset.WHM_ThinAirRaise) && + ActionReady(WHM.ThinAir) && !HasEffect(WHM.Buffs.ThinAir)) + return WHM.ThinAir; + + return actionID; + } + + default: + return actionID; + } + } + } + + //Caster Features + internal class ALL_Caster_Addle : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Caster_Addle; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Addle && TargetHasEffectAny(Debuffs.Addle) && IsOffCooldown(Addle) + ? OriginalHook(11) + : actionID; + } + } + + internal class ALL_Caster_Raise : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Caster_Raise; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + switch (actionID) + { + case BLU.AngelWhisper or RDM.Verraise: + case SMN.Resurrection when LocalPlayer.ClassJob.Id is SMN.JobID: + { + if (HasEffect(Buffs.Swiftcast) || HasEffect(RDM.Buffs.Dualcast)) + return actionID; + + if (IsOffCooldown(Swiftcast)) + return Swiftcast; + + if (LocalPlayer.ClassJob.Id is RDM.JobID && + ActionReady(RDM.Vercure)) + return RDM.Vercure; + + break; + } + } + + return actionID; + } + } + + //Melee DPS Features + internal class ALL_Melee_Feint : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Melee_Feint; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Feint && TargetHasEffectAny(Debuffs.Feint) && IsOffCooldown(Feint) + ? OriginalHook(11) + : actionID; + } + } + + internal class ALL_Melee_TrueNorth : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Melee_TrueNorth; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is TrueNorth && HasEffect(Buffs.TrueNorth) + ? OriginalHook(11) + : actionID; + } + } + + //Ranged Physical Features + internal class ALL_Ranged_Mitigation : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Ranged_Mitigation; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is BRD.Troubadour or MCH.Tactician or DNC.ShieldSamba && + (HasEffectAny(BRD.Buffs.Troubadour) || HasEffectAny(MCH.Buffs.Tactician) || + HasEffectAny(DNC.Buffs.ShieldSamba)) && IsOffCooldown(actionID) + ? OriginalHook(11) + : actionID; + } + } + + internal class ALL_Ranged_Interrupt : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.ALL_Ranged_Interrupt; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is FootGraze && CanInterruptEnemy() && ActionReady(HeadGraze) + ? HeadGraze + : actionID; + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/ALL/ALL_Config.cs b/XIVSlothCombo/Combos/PvE/ALL/ALL_Config.cs new file mode 100644 index 000000000..fc2b1606d --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/ALL/ALL_Config.cs @@ -0,0 +1,17 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class ALL +{ + internal static class Config + { + //Config goes here + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + //Presets + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/BLM.cs b/XIVSlothCombo/Combos/PvE/BLM.cs deleted file mode 100644 index b7446191d..000000000 --- a/XIVSlothCombo/Combos/PvE/BLM.cs +++ /dev/null @@ -1,513 +0,0 @@ -using Dalamud.Game.ClientState.JobGauge.Types; -using System; -using System.Collections.Generic; -using XIVSlothCombo.Combos.JobHelpers; -using XIVSlothCombo.Combos.PvE.Content; -using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; -using XIVSlothCombo.Data; -using XIVSlothCombo.Extensions; - -namespace XIVSlothCombo.Combos.PvE -{ - internal class BLM - { - public const byte ClassID = 7; - public const byte JobID = 25; - - public const uint - Fire = 141, - Blizzard = 142, - Thunder = 144, - Fire2 = 147, - Transpose = 149, - Fire3 = 152, - Thunder3 = 153, - Blizzard3 = 154, - AetherialManipulation = 155, - Scathe = 156, - Manafont = 158, - Freeze = 159, - Flare = 162, - LeyLines = 3573, - Sharpcast = 3574, - Blizzard4 = 3576, - Fire4 = 3577, - BetweenTheLines = 7419, - Thunder4 = 7420, - Triplecast = 7421, - Foul = 7422, - Thunder2 = 7447, - Despair = 16505, - UmbralSoul = 16506, - Xenoglossy = 16507, - Blizzard2 = 25793, - HighFire2 = 25794, - HighBlizzard2 = 25795, - Amplifier = 25796, - Paradox = 25797, - HighThunder = 36986, - HighThunder2 = 36987, - FlareStar = 36989; - - public static class Buffs - { - public const ushort - Thundercloud = 164, - Firestarter = 165, - LeyLines = 737, - CircleOfPower = 738, - Sharpcast = 867, - Triplecast = 1211, - Thunderhead = 3870; - } - - public static class Debuffs - { - public const ushort - Thunder = 161, - Thunder2 = 162, - Thunder3 = 163, - Thunder4 = 1210, - HighThunder = 3871, - HighThunder2 = 3872; - } - - public static class Traits - { - public const uint - UmbralHeart = 295, - EnhancedPolyglot = 297, - AspectMasteryIII = 459, - EnhancedFoul = 461, - EnhancedManafont = 463, - Enochian = 460, - EnhancedPolyglotII = 615; - } - - public static class MP - { - public const int MaxMP = 10000; - - public const int AllMPSpells = 800; //"ALL MP" spell. Only caring about the absolute minimum. - public static int FireI => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Fire)); - public static int FlareAoE => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Flare)); - public static int FireAoE => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Fire2)); - public static int FireIII => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Fire3)); - public static int BlizzardAoE => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Blizzard2)); - public static int BlizzardI => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(Blizzard)); - public static int Freeze => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(BLM.Freeze)); - public static int Despair => CustomComboFunctions.GetResourceCost(CustomComboFunctions.OriginalHook(BLM.Despair)); - } - - // Debuff Pairs of Actions and Debuff - public static readonly Dictionary - ThunderList = new() - { - { Thunder, Debuffs.Thunder }, - { Thunder2, Debuffs.Thunder2 }, - { Thunder3, Debuffs.Thunder3 }, - { Thunder4, Debuffs.Thunder4 }, - { HighThunder, Debuffs.HighThunder }, - { HighThunder2, Debuffs.HighThunder2 } - }; - - public static class Config - { - public static UserBool - BLM_Adv_Xeno_Burst = new("BLM_Adv_Xeno_Burst"); - - public static UserBoolArray - BLM_Adv_Cooldowns_Choice = new("BLM_Adv_Cooldowns_Choice"), - BLM_AoE_Adv_Cooldowns_Choice = new("BLM_AoE_Adv_Cooldowns_Choice"), - BLM_Adv_Movement_Choice = new("BLM_Adv_Movement_Choice"); - - public static UserInt - BLM_VariantCure = new("BLM_VariantCure"), - BLM_Adv_Cooldowns = new("BLM_Adv_Cooldowns"), - BLM_Adv_Thunder = new("BLM_Adv_Thunder"), - BLM_Adv_Rotation_Options = new("BLM_Adv_Rotation_Options"), - BLM_Advanced_OpenerSelection = new("BLM_Advanced_OpenerSelection"), - BLM_ST_Adv_ThunderHP = new("BLM_ST_Adv_ThunderHP"), - BLM_AoE_Adv_ThunderHP = new("BLM_AoE_Adv_ThunderHP"), - BLM_AoE_Adv_ThunderUptime = new("BLM_AoE_Adv_ThunderUptime"), - BLM_Adv_ThunderCloud = new("BLM_Adv_ThunderCloud"), - BLM_Adv_InitialCast = new("BLM_Adv_InitialCast"); - - public static UserFloat - BLM_AstralFire_Refresh = new("BLM_AstralFire_Refresh"); - } - - internal class BLM_ST_SimpleMode : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_ST_SimpleMode; - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID != Fire) return actionID; - - var gauge = GetJobGauge(); - var maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; - var maxPolyglotCD = maxPolyglot * 30000; - var remainingPolyglotCD = Math.Max(0, (maxPolyglot - gauge.PolyglotStacks) * 30000 + (gauge.EnochianTimer - 30000)); - var curMp = LocalPlayer.CurrentMp; - int nextMpGain = gauge.UmbralIceStacks switch - { - 0 => 0, - 1 => 2500, - 2 => 5000, - 3 => 10000, - _ => 0 - }; - var thunderDebuff = FindEffect(ThunderList[OriginalHook(Thunder)], CurrentTarget, LocalPlayer.GameObjectId); - var elementTimer = gauge.ElementTimeRemaining / 1000f; - var gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(Fire)); - var canSwiftB3 = IsOffCooldown(All.Swiftcast) || ActionReady(Triplecast) || GetBuffStacks(Buffs.Triplecast) > 0; - - if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && - IsEnabled(Variant.VariantCure) && - PlayerHealthPercentageHp() <= Config.BLM_VariantCure) - return Variant.VariantCure; - - if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && - IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart) && - CanSpellWeave(actionID)) - return Variant.VariantRampart; - - if (HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1) - { - if (thunderDebuff is null || thunderDebuff.RemainingTime < 3) - return OriginalHook(Thunder); - } - - if (ActionReady(Amplifier) && remainingPolyglotCD >= 20000 && CanSpellWeave(ActionWatching.LastSpell)) - return Amplifier; - - if (remainingPolyglotCD < 6000 && gcdsInTimer > 2 && gauge.HasPolyglotStacks()) - return Xenoglossy.LevelChecked() ? Xenoglossy : Foul; - - if (IsMoving) - { - if (ActionReady(Amplifier) && gauge.PolyglotStacks < maxPolyglot) - return Amplifier; - - if (gauge.HasPolyglotStacks()) - return Xenoglossy.LevelChecked() ? Xenoglossy : Foul; - } - - if (CanSpellWeave(actionID) && ActionReady(LeyLines)) - return LeyLines; - - if (gauge.InAstralFire) - { - if (gauge.IsParadoxActive && gcdsInTimer < 2 && curMp >= MP.FireI) - return Paradox; - - if (HasEffect(Buffs.Firestarter)) - { - if (gcdsInTimer < 2 || curMp < MP.FireI || WasLastAbility(Transpose)) - return Fire3; - } - - if (curMp < MP.FireI && Despair.LevelChecked() && curMp >= MP.Despair) - { - if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0) - return Triplecast; - - return Despair; - } - - if (curMp == 0 && FlareStar.LevelChecked() && gauge.AstralSoulStacks == 6) - return FlareStar; - - if (Fire4.LevelChecked()) - { - if (gcdsInTimer > 1 && curMp >= MP.FireI) - return Fire4; - } - - if (curMp >= MP.FireI) - return Fire; - - if (ActionReady(Manafont)) - return Manafont; - - if (ActionReady(Blizzard3) && !canSwiftB3) - return Blizzard3; - - if (ActionReady(Transpose)) - return Transpose; - - } - if (gauge.InUmbralIce) - { - if (ActionReady(Blizzard3) && gauge.UmbralIceStacks < 3) - { - if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0) - return Triplecast; - - if (GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast)) - return All.Swiftcast; - - if (HasEffect(All.Buffs.Swiftcast) || GetBuffStacks(Buffs.Triplecast) > 0) - return Blizzard3; - } - - if (Blizzard4.LevelChecked() && gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) - return Blizzard4; - - if (gauge.IsParadoxActive) - return Paradox; - - if (gauge.HasPolyglotStacks()) - return Xenoglossy.LevelChecked() ? Xenoglossy : Foul; - - if (curMp + nextMpGain >= 7500 && (LocalPlayer.CastActionId == Blizzard || WasLastSpell(Blizzard) || WasLastSpell(Blizzard4))) - { - if (Fire3.LevelChecked()) - return Fire3; - - return Fire; - } - - if ((curMp + nextMpGain <= 10000 || curMp < 7500)) - return Blizzard; - - if (ActionReady(Transpose) && CanSpellWeave(ActionWatching.LastSpell) && !Fire3.LevelChecked()) - return Transpose; - - if (Fire3.LevelChecked()) - return Fire3; - } - - if (Blizzard3.LevelChecked()) - return Blizzard3; - return actionID; - } - } - - internal class BLM_AoE_SimpleMode : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_AoE_SimpleMode; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is not (Blizzard2 or HighBlizzard2)) return actionID; - - var gauge = GetJobGauge(); - var maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; - var maxPolyglotCD = maxPolyglot * 30000; - var remainingPolyglotCD = Math.Max(0, (maxPolyglot - gauge.PolyglotStacks) * 30000 + (gauge.EnochianTimer - 30000)); - var curMp = LocalPlayer.CurrentMp; - int nextMpGain = gauge.UmbralIceStacks switch - { - 0 => 0, - 1 => 2500, - 2 => 5000, - 3 => 10000, - _ => 0 - }; - var thunderDebuff = FindEffect(ThunderList[OriginalHook(Thunder2)], CurrentTarget, LocalPlayer.GameObjectId); - var elementTimer = gauge.ElementTimeRemaining / 1000f; - var gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(ActionWatching.LastSpell)); - var canSwiftF = TraitLevelChecked(Traits.AspectMasteryIII) && (IsOffCooldown(All.Swiftcast) || ActionReady(Triplecast) || GetBuffStacks(Buffs.Triplecast) > 0); - var canWeave = CanSpellWeave(ActionWatching.LastSpell); - - if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && - IsEnabled(Variant.VariantCure) && - PlayerHealthPercentageHp() <= Config.BLM_VariantCure) - return Variant.VariantCure; - - if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && - IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart) && - canWeave) - return Variant.VariantRampart; - - if (HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && Thunder2.LevelChecked()) - { - if (thunderDebuff is null || thunderDebuff.RemainingTime < 3) - return OriginalHook(Thunder2); - } - - if (ActionReady(Amplifier) && remainingPolyglotCD >= 20000 && canWeave) - return Amplifier; - - if (IsMoving) - { - if (ActionReady(Amplifier) && gauge.PolyglotStacks < maxPolyglot) - return Amplifier; - - if (gauge.HasPolyglotStacks()) - return Foul; - } - - if (canWeave && ActionReady(LeyLines)) - return LeyLines; - - if (gauge.InAstralFire) - { - if (curMp == 0 && FlareStar.LevelChecked() && gauge.AstralSoulStacks == 6) - return FlareStar; - - if (!FlareStar.LevelChecked() && Fire2.LevelChecked() && curMp >= MP.FireAoE && (gauge.UmbralHearts > 1 || !TraitLevelChecked(Traits.UmbralHeart))) - return OriginalHook(Fire2); - - if (Flare.LevelChecked() && curMp >= MP.FlareAoE) - { - if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0 && canWeave) - return Triplecast; - - return Flare; - } - - if (Fire2.LevelChecked()) - { - if (gcdsInTimer > 1 && curMp >= MP.FireAoE) - return OriginalHook(Fire2); - } - - if (ActionReady(Manafont)) - return Manafont; - - if (ActionReady(Transpose) && (!TraitLevelChecked(Traits.AspectMasteryIII) || canSwiftF)) - return Transpose; - - if (ActionReady(Blizzard2) && TraitLevelChecked(Traits.AspectMasteryIII)) - return OriginalHook(Blizzard2); - - } - if (gauge.InUmbralIce) - { - if (ActionWatching.WhichOfTheseActionsWasLast(OriginalHook(Fire2), OriginalHook(Freeze), OriginalHook(Flare), OriginalHook(FlareStar)) == OriginalHook(Freeze) && FlareStar.LevelChecked()) - { - if (ActionReady(Transpose) && canWeave) - return Transpose; - - return OriginalHook(Fire2); - } - - if (ActionReady(OriginalHook(Blizzard2)) && gauge.UmbralIceStacks < 3 && TraitLevelChecked(Traits.AspectMasteryIII)) - { - if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0 && canWeave) - return Triplecast; - - if (GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast) && canWeave) - return All.Swiftcast; - - if (HasEffect(All.Buffs.Swiftcast) || GetBuffStacks(Buffs.Triplecast) > 0) - return OriginalHook(Blizzard2); - } - - if (gauge.UmbralIceStacks < 3 && ActionReady(OriginalHook(Blizzard2))) - return OriginalHook(Blizzard2); - - if (Freeze.LevelChecked() && gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) - return Freeze; - - if (gauge.HasPolyglotStacks()) - return Foul; - - if (BLMHelper.DoubleBlizz()) - { - if (Fire2.LevelChecked()) - return OriginalHook(Fire2); - } - - if (curMp < LocalPlayer.MaxMp) - return Freeze.LevelChecked() ? OriginalHook(Freeze) : OriginalHook(Blizzard2); - - if (ActionReady(Transpose) && ((canWeave && Flare.LevelChecked()) || !TraitLevelChecked(Traits.AspectMasteryIII))) - return Transpose; - - if (Fire2.LevelChecked() && TraitLevelChecked(Traits.AspectMasteryIII)) - return OriginalHook(Fire2); - } - - if (Blizzard2.LevelChecked()) - return OriginalHook(Blizzard2); - return actionID; - } - } - - internal class BLM_Variant_Raise : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Variant_Raise; - - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) => - (actionID is All.Swiftcast && HasEffect(All.Buffs.Swiftcast) && IsEnabled(Variant.VariantRaise)) - ? Variant.VariantRaise - : actionID; - } - - internal class BLM_Scathe_Xeno : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Scathe_Xeno; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) => - (actionID is Scathe && LevelChecked(Xenoglossy) && GetJobGauge().HasPolyglotStacks()) - ? Xenoglossy - : actionID; - } - - internal class BLM_Blizzard_1to3 : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Blizzard_1to3; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - if (actionID is Blizzard && LevelChecked(Freeze) && !GetJobGauge().InUmbralIce) - return Blizzard3; - - if (actionID is Freeze && !LevelChecked(Freeze)) - return Blizzard2; - - return actionID; - } - } - - internal class BLM_Fire_1to3 : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Fire_1to3; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) => - (actionID is Fire && ((LevelChecked(Fire3) && !GetJobGauge().InAstralFire) || HasEffect(Buffs.Firestarter))) - ? Fire3 - : actionID; - } - - internal class BLM_Between_The_LeyLines : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Between_The_LeyLines; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) => - actionID is LeyLines && HasEffect(Buffs.LeyLines) && LevelChecked(BetweenTheLines) - ? BetweenTheLines - : actionID; - } - - internal class BLM_Aetherial_Manipulation : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Aetherial_Manipulation; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) => - actionID is AetherialManipulation && - ActionReady(BetweenTheLines) && - HasEffect(Buffs.LeyLines) && - !HasEffect(Buffs.CircleOfPower) && - !IsMoving - ? BetweenTheLines - : actionID; - } - - internal class BLM_UmbralSoul : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_UmbralSoul; - - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) => - actionID is Transpose && GetJobGauge().InUmbralIce && LevelChecked(UmbralSoul) - ? UmbralSoul - : actionID; - } - } -} diff --git a/XIVSlothCombo/Combos/PvE/BLM/BLM.cs b/XIVSlothCombo/Combos/PvE/BLM/BLM.cs new file mode 100644 index 000000000..bba6f5a3d --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/BLM/BLM.cs @@ -0,0 +1,960 @@ +using System; +using System.Collections.Generic; +using Dalamud.Game.ClientState.Statuses; +using XIVSlothCombo.Combos.PvE.Content; +using XIVSlothCombo.CustomComboNS; +using XIVSlothCombo.Data; +using XIVSlothCombo.Extensions; +using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class BLM +{ + public const byte ClassID = 7; + public const byte JobID = 25; + + public const uint + Fire = 141, + Blizzard = 142, + Thunder = 144, + Fire2 = 147, + Transpose = 149, + Fire3 = 152, + Thunder3 = 153, + Blizzard3 = 154, + AetherialManipulation = 155, + Scathe = 156, + Manafont = 158, + Freeze = 159, + Flare = 162, + LeyLines = 3573, + Blizzard4 = 3576, + Fire4 = 3577, + BetweenTheLines = 7419, + Thunder4 = 7420, + Triplecast = 7421, + Foul = 7422, + Thunder2 = 7447, + Despair = 16505, + UmbralSoul = 16506, + Xenoglossy = 16507, + Blizzard2 = 25793, + HighFire2 = 25794, + HighBlizzard2 = 25795, + Amplifier = 25796, + Paradox = 25797, + HighThunder = 36986, + HighThunder2 = 36987, + FlareStar = 36989; + + internal static BLMOpenerLogic BLMOpener = new(); + + // Debuff Pairs of Actions and Debuff + public static readonly Dictionary + ThunderList = new() + { + { Thunder, Debuffs.Thunder }, + { Thunder2, Debuffs.Thunder2 }, + { Thunder3, Debuffs.Thunder3 }, + { Thunder4, Debuffs.Thunder4 }, + { HighThunder, Debuffs.HighThunder }, + { HighThunder2, Debuffs.HighThunder2 } + }; + + protected static int nextMpGain => Gauge.UmbralIceStacks switch + { + 0 => 0, + 1 => 2500, + 2 => 5000, + 3 => 10000, + var _ => 0 + }; + + public static class Buffs + { + public const ushort + Thundercloud = 164, + Firestarter = 165, + LeyLines = 737, + CircleOfPower = 738, + Sharpcast = 867, + Triplecast = 1211, + Thunderhead = 3870; + } + + public static class Debuffs + { + public const ushort + Thunder = 161, + Thunder2 = 162, + Thunder3 = 163, + Thunder4 = 1210, + HighThunder = 3871, + HighThunder2 = 3872; + } + + public static class Traits + { + public const uint + UmbralHeart = 295, + EnhancedPolyglot = 297, + AspectMasteryIII = 459, + EnhancedFoul = 461, + EnhancedManafont = 463, + Enochian = 460, + EnhancedPolyglotII = 615; + } + + public static class MP + { + public const int MaxMP = 10000; + + public const int AllMPSpells = 800; //"ALL MP" spell. Only caring about the absolute minimum. + + public static int FireI => GetResourceCost(OriginalHook(Fire)); + + public static int FlareAoE => GetResourceCost(OriginalHook(Flare)); + + public static int FireAoE => GetResourceCost(OriginalHook(Fire2)); + + public static int FireIII => GetResourceCost(OriginalHook(Fire3)); + + public static int BlizzardAoE => GetResourceCost(OriginalHook(Blizzard2)); + + public static int BlizzardI => GetResourceCost(OriginalHook(Blizzard)); + + public static int Freeze => GetResourceCost(OriginalHook(BLM.Freeze)); + + public static int Despair => GetResourceCost(OriginalHook(BLM.Despair)); + } + + internal class BLM_ST_SimpleMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_ST_SimpleMode; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + int maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : + TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; + bool canWeave = CanSpellWeave(ActionWatching.LastSpell); + + float elementTimer = Gauge.ElementTimeRemaining / 1000f; + double gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(ActionWatching.LastSpell)); + + int remainingPolyglotCD = Math.Max(0, + (maxPolyglot - Gauge.PolyglotStacks) * 30000 + (Gauge.EnochianTimer - 30000)); + + Status? thunderDebuffST = + FindEffect(ThunderList[OriginalHook(Thunder)], CurrentTarget, LocalPlayer.GameObjectId); + + uint curMp = LocalPlayer.CurrentMp; + + if (actionID is not Fire) + return actionID; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.BLM_VariantCure) + return Variant.VariantCure; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && canWeave) + return Variant.VariantRampart; + + if (BLMOpener.DoFullOpener(ref actionID)) + return actionID; + + //Weaves + if (canWeave) + { + if (ActionReady(Amplifier) && + remainingPolyglotCD >= 20000) + return Amplifier; + + if (IsEnabled(CustomComboPreset.BLM_ST_LeyLines) && + ActionReady(LeyLines)) + return LeyLines; + } + + if (HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (IsMoving) + { + if (ActionReady(Amplifier) && Gauge.PolyglotStacks < maxPolyglot) + return Amplifier; + + if (HasPolyglotStacks(Gauge)) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + } + + if (Gauge.InAstralFire) + { + if (Gauge.IsParadoxActive && gcdsInTimer < 2 && curMp >= MP.FireI) + return Paradox; + + if ((HasEffect(Buffs.Firestarter) && gcdsInTimer < 2 && + curMp >= MP.FireI) || (HasEffect(Buffs.Firestarter) && Gauge.AstralFireStacks < 3)) + return Fire3; + + if (curMp < MP.FireI && LevelChecked(Despair) && curMp >= MP.Despair) + { + if (canWeave && ActionReady(All.Swiftcast)) + return All.Swiftcast; + + if (canWeave && ActionReady(Triplecast) && + GetBuffStacks(Buffs.Triplecast) == 0 && + GetRemainingCharges(Triplecast) == GetMaxCharges(Triplecast)) + return Triplecast; + + if (HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (HasPolyglotStacks(Gauge) && gcdsInTimer >= 1 && + (ActionReady(All.Swiftcast) || + (ActionReady(Triplecast) && + GetBuffStacks(Buffs.Triplecast) == 0 && + GetRemainingCharges(Triplecast) == GetMaxCharges(Triplecast)))) + return Xenoglossy.LevelChecked() + ? Xenoglossy + : Foul; + + return Despair; + } + + if (curMp == 0 && LevelChecked(FlareStar) && Gauge.AstralSoulStacks == 6) + return FlareStar; + + if (LevelChecked(Fire4)) + if (gcdsInTimer > 1 && curMp >= MP.FireI) + return Fire4; + + if (curMp >= MP.FireI) + return Fire; + + if (IsEnabled(CustomComboPreset.BLM_ST_Manafont) && + ActionReady(Manafont)) + return HasEffect(Buffs.Firestarter) + ? Fire3 + : Manafont; + + if (ActionReady(Blizzard3) && + (ActionReady(All.Swiftcast) || + HasEffect(Buffs.Triplecast))) + { + if (canWeave && + ActionReady(Transpose)) + return Transpose; + + if (HasEffect(Buffs.Thunderhead) && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (HasPolyglotStacks(Gauge)) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + } + + if (ActionReady(Blizzard3)) + return Blizzard3; + } + + if (Gauge.InUmbralIce) + { + if (ActionReady(Blizzard3) && Gauge.UmbralIceStacks < 3 && TraitLevelChecked(Traits.UmbralHeart)) + { + if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0) + return Triplecast; + + if (GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast)) + return All.Swiftcast; + + if (HasEffect(All.Buffs.Swiftcast) || GetBuffStacks(Buffs.Triplecast) > 0) + return Blizzard3; + } + + if (LevelChecked(Blizzard4) && + Gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) + return Blizzard4; + + if (Gauge.IsParadoxActive) + return Paradox; + + if (HasPolyglotStacks(Gauge)) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + + if (curMp + nextMpGain >= 7500 && + (LocalPlayer.CastActionId == Blizzard || + WasLastSpell(Blizzard) || + WasLastSpell(Blizzard4))) + return LevelChecked(Fire3) + ? Fire3 + : Fire; + + if (curMp + nextMpGain <= 10000 || curMp < 7500) + return Blizzard; + + if (ActionReady(Transpose) && canWeave && + curMp is MP.MaxMP && HasEffect(Buffs.Firestarter)) + return Transpose; + + if (LevelChecked(Fire3)) + return Fire3; + } + + if (LevelChecked(Blizzard3)) + return Blizzard3; + + return actionID; + } + } + + internal class BLM_ST_AdvancedMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_ST_AdvancedMode; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + int maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : + TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; + bool canWeave = CanSpellWeave(ActionWatching.LastSpell); + + float elementTimer = Gauge.ElementTimeRemaining / 1000f; + double gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(ActionWatching.LastSpell)); + + int remainingPolyglotCD = Math.Max(0, + (maxPolyglot - Gauge.PolyglotStacks) * 30000 + (Gauge.EnochianTimer - 30000)); + uint curMp = LocalPlayer.CurrentMp; + + Status? thunderDebuffST = + FindEffect(ThunderList[OriginalHook(Thunder)], CurrentTarget, LocalPlayer.GameObjectId); + + int PolyglotStacks = Gauge.PolyglotStacks; + float TriplecastChargetime = GetCooldownChargeRemainingTime(Triplecast); + + if (actionID is not Fire) + return actionID; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.BLM_VariantCure) + return Variant.VariantCure; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + canWeave) + return Variant.VariantRampart; + + if (IsEnabled(CustomComboPreset.BLM_ST_Opener)) + if (BLMOpener.DoFullOpener(ref actionID)) + return actionID; + + //Weaves + if (canWeave) + { + if (IsEnabled(CustomComboPreset.BLM_ST_Amplifier) && + ActionReady(Amplifier) && remainingPolyglotCD >= 20000) + return Amplifier; + + if (IsEnabled(CustomComboPreset.BLM_ST_LeyLines) && + ActionReady(LeyLines)) + return LeyLines; + } + + if (IsEnabled(CustomComboPreset.BLM_ST_Thunder) && + HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && LevelChecked(Thunder) && + GetTargetHPPercent() >= Config.BLM_ST_ThunderHP && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (IsMoving) + { + if (IsEnabled(CustomComboPreset.BLM_ST_Amplifier) && + ActionReady(Amplifier) && Gauge.PolyglotStacks < maxPolyglot) + return Amplifier; + + if (IsEnabled(CustomComboPreset.BLM_ST_UsePolyglotMoving) && + PolyglotStacks > Config.BLM_ST_UsePolyglotMoving_HoldCharges) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + } + + if (Gauge.InAstralFire) + { + if (Gauge.IsParadoxActive && gcdsInTimer < 2 && curMp >= MP.FireI) + return Paradox; + + if ((HasEffect(Buffs.Firestarter) && gcdsInTimer < 2 && + curMp >= MP.FireI) || (HasEffect(Buffs.Firestarter) && Gauge.AstralFireStacks < 3)) + return Fire3; + + if (IsEnabled(CustomComboPreset.BLM_ST_Despair) && + curMp < MP.FireI && LevelChecked(Despair) && curMp >= MP.Despair) + { + if (IsEnabled(CustomComboPreset.BLM_ST_Triplecast) && + canWeave && ActionReady(Triplecast) && + GetBuffStacks(Buffs.Triplecast) == 0 && + (GetRemainingCharges(Triplecast) > Config.BLM_ST_Triplecast_HoldCharges || + TriplecastChargetime <= Config.BLM_ST_Triplecast_ChargeTime)) + return Triplecast; + + if (IsEnabled(CustomComboPreset.BLM_ST_Swiftcast) && + canWeave && ActionReady(All.Swiftcast) && + GetBuffStacks(Buffs.Triplecast) == 0) + return All.Swiftcast; + + if (IsEnabled(CustomComboPreset.BLM_ST_Thunder) && + HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (IsEnabled(CustomComboPreset.BLM_ST_UsePolyglot) && + (IsEnabled(CustomComboPreset.BLM_ST_Swiftcast) || + IsEnabled(CustomComboPreset.BLM_ST_Triplecast)) && + PolyglotStacks > Config.BLM_ST_UsePolyglot_HoldCharges && gcdsInTimer >= 1 && + (ActionReady(All.Swiftcast) || + (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0))) + return Xenoglossy.LevelChecked() + ? Xenoglossy + : Foul; + + return Despair; + } + + if (IsEnabled(CustomComboPreset.BLM_ST_Flarestar) && + curMp == 0 && LevelChecked(FlareStar) && Gauge.AstralSoulStacks == 6) + return FlareStar; + + if (LevelChecked(Fire4)) + if (gcdsInTimer > 1 && curMp >= MP.FireI) + return Fire4; + + if (curMp >= MP.FireI) + return Fire; + + if (IsEnabled(CustomComboPreset.BLM_ST_Manafont) && + ActionReady(Manafont)) + return HasEffect(Buffs.Firestarter) + ? Fire3 + : Manafont; + + if (ActionReady(Blizzard3) && + ((IsEnabled(CustomComboPreset.BLM_ST_Swiftcast) && ActionReady(All.Swiftcast)) || + HasEffect(Buffs.Triplecast))) + { + if (IsEnabled(CustomComboPreset.BLM_ST_Transpose) && + canWeave && ActionReady(Transpose)) + return Transpose; + + if (IsEnabled(CustomComboPreset.BLM_ST_Thunder) && + HasEffect(Buffs.Thunderhead) && + (thunderDebuffST is null || thunderDebuffST.RemainingTime < 3)) + return OriginalHook(Thunder); + + if (IsEnabled(CustomComboPreset.BLM_ST_UsePolyglot) && + PolyglotStacks > Config.BLM_ST_UsePolyglot_HoldCharges) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + } + + if (ActionReady(Blizzard3)) + return Blizzard3; + } + + if (Gauge.InUmbralIce) + { + if (ActionReady(Blizzard3) && Gauge.UmbralIceStacks < 3 && TraitLevelChecked(Traits.UmbralHeart)) + { + if (HasEffect(All.Buffs.Swiftcast) || HasEffect(Buffs.Triplecast)) + return Blizzard3; + + if (IsEnabled(CustomComboPreset.BLM_ST_Swiftcast) && + GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast)) + return All.Swiftcast; + + if (IsEnabled(CustomComboPreset.BLM_ST_Triplecast) && + LevelChecked(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0 && + (GetRemainingCharges(Triplecast) > Config.BLM_ST_Triplecast_HoldCharges || + TriplecastChargetime <= Config.BLM_ST_Triplecast_ChargeTime)) + return Triplecast; + } + + if (LevelChecked(Blizzard4) && Gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) + return Blizzard4; + + if (Gauge.IsParadoxActive) + return Paradox; + + if (IsEnabled(CustomComboPreset.BLM_ST_UsePolyglot) && + PolyglotStacks > Config.BLM_ST_UsePolyglot_HoldCharges) + return LevelChecked(Xenoglossy) + ? Xenoglossy + : Foul; + + if (curMp + nextMpGain >= 7500 && + (LocalPlayer.CastActionId == Blizzard || + WasLastSpell(Blizzard) || + WasLastSpell(Blizzard4))) + return LevelChecked(Fire3) + ? Fire3 + : Fire; + + if (curMp + nextMpGain <= 10000 || curMp < 7500) + return Blizzard; + + if (IsEnabled(CustomComboPreset.BLM_ST_Transpose) && + ActionReady(Transpose) && canWeave && + curMp is MP.MaxMP && HasEffect(Buffs.Firestarter)) + return Transpose; + + if (LevelChecked(Fire3)) + return Fire3; + } + + if (LevelChecked(Blizzard3)) + return Blizzard3; + + return actionID; + } + } + + internal class BLM_AoE_SimpleMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_AoE_SimpleMode; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + int maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : + TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; + + float elementTimer = Gauge.ElementTimeRemaining / 1000f; + double gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(ActionWatching.LastSpell)); + + int remainingPolyglotCD = Math.Max(0, + (maxPolyglot - Gauge.PolyglotStacks) * 30000 + (Gauge.EnochianTimer - 30000)); + uint curMp = LocalPlayer.CurrentMp; + + Status? thunderDebuffAoE = + FindEffect(ThunderList[OriginalHook(Thunder2)], CurrentTarget, LocalPlayer.GameObjectId); + + bool canSwiftF = TraitLevelChecked(Traits.AspectMasteryIII) && + IsOffCooldown(All.Swiftcast); + + if (actionID is not (Blizzard2 or HighBlizzard2)) + return actionID; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.BLM_VariantCure) + return Variant.VariantCure; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + CanSpellWeave(ActionWatching.LastSpell)) + return Variant.VariantRampart; + + if (WasLastSpell(UmbralSoul)) + return OriginalHook(Fire2); + + if ((HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && Thunder2.LevelChecked() && + thunderDebuffAoE is null) || thunderDebuffAoE.RemainingTime < 3) + return OriginalHook(Thunder2); + + if (ActionReady(Amplifier) && remainingPolyglotCD >= 20000 && CanSpellWeave(ActionWatching.LastSpell)) + return Amplifier; + + if (IsMoving) + { + if (ActionReady(Amplifier) && Gauge.PolyglotStacks < maxPolyglot) + return Amplifier; + + if (HasPolyglotStacks(Gauge)) + return Foul; + } + + if (CanSpellWeave(ActionWatching.LastSpell) && ActionReady(LeyLines)) + return LeyLines; + + if (Gauge.InAstralFire) + { + if (curMp == 0 && FlareStar.LevelChecked() && Gauge.AstralSoulStacks == 6) + return FlareStar; + + if (!FlareStar.LevelChecked() && Fire2.LevelChecked() && curMp >= MP.FireAoE && + (Gauge.UmbralHearts > 1 || !TraitLevelChecked(Traits.UmbralHeart))) + return OriginalHook(Fire2); + + if (Flare.LevelChecked() && curMp >= MP.FlareAoE) + { + if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0 && + CanSpellWeave(ActionWatching.LastSpell)) + return Triplecast; + + return Flare; + } + + if (Fire2.LevelChecked()) + if (gcdsInTimer > 1 && curMp >= MP.FireAoE) + return OriginalHook(Fire2); + + if (ActionReady(Manafont)) + return Manafont; + + if (ActionReady(Transpose) && (!TraitLevelChecked(Traits.AspectMasteryIII) || canSwiftF)) + return Transpose; + + if (ActionReady(Blizzard2) && TraitLevelChecked(Traits.AspectMasteryIII)) + return OriginalHook(Blizzard2); + } + + if (Gauge.InUmbralIce) + { + if (HasPolyglotStacks(Gauge)) + return Foul; + + if (ActionWatching.WhichOfTheseActionsWasLast(OriginalHook(Fire2), OriginalHook(Freeze), + OriginalHook(Flare), OriginalHook(FlareStar)) == OriginalHook(Freeze) && + FlareStar.LevelChecked()) + { + if (ActionReady(Transpose) && CanSpellWeave(ActionWatching.LastSpell)) + return Transpose; + + return OriginalHook(Fire2); + } + + if (ActionReady(OriginalHook(Blizzard2)) && Gauge.UmbralIceStacks < 3 && + TraitLevelChecked(Traits.AspectMasteryIII)) + { + if (ActionReady(Triplecast) && GetBuffStacks(Buffs.Triplecast) == 0 && + CanSpellWeave(ActionWatching.LastSpell)) + return Triplecast; + + if (GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast) && + CanSpellWeave(ActionWatching.LastSpell)) + return All.Swiftcast; + + if (HasEffect(All.Buffs.Swiftcast) || GetBuffStacks(Buffs.Triplecast) > 0) + return OriginalHook(Blizzard2); + } + + if (Gauge.UmbralIceStacks < 3 && ActionReady(OriginalHook(Blizzard2))) + return OriginalHook(Blizzard2); + + if (Freeze.LevelChecked() && Gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) + return Freeze; + + if (BLMHelper.DoubleBlizz() && Fire2.LevelChecked()) + return OriginalHook(Fire2); + + if (curMp < LocalPlayer.MaxMp) + return Freeze.LevelChecked() + ? OriginalHook(Freeze) + : OriginalHook(Blizzard2); + + if (IsEnabled(CustomComboPreset.BLM_AoE_Transpose) && + ActionReady(Transpose) && + ((CanSpellWeave(ActionWatching.LastSpell) && Flare.LevelChecked()) || + !TraitLevelChecked(Traits.AspectMasteryIII))) + return Transpose; + + if (Fire2.LevelChecked() && TraitLevelChecked(Traits.AspectMasteryIII)) + return OriginalHook(Fire2); + } + + if (Blizzard2.LevelChecked()) + return OriginalHook(Blizzard2); + + return actionID; + } + } + + internal class BLM_AoE_AdvancedMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_AoE_AdvancedMode; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + int maxPolyglot = TraitLevelChecked(Traits.EnhancedPolyglotII) ? 3 : + TraitLevelChecked(Traits.EnhancedPolyglot) ? 2 : 1; + + float elementTimer = Gauge.ElementTimeRemaining / 1000f; + double gcdsInTimer = Math.Floor(elementTimer / GetActionCastTime(ActionWatching.LastSpell)); + + Status? thunderDebuffAoE = + FindEffect(ThunderList[OriginalHook(Thunder2)], CurrentTarget, LocalPlayer.GameObjectId); + + int remainingPolyglotCD = Math.Max(0, + (maxPolyglot - Gauge.PolyglotStacks) * 30000 + (Gauge.EnochianTimer - 30000)); + uint curMp = LocalPlayer.CurrentMp; + + bool canSwiftF = TraitLevelChecked(Traits.AspectMasteryIII) && + IsOffCooldown(All.Swiftcast); + + int PolyglotStacks = Gauge.PolyglotStacks; + float TriplecastChargetime = GetCooldownChargeRemainingTime(Triplecast); + + if (actionID is not (Blizzard2 or HighBlizzard2)) + return actionID; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.BLM_VariantCure) + return Variant.VariantCure; + + if (IsEnabled(CustomComboPreset.BLM_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + CanSpellWeave(ActionWatching.LastSpell)) + return Variant.VariantRampart; + + if (WasLastSpell(UmbralSoul)) + return OriginalHook(Fire2); + + if ((IsEnabled(CustomComboPreset.BLM_AoE_Thunder) && + HasEffect(Buffs.Thunderhead) && gcdsInTimer > 1 && LevelChecked(Thunder2) && + GetTargetHPPercent() >= Config.BLM_AoE_ThunderHP && + thunderDebuffAoE is null) || thunderDebuffAoE.RemainingTime < 3) + return OriginalHook(Thunder2); + + if (IsEnabled(CustomComboPreset.BLM_AoE_Amplifier) && + ActionReady(Amplifier) && remainingPolyglotCD >= 20000 && CanSpellWeave(ActionWatching.LastSpell)) + return Amplifier; + + if (IsMoving) + { + if (IsEnabled(CustomComboPreset.BLM_AoE_Amplifier) && + ActionReady(Amplifier) && Gauge.PolyglotStacks < maxPolyglot) + return Amplifier; + + if (IsEnabled(CustomComboPreset.BLM_AoE_UsePolyglotMoving) && + PolyglotStacks > Config.BLM_AoE_UsePolyglotMoving_HoldCharges) + return Foul; + } + + if (IsEnabled(CustomComboPreset.BLM_AoE_LeyLines) && + CanSpellWeave(ActionWatching.LastSpell) && ActionReady(LeyLines)) + return LeyLines; + + if (Gauge.InAstralFire) + { + if (IsEnabled(CustomComboPreset.BLM_AoE_Flarestar) && + curMp == 0 && FlareStar.LevelChecked() && Gauge.AstralSoulStacks == 6) + return FlareStar; + + if (!FlareStar.LevelChecked() && Fire2.LevelChecked() && curMp >= MP.FireAoE && + (Gauge.UmbralHearts > 1 || !TraitLevelChecked(Traits.UmbralHeart))) + return OriginalHook(Fire2); + + if (IsEnabled(CustomComboPreset.BLM_AoE_Flare) && + Flare.LevelChecked() && curMp >= MP.FlareAoE) + { + if (LevelChecked(Triplecast) && CanSpellWeave(ActionWatching.LastSpell) && + GetBuffStacks(Buffs.Triplecast) == 0 && + (GetRemainingCharges(Triplecast) > Config.BLM_AoE_Triplecast_HoldCharges || + TriplecastChargetime <= Config.BLM_AoE_Triplecast_ChargeTime)) + return Triplecast; + + return Flare; + } + + if (Fire2.LevelChecked()) + if (gcdsInTimer > 1 && curMp >= MP.FireAoE) + return OriginalHook(Fire2); + + if (IsEnabled(CustomComboPreset.BLM_AoE_Manafont) && + ActionReady(Manafont)) + return Manafont; + + if (IsEnabled(CustomComboPreset.BLM_AoE_Transpose) && + ActionReady(Transpose) && (!TraitLevelChecked(Traits.AspectMasteryIII) || canSwiftF)) + return Transpose; + + if (ActionReady(Blizzard2) && TraitLevelChecked(Traits.AspectMasteryIII)) + return OriginalHook(Blizzard2); + } + + if (Gauge.InUmbralIce) + { + if (IsEnabled(CustomComboPreset.BLM_AoE_UsePolyglot) && + PolyglotStacks > Config.BLM_AoE_UsePolyglot_HoldCharges) + return Foul; + + if (ActionWatching.WhichOfTheseActionsWasLast(OriginalHook(Fire2), OriginalHook(Freeze), + OriginalHook(Flare), OriginalHook(FlareStar)) == OriginalHook(Freeze) && + FlareStar.LevelChecked()) + { + if (IsEnabled(CustomComboPreset.BLM_AoE_Transpose) && + ActionReady(Transpose) && CanSpellWeave(ActionWatching.LastSpell)) + return Transpose; + + return OriginalHook(Fire2); + } + + if (ActionReady(OriginalHook(Blizzard2)) && Gauge.UmbralIceStacks < 3 && + TraitLevelChecked(Traits.AspectMasteryIII)) + { + if (IsEnabled(CustomComboPreset.BLM_AoE_Triplecast) && + LevelChecked(Triplecast) && CanSpellWeave(ActionWatching.LastSpell) && + GetBuffStacks(Buffs.Triplecast) == 0 && + (GetRemainingCharges(Triplecast) > Config.BLM_AoE_Triplecast_HoldCharges || + TriplecastChargetime <= Config.BLM_AoE_Triplecast_ChargeTime)) + return Triplecast; + + if (IsEnabled(CustomComboPreset.BLM_AoE_Swiftcast) && + GetBuffStacks(Buffs.Triplecast) == 0 && IsOffCooldown(All.Swiftcast) && + CanSpellWeave(ActionWatching.LastSpell)) + return All.Swiftcast; + + if (HasEffect(All.Buffs.Swiftcast) || GetBuffStacks(Buffs.Triplecast) > 0) + return OriginalHook(Blizzard2); + } + + if (Gauge.UmbralIceStacks < 3 && ActionReady(OriginalHook(Blizzard2))) + return OriginalHook(Blizzard2); + + if (Freeze.LevelChecked() && Gauge.UmbralHearts < 3 && TraitLevelChecked(Traits.UmbralHeart)) + return Freeze; + + if (BLMHelper.DoubleBlizz() && Fire2.LevelChecked()) + return OriginalHook(Fire2); + + if (curMp < LocalPlayer.MaxMp) + return Freeze.LevelChecked() + ? OriginalHook(Freeze) + : OriginalHook(Blizzard2); + + if (IsEnabled(CustomComboPreset.BLM_AoE_Transpose) && + ActionReady(Transpose) && + ((CanSpellWeave(ActionWatching.LastSpell) && Flare.LevelChecked()) || + !TraitLevelChecked(Traits.AspectMasteryIII))) + return Transpose; + + if (Fire2.LevelChecked() && TraitLevelChecked(Traits.AspectMasteryIII)) + return OriginalHook(Fire2); + } + + if (Blizzard2.LevelChecked()) + return OriginalHook(Blizzard2); + + return actionID; + } + } + + internal class BLM_Variant_Raise : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Variant_Raise; + + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + { + return actionID is All.Swiftcast && HasEffect(All.Buffs.Swiftcast) && IsEnabled(Variant.VariantRaise) + ? Variant.VariantRaise + : actionID; + } + } + + internal class BLM_Scathe_Xeno : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Scathe_Xeno; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Scathe && LevelChecked(Xenoglossy) && HasPolyglotStacks(Gauge) + ? Xenoglossy + : actionID; + } + } + + internal class BLM_Blizzard_1to3 : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Blizzard_1to3; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID switch + { + Blizzard when LevelChecked(Freeze) && !Gauge.InUmbralIce => Blizzard3, + Freeze when !LevelChecked(Freeze) => Blizzard2, + var _ => actionID + }; + } + } + + internal class BLM_Fire_1to3 : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Fire_1to3; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Fire && + ((LevelChecked(Fire3) && !Gauge.InAstralFire) || + HasEffect(Buffs.Firestarter)) + ? Fire3 + : actionID; + } + } + + internal class BLM_Between_The_LeyLines : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Between_The_LeyLines; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is LeyLines && HasEffect(Buffs.LeyLines) && LevelChecked(BetweenTheLines) + ? BetweenTheLines + : actionID; + } + } + + internal class BLM_Aetherial_Manipulation : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_Aetherial_Manipulation; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is AetherialManipulation && + ActionReady(BetweenTheLines) && + HasEffect(Buffs.LeyLines) && + !HasEffect(Buffs.CircleOfPower) && + !IsMoving + ? BetweenTheLines + : actionID; + } + } + + internal class BLM_UmbralSoul : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_UmbralSoul; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Transpose && Gauge.InUmbralIce && LevelChecked(UmbralSoul) + ? UmbralSoul + : actionID; + } + } + + internal class BLM_TriplecastProtection : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.BLM_TriplecastProtection; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + return actionID is Triplecast && HasEffect(Buffs.Triplecast) && LevelChecked(Triplecast) + ? OriginalHook(11) + : actionID; + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/BLM/BLM_Config.cs b/XIVSlothCombo/Combos/PvE/BLM/BLM_Config.cs new file mode 100644 index 000000000..dcb02d124 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/BLM/BLM_Config.cs @@ -0,0 +1,95 @@ +using XIVSlothCombo.CustomComboNS.Functions; +using static XIVSlothCombo.Window.Functions.UserConfig; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class BLM +{ + internal static class Config + { + public static UserInt + BLM_VariantCure = new("BLM_VariantCure"), + BLM_VariantRampart = new("BLM_VariantRampart"), + BLM_ST_Triplecast_HoldCharges = new("BLM_ST_Triplecast_HoldCharges", 0), + BLM_ST_UsePolyglot_HoldCharges = new("BLM_ST_UsePolyglot_HoldCharges", 1), + BLM_ST_UsePolyglotMoving_HoldCharges = new("BLM_ST_UsePolyglotMoving_HoldCharges", 0), + BLM_ST_ThunderHP = new("BHP", 0), + BLM_AoE_Triplecast_HoldCharges = new("BLM_AoE_Triplecast_HoldCharges", 0), + BLM_AoE_UsePolyglot_HoldCharges = new("BLM_AoE_UsePolyglot_HoldCharges", 1), + BLM_AoE_UsePolyglotMoving_HoldCharges = new("BLM_AoE_UsePolyglotMoving_HoldCharges", 0), + BLM_AoE_ThunderHP = new("BLM_AoE_ThunderHP", 5); + + public static UserFloat + BLM_ST_Triplecast_ChargeTime = new("BLM_ST_Triplecast_ChargeTime", 20), + BLM_AoE_Triplecast_ChargeTime = new("BLM_AoE_Triplecast_ChargeTime", 20); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.BLM_Variant_Cure: + DrawSliderInt(1, 100, BLM_VariantCure, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.BLM_Variant_Rampart: + DrawSliderInt(1, 100, BLM_VariantRampart, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.BLM_ST_Triplecast: + DrawSliderInt(0, 1, BLM_ST_Triplecast_HoldCharges, "How many charges to keep ready? (0 = Use all)"); + + DrawSliderInt(10, 20, BLM_ST_Triplecast_ChargeTime, + "Set the amount of time remaining on Triplecast charge before using.(Only when at threshold)"); + + break; + + case CustomComboPreset.BLM_ST_UsePolyglot: + DrawSliderInt(0, 2, BLM_ST_UsePolyglot_HoldCharges, + "How many charges to keep ready? (0 = Use all)"); + + break; + + case CustomComboPreset.BLM_ST_UsePolyglotMoving: + DrawSliderInt(0, 2, BLM_ST_UsePolyglotMoving_HoldCharges, + "How many charges to keep ready? (0 = Use all)"); + + break; + + case CustomComboPreset.BLM_ST_Thunder: + DrawSliderInt(0, 10, BLM_ST_ThunderHP, + "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)"); + + break; + + case CustomComboPreset.BLM_AoE_Triplecast: + DrawSliderInt(0, 1, BLM_AoE_Triplecast_HoldCharges, + "How many charges to keep ready? (0 = Use all)"); + + DrawSliderInt(10, 20, BLM_AoE_Triplecast_ChargeTime, + "Set the amount of time remaining on Triplecast charge before using.(Only when at threshold)"); + + break; + + case CustomComboPreset.BLM_AoE_UsePolyglot: + DrawSliderInt(0, 2, BLM_AoE_UsePolyglot_HoldCharges, + "How many charges to keep ready? (0 = Use all)"); + + break; + + case CustomComboPreset.BLM_AoE_UsePolyglotMoving: + DrawSliderInt(0, 2, BLM_AoE_UsePolyglotMoving_HoldCharges, + "How many charges to keep ready? (0 = Use all)"); + + break; + + case CustomComboPreset.BLM_AoE_Thunder: + DrawSliderInt(0, 10, BLM_AoE_ThunderHP, + "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)"); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/BLM/BLM_Helper.cs b/XIVSlothCombo/Combos/PvE/BLM/BLM_Helper.cs new file mode 100644 index 000000000..d32191059 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/BLM/BLM_Helper.cs @@ -0,0 +1,276 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Dalamud.Game.ClientState.JobGauge.Types; +using ECommons.DalamudServices; +using XIVSlothCombo.Combos.JobHelpers.Enums; +using XIVSlothCombo.Data; +using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class BLM +{ + // BLM Gauge & Extensions + public static BLMGauge Gauge => GetJobGauge(); + + public static int Fire4Count => ActionWatching.CombatActions.Count(x => x == Fire4); + + public static bool HasPolyglotStacks(BLMGauge gauge) => gauge.PolyglotStacks > 0; + + internal class BLMOpenerLogic + { + private OpenerState currentState = OpenerState.PrePull; + + public uint OpenerStep = 1; + + public uint PrePullStep; + + private static uint OpenerLevel => 100; + + public static bool LevelChecked => LocalPlayer.Level >= OpenerLevel; + + private static bool CanOpener => HasCooldowns() && LevelChecked; + + public OpenerState CurrentState + { + get => currentState; + set + { + if (value != currentState) + { + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); + if (value == OpenerState.InOpener) OpenerStep = 1; + + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) + { + if (value == OpenerState.FailedOpener) + Svc.Log.Information($"Opener Failed at step {OpenerStep}"); + + ResetOpener(); + } + if (value == OpenerState.OpenerFinished) Svc.Log.Information("Opener Finished"); + + currentState = value; + } + } + } + + private static bool HasCooldowns() + { + if (!ActionReady(Manafont)) + return false; + + if (GetRemainingCharges(Triplecast) < 2) + return false; + + if (!ActionReady(All.Swiftcast)) + return false; + + if (!ActionReady(Amplifier)) + return false; + + return true; + } + + private bool DoPrePullSteps(ref uint actionID) + { + if (!LevelChecked) return false; + + if (CanOpener && PrePullStep == 0) PrePullStep = 1; + + if (!HasCooldowns()) PrePullStep = 0; + + if (CurrentState == OpenerState.PrePull && PrePullStep > 0) + { + if (WasLastAction(Fire3) && HasEffect(Buffs.Thunderhead) && PrePullStep == 1) + CurrentState = OpenerState.InOpener; + else if (PrePullStep == 1) actionID = Fire3; + + if (ActionWatching.CombatActions.Count > 2 && InCombat()) + CurrentState = OpenerState.FailedOpener; + + return true; + } + + PrePullStep = 0; + + return false; + } + + private bool DoOpener(ref uint actionID) + { + if (!LevelChecked) return false; + + if (currentState == OpenerState.InOpener) + { + if (WasLastAction(HighThunder) && OpenerStep == 1) OpenerStep++; + else if (OpenerStep == 1) actionID = HighThunder; + + if (WasLastAction(All.Swiftcast) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = All.Swiftcast; + + if (WasLastAction(Amplifier) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = Amplifier; + + if (WasLastAction(Fire4) && Fire4Count is 1 && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Fire4; + + if (WasLastAction(Fire4) && Fire4Count is 2 && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = Fire4; + + if (WasLastAction(Xenoglossy) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = Xenoglossy; + + if (WasLastAction(Triplecast) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = Triplecast; + + if ((WasLastAction(LeyLines) || IsOnCooldown(LeyLines)) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8) actionID = LeyLines; + + if (WasLastAction(Fire4) && Fire4Count is 3 && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = Fire4; + + if (WasLastAction(Fire4) && Fire4Count is 4 && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = Fire4; + + if (WasLastAction(Despair) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = Despair; + + if (WasLastAction(Manafont) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = Manafont; + + if (WasLastAction(Triplecast) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = Triplecast; + + if (WasLastAction(Fire4) && Fire4Count is 5 && OpenerStep == 14) OpenerStep++; + else if (OpenerStep == 14) actionID = Fire4; + + if (WasLastAction(Fire4) && Fire4Count is 6 && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = Fire4; + + if (WasLastAction(FlareStar) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = FlareStar; + + if (WasLastAction(Fire4) && Fire4Count is 7 && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = Fire4; + + if (WasLastAction(HighThunder) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = HighThunder; + + if (WasLastAction(Paradox) && OpenerStep == 19) OpenerStep++; + else if (OpenerStep == 19) actionID = Paradox; + + if (WasLastAction(Fire4) && Fire4Count is 8 && OpenerStep == 20) OpenerStep++; + else if (OpenerStep == 20) actionID = Fire4; + + if (WasLastAction(Fire4) && Fire4Count is 9 && OpenerStep == 21) OpenerStep++; + else if (OpenerStep == 21) actionID = Fire4; + + if (WasLastAction(Fire4) && Fire4Count is 10 && OpenerStep == 22) OpenerStep++; + else if (OpenerStep == 22) actionID = Fire4; + + if (WasLastAction(Despair) && OpenerStep == 23) CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 23) actionID = Despair; + + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; + + if (((actionID == Triplecast && GetRemainingCharges(Triplecast) == 0) || + (actionID == Amplifier && IsOnCooldown(Amplifier)) || + (actionID == LeyLines && IsOnCooldown(LeyLines)) || + (actionID == Manafont && IsOnCooldown(Manafont)) || + (actionID == All.Swiftcast && IsOnCooldown(All.Swiftcast)) || + (actionID == Xenoglossy && Gauge.PolyglotStacks == 0)) && + ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + { + CurrentState = OpenerState.FailedOpener; + + return false; + } + + return true; + } + + return false; + } + + private void ResetOpener() + { + PrePullStep = 0; + OpenerStep = 0; + } + + public bool DoFullOpener(ref uint actionID) + { + if (!LevelChecked) return false; + + if (CurrentState == OpenerState.PrePull) + if (DoPrePullSteps(ref actionID)) + return true; + + if (CurrentState == OpenerState.InOpener) + if (DoOpener(ref actionID)) + return true; + + if (!InCombat()) + { + ResetOpener(); + CurrentState = OpenerState.PrePull; + } + + return false; + } + } + + internal class BLMHelper + { + public static float MPAfterCast() + { + uint castedSpell = LocalPlayer.CastActionId; + + int nextMpGain = Gauge.UmbralIceStacks switch + { + 0 => 0, + 1 => 2500, + 2 => 5000, + 3 => 10000, + _ => 0 + }; + + if (castedSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) + return Math.Max(LocalPlayer.MaxMp, LocalPlayer.CurrentMp + nextMpGain); + + return Math.Max(0, LocalPlayer.CurrentMp - GetResourceCost(castedSpell)); + } + + public static bool DoubleBlizz() + { + List spells = ActionWatching.CombatActions.Where(x => + ActionWatching.GetAttackType(x) == ActionWatching.ActionAttackType.Spell && + x != OriginalHook(Thunder) && x != OriginalHook(Thunder2)).ToList(); + + if (spells.Count < 1) return false; + + uint firstSpell = spells[^1]; + + if (firstSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) + { + uint castedSpell = LocalPlayer.CastActionId; + + if (castedSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) + return true; + + if (spells.Count >= 2) + { + uint secondSpell = spells[^2]; + + if (secondSpell is Blizzard or Blizzard2 or Blizzard3 or Blizzard4 or Freeze or HighBlizzard2) + return true; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/BLU.cs b/XIVSlothCombo/Combos/PvE/BLU/BLU.cs similarity index 99% rename from XIVSlothCombo/Combos/PvE/BLU.cs rename to XIVSlothCombo/Combos/PvE/BLU/BLU.cs index a439cd633..5f0941788 100644 --- a/XIVSlothCombo/Combos/PvE/BLU.cs +++ b/XIVSlothCombo/Combos/PvE/BLU/BLU.cs @@ -3,7 +3,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class BLU + internal partial class BLU { public const byte JobID = 36; diff --git a/XIVSlothCombo/Combos/PvE/BLU/BLU_Config.cs b/XIVSlothCombo/Combos/PvE/BLU/BLU_Config.cs new file mode 100644 index 000000000..e27ae041e --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/BLU/BLU_Config.cs @@ -0,0 +1,17 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class BLU +{ + internal static class Config + { + //Config goes here + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + //Presets + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/BRD.cs b/XIVSlothCombo/Combos/PvE/BRD/BRD.cs similarity index 99% rename from XIVSlothCombo/Combos/PvE/BRD.cs rename to XIVSlothCombo/Combos/PvE/BRD/BRD.cs index fd27a225b..50da4bbf1 100644 --- a/XIVSlothCombo/Combos/PvE/BRD.cs +++ b/XIVSlothCombo/Combos/PvE/BRD/BRD.cs @@ -9,7 +9,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class BRD + internal partial class BRD { public const byte ClassID = 5; public const byte JobID = 23; @@ -73,17 +73,7 @@ public const ushort CausticBite = 1200, Stormbite = 1201; } - - public static class Config - { - public const string - BRD_RagingJawsRenewTime = "ragingJawsRenewTime", - BRD_NoWasteHPPercentage = "noWasteHpPercentage", - BRD_AoENoWasteHPPercentage = "AoENoWasteHpPercentage", - BRD_STSecondWindThreshold = "BRD_STSecondWindThreshold", - BRD_AoESecondWindThreshold = "BRD_AoESecondWindThreshold", - BRD_VariantCure = "BRD_VariantCure"; - } + internal static class Traits { internal const ushort diff --git a/XIVSlothCombo/Combos/PvE/BRD/BRD_Config.cs b/XIVSlothCombo/Combos/PvE/BRD/BRD_Config.cs new file mode 100644 index 000000000..d95ca9329 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/BRD/BRD_Config.cs @@ -0,0 +1,57 @@ +using static XIVSlothCombo.Window.Functions.UserConfig; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class BRD +{ + internal static class Config + { + public const string + BRD_RagingJawsRenewTime = "ragingJawsRenewTime", + BRD_NoWasteHPPercentage = "noWasteHpPercentage", + BRD_AoENoWasteHPPercentage = "AoENoWasteHpPercentage", + BRD_STSecondWindThreshold = "BRD_STSecondWindThreshold", + BRD_AoESecondWindThreshold = "BRD_AoESecondWindThreshold", + BRD_VariantCure = "BRD_VariantCure"; + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.BRD_Adv_RagingJaws: + DrawSliderInt(3, 10, BRD_RagingJawsRenewTime, + "Remaining time (In seconds). Recommended 5, increase little by little if refresh is outside of radiant window"); + + break; + + case CustomComboPreset.BRD_Adv_NoWaste: + DrawSliderInt(1, 10, BRD_NoWasteHPPercentage, "Remaining target HP percentage"); + + break; + + case CustomComboPreset.BRD_AoE_Adv_NoWaste: + DrawSliderInt(1, 10, BRD_AoENoWasteHPPercentage, + "Remaining target HP percentage"); + + break; + + case CustomComboPreset.BRD_ST_SecondWind: + DrawSliderInt(0, 100, BRD_STSecondWindThreshold, + "HP percent threshold to use Second Wind below."); + + break; + + case CustomComboPreset.BRD_AoE_SecondWind: + DrawSliderInt(0, 100, BRD_AoESecondWindThreshold, + "HP percent threshold to use Second Wind below."); + + break; + + case CustomComboPreset.BRD_Variant_Cure: + DrawSliderInt(1, 100, BRD_VariantCure, "HP% to be at or under", 200); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/Content/Bozja.cs b/XIVSlothCombo/Combos/PvE/Content/Bozja.cs index bcb36730a..ffb26d7dd 100644 --- a/XIVSlothCombo/Combos/PvE/Content/Bozja.cs +++ b/XIVSlothCombo/Combos/PvE/Content/Bozja.cs @@ -1,60 +1,59 @@ -namespace XIVSlothCombo.Combos.PvE.Content +namespace XIVSlothCombo.Combos.PvE.Content; + +internal class Bozja { - internal static class Bozja - { - public const uint - LostBanish3 = 20702, - FontOfMagic = 20715, - FontOfPower = 20717, - BannerOfNobleEnds = 20720, - BannerOfHonoredSacrifice = 20721, - LostCure = 20726, - LostCure2 = 20727, - LostCure3 = 20728, - LostCure4 = 20729, - LostIncense = 20731, - LostFlareStar = 22352, - LostRendArmor = 22353, - LostSeraphStrike = 22354, - LostAethershield = 22355, - LostDervish = 22356, - LostBurst = 23909, - LostRampage = 23910, - LostChainspell = 23913, - LostAssassination = 23914, - LostExcellence = 23919, - LostBloodRage = 23921; + public const uint + LostBanish3 = 20702, + FontOfMagic = 20715, + FontOfPower = 20717, + BannerOfNobleEnds = 20720, + BannerOfHonoredSacrifice = 20721, + LostCure = 20726, + LostCure2 = 20727, + LostCure3 = 20728, + LostCure4 = 20729, + LostIncense = 20731, + LostFlareStar = 22352, + LostRendArmor = 22353, + LostSeraphStrike = 22354, + LostAethershield = 22355, + LostDervish = 22356, + LostBurst = 23909, + LostRampage = 23910, + LostChainspell = 23913, + LostAssassination = 23914, + LostExcellence = 23919, + LostBloodRage = 23921; - public static class Buffs - { - public const ushort - MPRefresh = 909, - MPRefresh2 = 1198, - ProfaneEssence = 2320, - IrregularEssence = 2321, - BeastEssence = 2324, - BannerOfNobleEnds = 2326, - BannerOfHonoredSacrifice = 2327, - FontOfMagic = 2332, - LostBravery2 = 2341, - FontOfPower = 2346, - PureElder = 2435, - PureFiendhunter = 2437, - PureIndomitable = 2438, - PureDivine = 2439, - LostAethershield = 2443, - LostDervish = 2444, - ClericStance = 2484, - LostChainspell = 2560, - LostExcellence = 2564, - LostBloodRage = 2566; - } + public static class Buffs + { + public const ushort + MPRefresh = 909, + MPRefresh2 = 1198, + ProfaneEssence = 2320, + IrregularEssence = 2321, + BeastEssence = 2324, + BannerOfNobleEnds = 2326, + BannerOfHonoredSacrifice = 2327, + FontOfMagic = 2332, + LostBravery2 = 2341, + FontOfPower = 2346, + PureElder = 2435, + PureFiendhunter = 2437, + PureIndomitable = 2438, + PureDivine = 2439, + LostAethershield = 2443, + LostDervish = 2444, + ClericStance = 2484, + LostChainspell = 2560, + LostExcellence = 2564, + LostBloodRage = 2566; + } - public static class Debuffs - { - public const ushort - LostFlareStar = 2440, - LostRendArmor = 2441; - } + public static class Debuffs + { + public const ushort + LostFlareStar = 2440, + LostRendArmor = 2441; } -} +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/Content/Variant.cs b/XIVSlothCombo/Combos/PvE/Content/Variant.cs index 8f31b9a04..fa143d22e 100644 --- a/XIVSlothCombo/Combos/PvE/Content/Variant.cs +++ b/XIVSlothCombo/Combos/PvE/Content/Variant.cs @@ -1,50 +1,50 @@ using ECommons.DalamudServices; -namespace XIVSlothCombo.Combos.PvE.Content +namespace XIVSlothCombo.Combos.PvE.Content; + +internal static class Variant { - internal static class Variant + public const uint + VariantUltimatum = 29730, + VariantRaise = 29731, + VariantRaise2 = 29734; + + //1069 = The Sil'dihn Subterrane + //1137 = Mount Rokkon + //1176 = Aloalo Island + public static uint VariantCure => Svc.ClientState.TerritoryType switch { - public const uint - VariantUltimatum = 29730, - VariantRaise = 29731, - VariantRaise2 = 29734; - //1069 = The Sil'dihn Subterrane - //1137 = Mount Rokkon - //1176 = Aloalo Island - public static uint VariantCure => Svc.ClientState.TerritoryType switch - { - 1069 => 29729, - 1137 or 1176 => 33862, - _ => 0 - }; + 1069 => 29729, + 1137 or 1176 => 33862, + _ => 0 + }; - public static uint VariantSpiritDart => Svc.ClientState.TerritoryType switch - { - 1069 => 29732, - 1137 or 1176 => 33863, - _ => 0 - }; + public static uint VariantSpiritDart => Svc.ClientState.TerritoryType switch + { + 1069 => 29732, + 1137 or 1176 => 33863, + _ => 0 + }; - public static uint VariantRampart => Svc.ClientState.TerritoryType switch - { - 1069 => 29733, - 1137 or 1176 => 33864, - _ => 0 - }; + public static uint VariantRampart => Svc.ClientState.TerritoryType switch + { + 1069 => 29733, + 1137 or 1176 => 33864, + _ => 0 + }; - public static class Buffs - { - public const ushort - EmnityUp = 3358, - VulnDown = 3360, - Rehabilitation = 3367, - DamageBarrier = 3405; - } + public static class Buffs + { + public const ushort + EmnityUp = 3358, + VulnDown = 3360, + Rehabilitation = 3367, + DamageBarrier = 3405; + } - public static class Debuffs - { - public const ushort - SustainedDamage = 3359; - } + public static class Debuffs + { + public const ushort + SustainedDamage = 3359; } -} +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/DNC.cs b/XIVSlothCombo/Combos/PvE/DNC/DNC.cs similarity index 94% rename from XIVSlothCombo/Combos/PvE/DNC.cs rename to XIVSlothCombo/Combos/PvE/DNC/DNC.cs index 4ff1da3b8..e286cdcb2 100644 --- a/XIVSlothCombo/Combos/PvE/DNC.cs +++ b/XIVSlothCombo/Combos/PvE/DNC/DNC.cs @@ -1,12 +1,11 @@ using Dalamud.Game.ClientState.JobGauge.Types; using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Services; namespace XIVSlothCombo.Combos.PvE { - internal static class DNC + internal partial class DNC { public const byte JobID = 38; @@ -88,36 +87,6 @@ public const ushort Devilment = 1825; } - public static class Config - { - public static readonly UserInt - DNCEspritThreshold_ST = new UserInt("DNCEspritThreshold_ST", 50); // ST - Esprit threshold - public static readonly UserInt - DNCEspritThreshold_AoE = new UserInt("DNCEspritThreshold_AoE", 50); // AoE - Esprit threshold - - #region Advanced ST Sliders - public static readonly UserInt - DNC_ST_Adv_SSBurstPercent = new UserInt("DNC_ST_Adv_SSBurstPercent", 0), // Standard Step - target HP% threshold - DNC_ST_Adv_TSBurstPercent = new UserInt("DNC_ST_Adv_TSBurstPercent", 0), // Technical Step - target HP% threshold - DNC_ST_Adv_FeatherBurstPercent = new UserInt("DNC_ST_Adv_FeatherBurstPercent", 0), // Feather burst - target HP% threshold - DNC_ST_Adv_SaberThreshold = new UserInt("DNC_ST_Adv_SaberThreshold", 50), // Saber Dance - Esprit threshold - DNC_ST_Adv_PanicHealWaltzPercent = new UserInt("DNC_ST_Adv_PanicHealWaltzPercent", 30), // Curing Waltz - player HP% threshold - DNC_ST_Adv_PanicHealWindPercent = new UserInt("DNC_ST_Adv_PanicHealWindPercent", 20); // Second Wind - player HP% threshold - #endregion - - #region Advanced AoE Sliders - public static readonly UserInt - DNC_AoE_Adv_SSBurstPercent = new UserInt("DNC_AoE_Adv_SSBurstPercent", 0), // Standard Step - target HP% threshold - DNC_AoE_Adv_TSBurstPercent = new UserInt("DNC_AoE_Adv_TSBurstPercent", 0), // Technical Step - target HP% threshold - DNC_AoE_Adv_SaberThreshold = new UserInt("DNC_AoE_Adv_SaberThreshold", 50), // Saber Dance - Esprit threshold - DNC_AoE_Adv_PanicHealWaltzPercent = new UserInt("DNC_AoE_Adv_PanicHealWaltzPercent", 30), // Curing Waltz - player HP% threshold - DNC_AoE_Adv_PanicHealWindPercent = new UserInt("DNC_AoE_Adv_PanicHealWindPercent", 20); // Second Wind - player HP% threshold - #endregion - - public static readonly UserInt - DNCVariantCurePercent = new UserInt("DNCVariantCurePercent"); // Variant Cure - player HP% threshold - } - internal class DNC_DanceComboReplacer : CustomCombo { protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.DNC_DanceComboReplacer; diff --git a/XIVSlothCombo/Combos/PvE/DNC/DNC_Config.cs b/XIVSlothCombo/Combos/PvE/DNC/DNC_Config.cs new file mode 100644 index 000000000..f23ea6978 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/DNC/DNC_Config.cs @@ -0,0 +1,162 @@ +using System.Linq; +using ImGuiNET; +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Services; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class DNC +{ + internal static class Config + { + public static readonly UserInt + DNCEspritThreshold_ST = new("DNCEspritThreshold_ST", 50); // ST - Esprit threshold + + public static readonly UserInt + DNCEspritThreshold_AoE = new("DNCEspritThreshold_AoE", 50); // AoE - Esprit threshold + + #region Advanced ST Sliders + + public static readonly UserInt + DNC_ST_Adv_SSBurstPercent = new("DNC_ST_Adv_SSBurstPercent", 0), // Standard Step - target HP% threshold + DNC_ST_Adv_TSBurstPercent = new("DNC_ST_Adv_TSBurstPercent", 0), // Technical Step - target HP% threshold + DNC_ST_Adv_FeatherBurstPercent = + new("DNC_ST_Adv_FeatherBurstPercent", 0), // Feather burst - target HP% threshold + DNC_ST_Adv_SaberThreshold = new("DNC_ST_Adv_SaberThreshold", 50), // Saber Dance - Esprit threshold + DNC_ST_Adv_PanicHealWaltzPercent = + new("DNC_ST_Adv_PanicHealWaltzPercent", 30), // Curing Waltz - player HP% threshold + DNC_ST_Adv_PanicHealWindPercent = + new("DNC_ST_Adv_PanicHealWindPercent", 20); // Second Wind - player HP% threshold + + #endregion + + #region Advanced AoE Sliders + + public static readonly UserInt + DNC_AoE_Adv_SSBurstPercent = new("DNC_AoE_Adv_SSBurstPercent", 0), // Standard Step - target HP% threshold + DNC_AoE_Adv_TSBurstPercent = new("DNC_AoE_Adv_TSBurstPercent", 0), // Technical Step - target HP% threshold + DNC_AoE_Adv_SaberThreshold = new("DNC_AoE_Adv_SaberThreshold", 50), // Saber Dance - Esprit threshold + DNC_AoE_Adv_PanicHealWaltzPercent = + new("DNC_AoE_Adv_PanicHealWaltzPercent", 30), // Curing Waltz - player HP% threshold + DNC_AoE_Adv_PanicHealWindPercent = + new("DNC_AoE_Adv_PanicHealWindPercent", 20); // Second Wind - player HP% threshold + + #endregion + + public static readonly UserInt + DNCVariantCurePercent = new("DNCVariantCurePercent"); // Variant Cure - player HP% threshold + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.DNC_DanceComboReplacer: + { + int[]? actions = Service.Configuration.DancerDanceCompatActionIDs.Select(x => (int)x).ToArray(); + + bool inputChanged = false; + + inputChanged |= ImGui.InputInt("Emboite (Red) ActionID", ref actions[0], 0); + inputChanged |= ImGui.InputInt("Entrechat (Blue) ActionID", ref actions[1], 0); + inputChanged |= ImGui.InputInt("Jete (Green) ActionID", ref actions[2], 0); + inputChanged |= ImGui.InputInt("Pirouette (Yellow) ActionID", ref actions[3], 0); + + if (inputChanged) + { + //Service.Configuration.DancerDanceCompatActionIDs = actions.Cast().ToArray(); + Service.Configuration.DancerDanceCompatActionIDs = actions.Select(x => (uint)x).ToArray(); + Service.Configuration.Save(); + } + + ImGui.Spacing(); + + break; + } + + case CustomComboPreset.DNC_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, DNCVariantCurePercent, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.DNC_ST_EspritOvercap: + UserConfig.DrawSliderInt(50, 100, DNCEspritThreshold_ST, "Esprit", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DNC_AoE_EspritOvercap: + UserConfig.DrawSliderInt(50, 100, DNCEspritThreshold_AoE, "Esprit", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DNC_ST_Adv_SS: + UserConfig.DrawSliderInt(0, 5, DNC_ST_Adv_SSBurstPercent, + "Target HP% to stop using Standard Step below", 75); + + break; + + case CustomComboPreset.DNC_ST_Adv_TS: + UserConfig.DrawSliderInt(0, 5, DNC_ST_Adv_TSBurstPercent, + "Target HP% to stop using Technical Step below", 75); + + break; + + case CustomComboPreset.DNC_ST_Adv_Feathers: + UserConfig.DrawSliderInt(0, 5, DNC_ST_Adv_FeatherBurstPercent, + "Target HP% to dump all pooled feathers below", 75); + + break; + + case CustomComboPreset.DNC_ST_Adv_SaberDance: + UserConfig.DrawSliderInt(50, 100, DNC_ST_Adv_SaberThreshold, "Esprit", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DNC_ST_Adv_PanicHeals: + UserConfig.DrawSliderInt(0, 100, DNC_ST_Adv_PanicHealWaltzPercent, "Curing Waltz HP%", + 200); + + UserConfig.DrawSliderInt(0, 100, DNC_ST_Adv_PanicHealWindPercent, "Second Wind HP%", + 200); + + break; + + case CustomComboPreset.DNC_AoE_Adv_SS: + UserConfig.DrawSliderInt(0, 10, DNC_AoE_Adv_SSBurstPercent, + "Target HP% to stop using Standard Step below", 75); + + break; + + case CustomComboPreset.DNC_AoE_Adv_TS: + UserConfig.DrawSliderInt(0, 10, DNC_AoE_Adv_TSBurstPercent, + "Target HP% to stop using Technical Step below", 75); + + break; + + case CustomComboPreset.DNC_AoE_Adv_SaberDance: + UserConfig.DrawSliderInt(50, 100, DNC_AoE_Adv_SaberThreshold, "Esprit", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DNC_AoE_Adv_PanicHeals: + UserConfig.DrawSliderInt(0, 100, DNC_AoE_Adv_PanicHealWaltzPercent, "Curing Waltz HP%", + 200); + + UserConfig.DrawSliderInt(0, 100, DNC_AoE_Adv_PanicHealWindPercent, "Second Wind HP%", 200); + + break; + + case CustomComboPreset.DNCPvP_BurstMode_CuringWaltz: + UserConfig.DrawSliderInt(0, 90, DNCPvP.Config.DNCPvP_WaltzThreshold, + "Curing Waltz HP% - caps at 90 to prevent waste."); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/DOH.cs b/XIVSlothCombo/Combos/PvE/DOH/DOH.cs similarity index 93% rename from XIVSlothCombo/Combos/PvE/DOH.cs rename to XIVSlothCombo/Combos/PvE/DOH/DOH.cs index 790055752..db1bef4bb 100644 --- a/XIVSlothCombo/Combos/PvE/DOH.cs +++ b/XIVSlothCombo/Combos/PvE/DOH/DOH.cs @@ -1,6 +1,6 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class DOH + internal partial class DOH { public const byte ClassID = 0; public const byte JobID = 50; diff --git a/XIVSlothCombo/Combos/PvE/DOH/DOH_Config.cs b/XIVSlothCombo/Combos/PvE/DOH/DOH_Config.cs new file mode 100644 index 000000000..0b1656d8b --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/DOH/DOH_Config.cs @@ -0,0 +1,17 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class DOH +{ + internal static class Config + { + //Config goes here + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + //Presets + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/DOL.cs b/XIVSlothCombo/Combos/PvE/DOL/DOL.cs similarity index 99% rename from XIVSlothCombo/Combos/PvE/DOL.cs rename to XIVSlothCombo/Combos/PvE/DOL/DOL.cs index 365bfddd6..4e0bb0a3f 100644 --- a/XIVSlothCombo/Combos/PvE/DOL.cs +++ b/XIVSlothCombo/Combos/PvE/DOL/DOL.cs @@ -3,7 +3,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class DOL + internal partial class DOL { public const byte ClassID = 0; public const byte JobID = 51; diff --git a/XIVSlothCombo/Combos/PvE/DOL/DOL_Config.cs b/XIVSlothCombo/Combos/PvE/DOL/DOL_Config.cs new file mode 100644 index 000000000..44705ba34 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/DOL/DOL_Config.cs @@ -0,0 +1,17 @@ +namespace XIVSlothCombo.Combos.PvE; + +internal partial class DOL +{ + internal static class Config + { + //Config goes here + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + //Presets + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/DRG/DRG_Config.cs b/XIVSlothCombo/Combos/PvE/DRG/DRG_Config.cs index e522e757d..4106a0ace 100644 --- a/XIVSlothCombo/Combos/PvE/DRG/DRG_Config.cs +++ b/XIVSlothCombo/Combos/PvE/DRG/DRG_Config.cs @@ -43,8 +43,7 @@ internal static void Draw(CustomComboPreset preset) break; - case CustomComboPreset.DRG_Variant_Cure: - DrawSliderInt(1, 100, DRG_Variant_Cure, "HP% to be at or under", 200); + case CustomComboPreset.DRG_Variant_Cure: DrawSliderInt(1, 100, DRG_Variant_Cure, "HP% to be at or under", 200); break; diff --git a/XIVSlothCombo/Combos/PvE/DRK.cs b/XIVSlothCombo/Combos/PvE/DRK/DRK.cs similarity index 97% rename from XIVSlothCombo/Combos/PvE/DRK.cs rename to XIVSlothCombo/Combos/PvE/DRK/DRK.cs index eff77a9a3..874a2f712 100644 --- a/XIVSlothCombo/Combos/PvE/DRK.cs +++ b/XIVSlothCombo/Combos/PvE/DRK/DRK.cs @@ -5,7 +5,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class DRK + internal partial class DRK { public const byte JobID = 32; @@ -76,15 +76,6 @@ public const uint EnhancedDelirium = 572; } - public static class Config - { - public static readonly UserInt - DRK_ST_ManaSpenderPooling = new("DRK_ST_ManaSpenderPooling", 3000), - DRK_ST_LivingDeadThreshold = new("DRK_ST_LivingDeadThreshold", 10), - DRK_AoE_LivingDeadThreshold = new("DRK_AoE_LivingDeadThreshold", 40), - DRK_VariantCure = new("DRKVariantCure"); - } - internal class DRK_ST_Combo : CustomCombo { protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.DRK_ST_Combo; diff --git a/XIVSlothCombo/Combos/PvE/DRK/DRK_Config.cs b/XIVSlothCombo/Combos/PvE/DRK/DRK_Config.cs new file mode 100644 index 000000000..5f3119db5 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/DRK/DRK_Config.cs @@ -0,0 +1,58 @@ +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class DRK +{ + internal static class Config + { + public static readonly UserInt + DRK_ST_ManaSpenderPooling = new("DRK_ST_ManaSpenderPooling", 3000), + DRK_ST_LivingDeadThreshold = new("DRK_ST_LivingDeadThreshold", 10), + DRK_AoE_LivingDeadThreshold = new("DRK_AoE_LivingDeadThreshold", 40), + DRK_VariantCure = new("DRKVariantCure"); + + internal static void Draw(CustomComboPreset preset) + { + #region DARK KNIGHT + + switch (preset) + { + case CustomComboPreset.DRK_ST_ManaSpenderPooling: + UserConfig.DrawSliderInt(0, 3000, DRK_ST_ManaSpenderPooling, + "How much MP to save (0 = Use All)", 150, SliderIncrements.Thousands); + + break; + + case CustomComboPreset.DRK_ST_CDs_LivingShadow: + UserConfig.DrawSliderInt(0, 30, DRK_ST_LivingDeadThreshold, + "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DRK_AoE_CDs_LivingShadow: + UserConfig.DrawSliderInt(0, 60, DRK_AoE_LivingDeadThreshold, + "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)", 150, + SliderIncrements.Fives); + + break; + + case CustomComboPreset.DRKPvP_Burst: + UserConfig.DrawSliderInt(1, 100, DRKPvP.Config.ShadowbringerThreshold, + "HP% to be at or above to use Shadowbringer"); + + break; + + case CustomComboPreset.DRK_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, DRK_VariantCure, "HP% to be at or under", 200); + + break; + } + + #endregion + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/Enums/OpenerState.cs b/XIVSlothCombo/Combos/PvE/Enums/OpenerState.cs new file mode 100644 index 000000000..c7b462457 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/Enums/OpenerState.cs @@ -0,0 +1,9 @@ +namespace XIVSlothCombo.Combos.JobHelpers.Enums; + +internal enum OpenerState +{ + PrePull, + InOpener, + OpenerFinished, + FailedOpener +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/GNB.cs b/XIVSlothCombo/Combos/PvE/GNB/GNB.cs similarity index 99% rename from XIVSlothCombo/Combos/PvE/GNB.cs rename to XIVSlothCombo/Combos/PvE/GNB/GNB.cs index 6d85cc471..8b14c3cc5 100644 --- a/XIVSlothCombo/Combos/PvE/GNB.cs +++ b/XIVSlothCombo/Combos/PvE/GNB/GNB.cs @@ -8,7 +8,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class GNB + internal partial class GNB { public const byte JobID = 37; @@ -65,18 +65,6 @@ public const ushort BowShock = 1838, SonicBreak = 1837; } - - public static class Config - { - public const string - GNB_VariantCure = "GNB_VariantCure"; - - public static UserInt - GNB_ST_NoMercyStop = new("GNB_ST_NoMercyStop"), - GNB_AoE_NoMercyStop = new ("GNB_AoE_NoMercyStop"); - } - - internal class GNB_ST_SimpleMode : CustomCombo { protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.GNB_ST_Simple; diff --git a/XIVSlothCombo/Combos/PvE/GNB/GNB_Config.cs b/XIVSlothCombo/Combos/PvE/GNB/GNB_Config.cs new file mode 100644 index 000000000..c3860e482 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/GNB/GNB_Config.cs @@ -0,0 +1,40 @@ +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class GNB +{ + internal static class Config + { + public const string + GNB_VariantCure = "GNB_VariantCure"; + + public static UserInt + GNB_ST_NoMercyStop = new("GNB_ST_NoMercyStop"), + GNB_AoE_NoMercyStop = new("GNB_AoE_NoMercyStop"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.GNB_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, GNB_VariantCure, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.GNB_ST_NoMercy: + UserConfig.DrawSliderInt(0, 25, GNB_ST_NoMercyStop, + "Stop Usage if Target HP% is below set value.\nTo Disable this option, set to 0."); + + break; + + case CustomComboPreset.GNB_AoE_NoMercy: + UserConfig.DrawSliderInt(0, 25, GNB_AoE_NoMercyStop, + "Stop Usage if Target HP% is below set value.\nTo Disable this option, set to 0."); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/MCH/MCH.cs b/XIVSlothCombo/Combos/PvE/MCH/MCH.cs index a861b06ef..9f24faaea 100644 --- a/XIVSlothCombo/Combos/PvE/MCH/MCH.cs +++ b/XIVSlothCombo/Combos/PvE/MCH/MCH.cs @@ -48,7 +48,7 @@ public const uint Excavator = 36981, FullMetalField = 36982; - protected static MCHGauge? Gauge = GetJobGauge(); + protected static MCHGauge Gauge => GetJobGauge(); public static class Buffs { diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK/MNK.cs similarity index 97% rename from XIVSlothCombo/Combos/PvE/MNK.cs rename to XIVSlothCombo/Combos/PvE/MNK/MNK.cs index dfff50113..caa86886c 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK/MNK.cs @@ -2,16 +2,14 @@ using Dalamud.Game.ClientState.JobGauge.Enums; using Dalamud.Game.ClientState.JobGauge.Types; using Dalamud.Game.ClientState.Statuses; -using XIVSlothCombo.Combos.JobHelpers; using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; namespace XIVSlothCombo.Combos.PvE; -internal class MNK +internal partial class MNK { public const byte ClassID = 2; public const byte JobID = 20; @@ -73,17 +71,6 @@ public const ushort Brotherhood = 1185; } - public static class Config - { - public static UserInt - MNK_ST_SecondWind_Threshold = new("MNK_ST_SecondWindThreshold", 25), - MNK_ST_Bloodbath_Threshold = new("MNK_ST_BloodbathThreshold", 40), - MNK_AoE_SecondWind_Threshold = new("MNK_AoE_SecondWindThreshold", 25), - MNK_AoE_Bloodbath_Threshold = new("MNK_AoE_BloodbathThreshold", 40), - MNK_SelectedOpener = new("MNK_SelectedOpener"), - MNK_VariantCure = new("MNK_Variant_Cure"); - } - internal class MNK_ST_SimpleMode : CustomCombo { internal static MNKOpenerLogic MNKOpener = new(); @@ -240,7 +227,7 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb return WindsReply; // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID, true); + return DetermineCoreAbility(actionID, true); } return actionID; @@ -428,7 +415,7 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); + return DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); } return actionID; diff --git a/XIVSlothCombo/Combos/PvE/MNK/MNK_Config.cs b/XIVSlothCombo/Combos/PvE/MNK/MNK_Config.cs new file mode 100644 index 000000000..3da4ca451 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/MNK/MNK_Config.cs @@ -0,0 +1,54 @@ +using XIVSlothCombo.CustomComboNS.Functions; +using static XIVSlothCombo.Window.Functions.UserConfig; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class MNK +{ + internal static class Config + { + public static UserInt + MNK_ST_SecondWind_Threshold = new("MNK_ST_SecondWindThreshold", 25), + MNK_ST_Bloodbath_Threshold = new("MNK_ST_BloodbathThreshold", 40), + MNK_AoE_SecondWind_Threshold = new("MNK_AoE_SecondWindThreshold", 25), + MNK_AoE_Bloodbath_Threshold = new("MNK_AoE_BloodbathThreshold", 40), + MNK_SelectedOpener = new("MNK_SelectedOpener"), + MNK_VariantCure = new("MNK_Variant_Cure"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.MNK_ST_ComboHeals: + DrawSliderInt(0, 100, Config.MNK_ST_SecondWind_Threshold, + "Second Wind HP percentage threshold (0 = Disabled)"); + + DrawSliderInt(0, 100, Config.MNK_ST_Bloodbath_Threshold, + "Bloodbath HP percentage threshold (0 = Disabled)"); + + break; + + case CustomComboPreset.MNK_AoE_ComboHeals: + DrawSliderInt(0, 100, Config.MNK_AoE_SecondWind_Threshold, + "Second Wind HP percentage threshold (0 = Disabled)"); + + DrawSliderInt(0, 100, Config.MNK_AoE_Bloodbath_Threshold, + "Bloodbath HP percentage threshold (0 = Disabled)"); + + break; + + case CustomComboPreset.MNK_STUseOpener: + DrawHorizontalRadioButton(Config.MNK_SelectedOpener, "Double Lunar", "Uses Lunar/Lunar opener", 0); + + DrawHorizontalRadioButton(Config.MNK_SelectedOpener, "Solar Lunar", "Uses Solar/Lunar opener", 1); + + break; + + case CustomComboPreset.MNK_Variant_Cure: + DrawSliderInt(1, 100, Config.MNK_VariantCure, "HP% to be at or under", 200); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/MNK/MNK_Helper.cs b/XIVSlothCombo/Combos/PvE/MNK/MNK_Helper.cs new file mode 100644 index 000000000..3d96a4b8c --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/MNK/MNK_Helper.cs @@ -0,0 +1,389 @@ +using Dalamud.Game.ClientState.JobGauge.Enums; +using ECommons.DalamudServices; +using XIVSlothCombo.Combos.JobHelpers.Enums; +using XIVSlothCombo.Data; +using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class MNK +{ + private static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled) + { + if (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist)) + return Gauge.OpoOpoFury == 0 && LevelChecked(DragonKick) + ? DragonKick + : OriginalHook(Bootshine); + + if (HasEffect(Buffs.RaptorForm)) + return Gauge.RaptorFury == 0 && LevelChecked(TwinSnakes) + ? TwinSnakes + : OriginalHook(TrueStrike); + + if (HasEffect(Buffs.CoeurlForm)) + { + if (Gauge.CoeurlFury == 0 && LevelChecked(Demolish)) + { + if (!OnTargetsRear() && + TargetNeedsPositionals() && + !HasEffect(Buffs.TrueNorth) && + ActionReady(TrueNorth) && + useTrueNorthIfEnabled) + return TrueNorth; + + return Demolish; + } + + if (LevelChecked(SnapPunch)) + { + if (!OnTargetsFlank() && + TargetNeedsPositionals() && + !HasEffect(Buffs.TrueNorth) && + ActionReady(TrueNorth) && + useTrueNorthIfEnabled) + return TrueNorth; + + return OriginalHook(SnapPunch); + } + } + + return actionId; + } + + internal class MNKOpenerLogic + { + private OpenerState currentState = OpenerState.PrePull; + + public uint OpenerStep; + + public uint PrePullStep; + + private static uint OpenerLevel => 100; + + public static bool LevelChecked => LocalPlayer.Level >= OpenerLevel; + + private static bool CanOpener => HasCooldowns() && LevelChecked; + + public OpenerState CurrentState + { + get => currentState; + set + { + if (value != currentState) + { + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); + if (value == OpenerState.InOpener) OpenerStep = 1; + + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) + { + if (value == OpenerState.FailedOpener) + Svc.Log.Information($"Opener Failed at step {OpenerStep}"); + + ResetOpener(); + } + if (value == OpenerState.OpenerFinished) Svc.Log.Information("Opener Finished"); + + currentState = value; + } + } + } + + private static bool HasCooldowns() + { + if (GetRemainingCharges(PerfectBalance) < 2) + return false; + + if (!ActionReady(Brotherhood)) + return false; + + if (!ActionReady(RiddleOfFire)) + return false; + + if (!ActionReady(RiddleOfWind)) + return false; + + if (!ActionReady(Meditation) && Gauge.Chakra < 5) + return false; + + if (Gauge.Nadi != Nadi.NONE) + return false; + + if (Gauge.RaptorFury != 0) + return false; + + if (Gauge.CoeurlFury != 0) + return false; + + return true; + } + + private bool DoPrePullSteps(ref uint actionID) + { + if (!LevelChecked) return false; + + if (CanOpener && PrePullStep == 0) PrePullStep = 1; + + if (!HasCooldowns()) PrePullStep = 0; + + if (CurrentState == OpenerState.PrePull && PrePullStep > 0) + { + if (Gauge.Chakra < 5 && PrePullStep == 1) + { + actionID = ForbiddenMeditation; + + return true; + } + + if (!HasEffect(Buffs.FormlessFist) && + !HasEffect(Buffs.RaptorForm) && PrePullStep == 1) + { + actionID = FormShift; + + return true; + } + + if (WasLastAction(DragonKick) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + else if (PrePullStep == 1) actionID = DragonKick; + + if (ActionWatching.CombatActions.Count > 2 && InCombat()) + CurrentState = OpenerState.FailedOpener; + + return true; + } + PrePullStep = 0; + + return false; + } + + private bool DoSlOpener(ref uint actionID) + { + if (!LevelChecked) + return false; + + if (currentState == OpenerState.InOpener) + { + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + CanWeave(ActionWatching.LastWeaponskill) && + Gauge.Chakra >= 5 && + OpenerStep > 9) + { + actionID = TheForbiddenChakra; + + return true; + } + + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; + + if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = TwinSnakes; + + if (WasLastWeaponskill(Demolish) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = Demolish; + + if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Brotherhood; + + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) + actionID = RiddleOfFire; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; + + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; + + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) + actionID = RiddleOfWind; + + if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = RisingPhoenix; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; + + if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = WindsReply; + + if (WasLastWeaponskill(FiresReply) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = FiresReply; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; + + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; + + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; + + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; + + if (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || + (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || + (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || + (actionID is Brotherhood && IsOnCooldown(Brotherhood))) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; + + return false; + } + + return true; + } + + return false; + } + + private bool DoLlOpener(ref uint actionID) + { + if (!LevelChecked) + return false; + + if (currentState == OpenerState.InOpener) + { + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + CanWeave(ActionWatching.LastWeaponskill) && + Gauge.Chakra >= 5 && + OpenerStep > 9) + { + actionID = TheForbiddenChakra; + + return true; + } + + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; + + if (WasLastAction(LeapingOpo) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = LeapingOpo; + + if (WasLastAction(DragonKick) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = DragonKick; + + if (WasLastAction(Brotherhood) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Brotherhood; + + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) + actionID = RiddleOfFire; + + if (WasLastAction(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; + + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; + + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) + actionID = RiddleOfWind; + + if (WasLastAction(ElixirBurst) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = ElixirBurst; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; + + if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = WindsReply; + + if (WasLastWeaponskill(FiresReply) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = FiresReply; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; + + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; + + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; + + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; + + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; + + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; + + if (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || + (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || + (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || + (actionID is Brotherhood && IsOnCooldown(Brotherhood))) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; + + return false; + } + + return true; + } + + return false; + } + + private void ResetOpener() + { + PrePullStep = 0; + OpenerStep = 0; + } + + public bool DoFullOpener(ref uint actionID, int selectedOpener) + { + if (!LevelChecked) + return false; + + if (CurrentState == OpenerState.PrePull) + if (DoPrePullSteps(ref actionID)) + return true; + + if (CurrentState == OpenerState.InOpener) + switch (selectedOpener) + { + case 0 when DoLlOpener(ref actionID): + + case 1 when DoSlOpener(ref actionID): + return true; + } + + if (!InCombat()) + { + ResetOpener(); + CurrentState = OpenerState.PrePull; + } + + return false; + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/NIN.cs b/XIVSlothCombo/Combos/PvE/NIN/NIN.cs similarity index 97% rename from XIVSlothCombo/Combos/PvE/NIN.cs rename to XIVSlothCombo/Combos/PvE/NIN/NIN.cs index f36fb7d85..4c24e81bf 100644 --- a/XIVSlothCombo/Combos/PvE/NIN.cs +++ b/XIVSlothCombo/Combos/PvE/NIN/NIN.cs @@ -5,11 +5,10 @@ using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.Data; using XIVSlothCombo.Extensions; -using static XIVSlothCombo.Combos.JobHelpers.NIN; namespace XIVSlothCombo.Combos.PvE { - internal class NIN + internal partial class NIN { public const byte ClassID = 29; public const byte JobID = 30; @@ -112,30 +111,7 @@ public const uint EnhancedKasatsu = 250; } - public static class Config - { - public const string - Trick_CooldownRemaining = "Trick_CooldownRemaining", - Mug_NinkiGauge = "Mug_NinkiGauge", - Ninki_BhavaPooling = "Ninki_BhavaPooling", - Ninki_HellfrogPooling = "Ninki_HellfrogPooling", - NIN_SimpleMudra_Choice = "NIN_SimpleMudra_Choice", - Ninki_BunshinPoolingST = "Ninki_BunshinPoolingST", - Ninki_BunshinPoolingAoE = "Ninki_BunshinPoolingAoE", - Advanced_Trick_Cooldown = "Advanced_Trick_Cooldown", - Advanced_DotonTimer = "Advanced_DotonTimer", - Advanced_DotonHP = "Advanced_DotonHP", - BurnKazematoi = "BurnKazematoi", - Advanced_TCJEnderAoE = "Advanced_TCJEnderAoe", - Advanced_ChargePool = "Advanced_ChargePool", - SecondWindThresholdST = "SecondWindThresholdST", - ShadeShiftThresholdST = "ShadeShiftThresholdST", - BloodbathThresholdST = "BloodbathThresholdST", - SecondWindThresholdAoE = "SecondWindThresholdAoE", - ShadeShiftThresholdAoE = "ShadeShiftThresholdAoE", - BloodbathThresholdAoE = "BloodbathThresholdAoE", - NIN_VariantCure = "NIN_VariantCure"; - } + internal class NIN_ST_AdvancedMode : CustomCombo { @@ -187,8 +163,8 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (Raiton.LevelChecked() && IsEnabled(CustomComboPreset.NIN_ST_AdvancedMode_Ninjitsus_Raiton)) //under 45 will only use Raiton { - if (mudraState.CastRaiton(ref actionID)) - return actionID; + if (mudraState.CastRaiton(ref actionID)) + return actionID; } else if (!Raiton.LevelChecked() && mudraState.CastFumaShuriken(ref actionID) && IsEnabled(CustomComboPreset.NIN_ST_AdvancedMode_Ninjitsus_FumaShuriken)) // 30-35 will use only fuma return actionID; diff --git a/XIVSlothCombo/Combos/PvE/NIN/NIN_Config.cs b/XIVSlothCombo/Combos/PvE/NIN/NIN_Config.cs new file mode 100644 index 000000000..e5fa71402 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/NIN/NIN_Config.cs @@ -0,0 +1,155 @@ +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class NIN +{ + internal static class Config + { + public const string + Trick_CooldownRemaining = "Trick_CooldownRemaining", + Mug_NinkiGauge = "Mug_NinkiGauge", + Ninki_BhavaPooling = "Ninki_BhavaPooling", + Ninki_HellfrogPooling = "Ninki_HellfrogPooling", + NIN_SimpleMudra_Choice = "NIN_SimpleMudra_Choice", + Ninki_BunshinPoolingST = "Ninki_BunshinPoolingST", + Ninki_BunshinPoolingAoE = "Ninki_BunshinPoolingAoE", + Advanced_Trick_Cooldown = "Advanced_Trick_Cooldown", + Advanced_DotonTimer = "Advanced_DotonTimer", + Advanced_DotonHP = "Advanced_DotonHP", + BurnKazematoi = "BurnKazematoi", + Advanced_TCJEnderAoE = "Advanced_TCJEnderAoe", + Advanced_ChargePool = "Advanced_ChargePool", + SecondWindThresholdST = "SecondWindThresholdST", + ShadeShiftThresholdST = "ShadeShiftThresholdST", + BloodbathThresholdST = "BloodbathThresholdST", + SecondWindThresholdAoE = "SecondWindThresholdAoE", + ShadeShiftThresholdAoE = "ShadeShiftThresholdAoE", + BloodbathThresholdAoE = "BloodbathThresholdAoE", + NIN_VariantCure = "NIN_VariantCure"; + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.NIN_Simple_Mudras: + UserConfig.DrawRadioButton(NIN_SimpleMudra_Choice, "Mudra Path Set 1", + "1. Ten Mudras -> Fuma Shuriken, Raiton/Hyosho Ranryu, Suiton (Doton under Kassatsu).\nChi Mudras -> Fuma Shuriken, Hyoton, Huton.\nJin Mudras -> Fuma Shuriken, Katon/Goka Mekkyaku, Doton", + 1); + + UserConfig.DrawRadioButton(NIN_SimpleMudra_Choice, "Mudra Path Set 2", + "2. Ten Mudras -> Fuma Shuriken, Hyoton/Hyosho Ranryu, Doton.\nChi Mudras -> Fuma Shuriken, Katon, Suiton.\nJin Mudras -> Fuma Shuriken, Raiton/Goka Mekkyaku, Huton (Doton under Kassatsu).", + 2); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode: + UserConfig.DrawSliderInt(0, 10, BurnKazematoi, "Target HP% to dump all pooled Kazematoi below"); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_Bhavacakra: + UserConfig.DrawSliderInt(50, 100, Ninki_BhavaPooling, + "Set the minimal amount of Ninki required to have before spending on Bhavacakra."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_TrickAttack: + UserConfig.DrawSliderInt(0, 21, Trick_CooldownRemaining, + "Set the amount of time remaining on Trick Attack cooldown before trying to set up with Suiton."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_Bunshin: + UserConfig.DrawSliderInt(50, 100, Ninki_BunshinPoolingST, + "Set the amount of Ninki required to have before spending on Bunshin."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_Bunshin: + UserConfig.DrawSliderInt(50, 100, Ninki_BunshinPoolingAoE, + "Set the amount of Ninki required to have before spending on Bunshin."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_TrickAttack_Cooldowns: + UserConfig.DrawSliderInt(0, 21, Advanced_Trick_Cooldown, + "Set the amount of time remaining on Trick Attack cooldown to start saving cooldowns."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_SecondWind: + UserConfig.DrawSliderInt(0, 100, SecondWindThresholdST, + "Set a HP% threshold for when Second Wind will be used."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_ShadeShift: + UserConfig.DrawSliderInt(0, 100, ShadeShiftThresholdST, + "Set a HP% threshold for when Shade Shift will be used."); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_Bloodbath: + UserConfig.DrawSliderInt(0, 100, BloodbathThresholdST, + "Set a HP% threshold for when Bloodbath will be used."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_SecondWind: + UserConfig.DrawSliderInt(0, 100, SecondWindThresholdAoE, + "Set a HP% threshold for when Second Wind will be used."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_ShadeShift: + UserConfig.DrawSliderInt(0, 100, ShadeShiftThresholdAoE, + "Set a HP% threshold for when Shade Shift will be used."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_Bloodbath: + UserConfig.DrawSliderInt(0, 100, BloodbathThresholdAoE, + "Set a HP% threshold for when Bloodbath will be used."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_HellfrogMedium: + UserConfig.DrawSliderInt(50, 100, Ninki_HellfrogPooling, + "Set the amount of Ninki required to have before spending on Hellfrog Medium."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_Ninjitsus_Doton: + UserConfig.DrawSliderInt(0, 18, Advanced_DotonTimer, + "Sets the amount of time remaining on Doton before casting again."); + + UserConfig.DrawSliderInt(0, 100, Advanced_DotonHP, + "Sets the max remaining HP percentage of the current target to cast Doton."); + + break; + + case CustomComboPreset.NIN_AoE_AdvancedMode_TCJ: + UserConfig.DrawRadioButton(Advanced_TCJEnderAoE, "Ten Chi Jin Ender 1", + "Ends Ten Chi Jin with Suiton.", 0); + + UserConfig.DrawRadioButton(Advanced_TCJEnderAoE, "Ten Chi Jin Ender 2", + "Ends Ten Chi Jin with Doton.\nIf you have Doton enabled, Ten Chi Jin will be delayed according to the settings in that feature.", + 1); + + break; + + case CustomComboPreset.NIN_ST_AdvancedMode_Ninjitsus_Raiton: + UserConfig.DrawAdditionalBoolChoice(Advanced_ChargePool, "Pool Charges", + "Waits until at least 2 seconds before your 2nd charge or if Trick Attack debuff is on your target before spending."); + + break; + + case CustomComboPreset.NIN_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, NIN_VariantCure, "HP% to be at or under", 200); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/NIN/NIN_Helper.cs b/XIVSlothCombo/Combos/PvE/NIN/NIN_Helper.cs new file mode 100644 index 000000000..52676fadd --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/NIN/NIN_Helper.cs @@ -0,0 +1,698 @@ +using Dalamud.Game.ClientState.Conditions; +using Dalamud.Game.ClientState.JobGauge.Types; +using ECommons.DalamudServices; +using XIVSlothCombo.Combos.JobHelpers.Enums; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Extensions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class NIN +{ + internal class NINHelper + { + internal static bool InMudra = false; + + internal static bool TrickDebuff => TargetHasTrickDebuff(); + + internal static bool MugDebuff => TargetHasMugDebuff(); + + private static bool TargetHasTrickDebuff() + { + return CustomComboFunctions.TargetHasEffect(Debuffs.TrickAttack) || + CustomComboFunctions.TargetHasEffect(Debuffs.KunaisBane); + } + + private static bool TargetHasMugDebuff() + { + return CustomComboFunctions.TargetHasEffect(Debuffs.Mug) || + CustomComboFunctions.TargetHasEffect(Debuffs.Dokumori); + } + } + + internal class MudraCasting + { + public enum MudraState + { + None, + CastingFumaShuriken, + CastingKaton, + CastingRaiton, + CastingHyoton, + CastingHuton, + CastingDoton, + CastingSuiton, + CastingGokaMekkyaku, + CastingHyoshoRanryu + } + + private MudraState currentMudra = MudraState.None; + + private bool justResetMudra; + + public MudraState CurrentMudra + { + get => currentMudra; + set + { + if (value == MudraState.None) + justResetMudra = true; + else + justResetMudra = false; + + currentMudra = value; + } + } + + /// Checks if the player is in a state to be able to cast a ninjitsu. + private static bool CanCast() + { + if (NINHelper.InMudra) return true; + + float gcd = CustomComboFunctions.GetCooldown(GustSlash).CooldownTotal; + + if (gcd == 0.5) return true; + + if (CustomComboFunctions.GetRemainingCharges(Ten) == 0 && + !CustomComboFunctions.HasEffect(Buffs.Mudra) && + !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) + return false; + + return true; + } + + /// Simple method of casting Fuma Shuriken. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastFumaShuriken(ref uint actionID) + { + if (FumaShuriken.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingFumaShuriken) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Ten); + CurrentMudra = MudraState.CastingFumaShuriken; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Raiton. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastRaiton(ref uint actionID) + { + if (Raiton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingRaiton) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Chi); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Raiton) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Ten); + CurrentMudra = MudraState.CastingRaiton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Katon. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastKaton(ref uint actionID) + { + if (Katon.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingKaton) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Ten); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Katon) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Chi); + CurrentMudra = MudraState.CastingKaton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Hyoton. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastHyoton(ref uint actionID) + { + if (Hyoton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHyoton) + { + if (!CanCast() || CustomComboFunctions.HasEffect(Buffs.Kassatsu)) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Jin); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Ten); + CurrentMudra = MudraState.CastingHyoton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Huton. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastHuton(ref uint actionID) + { + if (Huton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHuton) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Jin); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) + { + actionID = CustomComboFunctions.OriginalHook(Ten); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Huton) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Chi); + CurrentMudra = MudraState.CastingHuton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Doton. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastDoton(ref uint actionID) + { + if (Doton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingDoton) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Jin); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Hyoton) + { + actionID = CustomComboFunctions.OriginalHook(Chi); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Doton) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Ten); + CurrentMudra = MudraState.CastingDoton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Suiton. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastSuiton(ref uint actionID) + { + if (Suiton.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingSuiton) + { + if (!CanCast()) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Chi); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Raiton) + { + actionID = CustomComboFunctions.OriginalHook(Jin); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is Suiton) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Ten); + CurrentMudra = MudraState.CastingSuiton; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Goka Mekkyaku. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastGokaMekkyaku(ref uint actionID) + { + if (GokaMekkyaku.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingGokaMekkyaku) + { + if (!CanCast() || !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Ten); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is GokaMekkyaku) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Chi); + CurrentMudra = MudraState.CastingGokaMekkyaku; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + /// Simple method of casting Hyosho Ranryu. + /// The actionID from the combo. + /// True if in a state to cast or continue the ninjitsu, modifies actionID to the step of the ninjitsu. + public bool CastHyoshoRanryu(ref uint actionID) + { + if (HyoshoRanryu.LevelChecked() && CurrentMudra is MudraState.None or MudraState.CastingHyoshoRanryu) + { + if (!CanCast() || !CustomComboFunctions.HasEffect(Buffs.Kassatsu)) + { + CurrentMudra = MudraState.None; + + return false; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is FumaShuriken) + { + actionID = CustomComboFunctions.OriginalHook(Jin); + + return true; + } + + if (CustomComboFunctions.OriginalHook(Ninjutsu) is HyoshoRanryu) + { + actionID = CustomComboFunctions.OriginalHook(Ninjutsu); + + return true; + } + + actionID = CustomComboFunctions.OriginalHook(Chi); + CurrentMudra = MudraState.CastingHyoshoRanryu; + + return true; + } + + CurrentMudra = MudraState.None; + + return false; + } + + public bool ContinueCurrentMudra(ref uint actionID) + { + if ((CustomComboFunctions.WasLastAction(FumaShuriken) || + CustomComboFunctions.WasLastAction(Katon) || + CustomComboFunctions.WasLastAction(Raiton) || + CustomComboFunctions.WasLastAction(Hyoton) || + CustomComboFunctions.WasLastAction(Huton) || + CustomComboFunctions.WasLastAction(Doton) || + CustomComboFunctions.WasLastAction(Suiton) || + CustomComboFunctions.WasLastAction(GokaMekkyaku) || + CustomComboFunctions.WasLastAction(HyoshoRanryu)) && + !justResetMudra) + CurrentMudra = MudraState.None; + + return CurrentMudra switch + { + MudraState.None => false, + MudraState.CastingFumaShuriken => CastFumaShuriken(ref actionID), + MudraState.CastingKaton => CastKaton(ref actionID), + MudraState.CastingRaiton => CastRaiton(ref actionID), + MudraState.CastingHyoton => CastHyoton(ref actionID), + MudraState.CastingHuton => CastHuton(ref actionID), + MudraState.CastingDoton => CastDoton(ref actionID), + MudraState.CastingSuiton => CastSuiton(ref actionID), + MudraState.CastingGokaMekkyaku => CastGokaMekkyaku(ref actionID), + MudraState.CastingHyoshoRanryu => CastHyoshoRanryu(ref actionID), + _ => false + }; + } + } + + internal class NINOpenerLogic + { + private OpenerState currentState = OpenerState.OpenerFinished; + + private bool openerEventsSetup; + + private uint openerStep = 1; + + public uint PrePullStep = 1; + + private static uint OpenerLevel => 100; + + public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; + + private static bool CanOpener => HasCooldowns() && LevelChecked; + + public OpenerState CurrentState + { + get => currentState; + set + { + if (value != currentState) + { + if (value == OpenerState.PrePull) PrePullStep = 1; + if (value == OpenerState.InOpener) OpenerStep = 1; + + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) + { + PrePullStep = 0; + OpenerStep = 0; + } + + currentState = value; + } + } + } + + public uint OpenerStep + { + get => openerStep; + set + { + if (value != openerStep) Svc.Log.Debug($"{value}"); + openerStep = value; + } + } + + private static bool HasCooldowns() + { + if (CustomComboFunctions.GetRemainingCharges(Ten) < 1) return false; + if (CustomComboFunctions.IsOnCooldown(Mug)) return false; + if (CustomComboFunctions.IsOnCooldown(TenChiJin)) return false; + if (CustomComboFunctions.IsOnCooldown(PhantomKamaitachi)) return false; + if (CustomComboFunctions.IsOnCooldown(Bunshin)) return false; + if (CustomComboFunctions.IsOnCooldown(DreamWithinADream)) return false; + if (CustomComboFunctions.IsOnCooldown(Kassatsu)) return false; + if (CustomComboFunctions.IsOnCooldown(TrickAttack)) return false; + + return true; + } + + private bool DoPrePullSteps(ref uint actionID, MudraCasting mudraState) + { + if (!LevelChecked) return false; + + if (CanOpener && PrePullStep == 0 && !CustomComboFunctions.InCombat()) CurrentState = OpenerState.PrePull; + + if (CurrentState == OpenerState.PrePull) + { + if (CustomComboFunctions.WasLastAction(Suiton) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + else if (PrePullStep == 1) mudraState.CastSuiton(ref actionID); + + ////Failure states + //if (PrePullStep is (1 or 2) && CustomComboFunctions.InCombat()) { mudraState.CurrentMudra = MudraCasting.MudraState.None; ResetOpener(); } + + return true; + } + + PrePullStep = 0; + + return false; + } + + private bool DoOpener(ref uint actionID, MudraCasting mudraState) + { + if (!LevelChecked) return false; + + if (CurrentState == OpenerState.InOpener) + { + bool inLateWeaveWindow = CustomComboFunctions.CanDelayedWeave(GustSlash, 1, 0); + + if (CustomComboFunctions.WasLastAction(Kassatsu) && OpenerStep == 1) OpenerStep++; + else if (OpenerStep == 1) actionID = CustomComboFunctions.OriginalHook(Kassatsu); + + if (CustomComboFunctions.WasLastAction(SpinningEdge) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = CustomComboFunctions.OriginalHook(SpinningEdge); + + if (CustomComboFunctions.WasLastAction(GustSlash) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = CustomComboFunctions.OriginalHook(GustSlash); + + if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(Mug)) && OpenerStep == 4) + OpenerStep++; + else if (OpenerStep == 4) actionID = CustomComboFunctions.OriginalHook(Mug); + + if (CustomComboFunctions.WasLastAction(Bunshin) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = CustomComboFunctions.OriginalHook(Bunshin); + + if (CustomComboFunctions.WasLastAction(PhantomKamaitachi) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = CustomComboFunctions.OriginalHook(PhantomKamaitachi); + + if (CustomComboFunctions.WasLastAction(ArmorCrush) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = CustomComboFunctions.OriginalHook(ArmorCrush); + + if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(TrickAttack)) && + OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8 && inLateWeaveWindow) + actionID = CustomComboFunctions.OriginalHook(TrickAttack); + + if (CustomComboFunctions.WasLastAction(HyoshoRanryu) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) mudraState.CastHyoshoRanryu(ref actionID); + + if (CustomComboFunctions.WasLastAction(DreamWithinADream) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = CustomComboFunctions.OriginalHook(DreamWithinADream); + + if (CustomComboFunctions.WasLastAction(Raiton) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) mudraState.CastRaiton(ref actionID); + + if (CustomComboFunctions.WasLastAction(TenChiJin) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = CustomComboFunctions.OriginalHook(TenChiJin); + + if (CustomComboFunctions.WasLastAction(TCJFumaShurikenTen) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = CustomComboFunctions.OriginalHook(Ten); + + if (CustomComboFunctions.WasLastAction(TCJRaiton) && OpenerStep == 14) OpenerStep++; + else if (OpenerStep == 14) actionID = CustomComboFunctions.OriginalHook(Chi); + + if (CustomComboFunctions.WasLastAction(TCJSuiton) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = CustomComboFunctions.OriginalHook(Jin); + + if (CustomComboFunctions.WasLastAction(Meisui) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = CustomComboFunctions.OriginalHook(Meisui); + + if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); + + if (CustomComboFunctions.WasLastAction(ZeshoMeppo) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = CustomComboFunctions.OriginalHook(Bhavacakra); + + if (CustomComboFunctions.WasLastAction(TenriJendo) && OpenerStep == 19) OpenerStep++; + else if (OpenerStep == 19) actionID = CustomComboFunctions.OriginalHook(TenriJendo); + + if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 20) OpenerStep++; + else if (OpenerStep == 20) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); + + if (CustomComboFunctions.WasLastAction(CustomComboFunctions.OriginalHook(Bhavacakra)) && + OpenerStep == 21) OpenerStep++; + else if (OpenerStep == 21) actionID = CustomComboFunctions.OriginalHook(Bhavacakra); + + if (CustomComboFunctions.WasLastAction(Raiton) && OpenerStep == 22) OpenerStep++; + else if (OpenerStep == 22) mudraState.CastRaiton(ref actionID); + + if (CustomComboFunctions.WasLastAction(FleetingRaiju) && OpenerStep == 23) + CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 23) actionID = CustomComboFunctions.OriginalHook(FleetingRaiju); + + //Failure states + if ((OpenerStep is 13 or 14 or 15 && CustomComboFunctions.IsMoving) || + (OpenerStep is 8 && !CustomComboFunctions.HasEffect(Buffs.ShadowWalker)) || + (OpenerStep is 18 or 21 && CustomComboFunctions.GetJobGauge().Ninki < 40) || + (OpenerStep is 17 or 20 && !CustomComboFunctions.HasEffect(Buffs.RaijuReady)) || + (OpenerStep is 9 && !CustomComboFunctions.HasEffect(Buffs.Kassatsu))) + ResetOpener(); + + return true; + } + + return false; + } + + private void ResetOpener() + { + CurrentState = OpenerState.FailedOpener; + } + + public bool DoFullOpener(ref uint actionID, MudraCasting mudraState) + { + if (!LevelChecked) return false; + + if (!openerEventsSetup) + { + Svc.Condition.ConditionChange += CheckCombatStatus; + openerEventsSetup = true; + } + + if (CurrentState == OpenerState.PrePull || CurrentState == OpenerState.FailedOpener) + if (DoPrePullSteps(ref actionID, mudraState)) + return true; + + if (CurrentState == OpenerState.InOpener) + if (DoOpener(ref actionID, mudraState)) + return true; + + if (CurrentState == OpenerState.OpenerFinished && !CustomComboFunctions.InCombat()) + ResetOpener(); + + return false; + } + + internal void Dispose() + { + Svc.Condition.ConditionChange -= CheckCombatStatus; + } + + private void CheckCombatStatus(ConditionFlag flag, bool value) + { + if (flag == ConditionFlag.InCombat && value == false) ResetOpener(); + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT/PCT.cs similarity index 97% rename from XIVSlothCombo/Combos/PvE/PCT.cs rename to XIVSlothCombo/Combos/PvE/PCT/PCT.cs index 2b3579f4d..5ca17c329 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT/PCT.cs @@ -1,15 +1,13 @@ using Dalamud.Game.ClientState.JobGauge.Types; -using XIVSlothCombo.Combos.JobHelpers; using XIVSlothCombo.Core; using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; using XIVSlothCombo.Extensions; namespace XIVSlothCombo.Combos.PvE { - internal class PCT + internal partial class PCT { public const byte JobID = 42; @@ -73,28 +71,7 @@ public static class Debuffs { } - - public static class Config - { - public static UserInt - CombinedAetherhueChoices = new("CombinedAetherhueChoices"), - PCT_ST_AdvancedMode_LucidOption = new("PCT_ST_AdvancedMode_LucidOption", 6500), - PCT_AoE_AdvancedMode_HolyinWhiteOption = new("PCT_AoE_AdvancedMode_HolyinWhiteOption", 0), - PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500), - PCT_VariantCure = new("PCT_VariantCure"), - PCT_ST_CreatureStop = new("PCT_ST_CreatureStop"), - PCT_AoE_CreatureStop = new("PCT_AoE_CreatureStop"), - PCT_ST_WeaponStop = new("PCT_ST_WeaponStop"), - PCT_AoE_WeaponStop = new("PCT_AoE_WeaponStop"), - PCT_ST_LandscapeStop = new("PCT_ST_LandscapeStop"), - PCT_AoE_LandscapeStop = new("PCT_AoE_LandscapeStop"); - - public static UserBool - CombinedMotifsMog = new("CombinedMotifsMog"), - CombinedMotifsMadeen = new("CombinedMotifsMadeen"), - CombinedMotifsWeapon = new("CombinedMotifsWeapon"); - } - + internal class PCT_ST_SimpleMode : CustomCombo { diff --git a/XIVSlothCombo/Combos/PvE/PCT/PCT_Config.cs b/XIVSlothCombo/Combos/PvE/PCT/PCT_Config.cs new file mode 100644 index 000000000..6c9e7d89f --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/PCT/PCT_Config.cs @@ -0,0 +1,125 @@ +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Extensions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class PCT +{ + internal static class Config + { + public static UserInt + CombinedAetherhueChoices = new("CombinedAetherhueChoices"), + PCT_ST_AdvancedMode_LucidOption = new("PCT_ST_AdvancedMode_LucidOption", 6500), + PCT_AoE_AdvancedMode_HolyinWhiteOption = new("PCT_AoE_AdvancedMode_HolyinWhiteOption", 0), + PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500), + PCT_VariantCure = new("PCT_VariantCure"), + PCT_ST_CreatureStop = new("PCT_ST_CreatureStop"), + PCT_AoE_CreatureStop = new("PCT_AoE_CreatureStop"), + PCT_ST_WeaponStop = new("PCT_ST_WeaponStop"), + PCT_AoE_WeaponStop = new("PCT_AoE_WeaponStop"), + PCT_ST_LandscapeStop = new("PCT_ST_LandscapeStop"), + PCT_AoE_LandscapeStop = new("PCT_AoE_LandscapeStop"); + + public static UserBool + CombinedMotifsMog = new("CombinedMotifsMog"), + CombinedMotifsMadeen = new("CombinedMotifsMadeen"), + CombinedMotifsWeapon = new("CombinedMotifsWeapon"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.CombinedAetherhues: + UserConfig.DrawRadioButton(CombinedAetherhueChoices, "Both Single Target & AoE", + $"Replaces both {FireInRed.ActionName()} & {FireIIinRed.ActionName()}", 0); + + UserConfig.DrawRadioButton(CombinedAetherhueChoices, "Single Target Only", + $"Replace only {FireInRed.ActionName()}", 1); + + UserConfig.DrawRadioButton(CombinedAetherhueChoices, "AoE Only", + $"Replace only {FireIIinRed.ActionName()}", 2); + + break; + + case CustomComboPreset.CombinedMotifs: + UserConfig.DrawAdditionalBoolChoice(CombinedMotifsMog, $"{MogoftheAges.ActionName()} Feature", + $"Add {MogoftheAges.ActionName()} when fully drawn and off cooldown."); + + UserConfig.DrawAdditionalBoolChoice(CombinedMotifsMadeen, + $"{RetributionoftheMadeen.ActionName()} Feature", + $"Add {RetributionoftheMadeen.ActionName()} when fully drawn and off cooldown."); + + UserConfig.DrawAdditionalBoolChoice(CombinedMotifsWeapon, $"{HammerStamp.ActionName()} Feature", + $"Add {HammerStamp.ActionName()} when under the effect of {Buffs.HammerTime.StatusName()}."); + + break; + + case CustomComboPreset.PCT_ST_AdvancedMode_LucidDreaming: + UserConfig.DrawSliderInt(0, 10000, PCT_ST_AdvancedMode_LucidOption, + "Add Lucid Dreaming when below this MP", sliderIncrement: SliderIncrements.Hundreds); + + break; + + case CustomComboPreset.PCT_AoE_AdvancedMode_HolyinWhite: + UserConfig.DrawSliderInt(0, 5, PCT_AoE_AdvancedMode_HolyinWhiteOption, + "How many charges to keep ready? (0 = Use all)"); + + break; + + case CustomComboPreset.PCT_AoE_AdvancedMode_LucidDreaming: + UserConfig.DrawSliderInt(0, 10000, PCT_AoE_AdvancedMode_LucidOption, + "Add Lucid Dreaming when below this MP", sliderIncrement: SliderIncrements.Hundreds); + + break; + + case CustomComboPreset.PCT_ST_AdvancedMode_LandscapeMotif: + UserConfig.DrawSliderInt(0, 10, PCT_ST_LandscapeStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_ST_AdvancedMode_CreatureMotif: + UserConfig.DrawSliderInt(0, 10, PCT_ST_CreatureStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_ST_AdvancedMode_WeaponMotif: + UserConfig.DrawSliderInt(0, 10, PCT_ST_WeaponStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_AoE_AdvancedMode_LandscapeMotif: + UserConfig.DrawSliderInt(0, 10, PCT_AoE_LandscapeStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_AoE_AdvancedMode_CreatureMotif: + UserConfig.DrawSliderInt(0, 10, PCT_AoE_CreatureStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_AoE_AdvancedMode_WeaponMotif: + UserConfig.DrawSliderInt(0, 10, PCT_AoE_WeaponStop, "Health % to stop Drawing Motif"); + + break; + + case CustomComboPreset.PCT_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, PCT_VariantCure, "HP% to be at or under", 200); + + break; + + // PvP + case CustomComboPreset.PCTPvP_BurstControl: + UserConfig.DrawSliderInt(1, 100, PCTPvP.Config.PCTPvP_BurstHP, "Target HP%", 200); + + break; + + case CustomComboPreset.PCTPvP_TemperaCoat: + UserConfig.DrawSliderInt(1, 100, PCTPvP.Config.PCTPvP_TemperaHP, "Player HP%", 200); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/JobHelpers/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT/PCT_Helper.cs similarity index 82% rename from XIVSlothCombo/Combos/JobHelpers/PCT.cs rename to XIVSlothCombo/Combos/PvE/PCT/PCT_Helper.cs index 01994dea9..3ce2223b5 100644 --- a/XIVSlothCombo/Combos/JobHelpers/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT/PCT_Helper.cs @@ -1,73 +1,41 @@ using Dalamud.Game.ClientState.JobGauge.Types; using ECommons.DalamudServices; using XIVSlothCombo.Combos.JobHelpers.Enums; -using XIVSlothCombo.Combos.PvE; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; using XIVSlothCombo.Extensions; +using CanvasFlags = Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags; -namespace XIVSlothCombo.Combos.JobHelpers -{ +namespace XIVSlothCombo.Combos.PvE; +internal partial class PCT +{ #region Lvl 100 Opener + internal class PCTOpenerLogicLvl100 : PCT { + private OpenerState currentState = OpenerState.PrePull; + public uint OpenerStep; - private static bool HasCooldowns() - { - if (!CustomComboFunctions.ActionReady(StarryMuse)) - return false; - - if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 3) - return false; - - if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) - return false; - return true; - } - private static bool HasMotifs() - { - var gauge = CustomComboFunctions.GetJobGauge(); - - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Pom)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Weapon)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Landscape)) - return false; - if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) - return false; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 100; - public uint PrePullStep = 0; - - public uint OpenerStep = 0; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; - public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -82,24 +50,52 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (!CustomComboFunctions.ActionReady(StarryMuse)) + return false; + + if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 3) + return false; + + if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) + return false; + + return true; + } + + private static bool HasMotifs() + { + PCTGauge gauge = CustomComboFunctions.GetJobGauge(); + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Pom)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape)) + return false; + + if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns() && !HasMotifs()) - { - PrePullStep = 0; - } + if (!HasCooldowns() && !HasMotifs()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull) { - if (CustomComboFunctions.LocalPlayer.CastActionId == RainbowDrip && PrePullStep == 1) CurrentState = OpenerState.InOpener; + if (CustomComboFunctions.LocalPlayer.CastActionId == RainbowDrip && PrePullStep == 1) + CurrentState = OpenerState.InOpener; else if (PrePullStep == 1) actionID = RainbowDrip; if (CustomComboFunctions.InCombat()) @@ -111,6 +107,7 @@ private bool DoPrePullSteps(ref uint actionID) return true; } PrePullStep = 0; + return false; } @@ -119,7 +116,8 @@ private bool DoOpener(ref uint actionID) if (!LevelChecked) return false; - bool isEarlyOpenerEnabled = CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); + bool isEarlyOpenerEnabled = + CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); if (currentState == OpenerState.InOpener) { @@ -141,7 +139,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.LocalPlayer.CastActionId == CustomComboFunctions.OriginalHook(CreatureMotif) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.LocalPlayer.CastActionId == + CustomComboFunctions.OriginalHook(CreatureMotif) && OpenerStep == adjustedStep) OpenerStep++; else if (OpenerStep == adjustedStep) actionID = CustomComboFunctions.OriginalHook(CreatureMotif); adjustedStep++; @@ -156,7 +155,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = SubtractivePalette; adjustedStep++; @@ -171,7 +171,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; @@ -215,6 +216,7 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to timeout."); + return false; } @@ -222,15 +224,16 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.OpenerFinished; Svc.Log.Information("Opener completed successfully."); + return false; } return true; } + return false; } - private void ResetOpener() { PrePullStep = 0; @@ -247,80 +250,47 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } + #endregion - #region Lvl 92 Opener + #region Lvl 92 Opener + internal class PCTOpenerLogicLvl92 : PCT { - private static bool HasCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) - return false; - - if (!CustomComboFunctions.ActionReady(ScenicMuse)) - return false; - - if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) - return false; - - return true; - } + private OpenerState currentState = OpenerState.PrePull; - private static bool HasMotifs() - { - var gauge = CustomComboFunctions.GetJobGauge(); + public uint OpenerStep; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Pom)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Weapon)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Landscape)) - return false; - if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) - return false; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 92; - public uint PrePullStep = 0; - - public uint OpenerStep = 0; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; - public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -335,24 +305,52 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) + return false; + + if (!CustomComboFunctions.ActionReady(ScenicMuse)) + return false; + + if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) + return false; + + return true; + } + + private static bool HasMotifs() + { + PCTGauge gauge = CustomComboFunctions.GetJobGauge(); + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Pom)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape)) + return false; + + if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns() && !HasMotifs()) - { - PrePullStep = 0; - } + if (!HasCooldowns() && !HasMotifs()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (CustomComboFunctions.LocalPlayer.CastActionId == RainbowDrip && PrePullStep == 1) CurrentState = OpenerState.InOpener; + if (CustomComboFunctions.LocalPlayer.CastActionId == RainbowDrip && PrePullStep == 1) + CurrentState = OpenerState.InOpener; else if (PrePullStep == 1) actionID = RainbowDrip; if (CustomComboFunctions.InCombat()) @@ -364,6 +362,7 @@ private bool DoPrePullSteps(ref uint actionID) return true; } PrePullStep = 0; + return false; } @@ -374,7 +373,8 @@ private bool DoOpener(ref uint actionID) if (currentState == OpenerState.InOpener) { - bool isEarlyOpenerEnabled = CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); + bool isEarlyOpenerEnabled = + CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); if (CustomComboFunctions.WasLastAction(StrikingMuse) && OpenerStep == 1) OpenerStep++; else if (OpenerStep == 1) actionID = StrikingMuse; @@ -392,7 +392,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.LocalPlayer.CastActionId == CustomComboFunctions.OriginalHook(CreatureMotif) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.LocalPlayer.CastActionId == + CustomComboFunctions.OriginalHook(CreatureMotif) && OpenerStep == adjustedStep) OpenerStep++; else if (OpenerStep == adjustedStep) actionID = CustomComboFunctions.OriginalHook(CreatureMotif); adjustedStep++; @@ -407,7 +408,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = SubtractivePalette; adjustedStep++; @@ -422,7 +424,8 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; @@ -460,12 +463,14 @@ private bool DoOpener(ref uint actionID) if (CustomComboFunctions.WasLastAction(RainbowDrip) && OpenerStep == adjustedStep) OpenerStep++; else if (OpenerStep == adjustedStep) actionID = RainbowDrip; - Svc.Log.Debug($"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); + Svc.Log.Debug( + $"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); if (ActionWatching.TimeSinceLastAction.TotalSeconds > 3) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to timeout."); + return false; } @@ -473,15 +478,16 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.OpenerFinished; Svc.Log.Information("Opener completed successfully."); + return false; } return true; } + return false; } - private void ResetOpener() { PrePullStep = 0; @@ -498,80 +504,47 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } + #endregion #region Lvl 90 Opener + internal class PCTOpenerLogicLvl90 : PCT { - private static bool HasCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) - return false; - - if (!CustomComboFunctions.ActionReady(ScenicMuse)) - return false; - - if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) - return false; + private OpenerState currentState = OpenerState.PrePull; - return true; - } + public uint OpenerStep; - private static bool HasMotifs() - { - var gauge = CustomComboFunctions.GetJobGauge(); - - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Pom)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Weapon)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Landscape)) - return false; - if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) - return false; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 90; - public uint PrePullStep = 0; - - public uint OpenerStep = 0; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; - public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -586,24 +559,52 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (CustomComboFunctions.GetRemainingCharges(SteelMuse) < 2) + return false; + + if (!CustomComboFunctions.ActionReady(ScenicMuse)) + return false; + + if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) + return false; + + return true; + } + + private static bool HasMotifs() + { + PCTGauge gauge = CustomComboFunctions.GetJobGauge(); + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Pom)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape)) + return false; + + if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns() && !HasMotifs()) - { - PrePullStep = 0; - } + if (!HasCooldowns() && !HasMotifs()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) + CurrentState = OpenerState.InOpener; else if (PrePullStep == 1) actionID = FireInRed; if (!HasMotifs()) @@ -612,6 +613,7 @@ private bool DoPrePullSteps(ref uint actionID) return true; } PrePullStep = 0; + return false; } @@ -626,10 +628,12 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to not being in combat."); + return false; } - bool isEarlyOpenerEnabled = CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); + bool isEarlyOpenerEnabled = + CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); if (CustomComboFunctions.WasLastAction(StrikingMuse) && OpenerStep == 1) OpenerStep++; else if (OpenerStep == 1) actionID = StrikingMuse; @@ -682,58 +686,69 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = SubtractivePalette; adjustedStep++; if (!isEarlyOpenerEnabled) { - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(CometinBlack) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(CometinBlack) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = CometinBlack; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; adjustedStep++; - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; } else { - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; adjustedStep++; - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(CometinBlack) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(CometinBlack) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = CometinBlack; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; } - Svc.Log.Debug($"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); + Svc.Log.Debug( + $"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); if (ActionWatching.TimeSinceLastAction.TotalSeconds > 3) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to timeout."); + return false; } @@ -741,15 +756,16 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.OpenerFinished; Svc.Log.Information("Opener completed successfully."); + return false; } return true; } + return false; } - private void ResetOpener() { PrePullStep = 0; @@ -766,80 +782,47 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } + #endregion #region Lvl 80 Opener + internal class PCTOpenerLogicLvl80 : PCT { - private static bool HasCooldowns() - { - if (!CustomComboFunctions.ActionReady(SteelMuse)) - return false; - - if (!CustomComboFunctions.ActionReady(ScenicMuse)) - return false; + private OpenerState currentState = OpenerState.PrePull; - if (!CustomComboFunctions.ActionReady(LivingMuse)) - return false; + public uint OpenerStep; - return true; - } - - private static bool HasMotifs() - { - var gauge = CustomComboFunctions.GetJobGauge(); - - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Pom)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Weapon)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Landscape)) - return false; - if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) - return false; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 80; - public uint PrePullStep = 0; - - public uint OpenerStep = 0; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; - public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -854,24 +837,52 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (!CustomComboFunctions.ActionReady(SteelMuse)) + return false; + + if (!CustomComboFunctions.ActionReady(ScenicMuse)) + return false; + + if (!CustomComboFunctions.ActionReady(LivingMuse)) + return false; + + return true; + } + + private static bool HasMotifs() + { + PCTGauge gauge = CustomComboFunctions.GetJobGauge(); + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Pom)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape)) + return false; + + if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns() && !HasMotifs()) - { - PrePullStep = 0; - } + if (!HasCooldowns() && !HasMotifs()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) + CurrentState = OpenerState.InOpener; else if (PrePullStep == 1) actionID = FireInRed; if (!HasMotifs()) @@ -880,6 +891,7 @@ private bool DoPrePullSteps(ref uint actionID) return true; } PrePullStep = 0; + return false; } @@ -890,7 +902,8 @@ private bool DoOpener(ref uint actionID) if (currentState == OpenerState.InOpener && CustomComboFunctions.InCombat()) { - bool isEarlyOpenerEnabled = CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); + bool isEarlyOpenerEnabled = + CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); if (CustomComboFunctions.WasLastAction(StrikingMuse) && OpenerStep == 1) OpenerStep++; else if (OpenerStep == 1) actionID = StrikingMuse; @@ -927,20 +940,18 @@ private bool DoOpener(ref uint actionID) else if (OpenerStep == adjustedStep) actionID = WingedMuse; adjustedStep++; - if ((CustomComboFunctions.WasLastAction(HammerStamp) || CustomComboFunctions.WasLastAction(HammerBrush)) && OpenerStep == adjustedStep) + + if ((CustomComboFunctions.WasLastAction(HammerStamp) || + CustomComboFunctions.WasLastAction(HammerBrush)) && OpenerStep == adjustedStep) { OpenerStep++; } else if (OpenerStep == adjustedStep) { if (HammerBrush.LevelChecked()) - { actionID = HammerBrush; - } else - { actionID = HammerStamp; - } } adjustedStep++; @@ -949,67 +960,73 @@ private bool DoOpener(ref uint actionID) else if (OpenerStep == adjustedStep) actionID = MogoftheAges; adjustedStep++; - if ((CustomComboFunctions.WasLastAction(HammerStamp) || CustomComboFunctions.WasLastAction(PolishingHammer)) && OpenerStep == adjustedStep) + + if ((CustomComboFunctions.WasLastAction(HammerStamp) || + CustomComboFunctions.WasLastAction(PolishingHammer)) && OpenerStep == adjustedStep) { OpenerStep++; } else if (OpenerStep == adjustedStep) { if (PolishingHammer.LevelChecked()) - { actionID = PolishingHammer; - } else - { actionID = HammerStamp; - } } adjustedStep++; - if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = SubtractivePalette; adjustedStep++; if (!isEarlyOpenerEnabled) { - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; adjustedStep++; - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; } else { - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; adjustedStep++; - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; } - - Svc.Log.Debug($"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); + Svc.Log.Debug( + $"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); if (ActionWatching.TimeSinceLastAction.TotalSeconds > 4) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to timeout."); + return false; } @@ -1017,15 +1034,16 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.OpenerFinished; Svc.Log.Information("Opener completed successfully."); + return false; } return true; } + return false; } - private void ResetOpener() { PrePullStep = 0; @@ -1042,78 +1060,47 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } + #endregion #region Lvl 70 Opener + internal class PCTOpenerLogicLvl70 : PCT { - private static bool HasCooldowns() - { - if (!CustomComboFunctions.ActionReady(SteelMuse)) - return false; + private OpenerState currentState = OpenerState.PrePull; - if (!CustomComboFunctions.ActionReady(ScenicMuse)) - return false; + public uint OpenerStep; - if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) - return false; - - return true; - } - - private static bool HasMotifs() - { - var gauge = CustomComboFunctions.GetJobGauge(); - - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Pom)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Weapon)) - return false; - if (!gauge.CanvasFlags.HasFlag(Dalamud.Game.ClientState.JobGauge.Enums.CanvasFlags.Landscape)) - return false; - if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) - return false; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 70; - public uint PrePullStep = 0; - - public uint OpenerStep = 0; public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; - private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; + private static bool CanOpener => HasCooldowns() && HasMotifs() && LevelChecked; public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -1128,24 +1115,52 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (!CustomComboFunctions.ActionReady(SteelMuse)) + return false; + + if (!CustomComboFunctions.ActionReady(ScenicMuse)) + return false; + + if (CustomComboFunctions.GetRemainingCharges(LivingMuse) < 2) + return false; + + return true; + } + + private static bool HasMotifs() + { + PCTGauge gauge = CustomComboFunctions.GetJobGauge(); + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Pom)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon)) + return false; + + if (!gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape)) + return false; + + if (CustomComboFunctions.HasEffect(Buffs.SubtractivePalette)) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns() && !HasMotifs()) - { - PrePullStep = 0; - } + if (!HasCooldowns() && !HasMotifs()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + if (CustomComboFunctions.WasLastAction(FireInRed) && PrePullStep == 1) + CurrentState = OpenerState.InOpener; else if (PrePullStep == 1) actionID = FireInRed; if (!HasMotifs()) @@ -1154,6 +1169,7 @@ private bool DoPrePullSteps(ref uint actionID) return true; } PrePullStep = 0; + return false; } @@ -1164,7 +1180,8 @@ private bool DoOpener(ref uint actionID) if (currentState == OpenerState.InOpener) { - bool isEarlyOpenerEnabled = CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); + bool isEarlyOpenerEnabled = + CustomComboFunctions.IsEnabled(CustomComboPreset.PCT_ST_Advanced_Openers_EarlyOpener); if (CustomComboFunctions.WasLastAction(StrikingMuse) && OpenerStep == 1) OpenerStep++; else if (OpenerStep == 1) actionID = StrikingMuse; @@ -1217,48 +1234,57 @@ private bool DoOpener(ref uint actionID) adjustedStep++; - if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(SubtractivePalette) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = SubtractivePalette; adjustedStep++; if (!isEarlyOpenerEnabled) { - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; adjustedStep++; - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; } else { - if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(StoneinYellow) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = StoneinYellow; adjustedStep++; - if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) OpenerStep++; + if (CustomComboFunctions.WasLastAction(ThunderinMagenta) && OpenerStep == adjustedStep) + OpenerStep++; else if (OpenerStep == adjustedStep) actionID = ThunderinMagenta; adjustedStep++; - if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(BlizzardinCyan) && OpenerStep == adjustedStep) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == adjustedStep) actionID = BlizzardinCyan; } - Svc.Log.Debug($"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); + Svc.Log.Debug( + $"TimeSinceLastAction: {ActionWatching.TimeSinceLastAction.TotalSeconds}, OpenerStep: {OpenerStep}"); if (ActionWatching.TimeSinceLastAction.TotalSeconds > 4) { CurrentState = OpenerState.FailedOpener; Svc.Log.Warning("Opener Failed due to timeout."); + return false; } @@ -1266,15 +1292,16 @@ private bool DoOpener(ref uint actionID) { CurrentState = OpenerState.OpenerFinished; Svc.Log.Information("Opener completed successfully."); + return false; } return true; } + return false; } - private void ResetOpener() { PrePullStep = 0; @@ -1291,18 +1318,18 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } + #endregion -} +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/PLD.cs b/XIVSlothCombo/Combos/PvE/PLD/PLD.cs similarity index 96% rename from XIVSlothCombo/Combos/PvE/PLD.cs rename to XIVSlothCombo/Combos/PvE/PLD/PLD.cs index 78ecd9f70..97af981f1 100644 --- a/XIVSlothCombo/Combos/PvE/PLD.cs +++ b/XIVSlothCombo/Combos/PvE/PLD/PLD.cs @@ -9,7 +9,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class PLD + internal partial class PLD { public const byte ClassID = 1; public const byte JobID = 19; @@ -69,26 +69,7 @@ public const ushort } private static PLDGauge Gauge => CustomComboFunctions.GetJobGauge(); - - public static class Config - { - public static UserInt - PLD_ST_FoF_Trigger = new("PLD_ST_FoF_Trigger", 0), - PLD_AoE_FoF_Trigger = new("PLD_AoE_FoF_Trigger", 0), - PLD_ST_SheltronOption = new("PLD_ST_SheltronOption", 50), - PLD_AoE_SheltronOption = new("PLD_AoE_SheltronOption", 50), - PLD_Intervene_HoldCharges = new("PLD_Intervene_HoldCharges", 1), - PLD_AoE_Intervene_HoldCharges = new("PLD_AoE_Intervene_HoldCharges", 1), - PLD_Intervene_MeleeOnly = new("PLD_Intervene_MeleeOnly", 1), - PLD_AoE_Intervene_MeleeOnly = new("PLD_AoE_Intervene_MeleeOnly", 1), - PLD_ST_MP_Reserve = new("PLD_ST_MP_Reserve", 1000), - PLD_AoE_MP_Reserve = new("PLD_AoE_MP_Reserve", 1000), - PLD_ShieldLob_SubOption = new("PLD_ShieldLob_SubOption", 1), - PLD_RequiescatOption = new("PLD_RequiescatOption"), - PLD_SpiritsWithinOption = new("PLD_SpiritsWithinOption"), - PLD_VariantCure = new("PLD_VariantCure"); - } - + internal class PLD_ST_SimpleMode : CustomCombo { protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.PLD_ST_SimpleMode; diff --git a/XIVSlothCombo/Combos/PvE/PLD/PLD_Config.cs b/XIVSlothCombo/Combos/PvE/PLD/PLD_Config.cs new file mode 100644 index 000000000..ab0243dab --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/PLD/PLD_Config.cs @@ -0,0 +1,121 @@ +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class PLD +{ + internal static class Config + { + public static UserInt + PLD_ST_FoF_Trigger = new("PLD_ST_FoF_Trigger", 0), + PLD_AoE_FoF_Trigger = new("PLD_AoE_FoF_Trigger", 0), + PLD_ST_SheltronOption = new("PLD_ST_SheltronOption", 50), + PLD_AoE_SheltronOption = new("PLD_AoE_SheltronOption", 50), + PLD_Intervene_HoldCharges = new("PLD_Intervene_HoldCharges", 1), + PLD_AoE_Intervene_HoldCharges = new("PLD_AoE_Intervene_HoldCharges", 1), + PLD_Intervene_MeleeOnly = new("PLD_Intervene_MeleeOnly", 1), + PLD_AoE_Intervene_MeleeOnly = new("PLD_AoE_Intervene_MeleeOnly", 1), + PLD_ST_MP_Reserve = new("PLD_ST_MP_Reserve", 1000), + PLD_AoE_MP_Reserve = new("PLD_AoE_MP_Reserve", 1000), + PLD_ShieldLob_SubOption = new("PLD_ShieldLob_SubOption", 1), + PLD_RequiescatOption = new("PLD_RequiescatOption"), + PLD_SpiritsWithinOption = new("PLD_SpiritsWithinOption"), + PLD_VariantCure = new("PLD_VariantCure"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + // Fight or Flight + case CustomComboPreset.PLD_ST_AdvancedMode_FoF: + UserConfig.DrawSliderInt(0, 50, PLD_ST_FoF_Trigger, "Target HP%", 200); + + break; + + case CustomComboPreset.PLD_AoE_AdvancedMode_FoF: + UserConfig.DrawSliderInt(0, 50, PLD_AoE_FoF_Trigger, "Target HP%", 200); + + break; + + // Sheltron + case CustomComboPreset.PLD_ST_AdvancedMode_Sheltron: + UserConfig.DrawSliderInt(50, 100, PLD_ST_SheltronOption, "Oath Gauge", 200, 5); + + break; + + case CustomComboPreset.PLD_AoE_AdvancedMode_Sheltron: + UserConfig.DrawSliderInt(50, 100, PLD_AoE_SheltronOption, "Oath Gauge", 200, 5); + + break; + + // Intervene + case CustomComboPreset.PLD_ST_AdvancedMode_Intervene: + UserConfig.DrawSliderInt(0, 1, PLD_Intervene_HoldCharges, "Charges", 200); + + UserConfig.DrawHorizontalRadioButton(PLD_Intervene_MeleeOnly, "Melee Range", + "Uses Intervene while within melee range.\nMay result in minor movement.", 1); + + UserConfig.DrawHorizontalRadioButton(PLD_Intervene_MeleeOnly, "No Movement", + "Only uses Intervene when it would not result in movement (zero distance).", 2); + + break; + + case CustomComboPreset.PLD_AoE_AdvancedMode_Intervene: + UserConfig.DrawSliderInt(0, 1, PLD_AoE_Intervene_HoldCharges, "Charges", 200); + + UserConfig.DrawHorizontalRadioButton(PLD_AoE_Intervene_MeleeOnly, "Melee Range", + "Uses Intervene while within melee range.\nMay result in minor movement.", 1); + + UserConfig.DrawHorizontalRadioButton(PLD_AoE_Intervene_MeleeOnly, "No Movement", + "Only uses Intervene when it would not result in movement (zero distance).", 2); + + break; + + // Shield Lob + case CustomComboPreset.PLD_ST_AdvancedMode_ShieldLob: + UserConfig.DrawHorizontalRadioButton(PLD_ShieldLob_SubOption, "Shield Lob Only", + "Uses only Shield Lob.", 1); + + UserConfig.DrawHorizontalRadioButton(PLD_ShieldLob_SubOption, "Hardcast Holy Spirit", + "Attempts to hardcast Holy Spirit when not moving.\nOtherwise uses Shield Lob.", 2); + + break; + + // MP Reservation + case CustomComboPreset.PLD_ST_AdvancedMode_MP_Reserve: + UserConfig.DrawSliderInt(1000, 5000, PLD_ST_MP_Reserve, "Minimum MP", sliderIncrement: 100); + + break; + + case CustomComboPreset.PLD_AoE_AdvancedMode_MP_Reserve: + UserConfig.DrawSliderInt(1000, 5000, PLD_AoE_MP_Reserve, "Minimum MP", sliderIncrement: 100); + + break; + + // Requiescat Spender Feature + case CustomComboPreset.PLD_Requiescat_Options: + UserConfig.DrawRadioButton(PLD_RequiescatOption, "Confiteor", "", 1); + UserConfig.DrawRadioButton(PLD_RequiescatOption, "Blade of Faith/Truth/Valor", "", 2); + UserConfig.DrawRadioButton(PLD_RequiescatOption, "Confiteor & Blade of Faith/Truth/Valor", "", 3); + UserConfig.DrawRadioButton(PLD_RequiescatOption, "Holy Spirit", "", 4); + UserConfig.DrawRadioButton(PLD_RequiescatOption, "Holy Circle", "", 5); + + break; + + // Spirits Within / Circle of Scorn Feature + case CustomComboPreset.PLD_SpiritsWithin: + UserConfig.DrawRadioButton(PLD_SpiritsWithinOption, "Prioritize Circle of Scorn", "", 1); + UserConfig.DrawRadioButton(PLD_SpiritsWithinOption, "Prioritize Spirits Within / Expiacion", "", 2); + + break; + + // Variant Cure Feature + case CustomComboPreset.PLD_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, PLD_VariantCure, "Player HP%", 200); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/RDM/RDM.cs b/XIVSlothCombo/Combos/PvE/RDM/RDM.cs index f78baa77d..26c30411e 100644 --- a/XIVSlothCombo/Combos/PvE/RDM/RDM.cs +++ b/XIVSlothCombo/Combos/PvE/RDM/RDM.cs @@ -3,7 +3,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static partial class RDM + internal partial class RDM { //7.0 Note //Gauge information is available via RDMMana diff --git a/XIVSlothCombo/Combos/PvE/RDM/RDM_Config.cs b/XIVSlothCombo/Combos/PvE/RDM/RDM_Config.cs index fb8666352..f4d48b232 100644 --- a/XIVSlothCombo/Combos/PvE/RDM/RDM_Config.cs +++ b/XIVSlothCombo/Combos/PvE/RDM/RDM_Config.cs @@ -7,7 +7,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static partial class RDM + internal partial class RDM { internal static class Config { diff --git a/XIVSlothCombo/Combos/PvE/RDM/RDM_Helper.cs b/XIVSlothCombo/Combos/PvE/RDM/RDM_Helper.cs index 67f14d646..3855a4000 100644 --- a/XIVSlothCombo/Combos/PvE/RDM/RDM_Helper.cs +++ b/XIVSlothCombo/Combos/PvE/RDM/RDM_Helper.cs @@ -9,7 +9,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static partial class RDM + internal partial class RDM { private class RDMMana { diff --git a/XIVSlothCombo/Combos/PvE/SAM.cs b/XIVSlothCombo/Combos/PvE/SAM/SAM.cs similarity index 96% rename from XIVSlothCombo/Combos/PvE/SAM.cs rename to XIVSlothCombo/Combos/PvE/SAM/SAM.cs index 2e457cab6..5953d267e 100644 --- a/XIVSlothCombo/Combos/PvE/SAM.cs +++ b/XIVSlothCombo/Combos/PvE/SAM/SAM.cs @@ -11,7 +11,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal class SAM + internal partial class SAM { public const byte JobID = 34; @@ -91,33 +91,7 @@ public const ushort EnhancedMeikyoShishui2 = 593; } - public static class Config - { - public static UserInt - SAM_STSecondWindThreshold = new("SAM_STSecondWindThreshold", 25), - SAM_STBloodbathThreshold = new("SAM_STBloodbathThreshold", 40), - SAM_AoESecondWindThreshold = new("SAM_AoESecondWindThreshold", 25), - SAM_AoEBloodbathThreshold = new("SAM_AoEBloodbathThreshold", 40), - SAM_Kasha_KenkiOvercapAmount = new(nameof(SAM_Kasha_KenkiOvercapAmount), 50), - SAM_Yukaze_KenkiOvercapAmount = new(nameof(SAM_Yukaze_KenkiOvercapAmount), 50), - SAM_Gekko_KenkiOvercapAmount = new(nameof(SAM_Gekko_KenkiOvercapAmount), 50), - SAM_Oka_KenkiOvercapAmount = new(nameof(SAM_Oka_KenkiOvercapAmount), 50), - SAM_Mangetsu_KenkiOvercapAmount = new(nameof(SAM_Mangetsu_KenkiOvercapAmount), 50), - SAM_ST_KenkiOvercapAmount = new(nameof(SAM_ST_KenkiOvercapAmount), 50), - SAM_AoE_KenkiOvercapAmount = new(nameof(SAM_AoE_KenkiOvercapAmount), 50), - SAM_VariantCure = new("SAM_VariantCure"); - - public static UserFloat - SAM_ST_Higanbana_Threshold = new("SAM_ST_Higanbana_Threshold", 1), - SAM_ST_ExecuteThreshold = new("SAM_ST_ExecuteThreshold", 1); - - public static UserBool - SAM_Kasha_KenkiOvercap = new(nameof(SAM_Kasha_KenkiOvercap)), - SAM_Yukaze_KenkiOvercap = new(nameof(SAM_Yukaze_KenkiOvercap)), - SAM_Gekko_KenkiOvercap = new(nameof(SAM_Gekko_KenkiOvercap)), - SAM_Oka_KenkiOvercap = new(nameof(SAM_Oka_KenkiOvercap)), - SAM_Mangetsu_KenkiOvercap = new(nameof(SAM_Mangetsu_KenkiOvercap)); - } + internal class SAM_ST_YukikazeCombo : CustomCombo { protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.SAM_ST_YukikazeCombo; diff --git a/XIVSlothCombo/Combos/PvE/SAM/SAM_Config.cs b/XIVSlothCombo/Combos/PvE/SAM/SAM_Config.cs new file mode 100644 index 000000000..7d4b9e0e3 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/SAM/SAM_Config.cs @@ -0,0 +1,157 @@ +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class SAM +{ + internal static class Config + { + public static UserInt + SAM_STSecondWindThreshold = new("SAM_STSecondWindThreshold", 25), + SAM_STBloodbathThreshold = new("SAM_STBloodbathThreshold", 40), + SAM_AoESecondWindThreshold = new("SAM_AoESecondWindThreshold", 25), + SAM_AoEBloodbathThreshold = new("SAM_AoEBloodbathThreshold", 40), + SAM_Kasha_KenkiOvercapAmount = new(nameof(SAM_Kasha_KenkiOvercapAmount), 50), + SAM_Yukaze_KenkiOvercapAmount = new(nameof(SAM_Yukaze_KenkiOvercapAmount), 50), + SAM_Gekko_KenkiOvercapAmount = new(nameof(SAM_Gekko_KenkiOvercapAmount), 50), + SAM_Oka_KenkiOvercapAmount = new(nameof(SAM_Oka_KenkiOvercapAmount), 50), + SAM_Mangetsu_KenkiOvercapAmount = new(nameof(SAM_Mangetsu_KenkiOvercapAmount), 50), + SAM_ST_KenkiOvercapAmount = new(nameof(SAM_ST_KenkiOvercapAmount), 50), + SAM_AoE_KenkiOvercapAmount = new(nameof(SAM_AoE_KenkiOvercapAmount), 50), + SAM_VariantCure = new("SAM_VariantCure"); + + public static UserFloat + SAM_ST_Higanbana_Threshold = new("SAM_ST_Higanbana_Threshold", 1), + SAM_ST_ExecuteThreshold = new("SAM_ST_ExecuteThreshold", 1); + + public static UserBool + SAM_Kasha_KenkiOvercap = new(nameof(SAM_Kasha_KenkiOvercap)), + SAM_Yukaze_KenkiOvercap = new(nameof(SAM_Yukaze_KenkiOvercap)), + SAM_Gekko_KenkiOvercap = new(nameof(SAM_Gekko_KenkiOvercap)), + SAM_Oka_KenkiOvercap = new(nameof(SAM_Oka_KenkiOvercap)), + SAM_Mangetsu_KenkiOvercap = new(nameof(SAM_Mangetsu_KenkiOvercap)); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.SAM_ST_CDs_Iaijutsu: + UserConfig.DrawSliderInt(0, 100, SAM_ST_Higanbana_Threshold, + "Stop using Higanbana on targets below this HP % (0% = always use)."); + + break; + + case CustomComboPreset.SAM_ST_ComboHeals: + UserConfig.DrawSliderInt(0, 100, SAM_STSecondWindThreshold, + "HP percent threshold to use Second Wind below (0 = Disabled)"); + + UserConfig.DrawSliderInt(0, 100, SAM_STBloodbathThreshold, + "HP percent threshold to use Bloodbath (0 = Disabled)"); + + break; + + case CustomComboPreset.SAM_AoE_ComboHeals: + UserConfig.DrawSliderInt(0, 100, SAM_AoESecondWindThreshold, + "HP percent threshold to use Second Wind below (0 = Disabled)"); + + UserConfig.DrawSliderInt(0, 100, SAM_AoEBloodbathThreshold, + "HP percent threshold to use Bloodbath below (0 = Disabled)"); + + break; + + case CustomComboPreset.SAM_ST_Shinten: + UserConfig.DrawSliderInt(50, 85, SAM_ST_KenkiOvercapAmount, + "Set the Kenki overcap amount for ST combos."); + UserConfig.DrawSliderInt(0, 100, SAM_ST_ExecuteThreshold, "HP percent threshold to not save Kenki"); + + break; + + case CustomComboPreset.SAM_AoE_Kyuten: + UserConfig.DrawSliderInt(50, 85, SAM_AoE_KenkiOvercapAmount, + "Set the Kenki overcap amount for AOE combos."); + + break; + + case CustomComboPreset.SAM_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, SAM_VariantCure, "HP% to be at or under", 200); + + break; + + //PvP + case CustomComboPreset.SAMPvP_BurstMode: + UserConfig.DrawSliderInt(0, 2, SAMPvP.Config.SAMPvP_SotenCharges, + "How many charges of Soten to keep ready? (0 = Use All)."); + + break; + + case CustomComboPreset.SAMPvP_KashaFeatures_GapCloser: + UserConfig.DrawSliderInt(0, 100, SAMPvP.Config.SAMPvP_SotenHP, + "Use Soten on enemies below selected HP."); + + break; + + case CustomComboPreset.SAM_ST_KashaCombo: + { + UserConfig.DrawAdditionalBoolChoice(SAM_Kasha_KenkiOvercap, "Kenki Overcap Protection", + "Spends Kenki when at the set value or above."); + + if (SAM_Kasha_KenkiOvercap) + UserConfig.DrawSliderInt(25, 100, SAM_Kasha_KenkiOvercapAmount, "Kenki Amount", + sliderIncrement: SliderIncrements.Fives); + + break; + } + + case CustomComboPreset.SAM_ST_YukikazeCombo: + { + UserConfig.DrawAdditionalBoolChoice(SAM_Yukaze_KenkiOvercap, "Kenki Overcap Protection", + "Spends Kenki when at the set value or above."); + + if (SAM_Yukaze_KenkiOvercap) + UserConfig.DrawSliderInt(25, 100, SAM_Yukaze_KenkiOvercapAmount, "Kenki Amount", + sliderIncrement: SliderIncrements.Fives); + + break; + } + + case CustomComboPreset.SAM_ST_GekkoCombo: + { + UserConfig.DrawAdditionalBoolChoice(SAM_Gekko_KenkiOvercap, "Kenki Overcap Protection", + "Spends Kenki when at the set value or above."); + + if (SAM_Gekko_KenkiOvercap) + UserConfig.DrawSliderInt(25, 100, SAM_Gekko_KenkiOvercapAmount, "Kenki Amount", + sliderIncrement: SliderIncrements.Fives); + + break; + } + + case CustomComboPreset.SAM_AoE_OkaCombo: + { + UserConfig.DrawAdditionalBoolChoice(SAM_Oka_KenkiOvercap, "Kenki Overcap Protection", + "Spends Kenki when at the set value or above."); + + if (SAM_Oka_KenkiOvercap) + UserConfig.DrawSliderInt(25, 100, SAM_Oka_KenkiOvercapAmount, "Kenki Amount", + sliderIncrement: SliderIncrements.Fives); + + break; + } + + case CustomComboPreset.SAM_AoE_MangetsuCombo: + { + UserConfig.DrawAdditionalBoolChoice(SAM_Mangetsu_KenkiOvercap, "Kenki Overcap Protection", + "Spends Kenki when at the set value or above."); + + if (SAM_Mangetsu_KenkiOvercap) + UserConfig.DrawSliderInt(25, 100, SAM_Mangetsu_KenkiOvercapAmount, "Kenki Amount", + sliderIncrement: SliderIncrements.Fives); + + break; + } + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/JobHelpers/SAM.cs b/XIVSlothCombo/Combos/PvE/SAM/SAM_Helper.cs similarity index 80% rename from XIVSlothCombo/Combos/JobHelpers/SAM.cs rename to XIVSlothCombo/Combos/PvE/SAM/SAM_Helper.cs index 4ebe67090..7088b880d 100644 --- a/XIVSlothCombo/Combos/JobHelpers/SAM.cs +++ b/XIVSlothCombo/Combos/PvE/SAM/SAM_Helper.cs @@ -2,87 +2,61 @@ using ECommons.DalamudServices; using FFXIVClientStructs.FFXIV.Client.Game; using XIVSlothCombo.Combos.JobHelpers.Enums; -using XIVSlothCombo.Combos.PvE; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; -namespace XIVSlothCombo.Combos.JobHelpers +namespace XIVSlothCombo.Combos.PvE; + +internal partial class SAM { - internal class SAMHelper : SAM + internal static int SenCount => GetSenCount(); + + internal static bool ComboStarted => GetComboStarted(); + + private static int GetSenCount() { - internal static int SenCount => GetSenCount(); - private static int GetSenCount() - { - var gauge = CustomComboFunctions.GetJobGauge(); - var senCount = 0; - if (gauge.HasGetsu) senCount++; - if (gauge.HasSetsu) senCount++; - if (gauge.HasKa) senCount++; + SAMGauge gauge = CustomComboFunctions.GetJobGauge(); + int senCount = 0; + if (gauge.HasGetsu) senCount++; + if (gauge.HasSetsu) senCount++; + if (gauge.HasKa) senCount++; - return senCount; - } - internal static bool ComboStarted => GetComboStarted(); - private unsafe static bool GetComboStarted() - { - var comboAction = ActionManager.Instance()->Combo.Action; - if (comboAction == CustomComboFunctions.OriginalHook(Hakaze) || comboAction == CustomComboFunctions.OriginalHook(Jinpu) || comboAction == CustomComboFunctions.OriginalHook(Shifu)) - return true; - return false; - } + return senCount; } - - internal class SAMOpenerLogic : SAM + private static unsafe bool GetComboStarted() { - private static bool HasCooldowns() - { - if (!CustomComboFunctions.ActionReady(Senei)) - return false; + uint comboAction = ActionManager.Instance()->Combo.Action; - if (!CustomComboFunctions.ActionReady(Ikishoten)) - return false; - - return true; - } + return comboAction == CustomComboFunctions.OriginalHook(Hakaze) || + comboAction == CustomComboFunctions.OriginalHook(Jinpu) || + comboAction == CustomComboFunctions.OriginalHook(Shifu); + } - public static bool HasPrePullCooldowns() - { - if (CustomComboFunctions.GetRemainingCharges(MeikyoShisui) < 2) - return false; + internal class SAMOpenerLogic + { + private OpenerState currentState = OpenerState.PrePull; - if (CustomComboFunctions.GetRemainingCharges(All.TrueNorth) < 2) - return false; + public uint OpenerStep = 1; - return true; - } + public uint PrePullStep; private static uint OpenerLevel => 100; - public uint PrePullStep = 0; - - public uint OpenerStep = 1; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; private static bool CanOpener => HasCooldowns() && HasPrePullCooldowns() && LevelChecked; - private OpenerState currentState = OpenerState.PrePull; - public OpenerState CurrentState { - get - { - return currentState; - } + get => currentState; set { if (value != currentState) { - if (value == OpenerState.PrePull) - { - Svc.Log.Debug($"Entered PrePull Opener"); - } + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); if (value == OpenerState.InOpener) OpenerStep = 1; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) { if (value == OpenerState.FailedOpener) @@ -97,27 +71,44 @@ public OpenerState CurrentState } } + private static bool HasCooldowns() + { + if (!CustomComboFunctions.ActionReady(Senei)) + return false; + + if (!CustomComboFunctions.ActionReady(Ikishoten)) + return false; + + return true; + } + + public static bool HasPrePullCooldowns() + { + if (CustomComboFunctions.GetRemainingCharges(MeikyoShisui) < 2) + return false; + + if (CustomComboFunctions.GetRemainingCharges(All.TrueNorth) < 2) + return false; + + return true; + } + private bool DoPrePullSteps(ref uint actionID) { if (!LevelChecked) return false; - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - if (!HasCooldowns()) - { - PrePullStep = 0; - } + if (!HasCooldowns()) PrePullStep = 0; if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { if (CustomComboFunctions.HasEffect(Buffs.MeikyoShisui) && PrePullStep == 1) PrePullStep++; else if (PrePullStep == 1) actionID = MeikyoShisui; - if (CustomComboFunctions.HasEffect(All.Buffs.TrueNorth) && PrePullStep == 2) currentState = OpenerState.InOpener; + if (CustomComboFunctions.HasEffect(All.Buffs.TrueNorth) && PrePullStep == 2) + currentState = OpenerState.InOpener; else if (PrePullStep == 2) actionID = All.TrueNorth; if (ActionWatching.CombatActions.Count > 2 && CustomComboFunctions.InCombat()) @@ -127,6 +118,7 @@ private bool DoPrePullSteps(ref uint actionID) } PrePullStep = 0; + return false; } @@ -202,22 +194,26 @@ private bool DoOpener(ref uint actionID) if (CustomComboFunctions.WasLastAction(TendoSetsugekka) && OpenerStep == 22) OpenerStep++; else if (OpenerStep == 22) actionID = TendoSetsugekka; - if (CustomComboFunctions.WasLastAction(TendoKaeshiSetsugekka) && OpenerStep == 23) CurrentState = OpenerState.OpenerFinished; + if (CustomComboFunctions.WasLastAction(TendoKaeshiSetsugekka) && OpenerStep == 23) + CurrentState = OpenerState.OpenerFinished; else if (OpenerStep == 23) actionID = TendoKaeshiSetsugekka; - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) CurrentState = OpenerState.FailedOpener; if (((actionID == Senei && CustomComboFunctions.IsOnCooldown(Senei)) || - (actionID == Ikishoten && CustomComboFunctions.IsOnCooldown(Ikishoten)) || - (actionID == MeikyoShisui && CustomComboFunctions.GetRemainingCharges(MeikyoShisui) < 1)) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + (actionID == Ikishoten && CustomComboFunctions.IsOnCooldown(Ikishoten)) || + (actionID == MeikyoShisui && CustomComboFunctions.GetRemainingCharges(MeikyoShisui) < 1)) && + ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) { CurrentState = OpenerState.FailedOpener; + return false; } + return true; } + return false; } @@ -237,16 +233,15 @@ public bool DoFullOpener(ref uint actionID) return true; if (CurrentState == OpenerState.InOpener) - { if (DoOpener(ref actionID)) return true; - } if (!CustomComboFunctions.InCombat()) { ResetOpener(); CurrentState = OpenerState.PrePull; } + return false; } } diff --git a/XIVSlothCombo/Combos/PvE/SMN.cs b/XIVSlothCombo/Combos/PvE/SMN/SMN.cs similarity index 98% rename from XIVSlothCombo/Combos/PvE/SMN.cs rename to XIVSlothCombo/Combos/PvE/SMN/SMN.cs index 87d17cb37..564b2a24f 100644 --- a/XIVSlothCombo/Combos/PvE/SMN.cs +++ b/XIVSlothCombo/Combos/PvE/SMN/SMN.cs @@ -3,11 +3,10 @@ using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.Core; using XIVSlothCombo.CustomComboNS; -using XIVSlothCombo.CustomComboNS.Functions; namespace XIVSlothCombo.Combos.PvE { - internal class SMN + internal partial class SMN { public const byte ClassID = 26; public const byte JobID = 27; @@ -134,22 +133,7 @@ public const ushort RefulgentLux = 3874; } - public static class Config - { - public static string - SMN_Lucid = "SMN_Lucid", - SMN_BurstPhase = "SMN_BurstPhase", - SMN_PrimalChoice = "SMN_PrimalChoice", - SMN_SwiftcastPhase = "SMN_SwiftcastPhase", - SMN_Burst_Delay = "SMN_Burst_Delay", - SMN_VariantCure = "SMN_VariantCure"; - - public static UserBoolArray - SMN_ST_Egi_AstralFlow = new("SMN_ST_Egi_AstralFlow"); - - public static UserBool - SMN_ST_CrimsonCycloneMelee = new("SMN_ST_CrimsonCycloneMelee"); - } + internal class SMN_Raise : CustomCombo { diff --git a/XIVSlothCombo/Combos/PvE/SMN/SMN_Config.cs b/XIVSlothCombo/Combos/PvE/SMN/SMN_Config.cs new file mode 100644 index 000000000..53bbc97cd --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/SMN/SMN_Config.cs @@ -0,0 +1,104 @@ +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class SMN +{ + internal static class Config + { + public static UserInt + SMN_Lucid = new("SMN_Lucid"), + SMN_BurstPhase = new("SMN_BurstPhase"), + SMN_PrimalChoice = new("SMN_PrimalChoice"), + SMN_SwiftcastPhase = new("SMN_SwiftcastPhase"), + SMN_Burst_Delay = new("SMN_Burst_Delay"), + SMN_VariantCure = new("SMN_VariantCure"); + + public static UserBoolArray + SMN_ST_Egi_AstralFlow = new("SMN_ST_Egi_AstralFlow"); + + public static UserBool + SMN_ST_CrimsonCycloneMelee = new("SMN_ST_CrimsonCycloneMelee"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.SMN_DemiEgiMenu_EgiOrder: + UserConfig.DrawHorizontalRadioButton(SMN_PrimalChoice, "Titan first", + "Summons Titan, Garuda then Ifrit.", 1); + + UserConfig.DrawHorizontalRadioButton(SMN_PrimalChoice, "Garuda first", + "Summons Garuda, Titan then Ifrit.", 2); + + break; + + case CustomComboPreset.SMN_DemiEgiMenu_oGCDPooling: + UserConfig.DrawSliderInt(0, 3, SMN_Burst_Delay, + "Sets the amount of GCDs under Demi summon to wait for oGCD use."); + + UserConfig.DrawHorizontalRadioButton(SMN_BurstPhase, "Solar Bahamut/Bahamut", + "Bursts during Bahamut phase.\nBahamut burst phase becomes Solar Bahamut at Lv100.", 1); + UserConfig.DrawHorizontalRadioButton(SMN_BurstPhase, "Phoenix", "Bursts during Phoenix phase.", 2); + + UserConfig.DrawHorizontalRadioButton(SMN_BurstPhase, "Any Demi Phase", + "Bursts during any Demi Summon phase.", 3); + + UserConfig.DrawHorizontalRadioButton(SMN_BurstPhase, "Flexible (SpS) Option", + "Bursts when Searing Light is ready, regardless of phase.", 4); + + break; + + case CustomComboPreset.SMN_DemiEgiMenu_SwiftcastEgi: + UserConfig.DrawHorizontalRadioButton(SMN_SwiftcastPhase, "Garuda", "Swiftcasts Slipstream", 1); + + UserConfig.DrawHorizontalRadioButton(SMN_SwiftcastPhase, "Ifrit", "Swiftcasts Ruby Ruin/Ruby Rite", + 2); + + UserConfig.DrawHorizontalRadioButton(SMN_SwiftcastPhase, "Flexible (SpS) Option", + "Swiftcasts the first available Egi when Swiftcast is ready.", 3); + + break; + + case CustomComboPreset.SMN_Lucid: + UserConfig.DrawSliderInt(4000, 9500, SMN_Lucid, + "Set value for your MP to be at or under for this feature to take effect.", 150, + SliderIncrements.Hundreds); + + break; + + case CustomComboPreset.SMN_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, SMN_VariantCure, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.SMN_ST_Egi_AstralFlow: + { + UserConfig.DrawHorizontalMultiChoice(SMN_ST_Egi_AstralFlow, "Add Mountain Buster", "", 3, 0); + UserConfig.DrawHorizontalMultiChoice(SMN_ST_Egi_AstralFlow, "Add Crimson Cyclone", "", 3, 1); + UserConfig.DrawHorizontalMultiChoice(SMN_ST_Egi_AstralFlow, "Add Slipstream", "", 3, 2); + + if (SMN_ST_Egi_AstralFlow[1]) + UserConfig.DrawAdditionalBoolChoice(SMN_ST_CrimsonCycloneMelee, + "Enforced Crimson Cyclone Melee Check", "Only uses Crimson Cyclone within melee range."); + + break; + } + + case CustomComboPreset.SMNPvP_BurstMode: + UserConfig.DrawSliderInt(50, 100, SMNPvP.Config.SMNPvP_FesterThreshold, + "Target HP% to cast Fester below.\nSet to 100 use Fester as soon as it's available."); + + break; + + case CustomComboPreset.SMNPvP_BurstMode_RadiantAegis: + UserConfig.DrawSliderInt(0, 90, SMNPvP.Config.SMNPvP_RadiantAegisThreshold, + "Caps at 90 to prevent waste."); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/WAR.cs b/XIVSlothCombo/Combos/PvE/WAR/WAR.cs similarity index 97% rename from XIVSlothCombo/Combos/PvE/WAR.cs rename to XIVSlothCombo/Combos/PvE/WAR/WAR.cs index 15631396c..c7c328c4a 100644 --- a/XIVSlothCombo/Combos/PvE/WAR.cs +++ b/XIVSlothCombo/Combos/PvE/WAR/WAR.cs @@ -6,7 +6,7 @@ namespace XIVSlothCombo.Combos.PvE { - internal static class WAR + internal partial class WAR { public const byte ClassID = 3; public const byte JobID = 21; @@ -56,19 +56,7 @@ public const ushort Placeholder = 1; } - public static class Config - { - public const string - WAR_InfuriateRange = "WarInfuriateRange", - WAR_SurgingRefreshRange = "WarSurgingRefreshRange", - WAR_KeepOnslaughtCharges = "WarKeepOnslaughtCharges", - WAR_KeepInfuriateCharges = "WarKeepInfuriateCharges", - WAR_VariantCure = "WAR_VariantCure", - WAR_FellCleaveGauge = "WAR_FellCleaveGauge", - WAR_DecimateGauge = "WAR_DecimateGauge", - WAR_InfuriateSTGauge = "WAR_InfuriateSTGauge", - WAR_InfuriateAoEGauge = "WAR_InfuriateAoEGauge"; - } + internal class WAR_ST_SimpleMode : CustomCombo { diff --git a/XIVSlothCombo/Combos/PvE/WAR/WAR_Config.cs b/XIVSlothCombo/Combos/PvE/WAR/WAR_Config.cs new file mode 100644 index 000000000..c1ca566d9 --- /dev/null +++ b/XIVSlothCombo/Combos/PvE/WAR/WAR_Config.cs @@ -0,0 +1,80 @@ +using XIVSlothCombo.Combos.PvP; +using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Window.Functions; + +namespace XIVSlothCombo.Combos.PvE; + +internal partial class WAR +{ + internal static class Config + { + public static UserInt + WAR_InfuriateRange = new("WarInfuriateRange"), + WAR_SurgingRefreshRange = new("WarSurgingRefreshRange"), + WAR_KeepOnslaughtCharges = new("WarKeepOnslaughtCharges"), + WAR_KeepInfuriateCharges = new("WarKeepInfuriateCharges"), + WAR_VariantCure = new("WAR_VariantCure"), + WAR_FellCleaveGauge = new("WAR_FellCleaveGauge"), + WAR_DecimateGauge = new("WAR_DecimateGauge"), + WAR_InfuriateSTGauge = new("WAR_InfuriateSTGauge"), + WAR_InfuriateAoEGauge = new("WAR_InfuriateAoEGauge"); + + internal static void Draw(CustomComboPreset preset) + { + switch (preset) + { + case CustomComboPreset.WAR_ST_Advanced_StormsEye: + UserConfig.DrawSliderInt(0, 30, WAR_SurgingRefreshRange, + "Seconds remaining before refreshing Surging Tempest."); + + break; + + case CustomComboPreset.WAR_InfuriateFellCleave: + UserConfig.DrawSliderInt(0, 50, WAR_InfuriateRange, + "Set how much rage to be at or under to use this feature."); + + break; + + case CustomComboPreset.WAR_ST_Advanced_Onslaught: + UserConfig.DrawSliderInt(0, 2, WAR_KeepOnslaughtCharges, + "How many charges to keep ready? (0 = Use All)"); + + break; + + case CustomComboPreset.WAR_ST_Advanced_Infuriate: + UserConfig.DrawSliderInt(0, 2, WAR_KeepInfuriateCharges, + "How many charges to keep ready? (0 = Use All)"); + + UserConfig.DrawSliderInt(0, 50, WAR_InfuriateSTGauge, "Use when gauge is under or equal to"); + + break; + + case CustomComboPreset.WAR_Variant_Cure: + UserConfig.DrawSliderInt(1, 100, WAR_VariantCure, "HP% to be at or under", 200); + + break; + + case CustomComboPreset.WAR_ST_Advanced_FellCleave: + UserConfig.DrawSliderInt(50, 100, WAR_FellCleaveGauge, "Minimum gauge to spend"); + + break; + + case CustomComboPreset.WAR_AoE_Advanced_Decimate: + UserConfig.DrawSliderInt(50, 100, WAR_DecimateGauge, "Minimum gauge to spend"); + + break; + + case CustomComboPreset.WAR_AoE_Advanced_Infuriate: + UserConfig.DrawSliderInt(0, 50, WAR_InfuriateAoEGauge, "Use when gauge is under or equal to"); + + break; + + case CustomComboPreset.WARPvP_BurstMode_Blota: + UserConfig.DrawHorizontalRadioButton(WARPvP.Config.WARPVP_BlotaTiming, "Before Primal Rend", "", 0); + UserConfig.DrawHorizontalRadioButton(WARPvP.Config.WARPVP_BlotaTiming, "After Primal Rend", "", 1); + + break; + } + } + } +} \ No newline at end of file diff --git a/XIVSlothCombo/CustomCombo/Functions/Party.cs b/XIVSlothCombo/CustomCombo/Functions/Party.cs index 383fa1ced..2eaf253ce 100644 --- a/XIVSlothCombo/CustomCombo/Functions/Party.cs +++ b/XIVSlothCombo/CustomCombo/Functions/Party.cs @@ -8,8 +8,14 @@ namespace XIVSlothCombo.CustomComboNS.Functions { internal abstract partial class CustomComboFunctions { - /// Checks if player is in a party - public static bool IsInParty() => (Svc.Party.PartyId > 0); + /// Checks if the player is in a party. Optionally, refine by minimum party size. + /// The minimum amount of party members required. + public static bool IsInParty(int? partySize = null) + { + if (Svc.Party.PartyId > 0) return partySize == null || Svc.Party.Length >= partySize; + + else return false; + } /// Gets the party list /// Current party list. diff --git a/XIVSlothCombo/CustomCombo/Functions/PlayerCharacter.cs b/XIVSlothCombo/CustomCombo/Functions/PlayerCharacter.cs index b11fd5660..73db277f0 100644 --- a/XIVSlothCombo/CustomCombo/Functions/PlayerCharacter.cs +++ b/XIVSlothCombo/CustomCombo/Functions/PlayerCharacter.cs @@ -21,6 +21,10 @@ internal abstract partial class CustomComboFunctions /// A value indicating whether the player is in combat. public static bool InCombat() => Svc.Condition[ConditionFlag.InCombat]; + /// Find if the player is bound by duty. + /// A value indicating whether the player is bound by duty. + public static bool InDuty() => Svc.Condition[ConditionFlag.BoundByDuty] || Svc.Condition[ConditionFlag.BoundByDuty56] || Svc.Condition[ConditionFlag.BoundByDuty95]; + /// Find if the player has a pet present. /// A value indicating whether the player has a pet (fairy/carbuncle) present. public static bool HasPetPresent() => Svc.Buddies.PetBuddy != null; diff --git a/XIVSlothCombo/CustomCombo/Functions/Target.cs b/XIVSlothCombo/CustomCombo/Functions/Target.cs index 78b26c199..6c042565b 100644 --- a/XIVSlothCombo/CustomCombo/Functions/Target.cs +++ b/XIVSlothCombo/CustomCombo/Functions/Target.cs @@ -158,18 +158,28 @@ public static bool HasFriendlyTarget(IGameObject? OurTarget = null) return healTarget; } - /// Determines if the enemy can be interrupted if they are currently casting. + /// Determines if the enemy is casting an action. Optionally, limit by total cast time. + /// The minimum total cast time required, in seconds. + /// Bool indicating whether they are casting an action or not. + public static bool TargetIsCasting(float? minTotalCast = null) + { + if (CurrentTarget is null || CurrentTarget is not IBattleChara chara) return false; + + if (chara.IsCasting) return minTotalCast == null || chara.TotalCastTime >= minTotalCast; + + else return false; + } + + /// Determines if the enemy is casting an action that can be interrupted. Optionally, limit by current cast time. + /// The minimum current cast time required, in seconds. /// Bool indicating whether they can be interrupted or not. - public static bool CanInterruptEnemy() + public static bool CanInterruptEnemy(float? minCurrentCast = null) { - if (CurrentTarget is null) - return false; - if (CurrentTarget is not IBattleChara chara) - return false; - if (chara.IsCasting) - return chara.IsCastInterruptible; + if (CurrentTarget is null || CurrentTarget is not IBattleChara chara) return false; - return false; + if (chara.IsCasting && chara.IsCastInterruptible) return minCurrentCast == null || chara.CurrentCastTime >= minCurrentCast; + + else return false; } /// Sets the player's target. diff --git a/XIVSlothCombo/Data/ActionWatching.cs b/XIVSlothCombo/Data/ActionWatching.cs index 0082e24c9..aea184679 100644 --- a/XIVSlothCombo/Data/ActionWatching.cs +++ b/XIVSlothCombo/Data/ActionWatching.cs @@ -12,7 +12,6 @@ using XIVSlothCombo.Combos.PvE; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Services; -using static XIVSlothCombo.Combos.JobHelpers.NIN; namespace XIVSlothCombo.Data { @@ -116,9 +115,9 @@ private unsafe static void SendActionDetour(ulong targetObjectId, byte actionTyp private static void UpdateHelpers(uint actionId) { if (actionId is NIN.Ten or NIN.Chi or NIN.Jin or NIN.TenCombo or NIN.ChiCombo or NIN.JinCombo) - NINHelper.InMudra = true; + NIN.NINHelper.InMudra = true; else - NINHelper.InMudra = false; + NIN.NINHelper.InMudra = false; } private unsafe static void CheckForChangedTarget(uint actionId, ref ulong targetObjectId) diff --git a/XIVSlothCombo/Window/Functions/Presets.cs b/XIVSlothCombo/Window/Functions/Presets.cs index ae88b7cf6..d340b045b 100644 --- a/XIVSlothCombo/Window/Functions/Presets.cs +++ b/XIVSlothCombo/Window/Functions/Presets.cs @@ -269,29 +269,29 @@ internal unsafe static void DrawPreset(CustomComboPreset preset, CustomComboInfo { switch (info.JobID) { - //case All.JobID: All.Config.Draw(preset); break; + // case All.JobID: All.Config.Draw(preset); break; case AST.JobID: AST.Config.Draw(preset); break; - //case BLM.JobID: BLM.Config.Draw(preset); break; - //case BLU.JobID: BLU.Config.Draw(preset); break; - //case BRD.JobID: BRD.Config.Draw(preset); break; - //case DNC.JobID: DNC.Config.Draw(preset); break; - //case DOL.JobID: DOL.Config.Draw(preset); break; - //case DRG.JobID: DRG.Config.Draw(preset); break; - //case DRK.JobID: DRK.Config.Draw(preset); break; - //case GNB.JobID: GNB.Config.Draw(preset); break; - //case MCH.JobID: MCH.Config.Draw(preset); break; - //case MNK.JobID: MNK.Config.Draw(preset); break; - //case NIN.JobID: NIN.Config.Draw(preset); break; - //case PCT.JobID: PCT.Config.Draw(preset); break; - //case PLD.JobID: PLD.Config.Draw(preset); break; - //case RPR.JobID: RPR.Config.Draw(preset); break; + case BLM.JobID: BLM.Config.Draw(preset); break; + case BLU.JobID: BLU.Config.Draw(preset); break; + case BRD.JobID: BRD.Config.Draw(preset); break; + case DNC.JobID: DNC.Config.Draw(preset); break; + case DOL.JobID: DOL.Config.Draw(preset); break; + case DRG.JobID: DRG.Config.Draw(preset); break; + case DRK.JobID: DRK.Config.Draw(preset); break; + case GNB.JobID: GNB.Config.Draw(preset); break; + case MCH.JobID: MCH.Config.Draw(preset); break; + // case MNK.JobID: MNK.Config.Draw(preset); break; + case NIN.JobID: NIN.Config.Draw(preset); break; + case PCT.JobID: PCT.Config.Draw(preset); break; + case PLD.JobID: PLD.Config.Draw(preset); break; + case RPR.JobID: RPR.Config.Draw(preset); break; case RDM.JobID: RDM.Config.Draw(preset); break; - //case SAM.JobID: SAM.Config.Draw(preset); break; + case SAM.JobID: SAM.Config.Draw(preset); break; case SCH.JobID: SCH.Config.Draw(preset); break; case SGE.JobID: SGE.Config.Draw(preset); break; - //case SMN.JobID: SMN.Config.Draw(preset); break; - //case VPR.JobID: VPR.Config.Draw(preset); break; - //case WAR.JobID: WAR.Config.Draw(preset); break; + case SMN.JobID: SMN.Config.Draw(preset); break; + case VPR.JobID: VPR.Config.Draw(preset); break; + case WAR.JobID: WAR.Config.Draw(preset); break; case WHM.JobID: WHM.Config.Draw(preset); break; default: UserConfigItems.Draw(preset, enabled); break; } diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index d59842956..5ae5f8b16 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1189,582 +1189,31 @@ internal static void Draw(CustomComboPreset preset, bool enabled) if (!enabled) return; // ==================================================================================== - #region Misc - - #endregion // ==================================================================================== - #region ADV - - #endregion // ==================================================================================== - // ==================================================================================== - #region BLACK MAGE - - if (preset is CustomComboPreset.BLM_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, BLM.Config.BLM_VariantCure, "HP% to be at or under", 200); - - #endregion // ==================================================================================== - #region BLUE MAGE - - #endregion // ==================================================================================== - #region BARD - - if (preset == CustomComboPreset.BRD_Adv_RagingJaws) - UserConfig.DrawSliderInt(3, 10, BRD.Config.BRD_RagingJawsRenewTime, "Remaining time (In seconds). Recommended 5, increase little by little if refresh is outside of radiant window"); - - if (preset == CustomComboPreset.BRD_Adv_NoWaste) - UserConfig.DrawSliderInt(1, 10, BRD.Config.BRD_NoWasteHPPercentage, "Remaining target HP percentage"); - - if (preset == CustomComboPreset.BRD_AoE_Adv_NoWaste) - UserConfig.DrawSliderInt(1, 10, BRD.Config.BRD_AoENoWasteHPPercentage, "Remaining target HP percentage"); - - if (preset == CustomComboPreset.BRD_ST_SecondWind) - UserConfig.DrawSliderInt(0, 100, BRD.Config.BRD_STSecondWindThreshold, "HP percent threshold to use Second Wind below.", 150, SliderIncrements.Ones); - - if (preset == CustomComboPreset.BRD_AoE_SecondWind) - UserConfig.DrawSliderInt(0, 100, BRD.Config.BRD_AoESecondWindThreshold, "HP percent threshold to use Second Wind below.", 150, SliderIncrements.Ones); - - if (preset == CustomComboPreset.BRD_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, BRD.Config.BRD_VariantCure, "HP% to be at or under", 200); - - #endregion // ==================================================================================== - #region DANCER - - if (preset == CustomComboPreset.DNC_DanceComboReplacer) - { - //int[]? actions = Service.Configuration.DancerDanceCompatActionIDs.Cast().ToArray(); - int[]? actions = Service.Configuration.DancerDanceCompatActionIDs.Select(x => (int)x).ToArray(); - - - bool inputChanged = false; - - inputChanged |= ImGui.InputInt("Emboite (Red) ActionID", ref actions[0], 0); - inputChanged |= ImGui.InputInt("Entrechat (Blue) ActionID", ref actions[1], 0); - inputChanged |= ImGui.InputInt("Jete (Green) ActionID", ref actions[2], 0); - inputChanged |= ImGui.InputInt("Pirouette (Yellow) ActionID", ref actions[3], 0); - - if (inputChanged) - { - //Service.Configuration.DancerDanceCompatActionIDs = actions.Cast().ToArray(); - Service.Configuration.DancerDanceCompatActionIDs = actions.Select(x => (uint)x).ToArray(); - Service.Configuration.Save(); - } - - ImGui.Spacing(); - } - - if (preset == CustomComboPreset.DNC_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, DNC.Config.DNCVariantCurePercent, "HP% to be at or under", 200); - - #region Multi-Button Sliders - - if (preset == CustomComboPreset.DNC_ST_EspritOvercap) - UserConfig.DrawSliderInt(50, 100, DNC.Config.DNCEspritThreshold_ST, "Esprit", 150, SliderIncrements.Fives); - - if (preset == CustomComboPreset.DNC_AoE_EspritOvercap) - UserConfig.DrawSliderInt(50, 100, DNC.Config.DNCEspritThreshold_AoE, "Esprit", 150, SliderIncrements.Fives); - - #endregion - - #region Advanced ST Sliders - - if (preset == CustomComboPreset.DNC_ST_Adv_SS) - UserConfig.DrawSliderInt(0, 5, DNC.Config.DNC_ST_Adv_SSBurstPercent, "Target HP% to stop using Standard Step below", 75); - - if (preset == CustomComboPreset.DNC_ST_Adv_TS) - UserConfig.DrawSliderInt(0, 5, DNC.Config.DNC_ST_Adv_TSBurstPercent, "Target HP% to stop using Technical Step below", 75); - - if (preset == CustomComboPreset.DNC_ST_Adv_Feathers) - UserConfig.DrawSliderInt(0, 5, DNC.Config.DNC_ST_Adv_FeatherBurstPercent, "Target HP% to dump all pooled feathers below", 75); - - if (preset == CustomComboPreset.DNC_ST_Adv_SaberDance) - UserConfig.DrawSliderInt(50, 100, DNC.Config.DNC_ST_Adv_SaberThreshold, "Esprit", 150, SliderIncrements.Fives); - - if (preset == CustomComboPreset.DNC_ST_Adv_PanicHeals) - UserConfig.DrawSliderInt(0, 100, DNC.Config.DNC_ST_Adv_PanicHealWaltzPercent, "Curing Waltz HP%", 200); - - if (preset == CustomComboPreset.DNC_ST_Adv_PanicHeals) - UserConfig.DrawSliderInt(0, 100, DNC.Config.DNC_ST_Adv_PanicHealWindPercent, "Second Wind HP%", 200); - - #endregion - - #region Advanced AoE Sliders - - if (preset == CustomComboPreset.DNC_AoE_Adv_SS) - UserConfig.DrawSliderInt(0, 10, DNC.Config.DNC_AoE_Adv_SSBurstPercent, "Target HP% to stop using Standard Step below", 75); - - if (preset == CustomComboPreset.DNC_AoE_Adv_TS) - UserConfig.DrawSliderInt(0, 10, DNC.Config.DNC_AoE_Adv_TSBurstPercent, "Target HP% to stop using Technical Step below", 75); - - if (preset == CustomComboPreset.DNC_AoE_Adv_SaberDance) - UserConfig.DrawSliderInt(50, 100, DNC.Config.DNC_AoE_Adv_SaberThreshold, "Esprit", 150, SliderIncrements.Fives); - - if (preset == CustomComboPreset.DNC_AoE_Adv_PanicHeals) - UserConfig.DrawSliderInt(0, 100, DNC.Config.DNC_AoE_Adv_PanicHealWaltzPercent, "Curing Waltz HP%", 200); - - if (preset == CustomComboPreset.DNC_AoE_Adv_PanicHeals) - UserConfig.DrawSliderInt(0, 100, DNC.Config.DNC_AoE_Adv_PanicHealWindPercent, "Second Wind HP%", 200); - - #endregion - - #region PvP Sliders - - if (preset == CustomComboPreset.DNCPvP_BurstMode_CuringWaltz) - UserConfig.DrawSliderInt(0, 90, DNCPvP.Config.DNCPvP_WaltzThreshold, "Curing Waltz HP% - caps at 90 to prevent waste.", 150, SliderIncrements.Ones); - - #endregion - - #endregion // ==================================================================================== - #region DARK KNIGHT - - if (preset == CustomComboPreset.DRK_ST_ManaSpenderPooling && enabled) - UserConfig.DrawSliderInt(0, 3000, DRK.Config.DRK_ST_ManaSpenderPooling, "How much MP to save (0 = Use All)", 150, SliderIncrements.Thousands); - - if (preset == CustomComboPreset.DRK_ST_CDs_LivingShadow && enabled) - UserConfig.DrawSliderInt(0, 30, DRK.Config.DRK_ST_LivingDeadThreshold, "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)", 150, SliderIncrements.Fives); - - if (preset == CustomComboPreset.DRK_AoE_CDs_LivingShadow && enabled) - UserConfig.DrawSliderInt(0, 60, DRK.Config.DRK_AoE_LivingDeadThreshold, "Stop Using When Target HP% is at or Below (Set to 0 to Disable This Check)", 150, SliderIncrements.Fives); - - if (preset == CustomComboPreset.DRKPvP_Burst) - UserConfig.DrawSliderInt(1, 100, DRKPvP.Config.ShadowbringerThreshold, "HP% to be at or above to use Shadowbringer"); - - if (preset == CustomComboPreset.DRK_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, DRK.Config.DRK_VariantCure, "HP% to be at or under", 200); - - #endregion // ==================================================================================== // ==================================================================================== - #region GUNBREAKER - - if (preset == CustomComboPreset.GNB_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, GNB.Config.GNB_VariantCure, "HP% to be at or under", 200); - if (preset == CustomComboPreset.GNB_ST_NoMercy) - UserConfig.DrawSliderInt(0, 25, GNB.Config.GNB_ST_NoMercyStop, "Stop Usage if Target HP% is below set value.\nTo Disable this option, set to 0."); - if (preset == CustomComboPreset.GNB_AoE_NoMercy) - UserConfig.DrawSliderInt(0, 25, GNB.Config.GNB_AoE_NoMercyStop, "Stop Usage if Target HP% is below set value.\nTo Disable this option, set to 0."); - - #endregion // ==================================================================================== // ==================================================================================== - - #region MONK - - if (preset == CustomComboPreset.MNK_ST_ComboHeals) - { - UserConfig.DrawSliderInt(0, 100, MNK.Config.MNK_ST_SecondWind_Threshold, - "Second Wind HP percentage threshold (0 = Disabled)", 150, SliderIncrements.Ones); - - UserConfig.DrawSliderInt(0, 100, MNK.Config.MNK_ST_Bloodbath_Threshold, - "Bloodbath HP percentage threshold (0 = Disabled)", 150, SliderIncrements.Ones); - } - - if (preset == CustomComboPreset.MNK_AoE_ComboHeals) - { - UserConfig.DrawSliderInt(0, 100, MNK.Config.MNK_AoE_SecondWind_Threshold, - "Second Wind HP percentage threshold (0 = Disabled)", 150, SliderIncrements.Ones); - - UserConfig.DrawSliderInt(0, 100, MNK.Config.MNK_AoE_Bloodbath_Threshold, - "Bloodbath HP percentage threshold (0 = Disabled)", 150, SliderIncrements.Ones); - } - - if (preset == CustomComboPreset.MNK_STUseOpener && enabled) - { - UserConfig.DrawHorizontalRadioButton(MNK.Config.MNK_SelectedOpener, "Double Lunar", - "Uses Lunar/Lunar opener", 0); - - UserConfig.DrawHorizontalRadioButton(MNK.Config.MNK_SelectedOpener, "Solar Lunar", - "Uses Solar/Lunar opener", 1); - } - - if (preset == CustomComboPreset.MNK_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, MNK.Config.MNK_VariantCure, "HP% to be at or under", 200); - - #endregion // ==================================================================================== - #region NINJA - - if (preset == CustomComboPreset.NIN_Simple_Mudras) - { - UserConfig.DrawRadioButton(NIN.Config.NIN_SimpleMudra_Choice, "Mudra Path Set 1", $"1. Ten Mudras -> Fuma Shuriken, Raiton/Hyosho Ranryu, Suiton (Doton under Kassatsu).\nChi Mudras -> Fuma Shuriken, Hyoton, Huton.\nJin Mudras -> Fuma Shuriken, Katon/Goka Mekkyaku, Doton", 1); - UserConfig.DrawRadioButton(NIN.Config.NIN_SimpleMudra_Choice, "Mudra Path Set 2", $"2. Ten Mudras -> Fuma Shuriken, Hyoton/Hyosho Ranryu, Doton.\nChi Mudras -> Fuma Shuriken, Katon, Suiton.\nJin Mudras -> Fuma Shuriken, Raiton/Goka Mekkyaku, Huton (Doton under Kassatsu).", 2); - } - if (preset == CustomComboPreset.NIN_ST_AdvancedMode) - UserConfig.DrawSliderInt(0, 10, NIN.Config.BurnKazematoi, "Target HP% to dump all pooled Kazematoi below"); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_Bhavacakra) - UserConfig.DrawSliderInt(50, 100, NIN.Config.Ninki_BhavaPooling, "Set the minimal amount of Ninki required to have before spending on Bhavacakra."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_TrickAttack) - UserConfig.DrawSliderInt(0, 21, NIN.Config.Trick_CooldownRemaining, "Set the amount of time remaining on Trick Attack cooldown before trying to set up with Suiton."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_Bunshin) - UserConfig.DrawSliderInt(50, 100, NIN.Config.Ninki_BunshinPoolingST, "Set the amount of Ninki required to have before spending on Bunshin."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_Bunshin) - UserConfig.DrawSliderInt(50, 100, NIN.Config.Ninki_BunshinPoolingAoE, "Set the amount of Ninki required to have before spending on Bunshin."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_TrickAttack_Cooldowns) - UserConfig.DrawSliderInt(0, 21, NIN.Config.Advanced_Trick_Cooldown, "Set the amount of time remaining on Trick Attack cooldown to start saving cooldowns."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_SecondWind) - UserConfig.DrawSliderInt(0, 100, NIN.Config.SecondWindThresholdST, "Set a HP% threshold for when Second Wind will be used."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_ShadeShift) - UserConfig.DrawSliderInt(0, 100, NIN.Config.ShadeShiftThresholdST, "Set a HP% threshold for when Shade Shift will be used."); - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_Bloodbath) - UserConfig.DrawSliderInt(0, 100, NIN.Config.BloodbathThresholdST, "Set a HP% threshold for when Bloodbath will be used."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_SecondWind) - UserConfig.DrawSliderInt(0, 100, NIN.Config.SecondWindThresholdAoE, "Set a HP% threshold for when Second Wind will be used."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_ShadeShift) - UserConfig.DrawSliderInt(0, 100, NIN.Config.ShadeShiftThresholdAoE, "Set a HP% threshold for when Shade Shift will be used."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_Bloodbath) - UserConfig.DrawSliderInt(0, 100, NIN.Config.BloodbathThresholdAoE, "Set a HP% threshold for when Bloodbath will be used."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_HellfrogMedium) - UserConfig.DrawSliderInt(50, 100, NIN.Config.Ninki_HellfrogPooling, "Set the amount of Ninki required to have before spending on Hellfrog Medium."); - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_Ninjitsus_Doton) - { - UserConfig.DrawSliderInt(0, 18, NIN.Config.Advanced_DotonTimer, "Sets the amount of time remaining on Doton before casting again."); - UserConfig.DrawSliderInt(0, 100, NIN.Config.Advanced_DotonHP, "Sets the max remaining HP percentage of the current target to cast Doton."); - } - - if (preset == CustomComboPreset.NIN_AoE_AdvancedMode_TCJ) - { - UserConfig.DrawRadioButton(NIN.Config.Advanced_TCJEnderAoE, "Ten Chi Jin Ender 1", "Ends Ten Chi Jin with Suiton.", 0); - UserConfig.DrawRadioButton(NIN.Config.Advanced_TCJEnderAoE, $"Ten Chi Jin Ender 2", "Ends Ten Chi Jin with Doton.\nIf you have Doton enabled, Ten Chi Jin will be delayed according to the settings in that feature.", 1); - } - - if (preset == CustomComboPreset.NIN_ST_AdvancedMode_Ninjitsus_Raiton) - { - UserConfig.DrawAdditionalBoolChoice(NIN.Config.Advanced_ChargePool, "Pool Charges", "Waits until at least 2 seconds before your 2nd charge or if Trick Attack debuff is on your target before spending."); - } - - if (preset == CustomComboPreset.NIN_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, NIN.Config.NIN_VariantCure, "HP% to be at or under", 200); - - #endregion // ==================================================================================== - #region PICTOMANCER - if (preset == CustomComboPreset.CombinedAetherhues) - { - UserConfig.DrawRadioButton(PCT.Config.CombinedAetherhueChoices, "Both Single Target & AoE", $"Replaces both {PCT.FireInRed.ActionName()} & {PCT.FireIIinRed.ActionName()}", 0); - UserConfig.DrawRadioButton(PCT.Config.CombinedAetherhueChoices, "Single Target Only", $"Replace only {PCT.FireInRed.ActionName()}", 1); - UserConfig.DrawRadioButton(PCT.Config.CombinedAetherhueChoices, "AoE Only", $"Replace only {PCT.FireIIinRed.ActionName()}", 2); - } - - if (preset == CustomComboPreset.CombinedMotifs) - { - UserConfig.DrawAdditionalBoolChoice(PCT.Config.CombinedMotifsMog, $"{PCT.MogoftheAges.ActionName()} Feature", $"Add {PCT.MogoftheAges.ActionName()} when fully drawn and off cooldown."); - UserConfig.DrawAdditionalBoolChoice(PCT.Config.CombinedMotifsMadeen, $"{PCT.RetributionoftheMadeen.ActionName()} Feature", $"Add {PCT.RetributionoftheMadeen.ActionName()} when fully drawn and off cooldown."); - UserConfig.DrawAdditionalBoolChoice(PCT.Config.CombinedMotifsWeapon, $"{PCT.HammerStamp.ActionName()} Feature", $"Add {PCT.HammerStamp.ActionName()} when under the effect of {PCT.Buffs.HammerTime.StatusName()}."); - } - - if(preset == CustomComboPreset.PCT_ST_AdvancedMode_LucidDreaming ) - { - UserConfig.DrawSliderInt(0, 10000, PCT.Config.PCT_ST_AdvancedMode_LucidOption, "Add Lucid Dreaming when below this MP", sliderIncrement: SliderIncrements.Hundreds); - } - - if (preset == CustomComboPreset.PCT_AoE_AdvancedMode_HolyinWhite) - { - UserConfig.DrawSliderInt(0, 5, PCT.Config.PCT_AoE_AdvancedMode_HolyinWhiteOption, "How many charges to keep ready? (0 = Use all)"); - } - - if(preset == CustomComboPreset.PCT_AoE_AdvancedMode_LucidDreaming) - { - UserConfig.DrawSliderInt(0, 10000, PCT.Config.PCT_AoE_AdvancedMode_LucidOption, "Add Lucid Dreaming when below this MP", sliderIncrement: SliderIncrements.Hundreds); - } - if (preset == CustomComboPreset.PCT_ST_AdvancedMode_LandscapeMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_ST_LandscapeStop, "Health % to stop Drawing Motif"); - if (preset == CustomComboPreset.PCT_ST_AdvancedMode_CreatureMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_ST_CreatureStop, "Health % to stop Drawing Motif"); - if (preset == CustomComboPreset.PCT_ST_AdvancedMode_WeaponMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_ST_WeaponStop, "Health % to stop Drawing Motif"); - if (preset == CustomComboPreset.PCT_AoE_AdvancedMode_LandscapeMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_AoE_LandscapeStop, "Health % to stop Drawing Motif"); - if (preset == CustomComboPreset.PCT_AoE_AdvancedMode_CreatureMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_AoE_CreatureStop, "Health % to stop Drawing Motif"); - if (preset == CustomComboPreset.PCT_AoE_AdvancedMode_WeaponMotif) - UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_AoE_WeaponStop, "Health % to stop Drawing Motif"); - - if (preset == CustomComboPreset.PCT_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, PCT.Config.PCT_VariantCure, "HP% to be at or under", 200); - - // PvP - if (preset == CustomComboPreset.PCTPvP_BurstControl) - UserConfig.DrawSliderInt(1, 100, PCTPvP.Config.PCTPvP_BurstHP, "Target HP%", 200); - - if (preset == CustomComboPreset.PCTPvP_TemperaCoat) - UserConfig.DrawSliderInt(1, 100, PCTPvP.Config.PCTPvP_TemperaHP, "Player HP%", 200); - #endregion // ==================================================================================== - #region PALADIN - - // Fight or Flight - if (preset == CustomComboPreset.PLD_ST_AdvancedMode_FoF) - UserConfig.DrawSliderInt(0, 50, PLD.Config.PLD_ST_FoF_Trigger, "Target HP%", 200); - - if (preset == CustomComboPreset.PLD_AoE_AdvancedMode_FoF) - UserConfig.DrawSliderInt(0, 50, PLD.Config.PLD_AoE_FoF_Trigger, "Target HP%", 200); - - // Sheltron - if (preset == CustomComboPreset.PLD_ST_AdvancedMode_Sheltron) - UserConfig.DrawSliderInt(50, 100, PLD.Config.PLD_ST_SheltronOption, "Oath Gauge", 200, 5); - - if (preset == CustomComboPreset.PLD_AoE_AdvancedMode_Sheltron) - UserConfig.DrawSliderInt(50, 100, PLD.Config.PLD_AoE_SheltronOption, "Oath Gauge", 200, 5); - - // Intervene - if (preset == CustomComboPreset.PLD_ST_AdvancedMode_Intervene) - { - UserConfig.DrawSliderInt(0, 1, PLD.Config.PLD_Intervene_HoldCharges, "Charges", 200); - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_Intervene_MeleeOnly, "Melee Range", "Uses Intervene while within melee range.\nMay result in minor movement.", 1); - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_Intervene_MeleeOnly, "No Movement", "Only uses Intervene when it would not result in movement (zero distance).", 2); - } - - if (preset == CustomComboPreset.PLD_AoE_AdvancedMode_Intervene) - { - UserConfig.DrawSliderInt(0, 1, PLD.Config.PLD_AoE_Intervene_HoldCharges, "Charges", 200); - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_AoE_Intervene_MeleeOnly, "Melee Range", "Uses Intervene while within melee range.\nMay result in minor movement.", 1); - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_AoE_Intervene_MeleeOnly, "No Movement", "Only uses Intervene when it would not result in movement (zero distance).", 2); - } - - // Shield Lob - if (preset == CustomComboPreset.PLD_ST_AdvancedMode_ShieldLob) - { - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_ShieldLob_SubOption, "Shield Lob Only", "Uses only Shield Lob.", 1); - UserConfig.DrawHorizontalRadioButton(PLD.Config.PLD_ShieldLob_SubOption, "Hardcast Holy Spirit", "Attempts to hardcast Holy Spirit when not moving.\nOtherwise uses Shield Lob.", 2); - } - - // MP Reservation - if (preset == CustomComboPreset.PLD_ST_AdvancedMode_MP_Reserve) - UserConfig.DrawSliderInt(1000, 5000, PLD.Config.PLD_ST_MP_Reserve, "Minimum MP", sliderIncrement: 100); - - if (preset == CustomComboPreset.PLD_AoE_AdvancedMode_MP_Reserve) - UserConfig.DrawSliderInt(1000, 5000, PLD.Config.PLD_AoE_MP_Reserve, "Minimum MP", sliderIncrement: 100); - - // Requiescat Spender Feature - if (preset == CustomComboPreset.PLD_Requiescat_Options) - { - UserConfig.DrawRadioButton(PLD.Config.PLD_RequiescatOption, "Confiteor", "", 1); - UserConfig.DrawRadioButton(PLD.Config.PLD_RequiescatOption, "Blade of Faith/Truth/Valor", "", 2); - UserConfig.DrawRadioButton(PLD.Config.PLD_RequiescatOption, "Confiteor & Blade of Faith/Truth/Valor", "", 3); - UserConfig.DrawRadioButton(PLD.Config.PLD_RequiescatOption, "Holy Spirit", "", 4); - UserConfig.DrawRadioButton(PLD.Config.PLD_RequiescatOption, "Holy Circle", "", 5); - } - - // Spirits Within / Circle of Scorn Feature - if (preset == CustomComboPreset.PLD_SpiritsWithin) - { - UserConfig.DrawRadioButton(PLD.Config.PLD_SpiritsWithinOption, "Prioritize Circle of Scorn", "", 1); - UserConfig.DrawRadioButton(PLD.Config.PLD_SpiritsWithinOption, "Prioritize Spirits Within / Expiacion", "", 2); - } - - // Variant Cure Feature - if (preset == CustomComboPreset.PLD_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, PLD.Config.PLD_VariantCure, "Player HP%", 200); - - #endregion // ==================================================================================== - // ==================================================================================== - // ==================================================================================== - // ==================================================================================== - #region SAMURAI - - if (preset == CustomComboPreset.SAM_ST_CDs_Iaijutsu) - { - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_ST_Higanbana_Threshold, "Stop using Higanbana on targets below this HP % (0% = always use).", 150, SliderIncrements.Ones); - } - if (preset == CustomComboPreset.SAM_ST_ComboHeals) - { - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_STSecondWindThreshold, "HP percent threshold to use Second Wind below (0 = Disabled)", 150, SliderIncrements.Ones); - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_STBloodbathThreshold, "HP percent threshold to use Bloodbath (0 = Disabled)", 150, SliderIncrements.Ones); - } - - if (preset == CustomComboPreset.SAM_AoE_ComboHeals) - { - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_AoESecondWindThreshold, "HP percent threshold to use Second Wind below (0 = Disabled)", 150, SliderIncrements.Ones); - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_AoEBloodbathThreshold, "HP percent threshold to use Bloodbath below (0 = Disabled)", 150, SliderIncrements.Ones); - } - - if (preset == CustomComboPreset.SAM_ST_Shinten) - { - UserConfig.DrawSliderInt(50, 85, SAM.Config.SAM_ST_KenkiOvercapAmount, "Set the Kenki overcap amount for ST combos."); - UserConfig.DrawSliderInt(0, 100, SAM.Config.SAM_ST_ExecuteThreshold, "HP percent threshold to not save Kenki", 150, SliderIncrements.Ones); - } - - if (preset == CustomComboPreset.SAM_AoE_Kyuten) - UserConfig.DrawSliderInt(50, 85, SAM.Config.SAM_AoE_KenkiOvercapAmount, "Set the Kenki overcap amount for AOE combos."); - - if (preset == CustomComboPreset.SAM_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, SAM.Config.SAM_VariantCure, "HP% to be at or under", 200); - - //PvP - if (preset == CustomComboPreset.SAMPvP_BurstMode && enabled) - UserConfig.DrawSliderInt(0, 2, SAMPvP.Config.SAMPvP_SotenCharges, "How many charges of Soten to keep ready? (0 = Use All)."); - - if (preset == CustomComboPreset.SAMPvP_KashaFeatures_GapCloser && enabled) - UserConfig.DrawSliderInt(0, 100, SAMPvP.Config.SAMPvP_SotenHP, "Use Soten on enemies below selected HP."); - - if (preset == CustomComboPreset.SAM_ST_KashaCombo) - { - UserConfig.DrawAdditionalBoolChoice(SAM.Config.SAM_Kasha_KenkiOvercap, "Kenki Overcap Protection", "Spends Kenki when at the set value or above."); - if (SAM.Config.SAM_Kasha_KenkiOvercap) - UserConfig.DrawSliderInt(25, 100, SAM.Config.SAM_Kasha_KenkiOvercapAmount, "Kenki Amount", sliderIncrement: SliderIncrements.Fives); - } - - if (preset == CustomComboPreset.SAM_ST_YukikazeCombo) - { - UserConfig.DrawAdditionalBoolChoice(SAM.Config.SAM_Yukaze_KenkiOvercap, "Kenki Overcap Protection", "Spends Kenki when at the set value or above."); - if (SAM.Config.SAM_Yukaze_KenkiOvercap) - UserConfig.DrawSliderInt(25, 100, SAM.Config.SAM_Yukaze_KenkiOvercapAmount, "Kenki Amount", sliderIncrement: SliderIncrements.Fives); - } - - if (preset == CustomComboPreset.SAM_ST_GekkoCombo) - { - UserConfig.DrawAdditionalBoolChoice(SAM.Config.SAM_Gekko_KenkiOvercap, "Kenki Overcap Protection", "Spends Kenki when at the set value or above."); - if (SAM.Config.SAM_Gekko_KenkiOvercap) - UserConfig.DrawSliderInt(25, 100, SAM.Config.SAM_Gekko_KenkiOvercapAmount, "Kenki Amount", sliderIncrement: SliderIncrements.Fives); - } - - if (preset == CustomComboPreset.SAM_AoE_OkaCombo) - { - UserConfig.DrawAdditionalBoolChoice(SAM.Config.SAM_Oka_KenkiOvercap, "Kenki Overcap Protection", "Spends Kenki when at the set value or above."); - if (SAM.Config.SAM_Oka_KenkiOvercap) - UserConfig.DrawSliderInt(25, 100, SAM.Config.SAM_Oka_KenkiOvercapAmount, "Kenki Amount", sliderIncrement: SliderIncrements.Fives); - } - - if (preset == CustomComboPreset.SAM_AoE_MangetsuCombo) - { - UserConfig.DrawAdditionalBoolChoice(SAM.Config.SAM_Mangetsu_KenkiOvercap, "Kenki Overcap Protection", "Spends Kenki when at the set value or above."); - if (SAM.Config.SAM_Mangetsu_KenkiOvercap) - UserConfig.DrawSliderInt(25, 100, SAM.Config.SAM_Mangetsu_KenkiOvercapAmount, "Kenki Amount", sliderIncrement: SliderIncrements.Fives); - } - - #endregion // ==================================================================================== - // ==================================================================================== - #region SUMMONER - - #region PvE - if (preset == CustomComboPreset.SMN_DemiEgiMenu_EgiOrder) - { - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_PrimalChoice, "Titan first", "Summons Titan, Garuda then Ifrit.", 1); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_PrimalChoice, "Garuda first", "Summons Garuda, Titan then Ifrit.", 2); - } - - if (preset == CustomComboPreset.SMN_DemiEgiMenu_oGCDPooling) - UserConfig.DrawSliderInt(0, 3, SMN.Config.SMN_Burst_Delay, "Sets the amount of GCDs under Demi summon to wait for oGCD use.", 150, SliderIncrements.Ones); - - if (preset == CustomComboPreset.SMN_DemiEgiMenu_oGCDPooling) - { - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_BurstPhase, "Solar Bahamut/Bahamut", "Bursts during Bahamut phase.\nBahamut burst phase becomes Solar Bahamut at Lv100.", 1); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_BurstPhase, "Phoenix", "Bursts during Phoenix phase.", 2); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_BurstPhase, "Any Demi Phase", "Bursts during any Demi Summon phase.", 3); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_BurstPhase, "Flexible (SpS) Option", "Bursts when Searing Light is ready, regardless of phase.", 4); - } - - if (preset == CustomComboPreset.SMN_DemiEgiMenu_SwiftcastEgi) - { - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_SwiftcastPhase, "Garuda", "Swiftcasts Slipstream", 1); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_SwiftcastPhase, "Ifrit", "Swiftcasts Ruby Ruin/Ruby Rite", 2); - UserConfig.DrawHorizontalRadioButton(SMN.Config.SMN_SwiftcastPhase, "Flexible (SpS) Option", "Swiftcasts the first available Egi when Swiftcast is ready.", 3); - } - - if (preset == CustomComboPreset.SMN_Lucid) - UserConfig.DrawSliderInt(4000, 9500, SMN.Config.SMN_Lucid, "Set value for your MP to be at or under for this feature to take effect.", 150, SliderIncrements.Hundreds); - - if (preset == CustomComboPreset.SMN_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, SMN.Config.SMN_VariantCure, "HP% to be at or under", 200); - - if (preset == CustomComboPreset.SMN_ST_Egi_AstralFlow) - { - UserConfig.DrawHorizontalMultiChoice(SMN.Config.SMN_ST_Egi_AstralFlow, "Add Mountain Buster", "", 3, 0); - UserConfig.DrawHorizontalMultiChoice(SMN.Config.SMN_ST_Egi_AstralFlow, "Add Crimson Cyclone", "", 3, 1); - UserConfig.DrawHorizontalMultiChoice(SMN.Config.SMN_ST_Egi_AstralFlow, "Add Slipstream", "", 3, 2); - - if (SMN.Config.SMN_ST_Egi_AstralFlow[1]) - UserConfig.DrawAdditionalBoolChoice(SMN.Config.SMN_ST_CrimsonCycloneMelee, "Enforced Crimson Cyclone Melee Check", "Only uses Crimson Cyclone within melee range."); - } - - - - #endregion - - #region PvP - - if (preset == CustomComboPreset.SMNPvP_BurstMode) - UserConfig.DrawSliderInt(50, 100, SMNPvP.Config.SMNPvP_FesterThreshold, "Target HP% to cast Fester below.\nSet to 100 use Fester as soon as it's available.", 150, SliderIncrements.Ones); - - if (preset == CustomComboPreset.SMNPvP_BurstMode_RadiantAegis) - UserConfig.DrawSliderInt(0, 90, SMNPvP.Config.SMNPvP_RadiantAegisThreshold, "Caps at 90 to prevent waste.", 150, SliderIncrements.Ones); - - #endregion - - #endregion // ==================================================================================== - // ==================================================================================== - #region WARRIOR - - if (preset == CustomComboPreset.WAR_ST_Advanced_StormsEye && enabled) - UserConfig.DrawSliderInt(0, 30, WAR.Config.WAR_SurgingRefreshRange, "Seconds remaining before refreshing Surging Tempest."); - - if (preset == CustomComboPreset.WAR_InfuriateFellCleave && enabled) - UserConfig.DrawSliderInt(0, 50, WAR.Config.WAR_InfuriateRange, "Set how much rage to be at or under to use this feature."); - - if (preset == CustomComboPreset.WAR_ST_Advanced_Onslaught && enabled) - UserConfig.DrawSliderInt(0, 2, WAR.Config.WAR_KeepOnslaughtCharges, "How many charges to keep ready? (0 = Use All)"); - - if (preset == CustomComboPreset.WAR_ST_Advanced_Infuriate && enabled) - UserConfig.DrawSliderInt(0, 2, WAR.Config.WAR_KeepInfuriateCharges, "How many charges to keep ready? (0 = Use All)"); - - if (preset == CustomComboPreset.WAR_Variant_Cure) - UserConfig.DrawSliderInt(1, 100, WAR.Config.WAR_VariantCure, "HP% to be at or under", 200); - - if (preset == CustomComboPreset.WAR_ST_Advanced_FellCleave) - UserConfig.DrawSliderInt(50, 100, WAR.Config.WAR_FellCleaveGauge, "Minimum gauge to spend"); - - if (preset == CustomComboPreset.WAR_AoE_Advanced_Decimate) - UserConfig.DrawSliderInt(50, 100, WAR.Config.WAR_DecimateGauge, "Minimum gauge to spend"); - - if (preset == CustomComboPreset.WAR_ST_Advanced_Infuriate) - UserConfig.DrawSliderInt(0, 50, WAR.Config.WAR_InfuriateSTGauge, "Use when gauge is under or equal to"); - - if (preset == CustomComboPreset.WAR_AoE_Advanced_Infuriate) - UserConfig.DrawSliderInt(0, 50, WAR.Config.WAR_InfuriateAoEGauge, "Use when gauge is under or equal to"); - - if (preset == CustomComboPreset.WARPvP_BurstMode_Blota) - { - UserConfig.DrawHorizontalRadioButton(WARPvP.Config.WARPVP_BlotaTiming, "Before Primal Rend", "", 0); - UserConfig.DrawHorizontalRadioButton(WARPvP.Config.WARPVP_BlotaTiming, "After Primal Rend", "", 1); - } - - #endregion // ==================================================================================== - // ==================================================================================== - #region DOH - - #endregion // ==================================================================================== - #region DOL - - #endregion // ==================================================================================== #region PvP VALUES