diff --git a/BossMod/Components/Cleave.cs b/BossMod/Components/Cleave.cs index ff163dbd6c..6e41c8106c 100644 --- a/BossMod/Components/Cleave.cs +++ b/BossMod/Components/Cleave.cs @@ -13,7 +13,7 @@ public class Cleave(BossModule module, ActionID aid, AOEShape shape, uint[]? ene public override void AddHints(int slot, Actor actor, TextHints hints) { - if (OriginsAndTargets().Any(e => e.target != actor && Shape.Check(actor.Position, e.origin.Position, e.angle))) + if (OriginsAndTargets().Any(e => e.target != actor && Shape.Check(WPos.ClampToGrid(actor.Position), e.origin.Position, e.angle))) { hints.Add("GTFO from cleave!"); } @@ -26,7 +26,7 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme foreach (var (origin, target, angle) in OriginsAndTargets()) if (actor != target) - hints.AddForbiddenZone(Shape, origin.Position, angle, NextExpected); + hints.AddForbiddenZone(Shape, WPos.ClampToGrid(origin.Position), angle, NextExpected); else AddTargetSpecificHints(actor, origin, hints); } @@ -37,13 +37,13 @@ private void AddTargetSpecificHints(Actor actor, Actor source, AIHints hints) switch (Shape) { case AOEShapeCircle circle: - hints.AddForbiddenZone(circle, a.Position); + hints.AddForbiddenZone(circle, WPos.ClampToGrid(a.Position)); break; case AOEShapeCone cone: - hints.AddForbiddenZone(ShapeDistance.Cone(source.Position, 100, source.AngleTo(a), cone.HalfAngle)); + hints.AddForbiddenZone(ShapeDistance.Cone(WPos.ClampToGrid(source.Position), 100f, source.AngleTo(a), cone.HalfAngle)); break; case AOEShapeRect rect: - hints.AddForbiddenZone(ShapeDistance.Cone(source.Position, 100, source.AngleTo(a), Angle.Asin(rect.HalfWidth / (a.Position - source.Position).Length()))); + hints.AddForbiddenZone(ShapeDistance.Cone(WPos.ClampToGrid(source.Position), 100f, source.AngleTo(a), Angle.Asin(rect.HalfWidth / (a.Position - source.Position).Length()))); break; } } @@ -52,7 +52,7 @@ public override void DrawArenaForeground(int pcSlot, Actor pc) { foreach (var e in OriginsAndTargets()) { - Shape.Outline(Arena, e.origin.Position, e.angle); + Shape.Outline(Arena, WPos.ClampToGrid(e.origin.Position), e.angle); } } diff --git a/BossMod/Components/Exaflare.cs b/BossMod/Components/Exaflare.cs index 7df7dc2982..60e0901525 100644 --- a/BossMod/Components/Exaflare.cs +++ b/BossMod/Components/Exaflare.cs @@ -63,12 +63,13 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) protected List<(WPos, DateTime, Angle)> FutureAOEs(int count) { var exas = new List<(WPos, DateTime, Angle)>(count); + var currentTime = WorldState.CurrentTime; for (var i = 0; i < count; ++i) { var l = Lines[i]; var num = Math.Min(l.ExplosionsLeft, l.MaxShownExplosions); var pos = l.Next; - var time = l.NextExplosion > WorldState.CurrentTime ? l.NextExplosion : WorldState.CurrentTime; + var time = l.NextExplosion > currentTime ? l.NextExplosion : currentTime; for (var j = 1; j < num; ++j) { pos += l.Advance; diff --git a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Aquarius.cs b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Aquarius.cs index e4a866a06f..6fd318f3af 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Aquarius.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Aquarius.cs @@ -53,18 +53,14 @@ public A10AquariusStates(BossModule module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var allDeadOrDestroyed = true; var enemies = module.Enemies(A10Aquarius.Trash); var count = enemies.Count; for (var i = 0; i < count; ++i) { if (!enemies[i].IsDeadOrDestroyed) - { - allDeadOrDestroyed = false; - break; - } + return false; } - return allDeadOrDestroyed; + return true; }; } } diff --git a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Despot.cs b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Despot.cs index ad7eadb3c0..a81985c1e6 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Despot.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Despot.cs @@ -91,18 +91,14 @@ public A10DespotStates(BossModule module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var allDeadOrDestroyed = true; var enemies = module.Enemies(A10Despot.Trash); var count = enemies.Count; for (var i = 0; i < count; ++i) { if (!enemies[i].IsDeadOrDestroyed) - { - allDeadOrDestroyed = false; - break; - } + return false; } - return allDeadOrDestroyed; + return true; }; } } diff --git a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Groundskeeper.cs b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Groundskeeper.cs index ed4a830687..e66cf48aed 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Groundskeeper.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10Groundskeeper.cs @@ -28,18 +28,14 @@ public A10GroundskeeperStates(BossModule module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var allDeadOrDestroyed = true; var enemies = module.Enemies(A10Groundskeeper.Trash); var count = enemies.Count; for (var i = 0; i < count; ++i) { if (!enemies[i].IsDeadOrDestroyed) - { - allDeadOrDestroyed = false; - break; - } + return false; } - return allDeadOrDestroyed; + return true; }; } } diff --git a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10VanguardPathfinder.cs b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10VanguardPathfinder.cs index be496fb422..de2bd5eba6 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10VanguardPathfinder.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A10Trash/A10VanguardPathfinder.cs @@ -30,18 +30,14 @@ public A10VanguardPathfinderStates(BossModule module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var allDeadOrDestroyed = true; var enemies = module.Enemies(A10VanguardPathfinder.Trash); var count = enemies.Count; for (var i = 0; i < count; ++i) { if (!enemies[i].IsDeadOrDestroyed) - { - allDeadOrDestroyed = false; - break; - } + return false; } - return allDeadOrDestroyed; + return true; }; } } diff --git a/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/A13ArkAngelsStates.cs b/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/A13ArkAngelsStates.cs index ac8f7577d4..1e23933c03 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/A13ArkAngelsStates.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A13ArkAngels/A13ArkAngelsStates.cs @@ -29,18 +29,14 @@ public A13ArkAngelsStates(A13ArkAngels module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var allDeadOrDestroyed = true; var enemies = module.Enemies(A13ArkAngels.Bosses); var count = enemies.Count; for (var i = 0; i < count; ++i) { if (!enemies[i].IsDeadOrDestroyed) - { - allDeadOrDestroyed = false; - break; - } + return false; } - return allDeadOrDestroyed; + return true; }; } diff --git a/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs b/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs index 5dbf22cb20..b898e664e5 100644 --- a/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs +++ b/BossMod/Modules/Dawntrail/Alliance/A14ShadowLord/UmbraSmash.cs @@ -28,7 +28,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) case (uint)AID.UmbraSmashAOE4: case (uint)AID.UmbraSmashAOEClone: var dir = spell.Rotation.ToDirection(); - var origin = spell.LocXZ + 30f * dir; + var origin = caster.Position + 30f * dir; Lines.Add(new() { Next = origin, Advance = 5f * dir.OrthoL(), Rotation = spell.Rotation + 90f.Degrees(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2.3f, ExplosionsLeft = 6, MaxShownExplosions = 2 }); Lines.Add(new() { Next = origin, Advance = 5f * dir.OrthoR(), Rotation = spell.Rotation - 90f.Degrees(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2.3f, ExplosionsLeft = 6, MaxShownExplosions = 2 }); break; @@ -45,7 +45,7 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) case (uint)AID.UmbraSmashAOE4: case (uint)AID.UmbraSmashAOEClone: ++NumCasts; - var origin = spell.LocXZ + 30f * spell.Rotation.ToDirection(); + var origin = caster.Position + 30f * spell.Rotation.ToDirection(); foreach (var l in Lines.Where(l => l.Next.AlmostEqual(origin, 1f))) { l.Next = origin + l.Advance; diff --git a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/CurseOfDarkness.cs b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/CurseOfDarkness.cs index 651eabe37e..c42fcd491a 100644 --- a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/CurseOfDarkness.cs +++ b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/CurseOfDarkness.cs @@ -19,13 +19,13 @@ public override void Update() public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.CurseOfDarkness && Raid.FindSlot(actor.InstanceID) is var slot && slot >= 0) + if (status.ID == (uint)SID.CurseOfDarkness && Raid.FindSlot(actor.InstanceID) is var slot && slot >= 0) _activation[slot] = status.ExpireAt; } public override void OnStatusLose(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.CurseOfDarkness && Raid.FindSlot(actor.InstanceID) is var slot && slot >= 0) + if (status.ID == (uint)SID.CurseOfDarkness && Raid.FindSlot(actor.InstanceID) is var slot && slot >= 0) _activation[slot] = default; } } diff --git a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/EvilSeed.cs b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/EvilSeed.cs index 3571eebd86..57eb20dcfe 100644 --- a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/EvilSeed.cs +++ b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/EvilSeed.cs @@ -7,7 +7,7 @@ class EvilSeedBait(BossModule module) : BossComponent(module) public override void DrawArenaForeground(int pcSlot, Actor pc) { foreach (var p in Raid.WithSlot(false, false, true).IncludedInMask(Baiters).Actors()) - Arena.AddCircle(p.Position, 5, Colors.Danger); + Arena.AddCircle(p.Position, 5f, Colors.Danger); } public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) @@ -17,7 +17,7 @@ public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) } } -class EvilSeedAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.EvilSeedAOE), 5); +class EvilSeedAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.EvilSeedAOE), 5f); class EvilSeedVoidzone(BossModule module) : Components.PersistentVoidzone(module, 5, module => module.Enemies(OID.EvilSeed).Where(z => z.EventState != 7)); diff --git a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/ThirdArtOfDarkness.cs b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/ThirdArtOfDarkness.cs index 5a367f1515..0a6ca91943 100644 --- a/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/ThirdArtOfDarkness.cs +++ b/BossMod/Modules/Dawntrail/Chaotic/Ch01CloudOfDarkness/ThirdArtOfDarkness.cs @@ -20,7 +20,7 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) _ => default }; if (dir != default) - yield return new(_shape, caster.Position, caster.Rotation + dir, m[0].activation); + yield return new(_shape, WPos.ClampToGrid(caster.Position), caster.Rotation + dir, m[0].activation); } } diff --git a/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash1.cs b/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash1.cs index de162e0f66..986cb9788c 100644 --- a/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash1.cs +++ b/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash1.cs @@ -22,16 +22,16 @@ public enum AID : uint DivineBurst = 35441 // DivineSprite->self, no cast, range 40 circle, raidwide when Divine Sprite dies } -class WaterIII(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WaterIII), 8); +class WaterIII(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WaterIII), 8f); -abstract class PelagicCleaver(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(40, 30.Degrees())); +abstract class PelagicCleaver(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(40f, 30f.Degrees())); class PelagicCleaver1(BossModule module) : PelagicCleaver(module, AID.PelagicCleaver1); class PelagicCleaver2(BossModule module) : PelagicCleaver(module, AID.PelagicCleaver2); class PelagicCleaver1Hint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.PelagicCleaver1)); class PelagicCleaver2Hint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.PelagicCleaver2)); -class Flood(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 6); +class Flood(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 6f); class WaterFlood(BossModule module) : Flood(module, AID.WaterFlood); class DivineFlood(BossModule module) : Flood(module, AID.DivineFlood); @@ -44,11 +44,11 @@ public A30Trash1States(A30Trash1 module) : base(module) .ActivateOnEnter() .Raw.Update = () => { - var enemies = module.Enemies(OID.Serpent); - for (var i = 0; i < enemies.Count; ++i) + var enemies = module.Enemies((uint)OID.Serpent); + var count = enemies.Count; + for (var i = 0; i < count; ++i) { - var e = enemies[i]; - if (!e.IsDeadOrDestroyed) + if (!enemies[i].IsDeadOrDestroyed) return false; } return true; @@ -69,19 +69,19 @@ public A30Trash1States(A30Trash1 module) : base(module) if (!e.IsDeadOrDestroyed) return false; } - return module.Enemies(OID.Serpent).Count == 0; + return module.Enemies((uint)OID.Serpent).Count == 0; }; } } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus, LTS", PrimaryActorOID = (uint)OID.Serpent, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 12478, SortOrder = 1)] -public class A30Trash1(WorldState ws, Actor primary) : BossModule(ws, primary, new(-800, -800), new ArenaBoundsCircle(20)) +public class A30Trash1(WorldState ws, Actor primary) : BossModule(ws, primary, new(-800f, -800f), new ArenaBoundsCircle(20f)) { public static readonly uint[] Trash = [(uint)OID.Triton, (uint)OID.DivineSprite, (uint)OID.WaterSprite]; protected override void DrawEnemies(int pcSlot, Actor pc) { - Arena.Actors(Enemies(OID.Serpent)); + Arena.Actors(Enemies((uint)OID.Serpent)); Arena.Actors(Enemies(Trash)); } } diff --git a/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash2.cs b/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash2.cs index 48b702186c..ec8c0f5c31 100644 --- a/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash2.cs +++ b/BossMod/Modules/Endwalker/Alliance/A30Trash/A30Trash2.cs @@ -16,11 +16,11 @@ public enum AID : uint Skylight = 35446 // AngelosMikros->self, 3.0s cast, range 6 circle } -class RingOfSkylight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.RingOfSkylight), new AOEShapeDonut(8, 30)); +class RingOfSkylight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.RingOfSkylight), new AOEShapeDonut(8f, 30f)); class RingOfSkylightInterruptHint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.RingOfSkylight)); -class SkylightCross(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SkylightCross), new AOEShapeCross(60, 4)); +class SkylightCross(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SkylightCross), new AOEShapeCross(60f, 4f)); class SkylightCrossInterruptHint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.SkylightCross)); -class Skylight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Skylight), 6); +class Skylight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Skylight), 6f); public class A30Trash2Pack1States : StateMachineBuilder { @@ -32,22 +32,36 @@ public A30Trash2Pack1States(A30Trash2Pack1 module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .Raw.Update = () => Module.PrimaryActor.IsDeadOrDestroyed && module.Enemies(OID.AngelosMikros).All(e => e.IsDead); + .Raw.Update = () => + { + var allDeadOrDestroyed = true; + var enemies = module.Enemies((uint)OID.AngelosMikros); + var count = enemies.Count; + for (var i = 0; i < count; ++i) + { + if (!enemies[i].IsDeadOrDestroyed) + { + allDeadOrDestroyed = false; + break; + } + } + return module.PrimaryActor.IsDeadOrDestroyed && allDeadOrDestroyed; + }; } } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", PrimaryActorOID = (uint)OID.AngelosPack1, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 12481, SortOrder = 5)] public class A30Trash2Pack1(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly Shape[] union = [new Rectangle(new(800, 786), 21, 13.5f), new Rectangle(new(800, 767), 7.5f, 10), new Rectangle(new(800, 758), 10, 4)]; - private static readonly Shape[] difference = [new Square(new(811.25f, 787), 1.5f), new Square(new(811.25f, 777.4f), 1.5f), new Square(new(788.75f, 787), 1.5f), new Square(new(788.75f, 777.4f), 1.5f), + private static readonly Shape[] union = [new Rectangle(new(800f, 786f), 21f, 13.5f), new Rectangle(new(800f, 767f), 7.5f, 10f), new Rectangle(new(800f, 758f), 10f, 4f)]; + private static readonly Shape[] difference = [new Square(new(811.25f, 787f), 1.5f), new Square(new(811.25f, 777.4f), 1.5f), new Square(new(788.75f, 787f), 1.5f), new Square(new(788.75f, 777.4f), 1.5f), new Circle(new(793.4f, 762.75f), 1.25f), new Circle(new(806.6f, 762.75f), 1.25f)]; private static readonly ArenaBoundsComplex arena = new(union, difference); protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.AngelosMikros)); + Arena.Actors(Enemies((uint)OID.AngelosMikros)); } } @@ -58,15 +72,25 @@ public A30Trash2Pack2States(A30Trash2Pack2 module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.AngelosPack2).All(e => e.IsDead); + .Raw.Update = () => + { + var enemies = module.Enemies((uint)OID.AngelosPack2); + var count = enemies.Count; + for (var i = 0; i < count; ++i) + { + if (!enemies[i].IsDeadOrDestroyed) + return false; + } + return true; + }; } } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", PrimaryActorOID = (uint)OID.AngelosPack2, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 12481, SortOrder = 6)] -public class A30Trash2Pack2(WorldState ws, Actor primary) : BossModule(ws, primary, new(800, 909.75f), new ArenaBoundsSquare(19.5f)) +public class A30Trash2Pack2(WorldState ws, Actor primary) : BossModule(ws, primary, new(800f, 909.75f), new ArenaBoundsSquare(19.5f)) { protected override void DrawEnemies(int pcSlot, Actor pc) { - Arena.Actors(Enemies(OID.AngelosPack2)); + Arena.Actors(Enemies((uint)OID.AngelosPack2)); } } diff --git a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/A31Thaliak.cs b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/A31Thaliak.cs index 7617985281..b603d94a31 100644 --- a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/A31Thaliak.cs +++ b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/A31Thaliak.cs @@ -1,9 +1,9 @@ namespace BossMod.Endwalker.Alliance.A31Thaliak; class Katarraktes(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.KatarraktesAOE)); -class Thlipsis(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.ThlipsisAOE), 6, 8); -class Hydroptosis(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.HydroptosisAOE), 6); -class Rhyton(BossModule module) : Components.BaitAwayIcon(module, new AOEShapeRect(70, 3), (uint)IconID.Rhyton, ActionID.MakeSpell(AID.RhytonAOE), 6); +class Thlipsis(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.ThlipsisAOE), 6f, 8); +class Hydroptosis(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.HydroptosisAOE), 6f); +class Rhyton(BossModule module) : Components.BaitAwayIcon(module, new AOEShapeRect(70, 3), (uint)IconID.Rhyton, ActionID.MakeSpell(AID.RhytonAOE), 6f); class Bank(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(60, 90.Degrees())); class LeftBank(BossModule module) : Bank(module, AID.LeftBank); diff --git a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Hieroglyphika.cs b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Hieroglyphika.cs index dd356b310b..2359ced32b 100644 --- a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Hieroglyphika.cs +++ b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Hieroglyphika.cs @@ -11,16 +11,16 @@ class Hieroglyphika(BossModule module) : Components.GenericAOEs(module, ActionID { public bool BindsAssigned; public WDir SafeSideDir; - public readonly List AOEs = []; + public readonly List AOEs = new(14); - private static readonly AOEShapeRect _shape = new(6, 6, 6); - private static readonly WDir[] _canonicalSafespots = [new(6, -18), new(-18, 18)]; + private static readonly AOEShapeRect _shape = new(6f, 6f, 6f); + private static readonly WDir[] _canonicalSafespots = [new(6f, -18f), new(-18f, 18f)]; public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.Bind) + if (status.ID == (uint)SID.Bind) BindsAssigned = true; } @@ -31,8 +31,8 @@ public override void OnEventEnvControl(byte index, uint state) WDir dir = index switch { - 0x17 => new(-1, 0), - 0x4A => new(0, 1), + 0x17 => new(-1f, default), + 0x4A => new(default, 1f), _ => default }; if (dir != default) @@ -41,25 +41,25 @@ public override void OnEventEnvControl(byte index, uint state) public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) { - var dir = (IconID)iconID switch + var dir = iconID switch { - IconID.HieroglyphikaCW => SafeSideDir.OrthoR(), - IconID.HieroglyphikaCCW => SafeSideDir.OrthoL(), + (uint)IconID.HieroglyphikaCW => SafeSideDir.OrthoR(), + (uint)IconID.HieroglyphikaCCW => SafeSideDir.OrthoL(), _ => default }; if (dir == default) return; WDir[] safespots = [.. _canonicalSafespots.Select(d => d.Rotate(dir))]; - var activation = WorldState.FutureTime(17.1f); + var activation = WorldState.FutureTime(17.1d); for (var z = -3; z <= 3; z += 2) { for (var x = -3; x <= 3; x += 2) { var cellOffset = new WDir(x * 6, z * 6); - if (!safespots.Any(s => s.AlmostEqual(cellOffset, 1))) + if (!safespots.Any(s => s.AlmostEqual(cellOffset, 1f))) { - AOEs.Add(new(_shape, Arena.Center + cellOffset, default, activation)); + AOEs.Add(new(_shape, WPos.ClampToGrid(Arena.Center + cellOffset), default, activation)); } } } @@ -67,12 +67,7 @@ public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if (spell.Action == WatchedAction) - { - ++NumCasts; - var cnt = AOEs.RemoveAll(aoe => aoe.Origin.AlmostEqual(caster.Position, 1)); - if (cnt != 1) - ReportError($"Incorrect AOE prediction: {caster.Position} matched {cnt} aoes"); - } + if (AOEs.Count != 0 && spell.Action == WatchedAction) + AOEs.Clear(); } } diff --git a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Rheognosis.cs b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Rheognosis.cs index 0e9fcfb623..897fd01c18 100644 --- a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Rheognosis.cs +++ b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Rheognosis.cs @@ -8,13 +8,13 @@ class RheognosisKnockback(BossModule module) : Components.Knockback(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.Rheognosis or AID.RheognosisPetrine) - _knockback = new(Arena.Center, 25, Module.CastFinishAt(spell, 20.3f), Direction: spell.Rotation + 180.Degrees(), Kind: Kind.DirForward); + if (spell.Action.ID is (uint)AID.Rheognosis or (uint)AID.RheognosisPetrine) + _knockback = new(Arena.Center, 25f, Module.CastFinishAt(spell, 20.3f), Direction: spell.Rotation + 180f.Degrees(), Kind: Kind.DirForward); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.RheognosisKnockback) + if (spell.Action.ID == (uint)AID.RheognosisKnockback) { _knockback = null; ++NumCasts; @@ -24,7 +24,7 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) public class RheognosisCrash : Components.Exaflare { - public RheognosisCrash(BossModule module) : base(module, new AOEShapeRect(10, 12.05f), ActionID.MakeSpell(AID.RheognosisCrash)) => ImminentColor = Colors.AOE; + public RheognosisCrash(BossModule module) : base(module, new AOEShapeRect(10f, 12f), ActionID.MakeSpell(AID.RheognosisCrash)) => ImminentColor = Colors.AOE; public override void OnEventEnvControl(byte index, uint state) { @@ -34,8 +34,8 @@ public override void OnEventEnvControl(byte index, uint state) var right = state == 0x01000001; var south = west == right; var start = Arena.Center + new WDir(west ? -Arena.Bounds.Radius : +Arena.Bounds.Radius, (south ? +Arena.Bounds.Radius : -Arena.Bounds.Radius) * 0.5f); - var dir = (west ? 90 : -90).Degrees(); - Lines.Add(new() { Next = start, Advance = 10 * dir.ToDirection(), Rotation = dir, NextExplosion = WorldState.FutureTime(4), TimeToMove = 0.2f, ExplosionsLeft = 5, MaxShownExplosions = 5 }); + var dir = (west ? 90f : -90f).Degrees(); + Lines.Add(new() { Next = start, Advance = 10f * dir.ToDirection(), Rotation = dir, NextExplosion = WorldState.FutureTime(4d), TimeToMove = 0.2f, ExplosionsLeft = 5, MaxShownExplosions = 5 }); } } @@ -44,7 +44,7 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell) if (spell.Action == WatchedAction) { ++NumCasts; - var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1)); + var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1f)); if (index >= 0) { AdvanceLine(Lines[index], caster.Position); diff --git a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Tetraktys.cs b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Tetraktys.cs index 313cac2ea3..5d9db334b0 100644 --- a/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Tetraktys.cs +++ b/BossMod/Modules/Endwalker/Alliance/A31Thaliak/Tetraktys.cs @@ -2,11 +2,11 @@ class TetraktysBorder(BossModule module) : Components.GenericAOEs(module) { - public static readonly WPos NormalCenter = new(-945, 945); - public static readonly ArenaBoundsSquare NormalBounds = new(24); + public static readonly WPos NormalCenter = new(-945f, 945f); + public static readonly ArenaBoundsSquare NormalBounds = new(24f); private static readonly Polygon[] triangle = [new(new(-945, 948.71267f), 27.71281f, 3, 180.Degrees())]; private static readonly ArenaBoundsComplex TriangleBounds = new(triangle); - private static readonly AOEShapeCustom transition = new([new Square(NormalCenter, 24)], triangle); + private static readonly AOEShapeCustom transition = new([new Square(NormalCenter, 24f)], triangle); private AOEInstance? _aoe; public bool Active; @@ -41,8 +41,8 @@ class Tetraktys(BossModule module) : Components.GenericAOEs(module) { public readonly List AOEs = []; - private static readonly AOEShapeTriCone _triSmall = new(16, 30.Degrees()); - private static readonly AOEShapeTriCone _triLarge = new(32, 30.Degrees()); + private static readonly AOEShapeTriCone _triSmall = new(16f, 30f.Degrees()); + private static readonly AOEShapeTriCone _triLarge = new(32f, 30f.Degrees()); private static readonly Angle _rot1 = -0.003f.Degrees(); private static readonly Angle _rot2 = -180.Degrees(); private static readonly Angle _rot3 = 179.995f.Degrees(); @@ -57,43 +57,50 @@ public override void OnEventEnvControl(byte index, uint state) // 5 E // 678 F 10 // 9ABCD - - var _activation = WorldState.FutureTime(3.8f); - if (state == 0x00020001) + void AddAOEs(AOEShapeTriCone shape, ReadOnlySpan positions, ReadOnlySpan rotations) { - if (index == 0x07) //07, 0A, 0D always activate together - { - AOEs.Add(new(_triSmall, new(-929, 948.5f), _rot1, _activation)); - AOEs.Add(new(_triSmall, new(-953, 962.356f), _rot2, _activation)); - AOEs.Add(new(_triSmall, new(-945, 948.5f), _rot2, _activation)); - } - else if (index == 0x05) //05, 08, 0B always activate together + for (var i = 0; i < positions.Length; ++i) { - AOEs.Add(new(_triSmall, new(-945, 948.5f), _rot1, _activation)); - AOEs.Add(new(_triSmall, new(-937, 934.644f), _rot1, _activation)); - AOEs.Add(new(_triSmall, new(-945, 921), _rot1, _activation)); + var pos = positions[i]; + var rot = rotations[i]; + AddAOE(shape, pos, rot); } - else if (index == 0x06) //06, 09, 0C always activate together + } + void AddAOE(AOEShapeTriCone shape, WPos pos, Angle rot) => AOEs.Add(new(shape, WPos.ClampToGrid(pos), rot, WorldState.FutureTime(3.8d))); + + if (state == 0x00020001) + { + switch (index) { - AOEs.Add(new(_triSmall, new(-937, 962.356f), _rot3, _activation)); - AOEs.Add(new(_triSmall, new(-961, 948.5f), _rot1, _activation)); - AOEs.Add(new(_triSmall, new(-953, 934.644f), _rot1, _activation)); + case 0x05: // 05, 08, 0B always activate together + AddAOEs(_triSmall, [new(-945f, 948.5f), new(-937f, 934.644f), new(-945f, 921f)], [_rot1, _rot1, _rot1]); + break; + case 0x06: // 06, 09, 0C always activate together + AddAOEs(_triSmall, [new(-937f, 962.356f), new(-961f, 948.5f), new(-953f, 934.644f)], [_rot3, _rot1, _rot1]); + break; + case 0x07: // 07, 0A, 0D always activate together + AddAOEs(_triSmall, [new(-929f, 948.5f), new(-953f, 962.356f), new(-945f, 948.5f)], [_rot1, _rot2, _rot2]); + break; + case 0x0E: + AddAOE(_triLarge, new(-945f, 921f), _rot1); + break; + case 0x0F: + AddAOE(_triLarge, new(-953, 934.644f), _rot1); + break; + case 0x10: + AddAOE(_triLarge, new(-937, 934.644f), _rot1); + break; } - else if (index == 0x0E) - AOEs.Add(new(_triLarge, new(-945, 921), _rot1, _activation)); - else if (index == 0x0F) - AOEs.Add(new(_triLarge, new(-953, 934.644f), _rot1, _activation)); - else if (index == 0x10) - AOEs.Add(new(_triLarge, new(-937, 934.644f), _rot1, _activation)); } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.TetraktysAOESmall or AID.TetraktysAOELarge) + if (spell.Action.ID is (uint)AID.TetraktysAOESmall or (uint)AID.TetraktysAOELarge) { - AOEs.RemoveAt(0); ++NumCasts; + if (AOEs.Count != 0) + AOEs.RemoveAt(0); } } } @@ -102,54 +109,54 @@ class TetraktuosKosmosCounter(BossModule module) : Components.CastCounter(module class TetraktuosKosmos(BossModule module) : Components.GenericAOEs(module) { - public readonly List AOEs = []; - private static readonly AOEShapeTriCone _shapeTri = new(16, 30.Degrees()); - private static readonly AOEShapeRect _shapeRect = new(30, 8); - private static readonly List Angles = - [-0.003f.Degrees(), -180.Degrees(), 179.995f.Degrees(), 59.995f.Degrees(), -60.Degrees(), - 119.997f.Degrees(), -120.003f.Degrees(), 60.Degrees()]; - - private static readonly List<(AOEShape shape, WPos pos, int angle)> combos = + public readonly List AOEs = new(6); + private static readonly AOEShapeTriCone _shapeTri = new(16f, 30f.Degrees()); + private static readonly AOEShapeRect _shapeRect = new(30f, 8f); + private static readonly Angle[] Angles = + [-0.003f.Degrees(), -180f.Degrees(), 179.995f.Degrees(), 59.995f.Degrees(), -60f.Degrees(), + 119.997f.Degrees(), -120.003f.Degrees(), 60f.Degrees()]; + + private static readonly (AOEShape shape, WPos pos, int angle)[] combos = [ // 0x12 - (_shapeTri, new(-945, 948.5f), 1), - (_shapeRect, new(-945, 935), 1), + (_shapeTri, new(-945f, 948.5f), 1), + (_shapeRect, new(-945f, 935), 1), (_shapeRect, new(-948.827f, 941.828f), 4), (_shapeRect, new(-941.173f, 941.828f), 7), // 0x14 - (_shapeTri, new(-953, 962.356f), 1), - (_shapeRect, new(-949, 955.428f), 3), - (_shapeRect, new(-957, 955.428f), 4), - (_shapeRect, new(-953, 948.5f), 1), + (_shapeTri, new(-953f, 962.356f), 1), + (_shapeRect, new(-949f, 955.428f), 3), + (_shapeRect, new(-957f, 955.428f), 4), + (_shapeRect, new(-953f, 948.5f), 1), // 0x15 - (_shapeTri, new(-937, 962.356f), 2), - (_shapeRect, new(-937, 948.5f), 1), - (_shapeRect, new(-933, 955.428f), 3), - (_shapeRect, new(-941, 955.428f), 4), + (_shapeTri, new(-937f, 962.356f), 2), + (_shapeRect, new(-937f, 948.5f), 1), + (_shapeRect, new(-933f, 955.428f), 3), + (_shapeRect, new(-941f, 955.428f), 4), // pair 0x13 + 0x15 - (_shapeTri, new(-961, 948.7f), 0), - (_shapeTri, new(-937, 962.356f), 2), - (_shapeRect, new(-933, 955.428f), 3), - (_shapeRect, new(-941, 955.428f), 4), - (_shapeRect, new(-937, 948.5f), 1), - (_shapeRect, new(-957, 955.428f), 5), + (_shapeTri, new(-961f, 948.7f), 0), + (_shapeTri, new(-937f, 962.356f), 2), + (_shapeRect, new(-933f, 955.428f), 3), + (_shapeRect, new(-941f, 955.428f), 4), + (_shapeRect, new(-937f, 948.5f), 1), + (_shapeRect, new(-957f, 955.428f), 5), // pair 0x12 + 0x16 - (_shapeTri, new(-945, 948.5f), 1), + (_shapeTri, new(-945f, 948.5f), 1), (_shapeTri, new(-929, 948.7f), 0), - (_shapeRect, new(-933, 955.428f), 6), + (_shapeRect, new(-933f, 955.428f), 6), (_shapeRect, new(-941.173f, 941.828f), 7), (_shapeRect, new(-948.827f, 941.828f), 4), - (_shapeRect, new(-945, 935), 1), + (_shapeRect, new(-945f, 935f), 1), // //pair 0x11 + 0x14 - (_shapeTri, new(-945, 921), 0), - (_shapeTri, new(-953, 962.356f), 1), - (_shapeRect, new(-945, 934.8f), 0), - (_shapeRect, new(-953, 948.5f), 1), - (_shapeRect, new(-957, 955.428f), 4), - (_shapeRect, new(-949, 955.428f), 3) + (_shapeTri, new(-945f, 921f), 0), + (_shapeTri, new(-953f, 962.356f), 1), + (_shapeRect, new(-945f, 934.8f), 0), + (_shapeRect, new(-953f, 948.5f), 1), + (_shapeRect, new(-957f, 955.428f), 4), + (_shapeRect, new(-949f, 955.428f), 3) ]; public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; @@ -166,58 +173,57 @@ public override void OnEventEnvControl(byte index, uint state) if (state != 0x00020001) return; var tutorialDone = Module.FindComponent()?.NumCasts != 0; - var activationTime = WorldState.FutureTime(7.9f); if (!tutorialDone) - HandleTutorial(index, activationTime); + HandleTutorial(index); else - HandleRest(index, activationTime); + HandleRest(index); } - private void HandleTutorial(byte index, DateTime activationTime) + private void HandleTutorial(byte index) { switch (index) { case 0x12: - AddAOEs([0, 1, 2, 3], activationTime); + AddAOEs([0, 1, 2, 3]); break; case 0x14: - AddAOEs([4, 5, 6, 7], activationTime); + AddAOEs([4, 5, 6, 7]); break; case 0x15: - AddAOEs([8, 9, 10, 11], activationTime); + AddAOEs([8, 9, 10, 11]); break; } } - private void HandleRest(byte index, DateTime activationTime) + private void HandleRest(byte index) { switch (index) { case 0x13: - AddAOEs([12, 13, 14, 15, 16, 17], activationTime); + AddAOEs([12, 13, 14, 15, 16, 17]); break; case 0x12: - AddAOEs([18, 19, 20, 21, 22, 23], activationTime); + AddAOEs([18, 19, 20, 21, 22, 23]); break; case 0x11: - AddAOEs([24, 25, 26, 27, 28, 29], activationTime); + AddAOEs([24, 25, 26, 27, 28, 29]); break; } } - private void AddAOEs(int[] indices, DateTime activationTime) + private void AddAOEs(int[] indices) { - foreach (var index in indices) + for (var i = 0; i < indices.Length; ++i) { - var (shape, pos, angle) = combos[index]; - AOEs.Add(new(shape, pos, Angles[angle], activationTime)); + var (shape, pos, angle) = combos[indices[i]]; + AOEs.Add(new(shape, WPos.ClampToGrid(pos), Angles[angle], WorldState.FutureTime(7.9d))); } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.TetraktuosKosmosAOETri) + if (spell.Action.ID == (uint)AID.TetraktuosKosmosAOETri) { AOEs.Clear(); ++NumCasts; diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/A32Llymlaen.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/A32Llymlaen.cs index 43420f8a7a..ce2fd34d6a 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/A32Llymlaen.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/A32Llymlaen.cs @@ -1,20 +1,20 @@ namespace BossMod.Endwalker.Alliance.A32Llymlaen; -class WindRose(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WindRose), 12); -class SeafoamSpiral(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SeafoamSpiral), new AOEShapeDonut(6, 70)); -class DeepDiveNormal(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DeepDiveNormal), 6, 8); -class Stormwhorl(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Stormwhorl), 6); -class Stormwinds(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.Stormwinds), 6); -class Maelstrom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Maelstrom), 6); +class WindRose(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WindRose), 12f); +class SeafoamSpiral(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SeafoamSpiral), new AOEShapeDonut(6f, 70f)); +class DeepDiveNormal(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DeepDiveNormal), 6f, 8); +class Stormwhorl(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Stormwhorl), 6f); +class Stormwinds(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.Stormwinds), 6f); +class Maelstrom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Maelstrom), 6f); class Godsbane(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.GodsbaneAOE)); -class DeepDiveHardWater(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DeepDiveHardWater), 6); +class DeepDiveHardWater(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DeepDiveHardWater), 6f); [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus, LTS", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 11299, SortOrder = 3)] public class A32Llymlaen(WorldState ws, Actor primary) : BossModule(ws, primary, DefaultCenter, DefaultBounds) { - public const float CorridorHalfLength = 40; - public static readonly WPos DefaultCenter = new(0, -900); - public static readonly ArenaBoundsRect DefaultBounds = new(19, 29); + public const float CorridorHalfLength = 40f; + public static readonly WPos DefaultCenter = new(0, -900f); + public static readonly ArenaBoundsRect DefaultBounds = new(19f, 29f); public static readonly ArenaBoundsCustom EastCorridorBounds = BuildCorridorBounds(+1); public static readonly ArenaBoundsCustom WestCorridorBounds = BuildCorridorBounds(-1); diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/NavigatorsTrident.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/NavigatorsTrident.cs index 71f2927f0a..27bcc58ce0 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/NavigatorsTrident.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/NavigatorsTrident.cs @@ -4,7 +4,7 @@ class DireStraits(BossModule module) : Components.GenericAOEs(module) { private readonly List _aoes = new(2); - private static readonly AOEShapeRect _shape = new(40, 40); + private static readonly AOEShapeRect _shape = new(40f, 40f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -25,7 +25,7 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.DireStraitsVisualFirst or AID.DireStraitsVisualSecond) + if (spell.Action.ID is (uint)AID.DireStraitsVisualFirst or (uint)AID.DireStraitsVisualSecond) { _aoes.Add(new(_shape, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell, 4.8f))); } @@ -33,7 +33,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.DireStraitsAOEFirst or AID.DireStraitsAOESecond) + if (spell.Action.ID is (uint)AID.DireStraitsAOEFirst or (uint)AID.DireStraitsAOESecond) { ++NumCasts; if (_aoes.Count != 0) @@ -42,31 +42,31 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) } } -class NavigatorsTridentAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.NavigatorsTridentAOE), new AOEShapeRect(40, 5)); +class NavigatorsTridentAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.NavigatorsTridentAOE), new AOEShapeRect(40f, 5f)); class NavigatorsTridentKnockback(BossModule module) : Components.Knockback(module) { private readonly SerpentsTide? _serpentsTide = module.FindComponent(); - private readonly List _sources = []; + private readonly List _sources = new(2); - private static readonly AOEShapeCone _shape = new(30, 90.Degrees()); + private static readonly AOEShapeCone _shape = new(30f, 90f.Degrees()); public override IEnumerable Sources(int slot, Actor actor) => _sources; public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => !Module.InBounds(pos) || (_serpentsTide?.AOEs.Any(z => z.Check(pos)) ?? false); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.NavigatorsTridentAOE) + if (spell.Action.ID == (uint)AID.NavigatorsTridentAOE) { _sources.Clear(); - _sources.Add(new(spell.LocXZ, 20, Module.CastFinishAt(spell), _shape, spell.Rotation + 90.Degrees(), Kind.DirForward)); - _sources.Add(new(spell.LocXZ, 20, Module.CastFinishAt(spell), _shape, spell.Rotation - 90.Degrees(), Kind.DirForward)); + _sources.Add(new(spell.LocXZ, 20, Module.CastFinishAt(spell), _shape, spell.Rotation + 90f.Degrees(), Kind.DirForward)); + _sources.Add(new(spell.LocXZ, 20, Module.CastFinishAt(spell), _shape, spell.Rotation - 90f.Degrees(), Kind.DirForward)); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.NavigatorsTridentAOE) + if (spell.Action.ID == (uint)AID.NavigatorsTridentAOE) { _sources.Clear(); ++NumCasts; diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SerpentsTide.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SerpentsTide.cs index 4a1c59ec85..d143d0f532 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SerpentsTide.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SerpentsTide.cs @@ -3,19 +3,19 @@ namespace BossMod.Endwalker.Alliance.A32Llymlaen; class SerpentsTide(BossModule module) : Components.GenericAOEs(module) { public readonly List AOEs = []; - private static readonly AOEShapeRect _shape = new(80, 10); + private static readonly AOEShapeRect _shape = new(80f, 10f); public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.SerpentsTide) + if (spell.Action.ID == (uint)AID.SerpentsTide) AOEs.Add(new(_shape, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell))); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.SerpentsTideAOEPerykosNS or AID.SerpentsTideAOEPerykosEW or AID.SerpentsTideAOEThalaosNS or AID.SerpentsTideAOEThalaosEW) + if (spell.Action.ID is (uint)AID.SerpentsTideAOEPerykosNS or (uint)AID.SerpentsTideAOEPerykosEW or (uint)AID.SerpentsTideAOEThalaosNS or (uint)AID.SerpentsTideAOEThalaosEW) { AOEs.Clear(); ++NumCasts; diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SurgingWave.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SurgingWave.cs index 76c17def26..8d0735795a 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SurgingWave.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/SurgingWave.cs @@ -10,21 +10,21 @@ public override void OnEventEnvControl(byte index, uint state) { CorridorDir = state switch { - 0x00800040 => new(-1, 0), - 0x08000400 => new(+1, 0), + 0x00800040 => new(-1f, default), + 0x08000400 => new(1f, default), _ => default }; } } } -class SurgingWaveAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SurgingWaveAOE), 6); -class SurgingWaveShockwave(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.SurgingWaveShockwave), 68, true); +class SurgingWaveAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SurgingWaveAOE), 6f); +class SurgingWaveShockwave(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.SurgingWaveShockwave), 68f, true); class SurgingWaveSeaFoam(BossModule module) : Components.PersistentVoidzone(module, 1.5f, m => m.Enemies(OID.SeaFoam).Where(x => !x.IsDead)); public class SurgingWaveFrothingSea : Components.Exaflare { - public SurgingWaveFrothingSea(BossModule module) : base(module, new AOEShapeRect(6, 20, 80)) + public SurgingWaveFrothingSea(BossModule module) : base(module, new AOEShapeRect(6f, 20f, 80f)) { ImminentColor = Colors.AOE; FutureColor = Colors.Danger; @@ -35,7 +35,7 @@ public class SurgingWaveFrothingSea : Components.Exaflare public override void OnEventEnvControl(byte index, uint state) { - var _activation = WorldState.FutureTime(30); + var _activation = WorldState.FutureTime(30d); if (index == 0x49) { if (state == 0x00800040) @@ -47,7 +47,7 @@ public override void OnEventEnvControl(byte index, uint state) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.SurgingWaveFrothingSea) + if (spell.Action.ID == (uint)AID.SurgingWaveFrothingSea) { ++NumCasts; if (Lines.Count != 0) @@ -60,5 +60,6 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell) } } -class LeftStrait(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LeftStrait), new AOEShapeCone(100, 90.Degrees())); -class RightStrait(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.RightStrait), new AOEShapeCone(100, 90.Degrees())); +abstract class Strait(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(100f, 90f.Degrees())); +class LeftStrait(BossModule module) : Strait(module, AID.LeftStrait); +class RightStrait(BossModule module) : Strait(module, AID.RightStrait); diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/ToTheLast.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/ToTheLast.cs index b979b6276a..d49f27088f 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/ToTheLast.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/ToTheLast.cs @@ -2,7 +2,7 @@ namespace BossMod.Endwalker.Alliance.A32Llymlaen; class ToTheLast(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeRect rect = new(80, 5); + private static readonly AOEShapeRect rect = new(80f, 5f); private readonly List _aoes = new(3); public override IEnumerable ActiveAOEs(int slot, Actor actor) @@ -25,13 +25,13 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.ToTheLastVisual) - _aoes.Add(new(rect, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell, 5 + 1.9f + _aoes.Count))); + if (spell.Action.ID == (uint)AID.ToTheLastVisual) + _aoes.Add(new(rect, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell, 5f + 1.9f * _aoes.Count))); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.ToTheLastAOE) + if (spell.Action.ID == (uint)AID.ToTheLastAOE) { ++NumCasts; if (_aoes.Count != 0) diff --git a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/TorrentialTridents.cs b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/TorrentialTridents.cs index ea5d62fb13..57bed69e7a 100644 --- a/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/TorrentialTridents.cs +++ b/BossMod/Modules/Endwalker/Alliance/A32Llymlaen/TorrentialTridents.cs @@ -27,12 +27,12 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.TorrentialTridentLanding: - AOEs.Add(new(_shape, caster.Position, default, WorldState.FutureTime(13.8f))); + case (uint)AID.TorrentialTridentLanding: + AOEs.Add(new(_shape, caster.Position, default, WorldState.FutureTime(13.8d))); break; - case AID.TorrentialTridentAOE: + case (uint)AID.TorrentialTridentAOE: ++NumCasts; if (AOEs.Count != 0) AOEs.RemoveAt(0); diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/A33Oschon.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/A33Oschon.cs index a418cb0445..8e0f47e488 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/A33Oschon.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/A33Oschon.cs @@ -2,27 +2,27 @@ class P1SuddenDownpour(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.SuddenDownpourAOE)); -class TrekShot(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65, 60.Degrees())); +class TrekShot(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65f, 60f.Degrees())); class P1TrekShotN(BossModule module) : TrekShot(module, AID.TrekShotNAOE); class P1TrekShotS(BossModule module) : TrekShot(module, AID.TrekShotSAOE); -class SoaringMinuet(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65, 135.Degrees())); +class SoaringMinuet(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65f, 135f.Degrees())); class P1SoaringMinuet1(BossModule module) : SoaringMinuet(module, AID.SoaringMinuet1); class P1SoaringMinuet2(BossModule module) : SoaringMinuet(module, AID.SoaringMinuet2); -class P1Arrow(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.ArrowP1AOE), new AOEShapeCircle(6), true); -class P1Downhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DownhillP1AOE), 6); +class P1Arrow(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.ArrowP1AOE), new AOEShapeCircle(6f), true); +class P1Downhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DownhillP1AOE), 6f); class P2MovingMountains(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.MovingMountains)); class P2PeakPeril(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.PeakPeril)); class P2Shockwave(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.Shockwave)); class P2SuddenDownpour(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.P2SuddenDownpourAOE)); -class P2PitonPull(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PitonPullAOE), 22); -class P2Altitude(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AltitudeAOE), 6); -class P2Arrow(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.ArrowP2AOE), new AOEShapeCircle(10), true); +class P2PitonPull(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PitonPullAOE), 22f); +class P2Altitude(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AltitudeAOE), 6f); +class P2Arrow(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.ArrowP2AOE), new AOEShapeCircle(10f), true); [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus, LTS", PrimaryActorOID = (uint)OID.BossP1, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 11300, SortOrder = 4)] -public class A33Oschon(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, 750), new ArenaBoundsSquare(25)) +public class A33Oschon(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, 750), new ArenaBoundsSquare(25f)) { private Actor? _bossP2; @@ -33,7 +33,7 @@ protected override void UpdateModule() { // TODO: this is an ugly hack, think how multi-actor fights can be implemented without it... // the problem is that on wipe, any actor can be deleted and recreated in the same frame - _bossP2 ??= StateMachine.ActivePhaseIndex == 1 ? Enemies(OID.BossP2).FirstOrDefault() : null; + _bossP2 ??= StateMachine.ActivePhaseIndex == 1 ? Enemies(OID.BossP2)[0] : null; } protected override void DrawEnemies(int pcSlot, Actor pc) diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/FlintedFoehn.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/FlintedFoehn.cs index 96e1b431dd..8f9295b8e1 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/FlintedFoehn.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/FlintedFoehn.cs @@ -1,12 +1,12 @@ namespace BossMod.Endwalker.Alliance.A33Oschon; -class P1FlintedFoehn(BossModule module) : Components.UniformStackSpread(module, 6, 0, 8) +class P1FlintedFoehn(BossModule module) : Components.UniformStackSpread(module, 6f, default, 8) { - public int NumCasts { get; private set; } + public int NumCasts; public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.FlintedFoehnP1AOE) + if (spell.Action.ID == (uint)AID.FlintedFoehnP1AOE) ++NumCasts; } @@ -17,19 +17,19 @@ public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) } } -class P2FlintedFoehn(BossModule module) : Components.UniformStackSpread(module, 8, 0, 8) +class P2FlintedFoehn(BossModule module) : Components.UniformStackSpread(module, 8f, default, 8) { - public int NumCasts { get; private set; } + public int NumCasts; public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.FlintedFoehnP2AOE) + if (spell.Action.ID == (uint)AID.FlintedFoehnP2AOE) ++NumCasts; } public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) { if (iconID == (uint)IconID.FlintedFoehn) - AddStack(actor, WorldState.FutureTime(5.1f)); + AddStack(actor, WorldState.FutureTime(5.1d)); } } diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1ClimbingShot.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1ClimbingShot.cs index c72e223046..738060d4b3 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1ClimbingShot.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1ClimbingShot.cs @@ -10,13 +10,13 @@ class P1ClimbingShot(BossModule module) : Components.Knockback(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.ClimbingShot1 or AID.ClimbingShot2 or AID.ClimbingShot3 or AID.ClimbingShot4) - _knockback = new(Module.PrimaryActor.Position, 20, Module.CastFinishAt(spell)); + if (spell.Action.ID is (uint)AID.ClimbingShot1 or (uint)AID.ClimbingShot2 or (uint)AID.ClimbingShot3 or (uint)AID.ClimbingShot4) + _knockback = new(spell.LocXZ, 20f, Module.CastFinishAt(spell)); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.ClimbingShot1 or AID.ClimbingShot2 or AID.ClimbingShot3 or AID.ClimbingShot4) + if (spell.Action.ID is (uint)AID.ClimbingShot1 or (uint)AID.ClimbingShot2 or (uint)AID.ClimbingShot3 or (uint)AID.ClimbingShot4) _knockback = null; } } diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1SwingingDraw.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1SwingingDraw.cs index 42f6a93d24..affcf6c717 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1SwingingDraw.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P1SwingingDraw.cs @@ -3,22 +3,22 @@ class P1SwingingDraw(BossModule module) : Components.GenericAOEs(module, ActionID.MakeSpell(AID.SwingingDrawAOE)) { public readonly List AOEs = []; - private static readonly AOEShapeCone _shape = new(60, 60.Degrees()); + private static readonly AOEShapeCone _shape = new(60f, 60f.Degrees()); public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - var dir = (AID)spell.Action.ID switch + var dir = spell.Action.ID switch { - AID.SwingingDrawCW => -45.Degrees(), - AID.SwingingDrawCCW => 45.Degrees(), + (uint)AID.SwingingDrawCW => -45f.Degrees(), + (uint)AID.SwingingDrawCCW => 45f.Degrees(), _ => default }; if (dir != default) { dir += Angle.FromDirection(caster.Position - Arena.Center); - AOEs.Add(new(_shape, Arena.Center + 25 * dir.ToDirection(), dir + 180.Degrees(), Module.CastFinishAt(spell, 6.2f))); + AOEs.Add(new(_shape, WPos.ClampToGrid(Arena.Center + 25 * dir.ToDirection()), dir + 180.Degrees(), Module.CastFinishAt(spell, 6.2f))); } } } diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2ArrowTrail.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2ArrowTrail.cs index 2341b77c5c..22d1977ca1 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2ArrowTrail.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2ArrowTrail.cs @@ -1,19 +1,19 @@ namespace BossMod.Endwalker.Alliance.A33Oschon; -class P2ArrowTrail(BossModule module) : Components.Exaflare(module, new AOEShapeRect(10, 5)) +class P2ArrowTrail(BossModule module) : Components.Exaflare(module, new AOEShapeRect(10f, 5f)) { public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.ArrowTrailHint) - Lines.Add(new() { Next = spell.LocXZ, Advance = 5 * caster.Rotation.ToDirection(), NextExplosion = Module.CastFinishAt(spell, 0.4f), TimeToMove = 0.5f, ExplosionsLeft = 8, MaxShownExplosions = 3 }); + if (spell.Action.ID == (uint)AID.ArrowTrailHint) + Lines.Add(new() { Next = caster.Position, Advance = 5 * caster.Rotation.ToDirection(), NextExplosion = Module.CastFinishAt(spell, 0.4f), TimeToMove = 0.5f, ExplosionsLeft = 8, MaxShownExplosions = 3 }); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.ArrowTrailAOE) + if (spell.Action.ID == (uint)AID.ArrowTrailAOE) { ++NumCasts; - var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1)); + var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1f)); if (index >= 0) { AdvanceLine(Lines[index], caster.Position); @@ -24,4 +24,4 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell) } } -class P2DownhillArrowTrailDownhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArrowTrailDownhill), 6); +class P2DownhillArrowTrailDownhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArrowTrailDownhill), 6f); diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingShot.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingShot.cs index eef070608d..bd6179f326 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingShot.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingShot.cs @@ -3,16 +3,16 @@ namespace BossMod.Endwalker.Alliance.A33Oschon; class P2WanderingShot(BossModule module) : Components.GenericAOEs(module, ActionID.MakeSpell(AID.GreatWhirlwind)) { private AOEInstance? _aoe; - private static readonly AOEShapeCircle _shape = new(23); + private static readonly AOEShapeCircle _shape = new(23f); public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - WPos coords = (AID)spell.Action.ID switch + var coords = spell.Action.ID switch { - AID.WanderingShotN or AID.WanderingVolleyN => new(-0.015f, 739.986f), - AID.WanderingShotS or AID.WanderingVolleyS => new(-0.015f, 759.975f), + (uint)AID.WanderingShotN or (uint)AID.WanderingVolleyN => WPos.ClampToGrid(new(0f, 740f)), + (uint)AID.WanderingShotS or (uint)AID.WanderingVolleyS => WPos.ClampToGrid(new(0f, 760f)), _ => default }; if (coords != default) diff --git a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingVolley.cs b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingVolley.cs index c5cc30e224..a08ec1857d 100644 --- a/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingVolley.cs +++ b/BossMod/Modules/Endwalker/Alliance/A33Oschon/P2WanderingVolley.cs @@ -1,24 +1,24 @@ namespace BossMod.Endwalker.Alliance.A33Oschon; -class P2WanderingVolleyDownhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WanderingVolleyDownhillAOE), 8); +class P2WanderingVolleyDownhill(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WanderingVolleyDownhillAOE), 8f); class P2WanderingVolleyKnockback(BossModule module) : Components.Knockback(module) { private readonly P2WanderingVolleyDownhill? _downhill = module.FindComponent(); private readonly List _sources = []; - private static readonly AOEShapeCone _shape = new(30, 90.Degrees()); + private static readonly AOEShapeCone _shape = new(30f, 90f.Degrees()); public override IEnumerable Sources(int slot, Actor actor) => _sources; public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => !Module.InBounds(pos) || (_downhill?.ActiveAOEs(slot, actor).Any(z => z.Check(pos)) ?? false); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.WanderingVolleyN or AID.WanderingVolleyS) + if (spell.Action.ID is (uint)AID.WanderingVolleyN or (uint)AID.WanderingVolleyS) { _sources.Clear(); // happens through center, so create two sources with origin at center looking orthogonally - _sources.Add(new(Module.Center, 12, Module.CastFinishAt(spell), _shape, spell.Rotation + 90.Degrees(), Kind.DirForward)); - _sources.Add(new(Module.Center, 12, Module.CastFinishAt(spell), _shape, spell.Rotation - 90.Degrees(), Kind.DirForward)); + _sources.Add(new(Arena.Center, 12f, Module.CastFinishAt(spell), _shape, spell.Rotation + 90f.Degrees(), Kind.DirForward)); + _sources.Add(new(Arena.Center, 12f, Module.CastFinishAt(spell), _shape, spell.Rotation - 90f.Degrees(), Kind.DirForward)); } } } @@ -26,19 +26,19 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) class P2WanderingVolleyAOE(BossModule module) : Components.GenericAOEs(module) { private AOEInstance? _aoe; - private static readonly AOEShapeRect _shape = new(40, 5); + private static readonly AOEShapeRect _shape = new(40f, 5f); public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.WanderingVolleyN or AID.WanderingVolleyS) + if (spell.Action.ID is (uint)AID.WanderingVolleyN or (uint)AID.WanderingVolleyS) _aoe = new(_shape, caster.Position, spell.Rotation, Module.CastFinishAt(spell)); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.WanderingVolleyN or AID.WanderingVolleyS) + if (spell.Action.ID is (uint)AID.WanderingVolleyN or (uint)AID.WanderingVolleyS) { _aoe = null; ++NumCasts; diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/A34Eulogia.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/A34Eulogia.cs index 92068fbe4e..c6e6bbdae1 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/A34Eulogia.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/A34Eulogia.cs @@ -2,12 +2,12 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; class ArenaChanges(BossModule module) : Components.GenericAOEs(module) { - public static readonly WPos Center = new(945, -945); - private static readonly ArenaBoundsSquare squareBounds = new(24); - private static readonly ArenaBoundsCircle smallerBounds = new(30); - public static readonly ArenaBoundsCircle BigBounds = new(35); - private static readonly AOEShapeCustom transitionSquare = new([new Circle(Center, 30)], [new Square(Center, 24)]); - private static readonly AOEShapeDonut transitionSmallerBounds = new(30, 35); + public static readonly WPos Center = new(945f, -945f); + private static readonly ArenaBoundsSquare squareBounds = new(24f); + private static readonly ArenaBoundsCircle smallerBounds = new(30f); + public static readonly ArenaBoundsCircle BigBounds = new(35f); + private static readonly AOEShapeCustom transitionSquare = new([new Square(Center, 30f)], [new Square(Center, 24f)]); + private static readonly AOEShapeDonut transitionSmallerBounds = new(30f, 35f); private AOEInstance? _aoe; public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); @@ -25,20 +25,20 @@ public override void OnEventEnvControl(byte index, uint state) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.Hieroglyphika) + if (spell.Action.ID == (uint)AID.Hieroglyphika) _aoe = new(transitionSquare, Center, default, Module.CastFinishAt(spell)); - else if ((AID)spell.Action.ID == AID.Whorl) + else if (spell.Action.ID == (uint)AID.Whorl) _aoe = new(transitionSmallerBounds, Center, default, Module.CastFinishAt(spell)); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.Hieroglyphika) + if (spell.Action.ID == (uint)AID.Hieroglyphika) { Arena.Bounds = squareBounds; _aoe = null; } - else if ((AID)spell.Action.ID == AID.Whorl) + else if (spell.Action.ID == (uint)AID.Whorl) { Arena.Bounds = smallerBounds; _aoe = null; @@ -46,14 +46,14 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) } } -class Sunbeam(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.SunbeamAOE), new AOEShapeCircle(6), true); -class DestructiveBolt(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DestructiveBoltAOE), 6, 8); +class Sunbeam(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.SunbeamAOE), new AOEShapeCircle(6f), true); +class DestructiveBolt(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.DestructiveBoltAOE), 6f, 8); -class HoD(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(90, 20)); +class HoD(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(90f, 20f)); class HandOfTheDestroyerWrath(BossModule module) : HoD(module, AID.HandOfTheDestroyerWrathAOE); class HandOfTheDestroyerJudgment(BossModule module) : HoD(module, AID.HandOfTheDestroyerJudgmentAOE); -class SoaringMinuet(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SoaringMinuet), new AOEShapeCone(40, 135.Degrees())); +class SoaringMinuet(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SoaringMinuet), new AOEShapeCone(40f, 135f.Degrees())); class EudaimonEorzea(BossModule module) : Components.CastCounter(module, ActionID.MakeSpell(AID.EudaimonEorzeaAOE)); [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus, LTS", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 962, NameID = 11301, SortOrder = 7)] diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/AsAboveSoBelow.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/AsAboveSoBelow.cs index a33fbff812..ecd0f2bd3a 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/AsAboveSoBelow.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/AsAboveSoBelow.cs @@ -1,16 +1,16 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; -class AsAboveSoBelow(BossModule module) : Components.Exaflare(module, 6) +class AsAboveSoBelow(BossModule module) : Components.Exaflare(module, 6f) { public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.EverfireFirst or AID.OnceBurnedFirst) + if (spell.Action.ID is (uint)AID.EverfireFirst or (uint)AID.OnceBurnedFirst) { var advance = 6 * spell.Rotation.ToDirection(); - var pos = spell.LocXZ; + var pos = caster.Position; var activation = Module.CastFinishAt(spell); // outer lines have 4 explosion only, rest 5 - var numExplosions = (pos - Arena.Center).LengthSq() > 500 ? 4 : 6; + var numExplosions = (pos - Arena.Center).LengthSq() > 500f ? 4 : 6; Lines.Add(new() { Next = pos, Advance = advance, NextExplosion = activation, TimeToMove = 1.5f, ExplosionsLeft = numExplosions, MaxShownExplosions = 5 }); Lines.Add(new() { Next = pos, Advance = -advance, NextExplosion = activation, TimeToMove = 1.5f, ExplosionsLeft = numExplosions, MaxShownExplosions = 5 }); } @@ -18,17 +18,17 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.EverfireFirst: - case AID.OnceBurnedFirst: + case (uint)AID.EverfireFirst: + case (uint)AID.OnceBurnedFirst: var dir = caster.Rotation.ToDirection(); Advance(caster.Position, dir); Advance(caster.Position, -dir); ++NumCasts; break; - case AID.EverfireRest: - case AID.OnceBurnedRest: + case (uint)AID.EverfireRest: + case (uint)AID.OnceBurnedRest: Advance(caster.Position, caster.Rotation.ToDirection()); ++NumCasts; break; @@ -37,7 +37,7 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell) private void Advance(WPos position, WDir dir) { - var index = Lines.FindIndex(item => item.Next.AlmostEqual(position, 1) && item.Advance.Dot(dir) > 5); + var index = Lines.FindIndex(item => item.Next.AlmostEqual(position, 1f) && item.Advance.Dot(dir) > 5f); if (index == -1) { ReportError($"Failed to find entry for {position} / {dir}"); diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ByregotStrike.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ByregotStrike.cs index f685970acb..ac4e711736 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ByregotStrike.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ByregotStrike.cs @@ -1,5 +1,5 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; -class ByregotStrikeJump(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ByregotStrike), 8); -class ByregotStrikeKnockback(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.ByregotStrikeKnockback), 20); -class ByregotStrikeCone(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ByregotStrikeAOE), new AOEShapeCone(90, 22.5f.Degrees())); +class ByregotStrikeJump(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ByregotStrike), 8f); +class ByregotStrikeKnockback(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.ByregotStrikeKnockback), 20f); +class ByregotStrikeCone(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ByregotStrikeAOE), new AOEShapeCone(90f, 22.5f.Degrees())); diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ClimbingShot.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ClimbingShot.cs index ffeab5aa67..24bd924551 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ClimbingShot.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ClimbingShot.cs @@ -10,13 +10,13 @@ class ClimbingShot(BossModule module) : Components.Knockback(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.ClimbingShotNald or AID.ClimbingShotThal) - _knockback = new(Module.PrimaryActor.Position, 20, Module.CastFinishAt(spell, 0.2f)); + if (spell.Action.ID is (uint)AID.ClimbingShotNald or (uint)AID.ClimbingShotThal) + _knockback = new(spell.LocXZ, 20f, Module.CastFinishAt(spell, 0.2f)); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.ClimbingShotAOE1 or AID.ClimbingShotAOE2 or AID.ClimbingShotAOE3 or AID.ClimbingShotAOE4) + if (spell.Action.ID is (uint)AID.ClimbingShotAOE1 or (uint)AID.ClimbingShotAOE2 or (uint)AID.ClimbingShotAOE3 or (uint)AID.ClimbingShotAOE4) { ++NumCasts; _knockback = null; diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hieroglyphika.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hieroglyphika.cs index bb24c2d3d7..53d721bc7c 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hieroglyphika.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hieroglyphika.cs @@ -7,38 +7,38 @@ class Hieroglyphika(BossModule module) : Components.GenericAOEs(module, ActionID public bool BindsAssigned; public readonly List AOEs = []; - private static readonly AOEShapeRect _shape = new(12, 6); - private static readonly WDir[] _canonicalSafespots = [new(-18, 18), new(18, -6)]; + private static readonly AOEShapeRect _shape = new(12f, 6f); + private static readonly WDir[] _canonicalSafespots = [new(-18f, 18f), new(18f, -6f)]; public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.Bind) + if (status.ID == (uint)SID.Bind) BindsAssigned = true; } public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) { - WDir dir = (IconID)iconID switch + WDir dir = iconID switch { - IconID.HieroglyphikaCW => new(-1, 0), - IconID.HieroglyphikaCCW => new(1, 0), + (uint)IconID.HieroglyphikaCW => new(-1f, 0f), + (uint)IconID.HieroglyphikaCCW => new(1f, 0f), _ => default }; if (dir == default) return; WDir[] safespots = [.. _canonicalSafespots.Select(d => d.Rotate(dir))]; - var activation = WorldState.FutureTime(17.1f); + var activation = WorldState.FutureTime(17.1d); for (var z = -3; z <= 3; z += 2) { for (var x = -3; x <= 3; x += 2) { - var cellOffset = new WDir(x * 6, z * 6); - if (!safespots.Any(s => s.AlmostEqual(cellOffset, 1))) + var cellOffset = new WDir(x * 6f, z * 6f); + if (!safespots.Any(s => s.AlmostEqual(cellOffset, 1f))) { - AOEs.Add(new(_shape, Arena.Center + cellOffset + new WDir(0, 6), 180.Degrees(), activation)); + AOEs.Add(new(_shape, WPos.ClampToGrid(Arena.Center + cellOffset + new WDir(0f, 6f)), 180f.Degrees(), activation)); } } } @@ -49,7 +49,7 @@ public override void OnEventCast(Actor caster, ActorCastEvent spell) if (spell.Action == WatchedAction) { ++NumCasts; - var cnt = AOEs.RemoveAll(aoe => aoe.Origin.AlmostEqual(caster.Position, 1)); + var cnt = AOEs.RemoveAll(aoe => aoe.Origin.AlmostEqual(caster.Position, 1f)); if (cnt != 1) ReportError($"Incorrect AOE prediction: {caster.Position} matched {cnt} aoes"); } diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hydrostasis.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hydrostasis.cs index 59e02edff1..b9caead0c3 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hydrostasis.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Hydrostasis.cs @@ -8,7 +8,7 @@ class Hydrostasis(BossModule module) : Components.Knockback(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.HydrostasisAOE1 or AID.HydrostasisAOE2 or AID.HydrostasisAOE3) + if (spell.Action.ID is (uint)AID.HydrostasisAOE1 or (uint)AID.HydrostasisAOE2 or (uint)AID.HydrostasisAOE3) { _sources.Add(new(caster.Position, 28, Module.CastFinishAt(spell))); _sources.SortBy(x => x.Activation); @@ -17,7 +17,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.HydrostasisAOE1 or AID.HydrostasisAOE2 or AID.HydrostasisAOE3) + if (spell.Action.ID is (uint)AID.HydrostasisAOE1 or (uint)AID.HydrostasisAOE2 or (uint)AID.HydrostasisAOE3) { ++NumCasts; if (_sources.Count != 0) diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/LovesLight.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/LovesLight.cs index 99f6b6aa2d..51dfb08c52 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/LovesLight.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/LovesLight.cs @@ -2,8 +2,8 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; class LovesLight(BossModule module) : Components.GenericAOEs(module) { - public readonly List AOEs = []; - private static readonly AOEShapeRect _shape = new(80, 12.5f); + public readonly List AOEs = new(4); + private static readonly AOEShapeRect _shape = new(80f, 12.5f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -11,21 +11,21 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (count == 0) return []; var max = count > 2 ? 2 : count; - List aoes = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) { var aoe = AOEs[i]; if (i == 0) - aoes.Add(count > 1 ? aoe with { Color = Colors.Danger } : aoe); + aoes[i] = count > 1 ? aoe with { Color = Colors.Danger } : aoe; else - aoes.Add(aoe); + aoes[i] = aoe; } return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.FirstBlush1 or AID.FirstBlush2 or AID.FirstBlush3 or AID.FirstBlush4) + if (spell.Action.ID is (uint)AID.FirstBlush1 or (uint)AID.FirstBlush2 or (uint)AID.FirstBlush3 or (uint)AID.FirstBlush4) { AOEs.Add(new(_shape, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell))); AOEs.SortBy(x => x.Activation); @@ -34,7 +34,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.FirstBlush1 or AID.FirstBlush2 or AID.FirstBlush3 or AID.FirstBlush4) + if (spell.Action.ID is (uint)AID.FirstBlush1 or (uint)AID.FirstBlush2 or (uint)AID.FirstBlush3 or (uint)AID.FirstBlush4) { ++NumCasts; if (AOEs.Count > 0) diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/MatronsBreath.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/MatronsBreath.cs index dee5656fbb..0f25e26e64 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/MatronsBreath.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/MatronsBreath.cs @@ -2,33 +2,35 @@ class MatronsBreath(BossModule module) : Components.GenericAOEs(module) { - private readonly List _blueSafe = module.Enemies(OID.BlueSafeZone); - private readonly List _goldSafe = module.Enemies(OID.GoldSafeZone); + private readonly List _blueSafe = module.Enemies((uint)OID.BlueSafeZone); + private readonly List _goldSafe = module.Enemies((uint)OID.GoldSafeZone); private readonly List _flowers = []; - private static readonly AOEShapeDonut _shape = new(8, 50); + private static readonly AOEShapeDonut _shape = new(8f, 50f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (_flowers.Count != 0) - yield return _flowers[0]; + return [_flowers[0]]; + else + return []; } public override void OnActorCreated(Actor actor) { - var safezone = (OID)actor.OID switch + var safezone = actor.OID switch { - OID.BlueFlowers => _blueSafe.FirstOrDefault(), - OID.GoldFlowers => _goldSafe.FirstOrDefault(), + (uint)OID.BlueFlowers => _blueSafe[0], + (uint)OID.GoldFlowers => _goldSafe[0], _ => null }; if (safezone != null) - _flowers.Add(new(_shape, safezone.Position, default, WorldState.FutureTime(11))); + _flowers.Add(new(_shape, safezone.Position, default, WorldState.FutureTime(11d))); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.Blueblossoms or AID.Giltblossoms) + if (spell.Action.ID is (uint)AID.Blueblossoms or (uint)AID.Giltblossoms) { ++NumCasts; if (_flowers.Count != 0) diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Quintessence.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Quintessence.cs index 4bbe6b1780..d8994f0d77 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Quintessence.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/Quintessence.cs @@ -45,14 +45,14 @@ public override void OnEventEnvControl(byte index, uint state) WDir offset = index switch { - 0x4C or 0x53 or 0x56 => new(8.979f, 8.996f), - 0x4D or 0x50 or 0x55 => new(-9.027f, 8.996f), - 0x4E or 0x52 or 0x57 => new(-9.027f, -9.009f), - 0x4F or 0x51 or 0x54 => new(8.979f, -9.009f), + 0x4C or 0x53 or 0x56 => new(9f, 9f), + 0x4D or 0x50 or 0x55 => new(-9f, 9f), + 0x4E or 0x52 or 0x57 => new(-9f, -9f), + 0x4F or 0x51 or 0x54 => new(9f, -9f), _ => default }; _index = index; - position = Arena.Center + offset; + position = WPos.ClampToGrid(Arena.Center + offset); } public override void OnCastStarted(Actor caster, ActorCastInfo spell) diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/SolarFans.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/SolarFans.cs index 5489d26245..c73d917de7 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/SolarFans.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/SolarFans.cs @@ -1,56 +1,50 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; -class SolarFans(BossModule module) : Components.ChargeAOEs(module, ActionID.MakeSpell(AID.SolarFansAOE), 5); +class SolarFans(BossModule module) : Components.ChargeAOEs(module, ActionID.MakeSpell(AID.SolarFansAOE), 5f); class RadiantRhythm(BossModule module) : Components.GenericAOEs(module) { private Angle _nextAngle; private DateTime _activation; - private static readonly AOEShapeDonutSector _shape = new(20, 30, 45.Degrees()); + private static readonly AOEShapeDonutSector _shape = new(20f, 30f, 45f.Degrees()); public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (_activation == default) - yield break; + return []; + var aoes = new AOEInstance[2]; + var center = Arena.Center; // assumption: we always have 4 moves if (NumCasts < 8) { - yield return new(_shape, Arena.Center, _nextAngle, _activation, Colors.Danger); - yield return new(_shape, Arena.Center, _nextAngle + 180.Degrees(), _activation, Colors.Danger); + aoes[0] = new(_shape, center, _nextAngle, _activation, Colors.Danger); + aoes[1] = new(_shape, center, _nextAngle + 180f.Degrees(), _activation, Colors.Danger); } if (NumCasts < 6) { - var future = _activation.AddSeconds(2.1f); - yield return new(_shape, Arena.Center, _nextAngle + 90.Degrees(), future); - yield return new(_shape, Arena.Center, _nextAngle - 90.Degrees(), future); + var future = _activation.AddSeconds(2.1d); + aoes[0] = new(_shape, center, _nextAngle + 90f.Degrees(), future); + aoes[1] = new(_shape, center, _nextAngle - 90f.Degrees(), future); } + return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - switch ((AID)spell.Action.ID) + if (spell.Action.ID == (uint)AID.SolarFansAOE) { - case AID.SolarFansAOE: - // assumption: flames always move CCW - var startingAngle = Angle.FromDirection(spell.LocXZ - Arena.Center); - if (_nextAngle != default && !_nextAngle.AlmostEqual(startingAngle + 45.Degrees(), 0.1f) && !_nextAngle.AlmostEqual(startingAngle - 135.Degrees(), 0.1f)) - ReportError($"Inconsistent starting angle: {_nextAngle} -> {startingAngle}"); - NumCasts = 0; - _nextAngle = startingAngle + 45.Degrees(); - _activation = Module.CastFinishAt(spell, 2.8f); - break; - case AID.RadiantFlight: - // verify our assumption - if (!spell.Rotation.AlmostEqual(_nextAngle, 0.1f) && !spell.Rotation.AlmostEqual(_nextAngle + 180.Degrees(), 0.1f)) - ReportError($"Unexpected angle: {spell.Rotation} vs {_nextAngle}"); - break; + // assumption: flames always move CCW + var startingAngle = Angle.FromDirection(spell.LocXZ - Arena.Center); + NumCasts = 0; + _nextAngle = startingAngle + 45f.Degrees(); + _activation = Module.CastFinishAt(spell, 2.8f); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.RadiantFlight) + if (spell.Action.ID == (uint)AID.RadiantFlight) { ++NumCasts; if (NumCasts == 8) @@ -60,8 +54,8 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) } else if ((NumCasts & 1) == 0) { - _nextAngle += 90.Degrees(); - _activation = WorldState.FutureTime(2.1f); + _nextAngle += 90f.Degrees(); + _activation = WorldState.FutureTime(2.1d); } } } diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ThousandfoldThrust.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ThousandfoldThrust.cs index 42a30eb4be..346dfa8735 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ThousandfoldThrust.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/ThousandfoldThrust.cs @@ -3,19 +3,19 @@ class ThousandfoldThrust(BossModule module) : Components.GenericAOEs(module) { private AOEInstance? _aoe; - private static readonly AOEShapeCone _shape = new(60, 90.Degrees()); + private static readonly AOEShapeCone _shape = new(60f, 90f.Degrees()); public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.ThousandfoldThrustAOEFirst) + if (spell.Action.ID == (uint)AID.ThousandfoldThrustAOEFirst) _aoe = new(_shape, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell)); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.ThousandfoldThrustAOEFirst or AID.ThousandfoldThrustAOERest) + if (spell.Action.ID is (uint)AID.ThousandfoldThrustAOEFirst or (uint)AID.ThousandfoldThrustAOERest) { ++NumCasts; _aoe = null; diff --git a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/TorrentialTridents.cs b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/TorrentialTridents.cs index e42ead8f5f..03df8c8499 100644 --- a/BossMod/Modules/Endwalker/Alliance/A34Eulogia/TorrentialTridents.cs +++ b/BossMod/Modules/Endwalker/Alliance/A34Eulogia/TorrentialTridents.cs @@ -3,7 +3,7 @@ namespace BossMod.Endwalker.Alliance.A34Eulogia; class TorrentialTrident(BossModule module) : Components.GenericAOEs(module) { public readonly List AOEs = new(6); - private static readonly AOEShapeCircle _shape = new(18); + private static readonly AOEShapeCircle _shape = new(18f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -11,28 +11,28 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (count == 0) return []; var max = count > 5 ? 5 : count; - List aoes = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) { var aoe = AOEs[i]; if (i == 0) - aoes.Add(count > 1 ? aoe with { Color = Colors.Danger } : aoe); + aoes[i] = count > 1 ? aoe with { Color = Colors.Danger } : aoe; else - aoes.Add(aoe); + aoes[i] = aoe; } return aoes; } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.TorrentialTridentLanding: - AOEs.Add(new(_shape, caster.Position, default, WorldState.FutureTime(13.6f))); + case (uint)AID.TorrentialTridentLanding: + AOEs.Add(new(_shape, WPos.ClampToGrid(caster.Position), default, WorldState.FutureTime(13.6d))); break; - case AID.LightningBolt: + case (uint)AID.LightningBolt: ++NumCasts; - if (AOEs.Count > 0) + if (AOEs.Count != 0) AOEs.RemoveAt(0); break; } diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD10Gancanagh.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD10Gancanagh.cs index 4f4e9396de..a0c2db9353 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD10Gancanagh.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD10Gancanagh.cs @@ -15,9 +15,9 @@ public enum AID : uint Mandrastorm = 31479 // Boss->self, 5.0s cast, range 60 circle, damage fall off AOE } -class MandraStorm(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrastorm), 20); -class Mandrashock1(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrashock1), 10); -class Mandrashock2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrashock2), 10, 6); +class MandraStorm(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrastorm), 20f); +class Mandrashock1(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrashock1), 10f); +class Mandrashock2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Mandrashock2), 10f, 6); class DD10GancanaghStates : StateMachineBuilder { @@ -31,4 +31,4 @@ public DD10GancanaghStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 897, NameID = 12240)] -public class DD10Gancanagh(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -300), new ArenaBoundsSquare(19.5f)); +public class DD10Gancanagh(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300f, -300f), new ArenaBoundsSquare(19.5f)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs index 30d479fa6c..56250127e6 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs @@ -24,8 +24,8 @@ public enum AID : uint class FlameBreath(BossModule module) : Components.GenericAOEs(module) { private readonly List _aoes = new(5); - private static readonly AOEShapeCone cone = new(50, 15.Degrees()); - private static readonly float intercardinalDistance = 16 * MathF.Sqrt(2); + private static readonly AOEShapeCone cone = new(50f, 15f.Degrees()); + private const float IntercardinalDistance = 22.627417f; public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -38,7 +38,7 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) for (var i = 0; i < count; ++i) { var a = _aoes[i]; - if ((a.Activation - firstact).TotalSeconds < 1) + if ((a.Activation - firstact).TotalSeconds < 1d) aoes.Add(a); } return aoes; @@ -46,29 +46,31 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.FlameBreathVisual3) + if (spell.Action.ID == (uint)AID.FlameBreathVisual3) { - var activation = WorldState.FutureTime(9.6f); + var activation = WorldState.FutureTime(9.6d); - if ((caster.Position - Arena.Center).LengthSq() > 625) - _aoes.Add(new(cone, CalculatePosition(caster), caster.Rotation, activation)); + if ((caster.Position - Arena.Center).LengthSq() > 625f) + _aoes.Add(new(cone, WPos.ClampToGrid(CalculatePosition(caster)), caster.Rotation, activation)); else - _aoes.Add(new(cone, RoundPosition(caster.Position), caster.Rotation, activation)); + _aoes.Add(new(cone, WPos.ClampToGrid(RoundPosition(caster.Position)), caster.Rotation, activation)); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (_aoes.Count != 0 && (AID)spell.Action.ID == AID.FlameBreath) + if (_aoes.Count != 0 && spell.Action.ID == (uint)AID.FlameBreath) _aoes.RemoveAt(0); } private static WPos CalculatePosition(Actor caster) { var isIntercardinal = IsCasterIntercardinal(caster); - var distance = isIntercardinal ? intercardinalDistance : 22; + var distance = isIntercardinal ? IntercardinalDistance : 22; var position = caster.Position + distance * caster.Rotation.ToDirection(); - return RoundPosition(position); + var pos = RoundPosition(position); + // the top left add is slightly off for some reason + return pos == new WPos(-315f, -315f) ? new(-315.5f, -315.5f) : pos; } private static bool IsCasterIntercardinal(Actor caster) @@ -82,7 +84,7 @@ private static bool IsCasterIntercardinal(Actor caster) private static WPos RoundPosition(WPos position) => new(MathF.Round(position.X * 2) * 0.5f, MathF.Round(position.Z * 2) * 0.5f); } -class PiercingLaser(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PiercingLaser), new AOEShapeRect(40, 2.5f)); +class PiercingLaser(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PiercingLaser), new AOEShapeRect(40f, 2.5f)); class DD20CloningNodeStates : StateMachineBuilder { @@ -95,4 +97,4 @@ public DD20CloningNodeStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 898, NameID = 12261)] -public class DD20CloningNode(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -300), new ArenaBoundsCircle(19.5f)); +public class DD20CloningNode(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300f, -300f), new ArenaBoundsCircle(19.5f)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD30TiamatsClone.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD30TiamatsClone.cs index 164bcc3e17..1aa14abf69 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD30TiamatsClone.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD30TiamatsClone.cs @@ -28,13 +28,13 @@ public enum IconID : uint ChasingAOE = 197 // player } -class WheiMorn(BossModule module) : Components.StandardChasingAOEs(module, new AOEShapeCircle(6), ActionID.MakeSpell(AID.WheiMornFirst), ActionID.MakeSpell(AID.WheiMornRest), 6, 2, 5, true, (uint)IconID.ChasingAOE); -class DarkMegaflare(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DarkMegaflare), 6); +class WheiMorn(BossModule module) : Components.StandardChasingAOEs(module, new AOEShapeCircle(6f), ActionID.MakeSpell(AID.WheiMornFirst), ActionID.MakeSpell(AID.WheiMornRest), 6f, 2f, 5, true, (uint)IconID.ChasingAOE); +class DarkMegaflare(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DarkMegaflare), 6f); -class DarkWyrm(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(40, 8)); +class DarkWyrm(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(40f, 8f)); class DarkWyrmwing(BossModule module) : DarkWyrm(module, AID.DarkWyrmwing); class DarkWyrmtail(BossModule module) : DarkWyrm(module, AID.DarkWyrmtail); -class CreatureOfDarkness(BossModule module) : Components.PersistentVoidzone(module, 2, m => m.Enemies(OID.DarkWanderer).Where(x => x.ModelState.AnimState1 == 1), 6); +class CreatureOfDarkness(BossModule module) : Components.PersistentVoidzone(module, 2f, m => m.Enemies(OID.DarkWanderer).Where(x => x.ModelState.AnimState1 == 1), 6f); class DD30TiamatsCloneStates : StateMachineBuilder { @@ -50,4 +50,4 @@ public DD30TiamatsCloneStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 899, NameID = 12242)] -public class DD30TiamatsClone(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -300), new ArenaBoundsSquare(19.5f)); +public class DD30TiamatsClone(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300f, -300f), new ArenaBoundsSquare(19.5f)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs index 03e9ec983a..f1e302ae32 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs @@ -22,9 +22,9 @@ public enum AID : uint TwistingDive = 31471 // Boss->self, 5.0s cast, range 50 width 15 rect } -class Twister(BossModule module) : Components.CastTwister(module, 1, (uint)OID.Twister, ActionID.MakeSpell(AID.TwisterVisual), 0.4f, 0.25f); -class BitingWind(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 5, ActionID.MakeSpell(AID.BitingWind), m => m.Enemies(OID.BitingWind).Where(z => z.EventState != 7), 0.9f); -class MeracydianSquall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MeracydianSquall), 5); +class Twister(BossModule module) : Components.CastTwister(module, 1f, (uint)OID.Twister, ActionID.MakeSpell(AID.TwisterVisual), 0.4f, 0.25f); +class BitingWind(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 5f, ActionID.MakeSpell(AID.BitingWind), m => m.Enemies(OID.BitingWind).Where(z => z.EventState != 7), 0.9f); +class MeracydianSquall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MeracydianSquall), 5f); class TwistersHint(BossModule module, AID aid) : Components.CastHint(module, ActionID.MakeSpell(aid), "Twisters soon, get moving!"); class Twisters1(BossModule module) : TwistersHint(module, AID.TwisterVisual); @@ -45,13 +45,13 @@ public override void OnActorPlayActionTimelineEvent(Actor actor, ushort id) if (id == 0x1E3A) preparing = true; else if (preparing && id == 0x1E43) - _aoe = new(rect, actor.Position, actor.Rotation, WorldState.FutureTime(6.9f)); + _aoe = new(rect, WPos.ClampToGrid(actor.Position), actor.Rotation, WorldState.FutureTime(6.9d)); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.TwistingDive) + if (spell.Action.ID == (uint)AID.TwistingDive) { _aoe = null; preparing = false; @@ -59,24 +59,36 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) } } -class Turbine(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.Turbine), 15) +class Turbine(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.Turbine), 15f) { + private readonly BitingWind _aoe = module.FindComponent()!; + private static readonly Angle a20 = 20f.Degrees(); + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - var forbidden = new List>(); - var component = Module.FindComponent()?.ActiveAOEs(slot, actor)?.ToList(); - var source = Sources(slot, actor).FirstOrDefault(); - if (source != default && component != null) + var source = Casters.Count != 0 ? Casters[0] : null; + if (source != null) { - forbidden.Add(ShapeDistance.InvertedCircle(Arena.Center, 5)); + var component = _aoe.Sources(Module).ToList(); + var forbidden = new List> + { + ShapeDistance.InvertedCircle(Arena.Center, 5f) + }; for (var i = 0; i < component.Count; ++i) - forbidden.Add(ShapeDistance.Cone(Arena.Center, 20, Angle.FromDirection(component[i].Origin - Arena.Center), 20.Degrees())); - if (forbidden.Count > 0) - hints.AddForbiddenZone(ShapeDistance.Intersection(forbidden), source.Activation); + forbidden.Add(ShapeDistance.Cone(Arena.Center, 20f, Angle.FromDirection(component[i].Position - Arena.Center), a20)); + hints.AddForbiddenZone(ShapeDistance.Intersection(forbidden), Module.CastFinishAt(source.CastInfo)); } } - public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || !Arena.InBounds(pos); + public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) + { + foreach (var aoe in _aoe.ActiveAOEs(slot, actor)) + { + if (aoe.Shape.Check(pos, aoe.Origin, aoe.Rotation)) + return true; + } + return !Arena.InBounds(pos); + } } class DD40TwintaniasCloneStates : StateMachineBuilder diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur16.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur16.cs index b6047cd035..ca7fd261fe 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur16.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur16.cs @@ -78,9 +78,9 @@ class DisorientingGroan(BossModule module) : Components.KnockbackFromCastTarget( { public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - var source = Sources(slot, actor).FirstOrDefault(); - if (source != default) - hints.AddForbiddenZone(ShapeDistance.InvertedCircle(Arena.Center, 5f), source.Activation); + var source = Casters.Count != 0 ? Casters[0] : null; + if (source != null) + hints.AddForbiddenZone(ShapeDistance.InvertedCircle(Arena.Center, 5f), Module.CastFinishAt(source.CastInfo)); } } diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD70Aeturna.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD70Aeturna.cs index 611ffae856..f87a657f73 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD70Aeturna.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD70Aeturna.cs @@ -26,56 +26,55 @@ public enum AID : uint } class SteelClaw(BossModule module) : Components.SingleTargetDelayableCast(module, ActionID.MakeSpell(AID.SteelClaw)); -class Ferocity(BossModule module) : Components.StretchTetherDuo(module, 15, 5.7f); -class PreternaturalTurnCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PreternaturalTurnCircle), 15); -class PreternaturalTurnDonut(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PreternaturalTurnDonut), new AOEShapeDonut(6, 30)); +class Ferocity(BossModule module) : Components.StretchTetherDuo(module, 15f, 5.7f); +class PreternaturalTurnCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PreternaturalTurnCircle), 15f); +class PreternaturalTurnDonut(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PreternaturalTurnDonut), new AOEShapeDonut(6f, 30f)); class Shatter(BossModule module) : Components.GenericAOEs(module) { - private bool FerocityCasted; - private readonly List _crystals = []; - private readonly List _aoes = []; + private bool ferocityCasted; + private readonly List _aoes = new(4); private static readonly AOEShapeCone cone = new(23.95f, 75.Degrees()); private static readonly AOEShapeCircle circle = new(8); - public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes.Take(4); - - public override void DrawArenaForeground(int pcSlot, Actor pc) - { - foreach (var s in _crystals) - Arena.Actor(s, Colors.Object, true); - } + public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.Impact) - _crystals.Add(caster); - else if ((AID)spell.Action.ID == AID.Ferocity) - FerocityCasted = true; - else if (!FerocityCasted && (AID)spell.Action.ID == AID.PreternaturalTurnDonut) - foreach (var c in Module.Enemies(OID.AllaganCrystal)) - _aoes.Add(new(circle, c.Position, default, Module.CastFinishAt(spell, 0.5f))); - else if (!FerocityCasted && (AID)spell.Action.ID == AID.PreternaturalTurnCircle) - foreach (var c in Module.Enemies(OID.AllaganCrystal)) - _aoes.Add(new(cone, c.Position, c.Rotation, Module.CastFinishAt(spell, 0.5f))); + void AddAOEs(AOEShape shape) + { + var crystals = Module.Enemies((uint)OID.AllaganCrystal); + var count = crystals.Count; + for (var i = 0; i < count; ++i) + _aoes.Add(new(shape, WPos.ClampToGrid(crystals[i].Position), default, Module.CastFinishAt(spell, 0.5f))); + } + switch (spell.Action.ID) + { + case (uint)AID.Ferocity: + ferocityCasted = true; + break; + case (uint)AID.PreternaturalTurnCircle when !ferocityCasted: + AddAOEs(cone); + break; + case (uint)AID.PreternaturalTurnDonut when !ferocityCasted: + AddAOEs(circle); + break; + } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.ShatterCircle or AID.ShatterCone) - { + if (spell.Action.ID is (uint)AID.ShatterCircle or (uint)AID.ShatterCone) _aoes.Clear(); - _crystals.Clear(); - } - if ((AID)spell.Action.ID is AID.PreternaturalTurnCircle or AID.PreternaturalTurnDonut) - FerocityCasted = false; + else if (spell.Action.ID is (uint)AID.PreternaturalTurnCircle or (uint)AID.PreternaturalTurnDonut) + ferocityCasted = false; } } class Roar(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Roar)); -class FallingRock(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FallingRock), 3); -class Impact(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Impact), 5); +class FallingRock(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FallingRock), 3f); +class Impact(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Impact), 5f); class DD70AeturnaStates : StateMachineBuilder { @@ -94,4 +93,4 @@ public DD70AeturnaStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "legendoficeman, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 903, NameID = 12246)] -public class DD70Aeturna(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -300), new ArenaBoundsCircle(20)); +public class DD70Aeturna(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300f, -300f), new ArenaBoundsCircle(20f)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD80ProtoKaliya.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD80ProtoKaliya.cs index 21081ed721..5bedc91a81 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD80ProtoKaliya.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD80ProtoKaliya.cs @@ -46,18 +46,32 @@ class Magnetism(BossModule module) : Components.Knockback(module, ignoreImmunes: { private readonly HashSet<(Actor, uint)> statusOnActor = []; public readonly HashSet<(Actor, Source)> sourceByActor = []; + private readonly NerveGasRingAndAutoCannons _aoe1 = module.FindComponent()!; + private readonly Barofield _aoe2 = module.FindComponent()!; public override IEnumerable Sources(int slot, Actor actor) { - if (sourceByActor.Count > 0 && Module.FindComponent()!.ActiveAOEs(slot, actor).Any(z => z.Shape == NerveGasRingAndAutoCannons.donut)) + if (sourceByActor.Count != 0 && _aoe1.AOEs.Any(z => z.Shape == NerveGasRingAndAutoCannons.donut)) { var x = sourceByActor.FirstOrDefault(x => x.Item1 == actor); - yield return new(x.Item2.Origin, x.Item2.Distance, x.Item2.Activation, Kind: x.Item2.Kind); + return [new(x.Item2.Origin, x.Item2.Distance, x.Item2.Activation, Kind: x.Item2.Kind)]; } + else + return []; } - public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || - (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || !Module.InBounds(pos); + public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) + { + var count = _aoe1.AOEs.Count; + for (var i = 0; i < count; ++i) + { + var aoe = _aoe1.AOEs[i]; + if (aoe.Shape.Check(pos, aoe.Origin, aoe.Rotation)) + return true; + } + + return _aoe2.AOE != null && _aoe2.AOE.Value.Check(pos) || !Module.InBounds(pos); + } private bool IsPull(Actor source, Actor target) { @@ -76,11 +90,11 @@ public override void OnTethered(Actor source, ActorTetherInfo tether) if (tether.ID == (uint)TetherID.Magnetism) { var target = WorldState.Actors.Find(tether.Target)!; - var activation = WorldState.FutureTime(10); + var activation = WorldState.FutureTime(10d); if (IsPull(source, target)) - sourceByActor.Add((target, new(source.Position, 10, activation, Kind: Kind.TowardsOrigin))); + sourceByActor.Add((target, new(source.Position, 10f, activation, Kind: Kind.TowardsOrigin))); else if (IsKnockback(source, target)) - sourceByActor.Add((target, new(source.Position, 10, activation))); + sourceByActor.Add((target, new(source.Position, 10f, activation))); } } @@ -95,7 +109,7 @@ public override void OnUntethered(Actor source, ActorTetherInfo tether) public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID is SID.NegativeChargeDrone or SID.PositiveChargeDrone or SID.PositiveChargePlayer or SID.NegativeChargePlayer) + if (status.ID is (uint)SID.NegativeChargeDrone or (uint)SID.PositiveChargeDrone or (uint)SID.PositiveChargePlayer or (uint)SID.NegativeChargePlayer) { statusOnActor.RemoveWhere(x => x.Item1 == actor); statusOnActor.Add((actor, status.ID)); @@ -107,90 +121,87 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme if (sourceByActor.Count > 0) { var target = sourceByActor.FirstOrDefault(x => x.Item1 == actor); - var offset = target.Item2.Kind == Kind.TowardsOrigin ? 180.Degrees() : default; - hints.AddForbiddenZone(ShapeDistance.InvertedDonutSector(Arena.Center, 15, 18, Angle.FromDirection(target.Item2.Origin - Arena.Center) + offset, 35.Degrees())); + var offset = target.Item2.Kind == Kind.TowardsOrigin ? 180f.Degrees() : default; + hints.AddForbiddenZone(ShapeDistance.InvertedDonutSector(Arena.Center, 15f, 18f, Angle.FromDirection(target.Item2.Origin - Arena.Center) + offset, 35f.Degrees())); } } } class Barofield(BossModule module) : Components.GenericAOEs(module) { - private DateTime activation; - private static readonly AOEShapeCircle circle = new(5); + private static readonly AOEShapeCircle circle = new(5f); + public AOEInstance? AOE; - public override IEnumerable ActiveAOEs(int slot, Actor actor) - { - if (activation != default) - yield return new(circle, Module.PrimaryActor.Position, default, activation); - } + public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(AOE); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if (activation == default && (AID)spell.Action.ID is AID.Barofield or AID.NanosporeJet) - activation = Module.CastFinishAt(spell, 0.7f); + if (AOE == null && spell.Action.ID is (uint)AID.Barofield or (uint)AID.NanosporeJet) + AOE = new(circle, spell.LocXZ, default, Module.CastFinishAt(spell, 0.7f)); } public override void OnStatusLose(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.Barofield) - activation = default; + if (status.ID == (uint)SID.Barofield) + AOE = null; } } class NerveGasRingAndAutoCannons(BossModule module) : Components.GenericAOEs(module) { - private readonly List _aoes = []; - private static readonly AOEShapeCross cross = new(43, 2.5f); - public static readonly AOEShapeDonut donut = new(8, 30); + public readonly List AOEs = new(2); + private static readonly AOEShapeCross cross = new(43f, 2.5f); + public static readonly AOEShapeDonut donut = new(8f, 30f); - public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; + public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.NerveGasRing) + if (spell.Action.ID == (uint)AID.NerveGasRing) { - _aoes.Add(new(donut, Arena.Center, default, Module.CastFinishAt(spell), Risky: false)); - _aoes.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); + AOEs.Add(new(donut, Arena.Center, default, Module.CastFinishAt(spell), Risky: false)); + AOEs.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); } - if (_aoes.Count == 0 && (AID)spell.Action.ID == AID.AutoCannons) - _aoes.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); - else if (_aoes.Count == 2 && (AID)spell.Action.ID == AID.AutoCannons) + if (AOEs.Count == 0 && (AID)spell.Action.ID == AID.AutoCannons) + AOEs.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); + else if (AOEs.Count == 2 && (AID)spell.Action.ID == AID.AutoCannons) { - _aoes.RemoveAt(1); - _aoes.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); + AOEs.RemoveAt(1); + AOEs.Add(new(cross, Arena.Center, default, Module.CastFinishAt(spell))); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (_aoes.Count != 0 && (AID)spell.Action.ID is AID.NerveGasRing or AID.AutoCannons) - _aoes.RemoveAt(0); + if (AOEs.Count != 0 && spell.Action.ID is (uint)AID.NerveGasRing or (uint)AID.AutoCannons) + AOEs.RemoveAt(0); } } -class NerveGas(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(30, 90.Degrees())); +class NerveGas(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(30f, 90f.Degrees())); class LeftNerveGas(BossModule module) : NerveGas(module, AID.LeftwardNerveGas); class RightNerveGas(BossModule module) : NerveGas(module, AID.RightwardNerveGas); -class CentralizedNerveGas(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.CentralizedNerveGas), new AOEShapeCone(30, 60.Degrees())); +class CentralizedNerveGas(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.CentralizedNerveGas), new AOEShapeCone(30f, 60f.Degrees())); -class AutoAttack(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.AutoAttack), new AOEShapeCone(11, 45.Degrees())) +class AutoAttack(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.AutoAttack), new AOEShapeCone(11f, 45f.Degrees())) { - private bool Inactive(int slot, Actor actor) => !Module.FindComponent()!.ActiveAOEs(slot, actor).Any(); + private readonly Barofield _aoe = module.FindComponent()!; + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - if (Inactive(slot, actor)) + if (_aoe.AOE != null) base.AddAIHints(slot, actor, assignment, hints); } public override void DrawArenaForeground(int pcSlot, Actor pc) { - if (Inactive(pcSlot, pc)) + if (_aoe.AOE != null) base.DrawArenaForeground(pcSlot, pc); } } -class Resonance(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.Resonance), new AOEShapeCone(12, 45.Degrees()), endsOnCastEvent: true) +class Resonance(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.Resonance), new AOEShapeCone(12f, 45f.Degrees()), endsOnCastEvent: true) { public override void AddGlobalHints(GlobalHints hints) { @@ -204,8 +215,8 @@ class DD80ProtoKaliyaStates : StateMachineBuilder public DD80ProtoKaliyaStates(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() .ActivateOnEnter() + .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() @@ -216,4 +227,4 @@ public DD80ProtoKaliyaStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus, legendoficeman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 904, NameID = 12247)] -public class DD80ProtoKaliya(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600, -300), new ArenaBoundsCircle(20)); \ No newline at end of file +public class DD80ProtoKaliya(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600f, -300f), new ArenaBoundsCircle(20f)); \ No newline at end of file diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD90Administrator.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD90Administrator.cs index e0b31bc061..83625ab468 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD90Administrator.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD90Administrator.cs @@ -47,8 +47,8 @@ public enum IconID : uint class AetheroChemicalLaserCombo(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShape[] _shapes = [new AOEShapeCone(50, 60.Degrees()), new AOEShapeDonut(8, 60), new AOEShapeRect(40, 2.5f), - new AOEShapeCross(60, 5), new AOEShapeDonut(5, 60)]; + private static readonly AOEShape[] _shapes = [new AOEShapeCone(50f, 60f.Degrees()), new AOEShapeDonut(8f, 60f), new AOEShapeRect(40f, 2.5f), + new AOEShapeCross(60f, 5f), new AOEShapeDonut(5f, 60f)]; private readonly Dictionary> _icons = new() { { (uint)IconID.Icon1, [] }, { (uint)IconID.Icon2, [] }, @@ -79,38 +79,38 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) { - var shapeIndex = (OID)actor.OID switch + var shapeIndex = actor.OID switch { - OID.SquareInterceptor => 2, - OID.OrbInterceptor => 1, - OID.EggInterceptor => 0, + (uint)OID.SquareInterceptor => 2, + (uint)OID.OrbInterceptor => 1, + (uint)OID.EggInterceptor => 0, _ => default }; var activation = iconID switch { - (uint)IconID.Icon1 => WorldState.FutureTime(7), - (uint)IconID.Icon2 => WorldState.FutureTime(10.5f), - (uint)IconID.Icon3 => WorldState.FutureTime(14), + (uint)IconID.Icon1 => WorldState.FutureTime(7d), + (uint)IconID.Icon2 => WorldState.FutureTime(10.5d), + (uint)IconID.Icon3 => WorldState.FutureTime(14d), _ => default }; - _icons[iconID].Add(new(_shapes[shapeIndex], actor.Position, (OID)actor.OID == OID.OrbInterceptor ? default : actor.Rotation, activation)); + _icons[iconID].Add(new(_shapes[shapeIndex], WPos.ClampToGrid(actor.Position), actor.OID == (uint)OID.OrbInterceptor ? default : actor.Rotation, activation)); } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - _boss = (AID)spell.Action.ID switch + _boss = spell.Action.ID switch { - AID.PeripheralLasers => new(_shapes[4], caster.Position, default, Module.CastFinishAt(spell)), - AID.CrossLaser => new(_shapes[3], caster.Position, spell.Rotation, Module.CastFinishAt(spell)), + (uint)AID.PeripheralLasers => new(_shapes[4], spell.LocXZ, default, Module.CastFinishAt(spell)), + (uint)AID.CrossLaser => new(_shapes[3], spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell)), _ => _boss }; } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.AetherochemicalLaserCone or AID.AetherochemicalLaserLine or AID.AetherochemicalLaserDonut) + if (spell.Action.ID is (uint)AID.AetherochemicalLaserCone or (uint)AID.AetherochemicalLaserLine or (uint)AID.AetherochemicalLaserDonut) { foreach (var icon in _icons) if (icon.Value.Count != 0) @@ -119,12 +119,12 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) break; } } - if ((AID)spell.Action.ID is AID.PeripheralLasers or AID.CrossLaser) + else if (spell.Action.ID is (uint)AID.PeripheralLasers or (uint)AID.CrossLaser) _boss = default; } } -class AetherLaserLine(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserLine), new AOEShapeRect(40, 2.5f), 4) +class AetherLaserLine(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserLine), new AOEShapeRect(40f, 2.5f), 4) { private readonly AetheroChemicalLaserCombo _aoe = module.FindComponent()!; public override IEnumerable ActiveAOEs(int slot, Actor actor) @@ -146,19 +146,19 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) return []; var max = count > 4 ? 4 : count; - List result = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) { var caster = Casters[i]; - result.Add(caster with { Color = i < 2 && count > i ? Colors.Danger : 0 }); + aoes[i] = caster with { Color = i < 2 && count > i ? Colors.Danger : 0 }; } - return result; + return aoes; } } -class AetherLaserLine2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserLine2), new AOEShapeRect(40, 2.5f)); -class AetherLaserCone(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserCone2), new AOEShapeCone(50, 60.Degrees())); -class HomingLasers(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.HomingLaser), 6); +class AetherLaserLine2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserLine2), new AOEShapeRect(40f, 2.5f)); +class AetherLaserCone(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AetherochemicalLaserCone2), new AOEShapeCone(50f, 60f.Degrees())); +class HomingLasers(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.HomingLaser), 6f); class Laserstream(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Laserstream)); class DD90AdministratorStates : StateMachineBuilder @@ -176,4 +176,4 @@ public DD90AdministratorStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "legendoficeman, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 905, NameID = 12102)] -public class DD90Administrator(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -300), new ArenaBoundsSquare(20)); +public class DD90Administrator(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300f, -300f), new ArenaBoundsSquare(20f)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD99Excalibur.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD99Excalibur.cs index 29ede77073..18bcdc2d34 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD99Excalibur.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD99Excalibur.cs @@ -57,16 +57,16 @@ public enum SID : uint class Steelstrike(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeRect rect = new(20, 2); - private static readonly AOEShapeRect rect2 = new(20, 2, 20); + private static readonly AOEShapeRect rect = new(20f, 2f); + private static readonly AOEShapeRect rect2 = new(20f, 2f, 20f); private readonly HashSet _aoes = []; private readonly List angles = []; private readonly List swordsFire = []; private readonly List swordsIce = []; - private static readonly Angle[] offsets = [default, 120.Degrees(), 240.Degrees()]; - private static readonly Angle a20 = 20.Degrees(); - private static readonly Angle a10 = 10.Degrees(); - private static readonly Angle a45 = 45.Degrees(); + private static readonly Angle[] offsets = [default, 120f.Degrees(), 240f.Degrees()]; + private static readonly Angle a20 = 20f.Degrees(); + private static readonly Angle a10 = 10f.Degrees(); + private static readonly Angle a45 = 45f.Degrees(); private bool? nextRaidwide; // null = none, false = fire, true = ice public override IEnumerable ActiveAOEs(int slot, Actor actor) @@ -74,8 +74,8 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (nextRaidwide == null) return _aoes; - var fire = actor.FindStatus(SID.SoulOfFire) != null; - var ice = actor.FindStatus(SID.SoulOfIce) != null; + var fire = actor.FindStatus((uint)SID.SoulOfFire) != null; + var ice = actor.FindStatus((uint)SID.SoulOfIce) != null; return ice && (bool)nextRaidwide ? GetSafeAOEs(swordsFire) : fire && !(bool)nextRaidwide ? GetSafeAOEs(swordsIce) @@ -95,21 +95,21 @@ private IEnumerable GetSafeAOEs(List swordAOEs) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.Caliburni: + case (uint)AID.Caliburni: AddAOEs(spell.Rotation); ++NumCasts; break; - case AID.ThermalDivide1: - case AID.ParadoxumVisual: + case (uint)AID.ThermalDivide1: + case (uint)AID.ParadoxumVisual: foreach (var a in angles) _aoes.Add(new(rect2, Arena.Center, a, Module.CastFinishAt(spell, 3.4f))); break; - case AID.Flameforge: + case (uint)AID.Flameforge: nextRaidwide = false; break; - case AID.Frostforge: + case (uint)AID.Frostforge: nextRaidwide = true; break; } @@ -126,8 +126,8 @@ public override void AddHints(int slot, Actor actor, TextHints hints) base.AddHints(slot, actor, hints); if (nextRaidwide != null) { - var fire = actor.FindStatus(SID.SoulOfFire) != null; - var ice = actor.FindStatus(SID.SoulOfIce) != null; + var fire = actor.FindStatus((uint)SID.SoulOfFire) != null; + var ice = actor.FindStatus((uint)SID.SoulOfIce) != null; if (ice && (bool)nextRaidwide) hints.Add("Get hit by a fire blade!"); else if (fire && !(bool)nextRaidwide) @@ -137,7 +137,7 @@ public override void AddHints(int slot, Actor actor, TextHints hints) public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.CaliburnusElement) + if (status.ID == (uint)SID.CaliburnusElement) { AddSwordAOE(actor, status.Extra == 0x219 ? swordsFire : swordsIce); if (swordsFire.Count == 5 && swordsIce.Count == 5) @@ -150,19 +150,19 @@ public override void OnStatusGain(Actor actor, ActorStatus status) private void AddSwordAOE(Actor actor, List swordAOEs) { - swordAOEs.Add(_aoes.FirstOrDefault(x => x.Origin.AlmostEqual(actor.Position, 1))); + swordAOEs.Add(_aoes.FirstOrDefault(x => x.Origin.AlmostEqual(actor.Position, 1f))); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.Steelstrike1: + case (uint)AID.Steelstrike1: _aoes.Clear(); break; - case AID.Steelstrike2: - case AID.SteelFlame: - case AID.SteelFrost: + case (uint)AID.Steelstrike2: + case (uint)AID.SteelFlame: + case (uint)AID.SteelFrost: _aoes.Clear(); angles.Clear(); swordsFire.Clear(); @@ -189,21 +189,21 @@ private void AddAOEs(Angle rotation) private void AddSingleAOE(Angle rotation) { - _aoes.Add(new(rect, Arena.Center, rotation)); + _aoes.Add(new(rect, WPos.ClampToGrid(Arena.Center), rotation)); angles.Add(rotation); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.FlamesRevelation or AID.FrostRevelation) + if (spell.Action.ID is (uint)AID.FlamesRevelation or (uint)AID.FrostRevelation) nextRaidwide = null; } } class ThermalDivideSides(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCone cone = new(40, 90.Degrees()); - private static readonly Angle a90 = 90.Degrees(); + private static readonly Angle a90 = 90f.Degrees(); + private static readonly AOEShapeCone cone = new(40f, a90); private bool? pattern; // null = none, false = ice left, fire right, true = fire left, ice right private Angle rotation; private WDir offset; @@ -213,8 +213,8 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (pattern != null) { - var fire = actor.FindStatus(SID.SoulOfFire) != null; - var ice = actor.FindStatus(SID.SoulOfIce) != null; + var fire = actor.FindStatus((uint)SID.SoulOfFire) != null; + var ice = actor.FindStatus((uint)SID.SoulOfIce) != null; return (bool)pattern ? HandleAOEs(fire) : HandleAOEs(ice); } @@ -224,8 +224,8 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) private IEnumerable HandleAOEs(bool condition) { - var pos1 = Arena.Center + offset; - var pos2 = Arena.Center - offset; + var pos1 = WPos.ClampToGrid(Arena.Center + offset); + var pos2 = WPos.ClampToGrid(Arena.Center - offset); if (condition) { @@ -241,7 +241,7 @@ private IEnumerable HandleAOEs(bool condition) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.ThermalDivideVisual1 or AID.ThermalDivideVisual2) + if (spell.Action.ID is (uint)AID.ThermalDivideVisual1 or (uint)AID.ThermalDivideVisual2) { pattern = (AID)spell.Action.ID == AID.ThermalDivideVisual2; rotation = spell.Rotation; @@ -252,7 +252,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.ThermalDivide2) + if (spell.Action.ID is (uint)AID.ThermalDivide2) pattern = null; } @@ -268,7 +268,7 @@ public override void AddHints(int slot, Actor actor, TextHints hints) class IceBloomCross(BossModule module) : Components.GenericAOEs(module) { private readonly List _aoes = new(6); - private static readonly AOEShapeCross cross = new(40, 2.5f); + private static readonly AOEShapeCross cross = new(40f, 2.5f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -276,15 +276,15 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (count == 0) return []; var max = count > 6 ? 6 : count; - List aoes = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) - aoes.Add(_aoes[i]); + aoes[i] = _aoes[i]; return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.IceShoot) + if (spell.Action.ID == (uint)AID.IceShoot) { var pos = spell.LocXZ; var activation = Module.CastFinishAt(spell, 6); @@ -295,21 +295,21 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if (_aoes.Count != 0 && (AID)spell.Action.ID == AID.IceBloomCross) + if (_aoes.Count != 0 && spell.Action.ID == (uint)AID.IceBloomCross) _aoes.RemoveAt(0); } } -class AbyssalSlash1(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash1), new AOEShapeDonutSector(2, 7, 90.Degrees())); -class AbyssalSlash2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash2), new AOEShapeDonutSector(7, 12, 90.Degrees())); -class AbyssalSlash3(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash3), new AOEShapeDonutSector(17, 22, 90.Degrees())); -class VacuumSlash(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.VacuumSlash), new AOEShapeCone(80, 22.5f.Degrees())); -class ThermalDivide(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ThermalDivide1), new AOEShapeRect(40, 4)); -class Exflammeus(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Exflammeus), 8); -class IceShoot(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IceShoot), 6); -class IceBloomCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IceBloomCircle), 6); -class EmptySoulsCaliber(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.EmptySoulsCaliber), new AOEShapeDonut(5, 40)); -class SolidSoulsCaliber(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SolidSoulsCaliber), 10); +class AbyssalSlash1(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash1), new AOEShapeDonutSector(2f, 7f, 90.Degrees())); +class AbyssalSlash2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash2), new AOEShapeDonutSector(7f, 12f, 90.Degrees())); +class AbyssalSlash3(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AbyssalSlash3), new AOEShapeDonutSector(17f, 22f, 90.Degrees())); +class VacuumSlash(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.VacuumSlash), new AOEShapeCone(80f, 22.5f.Degrees())); +class ThermalDivide(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ThermalDivide1), new AOEShapeRect(40f, 4f)); +class Exflammeus(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Exflammeus), 8f); +class IceShoot(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IceShoot), 6f); +class IceBloomCircle(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.IceBloomCircle), 6f); +class EmptySoulsCaliber(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.EmptySoulsCaliber), new AOEShapeDonut(5f, 40f)); +class SolidSoulsCaliber(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SolidSoulsCaliber), 10f); class DD99ExcaliburStates : StateMachineBuilder { @@ -333,4 +333,4 @@ public DD99ExcaliburStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 906, NameID = 12100)] -public class DD99Excalibur(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600, -300), new ArenaBoundsCircle(19.5f)); +public class DD99Excalibur(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600f, -300f), new ArenaBoundsCircle(19.5f)); diff --git a/BossMod/Modules/Endwalker/Dungeon/D06DeadEnds/D061CausticGrebuloff.cs b/BossMod/Modules/Endwalker/Dungeon/D06DeadEnds/D061CausticGrebuloff.cs index 7a00ae1cc7..c34324dd2c 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D06DeadEnds/D061CausticGrebuloff.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D06DeadEnds/D061CausticGrebuloff.cs @@ -36,13 +36,13 @@ class CertainSolitude(BossModule module) : Components.GenericStackSpread(module) { public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.CravenCompanionship && Stacks.Count == 0) - Stacks.Add(new(actor, 1.5f, 4, 4, activation: WorldState.FutureTime(5))); + if (status.ID == (uint)SID.CravenCompanionship && Stacks.Count == 0) + Stacks.Add(new(actor, 1.5f, 4, 4, activation: WorldState.FutureTime(5d))); } public override void Update() { - if (Stacks.Count != 0 && Raid.WithoutSlot(false, true, true).All(x => x.FindStatus(SID.CravenCompanionship) == null)) + if (Stacks.Count != 0 && Raid.WithoutSlot(false, true, true).All(x => x.FindStatus((uint)SID.CravenCompanionship) == null)) Stacks.Clear(); } } @@ -53,13 +53,13 @@ class Necrosis(BossModule module) : BossComponent(module) public override void OnStatusGain(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.Necrosis) + if (status.ID == (uint)SID.Necrosis) _doomed.Add(actor); } public override void OnStatusLose(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.Necrosis) + if (status.ID == (uint)SID.Necrosis) _doomed.Remove(actor); } @@ -112,18 +112,16 @@ public override void OnEventEnvControl(byte index, uint state) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - static WPos RoundPosition(WPos position) => new(MathF.Round(position.X * 10) * 0.1f, MathF.Round(position.Z * 10) * 0.1f); - if ((AID)spell.Action.ID == AID.NecroticFluid) + if (spell.Action.ID == (uint)AID.NecroticFluid) { - var roundedPos = RoundPosition(spell.LocXZ); var numExplosions = CurrentWind switch { - Pattern.Southward => GetSouthwardExplosions(roundedPos, Arena.Center), - Pattern.Northward => GetNorthwardExplosions(roundedPos, Arena.Center), + Pattern.Southward => GetSouthwardExplosions(caster.Position, Arena.Center), + Pattern.Northward => GetNorthwardExplosions(caster.Position, Arena.Center), _ => 0 }; - var advance = 6 * (CurrentWind == Pattern.Southward ? new WDir(0, 1) : new(0, -1)); - Lines.Add(new() { Next = spell.LocXZ, Advance = advance, NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = numExplosions, MaxShownExplosions = 5 }); + var advance = 6 * (CurrentWind == Pattern.Southward ? new WDir(0f, 1f) : new(0f, -1f)); + Lines.Add(new() { Next = caster.Position, Advance = advance, NextExplosion = Module.CastFinishAt(spell), TimeToMove = 2, ExplosionsLeft = numExplosions, MaxShownExplosions = 5 }); } } @@ -136,7 +134,7 @@ private static int GetSouthwardExplosions(WPos position, WPos center) -191.4f => 5, -194.5f => 6, -196.9f => 7, - _ => position.Z > -178 ? 1 : ((position - center).LengthSq() > 100 && position.Z == -178) ? 3 : 4, + _ => position.Z > -178f ? 1 : ((position - center).LengthSq() > 100f && position.Z == -178f) ? 3 : 4, }; } @@ -149,22 +147,19 @@ private static int GetNorthwardExplosions(WPos position, WPos center) -164.6f => 5, -161.5f => 6, -159.1f => 7, - _ => position.Z < -178 ? 1 : ((position - center).LengthSq() > 100 && position.Z == -178) ? 3 : 4, + _ => position.Z < -178f ? 1 : ((position - center).LengthSq() > 100f && position.Z == -178f) ? 3 : 4, }; } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.NecroticFluid or AID.NecroticMist) - { + if (spell.Action.ID is (uint)AID.NecroticFluid or (uint)AID.NecroticMist) Advance(spell.LocXZ); - ++NumCasts; - } } private void Advance(WPos position) { - var index = Lines.FindIndex(item => item.Next.AlmostEqual(position, 1)); + var index = Lines.FindIndex(item => item.Next.AlmostEqual(position, 1f)); if (index != -1) { AdvanceLine(Lines[index], position); @@ -177,52 +172,49 @@ private void Advance(WPos position) public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - if (Module.FindComponent()!.ActiveAOEs(slot, actor).Any()) + if (Module.FindComponent()?.AOEs.Count != 0) { } else base.AddAIHints(slot, actor, assignment, hints); } } -class Befoulment(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.Befoulment), 6); -class BlightedWater(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.BlightedWater), 6, 4, 4); +class Befoulment(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.Befoulment), 6f); +class BlightedWater(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.BlightedWater), 6f, 4, 4); class CoughUpAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.CoughUpAOE), 6); class WaveOfNausea(BossModule module) : Components.GenericAOEs(module) { private readonly NecroticFluidMist _exa = module.FindComponent()!; - private readonly List _aoes = new(2); + public readonly List AOEs = new(2); private static readonly AOEShapeDonut donut = new(6, 40); - private static readonly Shape[] differenceShapes = [new Circle(new(271.473f, -178.027f), 6), new Circle(new(261.494f, -178.027f), 6)]; + private static readonly Shape[] differenceShapes = [new Circle(new(271.473f, -178.027f), 6f), new Circle(new(261.494f, -178.027f), 6f)]; - public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; + public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { void AddAOE(Angle start, Angle end) - => _aoes.Add(new(new AOEShapeCustom([new ConeHA(spell.LocXZ, 6, start, end)], differenceShapes, InvertForbiddenZone: true), Arena.Center, default, Module.CastFinishAt(spell), Colors.SafeFromAOE)); + => AOEs.Add(new(new AOEShapeCustom([new ConeHA(spell.LocXZ, 6f, start, end)], differenceShapes, InvertForbiddenZone: true), Arena.Center, default, Module.CastFinishAt(spell), Colors.SafeFromAOE)); if ((AID)spell.Action.ID == AID.WaveOfNausea) { - _aoes.Add(new(donut, spell.LocXZ, default, Module.CastFinishAt(spell))); + AOEs.Add(new(donut, spell.LocXZ, default, Module.CastFinishAt(spell))); if (_exa.CurrentWind == NecroticFluidMist.Pattern.Southward) - AddAOE(180.Degrees(), 90.Degrees()); + AddAOE(180f.Degrees(), 90f.Degrees()); else if (_exa.CurrentWind == NecroticFluidMist.Pattern.Northward) - AddAOE(default, 90.Degrees()); + AddAOE(default, 90f.Degrees()); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.WaveOfNausea) - { - ++NumCasts; - _aoes.Clear(); - } + if (spell.Action.ID == (uint)AID.WaveOfNausea) + AOEs.Clear(); } public override void AddGlobalHints(GlobalHints hints) { - if (ActiveAOEs(default, default!).Any() && Module.FindComponent()!.ActiveAOEs(default, default!).Any()) + if (AOEs.Count != 0 && _exa.Lines.Count != 0) hints.Add("Wait in marked safespot for donut resolve!"); } } @@ -250,6 +242,6 @@ public D061CausticGrebuloffStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 792, NameID = 10313)] public class D061CausticGrebuloff(WorldState ws, Actor primary) : BossModule(ws, primary, defaultBounds.Center, defaultBounds) { - private static readonly ArenaBoundsComplex defaultBounds = new([new Polygon(new(266.5f, -178), 19.5f * CosPI.Pi32th, 32)], - [new Rectangle(new(266.5f, -198.75f), 20, 2), new Rectangle(new(266.5f, -157), 20, 2)]); + private static readonly ArenaBoundsComplex defaultBounds = new([new Polygon(new(266.5f, -178f), 19.5f * CosPI.Pi32th, 32)], + [new Rectangle(new(266.5f, -198.75f), 20f, 2f), new Rectangle(new(266.5f, -157f), 20f, 2f)]); } diff --git a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs index 365cd072ba..c04d2b3ce7 100644 --- a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs +++ b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs @@ -53,7 +53,7 @@ public enum SID : uint class LitPath(BossModule module) : Components.GenericAOEs(module) { public readonly List AOEs = new(5); - private static readonly AOEShapeRect rect = new(50, 5); + private static readonly AOEShapeRect rect = new(50f, 5f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -66,7 +66,7 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) for (var i = 0; i < max; ++i) // either 2 or 3 AOEs in a wave, no need to iterate on all 5 { var aoe = AOEs[i]; - if ((aoe.Activation - firstact).TotalSeconds < 1) + if ((aoe.Activation - firstact).TotalSeconds < 1d) aoes.Add(aoe); } return aoes; @@ -74,11 +74,11 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.LoyalFlameBlue or AID.LoyalFlameRed) + if (spell.Action.ID is (uint)AID.LoyalFlameBlue or (uint)AID.LoyalFlameRed) { - var isBlue = (AID)spell.Action.ID == AID.LoyalFlameBlue; - AddAOEs(Module.Enemies(OID.OrbOfImmolationBlue), spell, isBlue ? 2.2f : 4.4f); - AddAOEs(Module.Enemies(OID.OrbOfImmolationRed), spell, isBlue ? 4.4f : 2.2f); + var isBlue = spell.Action.ID == (uint)AID.LoyalFlameBlue; + AddAOEs(Module.Enemies((uint)OID.OrbOfImmolationBlue), spell, isBlue ? 2.2f : 4.4f); + AddAOEs(Module.Enemies((uint)OID.OrbOfImmolationRed), spell, isBlue ? 4.4f : 2.2f); if (!isBlue) AOEs.Reverse(); } @@ -89,13 +89,13 @@ private void AddAOEs(List orbs, ActorCastInfo spell, float delay) for (var i = 0; i < orbs.Count; ++i) { var orb = orbs[i]; - AOEs.Add(new(rect, orb.Position, orb.Position.X < -632 ? Angle.AnglesCardinals[3] : Angle.AnglesCardinals[2], Module.CastFinishAt(spell, delay))); + AOEs.Add(new(rect, WPos.ClampToGrid(orb.Position), orb.Position.X < -632f ? Angle.AnglesCardinals[3] : Angle.AnglesCardinals[2], Module.CastFinishAt(spell, delay))); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (AOEs.Count != 0 && (AID)spell.Action.ID is AID.LitPathBlue or AID.LitPathRed) + if (AOEs.Count != 0 && spell.Action.ID is (uint)AID.LitPathBlue or (uint)AID.LitPathRed) AOEs.RemoveAt(0); } } @@ -103,7 +103,7 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) class Burn(BossModule module) : Components.GenericAOEs(module) { private readonly List _aoes = new(16); - private static readonly AOEShapeCircle circle = new(10); + private static readonly AOEShapeCircle circle = new(10f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -111,19 +111,19 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (count == 0) return []; var max = count > 8 ? 8 : count; - List aoes = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) // 8 AOEs in a wave, no need to iterate on all 16 - aoes.Add(_aoes[i]); + aoes[i] = _aoes[i]; return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.LoyalFlameBlue or AID.LoyalFlameRed) + if (spell.Action.ID is (uint)AID.LoyalFlameBlue or (uint)AID.LoyalFlameRed) { - var isBlue = (AID)spell.Action.ID == AID.LoyalFlameBlue; - AddAOEs(Module.Enemies(OID.OrbOfConflagrationBlue), spell, isBlue ? 2.2f : 6.2f); - AddAOEs(Module.Enemies(OID.OrbOfConflagrationRed), spell, isBlue ? 6.2f : 2.2f); + var isBlue = spell.Action.ID == (uint)AID.LoyalFlameBlue; + AddAOEs(Module.Enemies((uint)OID.OrbOfConflagrationBlue), spell, isBlue ? 2.2f : 6.2f); + AddAOEs(Module.Enemies((uint)OID.OrbOfConflagrationRed), spell, isBlue ? 6.2f : 2.2f); if (!isBlue) _aoes.Reverse(); } @@ -134,61 +134,68 @@ private void AddAOEs(List orbs, ActorCastInfo spell, float delay) for (var i = 0; i < orbs.Count; ++i) { var orb = orbs[i]; - _aoes.Add(new(circle, orb.Position, default, Module.CastFinishAt(spell, delay))); + _aoes.Add(new(circle, WPos.ClampToGrid(orb.Position), default, Module.CastFinishAt(spell, delay))); } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (_aoes.Count != 0 && (AID)spell.Action.ID is AID.BurnBlue or AID.BurnRed) + if (_aoes.Count != 0 && spell.Action.ID is (uint)AID.BurnBlue or (uint)AID.BurnRed) _aoes.RemoveAt(0); } } class Drumbeat(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.Drumbeat)); -abstract class Cleave(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65, 90.Degrees())); +abstract class Cleave(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(65f, 90f.Degrees())); class LeftwardTrisula(BossModule module) : Cleave(module, AID.LeftwardTrisula); class RightwardParasu(BossModule module) : Cleave(module, AID.RightwardParasu); -class ErrantAkasa(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ErrantAkasa), new AOEShapeCone(60, 45.Degrees())); -class CosmicWeave(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.CosmicWeave), 18); -class KarmicFlames(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.KarmicFlames), 20); -class YawningHells(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.YawningHells), 8); -class InfernalRedemption(BossModule module) : Components.RaidwideCastDelay(module, ActionID.MakeSpell(AID.InfernalRedemptionVisual), ActionID.MakeSpell(AID.InfernalRedemption), 1); +class ErrantAkasa(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ErrantAkasa), new AOEShapeCone(60f, 45f.Degrees())); +class CosmicWeave(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.CosmicWeave), 18f); +class KarmicFlames(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.KarmicFlames), 20f); +class YawningHells(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.YawningHells), 8f); +class InfernalRedemption(BossModule module) : Components.RaidwideCastDelay(module, ActionID.MakeSpell(AID.InfernalRedemptionVisual), ActionID.MakeSpell(AID.InfernalRedemption), 1f); -class DivineCall(BossModule module) : Components.StatusDrivenForcedMarch(module, 2, (uint)SID.ForwardMarch, (uint)SID.AboutFace, (uint)SID.LeftFace, (uint)SID.RightFace) +class DivineCall(BossModule module) : Components.StatusDrivenForcedMarch(module, 2f, (uint)SID.ForwardMarch, (uint)SID.AboutFace, (uint)SID.LeftFace, (uint)SID.RightFace) { private readonly LitPath _lit = module.FindComponent()!; private readonly LeftwardTrisula _aoe1 = module.FindComponent()!; private readonly RightwardParasu _aoe2 = module.FindComponent()!; - private static readonly Dictionary directionhints = new() - { - { AID.DivineCall1, "Apply backwards march debuff" }, - { AID.DivineCall2, "Apply right march debuff" }, - { AID.DivineCall3, "Apply forwards march debuff" }, - { AID.DivineCall4, "Apply left march debuff" } - }; - public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) { - return _aoe1.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) || - _aoe2.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) || - _lit.AOEs.Count != 0 && !_lit.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)); + if (_aoe1.Casters.Count != 0 && _aoe1.Casters[0].Check(pos)) + return true; + if (_aoe2.Casters.Count != 0 && _aoe2.Casters[0].Check(pos)) + return true; + var count = _lit.AOEs.Count; + for (var i = 0; i < count; ++i) + { + var aoe = _lit.AOEs[i]; + if (aoe.Shape.Check(pos, aoe.Origin, aoe.Rotation)) + return true; + } + return false; } public override void AddGlobalHints(GlobalHints hints) { - if (Module.PrimaryActor.CastInfo != null) - foreach (var entry in directionhints) - { - if (Module.PrimaryActor.CastInfo.IsSpell(entry.Key)) - { - hints.Add(entry.Value); - break; - } - } + switch (Module.PrimaryActor.CastInfo?.Action.ID) + { + case (uint)AID.DivineCall1: + hints.Add("Apply backwards march debuff"); + break; + case (uint)AID.DivineCall2: + hints.Add("Apply right march debuff"); + break; + case (uint)AID.DivineCall3: + hints.Add("Apply fowards march debuff"); + break; + case (uint)AID.DivineCall4: + hints.Add("Apply left march debuff"); + break; + } } public override void AddHints(int slot, Actor actor, TextHints hints) @@ -227,7 +234,7 @@ public DaivadipaStates(BossModule module) : base(module) } [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.Fate, GroupID = 1763, NameID = 10269)] -public class Daivadipa(WorldState ws, Actor primary) : BossModule(ws, primary, new(-608, 811), new ArenaBoundsSquare(24.5f)) +public class Daivadipa(WorldState ws, Actor primary) : BossModule(ws, primary, new(-608f, 811f), new ArenaBoundsSquare(24.5f)) { - protected override bool CheckPull() => base.CheckPull() && (Center - Raid.Player()!.Position).LengthSq() < 625; + protected override bool CheckPull() => base.CheckPull() && (Center - Raid.Player()!.Position).LengthSq() < 625f; } diff --git a/BossMod/Modules/Endwalker/TreasureHunt/TheShiftingGymnasionAgonon/GymnasiouMandragoras.cs b/BossMod/Modules/Endwalker/TreasureHunt/TheShiftingGymnasionAgonon/GymnasiouMandragoras.cs index f8542bebcf..4a4efa9a4a 100644 --- a/BossMod/Modules/Endwalker/TreasureHunt/TheShiftingGymnasionAgonon/GymnasiouMandragoras.cs +++ b/BossMod/Modules/Endwalker/TreasureHunt/TheShiftingGymnasionAgonon/GymnasiouMandragoras.cs @@ -30,9 +30,9 @@ public enum AID : uint class Ram(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.Ram)); class SaibaiMandragora(BossModule module) : Components.CastHint(module, ActionID.MakeSpell(AID.SaibaiMandragora), "Calls adds"); -class LeafDagger(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LeafDagger), 3); +class LeafDagger(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LeafDagger), 3f); -abstract class Mandragoras(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 7); +abstract class Mandragoras(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 7f); class PluckAndPrune(BossModule module) : Mandragoras(module, AID.PluckAndPrune); class TearyTwirl(BossModule module) : Mandragoras(module, AID.TearyTwirl); class HeirloomScream(BossModule module) : Mandragoras(module, AID.HeirloomScream); @@ -52,7 +52,17 @@ public GymnasiouMandragorasStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .Raw.Update = () => module.Enemies(GymnasiouMandragoras.All).All(x => x.IsDeadOrDestroyed); + .Raw.Update = () => + { + var enemies = module.Enemies(GymnasiouMandragoras.All); + var count = enemies.Count; + for (var i = 0; i < count; ++i) + { + if (!enemies[i].IsDeadOrDestroyed) + return false; + } + return true; + }; } } @@ -66,7 +76,7 @@ public class GymnasiouMandragoras(WorldState ws, Actor primary) : THTemplate(ws, protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.GymnasiouKorrigan)); + Arena.Actors(Enemies((uint)OID.GymnasiouKorrigan)); Arena.Actors(Enemies(bonusAdds), Colors.Vulnerable); } diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/ArenaChange.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/ArenaChange.cs index 46dc7af5af..945c798bc0 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/ArenaChange.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/ArenaChange.cs @@ -2,17 +2,21 @@ namespace BossMod.Endwalker.VariantCriterion.V02MR.V021Yozakura; class ArenaChange(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCustom square1 = new([new Square(V021Yozakura.ArenaCenter1, 23)], [new Square(V021Yozakura.ArenaCenter1, 20)]); - private static readonly AOEShapeCustom square2 = new([new Square(V021Yozakura.ArenaCenter3, 23)], [new Square(V021Yozakura.ArenaCenter3, 20)]); + private static readonly AOEShapeCustom square1 = new([new Square(V021Yozakura.ArenaCenter1, 23f)], [new Square(V021Yozakura.ArenaCenter1, 20f)]); + private static readonly AOEShapeCustom square2 = new([new Square(V021Yozakura.ArenaCenter3, 23f)], [new Square(V021Yozakura.ArenaCenter3, 20f)]); private AOEInstance? _aoe; public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.GloryNeverlasting && Arena.Bounds == V021Yozakura.StartingBounds && Arena.Center == V021Yozakura.ArenaCenter1) - _aoe = new(square1, Arena.Center, default, Module.CastFinishAt(spell, 3.7f)); - else if ((AID)spell.Action.ID == AID.GloryNeverlasting && Arena.Bounds == V021Yozakura.StartingBounds && Arena.Center == V021Yozakura.ArenaCenter3) - _aoe = new(square2, Arena.Center, default, Module.CastFinishAt(spell, 3.7f)); + if (spell.Action.ID == (uint)AID.GloryNeverlasting && Arena.Bounds == V021Yozakura.StartingBounds) + { + void AddAOE(AOEShape shape) => _aoe = new(shape, Arena.Center, default, Module.CastFinishAt(spell, 3.7f)); + if (Arena.Center == V021Yozakura.ArenaCenter1) + AddAOE(square1); + else if (Arena.Center == V021Yozakura.ArenaCenter3) + AddAOE(square2); + } } public override void OnEventEnvControl(byte index, uint state) diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/LevinblossomLance.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/LevinblossomLance.cs index dd369dbfaf..95a7e988dc 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/LevinblossomLance.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/LevinblossomLance.cs @@ -2,24 +2,25 @@ namespace BossMod.Endwalker.VariantCriterion.V02MR.V021Yozakura; class LevinblossomLance(BossModule module) : Components.GenericRotatingAOE(module) { - private static readonly AOEShapeRect rect = new(30, 3.5f, 30); + private static readonly AOEShapeRect rect = new(30f, 3.5f, 30f); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - switch ((AID)spell.Action.ID) + void AddSequence(Angle angle) => Sequences.Add(new(rect, spell.LocXZ, spell.Rotation, angle, Module.CastFinishAt(spell, 0.8f), 1, 5, 2)); + switch (spell.Action.ID) { - case AID.LevinblossomLanceCCW: - Sequences.Add(new(rect, spell.LocXZ, spell.Rotation, 28.Degrees(), Module.CastFinishAt(spell, 0.8f), 1, 5, 2)); + case (uint)AID.LevinblossomLanceCCW: + AddSequence(28f.Degrees()); break; - case AID.LevinblossomLanceCW: - Sequences.Add(new(rect, spell.LocXZ, spell.Rotation, -28.Degrees(), Module.CastFinishAt(spell, 0.8f), 1, 5, 2)); + case (uint)AID.LevinblossomLanceCW: + AddSequence(-28f.Degrees()); break; } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.LevinblossomLanceFirst or AID.LevinblossomLanceRest) + if (spell.Action.ID is (uint)AID.LevinblossomLanceFirst or (uint)AID.LevinblossomLanceRest) AdvanceSequence(0, WorldState.CurrentTime); } } diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/SealOfTheRiotousBloom.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/SealOfTheRiotousBloom.cs index 27effc71be..1600c2e4eb 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/SealOfTheRiotousBloom.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/SealOfTheRiotousBloom.cs @@ -3,11 +3,11 @@ namespace BossMod.Endwalker.VariantCriterion.V02MR.V021Yozakura; class SealOfRiotousBloom(BossModule module) : Components.GenericAOEs(module) { private enum Element { Fire, Water, Thunder, Wind } - private readonly List _aoes = []; - private readonly HashSet elements = []; - private static readonly AOEShapeCircle circle = new(9); - private static readonly AOEShapeDonut donut = new(5, 60); - private static readonly AOEShapeCone cone = new(70, 22.5f.Degrees()); + private readonly List _aoes = new(10); + private readonly List elements = new(4); + private static readonly AOEShapeCircle circle = new(9f); + private static readonly AOEShapeDonut donut = new(5f, 60f); + private static readonly AOEShapeCone cone = new(70f, 22.5f.Degrees()); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -15,25 +15,33 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) if (count == 0) return []; var max = count > 5 ? 5 : count; - List aoes = new(max); + var aoes = new AOEInstance[max]; for (var i = 0; i < max; ++i) - aoes.Add(_aoes[i]); + aoes[i] = _aoes[i]; return aoes; } public override void OnActorEAnim(Actor actor, uint state) { - if (Enum.TryParse(Enum.GetName(typeof(OID), actor.OID), out Element element)) + Element? element = actor.OID switch + { + (uint)OID.Fire => Element.Fire, + (uint)OID.Water => Element.Water, + (uint)OID.Wind => Element.Wind, + (uint)OID.Thunder => Element.Thunder, + _ => null + }; + if (element is Element e) { switch (state) { case 0x00100020: // seals spawn - elements.Add(element); + elements.Add(e); break; case 0x00400080: // seal activates - if (elements.Contains(element)) - ActivateAOE(element, WorldState.FutureTime(8.1f)); + if (elements.Contains(e)) + ActivateAOE(e, WorldState.FutureTime(8.1d)); break; } } @@ -41,7 +49,7 @@ public override void OnActorEAnim(Actor actor, uint state) public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (_aoes.Count > 4 && (AID)spell.Action.ID is AID.SealOfTheFireblossom or AID.SealOfTheWindblossom) + if (_aoes.Count > 4 && spell.Action.ID is (uint)AID.SealOfTheFireblossom or (uint)AID.SealOfTheWindblossom) _aoes.RemoveRange(0, 5); } @@ -50,30 +58,33 @@ private void ActivateAOE(Element element, DateTime activation) switch (element) { case Element.Fire: - _aoes.Add(new(circle, Arena.Center, default, activation)); + AddAOE(circle, activation); break; - case Element.Thunder: AddConeAOEs(Angle.AnglesCardinals, activation); break; - case Element.Water: AddConeAOEs(Angle.AnglesIntercardinals, activation); break; - case Element.Wind: - _aoes.Add(new(donut, Arena.Center, default, activation)); + AddAOE(donut, activation); break; } elements.Remove(element); - if (_aoes.Count == 5 && elements.Count != 0) - foreach (var e in elements) - ActivateAOE(e, WorldState.FutureTime(16.3f)); + var eCount = elements.Count; + if (_aoes.Count == 5 && eCount != 0) + { + Element[] ele = [.. elements]; + for (var i = 0; i < eCount; ++i) + ActivateAOE(ele[i], WorldState.FutureTime(16.3d)); + } } - private void AddConeAOEs(ReadOnlySpan angles, DateTime activationTime) + private void AddAOE(AOEShape shape, DateTime activation, Angle rotation = default) => _aoes.Add(new(shape, WPos.ClampToGrid(Arena.Center), rotation, activation)); + + private void AddConeAOEs(ReadOnlySpan angles, DateTime activation) { for (var i = 0; i < 4; ++i) - _aoes.Add(new(cone, Arena.Center, angles[i], activationTime)); + AddAOE(cone, activation, angles[i]); } } diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021Yozakura.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021Yozakura.cs index 76d70623c4..5953adcbda 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021Yozakura.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021Yozakura.cs @@ -1,79 +1,96 @@ namespace BossMod.Endwalker.VariantCriterion.V02MR.V021Yozakura; class GloryNeverlasting(BossModule module) : Components.SingleTargetDelayableCast(module, ActionID.MakeSpell(AID.GloryNeverlasting)); -class ArtOfTheFireblossom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArtOfTheFireblossom), 9); -class ArtOfTheWindblossom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArtOfTheWindblossom), new AOEShapeDonut(5, 60)); +class ArtOfTheFireblossom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArtOfTheFireblossom), 9f); +class ArtOfTheWindblossom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ArtOfTheWindblossom), new AOEShapeDonut(5f, 60f)); class KugeRantsui(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.KugeRantsui)); class OkaRanman(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.OkaRanman)); -class LevinblossomStrike(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LevinblossomStrike), 3); +class LevinblossomStrike(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LevinblossomStrike), 3f); class DriftingPetals(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.DriftingPetals), 15, ignoreImmunes: true) { + private readonly Mudrain _aoe1 = module.FindComponent()!; + private readonly Witherwind _aoe2 = module.FindComponent()!; + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - var forbidden = new List>(); - var component = Module.FindComponent()?.ActiveAOEs(slot, actor)?.ToList(); - var source = Sources(slot, actor).FirstOrDefault(); - if (source != default) + var source = Casters.Count != 0 ? Casters[0] : null; + if (source != null) { - forbidden.Add(ShapeDistance.InvertedCircle(source.Origin, 5)); - if (component != null && component.Count != 0) - foreach (var c in component) - forbidden.Add(ShapeDistance.Cone(source.Origin, 20, Angle.FromDirection(c.Origin - Arena.Center), 20.Degrees())); - if (forbidden.Count != 0) - hints.AddForbiddenZone(ShapeDistance.Union(forbidden), source.Activation); + var component = _aoe1.Sources(Module).ToList(); + var forbidden = new List> + { + ShapeDistance.InvertedCircle(source.Position, 5f) + }; + if (component.Count != 0) + for (var i = 0; i < component.Count; ++i) + forbidden.Add(ShapeDistance.Cone(source.Position, 20f, Angle.FromDirection(component[i].Position - Arena.Center), 20f.Degrees())); + hints.AddForbiddenZone(ShapeDistance.Union(forbidden), Module.CastFinishAt(source.CastInfo)); } } - public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || - (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || !Module.InBounds(pos); + public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) + { + foreach (var aoe in _aoe1.ActiveAOEs(slot, actor)) + { + if (aoe.Shape.Check(pos, aoe.Origin, aoe.Rotation)) + return true; + } + foreach (var aoe in _aoe2.ActiveAOEs(slot, actor)) + { + if (aoe.Shape.Check(pos, aoe.Origin, aoe.Rotation)) + return true; + } + return !Arena.InBounds(pos); + } } -class Mudrain(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 5, ActionID.MakeSpell(AID.Mudrain), module => module.Enemies(OID.MudVoidzone).Where(z => z.EventState != 7), 0.7f); +class Mudrain(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 5f, ActionID.MakeSpell(AID.Mudrain), module => module.Enemies((uint)OID.MudVoidzone).Where(z => z.EventState != 7), 0.7f); class Icebloom(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Icebloom), 6); -class Shadowflight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Shadowflight), new AOEShapeRect(10, 3)); -class MudPie(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MudPie), new AOEShapeRect(60, 3)); -class FireblossomFlare(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FireblossomFlare), 6); +class Shadowflight(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Shadowflight), new AOEShapeRect(10f, 3f)); +class MudPie(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MudPie), new AOEShapeRect(60f, 3f)); +class FireblossomFlare(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FireblossomFlare), 6f); class ArtOfTheFluff1(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ArtOfTheFluff1)); class ArtOfTheFluff2(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ArtOfTheFluff2)); -class TatamiGaeshi(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.TatamiGaeshi), new AOEShapeRect(40, 5)); -class AccursedSeedling(BossModule module) : Components.PersistentVoidzone(module, 4, m => m.Enemies(OID.AccursedSeedling)); +class TatamiGaeshi(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.TatamiGaeshi), new AOEShapeRect(40f, 5f)); +class AccursedSeedling(BossModule module) : Components.PersistentVoidzone(module, 4f, m => m.Enemies((uint)OID.AccursedSeedling)); -class RootArrangement(BossModule module) : Components.StandardChasingAOEs(module, new AOEShapeCircle(4), ActionID.MakeSpell(AID.RockRootArrangementFirst), ActionID.MakeSpell(AID.RockRootArrangementRest), 4, 1, 4, true, (uint)IconID.ChasingAOE) +class RootArrangement(BossModule module) : Components.StandardChasingAOEs(module, new AOEShapeCircle(4f), ActionID.MakeSpell(AID.RockRootArrangementFirst), ActionID.MakeSpell(AID.RockRootArrangementRest), 4, 1, 4, true, (uint)IconID.ChasingAOE) { public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { base.AddAIHints(slot, actor, assignment, hints); if (Actors.Contains(actor)) - hints.AddForbiddenZone(ShapeDistance.Rect(Arena.Center + new WDir(19, 0), Arena.Center + new WDir(-19, 0), 20), Activation); + hints.AddForbiddenZone(ShapeDistance.Rect(Arena.Center + new WDir(19f, default), Arena.Center + new WDir(-19f, default), 20f), Activation); } } -class Witherwind(BossModule module) : Components.PersistentVoidzone(module, 3, m => m.Enemies(OID.AutumnalTempest), 20); +class Witherwind(BossModule module) : Components.PersistentVoidzone(module, 3f, m => m.Enemies((uint)OID.AutumnalTempest), 20f); [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 945, NameID = 12325, SortOrder = 1)] public class V021Yozakura(WorldState ws, Actor primary) : BossModule(ws, primary, primary.Position.X < -700 ? ArenaCenter1 : primary.Position.X > 700 ? ArenaCenter2 : ArenaCenter3, primary.Position.X < -700 ? StartingBounds : primary.Position.X > 700 ? DefaultBounds2 : StartingBounds) { - public static readonly WPos ArenaCenter1 = new(-775, 16); - public static readonly WPos ArenaCenter2 = new(737, 220); - public static readonly WPos ArenaCenter3 = new(47, 93); + public static readonly WPos ArenaCenter1 = new(-775f, 16f); + public static readonly WPos ArenaCenter2 = new(737f, 220f); + public static readonly WPos ArenaCenter3 = new(47f, 93f); public static readonly ArenaBoundsSquare StartingBounds = new(22.5f); - public static readonly ArenaBoundsSquare DefaultBounds1 = new(20); + public static readonly ArenaBoundsSquare DefaultBounds1 = new(20f); public static readonly ArenaBoundsSquare DefaultBounds2 = new(19.5f); protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.LivingGaol)); + Arena.Actors(Enemies((uint)OID.LivingGaol)); } protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - foreach (var e in hints.PotentialTargets) + var count = hints.PotentialTargets.Count; + for (var i = 0; i < count; ++i) { - e.Priority = (OID)e.Actor.OID switch + var e = hints.PotentialTargets[i]; + e.Priority = e.Actor.OID switch { - OID.LivingGaol => 2, - OID.Boss => 1, + (uint)OID.LivingGaol => 1, _ => 0 }; } diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraStates.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraStates.cs index 531592cb85..3511def37a 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraStates.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraStates.cs @@ -14,9 +14,9 @@ public V021YozakuraStates(BossModule module) : base(module) //Left Windy .ActivateOnEnter() .ActivateOnEnter() + .ActivateOnEnter() .ActivateOnEnter() //Left Rainy - .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() diff --git a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/WindblossomWhirl.cs b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/WindblossomWhirl.cs index 4f5e1bab23..68bde306db 100644 --- a/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/WindblossomWhirl.cs +++ b/BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/WindblossomWhirl.cs @@ -8,13 +8,13 @@ class WindblossomWhirl(BossModule module) : Components.GenericAOEs(module) public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.WindblossomWhirlVisual) + if (spell.Action.ID == (uint)AID.WindblossomWhirlVisual) _aoe = new(donut, Arena.Center, default, Module.CastFinishAt(spell, 6.3f)); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.WindblossomWhirl1 or AID.WindblossomWhirl2) + if (spell.Action.ID is (uint)AID.WindblossomWhirl1 or (uint)AID.WindblossomWhirl2) { if (++NumCasts == 5 && _aoe != null) { diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs b/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs index c15e31e502..8e456ceda1 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D01Holminster/D013Philia.cs @@ -28,12 +28,12 @@ public enum AID : uint IntoTheLightMarker = 15844, // Helper->player, no cast, single-target, line stack IntoTheLightVisual = 17232, // Boss->self, 5.0s cast, single-target IntoTheLight = 15845, // Boss->self, no cast, range 50 width 8 rect - FierceBeating1 = 15834, // Boss->self, 5.0s cast, single-target - FierceBeating2 = 15836, // Boss->self, no cast, single-target - FierceBeating3 = 15835, // Boss->self, no cast, single-target - FierceBeating4 = 15837, // Helper->self, 5.0s cast, range 4 circle - FierceBeating5 = 15839, // Helper->location, no cast, range 4 circle - FierceBeating6 = 15838, // Helper->self, no cast, range 4 circle + FierceBeatingRotationVisual = 15834, // Boss->self, 5.0s cast, single-target + FierceBeatingVisual1 = 15836, // Boss->self, no cast, single-target + FierceBeatingVisual2 = 15835, // Boss->self, no cast, single-target + FierceBeatingExaFirst = 15837, // Helper->self, 5.0s cast, range 4 circle + FierceBeatingExaRestFirst = 15838, // Helper->self, no cast, range 4 circle + FierceBeatingExaRestRest = 15839, // Helper->location, no cast, range 4 circle CatONineTailsVisual = 15840, // Boss->self, no cast, single-target CatONineTails = 15841 // Helper->self, 2.0s cast, range 25 120-degree cone } @@ -185,7 +185,7 @@ class CatONineTails(BossModule module) : Components.GenericRotatingAOE(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if (spell.Action.ID == (uint)AID.FierceBeating1) + if (spell.Action.ID == (uint)AID.FierceBeatingRotationVisual) Sequences.Add(new(_shape, spell.LocXZ, spell.Rotation + 180f.Degrees(), -45f.Degrees(), Module.CastFinishAt(spell), 2, 8)); } @@ -198,12 +198,8 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) class FierceBeating(BossModule module) : Components.Exaflare(module, 4f) { - private readonly List _casters = []; - private int linesstartedcounttotal; - private int linesstartedcount1; - private int linesstartedcount2; private static readonly AOEShapeCircle circle = new(4f); - private DateTime _activation; + private readonly List _aoes = new(2); public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -214,83 +210,73 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) var imminentAOEs = ImminentAOEs(linesCount); var futureCount = futureAOEs.Count; var imminentCount = imminentAOEs.Length; - var total = futureCount + imminentCount; + var aoesCount = _aoes.Count; + var total = futureCount + imminentCount + aoesCount; var index = 0; - var aoes = new AOEInstance[total + 2]; + var aoes = new AOEInstance[total]; for (var i = 0; i < futureCount; ++i) { var aoe = futureAOEs[i]; aoes[index++] = new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, FutureColor); } - for (var i = 0; i < imminentCount; ++i) { var aoe = imminentAOEs[i]; aoes[index++] = new(Shape, aoe.Item1, aoe.Item3, aoe.Item2, ImminentColor); } - if (linesstartedcount1 < 8) - aoes[index++] = new(circle, WPos.ClampToGrid(WPos.RotateAroundOrigin(linesstartedcount1 * 45, D013Philia.ArenaCenter, _casters[0])), default, _activation.AddSeconds(linesstartedcount1 * 3.7d)); - if (linesCount > 1 && linesstartedcount2 < 8) - aoes[index++] = new(circle, WPos.ClampToGrid(WPos.RotateAroundOrigin(linesstartedcount2 * 45, D013Philia.ArenaCenter, _casters[1])), default, _activation.AddSeconds(linesstartedcount2 * 3.7d)); - return aoes[..index]; - } - - public override void Update() - { - if (linesstartedcount1 != 0 && Lines.Count == 0) + for (var i = 0; i < _aoes.Count; ++i) { - linesstartedcounttotal = 0; - linesstartedcount1 = 0; - linesstartedcount2 = 0; - _casters.Clear(); + var aoe = _aoes[i]; + aoes[index++] = aoe; } + return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if (spell.Action.ID == (uint)AID.FierceBeating4) + if (spell.Action.ID == (uint)AID.FierceBeatingExaFirst) { - Lines.Add(new() { Next = spell.LocXZ, Advance = 2.5f * spell.Rotation.ToDirection(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 1f, ExplosionsLeft = 7, MaxShownExplosions = 3 }); - _activation = Module.CastFinishAt(spell); - ++linesstartedcounttotal; - ++NumCasts; - _casters.Add(caster.Position); - if (linesstartedcounttotal % 2 != 0) - ++linesstartedcount1; - else - ++linesstartedcount2; + AddLine(ref caster, Module.CastFinishAt(spell)); } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if (spell.Action.ID == (uint)AID.FierceBeating6) + if (spell.Action.ID == (uint)AID.FierceBeatingExaRestFirst) { - Lines.Add(new() { Next = caster.Position, Advance = 2.5f * caster.Rotation.ToDirection(), NextExplosion = WorldState.FutureTime(1), TimeToMove = 1f, ExplosionsLeft = 7, MaxShownExplosions = 3 }); - ++linesstartedcounttotal; - if (linesstartedcounttotal % 2 != 0) - ++linesstartedcount1; - else - ++linesstartedcount2; + AddLine(ref caster, WorldState.FutureTime(1d)); } - if (Lines.Count > 0) + if (Lines.Count != 0) { - if (spell.Action.ID is (uint)AID.FierceBeating4 or (uint)AID.FierceBeating6) - { - var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1f)); - AdvanceLine(Lines[index], caster.Position); - if (Lines[index].ExplosionsLeft == 0) - Lines.RemoveAt(index); - } - else if (spell.Action.ID == (uint)AID.FierceBeating5) - { - var index = Lines.FindIndex(item => item.Next.AlmostEqual(spell.TargetXZ, 1f)); - AdvanceLine(Lines[index], spell.TargetXZ); - if (Lines[index].ExplosionsLeft == 0) - Lines.RemoveAt(index); - } + if (spell.Action.ID is (uint)AID.FierceBeatingExaFirst or (uint)AID.FierceBeatingExaRestFirst) + Advance(caster.Position); + else if (spell.Action.ID == (uint)AID.FierceBeatingExaRestRest) + Advance(spell.TargetXZ); + } + + void Advance(WPos pos) + { + var index = Lines.FindIndex(item => item.Next.AlmostEqual(pos, 1f)); + if (index < 0) + return; + AdvanceLine(Lines[index], pos); + if (Lines[index].ExplosionsLeft == 0) + Lines.RemoveAt(index); } } + + public void AddLine(ref Actor caster, DateTime activation) + { + var adv = 2.5f * caster.Rotation.ToDirection(); + Lines.Add(new() { Next = caster.Position, Advance = adv, NextExplosion = activation, TimeToMove = 1f, ExplosionsLeft = 7, MaxShownExplosions = 3 }); + ++NumCasts; + if (_aoes.Count != 0 && NumCasts > 2) + _aoes.RemoveAt(0); + if (NumCasts <= 14) + _aoes.Add(new(circle, WPos.ClampToGrid(WPos.RotateAroundOrigin(45, D013Philia.ArenaCenter, caster.Position + adv)), default, WorldState.FutureTime(3.7d))); + if (NumCasts == 16) + NumCasts = 0; + } } class D013PhiliaStates : StateMachineBuilder diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/BA1Art.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/BA1Art.cs index 16ca261d7f..ed1676033c 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/BA1Art.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/BA1Art.cs @@ -2,13 +2,13 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA1Art; class Thricecull(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.Thricecull)); class AcallamNaSenorach(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.AcallamNaSenorach)); -class DefilersDeserts(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DefilersDeserts), new AOEShapeRect(35.5f, 4)); -class Pitfall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Pitfall), 20); -class LegendaryGeasAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LegendaryGeas), 8); +class DefilersDeserts(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.DefilersDeserts), new AOEShapeRect(35.5f, 4f)); +class Pitfall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Pitfall), 20f); +class LegendaryGeasAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.LegendaryGeas), 8f); class DefilersDesertsPredict(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCross cross = new(35.5f, 4); + private static readonly AOEShapeCross cross = new(35.5f, 4f); private readonly List _aoes = new(2); public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; @@ -16,12 +16,12 @@ class DefilersDesertsPredict(BossModule module) : Components.GenericAOEs(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { void AddAOE(Angle angle) => _aoes.Add(new(cross, spell.LocXZ, angle, Module.CastFinishAt(spell, 6.9f))); - if ((AID)spell.Action.ID == AID.LegendaryGeas) + if (spell.Action.ID == (uint)AID.LegendaryGeas) { - AddAOE(45.Degrees()); + AddAOE(45f.Degrees()); AddAOE(default); } - else if ((AID)spell.Action.ID == AID.DefilersDeserts) + else if (spell.Action.ID == (uint)AID.DefilersDeserts) _aoes.Clear(); } } @@ -30,7 +30,7 @@ class LegendaryGeasStay(BossModule module) : Components.StayMove(module) { public override void OnActorEAnim(Actor actor, uint state) { - if ((OID)actor.OID == OID.ShadowLinksHelper && actor.Position.AlmostEqual(new(-134.917f, 750.44f), 1)) + if (actor.OID == (uint)OID.ShadowLinksHelper && actor.Position.AlmostEqual(new(-135f, 750f), 1f)) { if (state == 0x00010002) Array.Fill(PlayerStates, new(Requirement.Stay2, WorldState.CurrentTime, 1)); @@ -46,6 +46,6 @@ class PiercingDark(BossModule module) : Components.SpreadFromCastTargets(module, [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.BaldesionArsenal, GroupID = 639, NameID = 7968, PlanLevel = 70, SortOrder = 1)] public class BA1Art(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-128.98f, 748), 29.5f, 64)], [new Rectangle(new(-129, 718), 20, 1.15f), new Rectangle(new(-129, 778), 20, 1.48f), - new Polygon(new(-123.5f, 778), 1.7f, 8), new Polygon(new(-134.5f, 778), 1.7f, 8), new Polygon(new(-123.5f, 718), 1.5f, 8), new Polygon(new(-134.5f, 718), 1.5f, 8)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-128.98f, 748f), 29.5f, 64)], [new Rectangle(new(-129f, 718f), 20, 1.15f), new Rectangle(new(-129f, 778f), 20f, 1.48f), + new Polygon(new(-123.5f, 778f), 1.7f, 8), new Polygon(new(-134.5f, 778f), 1.7f, 8), new Polygon(new(-123.5f, 718f), 1.5f, 8), new Polygon(new(-134.5f, 718f), 1.5f, 8)]); } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/LegendMythSpinnerCarver.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/LegendMythSpinnerCarver.cs index ffcc693653..626aa3b532 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/LegendMythSpinnerCarver.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Art/LegendMythSpinnerCarver.cs @@ -2,8 +2,8 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA1Art; class LegendMythSpinnerCarver(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCircle circle = new(15); - private static readonly AOEShapeDonut donut = new(7, 22); + private static readonly AOEShapeCircle circle = new(15f); + private static readonly AOEShapeDonut donut = new(7f, 22f); public readonly List AOEs = new(5); private bool mythcall; @@ -11,41 +11,42 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) { var count = AOEs.Count; if (count == 0) - yield break; - + return []; + var aoes = new AOEInstance[count]; for (var i = 0; i < count; ++i) { var aoe = AOEs[i]; if (count == 5 && i == 0) - yield return aoe with { Color = Colors.Danger }; + aoes[i] = aoe with { Color = Colors.Danger }; else - yield return aoe; + aoes[i] = aoe; } + return aoes; } public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - void AddAOE(AOEShape shape) => AOEs.Add(new(shape, caster.Position, default, Module.CastFinishAt(spell))); + void AddAOE(AOEShape shape) => AOEs.Add(new(shape, spell.LocXZ, default, Module.CastFinishAt(spell))); void AddAOEs(AOEShape shape) { - var orlasrach = Module.Enemies(OID.Orlasrach); + var orlasrach = Module.Enemies((uint)OID.Orlasrach); for (var i = 0; i < orlasrach.Count; ++i) - AOEs.Add(new(shape, orlasrach[i].Position, default, Module.CastFinishAt(spell, 2.6f))); + AOEs.Add(new(shape, WPos.ClampToGrid(orlasrach[i].Position), default, Module.CastFinishAt(spell, 2.6f))); mythcall = false; } - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.Legendcarver: + case (uint)AID.Legendcarver: AddAOE(circle); if (mythcall) AddAOEs(circle); break; - case AID.Legendspinner: + case (uint)AID.Legendspinner: AddAOE(donut); if (mythcall) AddAOEs(donut); break; - case AID.Mythcall: + case (uint)AID.Mythcall: mythcall = true; break; } @@ -53,7 +54,7 @@ void AddAOEs(AOEShape shape) public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if (AOEs.Count != 0 && (AID)spell.Action.ID is AID.Legendcarver or AID.Legendspinner or AID.Mythcarver or AID.Mythspinner) + if (AOEs.Count != 0 && spell.Action.ID is (uint)AID.Legendcarver or (uint)AID.Legendspinner or (uint)AID.Mythcarver or (uint)AID.Mythspinner) AOEs.RemoveAt(0); } } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/BA1Owain.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/BA1Owain.cs index 95af41abfb..ca43f96252 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/BA1Owain.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/BA1Owain.cs @@ -3,28 +3,29 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA1Owain; class Thricecull(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.Thricecull)); class AcallamNaSenorach(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.AcallamNaSenorach)); class LegendaryImbas(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.LegendaryImbas)); // applies dorito stacks, seems to get skipped if less than 4 people alive? -class Pitfall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Pitfall), 20); +class Pitfall(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Pitfall), 20f); [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.BaldesionArsenal, GroupID = 639, NameID = 7970, PlanLevel = 70, SortOrder = 2)] public class BA1Owain(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(128.98f, 748), 29.5f, 64)], [new Rectangle(new(129, 718), 20, 0.8f), new Rectangle(new(129, 778), 20, 0.825f), - new Polygon(new(123.5f, 778), 1.5f, 8), new Polygon(new(134.5f, 778), 1.5f, 8), new Polygon(new(123.5f, 718), 1.5f, 8), new Polygon(new(134.5f, 718), 1.5f, 8)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(128.98f, 748f), 29.5f, 64)], [new Rectangle(new(129f, 718f), 20f, 0.8f), new Rectangle(new(129f, 778f), 20f, 0.825f), + new Polygon(new(123.5f, 778f), 1.5f, 8), new Polygon(new(134.5f, 778f), 1.5f, 8), new Polygon(new(123.5f, 718f), 1.5f, 8), new Polygon(new(134.5f, 718f), 1.5f, 8)]); protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.IvoryPalm)); + Arena.Actors(Enemies((uint)OID.IvoryPalm)); } protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - for (var i = 0; i < hints.PotentialTargets.Count; ++i) + var count = hints.PotentialTargets.Count; + for (var i = 0; i < count; ++i) { var e = hints.PotentialTargets[i]; - e.Priority = (OID)e.Actor.OID switch + e.Priority = e.Actor.OID switch { - OID.IvoryPalm => 1, + (uint)OID.IvoryPalm => 1, _ => 0 }; } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/ElementalMagicks.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/ElementalMagicks.cs index 8b77c274ab..d23c5f165d 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/ElementalMagicks.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/ElementalMagicks.cs @@ -2,39 +2,39 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA1Owain; class ElementalMagicks(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCircle circle = new(13); + private static readonly AOEShapeCircle circle = new(13f); public readonly List AOEs = new(5); public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - void AddAOEs(SID sid) + void AddAOEs(uint sid) { - var mundberg = Module.Enemies(OID.Munderg); + var mundberg = Module.Enemies((uint)OID.Munderg); var activation = Module.CastFinishAt(spell); for (var i = 0; i < mundberg.Count; ++i) { var spear = mundberg[i]; if (spear.FindStatus(sid) != null) - AOEs.Add(new(circle, spear.Position, default, activation)); + AOEs.Add(new(circle, WPos.ClampToGrid(spear.Position), default, activation)); } AOEs.Add(new(circle, spell.LocXZ, default, activation)); } - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.ElementalMagicksFireBoss: - AddAOEs(SID.SoulOfFire); + case (uint)AID.ElementalMagicksFireBoss: + AddAOEs((uint)SID.SoulOfFire); break; - case AID.ElementalMagicksIceBoss: - AddAOEs(SID.SoulOfIce); + case (uint)AID.ElementalMagicksIceBoss: + AddAOEs((uint)SID.SoulOfIce); break; } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if (AOEs.Count != 0 && (AID)spell.Action.ID is AID.ElementalMagicksFireBoss or AID.ElementalMagicksFireSpears or AID.ElementalMagicksIceBoss or AID.ElementalMagicksIceSpears) + if (AOEs.Count != 0 && spell.Action.ID is (uint)AID.ElementalMagicksFireBoss or (uint)AID.ElementalMagicksFireSpears or (uint)AID.ElementalMagicksIceBoss or (uint)AID.ElementalMagicksIceSpears) AOEs.RemoveAt(0); } } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/IvoryPalm.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/IvoryPalm.cs index 93ff16ea4d..eb7beb7405 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/IvoryPalm.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/IvoryPalm.cs @@ -8,16 +8,17 @@ public override IEnumerable ActiveEyes(int slot, Actor actor) { var count = Tethers.Count; if (count == 0) - yield break; + return []; + for (var i = 0; i < count; ++i) { var tether = Tethers[i]; if (tether.target == actor && !tether.source.IsDead) // apparently tethers don't get removed immediately upon death { - yield return new(tether.source.Position); - yield break; + return [new(tether.source.Position)]; } } + return []; } public override void AddHints(int slot, Actor actor, TextHints hints) @@ -46,7 +47,7 @@ public override void OnUntethered(Actor source, ActorTetherInfo tether) class IvoryPalmExplosion(BossModule module) : Components.CastHint(module, ActionID.MakeSpell(AID.Explosion), "Ivory Palm is enraging!", true); -class EurekanAero(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.EurekanAero), new AOEShapeCone(6, 60.Degrees()), [(uint)OID.IvoryPalm]) +class EurekanAero(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.EurekanAero), new AOEShapeCone(6f, 60f.Degrees()), [(uint)OID.IvoryPalm]) { public override List<(Actor origin, Actor target, Angle angle)> OriginsAndTargets() { @@ -55,7 +56,7 @@ class IvoryPalmExplosion(BossModule module) : Components.CastHint(module, Action for (var i = 0; i < count; ++i) { var enemy = Enemies[i]; - if (enemy.IsDead || enemy.FindStatus(SID.Petrification) != null) + if (enemy.IsDead || enemy.FindStatus((uint)SID.Petrification) != null) continue; var target = WorldState.Actors.Find(enemy.TargetID); diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/Spiritcull.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/Spiritcull.cs index e7b6dbdb73..6debbd18cb 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/Spiritcull.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA1Owain/Spiritcull.cs @@ -1,7 +1,7 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA1Owain; -class PiercingLight1(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.PiercingLight1), 6); -class PiercingLight2(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.PiercingLight2), 6); +class PiercingLight1(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.PiercingLight1), 6f); +class PiercingLight2(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.PiercingLight2), 6f); class Spiritcull(BossModule module) : Components.GenericStackSpread(module) { @@ -9,17 +9,17 @@ class Spiritcull(BossModule module) : Components.GenericStackSpread(module) public override void OnEventIcon(Actor actor, uint iconID, ulong targetID) { - if ((IconID)iconID == IconID.DoritoStack) + if (iconID == (uint)IconID.DoritoStack) { targets.Add(actor); if (Stacks.Count == 0) - Stacks.Add(new(actor, 1.5f, 24, 24, activation: WorldState.FutureTime(5.1f))); + Stacks.Add(new(actor, 1.5f, 24, 24, activation: WorldState.FutureTime(5.1d))); } } public override void OnStatusLose(Actor actor, ActorStatus status) { - if ((SID)status.ID == SID.BloodSacrifice) + if (status.ID == (uint)SID.BloodSacrifice) { targets.Clear(); Stacks.Clear(); @@ -45,8 +45,8 @@ public override void DrawArenaForeground(int pcSlot, Actor pc) Actor? actor = null; var minDistanceSq = float.MaxValue; - - for (var i = 0; i < targets.Count; ++i) + var count = targets.Count; + for (var i = 0; i < count; ++i) { var target = targets[i]; if (target == pc) diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/ArenaChange.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/ArenaChange.cs index 3fe0d141a5..38e19e704f 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/ArenaChange.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/ArenaChange.cs @@ -9,13 +9,13 @@ class ArenaChange(BossModule module) : Components.GenericAOEs(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.Thundercall) + if (spell.Action.ID == (uint)AID.Thundercall) _aoe = new(donut, Arena.Center, default, Module.CastFinishAt(spell, 3.4f)); } public override void OnActorEAnim(Actor actor, uint state) { - if ((OID)actor.OID == OID.Electricwall) + if (actor.OID == (uint)OID.Electricwall) { if (state == 0x00010002) { diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/BA2Raiden.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/BA2Raiden.cs index b2cfd56bca..f804621d57 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/BA2Raiden.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/BA2Raiden.cs @@ -9,15 +9,15 @@ class Shingan(BossModule module) : Components.SingleTargetCast(module, ActionID. { public override bool KeepOnPhaseChange => true; } -class AmeNoSakahoko(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AmeNoSakahoko), 25) +class AmeNoSakahoko(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.AmeNoSakahoko), 25f) { public override bool KeepOnPhaseChange => true; } -class WhirlingZantetsuken(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WhirlingZantetsuken), new AOEShapeDonut(5, 60)) +class WhirlingZantetsuken(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WhirlingZantetsuken), new AOEShapeDonut(5f, 60f)) { public override bool KeepOnPhaseChange => true; } -class Shock(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Shock), 8); +class Shock(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Shock), 8f); class ForHonor(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ForHonor), 11.4f); abstract class LateralZantetsuken(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(75.4f, 19.5f)); @@ -25,8 +25,8 @@ class LateralZantetsuken1(BossModule module) : LateralZantetsuken(module, AID.La class LateralZantetsuken2(BossModule module) : LateralZantetsuken(module, AID.LateralZantetsuken2); class BitterBarbs(BossModule module) : Components.Chains(module, (uint)TetherID.Chains, ActionID.MakeSpell(AID.BitterBarbs)); -class BoomingLament(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.BoomingLament), 10); -class SilentLevin(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SilentLevin), 5); +class BoomingLament(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.BoomingLament), 10f); +class SilentLevin(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SilentLevin), 5f); class UltimateZantetsuken(BossModule module) : Components.CastHint(module, ActionID.MakeSpell(AID.UltimateZantetsuken), "Enrage, kill the adds!", true); @@ -34,24 +34,25 @@ class UltimateZantetsuken(BossModule module) : Components.CastHint(module, Actio public class BA2Raiden(WorldState ws, Actor primary) : BossModule(ws, primary, startingArena.Center, startingArena) { private static readonly WPos ArenaCenter = new(0, 458); - private static readonly ArenaBoundsComplex startingArena = new([new Polygon(ArenaCenter, 34.6f, 80)], [new Rectangle(new(35.3f, 458), 0.99f, 20), new Rectangle(new(-35.4f, 458), 1.65f, 20), + private static readonly ArenaBoundsComplex startingArena = new([new Polygon(ArenaCenter, 34.6f, 80)], [new Rectangle(new(35.3f, 458f), 0.99f, 20f), new Rectangle(new(-35.4f, 458f), 1.65f, 20f), new Rectangle(new(0, 493), 20, 0.75f)]); public static readonly ArenaBoundsComplex DefaultArena = new([new Polygon(ArenaCenter, 29.93f, 64)]); protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.StreakLightning)); + Arena.Actors(Enemies((uint)OID.StreakLightning)); } protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - for (var i = 0; i < hints.PotentialTargets.Count; ++i) + var count = hints.PotentialTargets.Count; + for (var i = 0; i < count; ++i) { var e = hints.PotentialTargets[i]; - e.Priority = (OID)e.Actor.OID switch + e.Priority = e.Actor.OID switch { - OID.StreakLightning => 1, + (uint)OID.StreakLightning => 1, _ => 0 }; } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/CloudToGround.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/CloudToGround.cs index 0a1aabaaf6..8f604bd719 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/CloudToGround.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/CloudToGround.cs @@ -4,18 +4,18 @@ class CloudToGround(BossModule module) : Components.Exaflare(module, 6) { public override void OnCastStarted(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID == AID.CloudToGroundFirst) + if (spell.Action.ID == (uint)AID.CloudToGroundFirst) { - var explosions = spell.LocXZ.InRect(Arena.Center, spell.Rotation, 35, 35, 15) ? 8 : spell.LocXZ.InRect(Arena.Center, spell.Rotation, 35, 35, 20) ? 6 : 4; - Lines.Add(new() { Next = spell.LocXZ, Advance = 8 * spell.Rotation.ToDirection(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 1.1f, ExplosionsLeft = explosions, MaxShownExplosions = 10 }); + var explosions = spell.LocXZ.InRect(Arena.Center, spell.Rotation, 35f, 35f, 15f) ? 8 : spell.LocXZ.InRect(Arena.Center, spell.Rotation, 35f, 35f, 20f) ? 6 : 4; + Lines.Add(new() { Next = caster.Position, Advance = 8f * spell.Rotation.ToDirection(), NextExplosion = Module.CastFinishAt(spell), TimeToMove = 1.1f, ExplosionsLeft = explosions, MaxShownExplosions = 10 }); } } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.CloudToGroundFirst or AID.CloudToGroundRest) + if (spell.Action.ID is (uint)AID.CloudToGroundFirst or (uint)AID.CloudToGroundRest) { - var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1)); + var index = Lines.FindIndex(item => item.Next.AlmostEqual(caster.Position, 1f)); if (index == -1) return; AdvanceLine(Lines[index], caster.Position); diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/LancingBlow.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/LancingBlow.cs index a37ab265fc..b88387cdb6 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/LancingBlow.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA2Raiden/LancingBlow.cs @@ -1,30 +1,30 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA2Raiden; -class LancingBlowSpread(BossModule module) : Components.SpreadFromIcon(module, (uint)IconID.Spreadmarker, ActionID.MakeSpell(AID.LancingBlow), 10, 6) +class LancingBlowSpread(BossModule module) : Components.SpreadFromIcon(module, (uint)IconID.Spreadmarker, ActionID.MakeSpell(AID.LancingBlow), 10f, 6f) { public override void OnActorCreated(Actor actor) { - if ((OID)actor.OID == OID.StreakLightning) + if (actor.OID == (uint)OID.StreakLightning) Spreads.Clear(); } } class LancingBlowAOE(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCircle circle = new(10); + private static readonly AOEShapeCircle circle = new(10f); public readonly List AOEs = new(6); public override IEnumerable ActiveAOEs(int slot, Actor actor) => AOEs; public override void OnActorCreated(Actor actor) { - if ((OID)actor.OID == OID.StreakLightning) - AOEs.Add(new(circle, actor.Position, default, WorldState.FutureTime(1))); + if (actor.OID == (uint)OID.StreakLightning) + AOEs.Add(new(circle, WPos.ClampToGrid(actor.Position), default, WorldState.FutureTime(1d))); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID == AID.LancingBlow) + if (spell.Action.ID == (uint)AID.LancingBlow) { ++NumCasts; AOEs.Clear(); diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/BA3AbsoluteVirtue.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/BA3AbsoluteVirtue.cs index 66f3a7158c..6e4720aa60 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/BA3AbsoluteVirtue.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/BA3AbsoluteVirtue.cs @@ -1,8 +1,8 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA3AbsoluteVirtue; class Meteor(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Meteor)); -class MedusaJavelin(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MedusaJavelin), new AOEShapeCone(65.4f, 45.Degrees())); -class AuroralWind(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.AuroralWind), new AOEShapeCircle(5), true) +class MedusaJavelin(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.MedusaJavelin), new AOEShapeCone(65.4f, 45f.Degrees())); +class AuroralWind(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.AuroralWind), new AOEShapeCircle(5f), true) { public override void AddGlobalHints(GlobalHints hints) { @@ -11,7 +11,7 @@ public override void AddGlobalHints(GlobalHints hints) } } -abstract class ExplosiveImpulse(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 18); +abstract class ExplosiveImpulse(BossModule module, AID aid) : Components.SimpleAOEs(module, ActionID.MakeSpell(aid), 18f); class ExplosiveImpulse1(BossModule module) : ExplosiveImpulse(module, AID.ExplosiveImpulse1); class ExplosiveImpulse2(BossModule module) : ExplosiveImpulse(module, AID.ExplosiveImpulse2); @@ -21,24 +21,25 @@ class MeteorEnrageCounter(BossModule module) : Components.CastCounter(module, Ac [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.BaldesionArsenal, GroupID = 639, NameID = 7976, PlanLevel = 70, SortOrder = 4)] public class BA3AbsoluteVirtue(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-175, 314), 29.95f, 96), new Rectangle(new(-146, 314), 0.8f, 5.8f), new Rectangle(new(-175, 285), 6, 1.05f)], - [new Rectangle(new(-144.4f, 314), 0.8f, 5.8f), new Polygon(new(-144.85f, 306.75f), 1.5f, 8, 22.5f.Degrees()), new Polygon(new(-144.85f, 321.25f), 1.5f, 8, 22.5f.Degrees()), - new Rectangle(new(-206, 314), 1.525f, 20)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-175, 314), 29.95f, 96), new Rectangle(new(-146f, 314f), 0.8f, 5.8f), new Rectangle(new(-175f, 285f), 6f, 1.05f)], + [new Rectangle(new(-144.4f, 314f), 0.8f, 5.8f), new Polygon(new(-144.85f, 306.75f), 1.5f, 8, 22.5f.Degrees()), new Polygon(new(-144.85f, 321.25f), 1.5f, 8, 22.5f.Degrees()), + new Rectangle(new(-206, 314), 1.525f, 20f)]); protected override void DrawEnemies(int pcSlot, Actor pc) { Arena.Actor(PrimaryActor); - Arena.Actors(Enemies(OID.AernsWynav)); + Arena.Actors(Enemies((uint)OID.AernsWynav)); } protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - for (var i = 0; i < hints.PotentialTargets.Count; ++i) + var count = hints.PotentialTargets.Count; + for (var i = 0; i < count; ++i) { var e = hints.PotentialTargets[i]; - e.Priority = (OID)e.Actor.OID switch + e.Priority = e.Actor.OID switch { - OID.AernsWynav => 1, + (uint)OID.AernsWynav => 1, _ => 0 }; } diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/DarkBrightAuroraTowers.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/DarkBrightAuroraTowers.cs index 819afe9070..cc92c96d88 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/DarkBrightAuroraTowers.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/DarkBrightAuroraTowers.cs @@ -2,7 +2,7 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA3AbsoluteVirtue; class BrightDarkAuroraExplosion(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCircle circle = new(8); + private static readonly AOEShapeCircle circle = new(8f); private readonly List<(Actor source, ulong target)> tetherByActor = new(8); public override IEnumerable ActiveAOEs(int slot, Actor actor) @@ -22,13 +22,14 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) break; } } - - List aoes = new(count); + var countAdj = isActorTarget ? count - 1 : count; + var aoes = new AOEInstance[countAdj]; + var index = 0; for (var i = 0; i < count; ++i) { var tether = tetherByActor[i]; if (tether.target != actor.InstanceID) - aoes.Add(new(circle, tetherByActor[i].source.Position, Risky: !isActorTarget)); + aoes[index++] = new(circle, WPos.ClampToGrid(tetherByActor[i].source.Position), Risky: !isActorTarget); } return aoes; } @@ -44,14 +45,14 @@ public override void OnUntethered(Actor source, ActorTetherInfo tether) } } -abstract class Towers(BossModule module, OID oid, TetherID tid) : Components.GenericTowersOpenWorld(module) +abstract class Towers(BossModule module, uint oid, uint tid) : Components.GenericTowersOpenWorld(module) { private readonly List<(Actor source, Actor target)> tetherByActor = new(4); private const string Hint = "Stand in a tower of opposite tether element!"; public override void OnActorEAnim(Actor actor, uint state) { - if ((OID)actor.OID == oid) + if (actor.OID == oid) { if (state == 0x00040008) { @@ -70,19 +71,19 @@ public override void OnActorEAnim(Actor actor, uint state) public override void OnActorCreated(Actor actor) { - if ((OID)actor.OID == oid) - Towers.Add(new(actor.Position, 2, 1, 1, [], WorldState.FutureTime(20))); + if (actor.OID == oid) + Towers.Add(new(actor.Position, 2f, 1, 1, [], WorldState.FutureTime(20d))); } public override void OnTethered(Actor source, ActorTetherInfo tether) { - if (tether.ID == (uint)tid) + if (tether.ID == tid) tetherByActor.Add((source, WorldState.Actors.Find(tether.Target)!)); } public override void OnUntethered(Actor source, ActorTetherInfo tether) { - if (tether.ID == (uint)tid) + if (tether.ID == tid) tetherByActor.Remove((source, WorldState.Actors.Find(tether.Target)!)); } @@ -146,7 +147,7 @@ public override void DrawArenaForeground(int pcSlot, Actor pc) if (source != null) { Arena.AddLine(source.Position, pc.Position); - Arena.AddCircle(source.Position, 2); + Arena.AddCircle(source.Position, 2f); Arena.Actor(source, Colors.Object, true); } } @@ -164,5 +165,5 @@ public override void Update() } } -class BrightAuroraTether(BossModule module) : Towers(module, OID.DarkAuroraHelper, TetherID.BrightAurora); -class DarkAuroraTether(BossModule module) : Towers(module, OID.BrightAuroraHelper, TetherID.DarkAurora); +class BrightAuroraTether(BossModule module) : Towers(module, (uint)OID.DarkAuroraHelper, (uint)TetherID.BrightAurora); +class DarkAuroraTether(BossModule module) : Towers(module, (uint)OID.BrightAuroraHelper, (uint)TetherID.DarkAurora); diff --git a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/UmbralAstralAspectAOEs.cs b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/UmbralAstralAspectAOEs.cs index 65afe9ce6b..d2fd99824a 100644 --- a/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/UmbralAstralAspectAOEs.cs +++ b/BossMod/Modules/Stormblood/Foray/BaldesionsArsenal/BA3AbsoluteVirtue/UmbralAstralAspectAOEs.cs @@ -2,7 +2,7 @@ namespace BossMod.Stormblood.Foray.BaldesionArsenal.BA3AbsoluteVirtue; class BrightDarkAurora(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeRect rect = new(30, 50); + private static readonly AOEShapeRect rect = new(30f, 50f); public readonly List _aoes = new(2); public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; @@ -10,17 +10,17 @@ class BrightDarkAurora(BossModule module) : Components.GenericAOEs(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { void AddAOE() => _aoes.Add(new(rect, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell))); - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.DarkAurora1: - case AID.DarkAurora2: - if (caster.FindStatus(SID.UmbralEssence) != null) + case (uint)AID.DarkAurora1: + case (uint)AID.DarkAurora2: + if (caster.FindStatus((uint)SID.UmbralEssence) != null) AddAOE(); break; - case AID.BrightAurora1: - case AID.BrightAurora2: + case (uint)AID.BrightAurora1: + case (uint)AID.BrightAurora2: - if (caster.FindStatus(SID.AstralEssence) != null) + if (caster.FindStatus((uint)SID.AstralEssence) != null) AddAOE(); break; } @@ -28,7 +28,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (_aoes.Count != 0 && (AID)spell.Action.ID is AID.BrightAurora1 or AID.BrightAurora2) // bright and dark always happen in a pair and we only add one of them to active AOEs + if (_aoes.Count != 0 && spell.Action.ID is (uint)AID.BrightAurora1 or (uint)AID.BrightAurora2) // bright and dark always happen in a pair and we only add one of them to active AOEs _aoes.RemoveAt(0); } } @@ -38,7 +38,7 @@ class BrightDarkAuroraCounter(BossModule module) : Components.CastCounterMulti(m class AstralUmbralRays(BossModule module) : Components.GenericAOEs(module) { - private static readonly AOEShapeCircle circleSmall = new(8), circleBig = new(16); + private static readonly AOEShapeCircle circleSmall = new(8f), circleBig = new(16f); public readonly List _aoes = new(9); public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes; @@ -46,22 +46,22 @@ class AstralUmbralRays(BossModule module) : Components.GenericAOEs(module) public override void OnCastStarted(Actor caster, ActorCastInfo spell) { void AddAOE(bool big) => _aoes.Add(new(big ? circleBig : circleSmall, spell.LocXZ, default, Module.CastFinishAt(spell))); - switch ((AID)spell.Action.ID) + switch (spell.Action.ID) { - case AID.UmbralRays1: - case AID.UmbralRays2: - AddAOE(Module.PrimaryActor.FindStatus(SID.UmbralEssence) != null); + case (uint)AID.UmbralRays1: + case (uint)AID.UmbralRays2: + AddAOE(Module.PrimaryActor.FindStatus((uint)SID.UmbralEssence) != null); break; - case AID.AstralRays1: - case AID.AstralRays2: - AddAOE(Module.PrimaryActor.FindStatus(SID.AstralEssence) != null); + case (uint)AID.AstralRays1: + case (uint)AID.AstralRays2: + AddAOE(Module.PrimaryActor.FindStatus((uint)SID.AstralEssence) != null); break; } } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.UmbralRays1 or AID.UmbralRays2 or AID.AstralRays1 or AID.AstralRays2) + if (spell.Action.ID is (uint)AID.UmbralRays1 or (uint)AID.UmbralRays2 or (uint)AID.AstralRays1 or (uint)AID.AstralRays2) _aoes.Clear(); } } diff --git a/BossMod/Modules/Stormblood/Trial/T09Seiryu/OnmyoSerpentEyeSigil.cs b/BossMod/Modules/Stormblood/Trial/T09Seiryu/OnmyoSerpentEyeSigil.cs index 1b489787cb..61f2541a3c 100644 --- a/BossMod/Modules/Stormblood/Trial/T09Seiryu/OnmyoSerpentEyeSigil.cs +++ b/BossMod/Modules/Stormblood/Trial/T09Seiryu/OnmyoSerpentEyeSigil.cs @@ -3,23 +3,23 @@ class OnmyoSerpentEyeSigil(BossModule module) : Components.GenericAOEs(module) { private AOEInstance? _aoe; - private static readonly AOEShapeDonut donut = new(6.95f, 30.05f); //adjusted sizes slightly since cast is done by helper with non identical position - private static readonly AOEShapeCircle circle = new(12.05f); + private static readonly AOEShapeDonut donut = new(7f, 30f); + private static readonly AOEShapeCircle circle = new(12f); public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); public override void OnActorModelStateChange(Actor actor, byte modelState, byte animState1, byte animState2) { - var activation = WorldState.FutureTime(5.6f); + void AddAOE(AOEShape shape) => _aoe = new(shape, WPos.ClampToGrid(actor.Position), default, WorldState.FutureTime(5.6d)); if (modelState == 32) - _aoe = new(circle, Module.PrimaryActor.Position, default, activation); - if (modelState == 33) - _aoe = new(donut, Module.PrimaryActor.Position, default, activation); + AddAOE(circle); + else if (modelState == 33) + AddAOE(donut); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if ((AID)spell.Action.ID is AID.OnmyoSigil2 or AID.SerpentEyeSigil2) + if (spell.Action.ID is (uint)AID.OnmyoSigil2 or (uint)AID.SerpentEyeSigil2) _aoe = null; } } diff --git a/BossMod/Modules/Stormblood/Trial/T09Seiryu/SerpentsAscending.cs b/BossMod/Modules/Stormblood/Trial/T09Seiryu/SerpentsAscending.cs index 63f8d2851b..ffe1891c82 100644 --- a/BossMod/Modules/Stormblood/Trial/T09Seiryu/SerpentsAscending.cs +++ b/BossMod/Modules/Stormblood/Trial/T09Seiryu/SerpentsAscending.cs @@ -4,13 +4,13 @@ class SerpentAscending(BossModule module) : Components.GenericTowers(module) { public override void OnActorCreated(Actor actor) { - if ((OID)actor.OID == OID.Towers) - Towers.Add(new(actor.Position, 3, activation: WorldState.FutureTime(7.8f))); + if (actor.OID == (uint)OID.Towers) + Towers.Add(new(actor.Position, 3, activation: WorldState.FutureTime(7.8d))); } public override void OnEventCast(Actor caster, ActorCastEvent spell) { - if ((AID)spell.Action.ID is AID.SerpentsFang or AID.SerpentsJaws) + if (spell.Action.ID is (uint)AID.SerpentsFang or (uint)AID.SerpentsJaws) Towers.Clear(); } } diff --git a/BossMod/Modules/Stormblood/Trial/T09Seiryu/T09Seiryu.cs b/BossMod/Modules/Stormblood/Trial/T09Seiryu/T09Seiryu.cs index 721f7222fc..69d10644cc 100644 --- a/BossMod/Modules/Stormblood/Trial/T09Seiryu/T09Seiryu.cs +++ b/BossMod/Modules/Stormblood/Trial/T09Seiryu/T09Seiryu.cs @@ -1,21 +1,25 @@ namespace BossMod.Stormblood.Trial.T09Seiryu; -class HundredTonzeSwing(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.HundredTonzeSwing), 16); -class CoursingRiver(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.CoursingRiverAOE), 25, true, kind: Kind.DirForward) +class HundredTonzeSwing(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.HundredTonzeSwing), 16f); +class CoursingRiver(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.CoursingRiverAOE), 25f, true, kind: Kind.DirForward) { + private readonly Handprint _aoe = module.FindComponent()!; + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - if (!Module.FindComponent()!.ActiveAOEs(slot, actor).Any()) - foreach (var c in Casters) - hints.AddForbiddenZone(ShapeDistance.Rect(c.CastInfo!.Rotation.AlmostEqual(90.Degrees(), Angle.DegToRad) ? c.Position - new WDir(12.5f, 0) : c.Position - new WDir(-12.5f, 0), c.Rotation, 50, default, 20), Module.CastFinishAt(c.CastInfo)); + if (_aoe.Casters.Count == 0 && Casters.Count != 0) + { + var c = Casters[0]; + hints.AddForbiddenZone(ShapeDistance.Rect(c.CastInfo!.Rotation.AlmostEqual(90f.Degrees(), Angle.DegToRad) ? c.Position - new WDir(12.5f, default) : c.Position - new WDir(-12.5f, default), c.Rotation, 50f, default, 20f), Module.CastFinishAt(c.CastInfo)); + } } } class DragonsWake(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.DragonsWake2)); class FifthElement(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.FifthElement)); -class FortuneBladeSigil(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FortuneBladeSigil), new AOEShapeRect(100, 2)); +class FortuneBladeSigil(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.FortuneBladeSigil), new AOEShapeRect(100f, 2f)); -class InfirmSoul(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.InfirmSoul), new AOEShapeCircle(4), true) +class InfirmSoul(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.InfirmSoul), new AOEShapeCircle(4f), true) { public override void AddGlobalHints(GlobalHints hints) { @@ -24,16 +28,16 @@ public override void AddGlobalHints(GlobalHints hints) } } -class SerpentDescending(BossModule module) : Components.SpreadFromIcon(module, (uint)IconID.Spreadmarker, ActionID.MakeSpell(AID.SerpentDescending), 5, 6); -class YamaKagura(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.YamaKagura), new AOEShapeRect(60, 3)); -class Handprint(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Handprint2), new AOEShapeCone(40, 90.Degrees())); +class SerpentDescending(BossModule module) : Components.SpreadFromIcon(module, (uint)IconID.Spreadmarker, ActionID.MakeSpell(AID.SerpentDescending), 5f, 6f); +class YamaKagura(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.YamaKagura), new AOEShapeRect(60f, 3f)); +class Handprint(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Handprint2), new AOEShapeCone(40f, 90f.Degrees())); -class ForceOfNature1(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.ForceOfNature1), 10) +class ForceOfNature1(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.ForceOfNature1), 10f) { public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - if (Sources(slot, actor).Any()) - hints.AddForbiddenZone(ShapeDistance.InvertedCircle(Arena.Center, 10), Sources(slot, actor).FirstOrDefault().Activation); + if (Casters.Count != 0) + hints.AddForbiddenZone(ShapeDistance.InvertedCircle(Arena.Center, 10f), Module.CastFinishAt(Casters[0].CastInfo)); } } class ForceOfNature2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.ForceOfNature2), 5); @@ -43,14 +47,14 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme { base.AddAIHints(slot, actor, assignment, hints); if (CurrentBaits.Any(x => x.Target == actor)) - hints.AddForbiddenZone(ShapeDistance.Circle(Arena.Center, 19), WorldState.FutureTime(ActivationDelay)); + hints.AddForbiddenZone(ShapeDistance.Circle(Arena.Center, 19f), WorldState.FutureTime(ActivationDelay)); } } -class KanaboAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Kanabo), new AOEShapeCone(45, 30.Degrees())); -class BlueBolt(BossModule module) : Components.LineStack(module, ActionID.MakeSpell(AID.BlueBoltMarker), ActionID.MakeSpell(AID.BlueBolt), 5.9f, 83, 2.5f); +class KanaboAOE(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.Kanabo), new AOEShapeCone(45f, 30f.Degrees())); +class BlueBolt(BossModule module) : Components.LineStack(module, ActionID.MakeSpell(AID.BlueBoltMarker), ActionID.MakeSpell(AID.BlueBolt), 5.9f, 83f, 2.5f); class ForbiddenArts(BossModule module) : Components.LineStack(module, ActionID.MakeSpell(AID.ForbiddenArtsMarker), ActionID.MakeSpell(AID.ForbiddenArtsSecond), 5.2f, 84.4f, 4); // this hits twice -class RedRush(BossModule module) : Components.BaitAwayTethers(module, new AOEShapeRect(82.6f, 2.5f), (uint)TetherID.BaitAway, ActionID.MakeSpell(AID.RedRush), (uint)OID.AkaNoShiki, 6) +class RedRush(BossModule module) : Components.BaitAwayTethers(module, new AOEShapeRect(82.6f, 2.5f), (uint)TetherID.BaitAway, ActionID.MakeSpell(AID.RedRush), (uint)OID.AkaNoShiki, 6f) { public override void OnTethered(Actor source, ActorTetherInfo tether) {