From 4c16578ed3c6bfaced000c53b4a9d4795c183af4 Mon Sep 17 00:00:00 2001 From: LTS-FFXIV <127939494+LTS-FFXIV@users.noreply.github.com> Date: Sun, 28 Jul 2024 00:50:36 -0500 Subject: [PATCH] Nuget bump, DT BLM and BRD support --- BasicRotations/Magical/BLM_Default.cs | 178 ++++++++++++++++---------- BasicRotations/Ranged/BRD_Default.cs | 38 ++++-- BasicRotations/RebornRotations.csproj | 2 +- 3 files changed, 139 insertions(+), 79 deletions(-) diff --git a/BasicRotations/Magical/BLM_Default.cs b/BasicRotations/Magical/BLM_Default.cs index f472548..934f783 100644 --- a/BasicRotations/Magical/BLM_Default.cs +++ b/BasicRotations/Magical/BLM_Default.cs @@ -1,45 +1,25 @@ namespace DefaultRotations.Magical; -[Rotation("Default", CombatType.PvE, GameVersion = "7.00")] +[Rotation("Default", CombatType.PvE, GameVersion = "7.01")] [SourceCode(Path = "main/DefaultRotations/Magical/BLM_Default.cs")] -[Api(1)] +[Api(2)] public class BLM_Default : BlackMageRotation -{/* - private bool NeedToGoIce - { - get - { - //Can use Despair. - if (DespairPvE.EnoughLevel && CurrentMp >= DespairPvE.Info.MPNeed) return false; - - //Can use Fire1 - if (FirePvE.EnoughLevel && CurrentMp >= FirePvE.Info.MPNeed) return false; - - return true; - } - } - - private bool NeedToTransposeGoIce(bool usedOne) - { - if (!NeedToGoIce) return false; - if (!ParadoxPvE.EnoughLevel) return false; - var compare = usedOne ? -1 : 0; - var count = PolyglotStacks; - if (count == compare++) return false; - if (count == compare++ && !EnchinaEndAfterGCD(2)) return false; - if (count >= compare && (HasFire || SwiftcastPvE.Cooldown.WillHaveOneChargeGCD(2) || TriplecastPvE.Cooldown.WillHaveOneChargeGCD(2))) return true; - if (!HasFire && !SwiftcastPvE.Cooldown.WillHaveOneChargeGCD(2) && !TriplecastPvE.CanUse(out _, gcdCountForAbility: 8)) return false; - return true; - } - +{ + #region Config Options [RotationConfig(CombatType.PvE, Name = "Use Transpose to Astral Fire before Paradox")] public bool UseTransposeForParadox { get; set; } = true; - [RotationConfig(CombatType.PvE, Name = "Extend Astral Fire Time Safely")] + [RotationConfig(CombatType.PvE, Name = "Use Retrace when out of Leylines and standing still (Dangerous and Experimental)")] + public bool UseRetrace { get; set; } = false; + + [RotationConfig(CombatType.PvE, Name = "Extend Astral Fire time more conservatively (3 GCDs) (Default is 2 GCDs)")] public bool ExtendTimeSafely { get; set; } = false; [RotationConfig(CombatType.PvE, Name = @"Use ""Double Paradox"" rotation [N15]")] public bool UseN15 { get; set; } = false; + #endregion + + #region Additional oGCD Logic protected override IAction? CountDownAction(float remainTime) { @@ -48,36 +28,14 @@ private bool NeedToTransposeGoIce(bool usedOne) { if (FireIiiPvE.CanUse(out act)) return act; } - if (remainTime <= 12 && SharpcastPvE.CanUse(out act, usedUp: true)) return act; + //if (remainTime <= 12 && SharpcastPvE.CanUse(out act, usedUp: true)) return act; return base.CountDownAction(remainTime); } - protected override bool AttackAbility(IAction nextGCD, out IAction? act) - { - if (IsBurst && UseBurstMedicine(out act)) return true; - if (InUmbralIce) - { - if (UmbralIceStacks == 2 && !HasFire - && !IsLastGCD(ActionID.ParadoxPvE)) - { - if (SwiftcastPvE.CanUse(out act)) return true; - if (TriplecastPvE.CanUse(out act, usedUp: true)) return true; - } - - if (UmbralIceStacks < 3 && LucidDreamingPvE.CanUse(out act)) return true; - if (SharpcastPvE.CanUse(out act, usedUp: true)) return true; - } - if (InAstralFire) - { - if (!CombatElapsedLess(6) && CombatElapsedLess(9) && LeyLinesPvE.CanUse(out act)) return true; - if (TriplecastPvE.CanUse(out act, gcdCountForAbility: 5)) return true; - } - if (AmplifierPvE.CanUse(out act)) return true; - return base.AttackAbility(nextGCD, out act); - } - + [RotationDesc] protected override bool EmergencyAbility(IAction nextGCD, out IAction? act) { + if (UseRetrace && RetracePvE.CanUse(out act)) return true; //To Fire if (CurrentMp >= 7200 && UmbralIceStacks == 2 && ParadoxPvE.EnoughLevel) { @@ -99,17 +57,84 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act) return base.EmergencyAbility(nextGCD, out act); } + [RotationDesc(ActionID.AetherialManipulationPvE)] + protected override bool MoveForwardAbility(IAction nextGCD, out IAction? act) + { + if (AetherialManipulationPvE.CanUse(out act)) return true; + + return base.MoveForwardAbility(nextGCD, out act); + } + + [RotationDesc(ActionID.BetweenTheLinesPvE)] + protected override bool MoveBackAbility(IAction nextGCD, out IAction? act) + { + if (BetweenTheLinesPvE.CanUse(out act)) return true; + + return base.MoveBackAbility(nextGCD, out act); + } + + [RotationDesc(ActionID.ManawardPvE)] + protected override bool DefenseSingleAbility(IAction nextGCD, out IAction? act) + { + if (ManawardPvE.CanUse(out act)) return true; + return base.DefenseSingleAbility(nextGCD, out act); + } + + [RotationDesc(ActionID.ManawardPvE, ActionID.AddlePvE)] + protected sealed override bool DefenseAreaAbility(IAction nextGCD, out IAction? act) + { + if (ManawardPvE.CanUse(out act)) return true; + if (AddlePvE.CanUse(out act)) return true; + return base.DefenseAreaAbility(nextGCD, out act); + } + #endregion + + #region oGCD Logic + [RotationDesc(ActionID.ManafontPvE, ActionID.TransposePvE)] + protected override bool GeneralAbility(IAction nextGCD, out IAction? act) + { + if (IsMoving && HasHostilesInRange && TriplecastPvE.CanUse(out act, usedUp: true)) return true; + + return base.GeneralAbility(nextGCD, out act); + } + + [RotationDesc(ActionID.RetracePvE, ActionID.SwiftcastPvE, ActionID.TriplecastPvE, ActionID.AmplifierPvE)] + protected override bool AttackAbility(IAction nextGCD, out IAction? act) + { + if (IsBurst && UseBurstMedicine(out act)) return true; + if (InUmbralIce) + { + if (UmbralIceStacks == 2 && !HasFire + && !IsLastGCD(ActionID.ParadoxPvE)) + { + if (SwiftcastPvE.CanUse(out act)) return true; + if (TriplecastPvE.CanUse(out act, usedUp: true)) return true; + } + + if (UmbralIceStacks < 3 && LucidDreamingPvE.CanUse(out act)) return true; + } + + if (InAstralFire) + { + if (TriplecastPvE.CanUse(out act, gcdCountForAbility: 5)) return true; + } + + if (AmplifierPvE.CanUse(out act)) return true; + return base.AttackAbility(nextGCD, out act); + } + #endregion + + #region GCD Logic protected override bool GeneralGCD(out IAction? act) { + if (FlareStarPvE.CanUse(out act)) return true; + if (InFireOrIce(out act, out var mustGo)) return true; if (mustGo) return false; - //Triplecast for moving. - if (IsMoving && HasHostilesInRange && TriplecastPvE.CanUse(out act, usedUp: true)) return true; if (AddElementBase(out act)) return true; if (ScathePvE.CanUse(out act)) return true; if (MaintainStatus(out act)) return true; - return base.GeneralGCD(out act); } @@ -308,7 +333,7 @@ private bool AddThunder(out IAction? act, uint gcdCount = 3) //So long for thunder. if (ThunderPvE.CanUse(out _) && (!ThunderPvE.Target.Target?.WillStatusEndGCD(gcdCount, 0, true, - StatusID.Thunder, StatusID.ThunderIi, StatusID.ThunderIii, StatusID.ThunderIv) ?? false)) + StatusID.Thunder, StatusID.ThunderIi, StatusID.ThunderIii, StatusID.ThunderIv, StatusID.HighThunder_3872) ?? false)) return false; if (ThunderIiPvE.CanUse(out act)) return true; @@ -339,7 +364,7 @@ private bool UsePolyglot(out IAction? act, uint gcdCount = 3) { act = null; - if (gcdCount == 0 || IsPolyglotStacksMaxed && EnchinaEndAfterGCD(gcdCount)) + if (gcdCount == 0 || IsPolyglotStacksMaxed && EnochianEndAfterGCD(gcdCount)) { if (FoulPvE.CanUse(out act)) return true; if (XenoglossyPvE.CanUse(out act)) return true; @@ -360,12 +385,31 @@ private bool MaintainStatus(out IAction? act) return false; } - [RotationDesc(ActionID.BetweenTheLinesPvE, ActionID.LeyLinesPvE)] - protected override bool HealSingleAbility(IAction nextGCD, out IAction? act) + private bool NeedToGoIce { - if (BetweenTheLinesPvE.CanUse(out act)) return true; - if (LeyLinesPvE.CanUse(out act)) return true; + get + { + //Can use Despair. + if (DespairPvE.EnoughLevel && CurrentMp >= DespairPvE.Info.MPNeed) return false; + + //Can use Fire1 + if (FirePvE.EnoughLevel && CurrentMp >= FirePvE.Info.MPNeed) return false; + + return true; + } + } - return base.HealSingleAbility(nextGCD, out act); + private bool NeedToTransposeGoIce(bool usedOne) + { + if (!NeedToGoIce) return false; + if (!ParadoxPvE.EnoughLevel) return false; + var compare = usedOne ? -1 : 0; + var count = PolyglotStacks; + if (count == compare++) return false; + if (count == compare++ && !EnochianEndAfterGCD(2)) return false; + if (count >= compare && (HasFire || SwiftcastPvE.Cooldown.WillHaveOneChargeGCD(2) || TriplecastPvE.Cooldown.WillHaveOneChargeGCD(2))) return true; + if (!HasFire && !SwiftcastPvE.Cooldown.WillHaveOneChargeGCD(2) && !TriplecastPvE.CanUse(out _, gcdCountForAbility: 8)) return false; + return true; } -*/} \ No newline at end of file + #endregion +} \ No newline at end of file diff --git a/BasicRotations/Ranged/BRD_Default.cs b/BasicRotations/Ranged/BRD_Default.cs index 4c97ff8..49da5ef 100644 --- a/BasicRotations/Ranged/BRD_Default.cs +++ b/BasicRotations/Ranged/BRD_Default.cs @@ -1,6 +1,6 @@ namespace DefaultRotations.Ranged; -[Rotation("Default", CombatType.PvE, GameVersion = "7.00", +[Rotation("Default", CombatType.PvE, GameVersion = "7.01", Description = "Please make sure that the three song times add up to 120 seconds, Wanderers default first song for now.")] [SourceCode(Path = "main/DefaultRotations/Ranged/BRD_Default.cs")] [Api(2)] @@ -52,7 +52,7 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act) protected override bool AttackAbility(IAction nextGCD, out IAction? act) { act = null; - if (Song == Song.NONE) + if (Song == Song.NONE && InCombat) { switch (FirstSong) { @@ -81,14 +81,20 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act) if (!BindWANDEnough) return true; } + + if (RadiantFinalePvE.CanUse(out act, skipAoeCheck: true)) + + { if (Player.HasStatus(true, StatusID.RagingStrikes) && RagingStrikesPvE.Cooldown.ElapsedOneChargeAfterGCD(1)) return true; } if (BattleVoicePvE.CanUse(out act, skipAoeCheck: true)) { - if (IsLastAction(true, RadiantFinalePvE)) return true; + if (nextGCD.IsTheSameTo(true, RadiantFinalePvE)) return true; + + if (nextGCD.IsTheSameTo(true, RadiantEncorePvE)) return true; if (Player.HasStatus(true, StatusID.RagingStrikes) && RagingStrikesPvE.Cooldown.ElapsedOneChargeAfterGCD(1)) return true; } @@ -96,14 +102,14 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act) if (RadiantFinalePvE.EnoughLevel && RadiantFinalePvE.Cooldown.IsCoolingDown && BattleVoicePvE.EnoughLevel && !BattleVoicePvE.Cooldown.IsCoolingDown) return false; - if (TheWanderersMinuetPvE.CanUse(out act)) + if (TheWanderersMinuetPvE.CanUse(out act) && InCombat) { if (SongEndAfter(ARMYRemainTime) && (Song != Song.NONE || Player.HasStatus(true, StatusID.ArmysEthos))) return true; } if (Song != Song.NONE && EmpyrealArrowPvE.CanUse(out act)) return true; - if (PitchPerfectPvE.CanUse(out act)) + if (PitchPerfectPvE.CanUse(out act, skipCastingCheck: true, skipAoeCheck: true, skipComboCheck: true)) { if (SongEndAfter(3) && Repertoire > 0) return true; @@ -112,13 +118,13 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act) if (Repertoire == 2 && EmpyrealArrowPvE.Cooldown.WillHaveOneChargeGCD()) return true; } - if (MagesBalladPvE.CanUse(out act)) + if (MagesBalladPvE.CanUse(out act) && InCombat) { if (Song == Song.WANDERER && SongEndAfter(WANDRemainTime) && Repertoire == 0) return true; if (Song == Song.ARMY && SongEndAfterGCD(2) && TheWanderersMinuetPvE.Cooldown.IsCoolingDown) return true; } - if (ArmysPaeonPvE.CanUse(out act)) + if (ArmysPaeonPvE.CanUse(out act) && InCombat) { if (TheWanderersMinuetPvE.EnoughLevel && SongEndAfter(MAGERemainTime) && Song == Song.MAGE) return true; if (TheWanderersMinuetPvE.EnoughLevel && SongEndAfter(2) && MagesBalladPvE.Cooldown.IsCoolingDown && Song == Song.WANDERER) return true; @@ -149,21 +155,25 @@ protected override bool GeneralGCD(out IAction? act) if (Player.HasStatus(true, StatusID.RagingStrikes) && Player.WillStatusEndGCD(1, 0, true, StatusID.RagingStrikes)) return true; } - if (CanUseApexArrow(out act)) return true; + if (ResonantArrowPvE.CanUse(out act, skipAoeCheck: true) && Player.HasStatus(true, StatusID.ResonantArrowReady)) return true; + if (CanUseApexArrow(out act)) return true; + if (RadiantEncorePvE.CanUse(out act, skipComboCheck: true) && Player.HasStatus(true, StatusID.RadiantEncoreReady)) return true; if (BlastArrowPvE.CanUse(out act, skipAoeCheck: true)) { if (!Player.HasStatus(true, StatusID.RagingStrikes)) return true; if (Player.HasStatus(true, StatusID.RagingStrikes) && BarragePvE.Cooldown.IsCoolingDown) return true; } - if (ShadowbitePvE.CanUse(out act)) return true; + //aoe + if (ShadowbitePvE.CanUse(out act) && Player.HasStatus(true, StatusID.HawksEye, StatusID.HawksEye_3861, StatusID.Barrage)) return true; + if (WideVolleyPvE.CanUse(out act) && Player.HasStatus(true, StatusID.HawksEye, StatusID.HawksEye_3861, StatusID.Barrage)) return true; if (QuickNockPvE.CanUse(out act)) return true; if (WindbitePvE.CanUse(out act)) return true; if (VenomousBitePvE.CanUse(out act)) return true; - - if (StraightShotPvE.CanUse(out act)) return true; + if (RefulgentArrowPvE.CanUse(out act, skipComboCheck: true) && Player.HasStatus(true, StatusID.HawksEye, StatusID.HawksEye_3861, StatusID.Barrage)) return true; + if (StraightShotPvE.CanUse(out act) && Player.HasStatus(true, StatusID.HawksEye, StatusID.HawksEye_3861, StatusID.Barrage)) return true; if (HeavyShotPvE.CanUse(out act)) return true; return base.GeneralGCD(out act); @@ -202,6 +212,12 @@ private bool BloodletterLogic(out IAction? act) bool isEmpyrealLevel = !EmpyrealArrowPvE.EnoughLevel; bool isRepertoire = Repertoire != 3; + if (HeartbreakShotPvE.CanUse(out act, usedUp: true)) + { + if (isBattleVoice || isRadiantFinale || (isRagingSoon && (isBloodTrait || isNoBloodTrait))) return false; + if (isEmpyrealArrowCD || isEmpyrealSoon || isEmpyrealLevel || isRepertoire) return true; + } + if (RainOfDeathPvE.CanUse(out act, usedUp: true)) { if (isEmpyrealArrowCD || isEmpyrealSoon || isEmpyrealLevel || isRepertoire) return true; diff --git a/BasicRotations/RebornRotations.csproj b/BasicRotations/RebornRotations.csproj index 93c3a7e..21b2317 100644 --- a/BasicRotations/RebornRotations.csproj +++ b/BasicRotations/RebornRotations.csproj @@ -9,7 +9,7 @@ - +