diff --git a/RotationSolver.Basic/Helpers/StatusHelper.cs b/RotationSolver.Basic/Helpers/StatusHelper.cs index eb0a2e55d..4bbb7ada7 100644 --- a/RotationSolver.Basic/Helpers/StatusHelper.cs +++ b/RotationSolver.Basic/Helpers/StatusHelper.cs @@ -76,6 +76,13 @@ public static bool WillStatusEnd(this BattleChara obj, float time, bool isFromSe return CooldownHelper.RecastAfter(remain, time); } + /// + /// Please Do NOT use it! + /// + /// + /// + /// + /// [EditorBrowsable(EditorBrowsableState.Never)] public static float StatusTime(this BattleChara obj, bool isFromSelf, params StatusID[] statusIDs) { diff --git a/RotationSolver.Basic/Rotations/Basic/RPR_Base.cs b/RotationSolver.Basic/Rotations/Basic/RPR_Base.cs index 05b10c0aa..8d7c6adb9 100644 --- a/RotationSolver.Basic/Rotations/Basic/RPR_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/RPR_Base.cs @@ -2,9 +2,14 @@ public abstract class RPR_Base : CustomRotation { - private static RPRGauge JobGauge => Service.JobGauges.Get(); - public override MedicineType MedicineType => MedicineType.Strength; + public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Reaper }; + protected static bool Enshrouded => Player.HasStatus(true, StatusID.Enshrouded); + + protected static bool SoulReaver => Player.HasStatus(true, StatusID.SoulReaver); + + #region JobGauge + static RPRGauge JobGauge => Service.JobGauges.Get(); protected static byte Soul => JobGauge.Soul; @@ -13,30 +18,34 @@ public abstract class RPR_Base : CustomRotation protected static byte LemureShroud => JobGauge.LemureShroud; protected static byte VoidShroud => JobGauge.VoidShroud; + #endregion - protected static bool Enshrouded => Player.HasStatus(true, StatusID.Enshrouded); - - protected static bool SoulReaver => Player.HasStatus(true, StatusID.SoulReaver); - - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Reaper }; - - #region Single + #region Attack Single + /// + /// 1 + /// public static IBaseAction Slice { get; } = new BaseAction(ActionID.Slice) { ActionCheck = b => !Enshrouded && !SoulReaver, }; + /// + /// 2 + /// public static IBaseAction WaxingSlice { get; } = new BaseAction(ActionID.WaxingSlice) { ActionCheck = Slice.ActionCheck, }; + /// + /// 3 + /// public static IBaseAction InfernalSlice { get; } = new BaseAction(ActionID.InfernalSlice) { ActionCheck = Slice.ActionCheck, }; - public static IBaseAction ShadowOfDeath { get; } = new BaseAction(ActionID.ShadowOfDeath, ActionOption.Dot) + public static IBaseAction ShadowOfDeath { get; } = new BaseAction(ActionID.ShadowOfDeath, ActionOption.Dot) { TargetStatus = new[] { StatusID.DeathsDesign }, ActionCheck = b => !SoulReaver, @@ -48,12 +57,18 @@ public abstract class RPR_Base : CustomRotation }; #endregion - #region AoE + #region Attack Area + /// + /// 1 + /// public static IBaseAction SpinningScythe { get; } = new BaseAction(ActionID.SpinningScythe) { ActionCheck = Slice.ActionCheck, }; + /// + /// 2 + /// public static IBaseAction NightmareScythe { get; } = new BaseAction(ActionID.NightmareScythe) { ActionCheck = Slice.ActionCheck, @@ -199,29 +214,20 @@ public abstract class RPR_Base : CustomRotation protected sealed override bool MoveForwardAbility(out IAction act) { if (HellsIngress.CanUse(out act)) return true; - return false; + return base.MoveForwardAbility(out act); } [RotationDesc(ActionID.Feint)] protected sealed override bool DefenseAreaAbility(out IAction act) { - if (!SoulReaver && !Enshrouded) - { - if (Feint.CanUse(out act)) return true; - } - - act = null; - return false; + if (!SoulReaver && !Enshrouded && Feint.CanUse(out act)) return true; + return base.DefenseAreaAbility(out act); } [RotationDesc(ActionID.ArcaneCrest)] protected override bool DefenseSingleAbility(out IAction act) { - if (!SoulReaver && !Enshrouded) - { - if (ArcaneCrest.CanUse(out act)) return true; - } - + if (!SoulReaver && !Enshrouded && ArcaneCrest.CanUse(out act)) return true; return base.DefenseSingleAbility(out act); } } diff --git a/RotationSolver.Basic/Rotations/Basic/SAM_Base.cs b/RotationSolver.Basic/Rotations/Basic/SAM_Base.cs index 7acc49a1b..b4bec7161 100644 --- a/RotationSolver.Basic/Rotations/Basic/SAM_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/SAM_Base.cs @@ -2,8 +2,19 @@ namespace RotationSolver.Basic.Rotations.Basic; public abstract class SAM_Base : CustomRotation { - private static SAMGauge JobGauge => Service.JobGauges.Get(); public override MedicineType MedicineType => MedicineType.Strength; + public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Samurai }; + + [Obsolete("Please use HasMoon", true)] + protected static bool HaveMoon => HasMoon; + protected static bool HasMoon => Player.HasStatus(true, StatusID.Fugetsu); + + [Obsolete("Please use HasFlower", true)] + protected static bool HaveFlower => HasFlower; + protected static bool HasFlower => Player.HasStatus(true, StatusID.Fuka); + + #region JobGauge + static SAMGauge JobGauge => Service.JobGauges.Get(); protected static bool HasSetsu => JobGauge.HasSetsu; @@ -15,16 +26,11 @@ public abstract class SAM_Base : CustomRotation protected static byte MeditationStacks => JobGauge.MeditationStacks; - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Samurai }; - protected static byte SenCount => (byte)((HasGetsu ? 1 : 0) + (HasSetsu ? 1 : 0) + (HasKa ? 1 : 0)); + #endregion - protected static bool HaveMoon => Player.HasStatus(true, StatusID.Fugetsu); - protected static float MoonTime => Player.StatusTime(true, StatusID.Fugetsu); - protected static bool HaveFlower => Player.HasStatus(true, StatusID.Fuka); - protected static float FlowerTime => Player.StatusTime(true, StatusID.Fuka); - #region Single + #region Attack Single public static IBaseAction Hakaze { get; } = new BaseAction(ActionID.Hakaze); public static IBaseAction Jinpu { get; } = new BaseAction(ActionID.Jinpu); @@ -43,7 +49,7 @@ public abstract class SAM_Base : CustomRotation }; #endregion - #region AoE + #region Attack Area public static IBaseAction Fuga { get; } = new BaseAction(ActionID.Fuga); public static IBaseAction Fuko { get; } = new BaseAction(ActionID.Fuko); @@ -172,20 +178,20 @@ public abstract class SAM_Base : CustomRotation protected sealed override bool MoveForwardAbility(out IAction act) { if (HissatsuGyoten.CanUse(out act)) return true; - return false; + return base.MoveForwardAbility(out act); } [RotationDesc(ActionID.Feint)] protected sealed override bool DefenseAreaAbility(out IAction act) { if (Feint.CanUse(out act)) return true; - return false; + return base.DefenseAreaAbility(out act); } [RotationDesc(ActionID.ThirdEye)] protected override bool DefenseSingleAbility(out IAction act) { if (ThirdEye.CanUse(out act)) return true; - return false; + return base.DefenseSingleAbility(out act); } } \ No newline at end of file diff --git a/RotationSolver.Basic/Rotations/Basic/SCH_Base.cs b/RotationSolver.Basic/Rotations/Basic/SCH_Base.cs index 082e40ec5..9f3325496 100644 --- a/RotationSolver.Basic/Rotations/Basic/SCH_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/SCH_Base.cs @@ -2,21 +2,22 @@ namespace RotationSolver.Basic.Rotations.Basic; public abstract class SCH_Base : CustomRotation { - private static SCHGauge JobGauge => Service.JobGauges.Get(); - public override MedicineType MedicineType => MedicineType.Mind; - - protected static byte FairyGauge => JobGauge.FairyGauge; - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Scholar }; - private sealed protected override IBaseAction Raise => Resurrection; + #region Job Gauge + static SCHGauge JobGauge => Service.JobGauges.Get(); + + protected static byte FairyGauge => JobGauge.FairyGauge; protected static bool HasAetherflow => JobGauge.Aetherflow > 0; protected static bool HasSeraph => JobGauge.SeraphTimer > 0; + #endregion #region Heal + private sealed protected override IBaseAction Raise => Resurrection; + public static IBaseAction Physick { get; } = new BaseAction(ActionID.Physick, ActionOption.Heal); public static IBaseAction Adloquium { get; } = new BaseAction(ActionID.Adloquium, ActionOption.Heal) diff --git a/RotationSolver.Basic/Rotations/Basic/SGE_Base.cs b/RotationSolver.Basic/Rotations/Basic/SGE_Base.cs index dcc87bb1e..630b2d511 100644 --- a/RotationSolver.Basic/Rotations/Basic/SGE_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/SGE_Base.cs @@ -2,29 +2,25 @@ namespace RotationSolver.Basic.Rotations.Basic; public abstract class SGE_Base : CustomRotation { - private static SGEGauge JobGauge => Service.JobGauges.Get(); + public override MedicineType MedicineType => MedicineType.Strength; + public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Sage }; + + #region Job Gauge + static SGEGauge JobGauge => Service.JobGauges.Get(); protected static bool HasEukrasia => JobGauge.Eukrasia; protected static byte Addersgall => JobGauge.Addersgall; protected static byte Addersting => JobGauge.Addersting; - public override MedicineType MedicineType => MedicineType.Strength; - protected static bool AddersgallEndAfter(float time) - { - return EndAfter(JobGauge.AddersgallTimer / 1000f, time); - } + protected static float AddersgallTimer => JobGauge.AddersgallTimer / 1000f; + protected static bool AddersgallEndAfter(float time) => EndAfter(AddersgallTimer, time); - protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount = 0) - { - return EndAfterGCD(JobGauge.AddersgallTimer / 1000f, gctCount, abilityCount); - } - - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Sage }; - private sealed protected override IBaseAction Raise => Egeiro; - - public static IBaseAction Egeiro { get; } = new BaseAction(ActionID.Egeiro, ActionOption.Friendly); + protected static bool AddersgallEndAfterGCD(uint gctCount = 0, float offset = 0) + => EndAfterGCD(AddersgallTimer, gctCount, offset); + #endregion + #region Attack public static IBaseAction Dosis { get; } = new BaseAction(ActionID.Dosis); public static IBaseAction EukrasianDosis { get; } = new BaseAction(ActionID.EukrasianDosis, ActionOption.Dot) @@ -36,6 +32,8 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount StatusID.EukrasianDosis3 }, }; + public static IBaseAction Dyskrasia { get; } = new BaseAction(ActionID.Dyskrasia); + public static IBaseAction Phlegma { get; } = new BaseAction(ActionID.Phlegma); @@ -43,6 +41,22 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount public static IBaseAction Phlegma3 { get; } = new BaseAction(ActionID.Phlegma3); + public static IBaseAction Toxikon { get; } = new BaseAction(ActionID.Toxikon) + { + ActionCheck = b => Addersting > 0, + }; + + public static IBaseAction Rhizomata { get; } = new BaseAction(ActionID.Rhizomata) + { + ActionCheck = b => Addersgall < 3, + }; + + public static IBaseAction Pneuma { get; } = new BaseAction(ActionID.Pneuma); + #endregion + + #region Heal + private sealed protected override IBaseAction Raise => Egeiro; + public static IBaseAction Egeiro { get; } = new BaseAction(ActionID.Egeiro, ActionOption.Friendly); public static IBaseAction Diagnosis { get; } = new BaseAction(ActionID.Diagnosis, ActionOption.Heal); public static IBaseAction Kardia { get; } = new BaseAction(ActionID.Kardia, ActionOption.Heal) @@ -71,26 +85,14 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount public static IBaseAction Soteria { get; } = new BaseAction(ActionID.Soteria, ActionOption.Heal); - public static IBaseAction Icarus { get; } = new BaseAction(ActionID.Icarus, ActionOption.EndSpecial) - { - ChoiceTarget = TargetFilter.FindTargetForMoving, - }; - - public static IBaseAction Druochole { get; } = new BaseAction(ActionID.Druochole, ActionOption.Heal) - { - ActionCheck = b => JobGauge.Addersgall > 0, - }; - - public static IBaseAction Dyskrasia { get; } = new BaseAction(ActionID.Dyskrasia); - public static IBaseAction Kerachole { get; } = new BaseAction(ActionID.Kerachole, ActionOption.Heal) { - ActionCheck = b => JobGauge.Addersgall > 0, + ActionCheck = b => Addersgall > 0, }; public static IBaseAction Ixochole { get; } = new BaseAction(ActionID.Ixochole, ActionOption.Heal) { - ActionCheck = b => JobGauge.Addersgall > 0, + ActionCheck = b => Addersgall > 0, }; public static IBaseAction Zoe { get; } = new BaseAction(ActionID.Zoe, ActionOption.Heal); @@ -98,12 +100,26 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount public static IBaseAction Taurochole { get; } = new BaseAction(ActionID.Taurochole, ActionOption.Heal) { ChoiceTarget = TargetFilter.FindAttackedTarget, - ActionCheck = b => JobGauge.Addersgall > 0, + ActionCheck = b => Addersgall > 0, }; - public static IBaseAction Toxikon { get; } = new BaseAction(ActionID.Toxikon) + public static IBaseAction Druochole { get; } = new BaseAction(ActionID.Druochole, ActionOption.Heal) { - ActionCheck = b => JobGauge.Addersting > 0, + ActionCheck = b => Addersgall > 0, + }; + public static IBaseAction Pepsis { get; } = new BaseAction(ActionID.Pepsis, ActionOption.Heal) + { + ActionCheck = b => + { + foreach (var chara in DataCenter.PartyMembers) + { + if (chara.HasStatus(true, StatusID.EukrasianDiagnosis, StatusID.EukrasianPrognosis) + && b.WillStatusEndGCD(2, 0, true, StatusID.EukrasianDiagnosis, StatusID.EukrasianPrognosis) + && chara.GetHealthRatio() < 0.9) return true; + } + + return false; + }, }; public static IBaseAction Haima { get; } = new BaseAction(ActionID.Haima, ActionOption.Heal) @@ -118,38 +134,22 @@ protected static bool AddersgallEndAfterGCD(uint gctCount = 0, int abilityCount public static IBaseAction EukrasianPrognosis { get; } = new BaseAction(ActionID.EukrasianPrognosis, ActionOption.Heal); - public static IBaseAction Rhizomata { get; } = new BaseAction(ActionID.Rhizomata) - { - ActionCheck = b => JobGauge.Addersgall < 3, - }; - public static IBaseAction Holos { get; } = new BaseAction(ActionID.Holos, ActionOption.Heal); public static IBaseAction Panhaima { get; } = new BaseAction(ActionID.Panhaima, ActionOption.Heal); public static IBaseAction Krasis { get; } = new BaseAction(ActionID.Krasis, ActionOption.Heal); + #endregion - public static IBaseAction Pneuma { get; } = new BaseAction(ActionID.Pneuma); - - public static IBaseAction Pepsis { get; } = new BaseAction(ActionID.Pepsis, ActionOption.Heal) + public static IBaseAction Icarus { get; } = new BaseAction(ActionID.Icarus, ActionOption.EndSpecial) { - ActionCheck = b => - { - foreach (var chara in DataCenter.PartyMembers) - { - if (chara.HasStatus(true, StatusID.EukrasianDiagnosis, StatusID.EukrasianPrognosis) - && b.WillStatusEndGCD(2, 0, true, StatusID.EukrasianDiagnosis, StatusID.EukrasianPrognosis) - && chara.GetHealthRatio() < 0.9) return true; - } - - return false; - }, + ChoiceTarget = TargetFilter.FindTargetForMoving, }; [RotationDesc(ActionID.Icarus)] protected sealed override bool MoveForwardAbility(out IAction act) { if (Icarus.CanUse(out act)) return true; - return false; + return base.MoveForwardAbility(out act); } } diff --git a/RotationSolver.Basic/Rotations/Basic/SMN_Base.cs b/RotationSolver.Basic/Rotations/Basic/SMN_Base.cs index 676192d40..7e6ec51fa 100644 --- a/RotationSolver.Basic/Rotations/Basic/SMN_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/SMN_Base.cs @@ -2,32 +2,18 @@ public abstract class SMN_Base : CustomRotation { - private static SMNGauge JobGauge => Service.JobGauges.Get(); - public override MedicineType MedicineType => MedicineType.Strength; - - protected static bool HasAetherflowStacks => JobGauge.HasAetherflowStacks; - - protected static byte Attunement => JobGauge.Attunement; - - protected static bool SummonTimeEndAfter(float time) - { - return EndAfter(JobGauge.SummonTimerRemaining / 1000f, time); - } - - protected static ushort SummonTimerRemaining => JobGauge.SummonTimerRemaining; - - protected static ushort AttunmentTimerRemaining => JobGauge.AttunmentTimerRemaining; - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Summoner, ClassJobID.Arcanist }; protected override bool CanHealSingleSpell => false; - private sealed protected override IBaseAction Raise => Resurrection; - - protected static bool HaveSummon => DataCenter.HasPet && JobGauge.SummonTimerRemaining == 0; - protected static bool InBahamut => Service.GetAdjustedActionId(ActionID.AstralFlow) == ActionID.DeathFlare; protected static bool InPhoenix => Service.GetAdjustedActionId(ActionID.AstralFlow) == ActionID.Rekindle; + #region JobGauge + static SMNGauge JobGauge => Service.JobGauges.Get(); + + protected static bool HasAetherflowStacks => JobGauge.HasAetherflowStacks; + + protected static byte Attunement => JobGauge.Attunement; protected static bool IsIfritReady => JobGauge.IsIfritReady; @@ -41,22 +27,37 @@ protected static bool SummonTimeEndAfter(float time) protected static bool InGaruda => JobGauge.IsGarudaAttuned; + private static float SummonTimerRemaining => JobGauge.SummonTimerRemaining / 1000f; + protected static bool SummonTimeEndAfter(float time) => EndAfter(SummonTimerRemaining, time); + + protected static bool SummonTimeEndAfterGCD(uint gctCount = 0, float offset = 0) + => EndAfterGCD(SummonTimerRemaining, gctCount, offset); + + private static float AttunmentTimerRemaining => JobGauge.AttunmentTimerRemaining / 1000f; + protected static bool AttunmentTimeEndAfter(float time) => EndAfter(AttunmentTimerRemaining, time); + + protected static bool AttunmentTimeEndAfterGCD(uint gctCount = 0, float offset = 0) + => EndAfterGCD(AttunmentTimerRemaining, gctCount, offset); + + private static bool HasSummon => DataCenter.HasPet && SummonTimeEndAfterGCD(); + #endregion + #region Summon public static IBaseAction SummonRuby { get; } = new BaseAction(ActionID.SummonRuby) { StatusProvide = new[] { StatusID.IfritsFavor }, - ActionCheck = b => HaveSummon && IsIfritReady + ActionCheck = b => DataCenter.HasPet && !SummonTimeEndAfterGCD() && IsIfritReady }; public static IBaseAction SummonTopaz { get; } = new BaseAction(ActionID.SummonTopaz) { - ActionCheck = b => HaveSummon && IsTitanReady, + ActionCheck = b => HasSummon && IsTitanReady, }; public static IBaseAction SummonEmerald { get; } = new BaseAction(ActionID.SummonEmerald) { StatusProvide = new[] { StatusID.GarudasFavor }, - ActionCheck = b => HaveSummon && IsGarudaReady, + ActionCheck = b => HasSummon && IsGarudaReady, }; public static IBaseAction SummonCarbuncle { get; } = new BaseAction(ActionID.SummonCarbuncle) @@ -78,12 +79,12 @@ protected static bool SummonTimeEndAfter(float time) public static IBaseAction AetherCharge { get; } = new BaseAction(ActionID.AetherCharge) { - ActionCheck = b => InCombat && HaveSummon + ActionCheck = b => InCombat && HasSummon }; public static IBaseAction SummonBahamut { get; } = new BaseAction(ActionID.SummonBahamut) { - ActionCheck = b => InCombat && HaveSummon + ActionCheck = b => InCombat && HasSummon }; public static IBaseAction EnkindleBahamut { get; } = new BaseAction(ActionID.EnkindleBahamut) @@ -139,7 +140,7 @@ protected static bool SummonTimeEndAfter(float time) public static IBaseAction RadiantAegis { get; } = new BaseAction(ActionID.RadiantAegis, ActionOption.Heal) { - ActionCheck = b => HaveSummon + ActionCheck = b => HasSummon }; public static IBaseAction EnergyDrain { get; } = new BaseAction(ActionID.EnergyDrainSMN) @@ -165,28 +166,32 @@ protected static bool SummonTimeEndAfter(float time) }; #endregion + #region Heal + private sealed protected override IBaseAction Raise => Resurrection; + public static IBaseAction Resurrection { get; } = new BaseAction(ActionID.ResurrectionSMN, ActionOption.Friendly); public static IBaseAction Physick { get; } = new BaseAction(ActionID.Physick, ActionOption.Heal); + #endregion [RotationDesc(ActionID.RadiantAegis)] protected sealed override bool DefenseSingleAbility(out IAction act) { if (RadiantAegis.CanUse(out act)) return true; - return false; + return base.DefenseSingleAbility(out act); } [RotationDesc(ActionID.Physick)] - protected override bool HealSingleGCD(out IAction act) + protected sealed override bool HealSingleGCD(out IAction act) { if (Physick.CanUse(out act)) return true; - return false; + return base.HealSingleGCD(out act); } [RotationDesc(ActionID.Addle)] protected override bool DefenseAreaAbility(out IAction act) { if (Addle.CanUse(out act)) return true; - return false; + return base.DefenseAreaAbility(out act); } } \ No newline at end of file diff --git a/RotationSolver.Basic/Rotations/Basic/WAR_Base.cs b/RotationSolver.Basic/Rotations/Basic/WAR_Base.cs index 75bf262d2..6327b4fd8 100644 --- a/RotationSolver.Basic/Rotations/Basic/WAR_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/WAR_Base.cs @@ -2,26 +2,43 @@ namespace RotationSolver.Basic.Rotations.Basic; public abstract class WAR_Base : CustomRotation { - private static WARGauge JobGauge => Service.JobGauges.Get(); public override MedicineType MedicineType => MedicineType.Strength; - protected static byte BeastGauge => JobGauge.BeastGauge; public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.Warrior, ClassJobID.Marauder }; - private sealed protected override IBaseAction TankStance => Defiance; - public static IBaseAction Defiance { get; } = new BaseAction(ActionID.Defiance, ActionOption.Defense); + static WARGauge JobGauge => Service.JobGauges.Get(); + protected static byte BeastGauge => JobGauge.BeastGauge; + + #region Attack Single + /// + /// 1 + /// public static IBaseAction HeavySwing { get; } = new BaseAction(ActionID.HeavySwing); + /// + /// 2 + /// public static IBaseAction Maim { get; } = new BaseAction(ActionID.Maim); + /// + /// 3 + /// public static IBaseAction StormsPath { get; } = new BaseAction(ActionID.StormsPath); + /// + /// 4 + /// public static IBaseAction StormsEye { get; } = new BaseAction(ActionID.StormsEye) { ActionCheck = b => Player.WillStatusEndGCD(9, 0, true, StatusID.SurgingTempest), }; + public static IBaseAction InnerBeast { get; } = new BaseAction(ActionID.InnerBeast) + { + ActionCheck = b => JobGauge.BeastGauge >= 50 || Player.HasStatus(true, StatusID.InnerRelease), + }; + public static IBaseAction Tomahawk { get; } = new BaseAction(ActionID.Tomahawk) { FilterForHostiles = TargetFilter.TankRangeTarget, @@ -35,25 +52,44 @@ public abstract class WAR_Base : CustomRotation public static IBaseAction Upheaval { get; } = new BaseAction(ActionID.Upheaval) { + //TODO: Why is that status? StatusNeed = new StatusID[] { StatusID.SurgingTempest }, }; + #endregion + #region Attack Area + /// + /// 1 + /// public static IBaseAction Overpower { get; } = new BaseAction(ActionID.Overpower); + /// + /// 2 + /// public static IBaseAction MythrilTempest { get; } = new BaseAction(ActionID.MythrilTempest); - public static IBaseAction Orogeny { get; } = new BaseAction(ActionID.Orogeny); - - public static IBaseAction InnerBeast { get; } = new BaseAction(ActionID.InnerBeast) + public static IBaseAction SteelCyclone { get; } = new BaseAction(ActionID.SteelCyclone) { - ActionCheck = b => JobGauge.BeastGauge >= 50 || Player.HasStatus(true, StatusID.InnerRelease), + ActionCheck = InnerBeast.ActionCheck, }; - public static IBaseAction SteelCyclone { get; } = new BaseAction(ActionID.SteelCyclone) + public static IBaseAction PrimalRend { get; } = new BaseAction(ActionID.PrimalRend) { - ActionCheck = InnerBeast.ActionCheck, + StatusNeed = new[] { StatusID.PrimalRendReady } }; + public static IBaseAction Orogeny { get; } = new BaseAction(ActionID.Orogeny); + + #endregion + + #region Heal + private sealed protected override IBaseAction TankStance => Defiance; + + public static IBaseAction Defiance { get; } = new BaseAction(ActionID.Defiance, ActionOption.Defense); + #endregion + + + #region Support public static IBaseAction Infuriate { get; } = new BaseAction(ActionID.Infuriate) { StatusProvide = new[] { StatusID.NascentChaos }, @@ -67,13 +103,13 @@ public abstract class WAR_Base : CustomRotation { ActionCheck = b => HasHostilesInRange && !InnerRelease.IsCoolingDown, }; + #endregion + #region Defense Ability public static IBaseAction ThrillOfBattle { get; } = new BaseAction(ActionID.ThrillOfBattle, ActionOption.Defense); public static IBaseAction Equilibrium { get; } = new BaseAction(ActionID.Equilibrium, ActionOption.Defense); - - #region Defense Ability public static IBaseAction Vengeance { get; } = new BaseAction(ActionID.Vengeance, ActionOption.Defense) { StatusProvide = Rampart.StatusProvide, @@ -98,12 +134,6 @@ public abstract class WAR_Base : CustomRotation }; #endregion - - public static IBaseAction PrimalRend { get; } = new BaseAction(ActionID.PrimalRend) - { - StatusNeed = new[] { StatusID.PrimalRendReady } - }; - protected override bool EmergencyAbility(IAction nextGCD, out IAction act) { if (Holmgang.CanUse(out act) && BaseAction.TankBreakOtherCheck(JobIDs[0])) return true; @@ -114,13 +144,13 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction act) protected sealed override bool MoveForwardAbility(out IAction act) { if (Onslaught.CanUse(out act)) return true; - return false; + return base.MoveForwardAbility(out act); } [RotationDesc(ActionID.PrimalRend)] protected sealed override bool MoveForwardGCD(out IAction act) { if (PrimalRend.CanUse(out act, CanUseOption.MustUse)) return true; - return false; + return base.MoveForwardGCD(out act); } } diff --git a/RotationSolver.Basic/Rotations/Basic/WHM_Base.cs b/RotationSolver.Basic/Rotations/Basic/WHM_Base.cs index 9ceaa5061..fb2fd1f07 100644 --- a/RotationSolver.Basic/Rotations/Basic/WHM_Base.cs +++ b/RotationSolver.Basic/Rotations/Basic/WHM_Base.cs @@ -2,9 +2,12 @@ namespace RotationSolver.Basic.Rotations.Basic; public abstract class WHM_Base : CustomRotation { - private static WHMGauge JobGauge => Service.JobGauges.Get(); + public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.WhiteMage, ClassJobID.Conjurer }; public override MedicineType MedicineType => MedicineType.Mind; + #region Job Gauge + private static WHMGauge JobGauge => Service.JobGauges.Get(); + protected static byte Lily => JobGauge.Lily; protected static byte BloodLily => JobGauge.BloodLily; @@ -14,20 +17,20 @@ protected static bool LilyAfter(float time) return EndAfter(JobGauge.LilyTimer / 1000f, time); } - protected static bool LilyAfterGCD(uint gctCount = 0, int abilityCount = 0) + protected static bool LilyAfterGCD(uint gctCount = 0, float offset = 0) { - return EndAfterGCD(JobGauge.LilyTimer / 1000f, gctCount, abilityCount); + return EndAfterGCD(JobGauge.LilyTimer / 1000f, gctCount, offset); } + #endregion - public sealed override ClassJobID[] JobIDs => new ClassJobID[] { ClassJobID.WhiteMage, ClassJobID.Conjurer }; + #region Heal private sealed protected override IBaseAction Raise => Raise1; + public static IBaseAction Raise1 { get; } = new BaseAction(ActionID.Raise1, ActionOption.Friendly); - #region Heal public static IBaseAction Cure { get; } = new BaseAction(ActionID.Cure, ActionOption.Heal); public static IBaseAction Medica { get; } = new BaseAction(ActionID.Medica, ActionOption.Heal); - public static IBaseAction Raise1 { get; } = new BaseAction(ActionID.Raise1, ActionOption.Friendly); public static IBaseAction Cure2 { get; } = new BaseAction(ActionID.Cure2, ActionOption.Heal);