From 47b453d88690bec563dbd1f4c2b964c20665b950 Mon Sep 17 00:00:00 2001 From: Kaedys Date: Sat, 10 Aug 2024 20:43:00 -0400 Subject: [PATCH] [FEATURE] Reaper revamp - Rewrote most of the existing Reaper combos - Merged a number of separate single target and AoE combos. - Merged a large number of combos that used to be separate per target button, but had the same effect - Most of the Reaper combos now note that they also apply to any other features that cause their target action to be a replacement for something else. - Example, turning Lemure's Slice into Sacrificium now also works when turning Gibbet/Void Reaping into Lemure's Slice. - Both of which then also work when turning Nightmare Slice into Gibbet. - Deleted the Sacrificium Priority combo, because it was a bear to code and strictly unneeded with the existing first and third weave options. - Deleted the Soul Sow on Shadow of Death feature. We already have options for Slice, Nightmare Scythe, and Harpe. - Renamed and resectioned basically every single other feature. - Implemented Automatic Soul Slice feature. Fixes #195. - Updated the Automatic usage of Blood Stalk and Grim Swathe to have an overcap-only secret subfeature. - Updated the Shadow Gibbet and Shadow Gallows features to only replace when Reaving by default. Fixes #403. - Add new subcombos that also replace while Enshrouded, and added a note about how extremely problematic those subfeatures are. - Rewrote most of the Reaper file logic to account for the changes. - Replaced every usage of `HasTarget` for hostile actions with `TargetIsEnemy`. - Replaced the single sole usage of `IsNotEnabled` with `!IsEnabled`, and deleted `IsNotEnabled`. - Same for `OutOfCombat` and `HasNoTarget`. --- .editorconfig | 2 + XIVComboExpanded/Combos/ADV.cs | 2 +- XIVComboExpanded/Combos/BLM.cs | 12 +- XIVComboExpanded/Combos/MCH.cs | 4 +- XIVComboExpanded/Combos/RPR.cs | 502 +++++++++++++++--------- XIVComboExpanded/Combos/SGE.cs | 20 +- XIVComboExpanded/CustomCombo.cs | 28 +- XIVComboExpanded/CustomComboPreset.cs | 287 ++++++-------- XIVComboExpanded/Interface/Changelog.cs | 8 + 9 files changed, 461 insertions(+), 404 deletions(-) diff --git a/.editorconfig b/.editorconfig index 8e251a433..e5684bc3a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,5 @@ dotnet_diagnostic.CA1822.severity=silent dotnet_diagnostic.SA1518.severity = none dotnet_diagnostic.SA1516.severity = none dotnet_diagnostic.SA1005.severity = none +dotnet_diagnostic.SA1119.severity = none +dotnet_diagnostic.IDE0047.severity = none diff --git a/XIVComboExpanded/Combos/ADV.cs b/XIVComboExpanded/Combos/ADV.cs index 536a6d3a9..f08fc0ef4 100644 --- a/XIVComboExpanded/Combos/ADV.cs +++ b/XIVComboExpanded/Combos/ADV.cs @@ -181,7 +181,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (actionID == ADV.HeadGraze && (LocalPlayer?.ClassJob.Id == BRD.ClassID || LocalPlayer?.ClassJob.Id == BRD.JobID || LocalPlayer?.ClassJob.Id == MCH.JobID || LocalPlayer?.ClassJob.Id == DNC.JobID)) { - if (!HasEffect(ADV.Buffs.Peloton) && OutOfCombat()) + if (!HasEffect(ADV.Buffs.Peloton) && InCombat()) { return ADV.Peloton; } diff --git a/XIVComboExpanded/Combos/BLM.cs b/XIVComboExpanded/Combos/BLM.cs index 5f69f8d75..482bc510a 100644 --- a/XIVComboExpanded/Combos/BLM.cs +++ b/XIVComboExpanded/Combos/BLM.cs @@ -98,7 +98,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.BlackSpellsUmbralSoulFeature)) { - if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !HasTarget()) + if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !TargetIsEnemy()) return BLM.UmbralSoul; } } @@ -140,7 +140,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.BlackEnochianDespairFeature)) { if (IsEnabled(CustomComboPreset.BlackEnochianDespairFlareStarFeature)) - { + { // 2nd and 3rd checks for opener and post-manafont usage if (level >= BLM.Levels.FlareStar && gauge.AstralSoulStacks >= 6 && (LocalPlayer?.CurrentMp <= 0 || LocalPlayer?.CurrentMp == 8400 || LocalPlayer?.CurrentMp == 10000)) return BLM.FlareStar; @@ -244,7 +244,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return BLM.Fire3; } - if (IsNotEnabled(CustomComboPreset.BlackFireOption2)) + if (!IsEnabled(CustomComboPreset.BlackFireOption2)) { if (!gauge.InAstralFire) return BLM.Fire3; @@ -271,7 +271,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.BlackSpellsUmbralSoulFeature)) { - if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !HasTarget()) + if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !TargetIsEnemy()) return BLM.UmbralSoul; } @@ -306,7 +306,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.BlackSpellsUmbralSoulFeature)) { - if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !HasTarget()) + if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !TargetIsEnemy()) return BLM.UmbralSoul; } } @@ -380,7 +380,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.BlackSpellsUmbralSoulFeature)) { - if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !HasTarget()) + if (level >= BLM.Levels.UmbralSoul && gauge.InUmbralIce && !TargetIsEnemy()) return BLM.UmbralSoul; } diff --git a/XIVComboExpanded/Combos/MCH.cs b/XIVComboExpanded/Combos/MCH.cs index 750b8d504..491a63f17 100644 --- a/XIVComboExpanded/Combos/MCH.cs +++ b/XIVComboExpanded/Combos/MCH.cs @@ -167,7 +167,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (actionID == MCH.Hypercharge) { - if (level >= MCH.Levels.Wildfire && IsCooldownUsable(MCH.Wildfire) && HasTarget()) + if (level >= MCH.Levels.Wildfire && IsCooldownUsable(MCH.Wildfire) && TargetIsEnemy()) return MCH.Wildfire; if (level >= MCH.Levels.Wildfire && !IsCooldownUsable(MCH.Hypercharge) && !IsOriginal(MCH.Wildfire)) @@ -190,7 +190,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.MachinistHyperfireFeature)) { - if (level >= MCH.Levels.Wildfire && IsCooldownUsable(MCH.Wildfire) && HasTarget()) + if (level >= MCH.Levels.Wildfire && IsCooldownUsable(MCH.Wildfire) && TargetIsEnemy()) return MCH.Wildfire; } diff --git a/XIVComboExpanded/Combos/RPR.cs b/XIVComboExpanded/Combos/RPR.cs index a24915acd..7cf646eba 100644 --- a/XIVComboExpanded/Combos/RPR.cs +++ b/XIVComboExpanded/Combos/RPR.cs @@ -118,59 +118,63 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return RPR.Soulsow; } - if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) + if (level >= RPR.Levels.SoulReaver && + (IsEnabled(CustomComboPreset.ReaperSliceGibbetFeature) || + IsEnabled(CustomComboPreset.ReaperSliceGallowsFeature))) { - if (IsEnabled(CustomComboPreset.ReaperSliceLemuresFeature)) + if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) - return RPR.LemuresSlice; - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) + { + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresSlice; + + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } + } - if (IsEnabled(CustomComboPreset.ReaperSacrificiumFeature)) - { - if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && gauge.LemureShroud < 5 && - (gauge.LemureShroud == 2 || !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature))) - return RPR.Sacrificium; - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) + { + if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) + return RPR.Communio; + } - if (IsEnabled(CustomComboPreset.ReaperSliceCommunioFeature)) - { - if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) - return RPR.Communio; - } - } + if (IsEnabled(CustomComboPreset.ReaperReapingEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedVoidReaping)) + return RPR.VoidReaping; - if ((level >= RPR.Levels.SoulReaver && HasEffect(RPR.Buffs.SoulReaver)) || - (level >= RPR.Levels.Executioner && HasEffect(RPR.Buffs.Executioner)) || - (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0)) - { - if (IsEnabled(CustomComboPreset.ReaperSliceEnhancedEnshroudedFeature) && HasEffect(RPR.Buffs.Enshrouded)) - { - if (HasEffect(RPR.Buffs.EnhancedVoidReaping)) + if (HasEffect(RPR.Buffs.EnhancedCrossReaping)) + return RPR.CrossReaping; + } + + if (IsEnabled(CustomComboPreset.ReaperSliceGibbetFeature)) return RPR.VoidReaping; - if (HasEffect(RPR.Buffs.EnhancedCrossReaping)) - return RPR.CrossReaping; + return RPR.CrossReaping; } - if (IsEnabled(CustomComboPreset.ReaperSliceEnhancedSoulReaverFeature)) + if (HasEffect(RPR.Buffs.SoulReaver) || HasEffect(RPR.Buffs.Executioner)) { - if (HasEffect(RPR.Buffs.EnhancedGibbet)) - // Void Reaping - return OriginalHook(RPR.Gibbet); + if (IsEnabled(CustomComboPreset.ReaperSoulReaverEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedGibbet)) + return OriginalHook(RPR.Gibbet); - if (HasEffect(RPR.Buffs.EnhancedGallows)) - // Cross Reaping - return OriginalHook(RPR.Gallows); - } + if (HasEffect(RPR.Buffs.EnhancedGallows)) + return OriginalHook(RPR.Gallows); + } - if (IsEnabled(CustomComboPreset.ReaperSliceGibbetFeature)) - // Void Reaping - return OriginalHook(RPR.Gibbet); + if (IsEnabled(CustomComboPreset.ReaperSliceGibbetFeature)) + return OriginalHook(RPR.Gibbet); - if (IsEnabled(CustomComboPreset.ReaperSliceGallowsFeature)) - // Cross Reaping return OriginalHook(RPR.Gallows); + } } if (IsEnabled(CustomComboPreset.ReaperComboPerfectioFeature)) @@ -179,6 +183,29 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return RPR.Perfectio; } + if (IsEnabled(CustomComboPreset.ReaperAutoSoulReaverFeature)) + { + // Blood Stalk if we're over 90 gauge, or if we're over 50 and the overcap-only feature isn't enabled, + // or if the auto-Soul Slice feature is enabled and our next action would otherwise be Soul Slice. + if (gauge.Soul >= 50 && (gauge.Soul > 90 || + !IsEnabled(CustomComboPreset.ReaperReaperAutoBloodStalkOvercapFeature) || + (IsEnabled(CustomComboPreset.ReaperAutoSoulSliceFeature) && + IsCooldownUsable(RPR.SoulSlice) && gauge.Soul > 50))) + { + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony)) + return RPR.Gluttony; + + return OriginalHook(RPR.BloodStalk); + } + } + + if (IsEnabled(CustomComboPreset.ReaperAutoSoulSliceFeature)) + { + if (IsCooldownUsable(RPR.SoulSlice) && gauge.Soul <= 50) + return RPR.SoulSlice; + } + if (IsEnabled(CustomComboPreset.ReaperSliceCombo)) { if (comboTime > 0) @@ -208,53 +235,77 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) + if (IsEnabled(CustomComboPreset.ReaperScytheSoulsowFeature)) { - if (IsEnabled(CustomComboPreset.ReaperScytheLemuresFeature)) - { - if (level >= RPR.Levels.LemuresScythe && gauge.VoidShroud >= 2) - return RPR.LemuresScythe; - } + if (level >= RPR.Levels.Soulsow && !InCombat() && !HasEffect(RPR.Buffs.Soulsow)) + return RPR.Soulsow; + } - if (IsEnabled(CustomComboPreset.ReaperSacrificiumFeature)) + if (level >= RPR.Levels.SoulReaver && + IsEnabled(CustomComboPreset.ReaperScytheGuillotineFeature)) + { + if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && gauge.LemureShroud < 5 && - (gauge.LemureShroud == 2 || !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature))) - return RPR.Sacrificium; - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) + { + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresScythe; + + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } + } - if (IsEnabled(CustomComboPreset.ReaperScytheCommunioFeature)) - { - if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) - return RPR.Communio; + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) + { + if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) + return RPR.Communio; + } + + return RPR.GrimReaping; } + + if (HasEffect(RPR.Buffs.SoulReaver) || HasEffect(RPR.Buffs.Executioner)) + return OriginalHook(RPR.Guillotine); } - if (IsEnabled(CustomComboPreset.ReaperScytheGuillotineFeature)) + if (IsEnabled(CustomComboPreset.ReaperComboPerfectioFeature)) { - if ((level >= RPR.Levels.SoulReaver && HasEffect(RPR.Buffs.SoulReaver)) || - (level >= RPR.Levels.Executioner && HasEffect(RPR.Buffs.Executioner)) || - (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0)) - // Grim Reaping - return OriginalHook(RPR.Guillotine); + if (level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) + return RPR.Perfectio; } if (IsEnabled(CustomComboPreset.ReaperScytheHarvestMoonFeature)) { - if (level >= RPR.Levels.HarvestMoon && HasEffect(RPR.Buffs.Soulsow) && HasTarget()) + if (level >= RPR.Levels.HarvestMoon && HasEffect(RPR.Buffs.Soulsow) && TargetIsEnemy()) return RPR.HarvestMoon; } - if (IsEnabled(CustomComboPreset.ReaperScytheSoulsowFeature)) + if (IsEnabled(CustomComboPreset.ReaperAutoSoulReaverFeature)) { - if (level >= RPR.Levels.Soulsow && !InCombat() && !HasEffect(RPR.Buffs.Soulsow)) - return RPR.Soulsow; + // Blood Stalk if we're over 90 gauge, or if we're over 50 and the overcap-only feature isn't enabled, + // or if the auto-Soul Slice feature is enabled and our next action would otherwise be Soul Slice. + if (gauge.Soul >= 50 && (gauge.Soul > 90 || + !IsEnabled(CustomComboPreset.ReaperReaperAutoBloodStalkOvercapFeature) || + (IsEnabled(CustomComboPreset.ReaperAutoSoulSliceFeature) && + IsCooldownUsable(RPR.SoulScythe) && gauge.Soul > 50))) + { + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony)) + return RPR.Gluttony; + + return OriginalHook(RPR.GrimSwathe); + } } - if (IsEnabled(CustomComboPreset.ReaperComboPerfectioFeature)) + if (IsEnabled(CustomComboPreset.ReaperAutoSoulSliceFeature)) { - if (level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) - return RPR.Perfectio; + if (IsCooldownUsable(RPR.SoulScythe) && gauge.Soul <= 50) + return RPR.SoulScythe; } if (IsEnabled(CustomComboPreset.ReaperScytheCombo)) @@ -283,38 +334,65 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (IsEnabled(CustomComboPreset.ReaperShadowSoulsowFeature)) - { - if (level >= RPR.Levels.Soulsow && !InCombat() && !HasEffect(RPR.Buffs.Soulsow)) - return RPR.Soulsow; - } - - if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) + if (level >= RPR.Levels.SoulReaver && + (IsEnabled(CustomComboPreset.ReaperShadowGibbetFeature) || + IsEnabled(CustomComboPreset.ReaperShadowGallowsFeature))) { - if (IsEnabled(CustomComboPreset.ReaperShadowLemuresFeature)) + if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0 && + (IsEnabled(CustomComboPreset.ReaperShadowGibbetEnshroudedFeature) || + IsEnabled(CustomComboPreset.ReaperShadowGallowsEnshroudedFeature))) { - if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) - return RPR.LemuresSlice; + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) + { + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresSlice; + + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } + } + + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) + { + if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) + return RPR.Communio; + } + + if (IsEnabled(CustomComboPreset.ReaperReapingEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedVoidReaping)) + return RPR.VoidReaping; + + if (HasEffect(RPR.Buffs.EnhancedCrossReaping)) + return RPR.CrossReaping; + } + + if (IsEnabled(CustomComboPreset.ReaperShadowGibbetEnshroudedFeature)) + return RPR.VoidReaping; + + return RPR.CrossReaping; } - if (IsEnabled(CustomComboPreset.ReaperShadowCommunioFeature)) + if (HasEffect(RPR.Buffs.SoulReaver) || HasEffect(RPR.Buffs.Executioner)) { - if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) - return RPR.Communio; - } - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedGibbet)) + return OriginalHook(RPR.Gibbet); - if ((level >= RPR.Levels.SoulReaver && HasEffect(RPR.Buffs.SoulReaver)) || - (level >= RPR.Levels.Executioner && HasEffect(RPR.Buffs.Executioner)) || - (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0)) - { - if (IsEnabled(CustomComboPreset.ReaperShadowGallowsFeature)) - // Cross Reaping - return OriginalHook(RPR.Gallows); + if (HasEffect(RPR.Buffs.EnhancedGallows)) + return OriginalHook(RPR.Gallows); + } - if (IsEnabled(CustomComboPreset.ReaperShadowGibbetFeature)) - // Void Reaping - return OriginalHook(RPR.Gibbet); + if (IsEnabled(CustomComboPreset.ReaperShadowGibbetFeature)) + return OriginalHook(RPR.Gibbet); + + return OriginalHook(RPR.Gallows); + } } } @@ -332,45 +410,76 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) + if (level >= RPR.Levels.SoulReaver && + (IsEnabled(CustomComboPreset.ReaperSoulGallowsFeature) || + IsEnabled(CustomComboPreset.ReaperSoulGibbetFeature))) { - if (IsEnabled(CustomComboPreset.ReaperSoulLemuresFeature)) + if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) - return RPR.LemuresSlice; + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) + { + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresSlice; + + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } + } + + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) + { + if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) + return RPR.Communio; + } + + if (IsEnabled(CustomComboPreset.ReaperReapingEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedVoidReaping)) + return RPR.VoidReaping; + + if (HasEffect(RPR.Buffs.EnhancedCrossReaping)) + return RPR.CrossReaping; + } + + if (IsEnabled(CustomComboPreset.ReaperSoulGibbetFeature)) + return RPR.VoidReaping; + + return RPR.CrossReaping; } - if (IsEnabled(CustomComboPreset.ReaperSoulCommunioFeature)) + if (HasEffect(RPR.Buffs.SoulReaver) || HasEffect(RPR.Buffs.Executioner)) { - if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) - return RPR.Communio; - } - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverEnhancedFeature)) + { + if (HasEffect(RPR.Buffs.EnhancedGibbet)) + return OriginalHook(RPR.Gibbet); - if ((level >= RPR.Levels.SoulReaver && HasEffect(RPR.Buffs.SoulReaver)) || - (level >= RPR.Levels.Executioner && HasEffect(RPR.Buffs.Executioner)) || - (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0)) - { - if (IsEnabled(CustomComboPreset.ReaperSoulGallowsFeature)) - // Cross Reaping - return OriginalHook(RPR.Gallows); + if (HasEffect(RPR.Buffs.EnhancedGallows)) + return OriginalHook(RPR.Gallows); + } - if (IsEnabled(CustomComboPreset.ReaperSoulGibbetFeature)) - // Void Reaping - return OriginalHook(RPR.Gibbet); - } + if (IsEnabled(CustomComboPreset.ReaperSoulGibbetFeature)) + return OriginalHook(RPR.Gibbet); - if (IsEnabled(CustomComboPreset.ReaperSoulOvercapFeature)) - { - if (IsEnabled(CustomComboPreset.ReaperBloodStalkGluttonyFeature)) - { - if (level >= RPR.Levels.Gluttony && gauge.Soul > 50 && gauge.EnshroudedTimeRemaining == 0 && IsCooldownUsable(RPR.Gluttony)) - return RPR.Gluttony; + return OriginalHook(RPR.Gallows); } - if (level >= RPR.Levels.BloodStalk && gauge.Soul > 50 && gauge.EnshroudedTimeRemaining == 0) - // Unveiled Gibbet and Gallows - return OriginalHook(RPR.BloodStalk); + if (IsEnabled(CustomComboPreset.ReaperAutoSoulReaverFeature)) + { + if (gauge.Soul >= 50 && (gauge.Soul > 50 || + !IsEnabled(CustomComboPreset.ReaperReaperAutoBloodStalkOvercapFeature))) + { + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony)) + return RPR.Gluttony; + + return OriginalHook(RPR.BloodStalk); + } + } } } @@ -388,16 +497,17 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (IsEnabled(CustomComboPreset.ReaperSoulScytheOvercapFeature)) + if (IsEnabled(CustomComboPreset.ReaperAutoSoulReaverFeature)) { - if (IsEnabled(CustomComboPreset.ReaperGrimSwatheGluttonyFeature)) + if (gauge.Soul >= 50 && (gauge.Soul > 50 || + !IsEnabled(CustomComboPreset.ReaperReaperAutoBloodStalkOvercapFeature))) { - if (level >= RPR.Levels.Gluttony && gauge.Soul >= 50 && gauge.EnshroudedTimeRemaining == 0 && IsCooldownUsable(RPR.Gluttony)) + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony)) return RPR.Gluttony; - } - if (level >= RPR.Levels.GrimSwathe && gauge.Soul > 50 && gauge.EnshroudedTimeRemaining == 0) - return RPR.GrimSwathe; + return OriginalHook(RPR.GrimSwathe); + } } } @@ -415,17 +525,25 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (IsEnabled(CustomComboPreset.ReaperBloodStalkGluttonyFeature)) + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature) && + level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony) && gauge.EnshroudedTimeRemaining == 0) - return RPR.Gluttony; - } + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresSlice; - if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) - { - if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && gauge.EnshroudedTimeRemaining > 0 && (gauge.VoidShroud < 2 || IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumPriorityFeature))) - return RPR.Sacrificium; + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } } + + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony) && + gauge.EnshroudedTimeRemaining == 0) + return RPR.Gluttony; } return actionID; @@ -442,17 +560,25 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if (IsEnabled(CustomComboPreset.ReaperGrimSwatheGluttonyFeature)) + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature) && + level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony) && gauge.EnshroudedTimeRemaining == 0) - return RPR.Gluttony; - } + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) + return RPR.LemuresScythe; - if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) - { - if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && gauge.EnshroudedTimeRemaining > 0 && (gauge.VoidShroud < 2 || IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumPriorityFeature))) - return RPR.Sacrificium; + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } } + + if (IsEnabled(CustomComboPreset.ReaperSoulReaverGluttonyFeature) && + level >= RPR.Levels.Gluttony && IsCooldownUsable(RPR.Gluttony) && + gauge.EnshroudedTimeRemaining == 0) + return RPR.Gluttony; } return actionID; @@ -469,17 +595,27 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { var gauge = GetJobGauge(); - if ((level >= RPR.Levels.SoulReaver && HasEffect(RPR.Buffs.SoulReaver)) || - (level >= RPR.Levels.Executioner && HasEffect(RPR.Buffs.Executioner)) || - (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0)) + if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (IsEnabled(CustomComboPreset.ReaperLemuresSoulReaverFeature)) + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) { + if (level >= RPR.Levels.Sacrificium && + IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (gauge.VoidShroud >= 2) + return RPR.LemuresSlice; + + if (HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) return RPR.LemuresSlice; } - if (IsEnabled(CustomComboPreset.ReaperCommunioSoulReaverFeature)) + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) { if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) return RPR.Communio; @@ -494,16 +630,17 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return RPR.CrossReaping; } - if (IsEnabled(CustomComboPreset.ReaperGibbetGallowsReaverFeature)) - { - if (HasEffect(RPR.Buffs.EnhancedGibbet)) - // Void Reaping - return OriginalHook(RPR.Gibbet); + return actionID; + } - if (HasEffect(RPR.Buffs.EnhancedGallows)) - // Cross Reaping - return OriginalHook(RPR.Gallows); - } + if (IsEnabled(CustomComboPreset.ReaperSoulReaverEnhancedFeature) && + (HasEffect(RPR.Buffs.SoulReaver) || HasEffect(RPR.Buffs.Executioner))) + { + if (HasEffect(RPR.Buffs.EnhancedGibbet)) + return OriginalHook(RPR.Gibbet); + + if (HasEffect(RPR.Buffs.EnhancedGallows)) + return OriginalHook(RPR.Gallows); } } @@ -513,13 +650,21 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (level >= RPR.Levels.Enshroud && gauge.EnshroudedTimeRemaining > 0) { - if (IsEnabled(CustomComboPreset.ReaperLemuresSoulReaverFeature)) + if (IsEnabled(CustomComboPreset.ReaperSoulReaverLemuresFeature)) { - if (level >= RPR.Levels.LemuresScythe && gauge.VoidShroud >= 2) + if (level >= RPR.Levels.EnhancedShroud && gauge.VoidShroud >= 2) return RPR.LemuresScythe; + + if (IsEnabled(CustomComboPreset.ReaperLemuresSacrificiumFeature)) + { + if (level >= RPR.Levels.Sacrificium && HasEffect(RPR.Buffs.Oblatio) && + (gauge.LemureShroud == 2 || (gauge.LemureShroud == 4 && + !IsEnabled(CustomComboPreset.ReaperSacrificiumAdvancedFeature)))) + return RPR.Sacrificium; + } } - if (IsEnabled(CustomComboPreset.ReaperCommunioSoulReaverFeature)) + if (IsEnabled(CustomComboPreset.ReaperSoulReaverCommunioFeature)) { if (level >= RPR.Levels.Communio && gauge.LemureShroud == 1) return RPR.Communio; @@ -571,11 +716,9 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (level >= RPR.Levels.PlentifulHarvest && HasEffect(RPR.Buffs.ImmortalSacrifice)) return RPR.PlentifulHarvest; - if (IsEnabled(CustomComboPreset.ReaperPerfectHarvestFeature)) - { - if (level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) + if (IsEnabled(CustomComboPreset.ReaperPerfectHarvestFeature) && + level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) return RPR.Perfectio; - } } } @@ -591,11 +734,9 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (actionID == RPR.PlentifulHarvest) { - if (IsEnabled(CustomComboPreset.ReaperPerfectHarvestFeature)) - { - if (level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) + if (IsEnabled(CustomComboPreset.ReaperPerfectHarvestFeature) && + level >= RPR.Levels.Perfectio && HasEffect(RPR.Buffs.PerfectioParata)) return RPR.Perfectio; - } } return actionID; @@ -610,23 +751,12 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (actionID == RPR.HellsEgress || actionID == RPR.HellsIngress) { - if (IsEnabled(CustomComboPreset.ReaperRegressFeature)) + if (level >= RPR.Levels.Regress && IsEnabled(CustomComboPreset.ReaperRegressFeature)) { - if (level >= RPR.Levels.Regress) - { - if (IsEnabled(CustomComboPreset.ReaperRegressOption)) - { - var threshold = FindEffect(RPR.Buffs.Threshold); - - if (threshold != null && threshold.RemainingTime <= 8.5) - return RPR.Regress; - } - else - { - if (HasEffect(RPR.Buffs.Threshold)) - return RPR.Regress; - } - } + var threshold = FindEffect(RPR.Buffs.Threshold); + if (threshold != null && (threshold.RemainingTime <= 8.5 || + IsEnabled(CustomComboPreset.ReaperRegressOption))) + return RPR.Regress; } } @@ -644,7 +774,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (IsEnabled(CustomComboPreset.ReaperHarpeHarvestSoulsowFeature)) { - if (level >= RPR.Levels.Soulsow && !HasEffect(RPR.Buffs.Soulsow) && (!InCombat() || !HasTarget())) + if (level >= RPR.Levels.Soulsow && !HasEffect(RPR.Buffs.Soulsow) && (!InCombat() || !TargetIsEnemy())) return RPR.Soulsow; } @@ -666,7 +796,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.ReaperHarpeHarvestMoonCombatFeature)) { - if (OutOfCombat()) + if (!InCombat()) return RPR.Harpe; } diff --git a/XIVComboExpanded/Combos/SGE.cs b/XIVComboExpanded/Combos/SGE.cs index 77ac35a54..60398706c 100644 --- a/XIVComboExpanded/Combos/SGE.cs +++ b/XIVComboExpanded/Combos/SGE.cs @@ -93,7 +93,7 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim { if (IsEnabled(CustomComboPreset.SageDosisPsyche)) { - if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && HasTarget() && InCombat()) + if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && TargetIsEnemy() && InCombat()) return OriginalHook(SGE.Psyche); } @@ -107,7 +107,8 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim return OriginalHook(SGE.Dosis); // have to explicitly check all variants of the dot for some reason else spaghetti code ensues - if (!(eurkasiandosis?.RemainingTime > 2.8 || eurkasiandosis2?.RemainingTime > 2.8 || eurkasiandosis3?.RemainingTime > 2.8)) + if (!(eurkasiandosis?.RemainingTime > 2.8 || eurkasiandosis2?.RemainingTime > 2.8 || + eurkasiandosis3?.RemainingTime > 2.8)) return SGE.Eukrasia; } @@ -118,9 +119,10 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim } } - if ((actionID == SGE.Dyskrasia || actionID == SGE.Dyskrasia2) && IsEnabled(CustomComboPreset.SagePsycheDyskrasiaFeature)) + if ((actionID == SGE.Dyskrasia || actionID == SGE.Dyskrasia2) && + IsEnabled(CustomComboPreset.SagePsycheDyskrasiaFeature)) { - if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && HasTarget() && InCombat()) + if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && TargetIsEnemy() && InCombat()) return OriginalHook(SGE.Psyche); } @@ -289,26 +291,26 @@ protected override uint Invoke(uint actionID, uint lastComboMove, float comboTim if (IsEnabled(CustomComboPreset.SagePhlegmaPsyche)) { - if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && HasTarget() && InCombat()) + if (level >= SGE.Levels.Psyche && IsCooldownUsable(SGE.Psyche) && TargetIsEnemy() && InCombat()) return OriginalHook(SGE.Psyche); } if (IsEnabled(CustomComboPreset.SagePhlegmaDyskrasia)) { - if (level >= SGE.Levels.Dyskrasia && HasNoTarget()) + if (level >= SGE.Levels.Dyskrasia && !TargetIsEnemy()) return OriginalHook(SGE.Dyskrasia); } - var gauge = GetJobGauge(); - if (IsEnabled(CustomComboPreset.SagePhlegmaToxikon)) { + var gauge = GetJobGauge(); var phlegma = level >= SGE.Levels.Phlegma3 ? SGE.Phlegma3 : level >= SGE.Levels.Phlegma2 ? SGE.Phlegma2 : level >= SGE.Levels.Phlegma ? SGE.Phlegma : 0; - if (level >= SGE.Levels.Toxicon && phlegma != 0 && !IsCooldownUsable(phlegma) && gauge.Addersting > 0) + if (level >= SGE.Levels.Toxicon && phlegma != 0 && !IsCooldownUsable(phlegma) && + gauge.Addersting > 0) return OriginalHook(SGE.Toxikon); } diff --git a/XIVComboExpanded/CustomCombo.cs b/XIVComboExpanded/CustomCombo.cs index 734149459..7ba98d290 100644 --- a/XIVComboExpanded/CustomCombo.cs +++ b/XIVComboExpanded/CustomCombo.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.JobGauge.Types; using Dalamud.Game.ClientState.Objects.Enums; @@ -5,8 +7,6 @@ using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Statuses; using Dalamud.Utility; -using System; -using System.Linq; using XIVComboExpandedPlugin.Attributes; namespace XIVComboExpandedPlugin.Combos; @@ -106,7 +106,7 @@ protected static uint CalcBestAction(uint original, params uint[] actions) (uint ActionID, CooldownData Data) a1, (uint ActionID, CooldownData Data) a2) { - // This intent of this priority algorithm is to generate a single unified number that results in the + // This intent of this priority algorithm is to generate a single unified number that results in the // following behaviors: // * Any ability that is off cooldown and at maximum charges has maximum (and equal) priority. // * If only one of the two abilities is currently usable, it has a higher priority. @@ -195,14 +195,6 @@ protected static bool IsOriginal(uint actionID) protected static bool IsEnabled(CustomComboPreset preset) => (int)preset < 100 || Service.Configuration.IsEnabled(preset); - /// - /// Determine if the given preset is not enabled. - /// - /// Preset to check. - /// A value indicating whether the preset is not enabled. - protected static bool IsNotEnabled(CustomComboPreset preset) - => !IsEnabled(preset); - /// /// Gets bool determining if action is greyed out or not. /// @@ -225,13 +217,6 @@ protected static bool HasCondition(ConditionFlag flag) protected static bool InCombat() => Service.Condition[ConditionFlag.InCombat]; - /// - /// Find if the player is not in combat. - /// - /// A value indicating whether the player is not in combat. - protected static bool OutOfCombat() - => !InCombat(); - /// /// Find if the player has a target. /// @@ -239,13 +224,6 @@ protected static bool OutOfCombat() protected static bool HasTarget() => CurrentTarget is not null; - /// - /// Find if the player has no target. - /// - /// A value indicating whether the player has a target. - protected static bool HasNoTarget() - => CurrentTarget is null; - /// /// Find if the current target is an enemy. /// diff --git a/XIVComboExpanded/CustomComboPreset.cs b/XIVComboExpanded/CustomComboPreset.cs index 928f9e373..362fa684a 100644 --- a/XIVComboExpanded/CustomComboPreset.cs +++ b/XIVComboExpanded/CustomComboPreset.cs @@ -1435,120 +1435,98 @@ public enum CustomComboPreset #endregion // ==================================================================================== #region REAPER + // Currently unused: 3913, 3914, 3915, 3919, 3920, 3921, 3922, 3923, 3924, 3927, 3928, 3929, 3935, 3941, 3946 [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.WaxingSlice, UTL.ArrowLeft, RPR.Slice])] - [SectionCombo("Single Target")] + [SectionCombo("Main Combos")] [CustomComboInfo("Slice Combo", "Replace Infernal Slice with its combo chain.", RPR.JobID)] ReaperSliceCombo = 3901, - [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.BloodStalk, UTL.Blank, UTL.Blank, UTL.Danger])] - [SectionCombo("Single Target")] - [AccessibilityCustomCombo] - [CustomComboInfo("Soul (Slice) Overcap Feature", "Replace Soul Slice with Blood Stalk not Enshrouded or Reaving and greater-than 50 Soul Gauge is present.", RPR.JobID)] - ReaperSoulOvercapFeature = 3934, - - [IconsCombo([RPR.BloodStalk, UTL.ArrowLeft, RPR.Gluttony])] - [SectionCombo("Single Target")] - [AccessibilityCustomCombo] - [CustomComboInfo("Blood Stalk Gluttony Feature", "Replace Blood Stalk with Gluttony when available.", RPR.JobID)] - ReaperBloodStalkGluttonyFeature = 3915, - - [IconsCombo([RPR.Harpe, UTL.ArrowLeft, RPR.HarvestMoon])] - [SectionCombo("Single Target")] - [ExpandedCustomCombo] - [CustomComboInfo("Harpe Harvest Moon Feature", "Replace Harpe with Harvest Moon when Soulsow is active and you are in combat.", RPR.JobID)] - ReaperHarpeHarvestMoonFeature = 3937, - - [IconsCombo([UTL.Forbidden, RPR.Buffs.EnhancedHarpe])] - [SectionCombo("Single Target")] - [ParentCombo(ReaperHarpeHarvestMoonFeature)] - [ExpandedCustomCombo] - [CustomComboInfo("Enhanced Harpe Option", "Prevent replacing Harpe with Harvest Moon when Enhanced Harpe is active.", RPR.JobID)] - ReaperHarpeHarvestMoonEnhancedFeature = 3939, - - [IconsCombo([UTL.Forbidden, UTL.OutOfBattle])] - [SectionCombo("Single Target")] - [ParentCombo(ReaperHarpeHarvestMoonFeature)] - [ExpandedCustomCombo] - [CustomComboInfo("Harpe Harvest Moon Only In Combat", "Prevent replacing Harpe with Harvest Moon when not in combat.", RPR.JobID)] - ReaperHarpeHarvestMoonCombatFeature = 3938, - [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.SpinningScythe])] - [SectionCombo("Area of Effect")] + [SectionCombo("Main Combos")] [CustomComboInfo("Scythe Combo", "Replace Nightmare Scythe with its combo chain.", RPR.JobID)] ReaperScytheCombo = 3902, - [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.HarvestMoon])] - [SectionCombo("Area of Effect")] - [AccessibilityCustomCombo] - [CustomComboInfo("Scythe Harvest Moon Feature", "Replace Nightmare Scythe with Harvest Moon when Soulsow is active and you have a target.", RPR.JobID)] - ReaperScytheHarvestMoonFeature = 3932, + [IconsCombo([RPR.BloodStalk, RPR.GrimSwathe, UTL.ArrowLeft, RPR.Gluttony])] + [SectionCombo("Soul Gauge")] + [ExpandedCustomCombo] + [CustomComboInfo("Soul Reaver Gluttony Feature", "Replace Blood Stalk and Grim Swathe with Gluttony whenever it is available. This also applies to any other features that replace other actions with Blood Stalk or Grim Swathe.", RPR.JobID)] + ReaperSoulReaverGluttonyFeature = 3916, - [IconsCombo([RPR.GrimSwathe, UTL.ArrowLeft, RPR.Gluttony])] - [SectionCombo("Area of Effect")] + [IconsCombo([RPR.InfernalSlice, RPR.NightmareScythe, UTL.ArrowLeft, RPR.SoulSlice, RPR.SoulScythe, UTL.Blank, UTL.Idea, UTL.Danger])] + [SectionCombo("Soul Gauge")] [AccessibilityCustomCombo] - [CustomComboInfo("Grim Swathe Gluttony Feature", "Replace Grim Swathe with Gluttony when available.", RPR.JobID)] - ReaperGrimSwatheGluttonyFeature = 3916, + [CustomComboInfo("Automatic Soul Slice", "Replace Infernal Slice with Soul Slice and Nightmare Scythe with Soul Scythe when a charge is available, you are not Reaving or Enshrouded, and you have 50 gauge or less.\n\nNOTE: This will not overcap your gauge by itself, but can easily cause you to overcap with a follow-up GCD when you suddenly gain much more gauge from a GCD than you expected. It is highly recommended to also enable the Automatic Soul Reaver feature to avoid this.", RPR.JobID)] + ReaperAutoSoulSliceFeature = 3951, - [IconsCombo([RPR.SoulScythe, UTL.ArrowLeft, RPR.GrimSwathe, UTL.Blank, UTL.Blank, UTL.Danger])] - [SectionCombo("Area of Effect")] + [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.BloodStalk, UTL.Blank, UTL.Blank, UTL.Idea])] + [SectionCombo("Soul Gauge")] [AccessibilityCustomCombo] - [CustomComboInfo("Soul (Scythe) Overcap Feature", "Replace Soul Scythe with Grim Swathe when not Enshrouded or Reaving and greater-than 50 Soul Gauge is present.", RPR.JobID)] - ReaperSoulScytheOvercapFeature = 3935, + [CustomComboInfo("Automatic Soul Reaver", "Replace all Soul Gauge generating abilities with Blood Stalk or Grim Swathe when at 50 or greater Soul Gauge and you're not currently Reaving or Enshrouded. This does NOT apply to Harpe or Harvest Moon, however, since those are ranged attacks and also rarely used.\n\nNOTE: This can cause you to miss positionals or use the incorrect Reaving ability if you're not expecting the Blood Stalk usage. It also has a very high chance of delaying your usage of Gluttony by not having enough gauge available when it comes off cooldown.", RPR.JobID)] + ReaperAutoSoulReaverFeature = 3934, + + [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.BloodStalk, UTL.Blank, UTL.Blank, UTL.Danger])] + [SectionCombo("Soul Gauge")] + [ParentCombo(ReaperAutoSoulReaverFeature)] + [SecretCustomCombo] + [CustomComboInfo("Soul Reaver Overcap", "Only replace Soul Gauge generating abilities if their next usage would overcap Soul Gauge.\n\nNOTE: This will cause Soul Slice and Soul Scythe to be replaced much earlier than other actions, due to their greater gauge generation.", RPR.JobID)] + ReaperReaperAutoBloodStalkOvercapFeature = 3948, [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Gibbet])] [SectionCombo("Soul Reaver")] [ConflictingCombos(ReaperSliceGallowsFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Slice Gibbet Feature", "Replace Infernal Slice with Gibbet while Reaving or Enshrouded.", RPR.JobID)] + [CustomComboInfo("Slice Gibbet Feature", "Replace Infernal Slice with Gibbet while Reaving and Void Reaping while Enshrouded.", RPR.JobID)] ReaperSliceGibbetFeature = 3903, [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Gallows])] [SectionCombo("Soul Reaver")] [ConflictingCombos(ReaperSliceGibbetFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Slice Gallows Feature", "Replace Infernal Slice with Gallows while Reaving or Enshrouded.", RPR.JobID)] + [CustomComboInfo("Slice Gallows Feature", "Replace Infernal Slice with Gallows while Reaving and Cross Reaping while Enshrouded.", RPR.JobID)] ReaperSliceGallowsFeature = 3904, [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.Gibbet])] [SectionCombo("Soul Reaver")] [ConflictingCombos(ReaperSoulGallowsFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Soul Gibbet Feature", "Replace Soul Slice with Gibbet while Reaving or Enshrouded.", RPR.JobID)] + [CustomComboInfo("Soul Gibbet Feature", "Replace Soul Slice with Gibbet while Reaving and Void Reaping while Enshrouded.", RPR.JobID)] ReaperSoulGibbetFeature = 3926, [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.Gallows])] [SectionCombo("Soul Reaver")] [ConflictingCombos(ReaperSoulGibbetFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Soul Gallows Feature", "Replace Soul Slice with Gallows while Reaving or Enshrouded.", RPR.JobID)] + [CustomComboInfo("Soul Gallows Feature", "Replace Soul Slice with Gallows while Reaving and Cross Reaping while Enshrouded.", RPR.JobID)] ReaperSoulGallowsFeature = 3925, [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.Gibbet])] [SectionCombo("Soul Reaver")] [ConflictingCombos(ReaperShadowGallowsFeature)] [AccessibilityCustomCombo] - [CustomComboInfo("Shadow Gibbet Feature", "Replace Shadow of Death with Gibbet while Reaving or Enshrouded.\nNOTE: This feature can be very problematic and is not recommended, since Shadow of Death is one of the few abilities than can be and is commonly used during Enshroud.", RPR.JobID)] + [CustomComboInfo("Shadow Gibbet Feature", "Replace Shadow of Death with Gibbet while Reaving (but NOT while Enshrouded).\n\nNOTE: Unlike the features for Slice and Soul Slice for Gibbet/Gallows, this feature only works when Reaving, not while Enshrouded. There is a subfeature available below to also work while Enshrouded.", RPR.JobID)] ReaperShadowGibbetFeature = 3906, - [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.Gallows])] + [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.BloodStalk, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Danger])] [SectionCombo("Soul Reaver")] - [ConflictingCombos(ReaperShadowGibbetFeature)] + [ParentCombo(ReaperShadowGibbetFeature)] [AccessibilityCustomCombo] - [CustomComboInfo("Shadow Gallows Feature", "Replace Shadow of Death with Gallows while Reaving or Enshrouded.\nNOTE: This feature can be very problematic and is not recommended, since Shadow of Death is one of the few abilities than can be and is commonly used during Enshroud.", RPR.JobID)] - ReaperShadowGallowsFeature = 3905, + [CustomComboInfo("Shadow Gibbet while Enshrouded", "Also replace Soul Slice when Enshrouded\n\nNOTE: This feature COMPLETELY prevents usage of Shadow of Death during Enshroud, which is a common element of Reaper gameplay, both for refreshing an expiring debuff and for delaying Communio when near raid buff windows. It is strongly recommended not to use this feature, and to either use the Soul Slice Gibbet feature instead of the Shadow Gibbet one, or use the Slice Enhanced Enshrouded Feature to place all of the Enshrouded actions on the Slice/Scythe combo buttons instead.", RPR.JobID)] + ReaperShadowGibbetEnshroudedFeature = 3949, - [IconsCombo([RPR.Gibbet, UTL.Cycle, RPR.Gallows])] + [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.Gallows])] [SectionCombo("Soul Reaver")] + [ConflictingCombos(ReaperShadowGibbetFeature)] [AccessibilityCustomCombo] - [CustomComboInfo("Gibbet/Gallows Enhanced Feature", "Replace Gibbet and Gallows with whichever is currently enhanced while Reaving.", RPR.JobID)] - ReaperGibbetGallowsReaverFeature = 3917, + [CustomComboInfo("Shadow Gallows Feature", "Replace Shadow of Death with Gallows while Reaving or Enshrouded.\n\nNOTE: Unlike the features for Slice and Soul Slice for Gibbet/Gallows, this feature only works when Reaving, not while Enshrouded. There is a subfeature available below to also work while Enshrouded.", RPR.JobID)] + ReaperShadowGallowsFeature = 3905, - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Gibbet, UTL.Cycle, RPR.Gallows])] + [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.BloodStalk, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Danger])] [SectionCombo("Soul Reaver")] + [ParentCombo(ReaperShadowGallowsFeature)] [AccessibilityCustomCombo] - [CustomComboInfo("Slice Enhanced Soul Reaver Feature", "Replace Infernal Slice with whichever of Gibbet or Gallows is currently enhanced while Reaving.\nNOTE: This can cause you to miss positionals.", RPR.JobID)] - ReaperSliceEnhancedSoulReaverFeature = 3913, + [CustomComboInfo("Shadow Gallows while Enshrouded", "Also replace Soul Slice when Enshrouded\n\nNOTE: This feature COMPLETELY prevents usage of Shadow of Death during Enshroud, which is a common element of Reaper gameplay, both for refreshing an expiring debuff and for delaying Communio when near raid buff windows. It is strongly recommended not to use this feature, and to either use the Soul Slice Gallows feature instead of the Shadow Gibbet one, or use the Slice Enhanced Enshrouded Feature to place all of the Enshrouded actions on the Slice/Scythe combo buttons instead.", RPR.JobID)] + ReaperShadowGallowsEnshroudedFeature = 3950, [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.Guillotine])] [SectionCombo("Soul Reaver")] @@ -1556,172 +1534,131 @@ public enum CustomComboPreset [CustomComboInfo("Scythe Guillotine Feature", "Replace Nightmare Scythe with Guillotine while Reaving or Enshrouded.", RPR.JobID)] ReaperScytheGuillotineFeature = 3907, - [IconsCombo([RPR.Enshroud, UTL.ArrowLeft, RPR.Communio, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Checkmark])] - [SectionCombo("Enshroud")] - [CustomComboInfo("Enshroud Communio Feature", "Replace Enshroud with Communio when Enshrouded.", RPR.JobID)] - ReaperEnshroudCommunioFeature = 3909, - - [IconsCombo([RPR.Enshroud, UTL.ArrowLeft, RPR.Perfectio, UTL.Blank, RPR.Buffs.PerfectioParata, UTL.Checkmark])] - [SectionCombo("Enshroud")] - [ExpandedCustomCombo] - [CustomComboInfo("Enshroud Perfectio Feature", "Replace Enshroud with Perfectio when available.", RPR.JobID)] - ReaperEnshroudPerfectioFeature = 3945, - - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.LemuresSlice, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Slice Lemure's Feature", "Replace Infernal Slice with Lemure's Slice when two or more stacks of Void Shroud are active.", RPR.JobID)] - ReaperSliceLemuresFeature = 3919, - - [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.LemuresSlice, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Soul Lemure's Feature", "Replace Soul Slice with Lemure's Slice when two or more stacks of Void Shroud are active.", RPR.JobID)] - ReaperSoulLemuresFeature = 3927, - - [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.LemuresSlice, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Shadow Lemure's Feature", "Replace Shadow of Death with Lemure's Slice when two or more stacks of Void Shroud are active.\nNOTE: This feature can be very problematic and is not recommended, since Shadow of Death is one of the few abilities than can be and is commonly used during Enshroud.", RPR.JobID)] - ReaperShadowLemuresFeature = 3923, - - [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.LemuresScythe, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Scythe Lemure's Feature", "Replace Nightmare Scythe with Lemure's Scythe when two or more stacks of Void Shroud are active.", RPR.JobID)] - ReaperScytheLemuresFeature = 3921, - - [IconsCombo([RPR.Gibbet, RPR.Gallows, RPR.Guillotine, UTL.ArrowLeft, RPR.LemuresSlice, RPR.LemuresScythe, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Soul Reaver Lemure's Feature", "Replace Gibbet and Gallows with Lemure's Slice and Guillotine with Lemure's Scythe when two or more stacks of Void Shroud are active.", RPR.JobID)] - ReaperLemuresSoulReaverFeature = 3911, - - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Slice Communio Feature", "Replace Infernal Slice with Communio when one stack of Shroud is left.", RPR.JobID)] - ReaperSliceCommunioFeature = 3920, - - [IconsCombo([RPR.SoulSlice, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Soul Communio Feature", "Replace Soul Slice with Communio when one stack of Shroud is left.", RPR.JobID)] - ReaperSoulCommunioFeature = 3928, - - [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Shadow Communio Feature", "Replace Shadow of Death with Communio when one stack of Shroud is left.\nNOTE: This feature can be very problematic and is not recommended, since Shadow of Death is one of the few abilities than can be and is commonly used during Enshroud.", RPR.JobID)] - ReaperShadowCommunioFeature = 3924, - - [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] - [SectionCombo("Enshroud")] + [IconsCombo([RPR.Gibbet, UTL.Cycle, RPR.Gallows])] + [SectionCombo("Soul Reaver")] [AccessibilityCustomCombo] - [CustomComboInfo("Scythe Communio Feature", "Replace Nightmare Scythe with Communio when one stack is left of Shroud.", RPR.JobID)] - ReaperScytheCommunioFeature = 3922, + [CustomComboInfo("Soul Reaver Enhanced Feature", "Replace Gibbet and Gallows with whichever is currently enhanced while Reaving. This also applies to any other features that replace other actions with Gibbet or Gallows.\n\nNOTE: This can cause you to miss positionals on Gibbet and Gallows. ", RPR.JobID)] + ReaperSoulReaverEnhancedFeature = 3917, - [IconsCombo([RPR.Gibbet, RPR.Gallows, RPR.Guillotine, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] + [IconsCombo([RPR.CrossReaping, UTL.Cycle, RPR.VoidReaping, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Checkmark])] [SectionCombo("Enshroud")] [AccessibilityCustomCombo] - [CustomComboInfo("Soul Reaver Communio Feature", "Replace Gibbet, Gallows, and Guillotine with Communio when one stack is left of Shroud.", RPR.JobID)] - ReaperCommunioSoulReaverFeature = 3912, + [CustomComboInfo("Reaping Enhanced Feature", "Replace Void Reaping and Cross Reaping with whichever is currently enhanced while Enshrouded. This also applies to any other features that replace other actions with Void Reaping or Cross Reaping.", RPR.JobID)] + ReaperReapingEnhancedFeature = 3918, - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.VoidReaping, RPR.CrossReaping, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Checkmark])] + [IconsCombo([RPR.VoidReaping, RPR.CrossReaping, RPR.GrimReaping, UTL.ArrowLeft, RPR.Communio, UTL.Blank, UTL.Blank, UTL.Idea])] [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Slice Enhanced Enshrouded Feature", "Replace Infernal Slice with whichever of Void Reaping or Cross Reaping is currently enhanced while Enshrouded.", RPR.JobID)] - ReaperSliceEnhancedEnshroudedFeature = 3914, + [ExpandedCustomCombo] + [CustomComboInfo("Reaping Communio Feature", "Replace Void Reaping, Cross Reaping, and Grim Reaping with Communio when one stack of Shroud is left. This also applies to any other features that replace other actions with Void Reaping, Cross Reaping, or Grim Reaping.", RPR.JobID)] + ReaperSoulReaverCommunioFeature = 3912, - [IconsCombo([RPR.CrossReaping, UTL.Cycle, RPR.VoidReaping, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Checkmark])] + [IconsCombo([RPR.VoidReaping, RPR.CrossReaping, RPR.GrimReaping, UTL.ArrowLeft, RPR.LemuresSlice, RPR.LemuresScythe, UTL.Blank, UTL.Blank, UTL.Idea])] [SectionCombo("Enshroud")] [AccessibilityCustomCombo] - [CustomComboInfo("Reaping Enhanced Feature", "Replace Void Reaping and Cross Reaping with whichever is currently enhanced while Enshrouded.", RPR.JobID)] - ReaperReapingEnhancedFeature = 3918, + [CustomComboInfo("Reaping Lemure's Feature", "Replace Void Reaping and Cross Reaping with Lemure's Slice and Grim Reaping with Lemure's Scythe when two or more stacks of Void Shroud are active. This also applies to any other features that replace other actions with Void Reaping, Cross Reaping, or Grim Reaping.", RPR.JobID)] + ReaperSoulReaverLemuresFeature = 3911, - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Sacrificium, UTL.Blank, RPR.Buffs.Oblatio, UTL.Checkmark, UTL.Plus, RPR.Buffs.Enshrouded, UTL.Checkmark])] + [IconsCombo([RPR.LemuresSlice, RPR.LemuresScythe, UTL.ArrowLeft, RPR.Sacrificium, UTL.Blank, RPR.Buffs.Oblatio, UTL.Checkmark])] [SectionCombo("Enshroud")] - [AccessibilityCustomCombo] - [CustomComboInfo("Sacrificium Feature", "Replace Infernal Slice and Nightmare Scythe with Sacrificium when available.", RPR.JobID)] - ReaperSacrificiumFeature = 3946, + [ExpandedCustomCombo] + [CustomComboInfo("Lemure's Sacrificium Feature", "Replace Lemure's Slice/Scythe with Sacrificium when available and you have fewer than 2 Void Shroud. This also applies to any other features that replace other actions with Lemure's Slice or Lemure's Scythe.", RPR.JobID)] + ReaperLemuresSacrificiumFeature = 3940, - [IconsCombo([UTL.Clock])] + [IconsCombo([RPR.Sacrificium, UTL.Clock])] [SectionCombo("Enshroud")] [SecretCustomCombo] - [ParentCombo(ReaperSacrificiumFeature)] - [CustomComboInfo("Sacrificium 3rd weave", "Replace Infernal Slice and Nightmare Scythe with Sacrificium during the 3rd Enshroud weave window instead of the 1st. Can be superior for certain cooldown windows.", RPR.JobID)] + [ParentCombo(ReaperLemuresSacrificiumFeature)] + [CustomComboInfo("Sacrificium 3rd weave", "Only replace Lemure's Slice/Scythe with Sacrificium when you have used 3 of the 5 Lemure's Shroud charges (ie. after the third Void/Cross Reaping).\n\nNOTE: This can be superior for certain cooldown windows, due to the first weave window often occurring before raid buffs are active during a double Enshroud sequence.", RPR.JobID)] ReaperSacrificiumAdvancedFeature = 3947, - [IconsCombo([RPR.LemuresSlice, RPR.LemuresScythe, UTL.ArrowLeft, RPR.Sacrificium, UTL.Blank, RPR.Buffs.Oblatio, UTL.Checkmark, UTL.Plus, RPR.Buffs.Enshrouded, UTL.Checkmark])] + [IconsCombo([RPR.Enshroud, UTL.ArrowLeft, RPR.Communio, UTL.Blank, RPR.Buffs.Enshrouded, UTL.Checkmark])] [SectionCombo("Enshroud")] - [ExpandedCustomCombo] - [CustomComboInfo("Lemure's Sacrificium Feature", "Replace Lemure's Slice/Scythe with Sacrificium when available and you have fewer than 2 Void Shroud.", RPR.JobID)] - ReaperLemuresSacrificiumFeature = 3940, + [CustomComboInfo("Enshroud Communio Feature", "Replace Enshroud with Communio when Enshrouded.", RPR.JobID)] + ReaperEnshroudCommunioFeature = 3909, - [IconsCombo([RPR.Sacrificium, UTL.ArrowUp])] + [IconsCombo([RPR.Enshroud, UTL.ArrowLeft, RPR.Perfectio, UTL.Blank, RPR.Buffs.PerfectioParata, UTL.Checkmark])] [SectionCombo("Enshroud")] - [ParentCombo(ReaperLemuresSacrificiumFeature)] - [SecretCustomCombo] - [CustomComboInfo("Prioritize Sacrificium over Lemure's", "Replace Lemure's Slice/Scythe with Sacrificium even when you have 2 Void Shroud. This can help ensure you do not miss a usage of Sacrificium, at the cost of potentially missing a Lemure's Slice/Scythe usage.", RPR.JobID)] - ReaperLemuresSacrificiumPriorityFeature = 3941, + [ExpandedCustomCombo] + [CustomComboInfo("Enshroud Perfectio Feature", "Replace Enshroud with Perfectio when available.", RPR.JobID)] + ReaperEnshroudPerfectioFeature = 3945, [IconsCombo([RPR.ArcaneCircle, UTL.ArrowLeft, RPR.PlentifulHarvest, UTL.Blank, RPR.Buffs.ImmortalSacrifice, UTL.Checkmark])] - [SectionCombo("Miscellaneous")] + [SectionCombo("Arcane Circle")] [CustomComboInfo("Arcane Harvest Feature", "Replace Arcane Circle with Plentiful Harvest when you have stacks of Immortal Sacrifice.", RPR.JobID)] ReaperArcaneHarvestFeature = 3908, [IconsCombo([RPR.PlentifulHarvest, UTL.ArrowLeft, RPR.Perfectio, UTL.Blank, RPR.Buffs.PerfectioParata, UTL.Checkmark])] - [SectionCombo("Miscellaneous")] + [SectionCombo("Arcane Circle")] [ExpandedCustomCombo] - [CustomComboInfo("Perfect Harvest Feature", "Replace Plentiful Harvest with Perfectio when available. Also replaces Arcane Circle if the Arcane Harvest Feature is also enabled.", RPR.JobID)] + [CustomComboInfo("Perfect Harvest Feature", "Replace Plentiful Harvest with Perfectio when available. This also applies to any other features that replace other actions with Plentiful Harvest.", RPR.JobID)] ReaperPerfectHarvestFeature = 3943, [IconsCombo([RPR.InfernalSlice, RPR.NightmareScythe, UTL.ArrowLeft, RPR.Perfectio, UTL.Blank, RPR.Buffs.PerfectioParata, UTL.Checkmark])] - [SectionCombo("Miscellaneous")] - [ExpandedCustomCombo] + [SectionCombo("Arcane Circle")] + [AccessibilityCustomCombo] [CustomComboInfo("Combo Perfectio Feature", "Replace Infernal Slice and Nightmare Scythe with Perfectio when under Perfectio Parata.", RPR.JobID)] ReaperComboPerfectioFeature = 3942, [IconsCombo([RPR.Harpe, UTL.ArrowLeft, RPR.Perfectio, UTL.Blank, RPR.Buffs.PerfectioParata, UTL.Checkmark])] - [SectionCombo("Miscellaneous")] + [SectionCombo("Arcane Circle")] [ExpandedCustomCombo] [CustomComboInfo("Harpe Perfectio Feature", "Replace Harpe with with Perfectio when under Perfectio Parata.", RPR.JobID)] ReaperHarpePerfectioFeature = 3944, - [IconsCombo([RPR.HellsIngress, RPR.HellsEgress, UTL.ArrowLeft, RPR.Regress])] + [IconsCombo([RPR.HellsIngress, RPR.HellsEgress, UTL.ArrowLeft, RPR.Regress, UTL.Blank, RPR.Buffs.Threshold])] [SectionCombo("Miscellaneous")] [CustomComboInfo("Regress Feature", "Replace Hell's Ingress and Egress turn with Regress when Threshold is active, instead of just the opposite of the one used.", RPR.JobID)] ReaperRegressFeature = 3910, - [IconsCombo([UTL.Clock])] + [IconsCombo([RPR.Buffs.Threshold, UTL.Clock])] [SectionCombo("Miscellaneous")] [ParentCombo(ReaperRegressFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Delayed Regress Option", "Replace the action used with Regress only after 1.5 seconds have elapsed on Threshold.", RPR.JobID)] + [CustomComboInfo("Delayed Regress Option", "Replace the action used with Regress only after 1.5 seconds have elapsed on Threshold.\n\nNOTE: This is to prevent you from immediately using Regress if you are spamming the button for the teleport.", RPR.JobID)] ReaperRegressOption = 3933, - [IconsCombo([RPR.Harpe, UTL.ArrowLeft, RPR.Soulsow])] - [SectionCombo("Out of Combat")] + [IconsCombo([RPR.Harpe, UTL.ArrowLeft, RPR.HarvestMoon])] + [SectionCombo("Harvest Moon")] [ExpandedCustomCombo] - [CustomComboInfo("Harpe Soulsow Feature", "Replace Harpe with Soulsow when not active and out of combat or you have no target.", RPR.JobID)] - ReaperHarpeHarvestSoulsowFeature = 3936, + [CustomComboInfo("Harpe Harvest Moon Feature", "Replace Harpe with Harvest Moon when Soulsow is active.", RPR.JobID)] + ReaperHarpeHarvestMoonFeature = 3937, - [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Soulsow])] - [SectionCombo("Out of Combat")] + [IconsCombo([UTL.Forbidden, RPR.Buffs.EnhancedHarpe])] + [SectionCombo("Harvest Moon")] + [ParentCombo(ReaperHarpeHarvestMoonFeature)] [ExpandedCustomCombo] - [CustomComboInfo("Slice Soulsow Feature", "Replace Infernal Slice with Soulsow when out of combat and not active.", RPR.JobID)] - ReaperSliceSoulsowFeature = 3930, + [CustomComboInfo("Enhanced Harpe Option", "Prevent replacing Harpe with Harvest Moon when Enhanced Harpe is active.", RPR.JobID)] + ReaperHarpeHarvestMoonEnhancedFeature = 3939, + + [IconsCombo([UTL.Forbidden, UTL.OutOfBattle])] + [SectionCombo("Harvest Moon")] + [ParentCombo(ReaperHarpeHarvestMoonFeature)] + [ExpandedCustomCombo] + [CustomComboInfo("Harpe Harvest Moon Only In Combat", "Prevent replacing Harpe with Harvest Moon when not in combat.", RPR.JobID)] + ReaperHarpeHarvestMoonCombatFeature = 3938, - [IconsCombo([RPR.ShadowOfDeath, UTL.ArrowLeft, RPR.Soulsow])] - [SectionCombo("Out of Combat")] + [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.HarvestMoon])] + [SectionCombo("Harvest Moon")] + [AccessibilityCustomCombo] + [CustomComboInfo("Scythe Harvest Moon Feature", "Replace Nightmare Scythe with Harvest Moon when Soulsow is active, you have an enemy target, and are not Reaving or Enshrouded.", RPR.JobID)] + ReaperScytheHarvestMoonFeature = 3932, + + [IconsCombo([RPR.Harpe, UTL.ArrowLeft, RPR.Soulsow, UTL.Blank, UTL.OutOfBattle])] + [SectionCombo("Harvest Moon")] [ExpandedCustomCombo] - [CustomComboInfo("Shadow Soulsow Feature", "Replace Shadow of Death with Soulsow when out of combat and not active.", RPR.JobID)] - ReaperShadowSoulsowFeature = 3929, + [CustomComboInfo("Harpe Soulsow Feature", "Replace Harpe with Soulsow when not active and you're either out of combat or have no target.", RPR.JobID)] + ReaperHarpeHarvestSoulsowFeature = 3936, + + [IconsCombo([RPR.InfernalSlice, UTL.ArrowLeft, RPR.Soulsow, UTL.Blank, UTL.OutOfBattle])] + [SectionCombo("Harvest Moon")] + [ExpandedCustomCombo] + [CustomComboInfo("Slice Soulsow Feature", "Replace Infernal Slice with Soulsow when not active and out of combat.", RPR.JobID)] + ReaperSliceSoulsowFeature = 3930, - [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.Soulsow])] - [SectionCombo("Out of Combat")] + [IconsCombo([RPR.NightmareScythe, UTL.ArrowLeft, RPR.Soulsow, UTL.Blank, UTL.OutOfBattle])] + [SectionCombo("Harvest Moon")] [ExpandedCustomCombo] - [CustomComboInfo("Scythe Soulsow Feature", "Replace Nightmare Scythe with Soulsow when out of combat and not active.", RPR.JobID)] + [CustomComboInfo("Scythe Soulsow Feature", "Replace Nightmare Scythe with Soulsow when not active and out of combat.", RPR.JobID)] ReaperScytheSoulsowFeature = 3931, #endregion diff --git a/XIVComboExpanded/Interface/Changelog.cs b/XIVComboExpanded/Interface/Changelog.cs index 7b7922aa3..62d4602d5 100644 --- a/XIVComboExpanded/Interface/Changelog.cs +++ b/XIVComboExpanded/Interface/Changelog.cs @@ -12,6 +12,14 @@ public static Dictionary GetChangelog() { return new Dictionary() { + { + "v2.0.0.10", + [ + "Rewrote RPR features and logic, combining many prior ones and updating interactions. @kaedys", + "Implemented RPR automatic Soul Slice feature. @kaedys", + "Removed Sacrificium Priority and Soulsow on Shadow of Death features. @kaedys", + ] + }, { "v2.0.0.9", [