diff --git a/BossMod/Autorotation/Utility/ClassASTUtility.cs b/BossMod/Autorotation/Utility/ClassASTUtility.cs index a247e2f96c..b34badf2c7 100644 --- a/BossMod/Autorotation/Utility/ClassASTUtility.cs +++ b/BossMod/Autorotation/Utility/ClassASTUtility.cs @@ -7,7 +7,6 @@ public enum StarOption { None, Use, End } public enum HoroscopeOption { None, Use, End } public enum MacrocosmosOption { None, Use, End } public enum HeliosOption { None, Use, UseEx } - public Actor? TargetChoice(StrategyValues.OptionRef strategy) => ResolveTargetOverride(strategy.Value); public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(AST.AID.AstralStasis); @@ -60,19 +59,20 @@ public static RotationModuleDefinition Definition() return res; } + // TODO: revise, this should be much simpler public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving) { ExecuteShared(strategy, IDLimitBreak3, primaryTarget); ExecuteSimple(strategy.Option(Track.Lightspeed), AST.AID.Lightspeed, Player); - ExecuteSimple(strategy.Option(Track.BeneficII), AST.AID.BeneficII, TargetChoice(strategy.Option(Track.BeneficII)) ?? Player, 1.5f); // TODO[cast-time]: adjustment (swiftcast etc) - ExecuteSimple(strategy.Option(Track.EssentialDignity), AST.AID.EssentialDignity, TargetChoice(strategy.Option(Track.EssentialDignity)) ?? Player); - ExecuteSimple(strategy.Option(Track.AspectedBenefic), AST.AID.AspectedBenefic, TargetChoice(strategy.Option(Track.AspectedBenefic)) ?? Player); - ExecuteSimple(strategy.Option(Track.Synastry), AST.AID.Synastry, TargetChoice(strategy.Option(Track.Synastry)) ?? Player); + ExecuteSimple(strategy.Option(Track.BeneficII), AST.AID.BeneficII, Player, 1.5f); // TODO[cast-time]: adjustment (swiftcast etc) + ExecuteSimple(strategy.Option(Track.EssentialDignity), AST.AID.EssentialDignity, Player); + ExecuteSimple(strategy.Option(Track.AspectedBenefic), AST.AID.AspectedBenefic, Player); + ExecuteSimple(strategy.Option(Track.Synastry), AST.AID.Synastry, Player); ExecuteSimple(strategy.Option(Track.CollectiveUnconscious), AST.AID.CollectiveUnconscious, Player); ExecuteSimple(strategy.Option(Track.CelestialOpposition), AST.AID.CelestialOpposition, Player); ExecuteSimple(strategy.Option(Track.CelestialIntersection), AST.AID.CelestialIntersection, Player); ExecuteSimple(strategy.Option(Track.NeutralSect), AST.AID.NeutralSect, Player); - ExecuteSimple(strategy.Option(Track.Exaltation), AST.AID.Exaltation, TargetChoice(strategy.Option(Track.Exaltation)) ?? Player); + ExecuteSimple(strategy.Option(Track.Exaltation), AST.AID.Exaltation, Player); ExecuteSimple(strategy.Option(Track.SunSign), AST.AID.SunSign, Player); var star = strategy.Option(Track.EarthlyStar); @@ -83,7 +83,7 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, _ => default }; if (starAction != default) - QueueOGCD(starAction, TargetChoice(star) ?? primaryTarget ?? Player); + QueueOGCD(starAction, ResolveTargetOverride(star.Value) ?? primaryTarget ?? Player); //Aspected Helios full execution var heliosUp = StatusDetails(Player, AST.SID.AspectedHelios, Player.InstanceID).Left > 0.1f || StatusDetails(Player, AST.SID.HeliosConjunction, Player.InstanceID).Left > 0.1f; diff --git a/BossMod/Autorotation/Utility/ClassBRDUtility.cs b/BossMod/Autorotation/Utility/ClassBRDUtility.cs index 7624292de6..c72e7a29a3 100644 --- a/BossMod/Autorotation/Utility/ClassBRDUtility.cs +++ b/BossMod/Autorotation/Utility/ClassBRDUtility.cs @@ -3,11 +3,10 @@ public sealed class ClassBRDUtility(RotationModuleManager manager, Actor player) : RoleRangedUtility(manager, player) { public enum Track { WardensPaean = SharedTrack.Count, Troubadour, NaturesMinne } + public enum TroubOption { None, Use87, Use87IfNotActive, Use88, Use88IfNotActive } public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(BRD.AID.SagittariusArrow); - public enum TroubOption { None, Use87, Use87IfNotActive, Use88, Use88IfNotActive } - public static RotationModuleDefinition Definition() { var res = new RotationModuleDefinition("Utility: BRD", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "veyn", RotationModuleQuality.Excellent, BitMask.Build((int)Class.BRD), 100); @@ -34,14 +33,16 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, ExecuteSimple(strategy.Option(Track.WardensPaean), BRD.AID.WardensPaean, ResolveTargetOverride(strategy.Option(Track.WardensPaean).Value) ?? primaryTarget ?? Player); ExecuteSimple(strategy.Option(Track.NaturesMinne), BRD.AID.NaturesMinne, Player); + // TODO: for 'if-not-active' strategy, add configurable min-time-left + // TODO: combine 87/88 options var troub = strategy.Option(Track.Troubadour); - var hasDefensive = Player.FindStatus(BRD.SID.Troubadour) != null || Player.FindStatus(MCH.SID.Tactician) != null || Player.FindStatus(DNC.SID.ShieldSamba) != null; - if (troub.As() != TroubOption.None) + var wantTroub = troub.As() switch { - if (troub.As() is TroubOption.Use87 or TroubOption.Use88) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.Troubadour), Player, troub.Priority(), troub.Value.ExpireIn); - if (troub.As() is TroubOption.Use87IfNotActive or TroubOption.Use88IfNotActive && !hasDefensive) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.Troubadour), Player, troub.Priority(), troub.Value.ExpireIn); - } + TroubOption.Use87 or TroubOption.Use88 => true, + TroubOption.Use87IfNotActive or TroubOption.Use88IfNotActive => Player.FindStatus(BRD.SID.Troubadour) == null && Player.FindStatus(MCH.SID.Tactician) == null && Player.FindStatus(DNC.SID.ShieldSamba) == null, + _ => false + }; + if (wantTroub) + Hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.Troubadour), Player, troub.Priority(), troub.Value.ExpireIn); } } diff --git a/BossMod/Autorotation/Utility/ClassDNCUtility.cs b/BossMod/Autorotation/Utility/ClassDNCUtility.cs index 678ab2ca3b..f86c89668d 100644 --- a/BossMod/Autorotation/Utility/ClassDNCUtility.cs +++ b/BossMod/Autorotation/Utility/ClassDNCUtility.cs @@ -3,7 +3,6 @@ public sealed class ClassDNCUtility(RotationModuleManager manager, Actor player) : RoleRangedUtility(manager, player) { public enum Track { CuringWaltz = SharedTrack.Count, ShieldSamba, Improvisation } - public enum SambaOption { None, Use87, Use87IfNotActive, Use88, Use88IfNotActive } public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(DNC.AID.CrimsonLotus); @@ -34,14 +33,16 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, ExecuteSimple(strategy.Option(Track.CuringWaltz), DNC.AID.CuringWaltz, Player); ExecuteSimple(strategy.Option(Track.Improvisation), DNC.AID.Improvisation, Player); + // TODO: for 'if-not-active' strategy, add configurable min-time-left + // TODO: combine 87/88 options var samba = strategy.Option(Track.ShieldSamba); - var hasDefensive = Player.FindStatus(BRD.SID.Troubadour) != null || Player.FindStatus(MCH.SID.Tactician) != null || Player.FindStatus(DNC.SID.ShieldSamba) != null; - if (samba.As() != SambaOption.None) + var wantSamba = samba.As() switch { - if (samba.As() is SambaOption.Use87 or SambaOption.Use88) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(DNC.AID.ShieldSamba), Player, samba.Priority(), samba.Value.ExpireIn); - if (samba.As() is SambaOption.Use87IfNotActive or SambaOption.Use88IfNotActive && !hasDefensive) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(DNC.AID.ShieldSamba), Player, samba.Priority(), samba.Value.ExpireIn); - } + SambaOption.Use87 or SambaOption.Use88 => true, + SambaOption.Use87IfNotActive or SambaOption.Use88IfNotActive => Player.FindStatus(BRD.SID.Troubadour) == null && Player.FindStatus(MCH.SID.Tactician) == null && Player.FindStatus(DNC.SID.ShieldSamba) == null, + _ => false + }; + if (wantSamba) + Hints.ActionsToExecute.Push(ActionID.MakeSpell(DNC.AID.ShieldSamba), Player, samba.Priority(), samba.Value.ExpireIn); } } diff --git a/BossMod/Autorotation/Utility/ClassMCHUtility.cs b/BossMod/Autorotation/Utility/ClassMCHUtility.cs index 60c3d8dbad..7dabd577d5 100644 --- a/BossMod/Autorotation/Utility/ClassMCHUtility.cs +++ b/BossMod/Autorotation/Utility/ClassMCHUtility.cs @@ -2,15 +2,11 @@ public sealed class ClassMCHUtility(RotationModuleManager manager, Actor player) : RoleRangedUtility(manager, player) { - // Add all MCH tracks to end of list, starting with Tactician - // SharedTrack.Count here is the "end" of the track list, so we set the first track we want as the "end" public enum Track { Tactician = SharedTrack.Count, Dismantle } + public enum TactOption { None, Use87, Use87IfNotActive, Use88, Use88IfNotActive } - // Add Machinist LB3 public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(MCH.AID.SatelliteBeam); - public enum TactOption { None, Use87, Use87IfNotActive, Use88, Use88IfNotActive } - public static RotationModuleDefinition Definition() { var res = new RotationModuleDefinition("Utility: MCH", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Aimsucks", RotationModuleQuality.Excellent, BitMask.Build((int)Class.MCH), 100); @@ -34,14 +30,16 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, ExecuteShared(strategy, IDLimitBreak3, primaryTarget); ExecuteSimple(strategy.Option(Track.Dismantle), MCH.AID.Dismantle, ResolveTargetOverride(strategy.Option(Track.Dismantle).Value) ?? primaryTarget); + // TODO: for 'if-not-active' strategy, add configurable min-time-left + // TODO: combine 87/88 options var tact = strategy.Option(Track.Tactician); - var hasDefensive = Player.FindStatus(BRD.SID.Troubadour) != null || Player.FindStatus(MCH.SID.Tactician) != null || Player.FindStatus(DNC.SID.ShieldSamba) != null; - if (tact.As() != TactOption.None) + var wantTact = tact.As() switch { - if (tact.As() is TactOption.Use87 or TactOption.Use88) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(MCH.AID.Tactician), Player, tact.Priority(), tact.Value.ExpireIn); - if (tact.As() is TactOption.Use87IfNotActive or TactOption.Use88IfNotActive && !hasDefensive) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(MCH.AID.Tactician), Player, tact.Priority(), tact.Value.ExpireIn); - } + TactOption.Use87 or TactOption.Use88 => true, + TactOption.Use87IfNotActive or TactOption.Use88IfNotActive => Player.FindStatus(BRD.SID.Troubadour) == null && Player.FindStatus(MCH.SID.Tactician) == null && Player.FindStatus(DNC.SID.ShieldSamba) == null, + _ => false + }; + if (wantTact) + Hints.ActionsToExecute.Push(ActionID.MakeSpell(MCH.AID.Tactician), Player, tact.Priority(), tact.Value.ExpireIn); } } diff --git a/BossMod/Autorotation/Utility/ClassMNKUtility.cs b/BossMod/Autorotation/Utility/ClassMNKUtility.cs index 5f31df827f..9ff3356308 100644 --- a/BossMod/Autorotation/Utility/ClassMNKUtility.cs +++ b/BossMod/Autorotation/Utility/ClassMNKUtility.cs @@ -4,8 +4,6 @@ public sealed class ClassMNKUtility(RotationModuleManager manager, Actor player) { public enum Track { Mantra = SharedTrack.Count, RiddleOfEarth, Thunderclap } public enum DashStrategy { None, GapClose, GapCloseHold1, GapCloseHold2 } - public float CDleft => World.Client.Cooldowns[ActionDefinitions.GCDGroup].Remaining; - public bool InMeleeRange(Actor? target) => Player.DistanceToHitbox(target) <= 3; //Checks if we're inside melee range public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(MNK.AID.FinalHeaven); diff --git a/BossMod/Autorotation/Utility/ClassNINUtility.cs b/BossMod/Autorotation/Utility/ClassNINUtility.cs index e84c98241b..997d705905 100644 --- a/BossMod/Autorotation/Utility/ClassNINUtility.cs +++ b/BossMod/Autorotation/Utility/ClassNINUtility.cs @@ -28,6 +28,7 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, ExecuteShared(strategy, IDLimitBreak3, primaryTarget); ExecuteSimple(strategy.Option(Track.ShadeShift), NIN.AID.ShadeShift, Player); + // TODO: revise, this doesn't look correct (shukuchi is area targeted, so it should use that; probably should expose options to use regardless of melee distance...) var dash = strategy.Option(Track.Shukuchi); var dashStrategy = strategy.Option(Track.Shukuchi).As(); var dashTarget = ResolveTargetOverride(dash.Value) ?? primaryTarget; //Smart-Targeting @@ -37,70 +38,10 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, { DashStrategy.None => false, DashStrategy.GapClose => distance is > 3f and <= 20f, - DashStrategy.GapCloseHold1 => distance is > 3f and <= 20f && cd <= 60.5f, + DashStrategy.GapCloseHold1 => distance is > 3f and <= 20f && cd <= 60.5f, // TODO: this condition doesn't look correct... _ => false, }; - if (shouldDash) - QueueOGCD(NIN.AID.Shukuchi, dashTarget, 3000); + if (shouldDash && dashTarget != null) + Hints.ActionsToExecute.Push(ActionID.MakeSpell(NIN.AID.Shukuchi), null, dash.Priority(), dash.Value.ExpireIn, 0, 0, dashTarget.PosRot.XYZ()); } - - #region Core Execution Helpers - - public NIN.AID NextGCD; //Next global cooldown action to be used - public void QueueGCD

(NIN.AID aid, Actor? target, P priority, float delay = 0) where P : Enum - => QueueGCD(aid, target, (int)(object)priority, delay); - - public void QueueGCD(NIN.AID aid, Actor? target, int priority = 8, float delay = 0) - { - var NextGCDPrio = 0; - - if (priority == 0) - return; - - if (QueueAction(aid, target, ActionQueue.Priority.High, delay) && priority > NextGCDPrio) - { - NextGCD = aid; - } - } - - public void QueueOGCD

(NIN.AID aid, Actor? target, P priority, float delay = 0) where P : Enum - => QueueOGCD(aid, target, (int)(object)priority, delay); - - public void QueueOGCD(NIN.AID aid, Actor? target, int priority = 4, float delay = 0) - { - if (priority == 0) - return; - - QueueAction(aid, target, ActionQueue.Priority.Medium + priority, delay); - } - - public bool QueueAction(NIN.AID aid, Actor? target, float priority, float delay) - { - if ((uint)(object)aid == 0) - return false; - - var def = ActionDefinitions.Instance.Spell(aid); - if (def == null) - return false; - - if (def.Range != 0 && target == null) - { - return false; - } - - Vector3 targetPos = default; - - if (def.AllowedTargets.HasFlag(ActionTargets.Area)) - { - if (def.Range == 0) - targetPos = Player.PosRot.XYZ(); - else if (target != null) - targetPos = target.PosRot.XYZ(); - } - - Hints.ActionsToExecute.Push(ActionID.MakeSpell(aid), target, priority, delay: delay, targetPos: targetPos); - return true; - } - #endregion - } diff --git a/BossMod/Autorotation/Utility/ClassPCTUtility.cs b/BossMod/Autorotation/Utility/ClassPCTUtility.cs index 4010312c79..1fe5d225d2 100644 --- a/BossMod/Autorotation/Utility/ClassPCTUtility.cs +++ b/BossMod/Autorotation/Utility/ClassPCTUtility.cs @@ -26,14 +26,14 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, { ExecuteShared(strategy, IDLimitBreak3, primaryTarget); - var canCoat = ActionUnlocked(ActionID.MakeSpell(PCT.AID.TemperaCoat)) && World.Client.Cooldowns[ActionDefinitions.Instance.Spell(PCT.AID.TemperaCoat)!.MainCooldownGroup].Remaining < 0.6f; - var hasCoat = StatusDetails(Player, PCT.SID.TemperaCoat, Player.InstanceID).Left > 0.1f; - var canGrassa = ActionUnlocked(ActionID.MakeSpell(PCT.AID.TemperaGrassa)) && hasCoat; - var hasGrassa = StatusDetails(Player, PCT.SID.TemperaGrassa, Player.InstanceID).Left > 0.1f; var tempera = strategy.Option(Track.TemperaCoat); var temperaStrat = tempera.As(); if (temperaStrat != TemperaCoatOption.None) { + var canCoat = ActionUnlocked(ActionID.MakeSpell(PCT.AID.TemperaCoat)) && World.Client.Cooldowns[ActionDefinitions.Instance.Spell(PCT.AID.TemperaCoat)!.MainCooldownGroup].Remaining < 0.6f; + var hasCoat = StatusDetails(Player, PCT.SID.TemperaCoat, Player.InstanceID).Left > 0.1f; + var canGrassa = ActionUnlocked(ActionID.MakeSpell(PCT.AID.TemperaGrassa)) && hasCoat; + var hasGrassa = StatusDetails(Player, PCT.SID.TemperaGrassa, Player.InstanceID).Left > 0.1f; if (temperaStrat == TemperaCoatOption.CoatOnly) { if (canCoat && (!hasCoat || !hasGrassa)) @@ -42,9 +42,9 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, if (temperaStrat == TemperaCoatOption.CoatGrassaASAP) { if (canCoat && !hasCoat) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(PCT.AID.TemperaCoat), Player, tempera.Priority() + 2000, tempera.Value.ExpireIn); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(PCT.AID.TemperaCoat), Player, tempera.Priority() + 2000, tempera.Value.ExpireIn); // TODO: revise, this is bad, utility modules should not arbitrarily adjust priorities if (canGrassa && !hasGrassa) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(PCT.AID.TemperaGrassa), Player, tempera.Priority() + 2000, tempera.Value.ExpireIn); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(PCT.AID.TemperaGrassa), Player, tempera.Priority() + 2000, tempera.Value.ExpireIn); // TODO: revise, this is bad, utility modules should not arbitrarily adjust priorities } if (temperaStrat == TemperaCoatOption.CoatGrassaWhenever) { diff --git a/BossMod/Autorotation/Utility/ClassPLDUtility.cs b/BossMod/Autorotation/Utility/ClassPLDUtility.cs index 8afa1ad0a6..624bcc528b 100644 --- a/BossMod/Autorotation/Utility/ClassPLDUtility.cs +++ b/BossMod/Autorotation/Utility/ClassPLDUtility.cs @@ -41,7 +41,7 @@ public static RotationModuleDefinition Definition() public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving) { ExecuteShared(strategy, IDLimitBreak3, IDStanceApply, IDStanceRemove, (uint)PLD.SID.IronWill, primaryTarget); - ExecuteSimple(strategy.Option(Track.Cover), PLD.AID.Cover, ResolveTargetOverride(strategy.Option(Track.Cover).Value) ?? primaryTarget ?? Player); //Cover execution + ExecuteSimple(strategy.Option(Track.Cover), PLD.AID.Cover, primaryTarget ?? Player); //Cover execution ExecuteSimple(strategy.Option(Track.Bulwark), PLD.AID.Bulwark, Player); //Bulwark execution ExecuteSimple(strategy.Option(Track.DivineVeil), PLD.AID.DivineVeil, Player); //DivineVeil execution ExecuteSimple(strategy.Option(Track.PassageOfArms), PLD.AID.PassageOfArms, Player); //PassageOfArms execution diff --git a/BossMod/Autorotation/Utility/ClassSCHUtility.cs b/BossMod/Autorotation/Utility/ClassSCHUtility.cs index 7fa63d3ff3..2d7bbe67cb 100644 --- a/BossMod/Autorotation/Utility/ClassSCHUtility.cs +++ b/BossMod/Autorotation/Utility/ClassSCHUtility.cs @@ -9,7 +9,6 @@ public enum DeployOption { None, Use, UseEx } public enum AetherpactOption { None, Use, End } public enum RecitationOption { None, Use, UseEx } public enum PetOption { None, Eos, Seraph } - public Actor? TargetChoice(StrategyValues.OptionRef strategy) => ResolveTargetOverride(strategy.Value); public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(SCH.AID.AngelFeathers); @@ -76,19 +75,20 @@ public static RotationModuleDefinition Definition() return res; } + // TODO: revise, this should be much simpler public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving) { ExecuteShared(strategy, IDLimitBreak3, primaryTarget); ExecuteSimple(strategy.Option(Track.WhisperingDawn), SCH.AID.WhisperingDawn, Player); - ExecuteSimple(strategy.Option(Track.Adloquium), SCH.AID.Adloquium, TargetChoice(strategy.Option(Track.Adloquium)) ?? Player, 2); // TODO[cast-time]: adjustment (swiftcast etc) + ExecuteSimple(strategy.Option(Track.Adloquium), SCH.AID.Adloquium, Player, 2); // TODO[cast-time]: adjustment (swiftcast etc) ExecuteSimple(strategy.Option(Track.FeyIllumination), SCH.AID.FeyIllumination, Player); ExecuteSimple(strategy.Option(Track.Indomitability), SCH.AID.Indomitability, Player); ExecuteSimple(strategy.Option(Track.EmergencyTactics), SCH.AID.EmergencyTactics, Player); ExecuteSimple(strategy.Option(Track.Dissipation), SCH.AID.Dissipation, primaryTarget); - ExecuteSimple(strategy.Option(Track.Excogitation), SCH.AID.Excogitation, TargetChoice(strategy.Option(Track.Excogitation)) ?? Player); + ExecuteSimple(strategy.Option(Track.Excogitation), SCH.AID.Excogitation, Player); ExecuteSimple(strategy.Option(Track.FeyBlessing), SCH.AID.FeyBlessing, Player); ExecuteSimple(strategy.Option(Track.Consolation), SCH.AID.Consolation, Player); - ExecuteSimple(strategy.Option(Track.Protraction), SCH.AID.Protraction, TargetChoice(strategy.Option(Track.Protraction)) ?? Player); + ExecuteSimple(strategy.Option(Track.Protraction), SCH.AID.Protraction, Player); ExecuteSimple(strategy.Option(Track.Expedient), SCH.AID.Expedient, Player); ExecuteSimple(strategy.Option(Track.Seraphism), SCH.AID.Seraphism, Player); @@ -110,7 +110,7 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, _ => default }; if (soilAction != default) - QueueOGCD(soilAction, TargetChoice(soil) ?? primaryTarget ?? Player); + QueueOGCD(soilAction, ResolveTargetOverride(soil.Value) ?? primaryTarget ?? Player); var deploy = strategy.Option(Track.DeploymentTactics); if (deploy.As() != DeployOption.None) @@ -119,7 +119,7 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, var pact = strategy.Option(Track.Aetherpact); var pactStrat = pact.As(); - var pactTarget = TargetChoice(strategy.Option(Track.Aetherpact)) ?? primaryTarget ?? Player; + var pactTarget = ResolveTargetOverride(pact.Value) ?? primaryTarget ?? Player; var juicing = pactTarget.FindStatus(SCH.SID.FeyUnion) != null; if (pactStrat != AetherpactOption.None) { @@ -145,24 +145,6 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, } #region Core Execution Helpers - - public SCH.AID NextGCD; //Next global cooldown action to be used - public void QueueGCD

(SCH.AID aid, Actor? target, P priority, float delay = 0) where P : Enum - => QueueGCD(aid, target, (int)(object)priority, delay); - - public void QueueGCD(SCH.AID aid, Actor? target, int priority = 8, float delay = 0) - { - var NextGCDPrio = 0; - - if (priority == 0) - return; - - if (QueueAction(aid, target, ActionQueue.Priority.High, delay) && priority > NextGCDPrio) - { - NextGCD = aid; - } - } - public void QueueOGCD

(SCH.AID aid, Actor? target, P priority, float delay = 0) where P : Enum => QueueOGCD(aid, target, (int)(object)priority, delay); @@ -202,5 +184,4 @@ public bool QueueAction(SCH.AID aid, Actor? target, float priority, float delay) return true; } #endregion - } diff --git a/BossMod/Autorotation/Utility/ClassSGEUtility.cs b/BossMod/Autorotation/Utility/ClassSGEUtility.cs index a65dd8198c..15600e418e 100644 --- a/BossMod/Autorotation/Utility/ClassSGEUtility.cs +++ b/BossMod/Autorotation/Utility/ClassSGEUtility.cs @@ -9,7 +9,6 @@ public enum PrognosisOption { None, Use, UseEP, UseEPEx } public enum PhysisOption { None, Use, UseEx } public enum ZoeOption { None, Use, UseEx } public enum DashStrategy { None, GapClose } - public Actor? TargetChoice(StrategyValues.OptionRef strategy) => ResolveTargetOverride(strategy.Value); public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(SGE.AID.TechneMakre); @@ -77,12 +76,12 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, { ExecuteShared(strategy, IDLimitBreak3, primaryTarget); ExecuteSimple(strategy.Option(Track.Eukrasia), SGE.AID.Eukrasia, Player); - ExecuteSimple(strategy.Option(Track.Druochole), SGE.AID.Druochole, TargetChoice(strategy.Option(Track.Druochole)) ?? primaryTarget ?? Player); + ExecuteSimple(strategy.Option(Track.Druochole), SGE.AID.Druochole, primaryTarget ?? Player); ExecuteSimple(strategy.Option(Track.Kerachole), SGE.AID.Kerachole, Player); ExecuteSimple(strategy.Option(Track.Ixochole), SGE.AID.Ixochole, Player); ExecuteSimple(strategy.Option(Track.Pepsis), SGE.AID.Pepsis, Player); - ExecuteSimple(strategy.Option(Track.Taurochole), SGE.AID.Taurochole, TargetChoice(strategy.Option(Track.Taurochole)) ?? primaryTarget ?? Player); - ExecuteSimple(strategy.Option(Track.Haima), SGE.AID.Haima, TargetChoice(strategy.Option(Track.Haima)) ?? primaryTarget ?? Player); + ExecuteSimple(strategy.Option(Track.Taurochole), SGE.AID.Taurochole, primaryTarget ?? Player); + ExecuteSimple(strategy.Option(Track.Haima), SGE.AID.Haima, primaryTarget ?? Player); ExecuteSimple(strategy.Option(Track.Rhizomata), SGE.AID.Rhizomata, Player); ExecuteSimple(strategy.Option(Track.Holos), SGE.AID.Holos, Player); ExecuteSimple(strategy.Option(Track.Panhaima), SGE.AID.Panhaima, Player); @@ -91,16 +90,16 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, if (World.Client.Cooldowns[ActionDefinitions.Instance.Spell(SGE.AID.Pneuma)!.MainCooldownGroup].Remaining < 0.6f) { - ExecuteSimple(strategy.Option(Track.Pneuma), SGE.AID.Pneuma, TargetChoice(strategy.Option(Track.Pneuma)) ?? primaryTarget); + ExecuteSimple(strategy.Option(Track.Pneuma), SGE.AID.Pneuma, primaryTarget); } //Kardia full execution var kardia = strategy.Option(Track.Kardia); var kardiaStrat = kardia.As(); - var kardiaTarget = TargetChoice(kardia) ?? primaryTarget ?? Player; - var hasKardia = kardiaTarget.FindStatus(SGE.SID.Kardia) != null; if (kardiaStrat != KardiaOption.None) { + var kardiaTarget = ResolveTargetOverride(kardia.Value) ?? primaryTarget ?? Player; + var hasKardia = kardiaTarget.FindStatus(SGE.SID.Kardia) != null; if (kardiaStrat == KardiaOption.Kardia && !hasKardia) Hints.ActionsToExecute.Push(ActionID.MakeSpell(SGE.AID.Kardia), kardiaTarget, kardia.Priority(), kardia.Value.ExpireIn); if (kardiaStrat == KardiaOption.Soteria) @@ -111,7 +110,6 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, var hasEukrasia = Player.FindStatus(SGE.SID.Eukrasia) != null; var ed = strategy.Option(Track.Diagnosis); var edStrat = ed.As(); - var edTarget = TargetChoice(ed) ?? primaryTarget ?? Player; if (edStrat != DiagnosisOption.None) { if (edStrat == DiagnosisOption.Use) @@ -123,7 +121,7 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, if (!hasEukrasia) Hints.ActionsToExecute.Push(ActionID.MakeSpell(SGE.AID.Eukrasia), Player, ed.Priority(), ed.Value.ExpireIn); if (hasEukrasia) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(SGE.AID.EukrasianDiagnosis), edTarget, ed.Priority(), ed.Value.ExpireIn); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(SGE.AID.EukrasianDiagnosis), ResolveTargetOverride(ed.Value) ?? primaryTarget ?? Player, ed.Priority(), ed.Value.ExpireIn); } } @@ -131,7 +129,6 @@ public override void Execute(StrategyValues strategy, ref Actor? primaryTarget, var shieldUp = StatusDetails(Player, SCH.SID.Galvanize, Player.InstanceID).Left > 0.1f || StatusDetails(Player, SGE.SID.EukrasianPrognosis, Player.InstanceID).Left > 0.1f; var ep = strategy.Option(Track.Prognosis); var epStrat = ep.As(); - if (epStrat != PrognosisOption.None) { if (epStrat == PrognosisOption.Use) diff --git a/BossMod/Autorotation/Utility/GenericUtility.cs b/BossMod/Autorotation/Utility/GenericUtility.cs index e5a3058a32..36a922af5f 100644 --- a/BossMod/Autorotation/Utility/GenericUtility.cs +++ b/BossMod/Autorotation/Utility/GenericUtility.cs @@ -32,10 +32,10 @@ protected static RotationModuleDefinition.ConfigRef DefineLimitBreak(in StrategyValues.OptionRef opt, AID aid, Actor? target, float castTime = 0) where AID : Enum + protected void ExecuteSimple(in StrategyValues.OptionRef opt, AID aid, Actor? defaultTarget, float castTime = 0) where AID : Enum { if (opt.As() == SimpleOption.Use) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(aid), ResolveTargetOverride(opt.Value) ?? target, opt.Priority(), opt.Value.ExpireIn, castTime: castTime); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(aid), ResolveTargetOverride(opt.Value) ?? defaultTarget, opt.Priority(), opt.Value.ExpireIn, castTime: castTime); } // returns 0 if not needed, or current LB level diff --git a/BossMod/Autorotation/Utility/RoleCasterUtility.cs b/BossMod/Autorotation/Utility/RoleCasterUtility.cs index 28650d23bf..4b1d7d6ed2 100644 --- a/BossMod/Autorotation/Utility/RoleCasterUtility.cs +++ b/BossMod/Autorotation/Utility/RoleCasterUtility.cs @@ -14,6 +14,8 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3) .AddAssociatedActions(ClassShared.AID.Skyshard, ClassShared.AID.Starstorm) .AddAssociatedAction(lb3); + // TODO: combine standard/ex options + // TODO: add 'if-not-active' strategy with configurable min-time-left def.Define(SharedTrack.Addle).As("Addle", "", 250) .AddOption(AddleOption.None, "None", "Do not use automatically") .AddOption(AddleOption.Use, "Use", "Use Addle (10s)", 90, 10, ActionTargets.Hostile, 22, 97) @@ -23,6 +25,7 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3) DefineSimpleConfig(def, SharedTrack.Sleep, "Sleep", "", -10, ClassShared.AID.Sleep); DefineSimpleConfig(def, SharedTrack.LucidDreaming, "LucidDreaming", "Lucid D.", 30, ClassShared.AID.LucidDreaming, 21); + // TODO: combine standard/ex options def.Define(SharedTrack.Swiftcast).As("Swiftcast", "Swiftcast", 20) .AddOption(SwiftcastOption.None, "None", "Do not use automatically") .AddOption(SwiftcastOption.Use, "Use", "Use Swiftcast (10s)", 60, 10, ActionTargets.Self, 22, 93) diff --git a/BossMod/Autorotation/Utility/RoleHealerUtility.cs b/BossMod/Autorotation/Utility/RoleHealerUtility.cs index 6be7e29676..ec385ceeb6 100644 --- a/BossMod/Autorotation/Utility/RoleHealerUtility.cs +++ b/BossMod/Autorotation/Utility/RoleHealerUtility.cs @@ -17,13 +17,14 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3) DefineSimpleConfig(def, SharedTrack.Esuna, "Esuna", "", 40, ClassShared.AID.Esuna); DefineSimpleConfig(def, SharedTrack.LucidDreaming, "LucidDreaming", "Lucid", 30, ClassShared.AID.LucidDreaming, 21); + // TODO: combine standard/ex options def.Define(SharedTrack.Swiftcast).As("Swiftcast", "Swift", 20) .AddOption(SwiftcastOption.None, "None", "Do not use automatically") .AddOption(SwiftcastOption.Use, "Use", "Use Swiftcast (10s)", 60, 10, ActionTargets.Self, 22, 93) .AddOption(SwiftcastOption.UseEx, "UseEx", "Use Swiftcast (15s)", 40, 10, ActionTargets.Self, 94) .AddAssociatedActions(ClassShared.AID.Swiftcast); - DefineSimpleConfig(def, SharedTrack.Surecast, "Surecast", "Anti-KB", 10, ClassShared.AID.Surecast, 6); // note: secondary effect 15s + DefineSimpleConfig(def, SharedTrack.Surecast, "Surecast", "", 10, ClassShared.AID.Surecast, 6); // note: secondary effect 15s DefineSimpleConfig(def, SharedTrack.Rescue, "Rescue", "", 50, ClassShared.AID.Rescue); } @@ -31,10 +32,10 @@ protected void ExecuteShared(StrategyValues strategy, ActionID lb3, Actor? prima { ExecuteSimple(strategy.Option(SharedTrack.Sprint), ClassShared.AID.Sprint, Player); ExecuteSimple(strategy.Option(SharedTrack.Repose), ClassShared.AID.Repose, primaryTarget, 2.5f); // TODO[cast-time]: adjustment (swiftcast etc) - ExecuteSimple(strategy.Option(SharedTrack.Esuna), ClassShared.AID.Esuna, ResolveTargetOverride(strategy.Option(SharedTrack.Esuna).Value) ?? primaryTarget, 1); // TODO[cast-time]: adjustment (swiftcast etc) + ExecuteSimple(strategy.Option(SharedTrack.Esuna), ClassShared.AID.Esuna, primaryTarget); ExecuteSimple(strategy.Option(SharedTrack.LucidDreaming), ClassShared.AID.LucidDreaming, Player); ExecuteSimple(strategy.Option(SharedTrack.Surecast), ClassShared.AID.Surecast, Player); - ExecuteSimple(strategy.Option(SharedTrack.Rescue), ClassShared.AID.Rescue, ResolveTargetOverride(strategy.Option(SharedTrack.Rescue).Value) ?? primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.Rescue), ClassShared.AID.Rescue, primaryTarget); var lb = strategy.Option(SharedTrack.LB); var lbLevel = LBLevelToExecute(lb.As()); diff --git a/BossMod/Autorotation/Utility/RoleMeleeUtility.cs b/BossMod/Autorotation/Utility/RoleMeleeUtility.cs index 4daddd03b4..522f74ca50 100644 --- a/BossMod/Autorotation/Utility/RoleMeleeUtility.cs +++ b/BossMod/Autorotation/Utility/RoleMeleeUtility.cs @@ -19,6 +19,8 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3) DefineSimpleConfig(def, SharedTrack.LegSweep, "LegSweep", "Stun", -150, ClassShared.AID.LegSweep, 3); DefineSimpleConfig(def, SharedTrack.Bloodbath, "Bloodbath", "", -50, ClassShared.AID.Bloodbath, 20); + // TODO: combine standard/ex options + // TODO: add 'if-not-active' strategy with configurable min-time-left def.Define(SharedTrack.Feint).As("Feint", "", 250) .AddOption(FeintOption.None, "None", "Do not use automatically") .AddOption(FeintOption.Use, "Use", "Use Feint (10s)", 90, 10, ActionTargets.Hostile, 22, 97) diff --git a/BossMod/Autorotation/Utility/RoleRangedUtility.cs b/BossMod/Autorotation/Utility/RoleRangedUtility.cs index 9ce8a0fc81..38d1ea8888 100644 --- a/BossMod/Autorotation/Utility/RoleRangedUtility.cs +++ b/BossMod/Autorotation/Utility/RoleRangedUtility.cs @@ -23,10 +23,10 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3) protected void ExecuteShared(StrategyValues strategy, ActionID lb3, Actor? primaryTarget) { ExecuteSimple(strategy.Option(SharedTrack.Sprint), ClassShared.AID.Sprint, Player); - ExecuteSimple(strategy.Option(SharedTrack.LegGraze), ClassShared.AID.LegGraze, ResolveTargetOverride(strategy.Option(SharedTrack.LegGraze).Value) ?? primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.LegGraze), ClassShared.AID.LegGraze, primaryTarget); ExecuteSimple(strategy.Option(SharedTrack.SecondWind), ClassShared.AID.SecondWind, Player); - ExecuteSimple(strategy.Option(SharedTrack.FootGraze), ClassShared.AID.FootGraze, ResolveTargetOverride(strategy.Option(SharedTrack.FootGraze).Value) ?? primaryTarget); - ExecuteSimple(strategy.Option(SharedTrack.HeadGraze), ClassShared.AID.HeadGraze, ResolveTargetOverride(strategy.Option(SharedTrack.HeadGraze).Value) ?? primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.FootGraze), ClassShared.AID.FootGraze, primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.HeadGraze), ClassShared.AID.HeadGraze, primaryTarget); ExecuteSimple(strategy.Option(SharedTrack.ArmsLength), ClassShared.AID.ArmsLength, Player); var lb = strategy.Option(SharedTrack.LB); diff --git a/BossMod/Autorotation/Utility/RoleTankUtility.cs b/BossMod/Autorotation/Utility/RoleTankUtility.cs index 090859ede0..841902af54 100644 --- a/BossMod/Autorotation/Utility/RoleTankUtility.cs +++ b/BossMod/Autorotation/Utility/RoleTankUtility.cs @@ -20,6 +20,8 @@ protected static void DefineShared(RotationModuleDefinition def, ActionID lb3, A DefineSimpleConfig(def, SharedTrack.Provoke, "Provoke", "", 200, ClassShared.AID.Provoke); DefineSimpleConfig(def, SharedTrack.Interject, "Interject", "Interrupt", -50, ClassShared.AID.Interject); + // TODO: combine standard/ex options + // TODO: add 'if-not-active' strategy with configurable min-time-left def.Define(SharedTrack.Reprisal).As("Reprisal", "", 250) .AddOption(ReprisalOption.None, "None", "Do not use automatically") .AddOption(ReprisalOption.Use, "Use", "Use Reprisal (10s)", 60, 10, ActionTargets.Self, 22, 97) @@ -41,9 +43,9 @@ protected void ExecuteShared(StrategyValues strategy, ActionID lb3, ActionID sta { ExecuteSimple(strategy.Option(SharedTrack.Sprint), ClassShared.AID.Sprint, Player); ExecuteSimple(strategy.Option(SharedTrack.Rampart), ClassShared.AID.Rampart, Player); - ExecuteSimple(strategy.Option(SharedTrack.LowBlow), ClassShared.AID.LowBlow, ResolveTargetOverride(strategy.Option(SharedTrack.LowBlow).Value) ?? primaryTarget); - ExecuteSimple(strategy.Option(SharedTrack.Provoke), ClassShared.AID.Provoke, ResolveTargetOverride(strategy.Option(SharedTrack.Provoke).Value) ?? primaryTarget); - ExecuteSimple(strategy.Option(SharedTrack.Interject), ClassShared.AID.Interject, ResolveTargetOverride(strategy.Option(SharedTrack.Interject).Value) ?? primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.LowBlow), ClassShared.AID.LowBlow, primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.Provoke), ClassShared.AID.Provoke, primaryTarget); + ExecuteSimple(strategy.Option(SharedTrack.Interject), ClassShared.AID.Interject, primaryTarget); ExecuteSimple(strategy.Option(SharedTrack.Shirk), ClassShared.AID.Shirk, CoTank()); ExecuteSimple(strategy.Option(SharedTrack.ArmsLength), ClassShared.AID.ArmsLength, Player); diff --git a/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D011Minduruva.cs b/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D011Minduruva.cs index eea08c780a..19baefd1b7 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D011Minduruva.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D011Minduruva.cs @@ -77,7 +77,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var c in _poisoned) { if (_poisoned.Count > 0 && actor.Role == Role.Healer) - hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High, castTime: 1); + hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High); if (_poisoned.Count > 0 && actor.Class == Class.BRD) hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.WardensPaean), c, ActionQueue.Priority.High); } diff --git a/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D013MagusSisters.cs b/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D013MagusSisters.cs index f9a4856c3f..f9789454ab 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D013MagusSisters.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D01TowerOfZot/D013MagusSisters.cs @@ -123,7 +123,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var c in _poisoned) { if (_poisoned.Count > 0 && actor.Role == Role.Healer) - hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High, castTime: 1); + hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High); if (_poisoned.Count > 0 && actor.Class == Class.BRD) hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.WardensPaean), c, ActionQueue.Priority.High); } diff --git a/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D112GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D112GalateaMagna.cs index ac0c9940f4..b2a5e99a99 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D112GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D112GalateaMagna.cs @@ -240,7 +240,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var c in _doomed) { if (_doomed.Count > 0 && actor.Role == Role.Healer) - hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High, castTime: 1); + hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High); if (_doomed.Count > 0 && actor.Class == Class.BRD) hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.WardensPaean), c, ActionQueue.Priority.High); } diff --git a/BossMod/Modules/Endwalker/Dungeon/D13LunarSubterrane/D131DarkElf.cs b/BossMod/Modules/Endwalker/Dungeon/D13LunarSubterrane/D131DarkElf.cs index 95c0b21ab4..23752849f2 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D13LunarSubterrane/D131DarkElf.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D13LunarSubterrane/D131DarkElf.cs @@ -108,7 +108,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var c in _doomed) { if (_doomed.Count > 0 && actor.Role == Role.Healer) - hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High, castTime: 1); + hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High); if (_doomed.Count > 0 && actor.Class == Class.BRD) hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.WardensPaean), c, ActionQueue.Priority.High); } diff --git a/BossMod/Modules/Shadowbringers/Hunt/RankS/Ixtab.cs b/BossMod/Modules/Shadowbringers/Hunt/RankS/Ixtab.cs index aa431baa70..63c3921fa6 100644 --- a/BossMod/Modules/Shadowbringers/Hunt/RankS/Ixtab.cs +++ b/BossMod/Modules/Shadowbringers/Hunt/RankS/Ixtab.cs @@ -126,7 +126,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var c in _doomed) { if (_doomed.Count > 0 && actor.Role == Role.Healer) - hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High, castTime: 1); + hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.Esuna), c, ActionQueue.Priority.High); if (_doomed.Count > 0 && actor.Class == Class.BRD) hints.ActionsToExecute.Push(ActionID.MakeSpell(BRD.AID.WardensPaean), c, ActionQueue.Priority.High); } diff --git a/TODO b/TODO index 4a180b932d..df49e692ed 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,7 @@ immediate plans -- get rid of legacyxxx (waiting for net9) -- review enemy prios usage - should framework do anything about any prios? like taunt at -4... -- freeze -- gaze avoidance + forced movement fail -- ex3 p2 ice bridges -- on ex1 the cleave is still telegraphed a bit too wide -- for p2 thordan cleavebuster the telegraph on the minimap is narrower than the actual hitbox +- remove 'ex' variants of strategies, replace with cooldown/effect functors, write a converter +- add strategy param, use for 'apply unless already active' flavours of utility strategies +- get rid of legacyxxx - ishape general: @@ -40,6 +36,9 @@ general: - alt style for player indicator on arena - MAO for pomanders holsters etc - ManualActionQueueTweak.Push should not special case gcds?.. +- review enemy prios usage - should framework do anything about any prios? like taunt at -4... +- freeze special mode implementation +- gaze avoidance + forced movement fail ai: - nav decision delay @@ -60,6 +59,9 @@ boss modules: -- a11: ai hints for spikes+uppercut -- a14: complex aoe hints (cthonic, battlements) -- a14: dark nebula kb hints +- [dt ex3] p2 ice bridges +- [dt ex1] the cleave is still telegraphed a bit too wide +- [dsr] for p2 thordan cleavebuster the telegraph on the minimap is narrower than the actual hitbox autorotation: - global strategy for track