diff --git a/BossMod/Autorotation/Standard/akechi/AkechiTools.cs b/BossMod/Autorotation/Standard/akechi/AkechiTools.cs index d32937236f..a268d6a1f5 100644 --- a/BossMod/Autorotation/Standard/akechi/AkechiTools.cs +++ b/BossMod/Autorotation/Standard/akechi/AkechiTools.cs @@ -526,6 +526,12 @@ public static float TargetHPP(Actor? target = null) /// - FALSE if otherwise or last action was not a combo action. protected AID ComboLastMove => (AID)(object)World.Client.ComboState.Action; + /// + /// Checks the time left remaining inside current combo before expiration. + /// NOTE: This does NOT check all actions, only combo actions. + /// + protected float ComboTimer => (float)(object)World.Client.ComboState.Remaining; + /// /// Retrieves actual cast time of a specified action. /// Example:
diff --git a/BossMod/Autorotation/Standard/akechi/DPS/AkechiBLM.cs b/BossMod/Autorotation/Standard/akechi/DPS/AkechiBLM.cs index e23a49048d..6053d5008d 100644 --- a/BossMod/Autorotation/Standard/akechi/DPS/AkechiBLM.cs +++ b/BossMod/Autorotation/Standard/akechi/DPS/AkechiBLM.cs @@ -207,12 +207,15 @@ private AID BestXenoglossy private bool canRetrace; //Can use Retrace private bool canBTL; //Can use Between the Lines private bool hasThunderhead; //Has Thunderhead buff - private float ThunderLeft; //Time left on DOT effect (30s base) - public bool canOpen; //Can use opener + private float thunderLeft; //Time left on DOT effect (30s base) + private bool canOpen; //Can use opener private bool ShouldUseAOE; private int NumSplashTargets; private Enemy? BestSplashTargets; + private Enemy? BestDOTTargets; private Enemy? BestSplashTarget; + private Enemy? BestDOTTarget; + #endregion #region Module Helpers @@ -264,7 +267,7 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) canRetrace = ActionReady(AID.Retrace) && PlayerHasEffect(SID.LeyLines, 30); //Can use Retrace canBTL = ActionReady(AID.BetweenTheLines) && PlayerHasEffect(SID.LeyLines, 30); //Can use Between the Lines hasThunderhead = PlayerHasEffect(SID.Thunderhead, 30); //Has Thunderhead buff - ThunderLeft = Utils.MaxAll( //Time left on DOT effect + thunderLeft = Utils.MaxAll( //Time left on DOT effect StatusDetails(BestSplashTarget?.Actor, SID.Thunder, Player.InstanceID, 24).Left, StatusDetails(BestSplashTarget?.Actor, SID.ThunderII, Player.InstanceID, 18).Left, StatusDetails(BestSplashTarget?.Actor, SID.ThunderIII, Player.InstanceID, 27).Left, @@ -272,8 +275,10 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) StatusDetails(BestSplashTarget?.Actor, SID.HighThunder, Player.InstanceID, 30).Left, StatusDetails(BestSplashTarget?.Actor, SID.HighThunderII, Player.InstanceID, 24).Left); ShouldUseAOE = Unlocked(AID.Blizzard2) && NumSplashTargets > 2; - (BestSplashTargets, NumSplashTargets) = GetBestTarget(BestSplashTarget, 25, IsSplashTarget); + (BestSplashTargets, NumSplashTargets) = GetBestTarget(primaryTarget, 25, IsSplashTarget); + (BestDOTTargets, thunderLeft) = GetDOTTarget(strategy, primaryTarget, ThunderLeft, 2); BestSplashTarget = ShouldUseAOE ? BestSplashTargets : primaryTarget; + BestDOTTarget = Unlocked(AID.Thunder1) ? BestDOTTargets : primaryTarget; canOpen = TotalCD(AID.LeyLines) <= 120 && TotalCD(AID.Triplecast) <= 0.1f && TotalCD(AID.Manafont) <= 0.1f @@ -406,18 +411,18 @@ movingOption is CastingOption.Forbid && { if (strategy.Automatic()) QueueGCD(BestThunder, - TargetChoice(thunder), - ThunderLeft <= 3 ? GCDPriority.NeedDOT : + TargetChoice(thunder) ?? (ShouldUseAOE ? BestSplashTargets?.Actor : BestDOTTarget?.Actor), + thunderLeft <= 3 ? GCDPriority.NeedDOT : GCDPriority.DOT); if (strategy.ForceST()) QueueGCD(BestThunderST, TargetChoice(thunder) ?? BestSplashTarget?.Actor, - ThunderLeft <= 3 ? GCDPriority.NeedDOT : + thunderLeft <= 3 ? GCDPriority.NeedDOT : GCDPriority.DOT); if (strategy.ForceAOE()) QueueGCD(BestThunderAOE, TargetChoice(thunder) ?? BestSplashTarget?.Actor, - ThunderLeft <= 3 ? GCDPriority.NeedDOT : + thunderLeft <= 3 ? GCDPriority.NeedDOT : GCDPriority.DOT); } //Polyglots @@ -1004,16 +1009,22 @@ private void BestAOE(Actor? target) //AOE rotation based on level #endregion #region Cooldown Helpers + + #region DOT + private static SID[] GetDotStatus() => [SID.Thunder, SID.ThunderII, SID.ThunderIII, SID.ThunderIV, SID.HighThunder, SID.HighThunderII]; + private float ThunderLeft(Actor? target) => target == null ? float.MaxValue : GetDotStatus().Select(stat => StatusDetails(target, (uint)stat, Player.InstanceID).Left).FirstOrDefault(dur => dur > 0); private bool ShouldUseThunder(Actor? target, ThunderStrategy strategy) => strategy switch { - ThunderStrategy.Thunder3 => Player.InCombat && target != null && hasThunderhead && ThunderLeft <= 3 && In25y(target), - ThunderStrategy.Thunder6 => Player.InCombat && target != null && hasThunderhead && ThunderLeft <= 6 && In25y(target), - ThunderStrategy.Thunder9 => Player.InCombat && target != null && hasThunderhead && ThunderLeft <= 9 && In25y(target), - ThunderStrategy.Thunder0 => Player.InCombat && target != null && hasThunderhead && ThunderLeft is 0 && In25y(target), + ThunderStrategy.Thunder3 => Player.InCombat && target != null && hasThunderhead && thunderLeft <= 3 && In25y(target), + ThunderStrategy.Thunder6 => Player.InCombat && target != null && hasThunderhead && thunderLeft <= 6 && In25y(target), + ThunderStrategy.Thunder9 => Player.InCombat && target != null && hasThunderhead && thunderLeft <= 9 && In25y(target), + ThunderStrategy.Thunder0 => Player.InCombat && target != null && hasThunderhead && thunderLeft is 0 && In25y(target), ThunderStrategy.Force => hasThunderhead, ThunderStrategy.Delay => false, _ => false }; + #endregion + private bool ShouldSpendPolyglot(Actor? target, PolyglotStrategy strategy) => strategy switch { PolyglotStrategy.AutoSpendAll => target != null && UsePolyglots(), diff --git a/BossMod/Autorotation/Standard/akechi/Healer/AkechiSCH.cs b/BossMod/Autorotation/Standard/akechi/Healer/AkechiSCH.cs index 34972fedea..b7bb4c0771 100644 --- a/BossMod/Autorotation/Standard/akechi/Healer/AkechiSCH.cs +++ b/BossMod/Autorotation/Standard/akechi/Healer/AkechiSCH.cs @@ -9,54 +9,11 @@ namespace BossMod.Autorotation.akechi; public sealed class AkechiSCH(RotationModuleManager manager, Actor player) : AkechiTools(manager, player) { #region Enums: Abilities / Strategies - public enum Track - { - AOE, //ST&AOE rotations tracking - Bio, //Bio tracking - Potion, //Potion item tracking - EnergyDrain, //Energy Drain tracking - ChainStratagem, //Chain Stratagem tracking - Aetherflow, //Aetherflow tracking - } - public enum AOEStrategy - { - Auto, //Automatically decide when to use ST or AOE abilities - Ruin2, //Force use of Ruin II only - Broil, //Force use of Broil only - ArtOfWar, //Force use of Art of War only - } - public enum BioStrategy - { - Bio3, //Force use of Bio if target has 3s or less remaining on DOT effect - Bio6, //Force use of Bio if target has 6s or less remaining on DOT effect - Bio9, //Force use of Bio if target has 9s or less remaining on DOT effect - Bio0, //Force use of Bio if target has does not have DOT effect - Force, //Force use of Bio regardless of DOT effect - Delay //Delay the use of Bio for manual or strategic usage - } - public enum PotionStrategy - { - Manual, //Manual potion usage - AlignWithRaidBuffs, //Align potion usage with raid buffs - Immediate //Use potions immediately when available - } - public enum EnergyStrategy - { - Use3, //Use all stacks of Aetherflow for Energy Drain - Use2, //Use 2 stacks of Aetherflow for Energy Drain - Use1, //Use 1 stack of Aetherflow for Energy Drain - Force, //Force the use of Energy Drain if any Aetherflow is available - Delay //Delay the use of Energy Drain - } - public enum OffensiveStrategy - { - Automatic, //Automatically decide when to use off-global offensive abilities - Force, //Force the use of off-global offensive abilities, regardless of weaving conditions - AnyWeave, //Force the use of off-global offensive abilities in any next possible weave slot - EarlyWeave, //Force the use of off-global offensive abilities in very next FIRST weave slot only - LateWeave, //Force the use of off-global offensive abilities in very next LAST weave slot only - Delay //Delay the use of offensive abilities for strategic reasons - } + public enum Track { AOE, Bio, Potion, EnergyDrain, ChainStratagem, Aetherflow } + public enum AOEStrategy { Auto, Ruin2, Broil, ArtOfWar } + public enum BioStrategy { Bio3, Bio6, Bio9, Bio0, Force, Delay } + public enum PotionStrategy { Manual, AlignWithRaidBuffs, Immediate } + public enum EnergyStrategy { Use3, Use2, Use1, Force, Delay } #endregion #region Module Definitions @@ -96,21 +53,21 @@ public static RotationModuleDefinition Definition() .AddOption(EnergyStrategy.Force, "Force", "Force use of Energy Drain if any Aetherflow is available", 0, 0, ActionTargets.None, 45) .AddOption(EnergyStrategy.Delay, "Delay", "Delay use of Energy Drain", 0, 0, ActionTargets.None, 45) .AddAssociatedActions(AID.EnergyDrain); - res.Define(Track.ChainStratagem).As("Chain Stratagem", "Stratagem", uiPriority: 170) - .AddOption(OffensiveStrategy.Automatic, "Auto", "Normal use of Chain Stratagem") - .AddOption(OffensiveStrategy.Force, "Force", "Force use of Chain Stratagem", 120, 20, ActionTargets.Hostile, 66) - .AddOption(OffensiveStrategy.AnyWeave, "Any Weave", "Force use of Chain Stratagem in any next possible weave slot", 120, 20, ActionTargets.Hostile, 66) - .AddOption(OffensiveStrategy.EarlyWeave, "Early Weave", "Force use of Chain Stratagem in very next FIRST weave slot only", 120, 20, ActionTargets.Hostile, 66) - .AddOption(OffensiveStrategy.LateWeave, "Late Weave", "Force use of Chain Stratagem in very next LAST weave slot only", 120, 20, ActionTargets.Hostile, 66) - .AddOption(OffensiveStrategy.Delay, "Delay", "Delay use of Chain Stratagem", 0, 0, ActionTargets.None, 66) + res.Define(Track.ChainStratagem).As("Chain Stratagem", "Stratagem", uiPriority: 170) + .AddOption(OGCDStrategy.Automatic, "Auto", "Normal use of Chain Stratagem") + .AddOption(OGCDStrategy.Force, "Force", "Force use of Chain Stratagem", 120, 20, ActionTargets.Hostile, 66) + .AddOption(OGCDStrategy.AnyWeave, "Any Weave", "Force use of Chain Stratagem in any next possible weave slot", 120, 20, ActionTargets.Hostile, 66) + .AddOption(OGCDStrategy.EarlyWeave, "Early Weave", "Force use of Chain Stratagem in very next FIRST weave slot only", 120, 20, ActionTargets.Hostile, 66) + .AddOption(OGCDStrategy.LateWeave, "Late Weave", "Force use of Chain Stratagem in very next LAST weave slot only", 120, 20, ActionTargets.Hostile, 66) + .AddOption(OGCDStrategy.Delay, "Delay", "Delay use of Chain Stratagem", 0, 0, ActionTargets.None, 66) .AddAssociatedActions(AID.ChainStratagem); - res.Define(Track.Aetherflow).As("Aetherflow", "A.flow", uiPriority: 160) - .AddOption(OffensiveStrategy.Automatic, "Auto", "Normal use of Aetherflow") - .AddOption(OffensiveStrategy.Force, "Force", "Force use of Aetherflow", 60, 10, ActionTargets.Self, 45) - .AddOption(OffensiveStrategy.AnyWeave, "Any Weave", "Force use of Aetherflow in any next possible weave slot", 60, 10, ActionTargets.Self, 45) - .AddOption(OffensiveStrategy.EarlyWeave, "Early Weave", "Force use of Aetherflow in very next FIRST weave slot only", 60, 10, ActionTargets.Self, 45) - .AddOption(OffensiveStrategy.LateWeave, "Late Weave", "Force use of Aetherflow in very next LAST weave slot only", 60, 10, ActionTargets.Self, 45) - .AddOption(OffensiveStrategy.Delay, "Delay", "Delay use of Aetherflow", 0, 0, ActionTargets.None, 45) + res.Define(Track.Aetherflow).As("Aetherflow", "A.flow", uiPriority: 160) + .AddOption(OGCDStrategy.Automatic, "Auto", "Normal use of Aetherflow") + .AddOption(OGCDStrategy.Force, "Force", "Force use of Aetherflow", 60, 10, ActionTargets.Self, 45) + .AddOption(OGCDStrategy.AnyWeave, "Any Weave", "Force use of Aetherflow in any next possible weave slot", 60, 10, ActionTargets.Self, 45) + .AddOption(OGCDStrategy.EarlyWeave, "Early Weave", "Force use of Aetherflow in very next FIRST weave slot only", 60, 10, ActionTargets.Self, 45) + .AddOption(OGCDStrategy.LateWeave, "Late Weave", "Force use of Aetherflow in very next LAST weave slot only", 60, 10, ActionTargets.Self, 45) + .AddOption(OGCDStrategy.Delay, "Delay", "Delay use of Aetherflow", 0, 0, ActionTargets.None, 45) .AddAssociatedActions(AID.Aetherflow); return res; @@ -153,15 +110,8 @@ public static RotationModuleDefinition Definition() private float bioLeft; //Time left on DOT effect (30s base) private float stratagemLeft; //Time left on Chain Stratagem (15s base) private bool ShouldUseAOE; //Checks if AOE should be used - public bool canWeaveIn; //Can weave in oGCDs - public bool canWeaveEarly; //Can early weave oGCDs - public bool canWeaveLate; //Can late weave oGCDs - public bool quarterWeave; //Can last second weave oGCDs - public float PotionLeft; //Time left on potion buff (30s base) - public float RaidBuffsLeft; //Time left on raid-wide buffs (typically 20s-22s) - public float RaidBuffsIn; //Time until raid-wide buffs are applied again (typically 20s-22s) - public float BurstWindowLeft; //Time left in current burst window (typically 20s-22s) - public float BurstWindowIn; //Time until next burst window (typically 20s-22s) + private Enemy? BestDOTTargets; + private Enemy? BestDOTTarget; #endregion public override void Execution(StrategyValues strategy, Enemy? primaryTarget) @@ -170,17 +120,14 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) var gauge = World.Client.GetGauge(); //Retrieve Scholar gauge Aetherflow.Stacks = gauge.Aetherflow; //Current Aetherflow stacks Aetherflow.IsActive = Aetherflow.Stacks > 0; //Checks if Aetherflow is available - bioLeft = StatusDetails(primaryTarget?.Actor, BestDOT, Player.InstanceID).Left; - stratagemLeft = StatusDetails(primaryTarget?.Actor, SID.ChainStratagem, Player.InstanceID).Left; + bioLeft = StatusDetails(BestDOTTargets?.Actor, BestDOT, Player.InstanceID).Left; + stratagemLeft = StatusDetails(BestDOTTargets, SID.ChainStratagem, Player.InstanceID).Left; canCS = ActionReady(AID.ChainStratagem); //Chain Stratagem is available canED = Unlocked(AID.EnergyDrain) && Aetherflow.IsActive; //Energy Drain is available canAF = ActionReady(AID.Aetherflow) && !Aetherflow.IsActive; //Aetherflow is available - canWeaveIn = GCD is <= 2.5f and >= 0.1f; //Can weave in oGCDs - canWeaveEarly = GCD is <= 2.5f and >= 1.25f; //Can weave in oGCDs early - canWeaveLate = GCD is <= 1.25f and >= 0.1f; //Can weave in oGCDs late - NextGCD = AID.None; //Next global cooldown action to be used - PotionLeft = PotionStatusLeft(); //Remaining time for potion buff (30s) ShouldUseAOE = ShouldUseAOECircle(5).OnTwoOrMore; //otherwise, use AOE if 2+ targets would be hit + (BestDOTTargets, bioLeft) = GetDOTTarget(strategy, PlayerTarget, BioLeft, 2); + BestDOTTarget = Unlocked(AID.Bio1) ? BestDOTTargets : primaryTarget; #region Strategy Definitions var AOE = strategy.Option(Track.AOE); //AOE track @@ -189,9 +136,9 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) var BioStrategy = Bio.As(); //Bio strategy var potion = strategy.Option(Track.Potion).As(); //Potion strategy var cs = strategy.Option(Track.ChainStratagem); //Chain Stratagem track - var csStrat = cs.As(); //Chain Stratagem strategy + var csStrat = cs.As(); //Chain Stratagem strategy var af = strategy.Option(Track.Aetherflow); //Aetherflow track - var afStrat = af.As(); //Aetherflow strategy + var afStrat = af.As(); //Aetherflow strategy var ed = strategy.Option(Track.EnergyDrain); //Energy Drain track var edStrat = ed.As(); //Energy Drain strategy #endregion @@ -216,7 +163,7 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) if (AOEStrategy is AOEStrategy.ArtOfWar) QueueGCD(BestAOE, Player, GCDPriority.ForcedGCD); if (ShouldUseBio(primaryTarget?.Actor, BioStrategy)) - QueueGCD(BestBio, TargetChoice(Bio) ?? primaryTarget?.Actor, GCDPriority.DOT); + QueueGCD(BestBio, TargetChoice(Bio) ?? BestDOTTarget?.Actor, GCDPriority.DOT); #endregion #region Cooldowns @@ -225,18 +172,18 @@ public override void Execution(StrategyValues strategy, Enemy? primaryTarget) if (ShouldUseChainStratagem(primaryTarget?.Actor, csStrat)) QueueOGCD(AID.ChainStratagem, TargetChoice(cs) ?? primaryTarget?.Actor, - csStrat is OffensiveStrategy.Force or OffensiveStrategy.AnyWeave or OffensiveStrategy.EarlyWeave or OffensiveStrategy.LateWeave + csStrat is OGCDStrategy.Force or OGCDStrategy.AnyWeave or OGCDStrategy.EarlyWeave or OGCDStrategy.LateWeave ? OGCDPriority.ForcedOGCD : OGCDPriority.ChainStratagem); if (ShouldUseAetherflow(primaryTarget?.Actor, afStrat)) QueueOGCD(AID.Aetherflow, Player, - afStrat is OffensiveStrategy.Force or OffensiveStrategy.AnyWeave or OffensiveStrategy.EarlyWeave or OffensiveStrategy.LateWeave + afStrat is OGCDStrategy.Force or OGCDStrategy.AnyWeave or OGCDStrategy.EarlyWeave or OGCDStrategy.LateWeave ? OGCDPriority.ForcedOGCD : OGCDPriority.Aetherflow); if (ShouldUseEnergyDrain(primaryTarget?.Actor, edStrat)) QueueOGCD(AID.EnergyDrain, TargetChoice(ed) ?? primaryTarget?.Actor, edStrat is EnergyStrategy.Force ? OGCDPriority.ForcedOGCD : OGCDPriority.EnergyDrain); - if (Player.HPMP.CurMP <= 9000 && canWeaveIn && ActionReady(AID.LucidDreaming)) + if (Player.HPMP.CurMP <= 9000 && CanWeaveIn && ActionReady(AID.LucidDreaming)) QueueOGCD(AID.LucidDreaming, Player, OGCDPriority.EnergyDrain); if (potion is PotionStrategy.AlignWithRaidBuffs && TotalCD(AID.ChainStratagem) < 5 || potion is PotionStrategy.Immediate) @@ -246,11 +193,15 @@ afStrat is OffensiveStrategy.Force or OffensiveStrategy.AnyWeave or OffensiveStr #endregion #region AI - GoalZoneSingle(25); + GoalZoneCombined(strategy, 25, Hints.GoalAOECircle(5), AID.ArtOfWar1, Unlocked(AID.Broil1) ? 2 : 1); #endregion } #region Cooldown Helpers + + #region DOT + private static SID[] GetDotStatus() => [SID.Bio1, SID.Bio2, SID.Biolysis]; + private float BioLeft(Actor? target) => target == null ? float.MaxValue : GetDotStatus().Select(stat => StatusDetails(target, (uint)stat, Player.InstanceID).Left).FirstOrDefault(dur => dur > 0); private bool ShouldUseBio(Actor? target, BioStrategy strategy) => strategy switch { BioStrategy.Bio3 => Player.InCombat && target != null && bioLeft <= 3 && In25y(target), @@ -261,31 +212,33 @@ afStrat is OffensiveStrategy.Force or OffensiveStrategy.AnyWeave or OffensiveStr BioStrategy.Delay => false, _ => false }; - private bool ShouldUseChainStratagem(Actor? target, OffensiveStrategy strategy) => strategy switch + #endregion + + private bool ShouldUseChainStratagem(Actor? target, OGCDStrategy strategy) => strategy switch { - OffensiveStrategy.Automatic => Player.InCombat && target != null && canCS && canWeaveIn && stratagemLeft == 0 && In25y(target), - OffensiveStrategy.Force => canCS, - OffensiveStrategy.AnyWeave => canCS && canWeaveIn, - OffensiveStrategy.EarlyWeave => canCS && canWeaveEarly, - OffensiveStrategy.LateWeave => canCS && canWeaveLate, - OffensiveStrategy.Delay => false, + OGCDStrategy.Automatic => Player.InCombat && target != null && canCS && CanWeaveIn && stratagemLeft == 0 && In25y(target), + OGCDStrategy.Force => canCS, + OGCDStrategy.AnyWeave => canCS && CanWeaveIn, + OGCDStrategy.EarlyWeave => canCS && CanEarlyWeaveIn, + OGCDStrategy.LateWeave => canCS && CanLateWeaveIn, + OGCDStrategy.Delay => false, _ => false }; - private bool ShouldUseAetherflow(Actor? target, OffensiveStrategy strategy) => strategy switch + private bool ShouldUseAetherflow(Actor? target, OGCDStrategy strategy) => strategy switch { - OffensiveStrategy.Automatic => Player.InCombat && target != null && canAF && canWeaveIn, - OffensiveStrategy.Force => canAF, - OffensiveStrategy.AnyWeave => canAF && canWeaveIn, - OffensiveStrategy.EarlyWeave => canAF && canWeaveEarly, - OffensiveStrategy.LateWeave => canAF && canWeaveLate, - OffensiveStrategy.Delay => false, + OGCDStrategy.Automatic => Player.InCombat && target != null && canAF && CanWeaveIn, + OGCDStrategy.Force => canAF, + OGCDStrategy.AnyWeave => canAF && CanWeaveIn, + OGCDStrategy.EarlyWeave => canAF && CanEarlyWeaveIn, + OGCDStrategy.LateWeave => canAF && CanLateWeaveIn, + OGCDStrategy.Delay => false, _ => false }; private bool ShouldUseEnergyDrain(Actor? target, EnergyStrategy strategy) => strategy switch { - EnergyStrategy.Use3 => canED && In25y(target) && canWeaveIn, - EnergyStrategy.Use2 => canED && Aetherflow.Stacks > 1 && In25y(target) && canWeaveIn, - EnergyStrategy.Use1 => canED && Aetherflow.Stacks > 2 && In25y(target) && canWeaveIn, + EnergyStrategy.Use3 => canED && In25y(target) && CanWeaveIn, + EnergyStrategy.Use2 => canED && Aetherflow.Stacks > 1 && In25y(target) && CanWeaveIn, + EnergyStrategy.Use1 => canED && Aetherflow.Stacks > 2 && In25y(target) && CanWeaveIn, EnergyStrategy.Force => canED, EnergyStrategy.Delay => false, _ => false