From dc1edff162f9a58f150574bf3ddd637021a6e280 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus <156172553+CarnifexOptimus@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:13:34 +0100 Subject: [PATCH] some LINQ removal --- BossMod/Components/Cleave.cs | 4 +- BossMod/Components/Exaflare.cs | 48 +++++++++++++++---- BossMod/Components/LineOfSightAOE.cs | 2 +- BossMod/Components/PersistentVoidzone.cs | 39 +++++++++++++-- .../Alliance/A13ArkAngels/ConeDonutCross.cs | 8 ++-- .../Alliance/A14ShadowLord/UmbraSmash.cs | 15 ++++-- .../JanquetilaquesPortrait.cs | 5 +- .../Criterion/C02AMR/C023Moko/AzureAuspice.cs | 2 +- .../Variant/V02MR/V022Moko/Upwell.cs | 31 +++++++++--- .../Dungeon/D01Holminster/D013Philia.cs | 33 +++++++++---- 10 files changed, 145 insertions(+), 42 deletions(-) diff --git a/BossMod/Components/Cleave.cs b/BossMod/Components/Cleave.cs index 09d5ee6c38..ca2a0b4847 100644 --- a/BossMod/Components/Cleave.cs +++ b/BossMod/Components/Cleave.cs @@ -28,10 +28,10 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme if (actor != target) hints.AddForbiddenZone(Shape, origin.Position, angle, NextExpected); else - AddTargetSpecificHints(actor, origin, angle, hints); + AddTargetSpecificHints(actor, origin, hints); } - private void AddTargetSpecificHints(Actor actor, Actor source, Angle angle, AIHints hints) + private void AddTargetSpecificHints(Actor actor, Actor source, AIHints hints) { foreach (var a in Raid.WithoutSlot().Exclude(actor)) switch (Shape) diff --git a/BossMod/Components/Exaflare.cs b/BossMod/Components/Exaflare.cs index 4a2e8691ca..7661da88be 100644 --- a/BossMod/Components/Exaflare.cs +++ b/BossMod/Components/Exaflare.cs @@ -19,23 +19,52 @@ public class Line public uint FutureColor = Colors.AOE; public readonly List Lines = []; - public bool Active => Lines.Count > 0; + public bool Active => Lines.Count != 0; public Exaflare(BossModule module, float radius, ActionID aid = new()) : this(module, new AOEShapeCircle(radius), aid) { } public override IEnumerable ActiveAOEs(int slot, Actor actor) { - foreach (var (c, t, r) in FutureAOEs()) - yield return new(Shape, c, r, t, FutureColor); - foreach (var (c, t, r) in ImminentAOEs()) - yield return new(Shape, c, r, t, ImminentColor); + var linesCount = Lines.Count; + if (linesCount == 0) + return []; + var futureAOEs = FutureAOEs(linesCount); + var imminentAOEs = ImminentAOEs(linesCount); + var futureCount = futureAOEs.Count; + var imminentCount = imminentAOEs.Count; + + List aoes = new(futureCount + imminentCount); + for (var i = 0; i < futureCount; ++i) + { + var aoe = futureAOEs[i]; + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, FutureColor)); + } + + for (var i = 0; i < imminentCount; ++i) + { + var aoe = imminentAOEs[i]; + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, ImminentColor)); + } + return aoes; } - protected IEnumerable<(WPos, DateTime, Angle)> ImminentAOEs() => Lines.Where(l => l.ExplosionsLeft > 0).Select(l => (l.Next, l.NextExplosion, l.Rotation)); + protected List<(WPos, DateTime, Angle)> ImminentAOEs(int count) + { + var exas = new List<(WPos, DateTime, Angle)>(count); + + for (var i = 0; i < count; ++i) + { + var l = Lines[i]; + if (l.ExplosionsLeft != 0) + exas.Add((l.Next, l.NextExplosion, l.Rotation)); + } + return exas; + } - protected IEnumerable<(WPos, DateTime, Angle)> FutureAOEs() + protected List<(WPos, DateTime, Angle)> FutureAOEs(int count) { - for (var i = 0; i < Lines.Count; ++i) + var exas = new List<(WPos, DateTime, Angle)>(count); + for (var i = 0; i < count; ++i) { var l = Lines[i]; var num = Math.Min(l.ExplosionsLeft, l.MaxShownExplosions); @@ -45,9 +74,10 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) { pos += l.Advance; time = time.AddSeconds(l.TimeToMove); - yield return (pos, time, l.Rotation); + exas.Add((pos, time, l.Rotation)); } } + return exas; } protected void AdvanceLine(Line l, WPos pos) diff --git a/BossMod/Components/LineOfSightAOE.cs b/BossMod/Components/LineOfSightAOE.cs index bd1b6709b5..559649f287 100644 --- a/BossMod/Components/LineOfSightAOE.cs +++ b/BossMod/Components/LineOfSightAOE.cs @@ -48,7 +48,7 @@ public override void AddHints(int slot, Actor actor, TextHints hints) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) - AddSafezone(Module.CastFinishAt(spell), caster.Rotation); + AddSafezone(Module.CastFinishAt(spell), spell.Rotation); } public void AddSafezone(DateTime activation, Angle rotation = default) diff --git a/BossMod/Components/PersistentVoidzone.cs b/BossMod/Components/PersistentVoidzone.cs index 4f58afc4fc..3b4557c6da 100644 --- a/BossMod/Components/PersistentVoidzone.cs +++ b/BossMod/Components/PersistentVoidzone.cs @@ -11,7 +11,12 @@ public class PersistentVoidzone(BossModule module, float radius, Func ActiveAOEs(int slot, Actor actor) { - return Sources(Module).Select(s => new AOEInstance(Shape, s.Position, s.Rotation)); + var aoes = new List(); + foreach (var source in Sources(Module)) + { + aoes.Add(new(Shape, source.Position, source.Rotation)); + } + return aoes; } public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) @@ -21,7 +26,19 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme var forbidden = new List>(); foreach (var s in Sources(Module)) forbidden.Add(Shape.Distance(s.Position, s.Rotation)); - hints.AddForbiddenZone(p => forbidden.Min(f => f(p))); + hints.AddForbiddenZone(minDistanceFunc); + + float minDistanceFunc(WPos pos) + { + var minDistance = float.MaxValue; + for (var i = 0; i < forbidden.Count; ++i) + { + var distance = forbidden[i](pos); + if (distance < minDistance) + minDistance = distance; + } + return minDistance; + } } } @@ -98,14 +115,26 @@ public override void AddHints(int slot, Actor actor, TextHints hints) public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - var shapes = Sources(Module).Select(s => Shape.Distance(s.Position, s.Rotation)).ToList(); + var shapes = new List>(); + + foreach (var source in Sources(Module)) + { + var shape = Shape.Distance(source.Position, source.Rotation); + shapes.Add(shape); + } if (shapes.Count == 0) return; float distance(WPos p) { - var dist = shapes.Select(s => s(p)).Min(); - return Inverted ? -dist : dist; + var minDistance = float.MaxValue; + for (var i = 0; i < shapes.Count; ++i) + { + var distance = shapes[i](p); + if (distance < minDistance) + minDistance = distance; + } + return Inverted ? -minDistance : minDistance; } hints.AddForbiddenZone(distance, InvertResolveAt); } diff --git a/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/ConeDonutCross.cs b/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/ConeDonutCross.cs index fcc80e8d65..02ca39c59f 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/ConeDonutCross.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/ConeDonutCross.cs @@ -26,13 +26,13 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (Casters.Count == 0) - yield break; + return []; var reaver = Module.FindComponent(); var check = _aoe != null && _aoe.Casters.Count != 0; var check2 = reaver != null && reaver.Casters.Count != 0; - yield return Casters[0] with { Color = check2 ? Colors.Danger : Colors.AOE, Risky = !check }; + return [Casters[0] with { Color = check2 ? Colors.Danger : Colors.AOE, Risky = !check }]; } } @@ -41,9 +41,9 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (Casters.Count == 0) - yield break; + return []; var chain = Module.FindComponent(); var check = chain != null && chain.Casters.Count != 0; - yield return Casters[0] with { Risky = !check }; + return [Casters[0] with { Risky = !check }]; } } diff --git a/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs b/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs index 1c0a0bf798..40c61a1938 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs @@ -5,9 +5,18 @@ namespace BossMod.Dawntrail.Alliance.A14ShadowLord; private static readonly HashSet casts = [AID.UmbraSmashAOE1, AID.UmbraSmashAOE2, AID.UmbraSmashAOE3, AID.UmbraSmashAOE4, AID.UmbraSmashAOEClone]; public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { + var linesCount = Lines.Count; + if (linesCount == 0) + return; + + var imminentAOEs = ImminentAOEs(linesCount); + // use only imminent aoes for hints - foreach (var (c, t, r) in ImminentAOEs()) - hints.AddForbiddenZone(Shape, c, r, t); + for (var i = 0; i < imminentAOEs.Count; ++i) + { + var aoe = imminentAOEs[i]; + hints.AddForbiddenZone(Shape, aoe.Item1, aoe.Item3, aoe.Item2); + } } public override void OnCastStarted(Actor caster, ActorCastInfo spell) @@ -15,7 +24,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) if ((AID)spell.Action.ID is AID.UmbraSmashAOE1 or AID.UmbraSmashAOE2 or AID.UmbraSmashAOE3 or AID.UmbraSmashAOE4 or AID.UmbraSmashAOEClone) { var dir = spell.Rotation.ToDirection(); - var origin = spell.LocXZ + 30 * dir; + var origin = caster.Position + 30 * dir; Lines.Add(new() { Next = origin, Advance = 5 * dir.OrthoL(), Rotation = spell.Rotation + 90.Degrees(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2.3f, ExplosionsLeft = 6, MaxShownExplosions = 2 }); Lines.Add(new() { Next = origin, Advance = 5 * dir.OrthoR(), Rotation = spell.Rotation - 90.Degrees(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2.3f, ExplosionsLeft = 6, MaxShownExplosions = 2 }); } diff --git a/BossMod/Modules/Dawntrail/Quest/JobQuests/Pictomancer/SomewhereOnlySheKnows/JanquetilaquesPortrait.cs b/BossMod/Modules/Dawntrail/Quest/JobQuests/Pictomancer/SomewhereOnlySheKnows/JanquetilaquesPortrait.cs index 392f89664c..1b53be3df4 100644 --- a/BossMod/Modules/Dawntrail/Quest/JobQuests/Pictomancer/SomewhereOnlySheKnows/JanquetilaquesPortrait.cs +++ b/BossMod/Modules/Dawntrail/Quest/JobQuests/Pictomancer/SomewhereOnlySheKnows/JanquetilaquesPortrait.cs @@ -104,8 +104,9 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) { var advance1 = spell.Rotation.ToDirection().OrthoR() * 7.5f; var advance2 = spell.Rotation.ToDirection().OrthoR() * 5; - Lines.Add(new() { Next = spell.LocXZ + advance1, Advance = advance2, Rotation = spell.Rotation, NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = 5, MaxShownExplosions = 2 }); - Lines.Add(new() { Next = spell.LocXZ - advance1, Advance = -advance2, Rotation = (spell.Rotation + 180.Degrees()).Normalized(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = 5, MaxShownExplosions = 2 }); + var pos = caster.Position; + Lines.Add(new() { Next = pos + advance1, Advance = advance2, Rotation = spell.Rotation, NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = 5, MaxShownExplosions = 2 }); + Lines.Add(new() { Next = pos - advance1, Advance = -advance2, Rotation = (spell.Rotation + 180.Degrees()).Normalized(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = 5, MaxShownExplosions = 2 }); } } diff --git a/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/AzureAuspice.cs b/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/AzureAuspice.cs index e037a96170..04765fceed 100644 --- a/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/AzureAuspice.cs +++ b/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/AzureAuspice.cs @@ -41,7 +41,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) if ((AID)spell.Action.ID is AID.NUpwellFirst or AID.SUpwellFirst) { var advance = spell.Rotation.ToDirection().OrthoR() * 5; - var pos = spell.LocXZ; + var pos = caster.Position; var activation = Module.CastFinishAt(spell); _lines.Add(new() { NextOrigin = pos, Advance = advance, Rotation = spell.Rotation, NextActivation = activation, NextShape = _shapeWide }); _lines.Add(new() { NextOrigin = pos, Advance = -advance, Rotation = (spell.Rotation + 180.Degrees()).Normalized(), NextActivation = activation }); diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V022Moko/Upwell.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V022Moko/Upwell.cs index 930c19ee6b..8b61bc2e1c 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V022Moko/Upwell.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V022Moko/Upwell.cs @@ -11,20 +11,37 @@ class UpwellFirst : Components.SimpleAOEs { public override IEnumerable ActiveAOEs(int slot, Actor actor) { + var linesCount = Lines.Count; + if (linesCount == 0) + return []; + var futureAOEs = FutureAOEs(linesCount); + var imminentAOEs = ImminentAOEs(linesCount); + var futureCount = futureAOEs.Count; + var imminentCount = imminentAOEs.Count; var imminentDeadline = WorldState.FutureTime(5); - foreach (var (c, t, r) in FutureAOEs()) - if (t <= imminentDeadline) - yield return new(Shape, c, r, t, FutureColor); - foreach (var (c, t, r) in ImminentAOEs()) - if (t <= imminentDeadline) - yield return new(Shape, c, r, t, ImminentColor); + + List aoes = new(futureCount + imminentCount); + for (var i = 0; i < futureCount; ++i) + { + var aoe = futureAOEs[i]; + if (aoe.Item2 <= imminentDeadline) + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, FutureColor)); + } + + for (var i = 0; i < imminentCount; ++i) + { + var aoe = imminentAOEs[i]; + if (aoe.Item2 <= imminentDeadline) + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, ImminentColor)); + } + return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.UpwellFirst) { - var pos = spell.LocXZ; + var pos = caster.Position; var check = pos.AlmostEqual(Arena.Center, 1); var isNorth = pos.Z == 530; var isSouth = pos.Z == 550; diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs b/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs index b7266a2120..1b919c7296 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs @@ -205,14 +205,31 @@ class FierceBeating(BossModule module) : Components.Exaflare(module, 4) public override IEnumerable ActiveAOEs(int slot, Actor actor) { - foreach (var (c, t, r) in FutureAOEs()) - yield return new(Shape, c, r, t, FutureColor); - foreach (var (c, t, r) in ImminentAOEs()) - yield return new(Shape, c, r, t, ImminentColor); - if (Lines.Count > 0 && linesstartedcount1 < 8) - yield return new(circle, WPos.RotateAroundOrigin(linesstartedcount1 * 45, D013Philia.ArenaCenter, _casters[0]), default, _activation.AddSeconds(linesstartedcount1 * 3.7f)); - if (Lines.Count > 1 && linesstartedcount2 < 8) - yield return new(circle, WPos.RotateAroundOrigin(linesstartedcount2 * 45, D013Philia.ArenaCenter, _casters[1]), default, _activation.AddSeconds(linesstartedcount2 * 3.7f)); + var linesCount = Lines.Count; + if (linesCount == 0) + return []; + var futureAOEs = FutureAOEs(linesCount); + var imminentAOEs = ImminentAOEs(linesCount); + var futureCount = futureAOEs.Count; + var imminentCount = imminentAOEs.Count; + + List aoes = new(futureCount + imminentCount + 2); + for (var i = 0; i < futureCount; ++i) + { + var aoe = futureAOEs[i]; + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, FutureColor)); + } + + for (var i = 0; i < imminentCount; ++i) + { + var aoe = imminentAOEs[i]; + aoes.Add(new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, ImminentColor)); + } + if (linesstartedcount1 < 8) + aoes.Add(new(circle, WPos.RotateAroundOrigin(linesstartedcount1 * 45, D013Philia.ArenaCenter, _casters[0]), default, _activation.AddSeconds(linesstartedcount1 * 3.7f))); + if (linesCount > 1 && linesstartedcount2 < 8) + aoes.Add(new(circle, WPos.RotateAroundOrigin(linesstartedcount2 * 45, D013Philia.ArenaCenter, _casters[1]), default, _activation.AddSeconds(linesstartedcount2 * 3.7f))); + return aoes; } public override void Update()