diff --git a/XIVSlothCombo/Combos/CustomComboPreset.cs b/XIVSlothCombo/Combos/CustomComboPreset.cs index 5cec488f8..cd6027a6f 100644 --- a/XIVSlothCombo/Combos/CustomComboPreset.cs +++ b/XIVSlothCombo/Combos/CustomComboPreset.cs @@ -1967,19 +1967,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)] @@ -2036,6 +2038,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)] @@ -2070,18 +2121,20 @@ 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, #endregion - + + // last value = 9037 // End Monk + #endregion #region NINJA @@ -2508,7 +2561,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)] @@ -2516,7 +2569,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)] @@ -2540,7 +2593,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)] @@ -2556,7 +2609,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)] @@ -2572,23 +2625,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)] @@ -2608,11 +2665,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)] @@ -2628,8 +2685,20 @@ public enum CustomComboPreset [CustomComboInfo("One Button Paint", "Consolidates paint-consuming actions into one button.", PCT.JobID)] CombinedPaint = 20004, + #endregion + + #region Variant + + [Variant] + [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_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 diff --git a/XIVSlothCombo/Combos/JobHelpers/MNK.cs b/XIVSlothCombo/Combos/JobHelpers/MNK.cs index 564013dd3..08cac0aef 100644 --- a/XIVSlothCombo/Combos/JobHelpers/MNK.cs +++ b/XIVSlothCombo/Combos/JobHelpers/MNK.cs @@ -1,415 +1,378 @@ -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) { - 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; - internal class MNKOpenerLogic : MNK + public uint OpenerStep; + + public uint PrePullStep; + + private static uint OpenerLevel => 100; + + public static bool LevelChecked => LocalPlayer.Level >= OpenerLevel; + + private static bool CanOpener => HasCooldowns() && LevelChecked; + + public OpenerState CurrentState { - 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 (Gauge.Chakra == 5 && PrePullStep == 1) PrePullStep++; + else if (PrePullStep == 1) actionID = OriginalHook(Meditation); - if (CanOpener && PrePullStep == 0) - { - PrePullStep = 1; - } + if (HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 2) PrePullStep++; + else if (PrePullStep == 2) actionID = FormShift; - if (!HasCooldowns()) - { - PrePullStep = 0; - } + if (WasLastAction(DragonKick) && PrePullStep == 3) CurrentState = OpenerState.InOpener; + else if (PrePullStep == 3) actionID = DragonKick; - if (CurrentState == OpenerState.PrePull && PrePullStep > 0) - { - if (Gauge.Chakra < 5 && PrePullStep == 1) - { - actionID = ForbiddenMeditation; - return true; - } + if (!HasEffect(Buffs.FormlessFist) && Gauge.Chakra == 5 && PrePullStep == 3) + currentState = OpenerState.FailedOpener; - 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) && + CanWeave(ActionWatching.LastWeaponskill) && + Gauge.Chakra >= 5 && + OpenerStep > 9) { - if (CustomComboFunctions.IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && OpenerStep > 2) - { - actionID = TheForbiddenChakra; - return true; - } + actionID = TheForbiddenChakra; + + return true; + } - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 1) OpenerStep++; - else if (OpenerStep == 1) actionID = PerfectBalance; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastAction(TheForbiddenChakra) && OpenerStep == 2) OpenerStep++; - else if (OpenerStep == 2) actionID = TheForbiddenChakra; + if (WasLastWeaponskill(TwinSnakes) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = TwinSnakes; - if (CustomComboFunctions.WasLastWeaponskill(TwinSnakes) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = TwinSnakes; + if (WasLastWeaponskill(Demolish) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = Demolish; - if (CustomComboFunctions.WasLastWeaponskill(Demolish) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = Demolish; + if (WasLastAbility(Brotherhood) && OpenerStep == 4) OpenerStep++; + else if (OpenerStep == 4) actionID = Brotherhood; - if (CustomComboFunctions.WasLastAbility(Brotherhood) && CustomComboFunctions.HasEffect(Buffs.Brotherhood) && OpenerStep == 5) OpenerStep++; - else if (OpenerStep == 5) actionID = Brotherhood; + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; - if (CustomComboFunctions.WasLastAction(RiddleOfFire) && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; - // Pot + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; - if (CustomComboFunctions.WasLastAction(RiddleOfWind) && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + if (WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = RisingPhoenix; - if (CustomComboFunctions.WasLastWeaponskill(RisingPhoenix) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = RisingPhoenix; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; + if (WasLastWeaponskill(WindsReply) && OpenerStep == 11) OpenerStep++; + else if (OpenerStep == 11) actionID = WindsReply; - if ((CustomComboFunctions.WasLastWeaponskill(FiresReply) || !CustomComboFunctions.HasEffect(Buffs.FiresRumination)) && OpenerStep == 11) OpenerStep++; - else if (OpenerStep == 11) actionID = FiresReply; + if (WasLastWeaponskill(FiresReply) && OpenerStep == 12) OpenerStep++; + else if (OpenerStep == 12) actionID = FiresReply; - if ((CustomComboFunctions.WasLastWeaponskill(WindsReply) || !CustomComboFunctions.HasEffect(Buffs.WindsRumination)) && OpenerStep == 12) OpenerStep++; - else if (OpenerStep == 12) actionID = WindsReply; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; + if (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || + (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || + (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || + (actionID is Brotherhood && IsOnCooldown(Brotherhood))) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; - 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; + return false; } - return false; + + return true; } - private bool DoLLOpener(ref uint actionID) - { - if (!LevelChecked) - return false; + return false; + } - if (currentState == OpenerState.InOpener) + private bool DoLlOpener(ref uint actionID) + { + if (!LevelChecked) + return false; + + if (currentState == OpenerState.InOpener) + { + if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) && + CanWeave(ActionWatching.LastWeaponskill) && + Gauge.Chakra >= 5 && + OpenerStep > 9) { - 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) && GetRemainingCharges(PerfectBalance) is 1 && OpenerStep == 1) + OpenerStep++; + else if (OpenerStep == 1) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 3) OpenerStep++; - else if (OpenerStep == 3) actionID = LeapingOpo; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 2) OpenerStep++; + else if (OpenerStep == 2) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 4) OpenerStep++; - else if (OpenerStep == 4) actionID = DragonKick; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 3) OpenerStep++; + else if (OpenerStep == 3) actionID = DragonKick; - if (CustomComboFunctions.WasLastAbility(Brotherhood) && CustomComboFunctions.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 (CustomComboFunctions.WasLastAction(RiddleOfFire) && CustomComboFunctions.HasEffect(Buffs.RiddleOfFire) && OpenerStep == 6) OpenerStep++; - else if (OpenerStep == 6) actionID = RiddleOfFire; + if (WasLastAction(RiddleOfFire) && OpenerStep == 5) OpenerStep++; + else if (OpenerStep == 5 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfFire; - // Pot + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 6) OpenerStep++; + else if (OpenerStep == 6) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 7) OpenerStep++; - else if (OpenerStep == 7) actionID = LeapingOpo; + if (WasLastAction(TheForbiddenChakra) && OpenerStep == 7) OpenerStep++; + else if (OpenerStep == 7) actionID = TheForbiddenChakra; - if (CustomComboFunctions.WasLastAction(RiddleOfWind) && CustomComboFunctions.HasEffect(Buffs.RiddleOfWind) && OpenerStep == 8) OpenerStep++; - else if (OpenerStep == 8) actionID = RiddleOfWind; + if (WasLastAction(RiddleOfWind) && OpenerStep == 8) OpenerStep++; + else if (OpenerStep == 8 && CanDelayedWeave(ActionWatching.LastWeaponskill)) actionID = RiddleOfWind; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; - else if (OpenerStep == 9) actionID = ElixirBurst; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 9) OpenerStep++; + else if (OpenerStep == 9) actionID = ElixirBurst; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; - else if (OpenerStep == 10) actionID = DragonKick; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 10) OpenerStep++; + else if (OpenerStep == 10) actionID = DragonKick; - if ((CustomComboFunctions.WasLastWeaponskill(FiresReply) || !CustomComboFunctions.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 ((CustomComboFunctions.WasLastWeaponskill(WindsReply) || !CustomComboFunctions.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 (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; - else if (OpenerStep == 13) actionID = LeapingOpo; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 13) OpenerStep++; + else if (OpenerStep == 13) actionID = LeapingOpo; - if ((CustomComboFunctions.WasLastAction(PerfectBalance) || CustomComboFunctions.HasEffect(Buffs.PerfectBalance)) && OpenerStep == 14) OpenerStep++; - else if (OpenerStep == 14) actionID = PerfectBalance; + if (WasLastAction(PerfectBalance) && GetRemainingCharges(PerfectBalance) is 0 && OpenerStep == 14) + OpenerStep++; + else if (OpenerStep == 14) actionID = PerfectBalance; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; - else if (OpenerStep == 15) actionID = DragonKick; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 15) OpenerStep++; + else if (OpenerStep == 15) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; - else if (OpenerStep == 16) actionID = LeapingOpo; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 16) OpenerStep++; + else if (OpenerStep == 16) actionID = LeapingOpo; - if (CustomComboFunctions.WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; - else if (OpenerStep == 17) actionID = DragonKick; + if (WasLastWeaponskill(DragonKick) && OpenerStep == 17) OpenerStep++; + else if (OpenerStep == 17) actionID = DragonKick; - if (CustomComboFunctions.WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; - else if (OpenerStep == 18) actionID = ElixirBurst; + if (WasLastWeaponskill(ElixirBurst) && OpenerStep == 18) OpenerStep++; + else if (OpenerStep == 18) actionID = ElixirBurst; - if (CustomComboFunctions.WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; - else if (OpenerStep == 19) actionID = LeapingOpo; + if (WasLastWeaponskill(LeapingOpo) && OpenerStep == 19) CurrentState = OpenerState.OpenerFinished; + else if (OpenerStep == 19) actionID = LeapingOpo; - if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) - CurrentState = OpenerState.FailedOpener; + if (ActionWatching.TimeSinceLastAction.TotalSeconds >= 5) + CurrentState = OpenerState.FailedOpener; - 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 (((actionID == PerfectBalance && GetRemainingCharges(PerfectBalance) == 0) || + (actionID is RiddleOfFire && IsOnCooldown(RiddleOfFire)) || + (actionID is RiddleOfWind && IsOnCooldown(RiddleOfWind)) || + (actionID is Brotherhood && IsOnCooldown(Brotherhood))) + && ActionWatching.TimeSinceLastAction.TotalSeconds >= 3) + { + Svc.Log.Debug($"Failed at {actionID}"); + CurrentState = OpenerState.FailedOpener; + + return false; } - return 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) - { - if (selectedOpener == 1) - { - if (DoLLOpener(ref actionID)) - return true; - } - else if (selectedOpener == 2) - { - if (DoSLOpener(ref actionID)) - return true; - } - } + public bool DoFullOpener(ref uint actionID, int selectedOpener) + { + if (!LevelChecked) + return false; + + if (CurrentState == OpenerState.PrePull) + if (DoPrePullSteps(ref actionID)) + return true; - if (!CustomComboFunctions.InCombat()) + if (CurrentState == OpenerState.InOpener) + switch (selectedOpener) { - ResetOpener(); - CurrentState = OpenerState.PrePull; + case 0 when DoLlOpener(ref actionID): + + case 1 when 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..229539948 100644 --- a/XIVSlothCombo/Combos/PvE/MNK.cs +++ b/XIVSlothCombo/Combos/PvE/MNK.cs @@ -1,690 +1,780 @@ +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.Extensions; +using XIVSlothCombo.Data; +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(); + + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_SimpleMode; - internal class MNK_ST_SimpleMode : CustomCombo + 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, 0)) + return actionID; + + if ((!InCombat() || !InMeleeRange()) && + Gauge.Chakra < 5 && + !HasEffect(Buffs.RiddleOfFire) && + LevelChecked(Meditation)) + return OriginalHook(Meditation); + + if (!InCombat() && LevelChecked(FormShift) && + !HasEffect(Buffs.FormlessFist)) + return FormShift; + + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; + + // 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(Brotherhood)) + return Brotherhood; + if (ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; - if (IsEnabled(Variant.VariantCure) && - PlayerHealthPercentageHp() <= Config.MNK_VariantCure) - return Variant.VariantCure; + if (ActionReady(RiddleOfWind)) + return RiddleOfWind; - if ((!inCombat || !InMeleeRange()) - && Gauge.Chakra < 5 - && !HasEffect(Buffs.RiddleOfFire) - && LevelChecked(Meditation)) + //Perfect Balance + if (ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) { - return OriginalHook(Meditation); + // 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; } - // OGCDs - if (canWeave) - { - if (IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; + if (PlayerHealthPercentageHp() <= 25 && + ActionReady(All.SecondWind)) + return All.SecondWind; - 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; - } - } + if (PlayerHealthPercentageHp() <= 40 && + ActionReady(All.Bloodbath)) + return All.Bloodbath; - if (ActionReady(Brotherhood)) - { - return Brotherhood; - } + if (Gauge.Chakra >= 5 && + LevelChecked(SteelPeak)) + return OriginalHook(Meditation); + } - if (ActionReady(RiddleOfFire)) - { - return RiddleOfFire; - } + // GCDs + if (HasEffect(Buffs.FormlessFist)) + return Gauge.OpoOpoFury == 0 + ? DragonKick + : OriginalHook(Bootshine); - if (ActionReady(RiddleOfWind)) - { - return RiddleOfWind; - } + // Masterful Blitz + if (LevelChecked(MasterfulBlitz) && + !HasEffect(Buffs.PerfectBalance) && + !IsOriginal(MasterfulBlitz)) + return OriginalHook(MasterfulBlitz); - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) - return All.SecondWind; - if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) - return All.Bloodbath; + // Perfect Balance + if (HasEffect(Buffs.PerfectBalance)) + { + #region Open Solar - if (Gauge.Chakra >= 5 - && SteelPeak.LevelChecked()) - { - return OriginalHook(SteelPeak); - } + if (!solarNadi && !bothNadisOpen) + { + if (coeurlChakra == 0) + return Gauge.CoeurlFury == 0 + ? Demolish + : OriginalHook(SnapPunch); + + if (raptorChakra == 0) + return Gauge.RaptorFury == 0 + ? TwinSnakes + : OriginalHook(TrueStrike); + + if (opoOpoChakra == 0) + return Gauge.OpoOpoFury == 0 + ? DragonKick + : OriginalHook(Bootshine); } - // GCDs + #endregion + + #region Open Lunar + + if (solarNadi || lunarNadi || bothNadisOpen) + return Gauge.OpoOpoFury == 0 + ? DragonKick + : OriginalHook(Bootshine); + + #endregion + } + + if (HasEffect(Buffs.FiresRumination) && + !HasEffect(Buffs.PerfectBalance) && + !HasEffect(Buffs.FormlessFist) && + (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, true); + } + + return actionID; + } + } + + internal class MNK_ST_AdvancedMode : CustomCombo + { + internal static MNKOpenerLogic MNKOpener = new(); + + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_ST_AdvancedMode; - // Ensure usage if buff is almost depleted. - if (HasEffect(Buffs.FiresRumination) && GetBuffRemainingTime(Buffs.FiresRumination) < 4) + 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; + + if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) && + (!InCombat() || !InMeleeRange()) && + Gauge.Chakra < 5 && + !HasEffect(Buffs.RiddleOfFire) && + LevelChecked(Meditation)) + return OriginalHook(Meditation); + + if (IsEnabled(CustomComboPreset.MNK_STUseFormShift) && + !InCombat() && LevelChecked(FormShift) && + !HasEffect(Buffs.FormlessFist)) + return FormShift; + + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + 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)) + { + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) { - return FiresReply; + if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) && + ActionReady(Brotherhood)) + return Brotherhood; + + if (IsEnabled(CustomComboPreset.MNK_STUseROW) && + ActionReady(RiddleOfWind)) + return RiddleOfWind; } - if (HasEffect(Buffs.WindsRumination) && GetBuffRemainingTime(Buffs.WindsRumination) < 4) + //Perfect Balance + if (IsEnabled(CustomComboPreset.MNK_STUsePerfectBalance) && + ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) { - return WindsReply; + // 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 (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 + if (HasEffect(Buffs.FormlessFist)) + return Gauge.OpoOpoFury == 0 + ? 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) && + !IsOriginal(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 + ? Demolish + : OriginalHook(SnapPunch); + + if (raptorChakra == 0) + return Gauge.RaptorFury == 0 + ? TwinSnakes + : OriginalHook(TrueStrike); + + if (opoOpoChakra == 0) + return Gauge.OpoOpoFury == 0 + ? DragonKick + : OriginalHook(Bootshine); } + #endregion + #region Open Lunar + if (solarNadi || lunarNadi || bothNadisOpen) - { - return Gauge.OpoOpoFury == 0 ? OriginalHook(DragonKick) : OriginalHook(Bootshine); - } - #endregion - } + return Gauge.OpoOpoFury == 0 + ? DragonKick + : OriginalHook(Bootshine); - if (HasEffect(Buffs.WindsRumination)) - { - return WindsReply; + #endregion } + } - if (HasEffect(Buffs.FiresRumination) - && !HasEffect(Buffs.PerfectBalance) - && !HasEffect(Buffs.FormlessFist) - && (WasLastWeaponskill(LeapingOpo) || WasLastWeaponskill(DragonKick))) - { + 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; - } - - // Standard Beast Chakras - return MNKHelper.DetermineCoreAbility(actionID); + if (IsEnabled(CustomComboPreset.MNK_STUseROW) && + IsEnabled(CustomComboPreset.MNK_STUseWindsReply) && + HasEffect(Buffs.WindsRumination) && + LevelChecked(WindsReply) && + (HasEffect(Buffs.RiddleOfFire) || + GetBuffRemainingTime(Buffs.WindsRumination) < 4)) + return WindsReply; } - return actionID; + // Standard Beast Chakras + return MNKHelper.DetermineCoreAbility(actionID, IsEnabled(CustomComboPreset.MNK_STUseTrueNorth)); } - } - internal class MNK_ST_AdvancedMode : CustomCombo - { - 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) - { - 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 (IsEnabled(CustomComboPreset.MNK_STUseOpener)) - { - if (MNKOpener.DoFullOpener(ref actionID, Config.MNK_SelectedOpener)) - return actionID; - } + return actionID; + } + } - if (IsEnabled(CustomComboPreset.MNK_STUseMeditation) - && (!inCombat || !InMeleeRange()) - && Gauge.Chakra < 5 - && !HasEffect(Buffs.RiddleOfFire) - && LevelChecked(Meditation)) - { - return OriginalHook(Meditation); - } + internal class MNK_AOE_SimpleMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_AOE_SimpleMode; - if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && IsEnabled(Variant.VariantCure) && PlayerHealthPercentageHp() <= GetOptionValue(Config.MNK_VariantCure)) - return Variant.VariantCure; + protected override uint Invoke(uint actionID, uint lastComboMove, float comboTime, byte level) + { + Status? pbStacks = FindEffectAny(Buffs.PerfectBalance); + bool lunarNadi = Gauge.Nadi == Nadi.LUNAR; + bool nadiNone = Gauge.Nadi == Nadi.NONE; - // OGCDs - if (inCombat && canWeave) - { - if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && - IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; + if (actionID is ArmOfTheDestroyer or ShadowOfTheDestroyer) + { + if (!InCombat() && Gauge.Chakra < 5 && LevelChecked(Meditation)) + return OriginalHook(Meditation); - 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; - } - } + //Variant Cure + if (IsEnabled(CustomComboPreset.MNK_Variant_Cure) && + IsEnabled(Variant.VariantCure) && + PlayerHealthPercentageHp() <= Config.MNK_VariantCure) + return Variant.VariantCure; - if (IsEnabled(CustomComboPreset.MNK_STUseBuffs)) - { - if (IsEnabled(CustomComboPreset.MNK_STUseBrotherhood) - && Brotherhood.LevelChecked() - && !IsOnCooldown(Brotherhood)) - { - return Brotherhood; - } + if (ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; - if (IsEnabled(CustomComboPreset.MNK_STUseROF) - && RiddleOfFire.LevelChecked() - && !IsOnCooldown(RiddleOfFire)) - { - return RiddleOfFire; - } + // Buffs + if (CanWeave(ActionWatching.LastWeaponskill)) + { + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; + + if (ActionReady(Brotherhood)) + return Brotherhood; + + if (ActionReady(RiddleOfWind)) + return RiddleOfWind; + + 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 (Gauge.Chakra >= 5 && + LevelChecked(HowlingFist) && + HasBattleTarget()) + return OriginalHook(HowlingFist); + + if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + return All.SecondWind; + + if (PlayerHealthPercentageHp() <= 40 && ActionReady(All.Bloodbath)) + return All.Bloodbath; + } - if (IsEnabled(CustomComboPreset.MNK_STUseROW) - && RiddleOfWind.LevelChecked() - && !IsOnCooldown(RiddleOfWind)) - { - return RiddleOfWind; - } - } + if (HasEffect(Buffs.WindsRumination)) + return WindsReply; - 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.FiresRumination)) + return FiresReply; - if (IsEnabled(CustomComboPreset.MNK_STUseTheForbiddenChakra) - && Gauge.Chakra >= 5 - && SteelPeak.LevelChecked()) - { - return OriginalHook(Meditation); - } - } + // Masterful Blitz + if (LevelChecked(MasterfulBlitz) && !HasEffect(Buffs.PerfectBalance) && + OriginalHook(MasterfulBlitz) != MasterfulBlitz) + return OriginalHook(MasterfulBlitz); - // GCDs - if (inCombat) - { - // Ensure usage if buff is almost depleted. - if (IsEnabled(CustomComboPreset.MNK_STUseFiresReply) - && HasEffect(Buffs.FiresRumination) - && GetBuffRemainingTime(Buffs.FiresRumination) < 4) - { - return FiresReply; - } + // Perfect Balance + if (HasEffect(Buffs.PerfectBalance)) + { + if (nadiNone || !lunarNadi) + if (pbStacks?.StackCount > 0) + return LevelChecked(ShadowOfTheDestroyer) + ? ShadowOfTheDestroyer + : Rockbreaker; - if (IsEnabled(CustomComboPreset.MNK_STUseWindsReply) - && HasEffect(Buffs.WindsRumination) - && GetBuffRemainingTime(Buffs.WindsRumination) < 4) + if (lunarNadi) + switch (pbStacks?.StackCount) { - return WindsReply; - } + case 3: + return OriginalHook(ArmOfTheDestroyer); - 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) && 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_AdvancedMode : CustomCombo + { + protected internal override CustomComboPreset Preset { get; } = CustomComboPreset.MNK_AOE_AdvancedMode; - internal class MNK_AoE_SimpleMode : CustomCombo + 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; + + if (IsEnabled(CustomComboPreset.MNK_AoEUseBuffs) && + IsEnabled(CustomComboPreset.MNK_AoEUseROF) && + ActionReady(RiddleOfFire) && + CanDelayedWeave(ActionWatching.LastWeaponskill)) + return RiddleOfFire; + + // 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) - { - if (gauge.Chakra < 5 && Meditation.LevelChecked()) - { - return OriginalHook(Meditation); ; - } - } - + //Variant Rampart + if (IsEnabled(CustomComboPreset.MNK_Variant_Rampart) && + IsEnabled(Variant.VariantRampart) && + IsOffCooldown(Variant.VariantRampart)) + return Variant.VariantRampart; - if (IsEnabled(Variant.VariantCure) && PlayerHealthPercentageHp() <= GetOptionValue(Config.MNK_VariantCure)) - return Variant.VariantCure; - - // Buffs - if (inCombat && canWeave) + if (IsEnabled(CustomComboPreset.MNK_AoEUseBuffs)) { - - if (IsEnabled(Variant.VariantRampart) && - IsOffCooldown(Variant.VariantRampart)) - return Variant.VariantRampart; - - 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)) - { + if (IsEnabled(CustomComboPreset.MNK_AoEUseBrotherhood) && + ActionReady(Brotherhood)) return Brotherhood; - } - if (ActionReady(RiddleOfWind)) - { + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && + ActionReady(RiddleOfWind)) return RiddleOfWind; - } - - if (Gauge.Chakra >= 5 - && HowlingFist.LevelChecked() - && HasBattleTarget()) - { - return OriginalHook(HowlingFist); - } + } - if (PlayerHealthPercentageHp() <= 25 && ActionReady(All.SecondWind)) + if (IsEnabled(CustomComboPreset.MNK_AoEUsePerfectBalance) && + ActionReady(PerfectBalance) && + !HasEffect(Buffs.PerfectBalance)) + + // 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 (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_AoEUseHowlingFist) && + Gauge.Chakra >= 5 && + LevelChecked(HowlingFist) && + HasBattleTarget()) + return OriginalHook(HowlingFist); + + 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_AoEUseBuffs)) + { + if (IsEnabled(CustomComboPreset.MNK_AoEUseROF) && + IsEnabled(CustomComboPreset.MNK_AoEUseFiresReply) && + HasEffect(Buffs.FiresRumination)) + return FiresReply; - if (HasEffect(Buffs.FiresRumination)) - { - return FiresReply; - } + if (IsEnabled(CustomComboPreset.MNK_AoEUseROW) && + IsEnabled(CustomComboPreset.MNK_AoEUseWindsReply) && + HasEffect(Buffs.WindsRumination)) + return WindsReply; + } - // 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 LevelChecked(ShadowOfTheDestroyer) + ? ShadowOfTheDestroyer + : Rockbreaker; + + if (lunarNadi) + switch (pbStacks?.StackCount) { - switch (pbStacks?.StackCount) - { - case 3: - return OriginalHook(ArmOfTheDestroyer); - case 2: - return FourPointFury; - case 1: - return Rockbreaker; - } - } - } - - // Monk Rotation - if (HasEffect(Buffs.OpoOpoForm)) - { - return OriginalHook(ArmOfTheDestroyer); - } + case 3: + return OriginalHook(ArmOfTheDestroyer); - if (HasEffect(Buffs.RaptorForm)) - { - if (FourPointFury.LevelChecked()) - return FourPointFury; + case 2: + return FourPointFury; - if (TwinSnakes.LevelChecked()) - return TwinSnakes; - } - - 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 is PerfectBalance && + OriginalHook(MasterfulBlitz) != MasterfulBlitz && LevelChecked(MasterfulBlitz)) + return OriginalHook(MasterfulBlitz); - return actionID; - } + 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 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/Combos/PvE/PCT.cs b/XIVSlothCombo/Combos/PvE/PCT.cs index 2e391e6eb..2b3579f4d 100644 --- a/XIVSlothCombo/Combos/PvE/PCT.cs +++ b/XIVSlothCombo/Combos/PvE/PCT.cs @@ -1,6 +1,7 @@ using Dalamud.Game.ClientState.JobGauge.Types; using XIVSlothCombo.Combos.JobHelpers; using XIVSlothCombo.Core; +using XIVSlothCombo.Combos.PvE.Content; using XIVSlothCombo.CustomComboNS; using XIVSlothCombo.CustomComboNS.Functions; using XIVSlothCombo.Data; @@ -24,6 +25,7 @@ public const uint AeroInGreen = 34651, WaterInBlue = 34652, FireIIinRed = 34656, + AeroIIinGreen = 34657, HammerMotif = 34668, WingedMuse = 34671, StrikingMuse = 34674, @@ -46,6 +48,7 @@ public const uint StarPrism = 34681, SteelMuse = 35348, SubtractivePalette = 34683, + StoneIIinYellow = 34660, ThunderIIinMagenta = 34661, ThunderinMagenta = 34655, WaterinBlue = 34652, @@ -76,14 +79,15 @@ public static class Config public static UserInt CombinedAetherhueChoices = new("CombinedAetherhueChoices"), PCT_ST_AdvancedMode_LucidOption = new("PCT_ST_AdvancedMode_LucidOption", 6500), + PCT_AoE_AdvancedMode_HolyinWhiteOption = new("PCT_AoE_AdvancedMode_HolyinWhiteOption", 0), + PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500), + PCT_VariantCure = new("PCT_VariantCure"), PCT_ST_CreatureStop = new("PCT_ST_CreatureStop"), PCT_AoE_CreatureStop = new("PCT_AoE_CreatureStop"), PCT_ST_WeaponStop = new("PCT_ST_WeaponStop"), PCT_AoE_WeaponStop = new("PCT_AoE_WeaponStop"), PCT_ST_LandscapeStop = new("PCT_ST_LandscapeStop"), - PCT_AoE_LandscapeStop = new("PCT_AoE_LandscapeStop"), - PCT_AoE_AdvancedMode_LucidOption = new("PCT_AoE_AdvancedMode_LucidOption", 6500); - + PCT_AoE_LandscapeStop = new("PCT_AoE_LandscapeStop"); public static UserBool CombinedMotifsMog = new("CombinedMotifsMog"), @@ -108,8 +112,21 @@ 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 (!InCombat() || InCombat() && CurrentTarget == null) { if (CreatureMotif.LevelChecked() && !gauge.CreatureMotifDrawn) @@ -119,7 +136,7 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb if (LandscapeMotif.LevelChecked() && !gauge.LandscapeMotifDrawn && !HasEffect(Buffs.StarryMuse)) return OriginalHook(LandscapeMotif); } - + // Lvl 100 Opener if (StarPrism.LevelChecked()) { @@ -361,6 +378,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb int weaponStop = PluginConfiguration.GetCustomIntValue(Config.PCT_ST_WeaponStop); + // 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)) { @@ -629,10 +659,23 @@ 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 (!InCombat() || InCombat() && CurrentTarget == null) + + + if (!InCombat() || InCombat() && CurrentTarget == null) { if (CreatureMotif.LevelChecked() && !gauge.CreatureMotifDrawn) return OriginalHook(CreatureMotif); @@ -822,6 +865,19 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb int landscapeStop = PluginConfiguration.GetCustomIntValue(Config.PCT_AoE_LandscapeStop); int weaponStop = PluginConfiguration.GetCustomIntValue(Config.PCT_AoE_WeaponStop); + // 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)) { @@ -982,6 +1038,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; @@ -1101,4 +1164,4 @@ protected override uint Invoke(uint actionID, uint lastComboActionID, float comb } } } -} \ No newline at end of file +} diff --git a/XIVSlothCombo/Window/Functions/UserConfig.cs b/XIVSlothCombo/Window/Functions/UserConfig.cs index 7b59bd9d3..3cb07f21a 100644 --- a/XIVSlothCombo/Window/Functions/UserConfig.cs +++ b/XIVSlothCombo/Window/Functions/UserConfig.cs @@ -1600,18 +1600,34 @@ 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) + { + 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); - 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) @@ -1706,6 +1722,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); @@ -1723,6 +1745,9 @@ internal static void Draw(CustomComboPreset preset, bool enabled) if (preset == CustomComboPreset.PCT_AoE_AdvancedMode_WeaponMotif) UserConfig.DrawSliderInt(0, 10, PCT.Config.PCT_AoE_WeaponStop, "Health % to stop Drawing Motif"); + if (preset == CustomComboPreset.PCT_Variant_Cure) + UserConfig.DrawSliderInt(1, 100, PCT.Config.PCT_VariantCure, "HP% to be at or under", 200); + // PvP if (preset == CustomComboPreset.PCTPvP_BurstControl) UserConfig.DrawSliderInt(1, 100, PCTPvP.Config.PCTPvP_BurstHP, "Target HP%", 200);