diff --git a/BossMod/Modules/Endwalker/FATE/Chi.cs b/BossMod/Modules/Endwalker/FATE/Chi.cs index 5cf88f7f6d..e4bf79afe5 100644 --- a/BossMod/Modules/Endwalker/FATE/Chi.cs +++ b/BossMod/Modules/Endwalker/FATE/Chi.cs @@ -339,7 +339,8 @@ public ChiStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs index c46d28c755..12e31f6944 100644 --- a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs +++ b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs @@ -59,7 +59,6 @@ public enum SID : uint class LitPath : Components.GenericAOEs { private static readonly AOEShapeRect rect = new(50, 5); - private static readonly Angle[] rotations = [0.Degrees(), 90.Degrees(), 180.Degrees(), -90.Degrees()]; private DateTime _activation; private bool redblue1; private bool redblue2; @@ -73,16 +72,16 @@ public override IEnumerable ActiveAOEs(BossModule module, int slot, { foreach (var o in module.Enemies(OID.OrbOfImmolationBlue)) { - if (bluered1 && o.Rotation.AlmostEqual(rotations.FirstOrDefault(r => o.Rotation.AlmostEqual(r, maxError)), maxError)) + if (bluered1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(1.9f)); - if (redblue2 && !redblue1 && o.Rotation.AlmostEqual(rotations.FirstOrDefault(r => o.Rotation.AlmostEqual(r, maxError)), maxError)) + if (redblue2 && !redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(4)); } foreach (var o in module.Enemies(OID.OrbOfImmolationRed)) { - if (bluered2 && !bluered1 && o.Rotation.AlmostEqual(rotations.FirstOrDefault(r => o.Rotation.AlmostEqual(r, maxError)), maxError)) + if (bluered2 && !bluered1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(4)); - if (redblue1 && o.Rotation.AlmostEqual(rotations.FirstOrDefault(r => o.Rotation.AlmostEqual(r, maxError)), maxError)) + if (redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(1.9f)); } } @@ -314,7 +313,8 @@ public DaivadipaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Aegeiros.cs b/BossMod/Modules/Endwalker/HuntA/Aegeiros.cs index 9a1acabfde..b0e0a829e1 100644 --- a/BossMod/Modules/Endwalker/HuntA/Aegeiros.cs +++ b/BossMod/Modules/Endwalker/HuntA/Aegeiros.cs @@ -21,8 +21,8 @@ public enum AID : uint class LeafstormRimestorm : Components.GenericAOEs { private DateTime _rimestormExpected; - private static AOEShapeCircle _leafstorm = new(10); - private static AOEShapeCone _rimestorm = new(40, 90.Degrees()); + private static readonly AOEShapeCircle _leafstorm = new(10); + private static readonly AOEShapeCone _rimestorm = new(40, 90.Degrees()); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -71,7 +71,8 @@ public AegeirosStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/ArchEta.cs b/BossMod/Modules/Endwalker/HuntA/ArchEta.cs index b680dc1d7a..1763966c67 100644 --- a/BossMod/Modules/Endwalker/HuntA/ArchEta.cs +++ b/BossMod/Modules/Endwalker/HuntA/ArchEta.cs @@ -50,7 +50,8 @@ public ArchEtaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/FanAil.cs b/BossMod/Modules/Endwalker/HuntA/FanAil.cs index 6ef9f0f43e..ebda7e327e 100644 --- a/BossMod/Modules/Endwalker/HuntA/FanAil.cs +++ b/BossMod/Modules/Endwalker/HuntA/FanAil.cs @@ -52,7 +52,8 @@ public FanAilStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Gurangatch.cs b/BossMod/Modules/Endwalker/HuntA/Gurangatch.cs index d81bece321..d81a78db97 100644 --- a/BossMod/Modules/Endwalker/HuntA/Gurangatch.cs +++ b/BossMod/Modules/Endwalker/HuntA/Gurangatch.cs @@ -69,7 +69,8 @@ public GurangatchStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Hulder.cs b/BossMod/Modules/Endwalker/HuntA/Hulder.cs index cb595c0aae..0c05759256 100644 --- a/BossMod/Modules/Endwalker/HuntA/Hulder.cs +++ b/BossMod/Modules/Endwalker/HuntA/Hulder.cs @@ -49,7 +49,8 @@ public HulderStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/LunatenderQueen.cs b/BossMod/Modules/Endwalker/HuntA/LunatenderQueen.cs index af57415b35..fbbc8c1660 100644 --- a/BossMod/Modules/Endwalker/HuntA/LunatenderQueen.cs +++ b/BossMod/Modules/Endwalker/HuntA/LunatenderQueen.cs @@ -70,7 +70,8 @@ public LunatenderQueenStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Minerva.cs b/BossMod/Modules/Endwalker/HuntA/Minerva.cs index 6e81a1357b..7ba6dacbed 100644 --- a/BossMod/Modules/Endwalker/HuntA/Minerva.cs +++ b/BossMod/Modules/Endwalker/HuntA/Minerva.cs @@ -113,7 +113,8 @@ public MinervaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/MoussePrincess.cs b/BossMod/Modules/Endwalker/HuntA/MoussePrincess.cs index 088372b048..8c936b80ed 100644 --- a/BossMod/Modules/Endwalker/HuntA/MoussePrincess.cs +++ b/BossMod/Modules/Endwalker/HuntA/MoussePrincess.cs @@ -102,7 +102,8 @@ public MoussePrincessStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Petalodus.cs b/BossMod/Modules/Endwalker/HuntA/Petalodus.cs index 9a53698811..2c99ba2f67 100644 --- a/BossMod/Modules/Endwalker/HuntA/Petalodus.cs +++ b/BossMod/Modules/Endwalker/HuntA/Petalodus.cs @@ -44,7 +44,8 @@ public PetalodusStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Storsie.cs b/BossMod/Modules/Endwalker/HuntA/Storsie.cs index c1f1b3252f..b6a67d3867 100644 --- a/BossMod/Modules/Endwalker/HuntA/Storsie.cs +++ b/BossMod/Modules/Endwalker/HuntA/Storsie.cs @@ -70,7 +70,8 @@ public StorsieStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Sugriva.cs b/BossMod/Modules/Endwalker/HuntA/Sugriva.cs index 8be4edbf48..ebc0b4fd81 100644 --- a/BossMod/Modules/Endwalker/HuntA/Sugriva.cs +++ b/BossMod/Modules/Endwalker/HuntA/Sugriva.cs @@ -84,7 +84,7 @@ class Rip : Components.SelfTargetedAOEs class RockThrow : Components.GenericAOEs { private Actor? _target; - private static AOEShapeCircle _shape = new(6); + private static readonly AOEShapeCircle _shape = new(6); public RockThrow() : base(ActionID.MakeSpell(AID.RockThrowRest)) { } @@ -142,7 +142,8 @@ public SugrivaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntA/Yilan.cs b/BossMod/Modules/Endwalker/HuntA/Yilan.cs index 00f63e2c42..0356ef9d8e 100644 --- a/BossMod/Modules/Endwalker/HuntA/Yilan.cs +++ b/BossMod/Modules/Endwalker/HuntA/Yilan.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace BossMod.Endwalker.HuntA.Yilan { @@ -31,7 +32,7 @@ class Soundstorm : Components.StatusDrivenForcedMarch { public Soundstorm() : base(2, (uint)SID.ForwardMarch, (uint)SID.AboutFace, (uint)SID.LeftFace, (uint)SID.RightFace) { } - public override bool DestinationUnsafe(BossModule module, int slot, Actor actor, WPos pos) => MiniLight.Shape.Check(pos, module.PrimaryActor); + public override bool DestinationUnsafe(BossModule module, int slot, Actor actor, WPos pos) => module.FindComponent()?.ActiveAOEs(module, slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false; public override void AddGlobalHints(BossModule module, GlobalHints hints) { @@ -44,7 +45,7 @@ class MiniLight : Components.GenericAOEs { private DateTime _activation; - public static AOEShapeCircle Shape = new(18); + private static readonly AOEShapeCircle Shape = new(18); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -95,7 +96,8 @@ public YilanStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/Armstrong.cs b/BossMod/Modules/Endwalker/HuntS/Armstrong.cs index a8b0277f76..b42c87818a 100644 --- a/BossMod/Modules/Endwalker/HuntS/Armstrong.cs +++ b/BossMod/Modules/Endwalker/HuntS/Armstrong.cs @@ -91,7 +91,8 @@ public ArmstrongStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } [ModuleInfo(NotoriousMonsterID = 196)] diff --git a/BossMod/Modules/Endwalker/HuntS/Burfurlur.cs b/BossMod/Modules/Endwalker/HuntS/Burfurlur.cs index 8467a0bd37..b1e87bc76d 100644 --- a/BossMod/Modules/Endwalker/HuntS/Burfurlur.cs +++ b/BossMod/Modules/Endwalker/HuntS/Burfurlur.cs @@ -25,7 +25,7 @@ public enum AID : uint class QuintupleSneeze : Components.GenericAOEs { private Angle _referenceAngle; - private List _pendingOffsets = new(); + private readonly List _pendingOffsets = []; private DateTime _nextSneeze; private static readonly AOEShapeCone _shape = new(40, 45.Degrees()); @@ -89,7 +89,8 @@ public BurfurlurStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/Ker.cs b/BossMod/Modules/Endwalker/HuntS/Ker.cs index 8394dc413f..c4f802a6ea 100644 --- a/BossMod/Modules/Endwalker/HuntS/Ker.cs +++ b/BossMod/Modules/Endwalker/HuntS/Ker.cs @@ -61,10 +61,12 @@ class AncientBlizzard : Components.SelfTargetedAOEs { public AncientBlizzard() : base(ActionID.MakeSpell(AID.AncientBlizzard), new AOEShapeDonut(8, 40)) { } } + class AncientBlizzard2 : Components.SelfTargetedAOEs { public AncientBlizzard2() : base(ActionID.MakeSpell(AID.AncientBlizzard2), new AOEShapeDonut(8, 40)) { } } + class AncientBlizzardWhispersManifest : Components.SelfTargetedAOEs { public AncientBlizzardWhispersManifest() : base(ActionID.MakeSpell(AID.WhispersManifest3), new AOEShapeDonut(8, 40)) { } @@ -89,6 +91,7 @@ class LeftInterment : Components.SelfTargetedAOEs { public LeftInterment() : base(ActionID.MakeSpell(AID.LeftInterment), new AOEShapeCone(40, 90.Degrees())) { } } + class Mirrored_ForeInterment : Components.SelfTargetedAOEs { public Mirrored_ForeInterment() : base(ActionID.MakeSpell(AID.Mirrored_ForeInterment), new AOEShapeCone(40, 90.Degrees())) { } @@ -98,6 +101,7 @@ class Mirrored_RearInterment : Components.SelfTargetedAOEs { public Mirrored_RearInterment() : base(ActionID.MakeSpell(AID.Mirrored_RearInterment), new AOEShapeCone(40, 90.Degrees())) { } } + class Mirrored_RightInterment : Components.SelfTargetedAOEs { public Mirrored_RightInterment() : base(ActionID.MakeSpell(AID.Mirrored_RightInterment), new AOEShapeCone(40, 90.Degrees())) { } @@ -107,48 +111,54 @@ class Mirrored_LeftInterment : Components.SelfTargetedAOEs { public Mirrored_LeftInterment() : base(ActionID.MakeSpell(AID.Mirrored_LeftInterment), new AOEShapeCone(40, 90.Degrees())) { } } + class EternalDamnation : Components.CastGaze { public EternalDamnation() : base(ActionID.MakeSpell(AID.EternalDamnation)) { } } + class EternalDamnationWhispersManifest : Components.CastGaze { public EternalDamnationWhispersManifest() : base(ActionID.MakeSpell(AID.WhispersManifest4)) { } } + class EternalDamnation2 : Components.CastGaze { public EternalDamnation2() : base(ActionID.MakeSpell(AID.EternalDamnation2)) { } } + class WhisperedIncantation : Components.CastHint { public WhisperedIncantation() : base(ActionID.MakeSpell(AID.WhisperedIncantation), "Remembers the next skill and uses it again when casting Whispers Manifest") { } } + class MirroredIncantation : BossComponent { private int Mirrorstacks; - private bool casting; - private bool casting2; + public enum Types { None, Mirroredx3, Mirroredx4 } + public Types Type { get; private set; } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.MirroredIncantation) - casting = true; + Type = Types.Mirroredx3; if ((AID)spell.Action.ID == AID.MirroredIncantation2) - casting2 = true; + Type = Types.Mirroredx4; } + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.MirroredIncantation || (AID)spell.Action.ID == AID.MirroredIncantation2) - casting = false; - casting2 = false; - + Type = Types.None; } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) { if (actor == module.PrimaryActor) - switch ((SID)status.ID) - { - case SID.MirroredIncantation: - var stacks = status.Extra switch + switch ((SID)status.ID) + { + case SID.MirroredIncantation: + var stacks = status.Extra switch { 0x1 => 1, 0x2 => 2, @@ -160,74 +170,87 @@ public override void OnStatusGain(BossModule module, Actor actor, ActorStatus st break; } } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) { - if (actor == module.PrimaryActor) - {if ((SID)status.ID == SID.MirroredIncantation) - { + if (actor == module.PrimaryActor) + { + if ((SID)status.ID == SID.MirroredIncantation) Mirrorstacks = 0; - } } } + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (Mirrorstacks > 0) hints.Add($"Mirrored interments left: {Mirrorstacks}!"); - if (casting) + if (Type == Types.Mirroredx3) hints.Add("The next three interments will be mirrored!"); - if (casting2) + if (Type == Types.Mirroredx4) hints.Add("The next four interments will be mirrored!"); } } + class AncientFlare : BossComponent { private BitMask _pyretic; public bool Pyretic { get; private set; } private bool casting; + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.AncientFlare || (AID)spell.Action.ID == AID.AncientFlare2 || (AID)spell.Action.ID == AID.WhispersManifest) casting = true; } + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.AncientFlare || (AID)spell.Action.ID == AID.AncientFlare2 || (AID)spell.Action.ID == AID.WhispersManifest) casting = false; } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) { if ((SID)status.ID == SID.Pyretic) _pyretic.Set(module.Raid.FindSlot(actor.InstanceID)); } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) { if ((SID)status.ID == SID.Pyretic) _pyretic.Clear(module.Raid.FindSlot(actor.InstanceID)); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { if (_pyretic[slot] != Pyretic) hints.Add("Pyretic on you! STOP everything!"); } + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (casting) hints.Add("Applies Pyretic - STOP everything until it runs out!"); } } + class AncientHoly : Components.SelfTargetedAOEs { public AncientHoly() : base(ActionID.MakeSpell(AID.AncientHoly), new AOEShapeCircle(20)) { } } + class AncientHoly2 : Components.SelfTargetedAOEs { public AncientHoly2() : base(ActionID.MakeSpell(AID.AncientHoly2), new AOEShapeCircle(20)) { } } + class AncientHolyWhispersManifest : Components.SelfTargetedAOEs { public AncientHolyWhispersManifest() : base(ActionID.MakeSpell(AID.WhispersManifest2), new AOEShapeCircle(20)) { } } + // TODO: wicked swipe, check if there are even more skills missing + class KerStates : StateMachineBuilder { public KerStates(BossModule module) : base(module) @@ -253,7 +276,8 @@ public KerStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/KerShroud.cs b/BossMod/Modules/Endwalker/HuntS/KerShroud.cs index 8a55ce7855..5799f3f234 100644 --- a/BossMod/Modules/Endwalker/HuntS/KerShroud.cs +++ b/BossMod/Modules/Endwalker/HuntS/KerShroud.cs @@ -28,7 +28,8 @@ public KerShroudStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/NarrowRift.cs b/BossMod/Modules/Endwalker/HuntS/NarrowRift.cs index 3f63ebe5aa..bc2a68f915 100644 --- a/BossMod/Modules/Endwalker/HuntS/NarrowRift.cs +++ b/BossMod/Modules/Endwalker/HuntS/NarrowRift.cs @@ -39,10 +39,10 @@ public enum SID : uint class EmptyPromise : Components.GenericAOEs { - private List _pendingShapes = new(); + private readonly List _pendingShapes = []; - private static AOEShapeCircle _shapeCircle = new(10); - private static AOEShapeDonut _shapeDonut = new(6, 40); + private static readonly AOEShapeCircle _shapeCircle = new(10); + private static readonly AOEShapeDonut _shapeDonut = new(6, 40); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -83,7 +83,7 @@ public override void OnCastFinished(BossModule module, Actor caster, ActorCastIn class VanishingRay : Components.GenericAOEs { private DateTime _activation; - private static AOEShapeRect _shape = new(50, 4); + private static readonly AOEShapeRect _shape = new(50, 4); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -125,7 +125,8 @@ public NarrowRiftStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/Ophioneus.cs b/BossMod/Modules/Endwalker/HuntS/Ophioneus.cs index b5ee25ce08..4b767e7833 100644 --- a/BossMod/Modules/Endwalker/HuntS/Ophioneus.cs +++ b/BossMod/Modules/Endwalker/HuntS/Ophioneus.cs @@ -35,8 +35,8 @@ class PyricCircleBurst : Components.GenericAOEs { private AOEInstance? _aoe; - private static AOEShapeCircle _shapeCircle = new(10); // TODO: verify falloff - private static AOEShapeDonut _shapeDonut = new(5, 40); + private static readonly AOEShapeCircle _shapeCircle = new(10); // TODO: verify falloff + private static readonly AOEShapeDonut _shapeDonut = new(5, 40); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) => Utils.ZeroOrOne(_aoe); @@ -81,7 +81,8 @@ public OphioneusStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/Ruminator.cs b/BossMod/Modules/Endwalker/HuntS/Ruminator.cs index bb9fb973e1..6710c39627 100644 --- a/BossMod/Modules/Endwalker/HuntS/Ruminator.cs +++ b/BossMod/Modules/Endwalker/HuntS/Ruminator.cs @@ -12,9 +12,9 @@ public enum AID : uint { AutoAttack = 871, // Boss->player, no cast, single-target ChitinousTraceCircleFirst = 26874, // Boss->self, 4.0s cast, range 8 circle - always followed by circle, does not 'record' shape by itself - ChitinousTraceDonutFirst = 26875, // Boss->self, 4.0s cast, range ?-40 donut - always followed by donut, does not 'record' shape by itself + ChitinousTraceDonutFirst = 26875, // Boss->self, 4.0s cast, range 8-40 donut - always followed by donut, does not 'record' shape by itself ChitinousTraceCircle = 26876, // Boss->self, 2.5s cast, range 8 circle - ChitinousTraceDonut = 26877, // Boss->self, 2.5s cast, range ?-40 donut + ChitinousTraceDonut = 26877, // Boss->self, 2.5s cast, range 8-40 donut ChitinousAdvanceCircleFirst = 26878, // Boss->self, 3.0s cast, range 8 circle ChitinousAdvanceDonutFirst = 26879, // Boss->self, 3.0s cast, range 8-40 donut ChitinousAdvanceCircleRest = 26880, // Boss->self, no cast, range 8 circle @@ -29,7 +29,7 @@ public enum AID : uint class ChitinousTrace : Components.GenericAOEs { private bool _active; - private List _pendingShapes = new(); + private readonly List _pendingShapes = []; public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -84,7 +84,8 @@ public RuminatorStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Endwalker/HuntS/Sphatika.cs b/BossMod/Modules/Endwalker/HuntS/Sphatika.cs index 3c887ec437..b67e499cf1 100644 --- a/BossMod/Modules/Endwalker/HuntS/Sphatika.cs +++ b/BossMod/Modules/Endwalker/HuntS/Sphatika.cs @@ -53,8 +53,8 @@ public Caterwaul() : base(ActionID.MakeSpell(AID.Caterwaul)) { } class Stance : Components.GenericAOEs { - private List _pendingCleaves = new(); - private static AOEShapeCone _shape = new(40, 90.Degrees()); + private readonly List _pendingCleaves = []; + private static readonly AOEShapeCone _shape = new(40, 90.Degrees()); public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { @@ -146,7 +146,8 @@ public SphatikaStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/PVP/HiddenGorge/GoblinMercenary.cs b/BossMod/Modules/PVP/HiddenGorge/GoblinMercenary.cs index 4b69719700..260bfc4a61 100644 --- a/BossMod/Modules/PVP/HiddenGorge/GoblinMercenary.cs +++ b/BossMod/Modules/PVP/HiddenGorge/GoblinMercenary.cs @@ -138,7 +138,6 @@ public GoblinMercenaryStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.IsTargetable; - } } diff --git a/BossMod/Modules/Shadowbringers/FATE/Archaeotania.cs b/BossMod/Modules/Shadowbringers/FATE/Archaeotania.cs index 4ffee7a9a9..ebfcc62a31 100644 --- a/BossMod/Modules/Shadowbringers/FATE/Archaeotania.cs +++ b/BossMod/Modules/Shadowbringers/FATE/Archaeotania.cs @@ -166,7 +166,8 @@ public ArchaeotaniaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/FATE/Formidable.cs b/BossMod/Modules/Shadowbringers/FATE/Formidable.cs index 3e46f21d69..8e8861779a 100644 --- a/BossMod/Modules/Shadowbringers/FATE/Formidable.cs +++ b/BossMod/Modules/Shadowbringers/FATE/Formidable.cs @@ -270,7 +270,8 @@ public FormidableStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Baal.cs b/BossMod/Modules/Shadowbringers/HuntA/Baal.cs index 6eb3fcab08..e6f7b7b793 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Baal.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Baal.cs @@ -82,7 +82,8 @@ public BaalStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Grassman.cs b/BossMod/Modules/Shadowbringers/HuntA/Grassman.cs index 3bfad74715..c25b69441e 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Grassman.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Grassman.cs @@ -94,7 +94,8 @@ public GrassmanStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Huracan.cs b/BossMod/Modules/Shadowbringers/HuntA/Huracan.cs index 776c7ada6e..cf25fefbe4 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Huracan.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Huracan.cs @@ -101,7 +101,8 @@ public HuracanStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/LilMurderer.cs b/BossMod/Modules/Shadowbringers/HuntA/LilMurderer.cs index 2f5696f79b..1ef39248ba 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/LilMurderer.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/LilMurderer.cs @@ -75,7 +75,8 @@ public LilMurdererStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Maliktender.cs b/BossMod/Modules/Shadowbringers/HuntA/Maliktender.cs index 9aa38fbfdf..cbe5221ab6 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Maliktender.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Maliktender.cs @@ -59,7 +59,8 @@ public MaliktenderStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Nariphon.cs b/BossMod/Modules/Shadowbringers/HuntA/Nariphon.cs index 6d0afd0284..050cfeec19 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Nariphon.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Nariphon.cs @@ -99,7 +99,8 @@ public NariphonStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Nuckelavee.cs b/BossMod/Modules/Shadowbringers/HuntA/Nuckelavee.cs index d3942a3df6..fbe403662d 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Nuckelavee.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Nuckelavee.cs @@ -77,7 +77,8 @@ public NuckelaveeStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/OPoorestPauldia.cs b/BossMod/Modules/Shadowbringers/HuntA/OPoorestPauldia.cs index d1a9e429f6..2fbc618941 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/OPoorestPauldia.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/OPoorestPauldia.cs @@ -43,7 +43,8 @@ public OPoorestPauldiaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Rusalka.cs b/BossMod/Modules/Shadowbringers/HuntA/Rusalka.cs index f1183967d8..738e3ac782 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Rusalka.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Rusalka.cs @@ -62,7 +62,8 @@ public RusalkaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Sugaar.cs b/BossMod/Modules/Shadowbringers/HuntA/Sugaar.cs index 833d5f14c4..f4b2ac5584 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Sugaar.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Sugaar.cs @@ -103,7 +103,8 @@ public SugaarStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/Supay.cs b/BossMod/Modules/Shadowbringers/HuntA/Supay.cs index 2e34b7ed62..40cbbe3f86 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/Supay.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/Supay.cs @@ -63,7 +63,8 @@ public SupayStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntA/TheMudman.cs b/BossMod/Modules/Shadowbringers/HuntA/TheMudman.cs index 318b99e5a6..014cb754f1 100644 --- a/BossMod/Modules/Shadowbringers/HuntA/TheMudman.cs +++ b/BossMod/Modules/Shadowbringers/HuntA/TheMudman.cs @@ -81,7 +81,8 @@ public TheMudmanStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/Aglaope.cs b/BossMod/Modules/Shadowbringers/HuntS/Aglaope.cs index 07d1df9b45..0dcc76c8e1 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/Aglaope.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/Aglaope.cs @@ -108,7 +108,8 @@ public AglaopeStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/ForgivenGossip.cs b/BossMod/Modules/Shadowbringers/HuntS/ForgivenGossip.cs index 7d6b5870d1..6730702319 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/ForgivenGossip.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/ForgivenGossip.cs @@ -28,7 +28,8 @@ public ForgivenGossipStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/ForgivenPedantry.cs b/BossMod/Modules/Shadowbringers/HuntS/ForgivenPedantry.cs index df5b4def1c..a80c173e8c 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/ForgivenPedantry.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/ForgivenPedantry.cs @@ -157,7 +157,8 @@ public ForgivenPedantryStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/ForgivenRebellion.cs b/BossMod/Modules/Shadowbringers/HuntS/ForgivenRebellion.cs index 5ae1b5110a..16ca33749a 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/ForgivenRebellion.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/ForgivenRebellion.cs @@ -228,7 +228,8 @@ public ForgivenRebellionStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/Gunitt.cs b/BossMod/Modules/Shadowbringers/HuntS/Gunitt.cs index 851d36f7af..9bc29c8e3f 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/Gunitt.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/Gunitt.cs @@ -109,7 +109,8 @@ public GunittStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/Ixtab.cs b/BossMod/Modules/Shadowbringers/HuntS/Ixtab.cs index 9e8849c015..c4b59a4b5f 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/Ixtab.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/Ixtab.cs @@ -189,7 +189,8 @@ public IxtabStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/Tarchia.cs b/BossMod/Modules/Shadowbringers/HuntS/Tarchia.cs index be2f81bd62..8554556ee3 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/Tarchia.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/Tarchia.cs @@ -94,7 +94,8 @@ public TarchiaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Shadowbringers/HuntS/Tyger.cs b/BossMod/Modules/Shadowbringers/HuntS/Tyger.cs index 7e7c85fabb..b41099481f 100644 --- a/BossMod/Modules/Shadowbringers/HuntS/Tyger.cs +++ b/BossMod/Modules/Shadowbringers/HuntS/Tyger.cs @@ -104,7 +104,8 @@ public TygerStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Stormblood/HuntA/Angada.cs b/BossMod/Modules/Stormblood/HuntA/Angada.cs index 5cb999fc72..5fbed68123 100644 --- a/BossMod/Modules/Stormblood/HuntA/Angada.cs +++ b/BossMod/Modules/Stormblood/HuntA/Angada.cs @@ -66,7 +66,8 @@ public AngadaStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Stormblood/HuntA/Gajasura.cs b/BossMod/Modules/Stormblood/HuntA/Gajasura.cs index cc804df438..c67e0b07f9 100644 --- a/BossMod/Modules/Stormblood/HuntA/Gajasura.cs +++ b/BossMod/Modules/Stormblood/HuntA/Gajasura.cs @@ -36,7 +36,8 @@ public GajasuraStates(BossModule module) : base(module) TrivialPhase() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; } } diff --git a/BossMod/Modules/Stormblood/HuntS/Okina.cs b/BossMod/Modules/Stormblood/HuntS/Okina.cs new file mode 100644 index 0000000000..f69bf67073 --- /dev/null +++ b/BossMod/Modules/Stormblood/HuntS/Okina.cs @@ -0,0 +1,92 @@ +// CONTRIB: made by malediktus, not checked +using System; +using System.Collections.Generic; + +namespace BossMod.Stormblood.HuntS.Okina +{ + public enum OID : uint + { + Boss = 0x1AB1, // R=8.0 + }; + + public enum AID : uint + { + AutoAttack = 872, // 1AB1->player, no cast, single-target + Hydrocannon = 7990, // 1AB1->self, no cast, range 22+R width 6 rect + ElectricSwipe = 7991, // 1AB1->self, 2,5s cast, range 17+R 60-degree cone, applies paralysis + BodySlam = 7993, // 1AB1->location, 4,0s cast, range 10 circle, knockback 20, away from source + ElectricWhorl = 7996, // 1AB1->self, 4,0s cast, range 8-60 donut + Expulsion = 7995, // 1AB1->self, 3,0s cast, range 6+R circle, knockback 30, away from source + Immersion = 7994, // 1AB1->self, 3,0s cast, range 60+R circle + RubyTide = 7992, // Boss->self, 2,0s cast, single-target, boss gives itself Dmg up buff + }; + + class Hydrocannon : Components.SelfTargetedAOEs + { + public Hydrocannon() : base(ActionID.MakeSpell(AID.Hydrocannon), new AOEShapeRect(30, 3)) { } + } + + class ElectricWhorl : Components.SelfTargetedAOEs + { + public ElectricWhorl() : base(ActionID.MakeSpell(AID.ElectricWhorl), new AOEShapeDonut(8, 60)) { } + } + + class Expulsion : Components.SelfTargetedAOEs + { + public Expulsion() : base(ActionID.MakeSpell(AID.Expulsion), new AOEShapeCircle(14)) { } + } + + class ExpulsionKB : Components.KnockbackFromCastTarget + { + public ExpulsionKB() : base(ActionID.MakeSpell(AID.Expulsion), 30, shape: new AOEShapeCircle(14)) { } + } + + class ElectricSwipe : Components.SelfTargetedAOEs + { + public ElectricSwipe() : base(ActionID.MakeSpell(AID.ElectricSwipe), new AOEShapeCone(25, 30.Degrees())) { } + } + + class BodySlam : Components.LocationTargetedAOEs + { + public BodySlam() : base(ActionID.MakeSpell(AID.BodySlam), 10) { } + } + + class BodySlamKB : Components.KnockbackFromCastTarget + { + public BodySlamKB() : base(ActionID.MakeSpell(AID.BodySlam), 20, shape: new AOEShapeCircle(10)) { } + } + + class Immersion : Components.RaidwideCast + { + public Immersion() : base(ActionID.MakeSpell(AID.Immersion)) { } + } + + class RubyTide : Components.CastHint + { + public RubyTide() : base(ActionID.MakeSpell(AID.RubyTide), "Applies damage buff to self") { } + } + + class OkinaStates : StateMachineBuilder + { + public OkinaStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.PrimaryActor.IsDead || !module.PrimaryActor.InCombat; + } + } + + [ModuleInfo(NotoriousMonsterID = 86)] + public class Okina : SimpleBossModule + { + public Okina(WorldState ws, Actor primary) : base(ws, primary) { } + } +} \ No newline at end of file