diff --git a/BasicRotations/Healer/AST_Default.cs b/BasicRotations/Healer/AST_Default.cs
index ea94af96..86bec5d6 100644
--- a/BasicRotations/Healer/AST_Default.cs
+++ b/BasicRotations/Healer/AST_Default.cs
@@ -24,6 +24,9 @@ public sealed class AST_Default : AstrologianRotation
[RotationConfig(CombatType.PvE, Name = "Simple Lord of Crowns logic (use under divinaiton)")]
public bool SimpleLord { get; set; } = false;
+ [RotationConfig(CombatType.PvE, Name = "Detonate Earlthy Star when you have Giant Dominance")]
+ public bool StellarNow { get; set; } = false;
+
[Range(4, 20, ConfigUnitType.Seconds)]
[RotationConfig(CombatType.PvE, Name = "Use Earthly Star during countdown timer.")]
public float UseEarthlyStarTime { get; set; } = 15;
@@ -85,6 +88,8 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
if (DivinationPvE.CanUse(out _)
&& UseBurstMedicine(out act)) return true;
+ if (StellarNow && Player.HasStatus(true, StatusID.GiantDominance) && StellarDetonationPvE.CanUse(out act)) return true;
+
return base.EmergencyAbility(nextGCD, out act);
}
diff --git a/BasicRotations/Healer/SGE_Default.cs b/BasicRotations/Healer/SGE_Default.cs
index f9f122e5..919130be 100644
--- a/BasicRotations/Healer/SGE_Default.cs
+++ b/BasicRotations/Healer/SGE_Default.cs
@@ -406,7 +406,7 @@ protected override bool HealAreaGCD(out IAction? act)
if (PneumaPvE.CanUse(out act)) return true;
}
- if (_EukrasiaActionAim != null && PrognosisPvE.CanUse(out act))
+ if (_EukrasiaActionAim == null && PrognosisPvE.CanUse(out act))
{
return true;
}
@@ -419,7 +419,7 @@ protected override bool HealSingleGCD(out IAction? act)
{
act = null;
if (IsLastAction(ActionID.SwiftcastPvE) && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false;
- if (_EukrasiaActionAim != null && DiagnosisPvE.CanUse(out act))
+ if (_EukrasiaActionAim == null && DiagnosisPvE.CanUse(out act))
{
return true;
}
@@ -453,13 +453,13 @@ protected override bool GeneralGCD(out IAction? act)
if (DoEukrasianDyskrasia(out act)) return true;
- if ((_EukrasiaActionAim != EukrasianDiagnosisPvE || _EukrasiaActionAim != EukrasianPrognosisPvE || _EukrasiaActionAim != EukrasianPrognosisIiPvE || _EukrasiaActionAim != EukrasianDyskrasiaPvE)
+ if ((_EukrasiaActionAim == null)
&& DyskrasiaPvE.CanUse(out act)) return true;
if (DoEukrasianPrognosis(out act)) return true;
if (DoEukrasianDiagnosis(out act)) return true;
- if ( DoEukrasianDosis(out act)) return true;
+ if (DoEukrasianDosis(out act)) return true;
if (DosisPvE.CanUse(out act)) return true;
if (OOCEukrasia && !InCombat && !Player.HasStatus(true, StatusID.Eukrasia) && EukrasiaPvE.CanUse(out act)) return true;
diff --git a/BasicRotations/Melee/NIN_Default.cs b/BasicRotations/Melee/NIN_Default.cs
index 3cac7a1e..0f6b3d8c 100644
--- a/BasicRotations/Melee/NIN_Default.cs
+++ b/BasicRotations/Melee/NIN_Default.cs
@@ -39,7 +39,7 @@ public sealed class NIN_Default : NinjaRotation
if (remainTime > 6) ClearNinjutsu();
// Decision-making for ninjutsu actions based on remaining time until combat starts.
- if (DoNinjutsu(out var act))
+ if (DoSuiton(out var act))
{
if (act == SuitonPvE && remainTime > CountDownAhead) return null;
return act;
@@ -59,21 +59,129 @@ public sealed class NIN_Default : NinjaRotation
}
#endregion
+ #region Move Logic
+ // Defines logic for actions to take when moving forward during combat.
+ // This attribute associates the method with the Forked Raiju PvE action,
+ // indicating it's a relevant ability when considering movement-based actions.
+ [RotationDesc(ActionID.ForkedRaijuPvE)]
+ protected override bool MoveForwardGCD(out IAction? act)
+ {
+ // Checks if Forked Raiju, a movement-friendly ability, can be used.
+ // If so, sets it as the action to perform, returning true to indicate an action has been selected.
+ if (ForkedRaijuPvE.CanUse(out act)) return true;
+
+ // If Forked Raiju is not available or not the best option,
+ // falls back to the base class's logic for choosing a move-forward action.
+ return base.MoveForwardGCD(out act);
+ }
+ #endregion
+
+ #region oGCD Logic
+ // Determines the emergency abilities to use, overriding the base class implementation.
+ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
+ {
+ // Initializes the action to null, indicating no action has been chosen yet.
+ act = null;
+
+ // If the last action performed matches any of a list of specific actions, it clears the Ninjutsu aim.
+ // This serves as a reset/cleanup mechanism to ensure the decision logic starts fresh for the next cycle.
+ if (IsLastAction(true, RabbitMediumPvE, FumaShurikenPvE, KatonPvE, RaitonPvE,
+ HyotonPvE, HutonPvE, DotonPvE, SuitonPvE, GokaMekkyakuPvE, HyoshoRanryuPvE) || (Player.HasStatus(true, StatusID.ShadowWalker)
+ && (_ninActionAim == SuitonPvE || _ninActionAim == HutonPvE)))
+ {
+ ClearNinjutsu();
+ }
+
+ if ((InCombat || (CommbatMudra && HasHostilesInMaxRange)) && ChoiceNinjutsu(out act)) return true;
+
+ // If Ninjutsu is available or not in combat, defers to the base class's emergency ability logic.
+ if (!NoNinjutsu || !InCombat) return base.EmergencyAbility(nextGCD, out act);
+
+ // First priority is given to Kassatsu if it's available, allowing for an immediate powerful Ninjutsu.
+ if (NoNinjutsu && KassatsuPvE.CanUse(out act)) return true;
+
+ if (TenriJindoPvE.CanUse(out act)) return true;
+
+ // If in a burst phase and not just starting combat, checks if Mug is available to generate additional Ninki.
+ if (IsBurst && !CombatElapsedLess(5) && MugPvE.CanUse(out act)) return true;
+
+ // Prioritizes using Suiton and Trick Attack for maximizing damage, especially outside the initial combat phase.
+ if (!CombatElapsedLess(6))
+ {
+ // Attempts to use Trick Attack if it's available.
+ if (KunaisBanePvE.CanUse(out act, skipAoeCheck: true, skipStatusProvideCheck: IsShadowWalking)) return true;
+ if (!KunaisBanePvE.EnoughLevel && TrickAttackPvE.CanUse(out act, skipStatusProvideCheck: IsShadowWalking)) return true;
+
+ // If Trick Attack is on cooldown but will not be ready soon, considers using Meisui to recover Ninki.
+ if (TrickAttackPvE.Cooldown.IsCoolingDown && !TrickAttackPvE.Cooldown.WillHaveOneCharge(19) && TenChiJinPvE.Cooldown.IsCoolingDown && MeisuiPvE.CanUse(out act)) return true;
+ }
+
+ if ((TenChiJinPvE.Cooldown.IsCoolingDown || Player.WillStatusEndGCD(2, 0, true, StatusID.ShadowWalker)) && MeisuiPvE.CanUse(out act)) return true;
+
+ // If none of the specific conditions are met, falls back to the base class's emergency ability logic.
+ return base.EmergencyAbility(nextGCD, out act);
+ }
+
+ // Defines attack abilities to use during combat, overriding the base class implementation.
+ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
+ {
+ act = null;
+ // If Ninjutsu is available or not in combat, it exits early, indicating no attack action to perform.
+ if (!NoNinjutsu || !InCombat) return false;
+
+ // If the player is within Trick Attack's effective window, and Ten Chi Jin hasn't recently been used,
+ // then Ten Chi Jin is set as the next action to perform.
+ if (InTrickAttack && !Player.HasStatus(true, StatusID.ShadowWalker) && !TenPvE.Cooldown.ElapsedAfter(30) && TenChiJinPvE.CanUse(out act)) return true;
+
+ // If more than 5 seconds have passed in combat, checks if Bunshin is available to use.
+ if (!CombatElapsedLess(5) && BunshinPvE.CanUse(out act)) return true;
+
+ // Special handling if within Trick Attack's effective window:
+ if (InTrickAttack)
+ {
+ // If Dream Within A Dream is not yet available, checks if Assassinate can be used.
+ if (!DreamWithinADreamPvE.EnoughLevel)
+ {
+ if (AssassinatePvE.CanUse(out act)) return true;
+ }
+ else
+ {
+ // If Dream Within A Dream is available, it's set as the next action.
+ if (DreamWithinADreamPvE.CanUse(out act)) return true;
+ }
+ }
+
+ // Checks for the use of Hellfrog Medium or Bhavacakra under certain conditions:
+ // - Not in the Mug's effective window or within Trick Attack's window
+ // - Certain cooldown conditions are met, or specific statuses are active.
+ if ((!InMug || InTrickAttack)
+ && (!BunshinPvE.Cooldown.WillHaveOneCharge(10) || HasPhantomKamaitachi || MugPvE.Cooldown.WillHaveOneCharge(2)))
+ {
+ if (HellfrogMediumPvE.CanUse(out act, skipAoeCheck: !BhavacakraPvE.EnoughLevel)) return true;
+ if (BhavacakraPvE.CanUse(out act)) return true;
+ if (TenriJindoPvE.CanUse(out act)) return true;
+ }
+
+ if (Ninki == 100)
+ {
+ if (HellfrogMediumPvE.CanUse(out act, skipAoeCheck: !BhavacakraPvE.EnoughLevel)) return true;
+ if (BhavacakraPvE.CanUse(out act)) return true;
+ }
+
+ if (MergedStatus.HasFlag(AutoStatus.MoveForward) && MoveForwardAbility(nextGCD, out act)) return true;
+ // If none of the conditions are met, it falls back to the base class's implementation for attack ability.
+ return base.AttackAbility(nextGCD, out act);
+ }
+ #endregion
+
#region Ninjutsu Logic
- // Sets the target ninjutsu action to be performed next.
- // If the action is null, or currently set to Rabbit Medium (indicating a failed Ninjutsu attempt), it exits early.
- // If the current action aim is not null and the last action matches certain conditions, it exits early.
- // Finally, updates the current ninjutsu action aim if it's different from the incoming action.
private void SetNinjutsu(IBaseAction act)
{
- if (act == null || AdjustId(ActionID.NinjutsuPvE) == ActionID.RabbitMediumPvE) return;
+ if (act == null || AdjustId(ActionID.NinjutsuPvE) == ActionID.RabbitMediumPvE || (_ninActionAim != null && IsLastAction(true, _ninActionAim))) return;
if (_ninActionAim != null && IsLastAction(false, TenPvE, JinPvE, ChiPvE, FumaShurikenPvE_18873, FumaShurikenPvE_18874, FumaShurikenPvE_18875)) return;
- if (_ninActionAim != act)
- {
- _ninActionAim = act;
- }
+ _ninActionAim = act;
}
// Clears the ninjutsu action aim, effectively resetting any planned ninjutsu action.
@@ -91,16 +199,8 @@ private bool ChoiceNinjutsu(out IAction? act)
{
act = null;
- // If the last action performed matches any of a list of specific actions, it clears the Ninjutsu aim.
- // This serves as a reset/cleanup mechanism to ensure the decision logic starts fresh for the next cycle.
- if (IsLastAction(true, DotonPvE, SuitonPvE,
- RabbitMediumPvE, FumaShurikenPvE, KatonPvE, RaitonPvE,
- HyotonPvE, HutonPvE, DotonPvE, SuitonPvE, GokaMekkyakuPvE, HyoshoRanryuPvE))
- {
- ClearNinjutsu();
- }
+ if (!TenPvE.CanUse(out _) && !HasKassatsu) return false;
- if (!TenPvE.Cooldown.HasOneCharge && TenPvE.EnoughLevel) return false;
// Ensures that the action ID currently considered for Ninjutsu is actually valid for Ninjutsu execution.
//if (AdjustId(ActionID.NinjutsuPvE) != ActionID.NinjutsuPvE) return false;
// If more than 4.5 seconds have passed since the last action, it clears any pending Ninjutsu to avoid stale actions.
@@ -111,26 +211,26 @@ private bool ChoiceNinjutsu(out IAction? act)
{
// Attempts to set high-damage AoE Ninjutsu if available under Kassatsu's effect.
// These are prioritized due to Kassatsu's enhancement of Ninjutsu abilities.
- if (GokaMekkyakuPvE.EnoughLevel && JinPvE.Cooldown.HasOneCharge)
+ if (DeathBlossomPvE.CanUse(out _) && GokaMekkyakuPvE.EnoughLevel)
{
SetNinjutsu(GokaMekkyakuPvE);
}
- if (HyoshoRanryuPvE.EnoughLevel && JinPvE.Cooldown.HasOneCharge)
+ if (!DeathBlossomPvE.CanUse(out _) && HyoshoRanryuPvE.EnoughLevel)
{
SetNinjutsu(HyoshoRanryuPvE);
}
- if (!HyoshoRanryuPvE.EnoughLevel && HutonPvE.EnoughLevel && TenPvE.CanUse(out _) && JinPvE.Cooldown.HasOneCharge)
+ if (!IsShadowWalking && ShadowWalkerNeeded && !HyoshoRanryuPvE.EnoughLevel)
{
SetNinjutsu(HutonPvE);
}
- if (!HyoshoRanryuPvE.EnoughLevel && KatonPvE.EnoughLevel && TenPvE.Cooldown.HasOneCharge)
+ if (DeathBlossomPvE.CanUse(out _) && !HyoshoRanryuPvE.EnoughLevel)
{
SetNinjutsu(KatonPvE);
}
- if (!HyoshoRanryuPvE.EnoughLevel && RaitonPvE.EnoughLevel && TenPvE.Cooldown.HasOneCharge)
+ if (!DeathBlossomPvE.CanUse(out _) && !HyoshoRanryuPvE.EnoughLevel)
{
SetNinjutsu(RaitonPvE);
}
@@ -138,28 +238,30 @@ private bool ChoiceNinjutsu(out IAction? act)
}
else
{
- // If Suiton is active but no specific Ninjutsu is currently aimed, it clears the Ninjutsu aim.
- // This check is relevant for managing Suiton's effect, particularly for enabling Trick Attack.
- if (Player.HasStatus(true, StatusID.ShadowWalker)
- && _ninActionAim == SuitonPvE)
- {
- ClearNinjutsu();
- }
-
// Chooses buffs or AoE actions based on combat conditions and cooldowns.
// For instance, setting Huton for speed buff or choosing AoE Ninjutsu like Katon or Doton based on enemy positioning.
// Also considers using Suiton for vulnerability debuff on the enemy if conditions are optimal.
+ //Vulnerable
+ if (ShadowWalkerNeeded && (!MeisuiPvE.Cooldown.IsCoolingDown || !TrickAttackPvE.Cooldown.IsCoolingDown || KunaisBanePvE.Cooldown.IsCoolingDown) && !IsShadowWalking && !HasTenChiJin && SuitonPvE.EnoughLevel && TenPvE.Cooldown.HasOneCharge)
+ {
+ if (DeathBlossomPvE.CanUse(out _))
+ SetNinjutsu(HutonPvE);
+ else
+ SetNinjutsu(SuitonPvE);
+ return false;
+ }
+
//Aoe
- if (NumberOfHostilesInRange > 1 && KatonPvE.EnoughLevel && ChiPvE.CanUse(out _) && TenPvE.CanUse(out _))
+ if (DeathBlossomPvE.CanUse(out _) && KatonPvE.EnoughLevel && TenPvE.CanUse(out _))
{
- if (!HasDoton && !IsMoving && !IsLastGCD(false, DotonPvE) && (!TenChiJinPvE.Cooldown.WillHaveOneCharge(6)) || !HasDoton && !TenChiJinPvE.Cooldown.IsCoolingDown && TenPvE.CanUse(out _) && ChiPvE.CanUse(out _) && JinPvE.CanUse(out _))
+ if (!HasDoton && !IsMoving && !IsLastGCD(true, DotonPvE) && (!TenChiJinPvE.Cooldown.WillHaveOneCharge(6)) || !HasDoton && !TenChiJinPvE.Cooldown.IsCoolingDown)
SetNinjutsu(DotonPvE);
else SetNinjutsu(KatonPvE);
}
//Single
- if (!ShadowWalkerNeeded && TenPvE.CanUse(out _, usedUp: InTrickAttack && !HasRaijuReady))
+ if (!DeathBlossomPvE.CanUse(out _) && !ShadowWalkerNeeded && TenPvE.CanUse(out _, usedUp: InTrickAttack && !HasRaijuReady))
{
if (RaitonPvE.EnoughLevel && TenPvE.Cooldown.HasOneCharge)
{
@@ -173,25 +275,29 @@ private bool ChoiceNinjutsu(out IAction? act)
return false;
}
}
-
- //Vulnerable
- if (ShadowWalkerNeeded && (!MeisuiPvE.Cooldown.IsCoolingDown || !TrickAttackPvE.Cooldown.IsCoolingDown || KunaisBanePvE.Cooldown.IsCoolingDown) && !IsShadowWalking && !HasTenChiJin && SuitonPvE.EnoughLevel && JinPvE.Cooldown.HasOneCharge)
- {
- SetNinjutsu(SuitonPvE);
- return false;
- }
}
return false; // Indicates that no specific Ninjutsu action was chosen in this cycle.
}
#endregion
#region Ninjutsu Execution
- // Attempts to perform a ninjutsu action, based on the current game state and conditions.
- private bool DoNinjutsu(out IAction? act)
+ private bool DoRabbitMedium(out IAction? act)
+ {
+ act = null;
+ uint ninjutsunId = AdjustId(NinjutsuPvE.ID);
+ if (ninjutsunId == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ if (RabbitMediumPvE.CanUse(out act)) return true;
+ ClearNinjutsu();
+ }
+ return false;
+ }
+
+ private bool DoTenChiJin(out IAction? act)
{
act = null;
- //TenChiJin
if (HasTenChiJin)
{
uint tenId = AdjustId(TenPvE.ID);
@@ -203,7 +309,7 @@ private bool DoNinjutsu(out IAction? act)
&& !IsLastAction(false, FumaShurikenPvE_18875, FumaShurikenPvE_18873))
{
//AOE
- if (KatonPvE.CanUse(out _))
+ if (DeathBlossomPvE.CanUse(out _))
{
if (FumaShurikenPvE_18875.CanUse(out act)) return true;
}
@@ -230,171 +336,580 @@ private bool DoNinjutsu(out IAction? act)
if (DotonPvE_18880.CanUse(out act, skipAoeCheck: true)) return true;
}
}
+ return false;
+ }
- //Keep Kassatsu in Burst.
- if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
- && HasKassatsu && !InTrickAttack) return false;
- if (_ninActionAim == null) return false;
-
- var id = AdjustId(ActionID.NinjutsuPvE);
+ private bool DoSuiton(out IAction? act)
+ {
+ act = null;
- //Failed
- if ((uint)id == RabbitMediumPvE.ID)
+ if (_ninActionAim != null && (_ninActionAim == SuitonPvE))
{
- _rabbitMediumFailures++;
- ClearNinjutsu();
- act = null;
- return false;
- }
- //First
- else if (id == ActionID.NinjutsuPvE)
- {
- //Can't use.
- if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
- && !TenPvE.CanUse(out _, usedUp: true)
- && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
{
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
return false;
}
- act = _ninActionAim.Setting.Ninjutsu![0];
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
+
+ act = _ninActionAim;
return true;
}
- //Second
- else if ((uint)id == _ninActionAim.ID)
+ return false;
+ }
+
+ private bool DoHyoshoRanryu(out IAction? act)
+ {
+ act = null;
+
+ if (_ninActionAim != null && (_ninActionAim == HyoshoRanryuPvE) && HasKassatsu)
{
- if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
- if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
{
- act = _ninActionAim;
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
return true;
}
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
+
+ act = _ninActionAim;
+ return true;
}
- //Third
- else if ((uint)id == FumaShurikenPvE.ID)
+ return false;
+ }
+
+ private bool DoGokaMekkyaku(out IAction? act)
+ {
+ act = null;
+
+ if (_ninActionAim != null && (_ninActionAim == GokaMekkyakuPvE) && HasKassatsu)
{
- if (_ninActionAim.Setting.Ninjutsu!.Length > 1
- && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
{
- act = _ninActionAim.Setting.Ninjutsu![1];
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
return true;
}
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
+
+ act = _ninActionAim;
+ return true;
}
- //Finished
- else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ return false;
+ }
+
+ private bool DoDoton(out IAction? act)
+ {
+ act = null;
+
+ if (_ninActionAim != null && (_ninActionAim == DotonPvE))
{
- if (_ninActionAim.Setting.Ninjutsu!.Length > 2
- && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
{
- act = _ninActionAim.Setting.Ninjutsu![2];
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
return true;
}
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
+
+ act = _ninActionAim;
+ return true;
}
return false;
}
- #endregion
- #region Move Logic
- // Defines logic for actions to take when moving forward during combat.
- // This attribute associates the method with the Forked Raiju PvE action,
- // indicating it's a relevant ability when considering movement-based actions.
- [RotationDesc(ActionID.ForkedRaijuPvE)]
- protected override bool MoveForwardGCD(out IAction? act)
+ private bool DoHuton(out IAction? act)
{
- // Checks if Forked Raiju, a movement-friendly ability, can be used.
- // If so, sets it as the action to perform, returning true to indicate an action has been selected.
- if (ForkedRaijuPvE.CanUse(out act)) return true;
+ act = null;
- // If Forked Raiju is not available or not the best option,
- // falls back to the base class's logic for choosing a move-forward action.
- return base.MoveForwardGCD(out act);
+ if (_ninActionAim != null && (_ninActionAim == HutonPvE))
+ {
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
+
+ act = _ninActionAim;
+ return true;
+ }
+ return false;
}
- #endregion
- #region oGCD Logic
- // Determines the emergency abilities to use, overriding the base class implementation.
- protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
+ private bool DoHyoton(out IAction? act)
{
- // Initializes the action to null, indicating no action has been chosen yet.
act = null;
- if ((InCombat || (CommbatMudra && HasHostilesInMaxRange)) && ChoiceNinjutsu(out act)) return true;
-
- // If Ninjutsu is available or not in combat, defers to the base class's emergency ability logic.
- if (!NoNinjutsu || !InCombat) return base.EmergencyAbility(nextGCD, out act);
+ if (_ninActionAim != null && (_ninActionAim == HyotonPvE))
+ {
+ var id = AdjustId(ActionID.NinjutsuPvE);
- // First priority is given to Kassatsu if it's available, allowing for an immediate powerful Ninjutsu.
- if (NoNinjutsu && KassatsuPvE.CanUse(out act)) return true;
- if ((!TenChiJinPvE.Cooldown.IsCoolingDown || Player.WillStatusEndGCD(2, 0, true, StatusID.ShadowWalker)) && MeisuiPvE.CanUse(out act)) return true;
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
- if (TenriJindoPvE.CanUse(out act)) return true;
+ act = _ninActionAim;
+ return true;
+ }
+ return false;
+ }
- // If in a burst phase and not just starting combat, checks if Mug is available to generate additional Ninki.
- if (IsBurst && !CombatElapsedLess(5) && MugPvE.CanUse(out act)) return true;
+ private bool DoRaiton(out IAction? act)
+ {
+ act = null;
- // Prioritizes using Suiton and Trick Attack for maximizing damage, especially outside the initial combat phase.
- if (!CombatElapsedLess(6))
+ if (_ninActionAim != null && (_ninActionAim == RaitonPvE))
{
- // Attempts to use Trick Attack if it's available.
- if (KunaisBanePvE.CanUse(out act, skipAoeCheck: true, skipStatusProvideCheck: IsShadowWalking)) return true;
- if (!KunaisBanePvE.EnoughLevel && TrickAttackPvE.CanUse(out act, skipStatusProvideCheck: IsShadowWalking)) return true;
+ var id = AdjustId(ActionID.NinjutsuPvE);
- // If Trick Attack is on cooldown but will not be ready soon, considers using Meisui to recover Ninki.
- if (TrickAttackPvE.Cooldown.IsCoolingDown && !TrickAttackPvE.Cooldown.WillHaveOneCharge(19) && TenChiJinPvE.Cooldown.IsCoolingDown && MeisuiPvE.CanUse(out act)) return true;
- }
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
+ }
- // If none of the specific conditions are met, falls back to the base class's emergency ability logic.
- return base.EmergencyAbility(nextGCD, out act);
+ act = _ninActionAim;
+ return true;
+ }
+ return false;
}
- // Defines attack abilities to use during combat, overriding the base class implementation.
- protected override bool AttackAbility(IAction nextGCD, out IAction? act)
+ private bool DoKaton(out IAction? act)
{
act = null;
- // If Ninjutsu is available or not in combat, it exits early, indicating no attack action to perform.
- if (!NoNinjutsu || !InCombat) return false;
- // If the player is within Trick Attack's effective window, and Ten Chi Jin hasn't recently been used,
- // then Ten Chi Jin is set as the next action to perform.
- if (InTrickAttack && !Player.HasStatus(true, StatusID.ShadowWalker) && !TenPvE.Cooldown.ElapsedAfter(30) && TenChiJinPvE.CanUse(out act)) return true;
-
- // If more than 5 seconds have passed in combat, checks if Bunshin is available to use.
- if (!CombatElapsedLess(5) && BunshinPvE.CanUse(out act)) return true;
-
- // Special handling if within Trick Attack's effective window:
- if (InTrickAttack)
+ if (_ninActionAim != null && (_ninActionAim == KatonPvE))
{
- // If Dream Within A Dream is not yet available, checks if Assassinate can be used.
- if (!DreamWithinADreamPvE.EnoughLevel)
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
{
- if (AssassinatePvE.CanUse(out act)) return true;
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
}
- else
+ //First
+ else if (id == ActionID.NinjutsuPvE)
{
- // If Dream Within A Dream is available, it's set as the next action.
- if (DreamWithinADreamPvE.CanUse(out act)) return true;
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ //Second
+ else if ((uint)id == _ninActionAim.ID)
+ {
+ if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
+ if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
+ {
+ act = _ninActionAim;
+ return true;
+ }
+ }
+ //Third
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ //Finished
+ else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 2
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![2];
+ return true;
+ }
}
- }
- // Checks for the use of Hellfrog Medium or Bhavacakra under certain conditions:
- // - Not in the Mug's effective window or within Trick Attack's window
- // - Certain cooldown conditions are met, or specific statuses are active.
- if ((!InMug || InTrickAttack)
- && (!BunshinPvE.Cooldown.WillHaveOneCharge(10) || HasPhantomKamaitachi || MugPvE.Cooldown.WillHaveOneCharge(2)))
- {
- if (HellfrogMediumPvE.CanUse(out act, skipAoeCheck: !BhavacakraPvE.EnoughLevel)) return true;
- if (BhavacakraPvE.CanUse(out act)) return true;
- if (TenriJindoPvE.CanUse(out act)) return true;
+ act = _ninActionAim;
+ return true;
}
+ return false;
+ }
- if (Ninki == 100)
+ private bool DoFumaShuriken(out IAction? act)
+ {
+ act = null;
+
+ if (_ninActionAim != null && (_ninActionAim == FumaShurikenPvE))
{
- if (HellfrogMediumPvE.CanUse(out act, skipAoeCheck: !BhavacakraPvE.EnoughLevel)) return true;
- if (BhavacakraPvE.CanUse(out act)) return true;
- }
+ //Keep Kassatsu in Burst.
+ if (!Player.WillStatusEnd(4, true, StatusID.Kassatsu) && !InTrickAttack) return false;
- if (MergedStatus.HasFlag(AutoStatus.MoveForward) && MoveForwardAbility(nextGCD, out act)) return true;
- // If none of the conditions are met, it falls back to the base class's implementation for attack ability.
- return base.AttackAbility(nextGCD, out act);
+ var id = AdjustId(ActionID.NinjutsuPvE);
+
+ //Failed
+ if ((uint)id == RabbitMediumPvE.ID)
+ {
+ _rabbitMediumFailures++;
+ ClearNinjutsu();
+ act = null;
+ return false;
+ }
+ //First
+ else if (id == ActionID.NinjutsuPvE)
+ {
+ //Can't use.
+ if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
+ && !TenPvE.CanUse(out _, usedUp: true)
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
+ {
+ return false;
+ }
+ act = _ninActionAim.Setting.Ninjutsu![0];
+ return true;
+ }
+ else if ((uint)id == FumaShurikenPvE.ID)
+ {
+ if (_ninActionAim.Setting.Ninjutsu!.Length > 1
+ && !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
+ {
+ act = _ninActionAim.Setting.Ninjutsu![1];
+ return true;
+ }
+ }
+ }
+ return false;
}
#endregion
@@ -403,8 +918,6 @@ protected override bool GeneralGCD(out IAction? act)
{
act = null;
- if (_ninActionAim == null && RabbitMediumPvE.CanUse(out act)) return true;
-
if (!IsExecutingMudra && (InTrickAttack || InMug) && NoNinjutsu && !HasRaijuReady
&& !Player.HasStatus(true, StatusID.TenChiJin)
&& PhantomKamaitachiPvE.CanUse(out act)) return true;
@@ -415,22 +928,41 @@ protected override bool GeneralGCD(out IAction? act)
if (ForkedUse && ForkedRaijuPvE.CanUse(out act)) return true;
}
- if (((!InCombat && CommbatMudra && HasHostilesInMaxRange) || !CombatElapsedLess(7)) && DoNinjutsu(out act)) return true;
-
- //No Ninjutsu
- if (NoNinjutsu)
- {
- if (!CombatElapsedLess(10) && FleetingRaijuPvE.CanUse(out act)) return true;
- if (HasRaijuReady) return false;
- }
+ if (DoTenChiJin(out act)) return true;
+ if (DoRabbitMedium(out act)) return true;
//AOE
+ if (DoGokaMekkyaku(out act)) return true;
+ if (DoHuton(out act)) return true;
+ if (DoDoton(out act)) return true;
+ if (DoKaton(out act)) return true;
+
if (HakkeMujinsatsuPvE.CanUse(out act)) return true;
if (DeathBlossomPvE.CanUse(out act)) return true;
+ if (DoHyoshoRanryu(out act)) return true;
+ if (DoSuiton(out act)) return true;
+ if (DoHuton(out act)) return true;
+ if (DoHyoton(out act)) return true;
+ if (DoRaiton(out act)) return true;
+ if (DoFumaShuriken(out act)) return true;
+
//Single
- if (!InTrickAttack && Kazematoi < 4 && ArmorCrushPvE.CanUse(out act)) return true;
- if (AeolianEdgePvE.CanUse(out act)) return true;
+ if (AeolianEdgePvE.EnoughLevel)
+ {
+ // If ArmorCrushPvE is not yet available, checks if AeolianEdgePvE can be used.
+ if (!ArmorCrushPvE.EnoughLevel)
+ {
+ if (AeolianEdgePvE.CanUse(out act)) return true;
+ }
+ else
+ {
+ if (Kazematoi == 0 && ArmorCrushPvE.CanUse(out act)) return true;
+ else if (Kazematoi > 0 && AeolianEdgePvE.CanUse(out act) && AeolianEdgePvE.Target.Target != null && CanHitPositional(EnemyPositional.Rear, AeolianEdgePvE.Target.Target)) return true;
+ else if (Kazematoi < 4 && ArmorCrushPvE.CanUse(out act) && ArmorCrushPvE.Target.Target != null && CanHitPositional(EnemyPositional.Flank, ArmorCrushPvE.Target.Target)) return true;
+ else if (Kazematoi > 0 && AeolianEdgePvE.CanUse(out act)) return true;
+ }
+ }
if (GustSlashPvE.CanUse(out act)) return true;
if (SpinningEdgePvE.CanUse(out act)) return true;
diff --git a/BasicRotations/Ranged/MCH_Default.cs b/BasicRotations/Ranged/MCH_Default.cs
index 87dbd8d0..343d8391 100644
--- a/BasicRotations/Ranged/MCH_Default.cs
+++ b/BasicRotations/Ranged/MCH_Default.cs
@@ -9,6 +9,9 @@ public sealed class MCH_Default : MachinistRotation
[RotationConfig(CombatType.PvE, Name = "Prioritize Barrel Stabilizer use")]
private bool BSPrio { get; set; } = true;
+ [RotationConfig(CombatType.PvE, Name = "Use Automation Queen as soon as its available")]
+ private bool DumbQueen { get; set; } = false;
+
[RotationConfig(CombatType.PvE, Name = "Delay Drill for combo GCD if have one charge and about to break combo")]
private bool HoldDrillForCombo { get; set; } = true;
@@ -106,6 +109,7 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
}
// Rook Autoturret/Queen Logic
+ if (DumbQueen && InCombat && RookAutoturretPvE.CanUse(out act)) return true;
if (CanUseQueenMeow(out act, nextGCD)) return true;
// Use Ricochet and Gauss
diff --git a/BasicRotations/Tank/PLD_Default.cs b/BasicRotations/Tank/PLD_Default.cs
index a9724d8c..c0fcb453 100644
--- a/BasicRotations/Tank/PLD_Default.cs
+++ b/BasicRotations/Tank/PLD_Default.cs
@@ -25,6 +25,9 @@ public sealed class PLD_Default : PaladinRotation
[RotationConfig(CombatType.PvE, Name = "Health threshold for Intervention (Set to 0 to disable)")]
private float InterventionRatio { get; set; } = 0.6f;
+ [RotationConfig(CombatType.PvE, Name = "Attempt to use intevention on CoTank during tankbusters")]
+ private bool InterventionTank { get; set; } = false;
+
[Range(0, 1, ConfigUnitType.Percent)]
[RotationConfig(CombatType.PvE, Name = "Health threshold for Cover (Set to 0 to disable)")]
private float CoverRatio { get; set; } = 0.3f;
@@ -132,6 +135,8 @@ protected override bool DefenseSingleAbility(IAction nextGCD, out IAction? act)
act = null;
if (PassageProtec && Player.HasStatus(true, StatusID.PassageOfArms)) return false;
+ if (InterventionTank && InterventionPvE.Target.Target?.HasStatus(false, StatusID.Grit, StatusID.RoyalGuard_1833, StatusID.IronWill, StatusID.Defiance) == true && InterventionPvE.CanUse(out act)) return true;
+
// If the player has the Hallowed Ground status, don't use any abilities.
if (!Player.HasStatus(true, StatusID.HallowedGround))
{
diff --git a/RotationSolver.Basic/Helpers/StatusHelper.cs b/RotationSolver.Basic/Helpers/StatusHelper.cs
index 063af48d..fd90d104 100644
--- a/RotationSolver.Basic/Helpers/StatusHelper.cs
+++ b/RotationSolver.Basic/Helpers/StatusHelper.cs
@@ -81,7 +81,10 @@ public static class StatusHelper
StatusID.TheEwer_3891,
};
- internal static StatusID[] TankStanceStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] TankStanceStatus { get; } =
{
StatusID.Grit,
StatusID.RoyalGuard_1833,
@@ -89,7 +92,10 @@ public static class StatusHelper
StatusID.Defiance,
};
- internal static StatusID[] NoNeedHealingStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] NoNeedHealingStatus { get; } =
{
StatusID.Holmgang_409,
StatusID.LivingDead,
@@ -97,14 +103,20 @@ public static class StatusHelper
StatusID.Superbolide,
};
- internal static StatusID[] SwiftcastStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] SwiftcastStatus { get; } =
{
StatusID.Swiftcast,
StatusID.Triplecast,
StatusID.Dualcast,
};
- internal static StatusID[] AstCardStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] AstCardStatus { get; } =
{
StatusID.TheBalance_3887,
StatusID.TheSpear_3889,
@@ -112,7 +124,10 @@ public static class StatusHelper
StatusID.BrinkOfDeath,
};
- internal static StatusID[] RampartStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] RampartStatus { get; } =
{
StatusID.Superbolide,
StatusID.HallowedGround,
@@ -129,7 +144,10 @@ public static class StatusHelper
StatusID.Superbolide,
};
- internal static StatusID[] NoPositionalStatus { get; } =
+ ///
+ ///
+ ///
+ public static StatusID[] NoPositionalStatus { get; } =
{
StatusID.TrueNorth,
StatusID.RightEye,
diff --git a/RotationSolver.Basic/RotationSolver.Basic.csproj b/RotationSolver.Basic/RotationSolver.Basic.csproj
index 6f15d7dd..0d555fa3 100644
--- a/RotationSolver.Basic/RotationSolver.Basic.csproj
+++ b/RotationSolver.Basic/RotationSolver.Basic.csproj
@@ -73,7 +73,7 @@
all
-
+
diff --git a/RotationSolver.SourceGenerators/RotationSolver.SourceGenerators.csproj b/RotationSolver.SourceGenerators/RotationSolver.SourceGenerators.csproj
index ed135280..ff8b3051 100644
--- a/RotationSolver.SourceGenerators/RotationSolver.SourceGenerators.csproj
+++ b/RotationSolver.SourceGenerators/RotationSolver.SourceGenerators.csproj
@@ -7,7 +7,7 @@
-
+