diff --git a/BasicRotations/Healer/SCH_Default.cs b/BasicRotations/Healer/SCH_Default.cs
index 030f214f9..50d5415ea 100644
--- a/BasicRotations/Healer/SCH_Default.cs
+++ b/BasicRotations/Healer/SCH_Default.cs
@@ -99,13 +99,16 @@ protected override bool HealAreaAbility(IAction nextGCD, out IAction? act)
protected override bool HealSingleAbility(IAction nextGCD, out IAction? act)
{
var haveLink = PartyMembers.Any(p => p.HasStatus(true, StatusID.FeyUnion_1223));
- if (ManifestationPvE.CanUse(out act)) return true;
- if (AetherpactPvE.CanUse(out act) && FairyGauge >= 70 && !haveLink) return true;
if (ProtractionPvE.CanUse(out act)) return true;
+ if (IsLastAbility(ActionID.RecitationPvE) && ExcogitationPvE.CanUse(out act)) return true;
+
+ if (AetherpactPvE.CanUse(out act) && FairyGauge >= 70 && !haveLink) return true;
if (ExcogitationPvE.CanUse(out act)) return true;
if (LustratePvE.CanUse(out act)) return true;
if (AetherpactPvE.CanUse(out act) && !haveLink) return true;
+ if (ExcogitationPvE.CanUse(out act)) return true;
+
return base.HealSingleAbility(nextGCD, out act);
}
@@ -172,6 +175,8 @@ protected override bool HealAreaGCD(out IAction? act)
if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false;
if (SuccorPvE.CanUse(out act)) return true;
+ if (ConcitationPvE.CanUse(out act, skipCastingCheck: true)) return true;
+ if (AccessionPvE.CanUse(out act)) return true;
return base.HealAreaGCD(out act);
}
@@ -182,8 +187,9 @@ protected override bool HealSingleGCD(out IAction? act)
act = null;
if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false;
-
+
if (AdloquiumPvE.CanUse(out act)) return true;
+ if (ManifestationPvE.CanUse(out act, skipCastingCheck: true)) return true;
if (PhysickPvE.CanUse(out act)) return true;
return base.HealSingleGCD(out act);
@@ -197,6 +203,9 @@ protected override bool DefenseAreaGCD(out IAction? act)
if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false;
if (SuccorPvE.CanUse(out act)) return true;
+ if (ConcitationPvE.CanUse(out act, skipCastingCheck: true)) return true;
+ if (AccessionPvE.CanUse(out act)) return true;
+
return base.DefenseAreaGCD(out act);
}
diff --git a/BasicRotations/Healer/SGE_Default.cs b/BasicRotations/Healer/SGE_Default.cs
index ee876d080..b35207af6 100644
--- a/BasicRotations/Healer/SGE_Default.cs
+++ b/BasicRotations/Healer/SGE_Default.cs
@@ -65,9 +65,10 @@ public sealed class SGE_Default : SageRotation
#region Countdown Logic
protected override IAction? CountDownAction(float remainTime)
{
- if (remainTime < DosisPvE.Info.CastTime + CountDownAhead
- && DosisPvE.CanUse(out var act)) return act;
+ if (remainTime < PneumaPvE.Info.CastTime + CountDownAhead
+ && PneumaPvE.CanUse(out var act)) return act;
if (remainTime <= 3 && UseBurstMedicine(out act)) return act;
+ if (remainTime <= 5 && EukrasiaPvE.CanUse(out act)) return act;
return base.CountDownAction(remainTime);
}
#endregion
@@ -85,20 +86,17 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
{
if (base.EmergencyAbility(nextGCD, out act)) return true;
- if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianDiagnosisPvE,
- EukrasianPrognosisPvE, EukrasianPrognosisIiPvE, DiagnosisPvE, PrognosisPvE))
+ if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianPrognosisPvE, EukrasianPrognosisIiPvE))
{
if (ZoePvE.CanUse(out act)) return true;
}
- if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianDiagnosisPvE,
- EukrasianPrognosisPvE, EukrasianPrognosisIiPvE, DiagnosisPvE, PrognosisPvE))
+ if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianDiagnosisPvE, DiagnosisPvE, PrognosisPvE))
{
if (KrasisPvE.CanUse(out act)) return true;
}
- if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianDiagnosisPvE,
- EukrasianPrognosisPvE, EukrasianPrognosisIiPvE, DiagnosisPvE, PrognosisPvE))
+ if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianPrognosisPvE, EukrasianPrognosisIiPvE, DiagnosisPvE, PrognosisPvE))
{
if (PhilosophiaPvE.CanUse(out act)) return true;
}
@@ -109,6 +107,11 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
[RotationDesc(ActionID.PanhaimaPvE, ActionID.KeracholePvE, ActionID.HolosPvE)]
protected override bool DefenseAreaAbility(IAction nextGCD, out IAction? act)
{
+ if (!PanhaimaPvE.Cooldown.IsCoolingDown)
+ {
+ if (PhysisIiPvE.CanUse(out act)) return true;
+ }
+
if (Addersgall <= 1)
{
if (PanhaimaPvE.CanUse(out act)) return true;
@@ -124,6 +127,11 @@ protected override bool DefenseAreaAbility(IAction nextGCD, out IAction? act)
[RotationDesc(ActionID.HaimaPvE, ActionID.TaurocholePvE, ActionID.PanhaimaPvE, ActionID.KeracholePvE, ActionID.HolosPvE)]
protected override bool DefenseSingleAbility(IAction nextGCD, out IAction? act)
{
+ if (!HaimaPvE.Cooldown.IsCoolingDown)
+ {
+ if (KrasisPvE.CanUse(out act)) return true;
+ }
+
if (Addersgall <= 1)
{
if (HaimaPvE.CanUse(out act)) return true;
@@ -146,16 +154,14 @@ protected override bool DefenseSingleAbility(IAction nextGCD, out IAction? act)
[RotationDesc(ActionID.KeracholePvE, ActionID.PhysisPvE, ActionID.HolosPvE, ActionID.IxocholePvE)]
protected override bool HealAreaAbility(IAction nextGCD, out IAction? act)
{
- if (PhysisIiPvE.CanUse(out act)) return true;
- if (!PhysisIiPvE.EnoughLevel && PhysisPvE.CanUse(out act)) return true;
-
if (KeracholePvE.CanUse(out act) && EnhancedKeracholeTrait.EnoughLevel) return true;
- if (HolosPvE.CanUse(out act) && PartyMembersAverHP < HolosHeal) return true;
-
if (IxocholePvE.CanUse(out act)) return true;
- if (KeracholePvE.CanUse(out act)) return true;
+ if (PhysisIiPvE.CanUse(out act)) return true;
+ if (!PhysisIiPvE.EnoughLevel && PhysisPvE.CanUse(out act)) return true;
+
+ if (HolosPvE.CanUse(out act) && PartyMembersAverHP < HolosHeal) return true;
return base.HealAreaAbility(nextGCD, out act);
}
@@ -165,8 +171,6 @@ protected override bool HealSingleAbility(IAction nextGCD, out IAction? act)
{
if (TaurocholePvE.CanUse(out act)) return true;
- if (KeracholePvE.CanUse(out act) && EnhancedKeracholeTrait.EnoughLevel) return true;
-
if ((!TaurocholePvE.EnoughLevel || TaurocholePvE.Cooldown.IsCoolingDown) && DruocholePvE.CanUse(out act)) return true;
if (SoteriaPvE.CanUse(out act) && PartyMembers.Any(b => b.HasStatus(true, StatusID.Kardion) && b.GetHealthRatio() < SoteriaHeal)) return true;
@@ -194,8 +198,6 @@ protected override bool HealSingleAbility(IAction nextGCD, out IAction? act)
if (KrasisPvE.CanUse(out act)) return true;
}
- if (KeracholePvE.CanUse(out act)) return true;
-
return base.HealSingleAbility(nextGCD, out act);
}
diff --git a/BasicRotations/Tank/WAR_Default.cs b/BasicRotations/Tank/WAR_Default.cs
index 3d7dfe20d..47443f64e 100644
--- a/BasicRotations/Tank/WAR_Default.cs
+++ b/BasicRotations/Tank/WAR_Default.cs
@@ -12,9 +12,19 @@ public sealed class WAR_Default : WarriorRotation
[RotationConfig(CombatType.PvE, Name = "Use Bloodwhetting/Raw intuition on single enemies")]
public bool SoloIntuition { get; set; } = false;
+ [Range(0, 1, ConfigUnitType.Percent)]
+ [RotationConfig(CombatType.PvE, Name = "Bloodwhetting/Raw intuition heal threshold")]
+ public float HealIntuition { get; set; } = 0.7f;
+
[RotationConfig(CombatType.PvE, Name = "Use Primal Rend while moving (Danger)")]
public bool YEET { get; set; } = false;
+ [RotationConfig(CombatType.PvE, Name = "Use both stacks of Onslaught during burst while standing still")]
+ public bool YEETBurst { get; set; } = true;
+
+ [RotationConfig(CombatType.PvE, Name = "Use a stack of Onslaught during when its about to overcap while standing still")]
+ public bool YEETCooldown { get; set; } = false;
+
[Range(1, 20, ConfigUnitType.Yalms)]
[RotationConfig(CombatType.PvE, Name = "Max distance you can be from the boss for Primal Rend use (Danger, setting too high will get you killed)")]
public float PrimalRendDistance { get; set; } = 2;
@@ -69,11 +79,20 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
if (Player.HasStatus(false, StatusID.Wrathful) && PrimalWrathPvE.CanUse(out act, skipAoeCheck: true)) return true;
- if (OnslaughtPvE.CanUse(out act, usedUp: IsBurstStatus) &&
+ if (YEETBurst && OnslaughtPvE.CanUse(out act, usedUp: IsBurstStatus) &&
!IsMoving &&
- !IsLastAction(true, OnslaughtPvE) &&
- !IsLastAction(true, UpheavalPvE) &&
- Player.HasStatus(false, StatusID.SurgingTempest))
+ !IsLastAction(false, OnslaughtPvE) &&
+ !IsLastAction(false, UpheavalPvE) &&
+ Player.HasStatus(true, StatusID.SurgingTempest))
+ {
+ return true;
+ }
+
+ if (YEETCooldown && OnslaughtPvE.CanUse(out act, usedUp: true) &&
+ !IsMoving &&
+ !IsLastAction(false, OnslaughtPvE) &&
+ OnslaughtPvE.Cooldown.WillHaveXChargesGCD(OnslaughtMax, 1) &&
+ Player.HasStatus(true, StatusID.SurgingTempest))
{
return true;
}
@@ -84,6 +103,16 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
protected override bool GeneralAbility(IAction nextGCD, out IAction? act)
{
+ if ((InCombat && Player.GetHealthRatio() < HealIntuition && NumberOfHostilesInRange > 0) || (InCombat && PartyMembers.Count() is 1 && NumberOfHostilesInRange > 0))
+ {
+ if (BloodwhettingPvE.CanUse(out act)) return true;
+ }
+
+ if ((InCombat && Player.GetHealthRatio() < HealIntuition && NumberOfHostilesInRange > 0) || (InCombat && PartyMembers.Count() is 1 && NumberOfHostilesInRange > 0))
+ {
+ if (RawIntuitionPvE.CanUse(out act)) return true;
+ }
+
if (Player.GetHealthRatio() < ThrillOfBattleHeal)
{
if (ThrillOfBattlePvE.CanUse(out act)) return true;
diff --git a/RotationSolver.Basic/Helpers/ObjectHelper.cs b/RotationSolver.Basic/Helpers/ObjectHelper.cs
index 33143d01c..4da1579d1 100644
--- a/RotationSolver.Basic/Helpers/ObjectHelper.cs
+++ b/RotationSolver.Basic/Helpers/ObjectHelper.cs
@@ -47,7 +47,7 @@ internal static bool CanProvoke(this IGameObject target)
{
foreach (var n in ns1)
{
- if (!string.IsNullOrEmpty(n) && new Regex(n).Match(target.Name.ExtractText()).Success)
+ if (!string.IsNullOrEmpty(n) && new Regex(n).Match(target.Name?.ExtractText() ?? string.Empty).Success)
{
return false;
}
@@ -55,13 +55,14 @@ internal static bool CanProvoke(this IGameObject target)
}
//Target can move or too big and has a target
- if ((target.GetObjectNPC()?.Unknown0 == 0 || target.HitboxRadius >= 5) // Unknown12 used to be the flag checked for the mobs ability to move, honestly just guessing on this one
+ var targetNpc = target.GetObjectNPC();
+ if ((targetNpc?.Unknown0 == 0 || target.HitboxRadius >= 5) // Unknown12 used to be the flag checked for the mobs ability to move, honestly just guessing on this one
&& (target.TargetObject?.IsValid() ?? false))
{
//the target is not a tank role
if (Svc.Objects.SearchById(target.TargetObjectId) is IBattleChara battle
&& !battle.IsJobCategory(JobRole.Tank)
- && (Vector3.Distance(target.Position, Player.Object.Position) > 5))
+ && (Vector3.Distance(target.Position, Player.Object?.Position ?? Vector3.Zero) > 5))
{
return true;
}
diff --git a/RotationSolver.Basic/Rotations/Basic/SageRotation.cs b/RotationSolver.Basic/Rotations/Basic/SageRotation.cs
index bcb5621db..84585f7a0 100644
--- a/RotationSolver.Basic/Rotations/Basic/SageRotation.cs
+++ b/RotationSolver.Basic/Rotations/Basic/SageRotation.cs
@@ -380,6 +380,7 @@ static partial void ModifyPhilosophiaPvE(ref ActionSetting setting)
{
setting.StatusProvide = [StatusID.Philosophia];
setting.TargetStatusProvide = [StatusID.Eudaimonia];
+ setting.TargetType = TargetType.Self;
setting.CreateConfig = () => new ActionConfig()
{
AoeCount = 1,
diff --git a/RotationSolver.Basic/Rotations/Basic/WarriorRotation.cs b/RotationSolver.Basic/Rotations/Basic/WarriorRotation.cs
index 345acebc0..3eb1ffa8a 100644
--- a/RotationSolver.Basic/Rotations/Basic/WarriorRotation.cs
+++ b/RotationSolver.Basic/Rotations/Basic/WarriorRotation.cs
@@ -11,6 +11,11 @@ partial class WarriorRotation
///
public static byte BeastGauge => JobGauge.BeastGauge;
+ ///
+ ///
+ ///
+ public static byte OnslaughtMax => EnhancedOnslaughtTrait.EnoughLevel ? (byte)3 : (byte)2;
+
///
/// Holds the remaining amount of InnerRelease stacks
///
@@ -34,13 +39,14 @@ public static byte BerserkStacks
return stacks == byte.MaxValue ? (byte)3 : stacks;
}
}
-
+
///
public override void DisplayStatus()
{
ImGui.Text("InnerReleaseStacks: " + InnerReleaseStacks.ToString());
ImGui.Text("BerserkStacks: " + BerserkStacks.ToString());
ImGui.Text("BeastGaugeValue: " + BeastGauge.ToString());
+ ImGui.Text("OnslaughtMax: " + OnslaughtMax.ToString());
}
private sealed protected override IBaseAction TankStance => DefiancePvE;
diff --git a/RotationSolver/UI/RotationConfigWindow.cs b/RotationSolver/UI/RotationConfigWindow.cs
index 3485c0f29..1e68d21c1 100644
--- a/RotationSolver/UI/RotationConfigWindow.cs
+++ b/RotationSolver/UI/RotationConfigWindow.cs
@@ -1017,7 +1017,6 @@ private static void DrawAboutLinks()
private void DrawAutoduty()
{
-
ImGui.TextWrapped("This is a gentle reminder that RSR is not a botting tool, and while I have taken steps to help it work better with Autoduty please keep that in mind");
ImGui.Spacing();
ImGui.TextWrapped("This menu is mostly for troubleshooting purposes and is a good first step to share to get assistance.");
@@ -1085,15 +1084,15 @@ private void DrawAutoduty()
// Create a new list of AutoDutyPlugin objects
var pluginsToCheck = new List
{
- new IncompatiblePlugin { Name = "AutoDuty" },
- new IncompatiblePlugin { Name = "vnavmesh" },
- new IncompatiblePlugin { Name = "BossMod Reborn" },
- new IncompatiblePlugin { Name = "Boss Mod" },
- new IncompatiblePlugin { Name = "Avarice" },
- new IncompatiblePlugin { Name = "Deliveroo" },
- new IncompatiblePlugin { Name = "AutoRetainer" },
- new IncompatiblePlugin { Name = "SkipCutscene" },
- new IncompatiblePlugin { Name = "AntiAfkKick" },
+ new IncompatiblePlugin { Name = "AutoDuty", Url = "https://puni.sh/api/repository/herc" },
+ new IncompatiblePlugin { Name = "vnavmesh", Url = "https://puni.sh/api/repository/veyn" },
+ new IncompatiblePlugin { Name = "BossMod Reborn", Url = "https://raw.githubusercontent.com/FFXIV-CombatReborn/CombatRebornRepo/main/pluginmaster.json" },
+ new IncompatiblePlugin { Name = "Boss Mod", Url = "" },
+ new IncompatiblePlugin { Name = "Avarice", Url = "https://love.puni.sh/ment.json" },
+ new IncompatiblePlugin { Name = "Deliveroo", Url = "https://plugins.carvel.li/" },
+ new IncompatiblePlugin { Name = "AutoRetainer", Url = "https://love.puni.sh/ment.json" },
+ new IncompatiblePlugin { Name = "SkipCutscene", Url = "https://raw.githubusercontent.com/KangasZ/DalamudPluginRepository/main/plugin_repository.json" },
+ new IncompatiblePlugin { Name = "AntiAfkKick", Url = "https://raw.githubusercontent.com/NightmareXIV/MyDalamudPlugins/main/pluginmaster.json" },
// Add more plugins as needed
};
@@ -1112,6 +1111,16 @@ private void DrawAutoduty()
bool isInstalled = plugin.IsInstalled;
+ // Add a button to copy the URL to the clipboard if the plugin is not installed
+ if (!isInstalled)
+ {
+ if (ImGui.Button($"Copy Repo URL##{plugin.Name}"))
+ {
+ ImGui.SetClipboardText(plugin.Url);
+ }
+ ImGui.SameLine();
+ }
+
// Determine the color and text for "Boss Mod"
Vector4 color;
string text;
@@ -1130,6 +1139,7 @@ private void DrawAutoduty()
ImGui.PushStyleColor(ImGuiCol.Text, color);
ImGui.TextWrapped(text);
ImGui.PopStyleColor();
+
ImGui.Spacing();
}
}