From 480a72efda6a7db8af5938a3956213c04a1e734c Mon Sep 17 00:00:00 2001 From: Katie Date: Sun, 25 Aug 2024 13:37:32 -0400 Subject: [PATCH 01/17] Add AoE Holy in White feature --- XIVSlothCombo/Combos/CustomComboPreset.cs | 28 +++++++++++--------- XIVSlothCombo/Combos/PvE/PCT.cs | 10 +++++++ XIVSlothCombo/Window/Functions/UserConfig.cs | 6 +++++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index e0539e3e7..53e086d6f 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -2486,7 +2486,7 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode = 20040, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Prepull Motifs Feature", "Adds missing Motifs to the combo while out of combat.", PCT.JobID)] + [CustomComboInfo("Prepull Motifs Feature", "Adds missing Motifs to the combo while out of combat.", PCT.JobID, 1)] PCT_AoE_AdvancedMode_PrePullMotifs = 20041, [ParentCombo(PCT_AoE_AdvancedMode_PrePullMotifs)] @@ -2494,7 +2494,7 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode_NoTargetMotifs = 20042, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Starry Muse Burst Feature", $"Adds selected spells below to the burst phase.", PCT.JobID)] + [CustomComboInfo("Starry Muse Burst Feature", $"Adds selected spells below to the burst phase.", PCT.JobID, 2)] PCT_AoE_AdvancedMode_Burst_Phase = 20043, [ParentCombo(PCT_AoE_AdvancedMode_Burst_Phase)] @@ -2518,7 +2518,7 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode_Burst_BlizzardInCyan = 20048, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Motif Selection Feature", $"Add Selected Motifs to the combo.", PCT.JobID)] + [CustomComboInfo("Motif Selection Feature", $"Add Selected Motifs to the combo.", PCT.JobID, 3)] PCT_AoE_AdvancedMode_MotifFeature = 20049, [ParentCombo(PCT_AoE_AdvancedMode_MotifFeature)] @@ -2534,7 +2534,7 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode_WeaponMotif = 20052, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Muse Selection Feature", $"Adds Selected Muses to the combo.", PCT.JobID)] + [CustomComboInfo("Muse Selection Feature", $"Adds Selected Muses to the combo.", PCT.JobID, 4)] PCT_AoE_AdvancedMode_MuseFeature = 20053, [ParentCombo(PCT_AoE_AdvancedMode_MuseFeature)] @@ -2550,23 +2550,27 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode_SteelMuse = 20056, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Mog/Madeen Feature", $"Adds Mog/Madeen to the combo.", PCT.JobID)] + [CustomComboInfo("Mog/Madeen Feature", $"Adds Mog/Madeen to the combo.", PCT.JobID, 5)] PCT_AoE_AdvancedMode_MogOfTheAges = 20057, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Subtractive Palette Feature", $"Adds Subtractive Palette to the combo.", PCT.JobID)] + [CustomComboInfo("Subtractive Palette Feature", $"Adds Subtractive Palette to the combo.", PCT.JobID, 6)] PCT_AoE_AdvancedMode_SubtractivePalette = 20058, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Comet in Black Option", $"Adds Comet in Black to the combo.", PCT.JobID)] + [CustomComboInfo("Comet in Black Option", $"Adds Comet in Black to the combo.", PCT.JobID, 7)] PCT_AoE_AdvancedMode_CometinBlack = 20059, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Hammer Stamp Combo Option", $"Adds Hammer Stamp combo.", PCT.JobID)] + [CustomComboInfo("Hammer Stamp Combo Option", $"Adds Hammer Stamp combo.", PCT.JobID, 8)] PCT_AoE_AdvancedMode_HammerStampCombo = 20060, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Movement Features", $"Adds selected features to the combo while moving.", PCT.JobID)] + [CustomComboInfo("Holy in White Option", $"Adds Holy in White to the combo.", PCT.JobID, 9)] + PCT_AoE_AdvancedMode_HolyinWhite = 20068, + + [ParentCombo(PCT_AoE_AdvancedMode)] + [CustomComboInfo("Movement Features", $"Adds selected features to the combo while moving.", PCT.JobID, 10)] PCT_AoE_AdvancedMode_MovementFeature = 20061, [ParentCombo(PCT_AoE_AdvancedMode_MovementFeature)] @@ -2586,11 +2590,11 @@ public enum CustomComboPreset PCT_AoE_AdvancedMode_SwitfcastOption = 20065, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Blizzard in Cyan Option", $"Adds Blizzard in Cyan to the combo.", PCT.JobID)] + [CustomComboInfo("Blizzard in Cyan Option", $"Adds Blizzard in Cyan to the combo.", PCT.JobID, 11)] PCT_AoE_AdvancedMode_BlizzardInCyan = 20066, [ParentCombo(PCT_AoE_AdvancedMode)] - [CustomComboInfo("Lucid Dreaming Option", $"Adds Lucid Dreaming to the combo.", PCT.JobID)] + [CustomComboInfo("Lucid Dreaming Option", $"Adds Lucid Dreaming to the combo.", PCT.JobID, 12)] PCT_AoE_AdvancedMode_LucidDreaming = 20067, [ReplaceSkill(PCT.FireInRed, PCT.FireIIinRed)] @@ -2607,7 +2611,7 @@ public enum CustomComboPreset CombinedPaint = 20004, - // Last value for AoE = 20067 + // Last value for AoE = 20068 #endregion #endregion diff --git a/XIVSlothCombo/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT.cs index df12da91e..26385815e 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT.cs @@ -23,6 +23,7 @@ public const uint AeroInGreen = 34651, WaterInBlue = 34652, FireIIinRed = 34656, + AeroIIinGreen = 34657, HammerMotif = 34668, WingedMuse = 34671, StrikingMuse = 34674, @@ -45,6 +46,7 @@ public const uint StarPrism = 34681, SteelMuse = 35348, SubtractivePalette = 34683, + StoneIIinYellow = 34660, ThunderIIinMagenta = 34661, ThunderinMagenta = 34655, WaterinBlue = 34652, @@ -75,6 +77,7 @@ 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); public static UserBool @@ -721,6 +724,13 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } } + if (IsEnabled(CustomComboPreset.PCT_AoE_AdvancedMode_HolyinWhite) && !HasEffect(Buffs.StarryMuse) && !HasEffect(Buffs.MonochromeTones)) + { + if (gauge.Paint > Config.PCT_AoE_AdvancedMode_HolyinWhiteOption || + (Config.PCT_AoE_AdvancedMode_HolyinWhiteOption == 5 && gauge.Paint == 5 && !HasEffect(Buffs.HammerTime) && + (HasEffect(Buffs.RainbowBright) || WasLastSpell(AeroIIinGreen) || WasLastSpell(StoneIIinYellow)))) + return OriginalHook(HolyInWhite); + } if (HasEffect(Buffs.RainbowBright) && !HasEffect(Buffs.StarryMuse)) return RainbowDrip; diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index bba1a908d..6bf69eddb 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1676,6 +1676,12 @@ internal static void Draw(CustomComboPreset preset, bool enabled) { 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); From 92e63524473fcf02289054f9c9ad88389c15d4f4 Mon Sep 17 00:00:00 2001 From: Katie Date: Sat, 7 Sep 2024 16:23:01 -0400 Subject: [PATCH 02/17] Add variant action options --- XIVSlothCombo/Combos/CustomComboPreset.cs | 9 ++++++ XIVSlothCombo/Combos/PvE/PCT.cs | 30 +++++++++++++++++++- XIVSlothCombo/Window/Functions/UserConfig.cs | 3 ++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index e0539e3e7..930761fc5 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -2606,6 +2606,15 @@ public enum CustomComboPreset [CustomComboInfo("One Button Paint", "Consolidates paint-consuming actions into one button.", PCT.JobID)] CombinedPaint = 20004, + [Variant] + [VariantParent(PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] + [CustomComboInfo("Cure Option", "Use Variant Cure when HP is below set threshold.", PCT.JobID)] + PCT_Variant_Cure = 20100, + + [Variant] + [VariantParent(PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] + [CustomComboInfo("Rampart Option", "Use Variant Rampart on cooldown.", PCT.JobID)] + PCT_Variant_Rampart = 20101, // Last value for AoE = 20067 #endregion diff --git a/XIVSlothCombo/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT.cs index df12da91e..2ab1524d0 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT.cs @@ -1,5 +1,6 @@ using Dalamud.Game.ClientState.JobGauge.Types; using XIVSlothCombo.Combos.JobHelpers; +using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; @@ -75,7 +76,8 @@ public static class Config public static UserInt CombinedAetherhueChoices = new("CombinedAetherhueChoices"), PCT_ST_AdvancedMode_LucidOption = new("PCT_ST_AdvancedMode_LucidOption", 6500), - PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500); + PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500), + PCT_VariantCure = new("PCT_VariantCure"); public static UserBool CombinedMotifsMog = new("CombinedMotifsMog"), @@ -193,6 +195,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb var gauge = GetJobGauge(); bool canWeave = CanSpellWeave(ActionWatching.LastSpell) || CanSpellWeave(actionID); + // Variant Cure + if (IsEnabled(CustomComboPreset.PCT_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= GetOptionValue(Config.PCT_VariantCure)) + return Variant.VariantCure; + + // Variant Rampart + if (IsEnabled(CustomComboPreset.PCT_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + canWeave) + return Variant.VariantRampart; + // Prepull logic if (IsEnabled(CustomComboPreset.PCT_ST_AdvancedMode_PrePullMotifs)) { @@ -558,6 +573,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb var gauge = GetJobGauge(); bool canWeave = CanSpellWeave(ActionWatching.LastSpell); + // Variant Cure + if (IsEnabled(CustomComboPreset.PCT_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= GetOptionValue(Config.PCT_VariantCure)) + return Variant.VariantCure; + + // Variant Rampart + if (IsEnabled(CustomComboPreset.PCT_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + canWeave) + return Variant.VariantRampart; + // Prepull logic if (IsEnabled(CustomComboPreset.PCT_AoE_AdvancedMode_PrePullMotifs)) { diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index 956d6bd4e..c50ee1c79 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1681,6 +1681,9 @@ internal static void Draw(CustomComboPreset preset, bool enabled) UserConfig.DrawSliderInt(0, 10000, PCT.Config.PCT_AoE_AdvancedMode_LucidOption, "Add Lucid Dreaming when below this MP", sliderIncrement: SliderIncrements.Hundreds); } + 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); From 07d41e49909e80962e52253c5a750bd7bc7f517c Mon Sep 17 00:00:00 2001 From: Kage Date: Sun, 8 Sep 2024 19:01:17 +0200 Subject: [PATCH 03/17] add Advanced AoE refactor code --- XIVSlothCombo/Combos/CustomComboPreset.cs | 63 +- XIVSlothCombo/Combos/JobHelpers/MNK.cs | 596 +++++---- XIVSlothCombo/Combos/PvE/MNK.cs | 1168 +++++++++--------- XIVSlothCombo/Window/Functions/UserConfig.cs | 9 + 4 files changed, 973 insertions(+), 863 deletions(-) diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index e0539e3e7..936d7cd6d 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -1947,19 +1947,21 @@ public enum CustomComboPreset #region MONK - [ReplaceSkill([MNK.Bootshine])] - [CustomComboInfo("Simple Mode - Single Target", "Replaces Bootshine with a one - button full single target rotation.\nThis is ideal for newcomers to the job.", MNK.JobID)] + [ReplaceSkill([MNK.Bootshine, MNK.LeapingOpo])] [ConflictingCombos(MNK_ST_BeastChakras, MNK_ST_AdvancedMode)] + [CustomComboInfo("Simple Mode - Single Target", "Replaces Bootshine with a one - button full single target rotation.\nThis is ideal for newcomers to the job.", MNK.JobID)] MNK_ST_SimpleMode = 9004, - [ReplaceSkill([MNK.ArmOfTheDestroyer])] + [ReplaceSkill([MNK.ArmOfTheDestroyer,MNK.ShadowOfTheDestroyer])] + [ConflictingCombos(MNK_AOE_AdvancedMode)] [CustomComboInfo("Simple Mode - AoE", "Replaces Arm of the Destroyer with a one-button full single target rotation.\nThis is ideal for newcomers to the job.", MNK.JobID)] MNK_AOE_SimpleMode = 9003, #region Monk Advanced ST + [ReplaceSkill([MNK.Bootshine])] - [CustomComboInfo("Advanced Mode - Single Target", "Replaces Bootshine with a one-button full single target rotation.\nThese features are ideal if you want to customize the rotation.", MNK.JobID)] [ConflictingCombos(MNK_ST_BeastChakras, MNK_ST_SimpleMode)] + [CustomComboInfo("Advanced Mode - Single Target", "Replaces Bootshine with a one-button full single target rotation.\nThese features are ideal if you want to customize the rotation.", MNK.JobID)] MNK_ST_AdvancedMode = 9005, [ParentCombo(MNK_ST_AdvancedMode)] @@ -2016,6 +2018,55 @@ public enum CustomComboPreset #endregion + #region Monk Advanced AOE + + [ReplaceSkill([MNK.ArmOfTheDestroyer, MNK.ShadowOfTheDestroyer])] + [ConflictingCombos(MNK_AOE_SimpleMode)] + [CustomComboInfo("Advanced Mode - AoE", "Replaces Arm of the Destroyer with a one-button full single target rotation.\nThese features are ideal if you want to customize the rotation.", MNK.JobID)] + MNK_AOE_AdvancedMode = 9027, + + [ParentCombo(MNK_AOE_AdvancedMode)] + [CustomComboInfo("Meditation Option", "Adds Meditation to the rotation", MNK.JobID)] + MNK_AoEUseMeditation = 9028, + + [ParentCombo(MNK_AOE_AdvancedMode)] + [CustomComboInfo("Buffs Option", "Adds selected buffs to the rotation", MNK.JobID)] + MNK_AoEUseBuffs = 9029, + + [ParentCombo(MNK_AoEUseBuffs)] + [CustomComboInfo("Brotherhood Option", "Adds Brotherhood to the rotation", MNK.JobID)] + MNK_AoEUseBrotherhood = 9030, + + [ParentCombo(MNK_AoEUseBuffs)] + [CustomComboInfo("Riddle of Wind Option", "Adds Riddle of Wind to the rotation", MNK.JobID)] + MNK_AoEUseROW = 9031, + + [ParentCombo(MNK_AoEUseBuffs)] + [CustomComboInfo("Riddle of Fire Option", "Adds Riddle of Fire to the rotation", MNK.JobID)] + MNK_AoEUseROF = 9032, + + [ParentCombo(MNK_AOE_AdvancedMode)] + [CustomComboInfo("Howling Fist Option", "Adds Howling Fist to the rotation", MNK.JobID)] + MNK_AoEUseHowlingFist = 9033, + + [ParentCombo(MNK_AOE_AdvancedMode)] + [CustomComboInfo("Perfect Balance Option", "Adds Perfect Balance and Masterful Blitz to the rotation", MNK.JobID)] + MNK_AoEUsePerfectBalance = 9034, + + [ParentCombo(MNK_AoEUseROW)] + [CustomComboInfo("Wind's Reply Option", "Adds Wind's Reply to the rotation", MNK.JobID)] + MNK_AoEUseWindsReply = 9035, + + [ParentCombo(MNK_AoEUseROF)] + [CustomComboInfo("Fire's Reply Option", "Adds Fire's Reply to the rotation", MNK.JobID)] + MNK_AoEUseFiresReply = 9036, + + [ParentCombo(MNK_AOE_AdvancedMode)] + [CustomComboInfo("Combo Heals Option", "Adds Bloodbath and Second Wind to the rotation.", MNK.JobID)] + MNK_AoE_ComboHeals = 9037, + + #endregion + #region Monk Beast Chakras [ConflictingCombos(MNK_ST_AdvancedMode, MNK_ST_SimpleMode)] @@ -2060,8 +2111,10 @@ public enum CustomComboPreset MNK_Variant_Cure = 9026, #endregion - + + // last value = 9037 // End Monk + #endregion #region NINJA diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index 564013dd3..a74cf5810 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -1,415 +1,405 @@ -using Dalamud.Game.ClientState.JobGauge.Types; +using Dalamud.Game.ClientState.JobGauge.Enums; using ECommons.DalamudServices; -using System.Linq; using XIVSlothCombo.Combos.JobHelpers.Enums; using XIVSlothCombo.Combos.PvE; -using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; -using XIVSlothCombo.Extensions; +using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; -namespace XIVSlothCombo.Combos.JobHelpers -{ +namespace XIVSlothCombo.Combos.JobHelpers; - internal class MNKHelper : MNK +internal abstract class MNKHelper : MNK +{ + public static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled = true) { - public static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled = true) + 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 (CustomComboFunctions.HasEffect(Buffs.OpoOpoForm) || CustomComboFunctions.HasEffect(Buffs.FormlessFist)) + if (Gauge.CoeurlFury == 0 && LevelChecked(Demolish)) { - if (Gauge.OpoOpoFury == 0 && DragonKick.LevelChecked()) - { - if (CustomComboFunctions.LevelChecked(DragonKick)) - return DragonKick; - } - else - { - return CustomComboFunctions.OriginalHook(Bootshine); - } - } + if (!OnTargetsRear() && + TargetNeedsPositionals() && + !HasEffect(Buffs.TrueNorth) && + ActionReady(TrueNorth) && + useTrueNorthIfEnabled) + return TrueNorth; - if (CustomComboFunctions.HasEffect(Buffs.RaptorForm)) - { - if (Gauge.RaptorFury == 0 && TwinSnakes.LevelChecked()) - { - if (CustomComboFunctions.LevelChecked(TwinSnakes)) - return TwinSnakes; - } - else - { - if (CustomComboFunctions.LevelChecked(TrueStrike)) - return CustomComboFunctions.OriginalHook(TrueStrike); - } + return Demolish; } - if (CustomComboFunctions.HasEffect(Buffs.CoeurlForm)) + if (LevelChecked(SnapPunch)) { - if (Gauge.CoeurlFury == 0 && Demolish.LevelChecked()) - { - if (!CustomComboFunctions.OnTargetsRear() - && CustomComboFunctions.TargetNeedsPositionals() - && !CustomComboFunctions.HasEffect(Buffs.TrueNorth) - && CustomComboFunctions.LevelChecked(TrueNorth) - && CustomComboFunctions.HasCharges(TrueNorth) - && useTrueNorthIfEnabled) - { - return TrueNorth; - } - else - { - if (CustomComboFunctions.LevelChecked(Demolish)) - return Demolish; - } - } - - if (!CustomComboFunctions.OnTargetsFlank() - && CustomComboFunctions.TargetNeedsPositionals() - && !CustomComboFunctions.HasEffect(Buffs.TrueNorth) - && CustomComboFunctions.LevelChecked(TrueNorth) - && CustomComboFunctions.HasCharges(TrueNorth) - && useTrueNorthIfEnabled) - { + if (!OnTargetsFlank() && + TargetNeedsPositionals() && + !HasEffect(Buffs.TrueNorth) && + ActionReady(TrueNorth) && + useTrueNorthIfEnabled) return TrueNorth; - } - else - { - if (CustomComboFunctions.LevelChecked(SnapPunch)) - return CustomComboFunctions.OriginalHook(SnapPunch); - } - } - return actionId; + return OriginalHook(SnapPunch); + } } + + return actionId; } +} + +internal class MNKOpenerLogic : MNK +{ + private OpenerState currentState = OpenerState.PrePull; + + public uint OpenerStep; + + public uint PrePullStep; - internal class MNKOpenerLogic : MNK + private static uint OpenerLevel => 100; + + public static bool LevelChecked => LocalPlayer.Level >= OpenerLevel; + + private static bool CanOpener => HasCooldowns() && LevelChecked; + + public OpenerState CurrentState { - private static bool HasCooldowns() + get => currentState; + set { - if (CustomComboFunctions.GetRemainingCharges(PerfectBalance) < 2) - return false; + if (value != currentState) + { + if (value == OpenerState.PrePull) Svc.Log.Debug("Entered PrePull Opener"); + if (value == OpenerState.InOpener) OpenerStep = 1; - if (!CustomComboFunctions.ActionReady(Brotherhood)) - return false; + if (value == OpenerState.OpenerFinished || value == OpenerState.FailedOpener) + { + if (value == OpenerState.FailedOpener) + Svc.Log.Information($"Opener Failed at step {OpenerStep}"); - if (!CustomComboFunctions.ActionReady(RiddleOfFire)) - return false; + ResetOpener(); + } + if (value == OpenerState.OpenerFinished) Svc.Log.Information("Opener Finished"); - if (!CustomComboFunctions.ActionReady(RiddleOfWind)) - return false; + currentState = value; + } + } + } - if (!CustomComboFunctions.ActionReady(Meditation) && Gauge.Chakra < 5) - return false; + private static bool HasCooldowns() + { + if (GetRemainingCharges(PerfectBalance) < 2) + return false; - if (Gauge.Nadi != Dalamud.Game.ClientState.JobGauge.Enums.Nadi.NONE) - return false; + if (!ActionReady(Brotherhood)) + return false; - if (Gauge.RaptorFury != 0) return false; - if (Gauge.CoeurlFury != 0) return false; + if (!ActionReady(RiddleOfFire)) + return false; - return true; - } + if (!ActionReady(RiddleOfWind)) + return false; - private static uint OpenerLevel => 100; + if (!ActionReady(Meditation) && Gauge.Chakra < 5) + return false; - public uint PrePullStep = 0; + if (Gauge.Nadi != Nadi.NONE) + return false; - public uint OpenerStep = 0; + if (Gauge.RaptorFury != 0 || Gauge.CoeurlFury != 0) + return false; - public static bool LevelChecked => CustomComboFunctions.LocalPlayer.Level >= OpenerLevel; + return true; + } - private static bool CanOpener => HasCooldowns() && LevelChecked; + private bool DoPrePullSteps(ref uint actionID) + { + if (!LevelChecked) + return false; - private OpenerState currentState = OpenerState.PrePull; + if (CanOpener && PrePullStep == 0) PrePullStep = 1; - 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; - } - } - } + if (!HasCooldowns()) PrePullStep = 0; - private bool DoPrePullSteps(ref uint actionID) + if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (!LevelChecked) - return false; - - if (CanOpener && PrePullStep == 0) + if (Gauge.Chakra < 5 && PrePullStep == 1) { - PrePullStep = 1; + actionID = ForbiddenMeditation; + + return true; } - if (!HasCooldowns()) + if (!HasEffect(Buffs.FormlessFist) && + !HasEffect(Buffs.RaptorForm) && PrePullStep == 1) { - PrePullStep = 0; + actionID = FormShift; + + return true; } - if (CurrentState == OpenerState.PrePull && PrePullStep > 0) - { - if (Gauge.Chakra < 5 && PrePullStep == 1) - { - actionID = ForbiddenMeditation; - return true; - } + if (WasLastAction(DragonKick) && PrePullStep == 1) CurrentState = OpenerState.InOpener; + else if (PrePullStep == 1) actionID = DragonKick; - if (!CustomComboFunctions.HasEffect(Buffs.FormlessFist) && !CustomComboFunctions.HasEffect(Buffs.RaptorForm) && PrePullStep == 1) - { - actionID = FormShift; - return true; - } + if (ActionWatching.CombatActions.Count > 2 && InCombat()) + CurrentState = OpenerState.FailedOpener; - if (CustomComboFunctions.WasLastAction(DragonKick) && PrePullStep == 1) CurrentState = OpenerState.InOpener; - else if (PrePullStep == 1) actionID = DragonKick; + return true; + } + PrePullStep = 0; - if (ActionWatching.CombatActions.Count > 2 && CustomComboFunctions.InCombat()) - CurrentState = OpenerState.FailedOpener; + return false; + } - return true; - } - PrePullStep = 0; + private bool DoSlOpener(ref uint actionID) + { + if (!LevelChecked) return false; - } - private bool DoSLOpener(ref uint actionID) + if (currentState == OpenerState.InOpener) { - if (!LevelChecked) - return false; - - if (currentState == OpenerState.InOpener) + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + Gauge.Chakra >= 5 && + OpenerStep > 2) { - if (CustomComboFunctions.IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && OpenerStep > 2) - { - actionID = TheForbiddenChakra; - return true; - } + actionID = TheForbiddenChakra; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = PerfectBalance; + return true; + } - if (CustomComboFunctions.WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TheForbiddenChakra; + if ((WasLastAction(PerfectBalance) || + HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(TwinSnakes) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = TwinSnakes; + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = TheForbiddenChakra; - if (CustomComboFunctions.WasLastWeaponskill(Demolish) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Demolish; + if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = TwinSnakes; - if (CustomComboFunctions.WasLastAbility(Brotherhood) && CustomComboFunctions.HasEffect(Buffs.Brotherhood) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Brotherhood; + if (WasLastWeaponskill(Demolish) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Demolish; - if (CustomComboFunctions.WasLastAction(RiddleOfFire) && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastAbility(Brotherhood) && HasEffect(Buffs.Brotherhood) && + OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = Brotherhood; - // Pot + if (WasLastAction(RiddleOfFire) && + HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = RiddleOfFire; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + // Pot - if (CustomComboFunctions.WasLastAction(RiddleOfWind) && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = RisingPhoenix; + if (WasLastAction(RiddleOfWind) && + HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8) actionID = RiddleOfWind; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; + if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = RisingPhoenix; - if ((CustomComboFunctions.WasLastWeaponskill(FiresReply) || !CustomComboFunctions.HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = FiresReply; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; - if ((CustomComboFunctions.WasLastWeaponskill(WindsReply) || !CustomComboFunctions.HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = WindsReply; + if ((WasLastWeaponskill(FiresReply) || + !HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = FiresReply; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; + if ((WasLastWeaponskill(WindsReply) || + !HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = WindsReply; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; + if ((WasLastAction(PerfectBalance) || + HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) + CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; - if (((actionID == PerfectBalance && CustomComboFunctions.GetRemainingCharges(PerfectBalance) == 0) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || - (OpenerStep is 6 && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire)) || - (OpenerStep is 8 && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind)) || - (OpenerStep is 5 && CustomComboFunctions.HasEffect(Buffs.Brotherhood)) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - Svc.Log.Debug($"Failed at {actionID}"); - CurrentState = OpenerState.FailedOpener; - return false; - } - return true; + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; + + if ((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0 && + ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || + (OpenerStep is 6 && HasEffect(Buffs.RiddleOfFire)) || + (OpenerStep is 8 && HasEffect(Buffs.RiddleOfWind)) || + (OpenerStep is 5 && HasEffect(Buffs.Brotherhood) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3)) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; + + return false; } - return false; + + return true; } - private bool DoLLOpener(ref uint actionID) - { - if (!LevelChecked) - return false; + return false; + } + + private bool DoLlOpener(ref uint actionID) + { + if (!LevelChecked) + return false; - if (currentState == OpenerState.InOpener) + if (currentState == OpenerState.InOpener) + { + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) + && Gauge.Chakra >= 5 + && OpenerStep > 2) { - if (CustomComboFunctions.IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && OpenerStep > 2) - { - actionID = TheForbiddenChakra; - return true; - } + actionID = TheForbiddenChakra; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = PerfectBalance; + return true; + } - if (CustomComboFunctions.WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TheForbiddenChakra; + if ((WasLastAction(PerfectBalance) || + HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = LeapingOpo; + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = TheForbiddenChakra; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = DragonKick; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastAbility(Brotherhood) && CustomComboFunctions.HasEffect(Buffs.Brotherhood) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Brotherhood; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = DragonKick; - if (CustomComboFunctions.WasLastAction(RiddleOfFire) && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastAbility(Brotherhood) && HasEffect(Buffs.Brotherhood) && + OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = Brotherhood; - // Pot + if (WasLastAction(RiddleOfFire) && + HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = RiddleOfFire; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + // Pot - if (CustomComboFunctions.WasLastAction(RiddleOfWind) && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = ElixirBurst; + if (WasLastAction(RiddleOfWind) && + HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8) actionID = RiddleOfWind; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = ElixirBurst; - if ((CustomComboFunctions.WasLastWeaponskill(FiresReply) || !CustomComboFunctions.HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = FiresReply; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; - if ((CustomComboFunctions.WasLastWeaponskill(WindsReply) || !CustomComboFunctions.HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = WindsReply; + if ((WasLastWeaponskill(FiresReply) || + !HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = FiresReply; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; + if ((WasLastWeaponskill(WindsReply) || + !HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = WindsReply; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; + if ((WasLastAction(PerfectBalance) || + HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) + CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; - if (((actionID == PerfectBalance && CustomComboFunctions.GetRemainingCharges(PerfectBalance) == 0) && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || - (OpenerStep is 6 && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire)) || - (OpenerStep is 8 && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind)) || - (OpenerStep is 5 && CustomComboFunctions.HasEffect(Buffs.Brotherhood)) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) - { - Svc.Log.Debug($"Failed at {actionID}"); - CurrentState = OpenerState.FailedOpener; - return false; - } - return true; + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; + + if ((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0 && + ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || + (OpenerStep is 6 && HasEffect(Buffs.RiddleOfFire)) || + (OpenerStep is 8 && HasEffect(Buffs.RiddleOfWind)) || + (OpenerStep is 5 && HasEffect(Buffs.Brotherhood) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3)) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; + + return false; } - return false; - } - private void ResetOpener() - { - PrePullStep = 0; - OpenerStep = 0; + return true; } - public bool DoFullOpener(ref uint actionID, int selectedOpener) - { - if (!LevelChecked) - return false; + return false; + } - if (CurrentState == OpenerState.PrePull) - if (DoPrePullSteps(ref actionID)) - return true; + private void ResetOpener() + { + PrePullStep = 0; + OpenerStep = 0; + } - if (CurrentState == OpenerState.InOpener) + 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) + { + if (selectedOpener == 1) { - if (selectedOpener == 1) - { - if (DoLLOpener(ref actionID)) - return true; - } - else if (selectedOpener == 2) - { - if (DoSLOpener(ref actionID)) - return true; - } + if (DoLlOpener(ref actionID)) + return true; } - - if (!CustomComboFunctions.InCombat()) + else if (selectedOpener == 2) { - ResetOpener(); - CurrentState = OpenerState.PrePull; + if (DoSlOpener(ref actionID)) + return true; } - return false; } + + if (!InCombat()) + { + ResetOpener(); + CurrentState = OpenerState.PrePull; + } + + return false; } } \ No newline at end of file diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index 69ef36c6a..04e9242d4 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -1,690 +1,748 @@ +using System.Linq; using Dalamud.Game.ClientState.JobGauge.Enums; using Dalamud.Game.ClientState.JobGauge.Types; -using System; -using System.Linq; +using Dalamud.Game.ClientState.Statuses; using XIVSlothCombo.Combos.JobHelpers; using XIVSlothCombo.Combos.PvE.Content; -using XIVSlothCombo.Core; using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.CustomComboNS.Functions; +using XIVSlothCombo.Data; using XIVSlothCombo.Extensions; +using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; + +namespace XIVSlothCombo.Combos.PvE; -namespace XIVSlothCombo.Combos.PvE +internal class MNK { - internal class MNK + public const byte ClassID = 2; + public const byte JobID = 20; + + public const uint + Bootshine = 53, + TrueStrike = 54, + SnapPunch = 56, + Meditation = 36940, + SteelPeak = 25761, + TwinSnakes = 61, + ArmOfTheDestroyer = 62, + Demolish = 66, + Mantra = 65, + DragonKick = 74, + Rockbreaker = 70, + Thunderclap = 25762, + HowlingFist = 25763, + FourPointFury = 16473, + PerfectBalance = 69, + FormShift = 4262, + TheForbiddenChakra = 3547, + MasterfulBlitz = 25764, + RiddleOfEarth = 7394, + EarthsReply = 36944, + RiddleOfFire = 7395, + Brotherhood = 7396, + RiddleOfWind = 25766, + EnlightenedMeditation = 36943, + Enlightenment = 16474, + SixSidedStar = 16476, + ShadowOfTheDestroyer = 25767, + RisingPhoenix = 25768, + WindsReply = 36949, + ForbiddenMeditation = 36942, + LeapingOpo = 36945, + RisingRaptor = 36946, + PouncingCoeurl = 36947, + TrueNorth = 7546, + ElixirBurst = 36948, + FiresReply = 36950; + + protected static MNKGauge Gauge => GetJobGauge(); + + protected static class Buffs { - public const byte ClassID = 2; - public const byte JobID = 20; - - public const uint - Bootshine = 53, - TrueStrike = 54, - SnapPunch = 56, - Meditation = 36940, - SteelPeak = 25761, - TwinSnakes = 61, - ArmOfTheDestroyer = 62, - Demolish = 66, - Mantra = 65, - DragonKick = 74, - Rockbreaker = 70, - Thunderclap = 25762, - HowlingFist = 25763, - FourPointFury = 16473, - PerfectBalance = 69, - FormShift = 4262, - TheForbiddenChakra = 3547, - MasterfulBlitz = 25764, - RiddleOfEarth = 7394, - EarthsReply = 36944, - RiddleOfFire = 7395, - Brotherhood = 7396, - RiddleOfWind = 25766, - EnlightenedMeditation = 36943, - Enlightenment = 16474, - SixSidedStar = 16476, - ShadowOfTheDestroyer = 25767, - RisingPhoenix = 25768, - WindsReply = 36949, - ForbiddenMeditation = 36942, - LeapingOpo = 36945, - RisingRaptor = 36946, - PouncingCoeurl = 36947, - TrueNorth = 7546, - ElixirBurst = 36948, - FiresReply = 36950; - - public static class Buffs - { - public const ushort - TwinSnakes = 101, - OpoOpoForm = 107, - RaptorForm = 108, - CoeurlForm = 109, - PerfectBalance = 110, - RiddleOfFire = 1181, - RiddleOfWind = 2687, - FormlessFist = 2513, - TrueNorth = 1250, - WindsRumination = 3842, - FiresRumination = 3843, - Brotherhood = 1185; - } + public const ushort + TwinSnakes = 101, + OpoOpoForm = 107, + RaptorForm = 108, + CoeurlForm = 109, + PerfectBalance = 110, + RiddleOfFire = 1181, + RiddleOfWind = 2687, + FormlessFist = 2513, + TrueNorth = 1250, + WindsRumination = 3842, + FiresRumination = 3843, + Brotherhood = 1185; + } - public static MNKGauge Gauge => CustomComboFunctions.GetJobGauge(); + 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"); + } - 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_SelectedOpener = new("MNK_SelectedOpener"), - MNK_VariantCure = new("MNK_Variant_Cure"); - } + internal class MNK_ST_SimpleMode : CustomCombo + { + internal static MNKOpenerLogic MNKOpener = new(); - internal class MNK_ST_SimpleMode : CustomCombo + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_SimpleMode; + + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_SimpleMode; - internal static MNKOpenerLogic MNKOpener = new(); - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + bool bothNadisOpen = Gauge.Nadi.ToString() == "LUNAR, SOLAR"; + bool solarNadi = Gauge.Nadi == Nadi.SOLAR; + bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; + int opoOpoChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.OPOOPO); + int raptorChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.RAPTOR); + int coeurlChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.COEURL); + + if (actionID is Bootshine or LeapingOpo) { - bool canWeave = CanWeave(actionID, 0.5); - bool inCombat = HasCondition(Dalamud.Game.ClientState.Conditions.ConditionFlag.InCombat); - bool bothNadisOpen = Gauge.Nadi.ToString() == "LUNAR, SOLAR"; - - if (actionID is Bootshine or LeapingOpo) + if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) + return actionID; + + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; + + if ((!InCombat() || !InMeleeRange()) && + Gauge.Chakra < 5 && + HasEffect(Buffs.RiddleOfFire) && + LevelChecked(Meditation)) + return OriginalHook(Meditation); + + // OGCDs + if (CanWeave(ActionWatching.LastWeaponskill)) { - if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) - return actionID; + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (ActionReady(PerfectBalance) && !HasEffect(Buffs.PerfectBalance) && + (((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && + GetCooldownRemainingTime(RiddleOfFire) < 8 && + GetCooldownRemainingTime(Brotherhood) < 7) || + (GetBuffRemainingTime(Buffs.RiddleOfFire) >= 8 && + !HasEffect(Buffs.FiresRumination)))) + return PerfectBalance; + + if (ActionReady(Brotherhood)) + return Brotherhood; + + if (ActionReady(RiddleOfFire)) + return RiddleOfFire; + + if (ActionReady(RiddleOfWind)) + return RiddleOfWind; + + if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + return All.SecondWind; + + if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) + return All.Bloodbath; + + if (Gauge.Chakra >= 5 && + SteelPeak.LevelChecked()) + return OriginalHook(SteelPeak); + } + + // GCDs + // Ensure usage if buff is almost depleted. + if (HasEffect(Buffs.FiresRumination) && + GetBuffRemainingTime(Buffs.FiresRumination) < 4) + return FiresReply; + if (HasEffect(Buffs.WindsRumination) && + GetBuffRemainingTime(Buffs.WindsRumination) < 4) + return WindsReply; - if (IsEnabled(Variant.VariantCure) && - PlayerHealthPercentageHp() <= Config.MNK_VariantCure) - return Variant.VariantCure; + if (HasEffect(Buffs.FormlessFist)) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); - if ((!inCombat || !InMeleeRange()) - && Gauge.Chakra < 5 - && !HasEffect(Buffs.RiddleOfFire) - && LevelChecked(Meditation)) + // Masterful Blitz + if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && + HasEffect(Buffs.RiddleOfFire) && !IsOriginal(MasterfulBlitz)) + return OriginalHook(MasterfulBlitz); + + // Perfect Balance + if (HasEffect(Buffs.PerfectBalance)) + { + #region Open Solar + + if (!solarNadi && !bothNadisOpen) { - return OriginalHook(Meditation); + if (coeurlChakra == 0) + return Gauge.CoeurlFury == 0 + ? OriginalHook(Demolish) + : OriginalHook(SnapPunch); + + if (raptorChakra == 0) + return Gauge.RaptorFury == 0 + ? OriginalHook(TwinSnakes) + : OriginalHook(TrueStrike); + + if (opoOpoChakra == 0) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); } - // OGCDs - if (canWeave) - { - if (IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; + #endregion - if (ActionReady(PerfectBalance) && !HasEffect(Buffs.PerfectBalance)) - { - if ((WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick)) - && (GetCooldownRemainingTime(RiddleOfFire) < 8 - && GetCooldownRemainingTime(Brotherhood) < 7) || - (GetBuffRemainingTime(Buffs.RiddleOfFire) >= 8 - && !HasEffect(Buffs.FiresRumination))) - { - return PerfectBalance; - } - } + #region Open Lunar - if (ActionReady(Brotherhood)) - { - return Brotherhood; - } + if (solarNadi || lunarNadi || bothNadisOpen) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); - if (ActionReady(RiddleOfFire)) - { - return RiddleOfFire; - } + #endregion + } - if (ActionReady(RiddleOfWind)) - { - return RiddleOfWind; - } + if (HasEffect(Buffs.WindsRumination)) + return WindsReply; - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) - return All.SecondWind; - if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) - return All.Bloodbath; + if (HasEffect(Buffs.FiresRumination) && + !HasEffect(Buffs.PerfectBalance) && + !HasEffect(Buffs.FormlessFist) && + (JustUsed(LeapingOpo) || JustUsed(DragonKick))) + return FiresReply; - if (Gauge.Chakra >= 5 - && SteelPeak.LevelChecked()) - { - return OriginalHook(SteelPeak); - } - } + // Standard Beast Chakras + return MNKHelper.DetermineCoreAbility(actionID); + } - // GCDs + return actionID; + } + } + + internal class MNK_ST_AdvancedMode : CustomCombo + { + internal static MNKOpenerLogic MNKOpener = new(); + + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_AdvancedMode; + + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + { + bool bothNadisOpen = Gauge.Nadi.ToString() == "LUNAR, SOLAR"; + bool solarNadi = Gauge.Nadi == Nadi.SOLAR; + bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; + int opoOpoChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.OPOOPO); + int raptorChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.RAPTOR); + int coeurlChakra = Gauge.BeastChakra.Count(x => x == BeastChakra.COEURL); + + if (actionID is Bootshine or LeapingOpo) + { + if (IsEnabled(CustomComboPreset.MNK_STUseOpener)) + if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) + return actionID; - // Ensure usage if buff is almost depleted. - if (HasEffect(Buffs.FiresRumination) && GetBuffRemainingTime(Buffs.FiresRumination) < 4) + if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) && + (!InCombat() || !InMeleeRange()) && + Gauge.Chakra < 5 && + !HasEffect(Buffs.RiddleOfFire) && + LevelChecked(Meditation)) + return OriginalHook(Meditation); + + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; + + // OGCDs + if (CanWeave(ActionWatching.LastWeaponskill)) + { + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance) && + ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) { - return FiresReply; + if ((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && + GetCooldownRemainingTime(RiddleOfFire) < 7 && + GetCooldownRemainingTime(Brotherhood) < 7) + return PerfectBalance; + + if ((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && + HasEffect(Buffs.RiddleOfFire) && + GetBuffRemainingTime(Buffs.RiddleOfFire) > 8 && + !HasEffect(Buffs.FiresRumination)) + return PerfectBalance; } - if (HasEffect(Buffs.WindsRumination) && GetBuffRemainingTime(Buffs.WindsRumination) < 4) + if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) { - return WindsReply; + if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) && + ActionReady(Brotherhood)) + return Brotherhood; + + if (IsEnabled(CustomComboPreset.MNK_STUseROF) && + ActionReady(RiddleOfFire)) + return RiddleOfFire; + + if (IsEnabled(CustomComboPreset.MNK_STUseROW) && + ActionReady(RiddleOfWind)) + return RiddleOfWind; } - if (HasEffect(Buffs.FormlessFist)) + if (IsEnabled(CustomComboPreset.MNK_ST_ComboHeals)) { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); + if (PlayerHealthPercentageHp() <= Config.MNK_ST_SecondWind_Threshold && + ActionReady(All.SecondWind)) + return All.SecondWind; + + if (PlayerHealthPercentageHp() <= Config.MNK_ST_Bloodbath_Threshold && + ActionReady(All.Bloodbath)) + return All.Bloodbath; } + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + Gauge.Chakra >= 5 && + LevelChecked(SteelPeak)) + return OriginalHook(Meditation); + } + + // GCDs + // Ensure usage if buff is almost depleted. + if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && + HasEffect(Buffs.FiresRumination) && + GetBuffRemainingTime(Buffs.FiresRumination) < 4) + return FiresReply; + + if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && + HasEffect(Buffs.WindsRumination) && + GetBuffRemainingTime(Buffs.WindsRumination) < 4) + return WindsReply; + + if (HasEffect(Buffs.FormlessFist)) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); + + if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance)) + { // Masterful Blitz - if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && HasEffect(Buffs.RiddleOfFire) && !IsOriginal(MasterfulBlitz)) - { + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && + HasEffect(Buffs.RiddleOfFire) && + OriginalHook(MasterfulBlitz) != MasterfulBlitz) return OriginalHook(MasterfulBlitz); - } // Perfect Balance if (HasEffect(Buffs.PerfectBalance)) { - bool solarNadi = Gauge.Nadi == Nadi.SOLAR; - bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; - int opoOpoChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.OPOOPO).Count(); - int raptorChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.RAPTOR).Count(); - int coeurlChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.COEURL).Count(); - #region Open Solar + if (!solarNadi && !bothNadisOpen) { if (coeurlChakra == 0) - { - return Gauge.CoeurlFury == 0 ? OriginalHook(Demolish) : OriginalHook(SnapPunch); - } - else if (raptorChakra == 0) - { - return Gauge.RaptorFury == 0 ? OriginalHook(TwinSnakes) : OriginalHook(TrueStrike); - } - else if (opoOpoChakra == 0) - { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } + return Gauge.CoeurlFury == 0 + ? OriginalHook(Demolish) + : OriginalHook(SnapPunch); + + if (raptorChakra == 0) + return Gauge.RaptorFury == 0 + ? OriginalHook(TwinSnakes) + : OriginalHook(TrueStrike); + + if (opoOpoChakra == 0) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); } + #endregion + #region Open Lunar - if (solarNadi || lunarNadi || bothNadisOpen) - { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } - #endregion - } - if (HasEffect(Buffs.WindsRumination)) - { - return WindsReply; - } + if (solarNadi || lunarNadi || bothNadisOpen) + return Gauge.OpoOpoFury == 0 + ? OriginalHook(DragonKick) + : OriginalHook(Bootshine); - if (HasEffect(Buffs.FiresRumination) - && !HasEffect(Buffs.PerfectBalance) - && !HasEffect(Buffs.FormlessFist) - && (WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick))) - { - return FiresReply; + #endregion } - - // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID); - } - return actionID; + if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && + HasEffect(Buffs.WindsRumination) && + LevelChecked(WindsReply)) + return WindsReply; + + if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && + HasEffect(Buffs.FiresRumination) && + !HasEffect(Buffs.PerfectBalance) && + !HasEffect(Buffs.FormlessFist) && + (JustUsed(LeapingOpo) || JustUsed(DragonKick)) && + LevelChecked(FiresReply)) + return FiresReply; + + // Standard Beast Chakras + return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); } + + return actionID; } + } + + internal class MNK_AOE_SimpleMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_AOE_SimpleMode; - internal class MNK_ST_AdvancedMode : CustomCombo + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_AdvancedMode; - internal static MNKOpenerLogic MNKOpener = new(); - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + Status? pbStacks = FindEffectAny(Buffs.PerfectBalance); + bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; + bool nadiNone = Gauge.Nadi == Nadi.NONE; + + if (actionID is ArmOfTheDestroyer or ShadowOfTheDestroyer) { - bool canWeave = CanWeave(actionID, 0.5); - bool inCombat = HasCondition(Dalamud.Game.ClientState.Conditions.ConditionFlag.InCombat); - bool bothNadisOpen = Gauge.Nadi.ToString() == "LUNAR, SOLAR"; + if (!InCombat() && Gauge.Chakra < 5 && LevelChecked(Meditation)) + return OriginalHook(Meditation); - if (actionID is Bootshine or LeapingOpo) - { - if (IsEnabled(CustomComboPreset.MNK_STUseOpener)) - { - if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) - return actionID; - } + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; - if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) - && (!inCombat || !InMeleeRange()) - && Gauge.Chakra < 5 - && !HasEffect(Buffs.RiddleOfFire) - && LevelChecked(Meditation)) + // Buffs + if (CanWeave(ActionWatching.LastWeaponskill)) + { + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (ActionReady(RiddleOfFire)) + return RiddleOfFire; + + if (LevelChecked(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance) && + IsOriginal(MasterfulBlitz)) { - return OriginalHook(Meditation); + // Use Perfect Balance if: + // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE + // 2. At max stacks / before overcap. + // 3. During Brotherhood. + // 4. During Riddle of Fire. + // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. + if ((HasCharges(PerfectBalance) && + GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)) || + GetCooldownRemainingTime(PerfectBalance) <= 4 || + HasEffect(Buffs.Brotherhood) || + (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || + (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) + return PerfectBalance; } - if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && IsEnabled(Variant.VariantCure) && PlayerHealthPercentageHp() <= GetOptionValue(Config.MNK_VariantCure)) - return Variant.VariantCure; + if (ActionReady(Brotherhood)) + return Brotherhood; - // OGCDs - if (inCombat && canWeave) - { - if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && - IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; + if (ActionReady(RiddleOfWind)) + return RiddleOfWind; - if (PerfectBalance.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && HasCharges(PerfectBalance) && IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance)) - { - if ((WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick)) - && GetCooldownRemainingTime(RiddleOfFire) < 7 - && GetCooldownRemainingTime(Brotherhood) < 7) - { - return PerfectBalance; - } - else if ((WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick)) - && HasEffect(Buffs.RiddleOfFire) - && GetBuffRemainingTime(Buffs.RiddleOfFire) > 8 - && !HasEffect(Buffs.FiresRumination)) - { - return PerfectBalance; - } - } + if (Gauge.Chakra >= 5 && + LevelChecked(HowlingFist) && + HasBattleTarget()) + return OriginalHook(HowlingFist); - if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) - { - if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) - && Brotherhood.LevelChecked() - && !IsOnCooldown(Brotherhood)) - { - return Brotherhood; - } - - if (IsEnabled(CustomComboPreset.MNK_STUseROF) - && RiddleOfFire.LevelChecked() - && !IsOnCooldown(RiddleOfFire)) - { - return RiddleOfFire; - } + if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + return All.SecondWind; - if (IsEnabled(CustomComboPreset.MNK_STUseROW) - && RiddleOfWind.LevelChecked() - && !IsOnCooldown(RiddleOfWind)) - { - return RiddleOfWind; - } - } + if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) + return All.Bloodbath; + } - if (PlayerHealthPercentageHp() <= PluginConfiguration.GetCustomIntValue(Config.MNK_ST_SecondWind_Threshold) && IsEnabled(CustomComboPreset.MNK_ST_ComboHeals) && LevelChecked(All.SecondWind) && IsOffCooldown(All.SecondWind)) - return All.SecondWind; - if (PlayerHealthPercentageHp() <= PluginConfiguration.GetCustomIntValue(Config.MNK_ST_Bloodbath_Threshold) && IsEnabled(CustomComboPreset.MNK_ST_ComboHeals) && LevelChecked(All.Bloodbath) && IsOffCooldown(All.Bloodbath)) - return All.Bloodbath; + if (HasEffect(Buffs.WindsRumination)) + return WindsReply; - if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && SteelPeak.LevelChecked()) - { - return OriginalHook(Meditation); - } - } + if (HasEffect(Buffs.FiresRumination)) + return FiresReply; - // GCDs - if (inCombat) - { - // Ensure usage if buff is almost depleted. - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) - && HasEffect(Buffs.FiresRumination) - && GetBuffRemainingTime(Buffs.FiresRumination) < 4) - { - return FiresReply; - } + // Masterful Blitz + if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && + OriginalHook(MasterfulBlitz) != MasterfulBlitz) + return OriginalHook(MasterfulBlitz); - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) - && HasEffect(Buffs.WindsRumination) - && GetBuffRemainingTime(Buffs.WindsRumination) < 4) - { - return WindsReply; - } + // Perfect Balance + if (HasEffect(Buffs.PerfectBalance)) + { + if (nadiNone || !lunarNadi) + if (pbStacks?.StackCount > 0) + return ShadowOfTheDestroyer.LevelChecked() + ? ShadowOfTheDestroyer + : Rockbreaker; - if (HasEffect(Buffs.FormlessFist)) + if (lunarNadi) + switch (pbStacks?.StackCount) { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } + case 3: + return OriginalHook(ArmOfTheDestroyer); - if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance)) - { - // Masterful Blitz - if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && HasEffect(Buffs.RiddleOfFire) && OriginalHook(MasterfulBlitz) != MasterfulBlitz) - { - return OriginalHook(MasterfulBlitz); - } + case 2: + return FourPointFury; - // Perfect Balance - if (HasEffect(Buffs.PerfectBalance)) - { - bool solarNadi = Gauge.Nadi == Nadi.SOLAR; - bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; - int opoOpoChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.OPOOPO).Count(); - int raptorChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.RAPTOR).Count(); - int coeurlChakra = Gauge.BeastChakra.Where(x => x == BeastChakra.COEURL).Count(); - - #region Open Solar - if (!solarNadi && !bothNadisOpen) - { - if (coeurlChakra == 0) - { - return Gauge.CoeurlFury == 0 ? OriginalHook(Demolish) : OriginalHook(SnapPunch); - } - else if (raptorChakra == 0) - { - return Gauge.RaptorFury == 0 ? OriginalHook(TwinSnakes) : OriginalHook(TrueStrike); - } - else if (opoOpoChakra == 0) - { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } - } - #endregion - #region Open Lunar - if (solarNadi || lunarNadi || bothNadisOpen) - { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } - #endregion - } + case 1: + return Rockbreaker; } + } - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) - && HasEffect(Buffs.WindsRumination) - && WindsReply.LevelChecked()) - { - return WindsReply; - } + // Monk Rotation + if (HasEffect(Buffs.OpoOpoForm)) + return OriginalHook(ArmOfTheDestroyer); - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) - && HasEffect(Buffs.FiresRumination) - && !HasEffect(Buffs.PerfectBalance) - && !HasEffect(Buffs.FormlessFist) - && (WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick)) - && FiresReply.LevelChecked()) - { - return FiresReply; - } + if (HasEffect(Buffs.RaptorForm)) + { + if (LevelChecked(FourPointFury)) + return FourPointFury; - // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); - } + if (LevelChecked(TwinSnakes)) + return TwinSnakes; } - return actionID; + if (HasEffect(Buffs.CoeurlForm) && LevelChecked(Rockbreaker)) + return Rockbreaker; } + + return actionID; } + } - internal class MNK_AoE_SimpleMode : CustomCombo + internal class MNK_AOE_AdvancedMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_AOE_AdvancedMode; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_AOE_SimpleMode; + Status? pbStacks = FindEffectAny(Buffs.PerfectBalance); + bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; + bool nadiNone = Gauge.Nadi == Nadi.NONE; - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + if (actionID is ArmOfTheDestroyer or ShadowOfTheDestroyer) { - if (actionID is ArmOfTheDestroyer or ShadowOfTheDestroyer) + if (IsEnabled(CustomComboPreset.MNK_AoEUseMeditation) && + !InCombat() && Gauge.Chakra < 5 && LevelChecked(Meditation)) + return OriginalHook(Meditation); + + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; + + // Buffs + if (CanWeave(ActionWatching.LastWeaponskill)) { - bool inCombat = HasCondition(Dalamud.Game.ClientState.Conditions.ConditionFlag.InCombat); - MNKGauge gauge = GetJobGauge(); - bool canWeave = CanWeave(actionID, 0.5); - _ = CanWeave(actionID); - Dalamud.Game.ClientState.Statuses.Status? pbStacks = FindEffectAny(Buffs.PerfectBalance); - bool lunarNadi = gauge.Nadi == Nadi.LUNAR; - bool nadiNONE = gauge.Nadi == Nadi.NONE; - - if (!inCombat) + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (IsEnabled(CustomComboPreset.MNK_AoEUseROF) && + ActionReady(RiddleOfFire)) + return RiddleOfFire; + + if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance) && + LevelChecked(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance) && + IsOriginal(MasterfulBlitz)) { - if (gauge.Chakra < 5 && Meditation.LevelChecked()) - { - return OriginalHook(Meditation); ; - } + // Use Perfect Balance if: + // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE + // 2. At max stacks / before overcap. + // 3. During Brotherhood. + // 4. During Riddle of Fire. + // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. + if ((HasCharges(PerfectBalance) && + GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)) || + GetCooldownRemainingTime(PerfectBalance) <= 4 || + HasEffect(Buffs.Brotherhood) || + (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || + (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) + return PerfectBalance; } + if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && + ActionReady(Brotherhood)) + return Brotherhood; - if (IsEnabled(Variant.VariantCure) && PlayerHealthPercentageHp() <= GetOptionValue(Config.MNK_VariantCure)) - return Variant.VariantCure; + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && + ActionReady(RiddleOfWind)) + return RiddleOfWind; - // Buffs - if (inCombat && canWeave) - { - - if (IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; + if (IsEnabled(CustomComboPreset.MNK_AoEUseHowlingFist) && + Gauge.Chakra >= 5 && + LevelChecked(HowlingFist) && + HasBattleTarget()) + return OriginalHook(HowlingFist); - if (ActionReady(RiddleOfFire)) - { - return RiddleOfFire; - } - - if (PerfectBalance.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && IsOriginal(MasterfulBlitz)) - { - // Use Perfect Balance if: - // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE - // 2. At max stacks / before overcap. - // 3. During Brotherhood. - // 4. During Riddle of Fire. - // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. - if (HasCharges(PerfectBalance) && - (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)) || - (GetCooldownRemainingTime(PerfectBalance) <= 4) || - (HasEffect(Buffs.Brotherhood)) || - (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || - (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) - { - return PerfectBalance; - } - } - - if (ActionReady(Brotherhood)) - { - return Brotherhood; - } - - if (ActionReady(RiddleOfWind)) - { - return RiddleOfWind; - } - - if (Gauge.Chakra >= 5 - && HowlingFist.LevelChecked() - && HasBattleTarget()) - { - return OriginalHook(HowlingFist); - } - - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + if (IsEnabled(CustomComboPreset.MNK_AoE_ComboHeals)) + { + if (PlayerHealthPercentageHp() <= Config.MNK_AoE_SecondWind_Threshold && + ActionReady(All.SecondWind)) return All.SecondWind; - if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) + + if (PlayerHealthPercentageHp() <= Config.MNK_AoE_Bloodbath_Threshold && + ActionReady(All.Bloodbath)) return All.Bloodbath; } + } - if (inCombat) - { - if (HasEffect(Buffs.WindsRumination)) - { - return WindsReply; - } + if (IsEnabled(CustomComboPreset.MNK_AoEUseWindsReply) && + HasEffect(Buffs.WindsRumination)) + return WindsReply; - if (HasEffect(Buffs.FiresRumination)) - { - return FiresReply; - } + if (IsEnabled(CustomComboPreset.MNK_AoEUseFiresReply) && + HasEffect(Buffs.FiresRumination)) + return FiresReply; - // Masterful Blitz - if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && OriginalHook(MasterfulBlitz) != MasterfulBlitz) - { - return OriginalHook(MasterfulBlitz); - } + // Masterful Blitz + if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance)) + { + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && + OriginalHook(MasterfulBlitz) != MasterfulBlitz) + return OriginalHook(MasterfulBlitz); - // Perfect Balance - if (HasEffect(Buffs.PerfectBalance)) - { - if (nadiNONE || !lunarNadi) - { - if (pbStacks?.StackCount > 0) - { - return ShadowOfTheDestroyer.LevelChecked() ? ShadowOfTheDestroyer : Rockbreaker; - } - } - if (lunarNadi) + // Perfect Balance + if (HasEffect(Buffs.PerfectBalance)) + { + if (nadiNone || !lunarNadi) + if (pbStacks?.StackCount > 0) + return ShadowOfTheDestroyer.LevelChecked() + ? ShadowOfTheDestroyer + : Rockbreaker; + + if (lunarNadi) + switch (pbStacks?.StackCount) { - switch (pbStacks?.StackCount) - { - case 3: - return OriginalHook(ArmOfTheDestroyer); - case 2: - return FourPointFury; - case 1: - return Rockbreaker; - } - } - } + case 3: + return OriginalHook(ArmOfTheDestroyer); - // Monk Rotation - if (HasEffect(Buffs.OpoOpoForm)) - { - return OriginalHook(ArmOfTheDestroyer); - } - - if (HasEffect(Buffs.RaptorForm)) - { - if (FourPointFury.LevelChecked()) - return FourPointFury; - - if (TwinSnakes.LevelChecked()) - return TwinSnakes; - } + case 2: + return FourPointFury; - if (HasEffect(Buffs.CoeurlForm) && Rockbreaker.LevelChecked()) - { - return Rockbreaker; - } + case 1: + return Rockbreaker; + } } } - return actionID; - } - } - #region Beast Chakras - internal class MNK_BeastChakra_OpoOpo : CustomCombo - { - protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; + // Monk Rotation + if (HasEffect(Buffs.OpoOpoForm)) + return OriginalHook(ArmOfTheDestroyer); - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) - { - if (IsEnabled(CustomComboPreset.MNK_BC_OPOOPO)) + if (HasEffect(Buffs.RaptorForm)) { - if (actionID is Bootshine or LeapingOpo) - { - if (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance)) - { - if (Gauge.OpoOpoFury == 0) - { - if (LevelChecked(DragonKick)) - return DragonKick; - } - else - { - return OriginalHook(Bootshine); - } - } - } + if (LevelChecked(FourPointFury)) + return FourPointFury; + + if (LevelChecked(TwinSnakes)) + return TwinSnakes; } - return actionID; + if (HasEffect(Buffs.CoeurlForm) && LevelChecked(Rockbreaker)) + return Rockbreaker; } + + return actionID; } + } - internal class MNK_BeastChakra_Raptor : CustomCombo - { - protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; + internal class MNK_PerfectBalance : CustomCombo + { + protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_PerfectBalance; - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) - { - if (IsEnabled(CustomComboPreset.MNK_BC_RAPTOR)) - { - if (actionID is TrueStrike or RisingRaptor) - { - if (HasEffect(Buffs.RaptorForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance)) - { - if (Gauge.RaptorFury == 0) - { - if (LevelChecked(TwinSnakes)) - return TwinSnakes; - } - else - { - return OriginalHook(TrueStrike); - } - } - } - } + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + { + if (actionID == PerfectBalance) + if (OriginalHook(MasterfulBlitz) != MasterfulBlitz && MasterfulBlitz.LevelChecked()) + return OriginalHook(MasterfulBlitz); - return actionID; - } + return actionID; } + } - internal class MNK_BeastChakra_Coeurl : CustomCombo + internal class MNK_Riddle_Brotherhood : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_Riddle_Brotherhood; + + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) { - protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; + return actionID is RiddleOfFire && ActionReady(Brotherhood) && IsOnCooldown(RiddleOfFire) + ? Brotherhood + : actionID; + } + } - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) - { - if (IsEnabled(CustomComboPreset.MNK_BC_COEURL)) - { - if (actionID is SnapPunch or PouncingCoeurl) - { - if (HasEffect(Buffs.CoeurlForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance)) - { - if (Gauge.CoeurlFury == 0) - { - if (LevelChecked(Demolish)) - return Demolish; - } - else - { - return OriginalHook(SnapPunch); - } - } - } - } + #region Beast Chakras - return actionID; - } - } - #endregion + internal class MNK_BeastChakra_OpoOpo : CustomCombo + { + protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; - internal class MNK_PerfectBalance : CustomCombo + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { - protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_PerfectBalance; + if (IsEnabled(CustomComboPreset.MNK_BC_OPOOPO) && + actionID is Bootshine or LeapingOpo && + (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) + return Gauge.OpoOpoFury == 0 && LevelChecked(DragonKick) + ? DragonKick + : OriginalHook(Bootshine); + + return actionID; + } + } - protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) - { - if (actionID == PerfectBalance) - { - if (OriginalHook(MasterfulBlitz) != MasterfulBlitz && MasterfulBlitz.LevelChecked()) - return OriginalHook(MasterfulBlitz); - } + internal class MNK_BeastChakra_Raptor : CustomCombo + { + protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; - return actionID; - } + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + { + if (IsEnabled(CustomComboPreset.MNK_BC_RAPTOR) && + actionID is TrueStrike or RisingRaptor && + (HasEffect(Buffs.RaptorForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) + return Gauge.RaptorFury == 0 && LevelChecked(TwinSnakes) + ? TwinSnakes + : OriginalHook(TrueStrike); + + return actionID; } + } - internal class MNK_Riddle_Brotherhood : CustomCombo - { - protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_Riddle_Brotherhood; + internal class MNK_BeastChakra_Coeurl : CustomCombo + { + protected internal override CustomComboPreset Preset => CustomComboPreset.MNK_ST_BeastChakras; - protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) - { - return actionID is RiddleOfFire && Brotherhood.LevelChecked() && IsOnCooldown(RiddleOfFire) && IsOffCooldown(Brotherhood) - ? Brotherhood - : actionID; - } + protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) + { + if (IsEnabled(CustomComboPreset.MNK_BC_COEURL) && + actionID is SnapPunch or PouncingCoeurl && + (HasEffect(Buffs.CoeurlForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) + return Gauge.CoeurlFury == 0 && LevelChecked(Demolish) + ? Demolish + : OriginalHook(SnapPunch); + + return actionID; } } + + #endregion } \ No newline at end of file diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index 956d6bd4e..43affc224 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1580,6 +1580,15 @@ internal static void Draw(CustomComboPreset preset, bool enabled) 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", 1); From 74ea6f6b50ff8df7d380160d3e9e03921ec869a5 Mon Sep 17 00:00:00 2001 From: Kage Date: Sun, 8 Sep 2024 19:02:27 +0200 Subject: [PATCH 04/17] revert MCH changes - different PR --- XIVSlothCombo/Combos/JobHelpers/MCH.cs | 58 ++--- XIVSlothCombo/Combos/PvE/MCH.cs | 340 ++++++++++++------------- 2 files changed, 179 insertions(+), 219 deletions(-) diff --git a/XIVSlothCombo/Combos/JobHelpers/MCH.cs b/XIVSlothCombo/Combos/JobHelpers/MCH.cs index 8d5528569..9304ba7a3 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MCH.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MCH.cs @@ -277,46 +277,28 @@ public static bool UseQueen(MCHGauge gauge) { int BSUsed = ActionWatching.CombatActions.Count(x => x == BarrelStabilizer); - if (!ActionWatching.HasDoubleWeaved() && !gauge.IsOverheated && !HasEffect(Buffs.Wildfire) && - !JustUsed(OriginalHook(Heatblast)) && LevelChecked(OriginalHook(RookAutoturret)) && - !gauge.IsRobotActive && gauge.Battery >= 50) + if (!ActionWatching.HasDoubleWeaved() && CanWeave(OriginalHook(SplitShot)) && + !gauge.IsOverheated && !HasEffect(Buffs.Wildfire) && !JustUsed(OriginalHook(Heatblast)) && + LevelChecked(OriginalHook(RookAutoturret)) && !gauge.IsRobotActive && gauge.Battery >= 50 && + ((LevelChecked(FullMetalField) && !JustUsed(FullMetalField)) || !LevelChecked(FullMetalField))) { - if (LevelChecked(FullMetalField)) - { - //1min - if (BSUsed == 1 & gauge.Battery >= 90) - return true; - - //even mins - if (BSUsed >= 2 && gauge.Battery == 100) - return true; - - //odd mins 1st queen - if (BSUsed >= 2 && gauge.Battery == 50 && - gauge.LastSummonBatteryPower == 100) - return true; - - //odd mins 2nd queen - if ((BSUsed is 2 or 5 or 8) && gauge.Battery >= 60 && - gauge.LastSummonBatteryPower == 50) - return true; - - //odd mins 2nd queen - if ((BSUsed is 3 or 6 or 9) && gauge.Battery >= 70 && - gauge.LastSummonBatteryPower == 50) - return true; - - //odd mins 2nd queen - if ((BSUsed is 4 or 7 or 10) && gauge.Battery >= 80 && - gauge.LastSummonBatteryPower == 50) - return true; - } + //1min + if (BSUsed == 1 & gauge.Battery >= 90) + return true; - if (!LevelChecked(FullMetalField)) - { - if (gauge.Battery == 100) - return true; - } + //even mins + if (BSUsed >= 2 && gauge.Battery >= 100) + return true; + + //odd mins 1st queen + if (BSUsed >= 2 && gauge.Battery >= 50 && + GetCooldownRemainingTime(BarrelStabilizer) is >= 30 and <= 65) + return true; + + //odd mins 2nd queen + if (BSUsed >= 2 && gauge.Battery >= 60 && + GetCooldownRemainingTime(BarrelStabilizer) is >= 10 and <= 30) + return true; if (!LevelChecked(BarrelStabilizer)) return true; diff --git a/XIVSlothCombo/Combos/PvE/MCH.cs b/XIVSlothCombo/Combos/PvE/MCH.cs index ed69436e7..cc29a8ddd 100644 --- a/XIVSlothCombo/Combos/PvE/MCH.cs +++ b/XIVSlothCombo/Combos/PvE/MCH.cs @@ -1,6 +1,5 @@ using Dalamud.Game.ClientState.JobGauge.Types; using ECommons.DalamudServices; -using System.Linq; using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.CustomComboNS.Functions; @@ -109,13 +108,12 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim bool anchorCD = !LevelChecked(AirAnchor) || (LevelChecked(AirAnchor) && GetCooldownRemainingTime(AirAnchor) > heatblastRC * 6); bool sawCD = !LevelChecked(Chainsaw) || (LevelChecked(Chainsaw) && GetCooldownRemainingTime(Chainsaw) > heatblastRC * 6); float GCD = GetCooldown(OriginalHook(SplitShot)).CooldownTotal; - int BSUsed = ActionWatching.CombatActions.Count(x => x == BarrelStabilizer); if (actionID is SplitShot or HeatedSplitShot) { if (IsEnabled(CustomComboPreset.MCH_Variant_Cure) && - IsEnabled(Variant.VariantCure) && - PlayerHealthPercentageHp() <= Config.MCH_VariantCure) + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MCH_VariantCure) return Variant.VariantCure; if (IsEnabled(CustomComboPreset.MCH_Variant_Rampart) && @@ -124,7 +122,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim CanWeave(actionID)) return Variant.VariantRampart; - // Opener + // Opener for MCH if (MCHOpener.DoFullOpener(ref actionID)) return actionID; @@ -132,95 +130,77 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (interruptReady) return All.HeadGraze; - // All weaves - if (CanWeave(ActionWatching.LastWeaponskill) && - !ActionWatching.HasDoubleWeaved()) - { - // Wildfire - if (JustUsed(Hypercharge) && ActionReady(Wildfire)) - return Wildfire; - - // BarrelStabilizer - if (!gauge.IsOverheated && ActionReady(BarrelStabilizer)) - return BarrelStabilizer; - - // Hypercharge - if ((gauge.Heat >= 50 || HasEffect(Buffs.Hypercharged)) && !MCHExtensions.IsComboExpiring(6) && - LevelChecked(Hypercharge) && !gauge.IsOverheated) - { - // Ensures Hypercharge is double weaved with WF - if ((LevelChecked(FullMetalField) && JustUsed(FullMetalField) && (GetCooldownRemainingTime(Wildfire) < GCD || ActionReady(Wildfire))) || - ((!LevelChecked(FullMetalField)) && ActionReady(Wildfire)) || - !LevelChecked(Wildfire)) - return Hypercharge; - - // Only Hypercharge when tools are on cooldown - if (drillCD && anchorCD && sawCD && - ((GetCooldownRemainingTime(Wildfire) > 40 && LevelChecked(Wildfire)) || !LevelChecked(Wildfire))) - return Hypercharge; - } - - //Queen - if (MCHExtensions.UseQueen(gauge) && - GetCooldownRemainingTime(Wildfire) > GCD) - return OriginalHook(RookAutoturret); + // Wildfire + if (JustUsed(Hypercharge) && CanWeave(actionID) && ActionReady(Wildfire)) + return Wildfire; - // Gauss Round and Ricochet during HC - if (JustUsed(OriginalHook(Heatblast)) && - (ActionWatching.GetAttackType(ActionWatching.LastAction) != ActionWatching.ActionAttackType.Ability)) - { - if (ActionReady(OriginalHook(GaussRound)) && - GetRemainingCharges(OriginalHook(GaussRound)) >= GetRemainingCharges(OriginalHook(Ricochet))) - return OriginalHook(GaussRound); - - if (ActionReady(OriginalHook(Ricochet)) && - GetRemainingCharges(OriginalHook(Ricochet)) > GetRemainingCharges(OriginalHook(GaussRound))) - return OriginalHook(Ricochet); - } - - // Gauss Round and Ricochet outside HC - if (!gauge.IsOverheated && - (JustUsed(OriginalHook(AirAnchor)) || JustUsed(Chainsaw) || - JustUsed(Drill) || JustUsed(Excavator))) - { - if (ActionReady(OriginalHook(GaussRound)) && !JustUsed(OriginalHook(GaussRound))) - return OriginalHook(GaussRound); - - if (ActionReady(OriginalHook(Ricochet)) && !JustUsed(OriginalHook(Ricochet))) - return OriginalHook(Ricochet); - } - - // Healing - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind) && !gauge.IsOverheated) - return All.SecondWind; + // BarrelStabilizer + if (!gauge.IsOverheated && CanWeave(actionID) && ActionReady(BarrelStabilizer)) + return BarrelStabilizer; + + if (CanWeave(actionID) && (gauge.Heat >= 50 || HasEffect(Buffs.Hypercharged)) && + LevelChecked(Hypercharge) && !gauge.IsOverheated && !MCHExtensions.IsComboExpiring(6)) + { + //Protection & ensures Hyper charged is double weaved with WF during reopener + if ((LevelChecked(FullMetalField) && JustUsed(FullMetalField) && (GetCooldownRemainingTime(Wildfire) < GCD || ActionReady(Wildfire))) || + ((!LevelChecked(FullMetalField)) && ActionReady(Wildfire)) || + !LevelChecked(Wildfire)) + return Hypercharge; + + if (drillCD && anchorCD && sawCD && + ((GetCooldownRemainingTime(Wildfire) > 40 && LevelChecked(Wildfire)) || !LevelChecked(Wildfire))) + return Hypercharge; } - // Full Metal Field + //Full Metal Field if (HasEffect(Buffs.FullMetalMachinist) && (GetCooldownRemainingTime(Wildfire) <= GCD || ActionReady(Wildfire) || GetBuffRemainingTime(Buffs.FullMetalMachinist) <= 6) && LevelChecked(FullMetalField)) - return FullMetalField; + return OriginalHook(BarrelStabilizer); + + //Heatblast, Gauss, Rico + if (CanWeave(actionID) && JustUsed(OriginalHook(Heatblast)) && + (ActionWatching.GetAttackType(ActionWatching.LastAction) != ActionWatching.ActionAttackType.Ability)) + { + if (ActionReady(OriginalHook(GaussRound)) && + GetRemainingCharges(OriginalHook(GaussRound)) >= GetRemainingCharges(OriginalHook(Ricochet))) + return OriginalHook(GaussRound); + + if (ActionReady(OriginalHook(Ricochet)) && + GetRemainingCharges(OriginalHook(Ricochet)) > GetRemainingCharges(OriginalHook(GaussRound))) + return OriginalHook(Ricochet); + } - // Heatblast if (gauge.IsOverheated && LevelChecked(OriginalHook(Heatblast))) return OriginalHook(Heatblast); - // Reassemble and Tools - if (ReassembledTools(ref actionID, gauge)) + //Queen + if (MCHExtensions.UseQueen(gauge) && + GetCooldownRemainingTime(Wildfire) > GCD) + return OriginalHook(RookAutoturret); + + //gauss and ricochet outside HC + if (CanWeave(actionID) && !gauge.IsOverheated && + (JustUsed(OriginalHook(AirAnchor)) || JustUsed(Chainsaw) || + JustUsed(Drill) || JustUsed(Excavator)) && + !ActionWatching.HasDoubleWeaved()) + { + if (ActionReady(OriginalHook(GaussRound)) && !JustUsed(OriginalHook(GaussRound))) + return OriginalHook(GaussRound); + + if (ActionReady(OriginalHook(Ricochet)) && !JustUsed(OriginalHook(Ricochet))) + return OriginalHook(Ricochet); + } + + if (ReassembledTools(ref actionID, gauge) && !gauge.IsOverheated) return actionID; - // Excavator - if (LevelChecked(Excavator) && - HasEffect(Buffs.ExcavatorReady) && - ((BSUsed is 1) || - ((BSUsed is 2 or 5 or 8) && gauge.Battery <= 40) || - ((BSUsed is 3 or 6 or 9) && gauge.Battery <= 50) || - ((BSUsed is 4 or 7 or 10) && gauge.Battery <= 60) || - (GetBuffRemainingTime(Buffs.ExcavatorReady) < 6))) - return OriginalHook(Chainsaw); + // healing + if (CanWeave(actionID) && PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + return All.SecondWind; - // 1-2-3 Combo + //1-2-3 Combo if (comboTime > 0) { if (lastComboMove is SplitShot && LevelChecked(OriginalHook(SlugShot))) @@ -242,9 +222,10 @@ private static bool ReassembledTools(ref uint actionID, MCHGauge gauge) { bool battery = Svc.Gauges.Get().Battery >= 100; + // TOOLS!! Chainsaw Drill Air Anchor Excavator if (!gauge.IsOverheated && !JustUsed(OriginalHook(Heatblast)) && !ActionWatching.HasDoubleWeaved() && - !HasEffect(Buffs.Reassembled) && ActionReady(Reassemble) && (CanWeave(ActionWatching.LastWeaponskill) || !InCombat()) & - ((LevelChecked(Excavator) && HasEffect(Buffs.ExcavatorReady) && !battery && gauge.IsRobotActive && GetCooldownRemainingTime(Wildfire) > 3) || + !HasEffect(Buffs.Reassembled) && ActionReady(Reassemble) && (CanWeave(actionID) || !InCombat()) & + ((LevelChecked(Excavator) && HasEffect(Buffs.ExcavatorReady) && !battery) || (LevelChecked(Chainsaw) && !LevelChecked(Excavator) && ((GetCooldownRemainingTime(Chainsaw) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Chainsaw)) && !battery) || (LevelChecked(AirAnchor) && ((GetCooldownRemainingTime(AirAnchor) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(AirAnchor)) && !battery) || (LevelChecked(Drill) && !LevelChecked(AirAnchor) && ((GetCooldownRemainingTime(Drill) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Drill))))) @@ -253,6 +234,14 @@ private static bool ReassembledTools(ref uint actionID, MCHGauge gauge) return true; } + if (LevelChecked(OriginalHook(Chainsaw)) && + !battery && + HasEffect(Buffs.ExcavatorReady)) + { + actionID = OriginalHook(Chainsaw); + return true; + } + if (LevelChecked(Chainsaw) && !battery && ((GetCooldownRemainingTime(Chainsaw) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Chainsaw))) @@ -295,8 +284,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim bool anchorCD = !LevelChecked(AirAnchor) || (LevelChecked(AirAnchor) && GetCooldownRemainingTime(AirAnchor) > heatblastRC * 6); bool sawCD = !LevelChecked(Chainsaw) || (LevelChecked(Chainsaw) && GetCooldownRemainingTime(Chainsaw) > heatblastRC * 6); float GCD = GetCooldown(OriginalHook(SplitShot)).CooldownTotal; - bool reassembledExcavator = (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && Config.MCH_ST_Reassembled[0] && (HasEffect(Buffs.Reassembled) || !HasEffect(Buffs.Reassembled))) || (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !Config.MCH_ST_Reassembled[0] && !HasEffect(Buffs.Reassembled)) || (!HasEffect(Buffs.Reassembled) && GetRemainingCharges(Reassemble) <= Config.MCH_ST_ReassemblePool) || (!IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble)); - int BSUsed = ActionWatching.CombatActions.Count(x => x == BarrelStabilizer); if (actionID is SplitShot or HeatedSplitShot) { @@ -311,7 +298,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim CanWeave(actionID)) return Variant.VariantRampart; - // Opener + // Opener for MCH if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Opener)) { if (MCHOpener.DoFullOpener(ref actionID)) @@ -322,112 +309,92 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Interrupt) && interruptReady) return All.HeadGraze; - // All weaves - if (CanWeave(ActionWatching.LastWeaponskill) && - !ActionWatching.HasDoubleWeaved()) - { - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_QueenOverdrive) && - gauge.IsRobotActive && GetTargetHPPercent() <= Config.MCH_ST_QueenOverDrive && - ActionReady(OriginalHook(RookOverdrive))) - return OriginalHook(RookOverdrive); - - // Wildfire - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_WildFire) && - JustUsed(Hypercharge) && ActionReady(Wildfire) && - GetTargetHPPercent() >= Config.MCH_ST_WildfireHP) - return Wildfire; - - // BarrelStabilizer - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Stabilizer) && - !gauge.IsOverheated && ActionReady(BarrelStabilizer)) - return BarrelStabilizer; - - // Hypercharge - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Hypercharge) && - (gauge.Heat >= 50 || HasEffect(Buffs.Hypercharged)) && !MCHExtensions.IsComboExpiring(6) && - LevelChecked(Hypercharge) && !gauge.IsOverheated && GetTargetHPPercent() >= Config.MCH_ST_HyperchargeHP) - { - // Ensures Hypercharge is double weaved with WF - if ((LevelChecked(FullMetalField) && JustUsed(FullMetalField) && (GetCooldownRemainingTime(Wildfire) < GCD || ActionReady(Wildfire))) || - ((!LevelChecked(FullMetalField)) && ActionReady(Wildfire)) || - !LevelChecked(Wildfire)) - return Hypercharge; - - // Only Hypercharge when tools are on cooldown - if (drillCD && anchorCD && sawCD && - ((GetCooldownRemainingTime(Wildfire) > 40 && LevelChecked(Wildfire)) || !LevelChecked(Wildfire))) - return Hypercharge; - } - - // Queen - if (IsEnabled(CustomComboPreset.MCH_Adv_TurretQueen) && - MCHExtensions.UseQueen(gauge) && - GetCooldownRemainingTime(Wildfire) > GCD) - return OriginalHook(RookAutoturret); + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_QueenOverdrive) && + gauge.IsRobotActive && GetTargetHPPercent() <= Config.MCH_ST_QueenOverDrive && + CanWeave(actionID) && ActionReady(OriginalHook(RookOverdrive))) + return OriginalHook(RookOverdrive); - // Gauss Round and Ricochet during HC - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_GaussRicochet) && - JustUsed(OriginalHook(Heatblast)) && - (ActionWatching.GetAttackType(ActionWatching.LastAction) != ActionWatching.ActionAttackType.Ability)) - { - if (ActionReady(OriginalHook(GaussRound)) && - GetRemainingCharges(OriginalHook(GaussRound)) >= GetRemainingCharges(OriginalHook(Ricochet))) - return OriginalHook(GaussRound); - - if (ActionReady(OriginalHook(Ricochet)) && - GetRemainingCharges(OriginalHook(Ricochet)) > GetRemainingCharges(OriginalHook(GaussRound))) - return OriginalHook(Ricochet); - } - - // Gauss Round and Ricochet outside HC - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_GaussRicochet) && - !gauge.IsOverheated && - (JustUsed(OriginalHook(AirAnchor)) || JustUsed(Chainsaw) || - JustUsed(Drill) || JustUsed(Excavator))) - { - if (ActionReady(OriginalHook(GaussRound)) && !JustUsed(OriginalHook(GaussRound))) - return OriginalHook(GaussRound); - - if (ActionReady(OriginalHook(Ricochet)) && !JustUsed(OriginalHook(Ricochet))) - return OriginalHook(Ricochet); - } - - // Healing - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_SecondWind) && - PlayerHealthPercentageHp() <= Config.MCH_ST_SecondWindThreshold && ActionReady(All.SecondWind) && !gauge.IsOverheated) - return All.SecondWind; + // Wildfire + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_WildFire) && + JustUsed(Hypercharge) && CanWeave(actionID) && ActionReady(Wildfire) && + GetTargetHPPercent() >= Config.MCH_ST_WildfireHP) + return Wildfire; + + // BarrelStabilizer + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Stabilizer) && + !gauge.IsOverheated && CanWeave(actionID) && ActionReady(BarrelStabilizer)) + return BarrelStabilizer; + + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Hypercharge) && + CanWeave(actionID) && (gauge.Heat >= 50 || HasEffect(Buffs.Hypercharged)) && !MCHExtensions.IsComboExpiring(6) && + LevelChecked(Hypercharge) && !gauge.IsOverheated && GetTargetHPPercent() >= Config.MCH_ST_HyperchargeHP) + { + //Protection & ensures Hyper charged is double weaved with WF during reopener + if ((LevelChecked(FullMetalField) && JustUsed(FullMetalField) && (GetCooldownRemainingTime(Wildfire) < GCD || ActionReady(Wildfire))) || + ((!LevelChecked(FullMetalField)) && ActionReady(Wildfire)) || + !LevelChecked(Wildfire)) + return Hypercharge; + + if (drillCD && anchorCD && sawCD && + ((GetCooldownRemainingTime(Wildfire) > 40 && LevelChecked(Wildfire)) || !LevelChecked(Wildfire))) + return Hypercharge; } - // Full Metal Field + //Full Metal Field if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Stabilizer_FullMetalField) && HasEffect(Buffs.FullMetalMachinist) && (GetCooldownRemainingTime(Wildfire) <= GCD || ActionReady(Wildfire) || GetBuffRemainingTime(Buffs.FullMetalMachinist) <= 6) && LevelChecked(FullMetalField)) - return FullMetalField; + return OriginalHook(BarrelStabilizer); + + //Heatblast, Gauss, Rico + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_GaussRicochet) && + CanWeave(actionID) && JustUsed(OriginalHook(Heatblast)) && + (ActionWatching.GetAttackType(ActionWatching.LastAction) != ActionWatching.ActionAttackType.Ability)) + { + if (ActionReady(OriginalHook(GaussRound)) && + GetRemainingCharges(OriginalHook(GaussRound)) >= GetRemainingCharges(OriginalHook(Ricochet))) + return OriginalHook(GaussRound); + + if (ActionReady(OriginalHook(Ricochet)) && + GetRemainingCharges(OriginalHook(Ricochet)) > GetRemainingCharges(OriginalHook(GaussRound))) + return OriginalHook(Ricochet); + } - // Heatblast if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Heatblast) && gauge.IsOverheated && LevelChecked(OriginalHook(Heatblast))) return OriginalHook(Heatblast); - // Reassemble and Tools - if (ReassembledTools(ref actionID, gauge)) + //Queen + if (IsEnabled(CustomComboPreset.MCH_Adv_TurretQueen) && + MCHExtensions.UseQueen(gauge) && + GetCooldownRemainingTime(Wildfire) > GCD) + return OriginalHook(RookAutoturret); + + //gauss and ricochet outside HC + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_GaussRicochet) && + CanWeave(actionID) && !gauge.IsOverheated && + (JustUsed(OriginalHook(AirAnchor)) || JustUsed(Chainsaw) || + JustUsed(Drill) || JustUsed(Excavator)) && + !ActionWatching.HasDoubleWeaved()) + { + if (ActionReady(OriginalHook(GaussRound)) && !JustUsed(OriginalHook(GaussRound))) + return OriginalHook(GaussRound); + + if (ActionReady(OriginalHook(Ricochet)) && !JustUsed(OriginalHook(Ricochet))) + return OriginalHook(Ricochet); + } + + if (ReassembledTools(ref actionID, gauge) && !gauge.IsOverheated) return actionID; - // Excavator - if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Excavator) && - reassembledExcavator && - LevelChecked(Excavator) && - HasEffect(Buffs.ExcavatorReady) && - ((BSUsed is 1) || - ((BSUsed is 2 or 5 or 8) && gauge.Battery <= 40) || - ((BSUsed is 3 or 6 or 9) && gauge.Battery <= 50) || - ((BSUsed is 4 or 7 or 10) && gauge.Battery <= 60) || - (GetBuffRemainingTime(Buffs.ExcavatorReady) < 6))) - return OriginalHook(Chainsaw); + // healing + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_SecondWind) && + CanWeave(actionID) && PlayerHealthPercentageHp() <= Config.MCH_ST_SecondWindThreshold && ActionReady(All.SecondWind)) + return All.SecondWind; - // 1-2-3 Combo + //1-2-3 Combo if (comboTime > 0) { if (lastComboMove is SplitShot && LevelChecked(OriginalHook(SlugShot))) @@ -448,15 +415,17 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim private static bool ReassembledTools(ref uint actionID, MCHGauge gauge) { bool battery = Svc.Gauges.Get().Battery >= 100; + bool reassembledExcavator = (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && Config.MCH_ST_Reassembled[0] && (HasEffect(Buffs.Reassembled) || !HasEffect(Buffs.Reassembled))) || (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !Config.MCH_ST_Reassembled[0] && !HasEffect(Buffs.Reassembled)) || (!HasEffect(Buffs.Reassembled) && GetRemainingCharges(Reassemble) <= Config.MCH_ST_ReassemblePool) || (!IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble)); bool reassembledChainsaw = (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && Config.MCH_ST_Reassembled[1] && (HasEffect(Buffs.Reassembled) || !HasEffect(Buffs.Reassembled))) || (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !Config.MCH_ST_Reassembled[1] && !HasEffect(Buffs.Reassembled)) || (!HasEffect(Buffs.Reassembled) && GetRemainingCharges(Reassemble) <= Config.MCH_ST_ReassemblePool) || (!IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble)); bool reassembledAnchor = (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && Config.MCH_ST_Reassembled[2] && (HasEffect(Buffs.Reassembled) || !HasEffect(Buffs.Reassembled))) || (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !Config.MCH_ST_Reassembled[2] && !HasEffect(Buffs.Reassembled)) || (!HasEffect(Buffs.Reassembled) && GetRemainingCharges(Reassemble) <= Config.MCH_ST_ReassemblePool) || (!IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble)); bool reassembledDrill = (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && Config.MCH_ST_Reassembled[3] && (HasEffect(Buffs.Reassembled) || !HasEffect(Buffs.Reassembled))) || (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !Config.MCH_ST_Reassembled[3] && !HasEffect(Buffs.Reassembled)) || (!HasEffect(Buffs.Reassembled) && GetRemainingCharges(Reassemble) <= Config.MCH_ST_ReassemblePool) || (!IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble)); + // TOOLS!! Chainsaw Drill Air Anchor Excavator if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Reassemble) && !gauge.IsOverheated && !JustUsed(OriginalHook(Heatblast)) && !ActionWatching.HasDoubleWeaved() && - !HasEffect(Buffs.Reassembled) && ActionReady(Reassemble) && (CanWeave(ActionWatching.LastWeaponskill) || !InCombat()) && + !HasEffect(Buffs.Reassembled) && ActionReady(Reassemble) && (CanWeave(actionID) || !InCombat()) && GetRemainingCharges(Reassemble) > Config.MCH_ST_ReassemblePool && - ((Config.MCH_ST_Reassembled[0] && LevelChecked(Excavator) && HasEffect(Buffs.ExcavatorReady) && !battery && gauge.IsRobotActive && GetCooldownRemainingTime(Wildfire) > 3) || + ((Config.MCH_ST_Reassembled[0] && LevelChecked(Excavator) && HasEffect(Buffs.ExcavatorReady) && !battery) || (Config.MCH_ST_Reassembled[1] && LevelChecked(Chainsaw) && (!LevelChecked(Excavator) || !Config.MCH_ST_Reassembled[0]) && ((GetCooldownRemainingTime(Chainsaw) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Chainsaw)) && !battery) || (Config.MCH_ST_Reassembled[2] && LevelChecked(AirAnchor) && ((GetCooldownRemainingTime(AirAnchor) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(AirAnchor)) && !battery) || (Config.MCH_ST_Reassembled[3] && LevelChecked(Drill) && (!LevelChecked(AirAnchor) || !Config.MCH_ST_Reassembled[2]) && ((GetCooldownRemainingTime(Drill) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Drill))))) @@ -465,6 +434,16 @@ private static bool ReassembledTools(ref uint actionID, MCHGauge gauge) return true; } + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Excavator) && + reassembledExcavator && + LevelChecked(OriginalHook(Chainsaw)) && + !battery && + HasEffect(Buffs.ExcavatorReady)) + { + actionID = OriginalHook(Chainsaw); + return true; + } + if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Chainsaw) && reassembledChainsaw && LevelChecked(Chainsaw) && @@ -488,8 +467,7 @@ private static bool ReassembledTools(ref uint actionID, MCHGauge gauge) if (IsEnabled(CustomComboPreset.MCH_ST_Adv_Drill) && reassembledDrill && LevelChecked(Drill) && - !JustUsed(Drill) && - ((GetCooldownRemainingTime(Drill) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Drill)) && + !JustUsed(Drill) && ((GetCooldownRemainingTime(Drill) <= GetCooldownRemainingTime(OriginalHook(SplitShot)) + 0.25) || ActionReady(Drill)) && GetCooldownRemainingTime(Wildfire) is >= 20 or <= 10) { actionID = Drill; @@ -527,7 +505,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim //Full Metal Field if (HasEffect(Buffs.FullMetalMachinist) && LevelChecked(FullMetalField)) - return FullMetalField; + return OriginalHook(BarrelStabilizer); // BarrelStabilizer if (!gauge.IsOverheated && CanWeave(actionID) && ActionReady(BarrelStabilizer)) @@ -617,7 +595,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim //Full Metal Field if (IsEnabled(CustomComboPreset.MCH_AoE_Adv_Stabilizer_FullMetalField) && HasEffect(Buffs.FullMetalMachinist) && LevelChecked(FullMetalField)) - return FullMetalField; + return OriginalHook(BarrelStabilizer); // BarrelStabilizer if (IsEnabled(CustomComboPreset.MCH_AoE_Adv_Stabilizer) && From 3380025171196629165791ca78cec7747b7d8d26 Mon Sep 17 00:00:00 2001 From: Kage Date: Sun, 8 Sep 2024 19:33:28 +0200 Subject: [PATCH 05/17] Masterfull blitz fix from @Akechi --- XIVSlothCombo/Combos/PvE/MNK.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index 04e9242d4..8f3d5fb08 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -170,8 +170,9 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb : OriginalHook(Bootshine); // Masterful Blitz - if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && - HasEffect(Buffs.RiddleOfFire) && !IsOriginal(MasterfulBlitz)) + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && + (HasEffect(Buffs.RiddleOfFire) || GetCooldownRemainingTime(RiddleOfFire) > 35) && + !IsOriginal(MasterfulBlitz)) return OriginalHook(MasterfulBlitz); // Perfect Balance @@ -338,8 +339,8 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb { // Masterful Blitz if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && - HasEffect(Buffs.RiddleOfFire) && - OriginalHook(MasterfulBlitz) != MasterfulBlitz) + (HasEffect(Buffs.RiddleOfFire) || GetCooldownRemainingTime(RiddleOfFire) > 35) && + !IsOriginal(MasterfulBlitz)) return OriginalHook(MasterfulBlitz); // Perfect Balance From f01ce391f3fd84c40c606224466d9f1a22fde713 Mon Sep 17 00:00:00 2001 From: Kage Date: Mon, 9 Sep 2024 12:53:28 +0200 Subject: [PATCH 06/17] rework ST for lower lvls PB optimizations Masterful Blitz optimization remove obselete code --- XIVSlothCombo/Combos/JobHelpers/MNK.cs | 15 +- XIVSlothCombo/Combos/PvE/MNK.cs | 207 +++++++++++-------- XIVSlothCombo/Window/Functions/UserConfig.cs | 15 +- 3 files changed, 132 insertions(+), 105 deletions(-) diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index a74cf5810..3e3b45ea7 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -9,7 +9,7 @@ namespace XIVSlothCombo.Combos.JobHelpers; internal abstract class MNKHelper : MNK { - public static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled = true) + public static uint DetermineCoreAbility(uint actionId, bool useTrueNorthIfEnabled) { if (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist)) return Gauge.OpoOpoFury == 0 && LevelChecked(DragonKick) @@ -381,18 +381,13 @@ public bool DoFullOpener(ref uint actionID, int selectedOpener) return true; if (CurrentState == OpenerState.InOpener) - { - if (selectedOpener == 1) - { - if (DoLlOpener(ref actionID)) - return true; - } - else if (selectedOpener == 2) + switch (selectedOpener) { - if (DoSlOpener(ref actionID)) + case 0 when DoLlOpener(ref actionID): + + case 1 when DoSlOpener(ref actionID): return true; } - } if (!InCombat()) { diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index 8f3d5fb08..a2e63d392 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -102,21 +102,24 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (actionID is Bootshine or LeapingOpo) { - if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) + if (MNKOpener.DoFullOpener(ref actionID, 0)) return actionID; + if ((!InCombat() || !InMeleeRange()) && + Gauge.Chakra < 5 && + !HasEffect(Buffs.RiddleOfFire) && + LevelChecked(Meditation)) + return OriginalHook(Meditation); + + if (!InCombat() && !HasEffect(Buffs.FormlessFist)) + return FormShift; + //Variant Cure if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && IsEnabled(Variant.VariantCure) && PlayerHealthPercentageHp() <= Config.MNK_VariantCure) return Variant.VariantCure; - if ((!InCombat() || !InMeleeRange()) && - Gauge.Chakra < 5 && - HasEffect(Buffs.RiddleOfFire) && - LevelChecked(Meditation)) - return OriginalHook(Meditation); - // OGCDs if (CanWeave(ActionWatching.LastWeaponskill)) { @@ -126,52 +129,64 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - if (ActionReady(PerfectBalance) && !HasEffect(Buffs.PerfectBalance) && - (((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && - GetCooldownRemainingTime(RiddleOfFire) < 8 && - GetCooldownRemainingTime(Brotherhood) < 7) || - (GetBuffRemainingTime(Buffs.RiddleOfFire) >= 8 && - !HasEffect(Buffs.FiresRumination)))) - return PerfectBalance; - - if (ActionReady(Brotherhood)) + if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) && + ActionReady(Brotherhood)) return Brotherhood; - if (ActionReady(RiddleOfFire)) + if (IsEnabled(CustomComboPreset.MNK_STUseROF) && + ActionReady(RiddleOfFire)) return RiddleOfFire; - if (ActionReady(RiddleOfWind)) + if (IsEnabled(CustomComboPreset.MNK_STUseROW) && + ActionReady(RiddleOfWind)) return RiddleOfWind; - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + //Perfect Balance + if (ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) + { + // Odd window + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + !JustUsed(PerfectBalance, 20) && + HasEffect(Buffs.RiddleOfFire) && + !HasEffect(Buffs.Brotherhood)) + return PerfectBalance; + + // Even window + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + HasEffect(Buffs.Brotherhood) && + HasEffect(Buffs.RiddleOfFire)) + return PerfectBalance; + + // Low level + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + ((HasEffect(Buffs.RiddleOfFire) && !LevelChecked(Brotherhood)) || + !LevelChecked(RiddleOfFire))) + return PerfectBalance; + } + + if (PlayerHealthPercentageHp() <= 25 && + ActionReady(All.SecondWind)) return All.SecondWind; - if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) + if (PlayerHealthPercentageHp() <= 40 && + ActionReady(All.Bloodbath)) return All.Bloodbath; if (Gauge.Chakra >= 5 && - SteelPeak.LevelChecked()) - return OriginalHook(SteelPeak); + LevelChecked(SteelPeak)) + return OriginalHook(Meditation); } // GCDs - // Ensure usage if buff is almost depleted. - if (HasEffect(Buffs.FiresRumination) && - GetBuffRemainingTime(Buffs.FiresRumination) < 4) - return FiresReply; - - if (HasEffect(Buffs.WindsRumination) && - GetBuffRemainingTime(Buffs.WindsRumination) < 4) - return WindsReply; - if (HasEffect(Buffs.FormlessFist)) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); // Masterful Blitz - if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && - (HasEffect(Buffs.RiddleOfFire) || GetCooldownRemainingTime(RiddleOfFire) > 35) && + if (LevelChecked(MasterfulBlitz) && + !HasEffect(Buffs.PerfectBalance) && !IsOriginal(MasterfulBlitz)) return OriginalHook(MasterfulBlitz); @@ -184,17 +199,17 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb { if (coeurlChakra == 0) return Gauge.CoeurlFury == 0 - ? OriginalHook(Demolish) + ? Demolish : OriginalHook(SnapPunch); if (raptorChakra == 0) return Gauge.RaptorFury == 0 - ? OriginalHook(TwinSnakes) + ? TwinSnakes : OriginalHook(TrueStrike); if (opoOpoChakra == 0) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); } @@ -204,23 +219,28 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (solarNadi || lunarNadi || bothNadisOpen) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); #endregion } - if (HasEffect(Buffs.WindsRumination)) - return WindsReply; - if (HasEffect(Buffs.FiresRumination) && !HasEffect(Buffs.PerfectBalance) && !HasEffect(Buffs.FormlessFist) && - (JustUsed(LeapingOpo) || JustUsed(DragonKick))) + (JustUsed(OriginalHook(Bootshine)) || + JustUsed(DragonKick) || + GetBuffRemainingTime(Buffs.FiresRumination) < 4)) return FiresReply; + if (HasEffect(Buffs.WindsRumination) && + LevelChecked(WindsReply) && + (HasEffect(Buffs.RiddleOfFire) || + GetBuffRemainingTime(Buffs.WindsRumination) < 4)) + return WindsReply; + // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID); + return MNKHelper.DetermineCoreAbility(actionID, true); } return actionID; @@ -245,8 +265,10 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (actionID is Bootshine or LeapingOpo) { if (IsEnabled(CustomComboPreset.MNK_STUseOpener)) + { if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) return actionID; + } if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) && (!InCombat() || !InMeleeRange()) && @@ -255,6 +277,10 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb LevelChecked(Meditation)) return OriginalHook(Meditation); + if (IsEnabled(CustomComboPreset.MNK_STUseFormShift) && + !InCombat() && !HasEffect(Buffs.FormlessFist)) + return FormShift; + //Variant Cure if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && IsEnabled(Variant.VariantCure) && @@ -270,22 +296,6 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance) && - ActionReady(PerfectBalance) && - !HasEffect(Buffs.PerfectBalance)) - { - if ((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && - GetCooldownRemainingTime(RiddleOfFire) < 7 && - GetCooldownRemainingTime(Brotherhood) < 7) - return PerfectBalance; - - if ((JustUsed(LeapingOpo) || JustUsed(DragonKick)) && - HasEffect(Buffs.RiddleOfFire) && - GetBuffRemainingTime(Buffs.RiddleOfFire) > 8 && - !HasEffect(Buffs.FiresRumination)) - return PerfectBalance; - } - if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) { if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) && @@ -301,6 +311,31 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb return RiddleOfWind; } + //Perfect Balance + if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance) && + ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) + { + // Odd window + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + !JustUsed(PerfectBalance, 20) && + HasEffect(Buffs.RiddleOfFire) && + !HasEffect(Buffs.Brotherhood)) + return PerfectBalance; + + // Even window + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + HasEffect(Buffs.Brotherhood) && + HasEffect(Buffs.RiddleOfFire)) + return PerfectBalance; + + // Low level + if ((JustUsed(OriginalHook(Bootshine)) || JustUsed(DragonKick)) && + ((HasEffect(Buffs.RiddleOfFire) && !LevelChecked(Brotherhood)) || + !LevelChecked(RiddleOfFire))) + return PerfectBalance; + } + if (IsEnabled(CustomComboPreset.MNK_ST_ComboHeals)) { if (PlayerHealthPercentageHp() <= Config.MNK_ST_SecondWind_Threshold && @@ -319,27 +354,16 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } // GCDs - // Ensure usage if buff is almost depleted. - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && - HasEffect(Buffs.FiresRumination) && - GetBuffRemainingTime(Buffs.FiresRumination) < 4) - return FiresReply; - - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && - HasEffect(Buffs.WindsRumination) && - GetBuffRemainingTime(Buffs.WindsRumination) < 4) - return WindsReply; - if (HasEffect(Buffs.FormlessFist)) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance)) { // Masterful Blitz - if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && - (HasEffect(Buffs.RiddleOfFire) || GetCooldownRemainingTime(RiddleOfFire) > 35) && + if (LevelChecked(MasterfulBlitz) && + !HasEffect(Buffs.PerfectBalance) && !IsOriginal(MasterfulBlitz)) return OriginalHook(MasterfulBlitz); @@ -352,17 +376,17 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb { if (coeurlChakra == 0) return Gauge.CoeurlFury == 0 - ? OriginalHook(Demolish) + ? Demolish : OriginalHook(SnapPunch); if (raptorChakra == 0) return Gauge.RaptorFury == 0 - ? OriginalHook(TwinSnakes) + ? TwinSnakes : OriginalHook(TrueStrike); if (opoOpoChakra == 0) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); } @@ -372,26 +396,29 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (solarNadi || lunarNadi || bothNadisOpen) return Gauge.OpoOpoFury == 0 - ? OriginalHook(DragonKick) + ? DragonKick : OriginalHook(Bootshine); #endregion } } - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && - HasEffect(Buffs.WindsRumination) && - LevelChecked(WindsReply)) - return WindsReply; - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && HasEffect(Buffs.FiresRumination) && !HasEffect(Buffs.PerfectBalance) && !HasEffect(Buffs.FormlessFist) && - (JustUsed(LeapingOpo) || JustUsed(DragonKick)) && - LevelChecked(FiresReply)) + (JustUsed(OriginalHook(Bootshine)) || + JustUsed(DragonKick) || + GetBuffRemainingTime(Buffs.FiresRumination) < 4)) return FiresReply; + if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && + HasEffect(Buffs.WindsRumination) && + LevelChecked(WindsReply) && + (HasEffect(Buffs.RiddleOfFire) || + GetBuffRemainingTime(Buffs.WindsRumination) < 4)) + return WindsReply; + // Standard Beast Chakras return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); } @@ -436,7 +463,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (LevelChecked(PerfectBalance) && !HasEffect(Buffs.PerfectBalance) && IsOriginal(MasterfulBlitz)) - { + // Use Perfect Balance if: // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE // 2. At max stacks / before overcap. @@ -450,7 +477,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - } if (ActionReady(Brotherhood)) return Brotherhood; @@ -564,7 +590,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim LevelChecked(PerfectBalance) && !HasEffect(Buffs.PerfectBalance) && IsOriginal(MasterfulBlitz)) - { + // Use Perfect Balance if: // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE // 2. At max stacks / before overcap. @@ -578,7 +604,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - } if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && ActionReady(Brotherhood)) @@ -701,7 +726,7 @@ internal class MNK_BeastChakra_OpoOpo : CustomCombo protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { if (IsEnabled(CustomComboPreset.MNK_BC_OPOOPO) && - actionID is Bootshine or LeapingOpo && + actionID is Bootshine or LeapingOpo && (HasEffect(Buffs.OpoOpoForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) return Gauge.OpoOpoFury == 0 && LevelChecked(DragonKick) ? DragonKick @@ -718,7 +743,7 @@ internal class MNK_BeastChakra_Raptor : CustomCombo protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { if (IsEnabled(CustomComboPreset.MNK_BC_RAPTOR) && - actionID is TrueStrike or RisingRaptor && + actionID is TrueStrike or RisingRaptor && (HasEffect(Buffs.RaptorForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) return Gauge.RaptorFury == 0 && LevelChecked(TwinSnakes) ? TwinSnakes @@ -735,7 +760,7 @@ internal class MNK_BeastChakra_Coeurl : CustomCombo protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { if (IsEnabled(CustomComboPreset.MNK_BC_COEURL) && - actionID is SnapPunch or PouncingCoeurl && + actionID is SnapPunch or PouncingCoeurl && (HasEffect(Buffs.CoeurlForm) || HasEffect(Buffs.FormlessFist) || HasEffect(Buffs.PerfectBalance))) return Gauge.CoeurlFury == 0 && LevelChecked(Demolish) ? Demolish diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index 43affc224..1d9f01d9c 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1572,12 +1572,16 @@ internal static void Draw(CustomComboPreset preset, bool enabled) #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); + 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) @@ -1591,8 +1595,11 @@ internal static void Draw(CustomComboPreset preset, bool enabled) if (preset == CustomComboPreset.MNK_STUseOpener && enabled) { - UserConfig.DrawHorizontalRadioButton(MNK.Config.MNK_SelectedOpener, "Double Lunar", "Uses Lunar/Lunar opener", 1); - UserConfig.DrawHorizontalRadioButton(MNK.Config.MNK_SelectedOpener, "Solar Lunar", "Uses Solar/Lunar opener", 2); + 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) From f7262c3f41309b569de77dbd3ca3951753b450c6 Mon Sep 17 00:00:00 2001 From: Kage Date: Mon, 9 Sep 2024 13:07:30 +0200 Subject: [PATCH 07/17] update AoE --- XIVSlothCombo/Combos/PvE/MNK.cs | 59 ++++++++++++++------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index a2e63d392..97c886525 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -456,31 +456,23 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim IsEnabled(Variant.VariantRampart) && IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - + + if (ActionReady(Brotherhood)) + return Brotherhood; + if (ActionReady(RiddleOfFire)) return RiddleOfFire; - if (LevelChecked(PerfectBalance) && - !HasEffect(Buffs.PerfectBalance) && - IsOriginal(MasterfulBlitz)) - - // Use Perfect Balance if: - // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE - // 2. At max stacks / before overcap. - // 3. During Brotherhood. - // 4. During Riddle of Fire. - // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. - if ((HasCharges(PerfectBalance) && - GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)) || + if (ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) + + if (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance) || GetCooldownRemainingTime(PerfectBalance) <= 4 || HasEffect(Buffs.Brotherhood) || (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - - if (ActionReady(Brotherhood)) - return Brotherhood; - + if (ActionReady(RiddleOfWind)) return RiddleOfWind; @@ -503,7 +495,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return FiresReply; // Masterful Blitz - if (MasterfulBlitz.LevelChecked() && !HasEffect(Buffs.PerfectBalance) && + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && OriginalHook(MasterfulBlitz) != MasterfulBlitz) return OriginalHook(MasterfulBlitz); @@ -512,7 +504,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (nadiNone || !lunarNadi) if (pbStacks?.StackCount > 0) - return ShadowOfTheDestroyer.LevelChecked() + return LevelChecked(ShadowOfTheDestroyer) ? ShadowOfTheDestroyer : Rockbreaker; @@ -582,14 +574,17 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; + if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && + ActionReady(Brotherhood)) + return Brotherhood; + if (IsEnabled(CustomComboPreset.MNK_AoEUseROF) && ActionReady(RiddleOfFire)) return RiddleOfFire; if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance) && - LevelChecked(PerfectBalance) && - !HasEffect(Buffs.PerfectBalance) && - IsOriginal(MasterfulBlitz)) + ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) // Use Perfect Balance if: // 1. It's after Bootshine/Dragon Kick. - This doesn't apply to AoE @@ -597,18 +592,13 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim // 3. During Brotherhood. // 4. During Riddle of Fire. // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. - if ((HasCharges(PerfectBalance) && - GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)) || + if (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)|| GetCooldownRemainingTime(PerfectBalance) <= 4 || HasEffect(Buffs.Brotherhood) || (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - - if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && - ActionReady(Brotherhood)) - return Brotherhood; - + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && ActionReady(RiddleOfWind)) return RiddleOfWind; @@ -642,7 +632,8 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim // Masterful Blitz if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance)) { - if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && + if (LevelChecked(MasterfulBlitz) && + !HasEffect(Buffs.PerfectBalance) && OriginalHook(MasterfulBlitz) != MasterfulBlitz) return OriginalHook(MasterfulBlitz); @@ -651,7 +642,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (nadiNone || !lunarNadi) if (pbStacks?.StackCount > 0) - return ShadowOfTheDestroyer.LevelChecked() + return LevelChecked(ShadowOfTheDestroyer) ? ShadowOfTheDestroyer : Rockbreaker; @@ -697,9 +688,9 @@ internal class MNK_PerfectBalance : CustomCombo protected override uint Invoke(uint actionID, uint lastComboActionID, float comboTime, byte level) { - if (actionID == PerfectBalance) - if (OriginalHook(MasterfulBlitz) != MasterfulBlitz && MasterfulBlitz.LevelChecked()) - return OriginalHook(MasterfulBlitz); + if (actionID is PerfectBalance && + OriginalHook(MasterfulBlitz) != MasterfulBlitz && LevelChecked(MasterfulBlitz)) + return OriginalHook(MasterfulBlitz); return actionID; } From 063111f687cd5331c01e37e495356008f48d76c7 Mon Sep 17 00:00:00 2001 From: Kage Date: Mon, 9 Sep 2024 13:08:29 +0200 Subject: [PATCH 08/17] remove unused code --- XIVSlothCombo/Combos/PvE/MNK.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index 97c886525..c44eda054 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -7,7 +7,6 @@ using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; -using XIVSlothCombo.Extensions; using static XIVSlothCombo.CustomComboNS.Functions.CustomComboFunctions; namespace XIVSlothCombo.Combos.PvE; @@ -265,10 +264,8 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (actionID is Bootshine or LeapingOpo) { if (IsEnabled(CustomComboPreset.MNK_STUseOpener)) - { if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) return actionID; - } if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) && (!InCombat() || !InMeleeRange()) && @@ -456,23 +453,23 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim IsEnabled(Variant.VariantRampart) && IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - - if (ActionReady(Brotherhood)) + + if (ActionReady(Brotherhood)) return Brotherhood; - + if (ActionReady(RiddleOfFire)) return RiddleOfFire; if (ActionReady(PerfectBalance) && !HasEffect(Buffs.PerfectBalance)) - + if (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance) || GetCooldownRemainingTime(PerfectBalance) <= 4 || HasEffect(Buffs.Brotherhood) || (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - + if (ActionReady(RiddleOfWind)) return RiddleOfWind; @@ -592,13 +589,13 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim // 3. During Brotherhood. // 4. During Riddle of Fire. // 5. Prepare Masterful Blitz for the Riddle of Fire & Brotherhood window. - if (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance)|| + if (GetRemainingCharges(PerfectBalance) == GetMaxCharges(PerfectBalance) || GetCooldownRemainingTime(PerfectBalance) <= 4 || HasEffect(Buffs.Brotherhood) || (HasEffect(Buffs.RiddleOfFire) && GetBuffRemainingTime(Buffs.RiddleOfFire) < 10) || (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && ActionReady(RiddleOfWind)) return RiddleOfWind; @@ -632,7 +629,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim // Masterful Blitz if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance)) { - if (LevelChecked(MasterfulBlitz) && + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && OriginalHook(MasterfulBlitz) != MasterfulBlitz) return OriginalHook(MasterfulBlitz); From 2ca46121a8678fada9f9e30e72f9af8114ab843c Mon Sep 17 00:00:00 2001 From: Kage Date: Mon, 9 Sep 2024 13:52:48 +0200 Subject: [PATCH 09/17] link everything to correct options --- XIVSlothCombo/Combos/PvE/MNK.cs | 110 ++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index c44eda054..357698116 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -128,16 +128,14 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) && - ActionReady(Brotherhood)) + if (ActionReady(Brotherhood)) return Brotherhood; - if (IsEnabled(CustomComboPreset.MNK_STUseROF) && - ActionReady(RiddleOfFire)) + if (ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) return RiddleOfFire; - if (IsEnabled(CustomComboPreset.MNK_STUseROW) && - ActionReady(RiddleOfWind)) + if (ActionReady(RiddleOfWind)) return RiddleOfWind; //Perfect Balance @@ -284,6 +282,12 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb PlayerHealthPercentageHp() <= Config.MNK_VariantCure) return Variant.VariantCure; + if (IsEnabled(CustomComboPreset.MNK_STUseBuffs) && + IsEnabled(CustomComboPreset.MNK_STUseROF) && + ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; + // OGCDs if (CanWeave(ActionWatching.LastWeaponskill)) { @@ -299,10 +303,6 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb ActionReady(Brotherhood)) return Brotherhood; - if (IsEnabled(CustomComboPreset.MNK_STUseROF) && - ActionReady(RiddleOfFire)) - return RiddleOfFire; - if (IsEnabled(CustomComboPreset.MNK_STUseROW) && ActionReady(RiddleOfWind)) return RiddleOfWind; @@ -400,21 +400,26 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } } - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && - HasEffect(Buffs.FiresRumination) && - !HasEffect(Buffs.PerfectBalance) && - !HasEffect(Buffs.FormlessFist) && - (JustUsed(OriginalHook(Bootshine)) || - JustUsed(DragonKick) || - GetBuffRemainingTime(Buffs.FiresRumination) < 4)) - return FiresReply; - - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && - HasEffect(Buffs.WindsRumination) && - LevelChecked(WindsReply) && - (HasEffect(Buffs.RiddleOfFire) || - GetBuffRemainingTime(Buffs.WindsRumination) < 4)) - return WindsReply; + if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) + { + if (IsEnabled(CustomComboPreset.MNK_STUseROF) && + IsEnabled(CustomComboPreset.MNK_STUseFiresReply) && + HasEffect(Buffs.FiresRumination) && + !HasEffect(Buffs.PerfectBalance) && + !HasEffect(Buffs.FormlessFist) && + (JustUsed(OriginalHook(Bootshine)) || + JustUsed(DragonKick) || + GetBuffRemainingTime(Buffs.FiresRumination) < 4)) + return FiresReply; + + if (IsEnabled(CustomComboPreset.MNK_STUseROW) && + IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && + HasEffect(Buffs.WindsRumination) && + LevelChecked(WindsReply) && + (HasEffect(Buffs.RiddleOfFire) || + GetBuffRemainingTime(Buffs.WindsRumination) < 4)) + return WindsReply; + } // Standard Beast Chakras return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); @@ -445,6 +450,10 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim PlayerHealthPercentageHp() <= Config.MNK_VariantCure) return Variant.VariantCure; + if (ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; + // Buffs if (CanWeave(ActionWatching.LastWeaponskill)) { @@ -456,9 +465,9 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (ActionReady(Brotherhood)) return Brotherhood; - - if (ActionReady(RiddleOfFire)) - return RiddleOfFire; + + if (ActionReady(RiddleOfWind)) + return RiddleOfWind; if (ActionReady(PerfectBalance) && !HasEffect(Buffs.PerfectBalance)) @@ -470,9 +479,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - if (ActionReady(RiddleOfWind)) - return RiddleOfWind; - if (Gauge.Chakra >= 5 && LevelChecked(HowlingFist) && HasBattleTarget()) @@ -562,6 +568,12 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim PlayerHealthPercentageHp() <= Config.MNK_VariantCure) return Variant.VariantCure; + if (IsEnabled(CustomComboPreset.MNK_AoEUseBuffs) && + IsEnabled(CustomComboPreset.MNK_AoEUseROF) && + ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; + // Buffs if (CanWeave(ActionWatching.LastWeaponskill)) { @@ -571,13 +583,16 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim IsOffCooldown(Variant.VariantRampart)) return Variant.VariantRampart; - if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && - ActionReady(Brotherhood)) - return Brotherhood; + if (IsEnabled(CustomComboPreset.MNK_AoEUseBuffs)) + { + if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && + ActionReady(Brotherhood)) + return Brotherhood; - if (IsEnabled(CustomComboPreset.MNK_AoEUseROF) && - ActionReady(RiddleOfFire)) - return RiddleOfFire; + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && + ActionReady(RiddleOfWind)) + return RiddleOfWind; + } if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance) && ActionReady(PerfectBalance) && @@ -596,10 +611,6 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim (GetCooldownRemainingTime(RiddleOfFire) < 4 && GetCooldownRemainingTime(Brotherhood) < 8)) return PerfectBalance; - if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && - ActionReady(RiddleOfWind)) - return RiddleOfWind; - if (IsEnabled(CustomComboPreset.MNK_AoEUseHowlingFist) && Gauge.Chakra >= 5 && LevelChecked(HowlingFist) && @@ -618,13 +629,18 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim } } - if (IsEnabled(CustomComboPreset.MNK_AoEUseWindsReply) && - HasEffect(Buffs.WindsRumination)) - return WindsReply; + if (IsEnabled(CustomComboPreset.MNK_AoEUseBuffs)) + { + if (IsEnabled(CustomComboPreset.MNK_AoEUseROF) && + IsEnabled(CustomComboPreset.MNK_AoEUseFiresReply) && + HasEffect(Buffs.FiresRumination)) + return FiresReply; - if (IsEnabled(CustomComboPreset.MNK_AoEUseFiresReply) && - HasEffect(Buffs.FiresRumination)) - return FiresReply; + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && + IsEnabled(CustomComboPreset.MNK_AoEUseWindsReply) && + HasEffect(Buffs.WindsRumination)) + return WindsReply; + } // Masterful Blitz if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance)) From 395cbebf374cc600f6e931c7d86baad89f289dda Mon Sep 17 00:00:00 2001 From: Kage Date: Mon, 9 Sep 2024 15:36:38 +0200 Subject: [PATCH 10/17] add lvlcheck formshift --- XIVSlothCombo/Combos/PvE/MNK.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/MNK.cs b/XIVSlothCombo/Combos/PvE/MNK.cs index 357698116..229539948 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -110,7 +110,8 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb LevelChecked(Meditation)) return OriginalHook(Meditation); - if (!InCombat() && !HasEffect(Buffs.FormlessFist)) + if (!InCombat() && LevelChecked(FormShift) && + !HasEffect(Buffs.FormlessFist)) return FormShift; //Variant Cure @@ -273,7 +274,8 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb return OriginalHook(Meditation); if (IsEnabled(CustomComboPreset.MNK_STUseFormShift) && - !InCombat() && !HasEffect(Buffs.FormlessFist)) + !InCombat() && LevelChecked(FormShift) && + !HasEffect(Buffs.FormlessFist)) return FormShift; //Variant Cure From 307d726dbbdd6ac0cbb8bcfbd1ccd54893d934ae Mon Sep 17 00:00:00 2001 From: Kage Date: Wed, 11 Sep 2024 18:39:05 +0200 Subject: [PATCH 11/17] update opener --- XIVSlothCombo/Combos/JobHelpers/MNK.cs | 157 +++++++++++-------------- 1 file changed, 66 insertions(+), 91 deletions(-) diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index 3e3b45ea7..e830d05da 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -127,23 +127,14 @@ private bool DoPrePullSteps(ref uint actionID) 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; + if (Gauge.Chakra < 5 && PrePullStep == 1) PrePullStep++; + else if (PrePullStep == 1) actionID = Meditation; - return true; - } + if (!HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 2) PrePullStep++; + else if (PrePullStep == 2) actionID = FormShift; - if (WasLastAction(DragonKick) && PrePullStep == 1) CurrentState = OpenerState.InOpener; - else if (PrePullStep == 1) actionID = DragonKick; + if (WasLastAction(DragonKick) && PrePullStep == 3) CurrentState = OpenerState.InOpener; + else if (PrePullStep == 3) actionID = DragonKick; if (ActionWatching.CombatActions.Count > 2 && InCombat()) CurrentState = OpenerState.FailedOpener; @@ -163,42 +154,38 @@ private bool DoSlOpener(ref uint actionID) if (currentState == OpenerState.InOpener) { if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + CanWeave(ActionWatching.LastWeaponskill) && Gauge.Chakra >= 5 && - OpenerStep > 2) + OpenerStep > 9) { actionID = TheForbiddenChakra; return true; } - if ((WasLastAction(PerfectBalance) || - HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; else if (OpenerStep == 1) actionID = PerfectBalance; - if (WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TheForbiddenChakra; - - if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = TwinSnakes; + if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = TwinSnakes; - if (WasLastWeaponskill(Demolish) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Demolish; + if (WasLastWeaponskill(Demolish) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = Demolish; - if (WasLastAbility(Brotherhood) && HasEffect(Buffs.Brotherhood) && - OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Brotherhood; + if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Brotherhood; - if (WasLastAction(RiddleOfFire) && - HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = RiddleOfFire; - // Pot + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; - if (WasLastAction(RiddleOfWind) && - HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; else if (OpenerStep == 8) actionID = RiddleOfWind; if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; @@ -207,19 +194,17 @@ private bool DoSlOpener(ref uint actionID) if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; else if (OpenerStep == 10) actionID = DragonKick; - if ((WasLastWeaponskill(FiresReply) || - !HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = FiresReply; + if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = WindsReply; - if ((WasLastWeaponskill(WindsReply) || - !HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) 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) || - HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; else if (OpenerStep == 14) actionID = PerfectBalance; if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; @@ -234,19 +219,17 @@ private bool DoSlOpener(ref uint actionID) if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; else if (OpenerStep == 18) actionID = ElixirBurst; - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) - CurrentState = OpenerState.OpenerFinished; + 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 && - ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || - (OpenerStep is 6 && HasEffect(Buffs.RiddleOfFire)) || - (OpenerStep is 8 && HasEffect(Buffs.RiddleOfWind)) || - (OpenerStep is 5 && HasEffect(Buffs.Brotherhood) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3)) + 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; @@ -267,43 +250,39 @@ private bool DoLlOpener(ref uint actionID) if (currentState == OpenerState.InOpener) { - if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && OpenerStep > 2) + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + CanWeave(ActionWatching.LastWeaponskill) && + Gauge.Chakra >= 5 && + OpenerStep > 9) { actionID = TheForbiddenChakra; return true; } - if ((WasLastAction(PerfectBalance) || - HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; else if (OpenerStep == 1) actionID = PerfectBalance; - if (WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TheForbiddenChakra; - - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = LeapingOpo; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = LeapingOpo; - if (WasLastWeaponskill(DragonKick) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = DragonKick; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = DragonKick; - if (WasLastAbility(Brotherhood) && HasEffect(Buffs.Brotherhood) && - OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Brotherhood; + if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Brotherhood; - if (WasLastAction(RiddleOfFire) && - HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5) actionID = RiddleOfFire; - // Pot + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; - if (WasLastAction(RiddleOfWind) && - HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; else if (OpenerStep == 8) actionID = RiddleOfWind; if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; @@ -312,19 +291,17 @@ private bool DoLlOpener(ref uint actionID) if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; else if (OpenerStep == 10) actionID = DragonKick; - if ((WasLastWeaponskill(FiresReply) || - !HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = FiresReply; + if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = WindsReply; - if ((WasLastWeaponskill(WindsReply) || - !HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) 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) || - HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; else if (OpenerStep == 14) actionID = PerfectBalance; if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; @@ -339,19 +316,17 @@ private bool DoLlOpener(ref uint actionID) if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; else if (OpenerStep == 18) actionID = ElixirBurst; - if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) - CurrentState = OpenerState.OpenerFinished; + 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 && - ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) || - (OpenerStep is 6 && HasEffect(Buffs.RiddleOfFire)) || - (OpenerStep is 8 && HasEffect(Buffs.RiddleOfWind)) || - (OpenerStep is 5 && HasEffect(Buffs.Brotherhood) - && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3)) + 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; From b668f1bfd0ecec1f07e3acdb0ff3f04919d5836a Mon Sep 17 00:00:00 2001 From: Kage Date: Wed, 11 Sep 2024 19:32:44 +0200 Subject: [PATCH 12/17] fix prepull --- XIVSlothCombo/Combos/JobHelpers/MNK.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index e830d05da..506a1afc1 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -127,15 +127,18 @@ private bool DoPrePullSteps(ref uint actionID) if (CurrentState == OpenerState.PrePull && PrePullStep > 0) { - if (Gauge.Chakra < 5 && PrePullStep == 1) PrePullStep++; - else if (PrePullStep == 1) actionID = Meditation; + if (Gauge.Chakra == 5 && PrePullStep == 1) PrePullStep++; + else if (PrePullStep == 1) actionID = OriginalHook(Meditation); - if (!HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 2) PrePullStep++; + if (HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 2) PrePullStep++; else if (PrePullStep == 2) actionID = FormShift; if (WasLastAction(DragonKick) && PrePullStep == 3) CurrentState = OpenerState.InOpener; else if (PrePullStep == 3) actionID = DragonKick; + if (!HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 3) + currentState = OpenerState.FailedOpener; + if (ActionWatching.CombatActions.Count > 2 && InCombat()) CurrentState = OpenerState.FailedOpener; From 104e31d00dfc7e796672ef34942be7886b76fa8c Mon Sep 17 00:00:00 2001 From: Kage Date: Thu, 12 Sep 2024 15:37:26 +0200 Subject: [PATCH 13/17] add variant options on simple mode --- XIVSlothCombo/Combos/CustomComboPreset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index 936d7cd6d..b5dae288f 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -2101,12 +2101,12 @@ public enum CustomComboPreset #region Variant [Variant] - [VariantParent(MNK_ST_AdvancedMode, MNK_AOE_SimpleMode)] + [VariantParent(MNK_ST_SimpleMode,MNK_ST_AdvancedMode, MNK_AOE_SimpleMode,MNK_AOE_AdvancedMode)] [CustomComboInfo("Rampart Option", "Use Variant Rampart on cooldown.", MNK.JobID)] MNK_Variant_Rampart = 9025, [Variant] - [VariantParent(MNK_ST_AdvancedMode, MNK_AOE_SimpleMode)] + [VariantParent(MNK_ST_SimpleMode, MNK_ST_AdvancedMode, MNK_AOE_SimpleMode, MNK_AOE_AdvancedMode)] [CustomComboInfo("Cure Option", "Use Variant Cure when HP is below set threshold.", MNK.JobID)] MNK_Variant_Cure = 9026, From bcc20d9b9cf176dacdc173445d310bd2517a4eee Mon Sep 17 00:00:00 2001 From: Tartarga <109563717+Tartarga@users.noreply.github.com> Date: Thu, 12 Sep 2024 08:58:11 -0500 Subject: [PATCH 14/17] PCT Variant on Simple Mode --- XIVSlothCombo/Combos/CustomComboPreset.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index 930761fc5..8c0319314 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -2606,17 +2606,21 @@ public enum CustomComboPreset [CustomComboInfo("One Button Paint", "Consolidates paint-consuming actions into one button.", PCT.JobID)] CombinedPaint = 20004, + // Last value for AoE = 20067 + #endregion + + #region Variant + [Variant] - [VariantParent(PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] + [VariantParent(PCT_ST_SimpleMode, PCT_AoE_SimpleMode, PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] [CustomComboInfo("Cure Option", "Use Variant Cure when HP is below set threshold.", PCT.JobID)] PCT_Variant_Cure = 20100, [Variant] - [VariantParent(PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] + [VariantParent(PCT_ST_SimpleMode, PCT_AoE_SimpleMode, PCT_ST_AdvancedMode, PCT_AoE_AdvancedMode)] [CustomComboInfo("Rampart Option", "Use Variant Rampart on cooldown.", PCT.JobID)] PCT_Variant_Rampart = 20101, - // Last value for AoE = 20067 #endregion #endregion From a9512b0997d54e0def4b546b431c2ebc4c22dc52 Mon Sep 17 00:00:00 2001 From: Tartarga <109563717+Tartarga@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:00:02 -0500 Subject: [PATCH 15/17] PCT Variant on Simple Modes pt 2 --- XIVSlothCombo/Combos/PvE/PCT.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/XIVSlothCombo/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT.cs index 2ab1524d0..28ef227ab 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT.cs @@ -97,6 +97,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb var gauge = GetJobGauge(); bool canWeave = CanSpellWeave(ActionWatching.LastSpell); + // Variant Cure + if (IsEnabled(CustomComboPreset.PCT_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= GetOptionValue(Config.PCT_VariantCure)) + return Variant.VariantCure; + + // Variant Rampart + if (IsEnabled(CustomComboPreset.PCT_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + canWeave) + return Variant.VariantRampart; + if (HasEffect(Buffs.Starstruck)) return OriginalHook(StarPrism); @@ -478,6 +491,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb var gauge = GetJobGauge(); bool canWeave = CanSpellWeave(ActionWatching.LastSpell); + // Variant Cure + if (IsEnabled(CustomComboPreset.PCT_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= GetOptionValue(Config.PCT_VariantCure)) + return Variant.VariantCure; + + // Variant Rampart + if (IsEnabled(CustomComboPreset.PCT_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart) && + canWeave) + return Variant.VariantRampart; + if (HasEffect(Buffs.Starstruck)) return OriginalHook(StarPrism); @@ -868,4 +894,4 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } } } -} \ No newline at end of file +} From a2954040085728b772b683cb0301ca4633253f12 Mon Sep 17 00:00:00 2001 From: Kage Date: Fri, 13 Sep 2024 18:22:25 +0200 Subject: [PATCH 16/17] add delayed weave to RoF and RoW in opener --- XIVSlothCombo/Combos/JobHelpers/MNK.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index 506a1afc1..08cac0aef 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -180,7 +180,7 @@ private bool DoSlOpener(ref uint actionID) else if (OpenerStep == 4) actionID = Brotherhood; if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = RiddleOfFire; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; else if (OpenerStep == 6) actionID = LeapingOpo; @@ -189,7 +189,7 @@ private bool DoSlOpener(ref uint actionID) else if (OpenerStep == 7) actionID = TheForbiddenChakra; if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; else if (OpenerStep == 9) actionID = RisingPhoenix; @@ -277,7 +277,7 @@ private bool DoLlOpener(ref uint actionID) else if (OpenerStep == 4) actionID = Brotherhood; if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = RiddleOfFire; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; else if (OpenerStep == 6) actionID = LeapingOpo; @@ -286,7 +286,7 @@ private bool DoLlOpener(ref uint actionID) else if (OpenerStep == 7) actionID = TheForbiddenChakra; if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; else if (OpenerStep == 9) actionID = ElixirBurst; From 12789df7647edc6d6ed218e9e6c9c2370331efcb Mon Sep 17 00:00:00 2001 From: Tartarga <109563717+Tartarga@users.noreply.github.com> Date: Sun, 15 Sep 2024 09:44:10 -0500 Subject: [PATCH 17/17] Fixed Merge Compile Breaker --- XIVSlothCombo/Combos/PvE/PCT.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/XIVSlothCombo/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT.cs index af9d707cd..2b3579f4d 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT.cs @@ -81,15 +81,13 @@ public static UserInt 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_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"), - PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500); - + PCT_AoE_LandscapeStop = new("PCT_AoE_LandscapeStop"); public static UserBool CombinedMotifsMog = new("CombinedMotifsMog"),