From 697e61cf12b1aa858fca7a33c3ee13558091b9b6 Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 13:46:28 +0000 Subject: [PATCH 1/6] Leylines module --- .../Autorotation/MiscAI/StayWithinLeylines.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 BossMod/Autorotation/MiscAI/StayWithinLeylines.cs diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs new file mode 100644 index 0000000000..70bb64d318 --- /dev/null +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -0,0 +1,51 @@ +using static BossMod.ActionQueue; + +namespace BossMod.Autorotation.MiscAI; + +public sealed class StayWithinLeylines(RotationModuleManager manager, Actor player) : RotationModule(manager, player) +{ + public enum Tracks + { + UseRetrace + } + + public enum RetraceDefinition + { + No = 0, + Yes = 1, + } + + public static RotationModuleDefinition Definition() + { + RotationModuleDefinition def = new("Misc AI: Stay within leylines when active", "Black Mage utility module.", "Misc", "Taurenkey", RotationModuleQuality.Basic, BitMask.Build(Class.BLM), 1000); + + var config = def.Define(Tracks.UseRetrace).As("Use Retrace", "Use Retrace"); + + config.AddOption(RetraceDefinition.No, "No"); + config.AddOption(RetraceDefinition.Yes, "Yes"); + + return def; + } + + public override void Execute(StrategyValues strategy, Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving) + { + bool InLeyLines = Player.FindStatus(738) != null; + + if (!InLeyLines) + { + var zone = World.Actors.FirstOrDefault(x => x.OID == 0x179 && x.OwnerID == Player.InstanceID); + if (zone != null) + { + var retrace = ActionID.MakeSpell(BLM.AID.Retrace); + var cd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; + var strat = strategy.Option(Tracks.UseRetrace).As(); + //try Retrace First + if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f) + Hints.ActionsToExecute.Push(retrace, null, Priority.Low, targetPos: Player.PosRot.XYZ()); + else + Hints.GoalZones.Add(Hints.GoalSingleTarget(zone.Position, 1f)); + } + } + + } +} From ea2627fde5dcd67c6d9050a246a86500474e87bc Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 13:49:39 +0000 Subject: [PATCH 2/6] Update coded status to SID --- BossMod/Autorotation/MiscAI/StayWithinLeylines.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs index 70bb64d318..4ce54c4ff3 100644 --- a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -29,7 +29,7 @@ public static RotationModuleDefinition Definition() public override void Execute(StrategyValues strategy, Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving) { - bool InLeyLines = Player.FindStatus(738) != null; + bool InLeyLines = Player.FindStatus(BLM.SID.CircleOfPower) != null; if (!InLeyLines) { From 72323954e36b44f5229743cc2899e6a2e476bd60 Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 14:03:17 +0000 Subject: [PATCH 3/6] Movement check for retrace --- BossMod/Autorotation/MiscAI/StayWithinLeylines.cs | 2 +- .../Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs index 4ce54c4ff3..0f9ff80baa 100644 --- a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -40,7 +40,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa var cd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; var strat = strategy.Option(Tracks.UseRetrace).As(); //try Retrace First - if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f) + if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f && !isMoving) Hints.ActionsToExecute.Push(retrace, null, Priority.Low, targetPos: Player.PosRot.XYZ()); else Hints.GoalZones.Add(Hints.GoalSingleTarget(zone.Position, 1f)); diff --git a/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs b/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs index b897f41265..31e1b30516 100644 --- a/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs +++ b/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs @@ -54,7 +54,7 @@ private WPos CalculateSafeSpot(int slot) WDir[] offsets = [new(+1, -1), new(+1, +1), new(-1, +1), new(-1, -1)]; // CW from N var relevantTether = _states[slot].Debuff == DebuffType.Light ? EngravementOfSoulsTethers.TetherType.Dark : EngravementOfSoulsTethers.TetherType.Light; var expectedPositions = _tethers.States.Where(s => s.Source != null).Select(s => (s.Source!.Position + 40 * s.Source.Rotation.ToDirection(), s.Tether == relevantTether)).ToList(); - var offsetsOrdered = (Raid[slot]?.Class.IsSupport() ?? false) ? offsets.AsEnumerable() : offsets.Reverse(); + var offsetsOrdered = (Raid[slot]?.Class.IsSupport() ?? false) ? offsets.AsEnumerable() : Enumerable.Reverse(offsets); var positionsOrdered = offsetsOrdered.Select(d => Module.Center + 7 * d); var firstMatch = positionsOrdered.First(p => expectedPositions.MinBy(ep => (ep.Item1 - p).LengthSq()).Item2); _states[slot].CachedSafespot = firstMatch; From 8f3771afd66a57f813cdc89a4c053c2eef54b1ed Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 14:03:40 +0000 Subject: [PATCH 4/6] Revert "Movement check for retrace" This reverts commit 72323954e36b44f5229743cc2899e6a2e476bd60. --- BossMod/Autorotation/MiscAI/StayWithinLeylines.cs | 2 +- .../Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs index 0f9ff80baa..4ce54c4ff3 100644 --- a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -40,7 +40,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa var cd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; var strat = strategy.Option(Tracks.UseRetrace).As(); //try Retrace First - if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f && !isMoving) + if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f) Hints.ActionsToExecute.Push(retrace, null, Priority.Low, targetPos: Player.PosRot.XYZ()); else Hints.GoalZones.Add(Hints.GoalSingleTarget(zone.Position, 1f)); diff --git a/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs b/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs index 31e1b30516..b897f41265 100644 --- a/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs +++ b/BossMod/Modules/Endwalker/Savage/P12S1Athena/EngravementOfSouls1.cs @@ -54,7 +54,7 @@ private WPos CalculateSafeSpot(int slot) WDir[] offsets = [new(+1, -1), new(+1, +1), new(-1, +1), new(-1, -1)]; // CW from N var relevantTether = _states[slot].Debuff == DebuffType.Light ? EngravementOfSoulsTethers.TetherType.Dark : EngravementOfSoulsTethers.TetherType.Light; var expectedPositions = _tethers.States.Where(s => s.Source != null).Select(s => (s.Source!.Position + 40 * s.Source.Rotation.ToDirection(), s.Tether == relevantTether)).ToList(); - var offsetsOrdered = (Raid[slot]?.Class.IsSupport() ?? false) ? offsets.AsEnumerable() : Enumerable.Reverse(offsets); + var offsetsOrdered = (Raid[slot]?.Class.IsSupport() ?? false) ? offsets.AsEnumerable() : offsets.Reverse(); var positionsOrdered = offsetsOrdered.Select(d => Module.Center + 7 * d); var firstMatch = positionsOrdered.First(p => expectedPositions.MinBy(ep => (ep.Item1 - p).LengthSq()).Item2); _states[slot].CachedSafespot = firstMatch; From 92c00e39098c60d8b7b6826b13d5fc63736eeadc Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 14:06:06 +0000 Subject: [PATCH 5/6] Movement check for retrace --- BossMod/Autorotation/MiscAI/StayWithinLeylines.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs index 0f9ff80baa..4ce54c4ff3 100644 --- a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -40,7 +40,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa var cd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; var strat = strategy.Option(Tracks.UseRetrace).As(); //try Retrace First - if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f && !isMoving) + if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f) Hints.ActionsToExecute.Push(retrace, null, Priority.Low, targetPos: Player.PosRot.XYZ()); else Hints.GoalZones.Add(Hints.GoalSingleTarget(zone.Position, 1f)); From ac75f3a14950ca872d4c01246e55a5fadc3c3361 Mon Sep 17 00:00:00 2001 From: Taurenkey Date: Mon, 25 Nov 2024 14:46:43 +0000 Subject: [PATCH 6/6] Add between the lines option --- .../Autorotation/MiscAI/StayWithinLeylines.cs | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs index 0f9ff80baa..73a4092567 100644 --- a/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs +++ b/BossMod/Autorotation/MiscAI/StayWithinLeylines.cs @@ -6,7 +6,8 @@ public sealed class StayWithinLeylines(RotationModuleManager manager, Actor play { public enum Tracks { - UseRetrace + UseRetrace, + UseBetweenTheLines } public enum RetraceDefinition @@ -15,14 +16,23 @@ public enum RetraceDefinition Yes = 1, } + public enum BetweenTheLinesDefinition + { + No = 0, + Yes = 1, + } + public static RotationModuleDefinition Definition() { RotationModuleDefinition def = new("Misc AI: Stay within leylines when active", "Black Mage utility module.", "Misc", "Taurenkey", RotationModuleQuality.Basic, BitMask.Build(Class.BLM), 1000); - var config = def.Define(Tracks.UseRetrace).As("Use Retrace", "Use Retrace"); + var retrace = def.Define(Tracks.UseRetrace).As("Use Retrace", "Use Retrace"); + retrace.AddOption(RetraceDefinition.No, "No"); + retrace.AddOption(RetraceDefinition.Yes, "Yes"); - config.AddOption(RetraceDefinition.No, "No"); - config.AddOption(RetraceDefinition.Yes, "Yes"); + var btl = def.Define(Tracks.UseBetweenTheLines).As("Use Between The Lines", "Use Between The Lines"); + btl.AddOption(BetweenTheLinesDefinition.No, "No"); + btl.AddOption(BetweenTheLinesDefinition.Yes, "Yes"); return def; } @@ -37,10 +47,16 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa if (zone != null) { var retrace = ActionID.MakeSpell(BLM.AID.Retrace); - var cd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; - var strat = strategy.Option(Tracks.UseRetrace).As(); - //try Retrace First - if (strat == RetraceDefinition.Yes && ActionUnlocked(retrace) && cd.HasValue && World.Client.Cooldowns[cd.Value].Elapsed <= 2f && !isMoving) + var btl = ActionID.MakeSpell(BLM.AID.BetweenTheLines); + var retraceCd = ActionDefinitions.Instance.Spell(BLM.AID.Retrace)?.MainCooldownGroup; + var btlCd = ActionDefinitions.Instance.Spell(BLM.AID.BetweenTheLines)?.MainCooldownGroup; + var retraceStrat = strategy.Option(Tracks.UseRetrace).As(); + var btlStrat = strategy.Option(Tracks.UseBetweenTheLines).As(); + + //BTL first, followed by retrace, then walk + if (btlStrat == BetweenTheLinesDefinition.Yes && ActionUnlocked(btl) && btlCd.HasValue && World.Client.Cooldowns[btlCd.Value].Elapsed <= 2f && !isMoving) + Hints.ActionsToExecute.Push(btl, Player, Priority.Low, targetPos: zone.PosRot.XYZ()); + else if (retraceStrat == RetraceDefinition.Yes && ActionUnlocked(retrace) && retraceCd.HasValue && World.Client.Cooldowns[retraceCd.Value].Elapsed <= 2f && !isMoving) Hints.ActionsToExecute.Push(retrace, null, Priority.Low, targetPos: Player.PosRot.XYZ()); else Hints.GoalZones.Add(Hints.GoalSingleTarget(zone.Position, 1f));