From 1d31a83752cb66ee6d077af44870ebc9c3787eca Mon Sep 17 00:00:00 2001 From: CarnifexOptimus <156172553+CarnifexOptimus@users.noreply.github.com> Date: Mon, 18 Nov 2024 02:00:00 +0100 Subject: [PATCH] another sphene test --- BossMod/Components/GenericAOEs.cs | 41 +--- .../D091LindblumZaghnal.cs | 128 +++++++++++++ .../D092OverseerKanilokka.cs | 181 ++++++++++++++++++ .../Extreme/Ex3QueenEternal/RadicalShift.cs | 21 +- .../Savage/P9SKokytos/ArchaicRockbreaker.cs | 2 +- .../Modules/Endwalker/Ultimate/TOP/P5Delta.cs | 2 +- .../Extreme/Ex4Ifrit/Ex4IfritAI.cs | 2 +- .../D08AkadaemiaAnyder/D081Cladoselache.cs | 2 +- .../CriticalEngagement/CE21FinalFurlong.cs | 2 +- .../Stormblood/Ultimate/UWU/P2Eruption.cs | 2 +- 10 files changed, 334 insertions(+), 49 deletions(-) create mode 100644 BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D091LindblumZaghnal.cs create mode 100644 BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D092OverseerKanilokka.cs diff --git a/BossMod/Components/GenericAOEs.cs b/BossMod/Components/GenericAOEs.cs index 9b195024d8..7c4dd07dfc 100644 --- a/BossMod/Components/GenericAOEs.cs +++ b/BossMod/Components/GenericAOEs.cs @@ -83,54 +83,29 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) } // location-targeted circle aoe that happens at the end of the cast -public class LocationTargetedAOEs(BossModule module, ActionID aid, float radius, int maxCasts = int.MaxValue) : GenericAOEs(module, aid) -{ - public AOEShapeCircle Shape { get; init; } = new(radius); - public int MaxCasts = maxCasts; // used for staggered aoes, when showing all active would be pointless - public uint Color; // can be customized if needed - public bool Risky = true; // can be customized if needed - public readonly List Casters = []; - - public IEnumerable ActiveCasters => Casters.Take(MaxCasts); - - public override IEnumerable ActiveAOEs(int slot, Actor actor) => ActiveCasters.Select(c => new AOEInstance(Shape, WorldState.Actors.Find(c.CastInfo!.TargetID)?.Position ?? c.CastInfo!.LocXZ, c.CastInfo.Rotation, Module.CastFinishAt(c.CastInfo), Color, Risky)); - - public override void OnCastStarted(Actor caster, ActorCastInfo spell) - { - if (spell.Action == WatchedAction) - Casters.Add(caster); - } - - public override void OnCastFinished(Actor caster, ActorCastInfo spell) - { - if (spell.Action == WatchedAction) - Casters.Remove(caster); - } -} - -// location-targeted aoe component which supports shapes that aren't circles -public class LocationTargetedAOEsOther(BossModule module, ActionID aid, AOEShape shape, int maxCasts = int.MaxValue) : GenericAOEs(module, aid) +public class LocationTargetedAOEs(BossModule module, ActionID aid, AOEShape shape, int maxCasts = int.MaxValue) : GenericAOEs(module, aid) { + public LocationTargetedAOEs(BossModule module, ActionID aid, float radius, int maxCasts = int.MaxValue) : this(module, aid, new AOEShapeCircle(radius), maxCasts) { } public AOEShape Shape { get; init; } = shape; public int MaxCasts = maxCasts; // used for staggered aoes, when showing all active would be pointless public uint Color; // can be customized if needed public bool Risky = true; // can be customized if needed - public readonly List Casters = []; - public IEnumerable ActiveCasters => Casters.Take(MaxCasts); + public List Casters { get; } = []; + public IEnumerable ActiveCasters => Casters.Take(MaxCasts); - public override IEnumerable ActiveAOEs(int slot, Actor actor) => ActiveCasters.Select(c => new AOEInstance(Shape, WorldState.Actors.Find(c.CastInfo!.TargetID)?.Position ?? c.CastInfo!.LocXZ, c.CastInfo.Rotation, Module.CastFinishAt(c.CastInfo), Color, Risky)); + public override IEnumerable ActiveAOEs(int slot, Actor actor) => Casters.Take(MaxCasts); public override void OnCastStarted(Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) - Casters.Add(caster); + Casters.Add(new(Shape, spell.LocXZ, spell.Rotation, Module.CastFinishAt(spell), Color, Risky)); } public override void OnCastFinished(Actor caster, ActorCastInfo spell) { - if (spell.Action == WatchedAction) - Casters.Remove(caster); + if (Casters.Count != 0 && spell.Action == WatchedAction) + Casters.RemoveAt(0); } } diff --git a/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D091LindblumZaghnal.cs b/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D091LindblumZaghnal.cs new file mode 100644 index 0000000000..a25572be3a --- /dev/null +++ b/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D091LindblumZaghnal.cs @@ -0,0 +1,128 @@ +namespace BossMod.Dawntrail.Dungeon.D09YuweyawataFieldStation.D091LindblumZaghnal; + +public enum OID : uint +{ + Boss = 0x4641, // R9.0 + RawElectrope = 0x4642, // R1.0 + Helper = 0x233C +} + +public enum AID : uint +{ + AutoAttack = 872, // Boss->player, no cast, single-target + Teleport = 40622, // Boss->location, no cast, single-target + + ElectricalOverload = 40635, // Boss->self, 5.0s cast, range 40 circle + + Gore1 = 40630, // Boss->self, 3.0s cast, single-target + Gore2 = 41266, // Boss->self, 3.0s cast, single-target + CaberToss = 40624, // Boss->self, 19.0s cast, single-target + LineVoltageWide1 = 41121, // Helper->self, 3.3s cast, range 50 width 10 rect + LineVoltageWide2 = 40627, // Helper->self, 3.5s cast, range 50 width 10 rect + LineVoltageNarrow1 = 41122, // Helper->self, 3.0s cast, range 50 width 5 rect + LineVoltageNarrow2 = 40625, // Helper->self, 4.0s cast, range 50 width 5 rect + CellShock = 40626, // Helper->self, 2.0s cast, range 26 circle + + LightningStormVisual = 40636, // Boss->self, 4.5s cast, single-target + LightningStorm = 40637, // Helper->player, 5.0s cast, range 5 circle, spread + + SparkingFissureVisual = 40632, // Boss->self, 13.0s cast, single-target + SparkingFissure = 41258, // Helper->self, 13.7s cast, range 40 circle + SparkingFissureFirst = 41267, // Helper->self, 5.2s cast, range 40 circle + SparkingFissureRepeat = 40631, // Helper->self, no cast, range 40 circle + + LightningBolt = 40638, // Helper->location, 5.0s cast, range 6 circle + Electrify = 40634, // RawElectrope->self, 16.0s cast, range 40 circle +} + +abstract class LineVoltage(BossModule module, AID aid, float halfWidth) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(aid), new AOEShapeRect(50, halfWidth)); +class LineVoltageWide1(BossModule module) : LineVoltage(module, AID.LineVoltageWide1, 5); +class LineVoltageWide2(BossModule module) : LineVoltage(module, AID.LineVoltageWide2, 5); +class LineVoltageNarrow1(BossModule module) : LineVoltage(module, AID.LineVoltageNarrow1, 2.5f); +class LineVoltageNarrow2(BossModule module) : LineVoltage(module, AID.LineVoltageNarrow2, 2.5f); + +class LightningBolt(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.LightningBolt), 6); +class LightningStorm(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.LightningStorm), 5); +class ElectricalOverload(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.ElectricalOverload)); +class SparkingFissure(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SparkingFissure)); +class SparkingFissureFirst(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SparkingFissureFirst)); + +class CellShock(BossModule module) : Components.GenericAOEs(module) +{ + private static readonly AOEShapeCircle Circle = new(26); + private AOEInstance? _aoe; + + private static readonly Dictionary initialPositions = new() + { + { 0x0D, new(81.132f, 268.868f) }, { 0x0E, new(81.132f, 285.132f) }, + { 0x0F, new(64.868f, 268.868f) }, { 0x10, new(64.868f, 285.132f) } + }; + + private static readonly Dictionary pairsWithSamePositions = new() + { + { 0x0D, 0x10 }, { 0x0E, 0x0F }, { 0x0F, 0x0E }, { 0x10, 0x0D } + }; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); + + public override void OnEventEnvControl(byte index, uint state) + { + if (state is 0x00020001 or 0x00200010) + { + if (state == 0x00200010 && pairsWithSamePositions.TryGetValue(index, out var remappedIndex)) + index = remappedIndex; + + if (initialPositions.TryGetValue(index, out var position)) + _aoe = new(Circle, position, default, WorldState.FutureTime(8)); + } + } + + public override void OnCastFinished(Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.CellShock) + _aoe = null; + } +} + +class D091LindblumZaghnalStates : StateMachineBuilder +{ + public D091LindblumZaghnalStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 1008, NameID = 13623)] +public class D091LindblumZaghnal(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) +{ + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(73, 277), 19.5f * CosPI.Pi40th, 40)], [new Rectangle(new(72, 297), 20, 1.1f), + new Rectangle(new(72, 257), 20, 1.05f)]); + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(Enemies(OID.RawElectrope).Concat([PrimaryActor])); + } + + protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + for (var i = 0; i < hints.PotentialTargets.Count; ++i) + { + var e = hints.PotentialTargets[i]; + e.Priority = (OID)e.Actor.OID switch + { + OID.RawElectrope => 1, + _ => 0 + }; + } + } +} diff --git a/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D092OverseerKanilokka.cs b/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D092OverseerKanilokka.cs new file mode 100644 index 0000000000..ebb467950a --- /dev/null +++ b/BossMod/Modules/Dawntrail/Dungeon/D09YuweyawataFieldStation/D092OverseerKanilokka.cs @@ -0,0 +1,181 @@ +namespace BossMod.Dawntrail.Dungeon.D09YuweyawataFieldStation.D092OverseerKanilokka; + +public enum OID : uint +{ + Boss = 0x464A, // R9.0 + RawElectrope = 0x4642, // R1.0 + PreservedSoul = 0x464B, // R2.5 + Helper = 0x233C +} + +public enum AID : uint +{ + AutoAttack = 40659, // Boss->player, no cast, single-target + + DarkSouls = 40658, // Boss->player, 5.0s cast, single-target + + FreeSpiritsVisual = 40639, // Boss->self, 4.0+1,0s cast, single-target + FreeSpirits = 40640, // Helper->self, 5.0s cast, range 20 circle + + Soulweave1 = 40642, // PreservedSoul->self, 2.5s cast, range ?-32 donut + Soulweave2 = 40641, // PreservedSoul->self, 2.5s cast, range ?-32 donut + + PhantomFloodVisual = 40643, // Boss->self, 3.7+1,3s cast, single-target + PhantomFlood = 40644, // Helper->self, 5.0s cast, range 5-20 donut + + DarkIIVisual1 = 40654, // Boss->self, 4.5+0,5s cast, single-target + DarkIIVisual2 = 40655, // Boss->self, no cast, single-target + DarkII1 = 40656, // Helper->self, 5.0s cast, range 35 30-degree cone + DarkII2 = 40657, // Helper->self, 7.5s cast, range 35 30-degree cone + + TelltaleTears = 40649, // Helper->players, 5.0s cast, range 5 circle, spread + LostHope = 40645, // Boss->self, 3.0s cast, range 20 circle + Necrohazard = 40646, // Boss->self, 15.0s cast, range 20 circle, damage fall off AOE, very extreme damage if not almost at the border + Bloodburst = 40647, // Boss->self, 5.0s cast, range 45 circle + SoulDouse = 40651, // Helper->players, 5.0s cast, range 6 circle +} + +class ArenaChanges(BossModule module) : Components.GenericAOEs(module) +{ + private static readonly AOEShapeDonut donutBig = new(15, 20); + private static readonly AOEShapeDonut donutSmall = new(5, 15); + 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.FreeSpirits) + _aoe = new(donutBig, Arena.Center, default, Module.CastFinishAt(spell)); + else if ((AID)spell.Action.ID == AID.PhantomFlood) + _aoe = new(donutSmall, Arena.Center, default, Module.CastFinishAt(spell)); + } + + public override void OnEventEnvControl(byte index, uint state) + { + if (index != 0x07) + return; + switch (state) + { + case 0x00020001: + case 0x00080004: + SetArena(D092OverseerKanilokka.DefaultArena, D092OverseerKanilokka.DefaultArena.Center); + break; + case 0x00200010: + SetArena(D092OverseerKanilokka.TinyArena, D092OverseerKanilokka.TinyArena.Center); + break; + case 0x00800040: + SetArena(D092OverseerKanilokka.ArenaENVC00800040, D092OverseerKanilokka.ArenaENVC00800040.Center); + break; + case 0x02000100: + SetArena(D092OverseerKanilokka.ArenaENVC02000100, D092OverseerKanilokka.ArenaENVC02000100.Center); + break; + } + _aoe = null; + } + + private void SetArena(ArenaBounds bounds, WPos center) + { + Arena.Bounds = bounds; + Arena.Center = center; + } +} + +abstract class Soulweave(BossModule module, AID aid) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(aid), new AOEShapeDonut(28, 32)); +class Soulweave1(BossModule module) : Soulweave(module, AID.Soulweave1); +class Soulweave2(BossModule module) : Soulweave(module, AID.Soulweave2); + +class FreeSpirits(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.FreeSpirits)); +class Bloodburst(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Bloodburst)); +class DarkSouls(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.DarkSouls)); +class TelltaleTears(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.TelltaleTears), 5); +class SoulDouse(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.SoulDouse), 6, 4, 4); +class LostHope(BossModule module) : Components.CastHint(module, ActionID.MakeSpell(AID.LostHope), "Apply temporary misdirection"); +class Necrohazard(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Necrohazard), new AOEShapeCircle(18)); + +class DarkII(BossModule module) : Components.GenericAOEs(module) +{ + private static readonly AOEShapeCone cone = new(35, 15.Degrees()); + private readonly List _aoes = []; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) => _aoes.Take(6); + + public override void OnCastStarted(Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID is AID.DarkII1 or AID.DarkII2) + { + _aoes.Add(new(cone, caster.Position, spell.Rotation, Module.CastFinishAt(spell))); + if (_aoes.Count == 12) + _aoes.SortBy(x => x.Activation); + } + } + + public override void OnCastFinished(Actor caster, ActorCastInfo spell) + { + if (_aoes.Count != 0 && (AID)spell.Action.ID is AID.DarkII1 or AID.DarkII2) + _aoes.RemoveAt(0); + } +} + +class D092OverseerKanilokkaStates : StateMachineBuilder +{ + public D092OverseerKanilokkaStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 1008, NameID = 13623)] +public class D092OverseerKanilokka(WorldState ws, Actor primary) : BossModule(ws, primary, StartingBounds.Center, StartingBounds) +{ + private const int Edges = 60; + private const float Offset = -0.5f; // pathfinding offset + public static readonly WPos ArenaCenter = new(116, -66); + public static readonly Polygon[] StartingPolygon = [new Polygon(ArenaCenter, 19.5f * CosPI.Pi60th, Edges)]; + public static readonly Polygon[] TinyPolygon = [new Polygon(ArenaCenter, 5, Edges)]; + private static readonly WPos[] vertices02000100West = [new(111.06f, -65.72f), new(110.67f, -65.43f), new(107.318f, -65.444f), new(105.58f, -65.14f), new(104.667f, -64.333f), + new(103.67f, -62.384f), new(103.178f, -60.442f), new(103.86f, -59.34f), new(103.95f, -57.884f), new(102.706f, -57.1f), new(100.07f, -58.374f), new(98.053f, -57.253f), + new(99.5f, -54.79f), new(100.76f, -55.59f), new(103.6f, -54.06f), new(105.967f, -55.71f), new(106.658f, -56.668f), new(106.886f, -59.705f), new(107.185f, -61.381f), + new(108.828f, -62.385f), new(110.195f, -62.339f), new(111.853f, -61.94f), new(112.56f, -61.859f), new(113.26f, -61.845f)]; + private static readonly WPos[] vertices02000100North = [new(118.766f, -70.106f), new(118.784f, -70.473f), new(118.395f, -72.065f), new(114.281f, -74.929f), new(114.281f, -76.494f), + new(114.916f, -77.026f), new(115.96f, -77.269f), new(117.036f, -77.379f), new(118.31f, -77.806f), new(119.238f, -78.268f), new(120.02f, -78.853f), new(120.581f, -80.649f), + new(120.215f, -83.173f), new(119.498f, -83.807f), new(117.335f, -85.069f), new(117.422f, -85.957f), new(114.534f, -86.06f), new(114.917f, -84.171f), new(116, -83.361f), + new(117.7f, -82.228f), new(117.576f, -80.921f), new(117.118f, -80.047f), new(116, -79.764f), new(114.6f, -79.644f), new(112.1f, -78.814f), new(111.198f, -77.547f), + new(110.9f, -76.129f), new(110.936f, -74.878f), new(113.477f, -72.316f), new(113.307f, -70.185f)]; + private static readonly WPos[] vertices02000100East = [new(118.87f, -61.951f), new(119.5f, -61.2f), new(119.5f, -58.872f), new(119.8f, -57.9f), new(123.96f, -55.915f), + new(124.767f, -55.898f), new(126.807f, -56.914f), new(127.894f, -57.773f), new(128.759f, -59.09f), new(131.165f, -58.697f), new(131.542f, -57.7f), new(131.489f, -55.889f), + new(131.625f, -55.403f), new(131.5f, -54.809f), new(133.929f, -57.215f), new(133.676f, -57.343f), new(133.483f, -60.665f), new(131.628f, -62.529f), new(129.073f, -62.57f), + new(126.344f, -60.348f), new(124.493f, -59.185f), new(122.206f, -60.479f), new(122.439f, -61.998f), new(121.883f, -63.458f), new(120.931f, -65.486f)]; + private static readonly WPos[] vertices00800040North = [new(119.67f, -69.1f), new(119.72f, -72.25f), new(117.4f, -76.6f), new(116, -78.4f), new(117.5f, -79.8f), new(121, -81.2f), + new(123.3f, -85.5f), new(119.9f, -85.5f), new(117, -83.8f), new(113.667f, -80.854f), new(113, -77.5f), new(115.883f, -72.848f), new(114, -70.5f)]; + private static readonly WPos[] vertices00800040East = [new(119.89f, -63), new(122.887f, -63.63f), new(126.394f, -65.31f), new(127.887f, -67.5f), new(129.465f, -67.817f), + new(131.81f, -64.4f), new(136.6f, -62.82f), new(135.9f, -65.945f), new(133.18f, -66.62f), new(131.69f, -70.87f), new(127.1f, -71.56f), new(124.32f, -68.3f), + new(122.6f, -67.54f), new(120.32f, -68.186f)]; + private static readonly WPos[] vertices00800040South = [new(112.684f, -62.388f), new(112.2f, -60.07f), new(107.836f, -57.852f), new(107.12f, -53.635f), new(111.456f, -49.98f), + new(110.765f, -46.659f), new(113.8f, -46.079f), new(115.03f, -51.19f), new(111.5f, -53.67f), new(111.4f, -55.61f), new(116.356f, -58.773f), new(117.67f, -61.434f)]; + private static readonly WPos[] vertices00800040West = [new(112.793f, -69.754f), new(110.552f, -70.2f), new(108.04f, -73.04f), new(103.3f, -72.96f), new(100.9f, -70.243f), + new(98.644f, -70.563f), new(97.194f, -72.67f), new(96.467f, -69.863f), new(98.48f, -67.5f), new(101.8f, -67), new(104.645f, -69.163f), new(106.676f, -69.848f), + new(108.837f, -66.57f), new(111.04f, -65.8f)]; + public static readonly ArenaBoundsComplex StartingBounds = new(StartingPolygon, [new Rectangle(new(116, -46), 20, 1.25f), new Rectangle(new(116, -86), 20, 1.25f)]); + public static readonly ArenaBoundsComplex DefaultArena = new([new Polygon(ArenaCenter, 15, Edges)]); + public static readonly ArenaBoundsComplex TinyArena = new(TinyPolygon, MapResolution: 0.1f); + private static readonly DonutV[] difference = [new DonutV(ArenaCenter, 19.5f, 22, Edges)]; + public static readonly ArenaBoundsComplex ArenaENVC00800040 = new([new PolygonCustom(vertices00800040North), new PolygonCustom(vertices00800040East), + new PolygonCustom(vertices00800040South), new PolygonCustom(vertices00800040West), ..TinyPolygon], difference, Offset: Offset); + public static readonly ArenaBoundsComplex ArenaENVC02000100 = new([new PolygonCustom(vertices02000100East), new PolygonCustom(vertices02000100North), + new PolygonCustom(vertices02000100West), ..TinyPolygon], difference, Offset: Offset); + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(Enemies(OID.PreservedSoul).Where(x => x.CastInfo != null).Concat([PrimaryActor]), allowDeadAndUntargetable: true); + } +} diff --git a/BossMod/Modules/Dawntrail/Extreme/Ex3QueenEternal/RadicalShift.cs b/BossMod/Modules/Dawntrail/Extreme/Ex3QueenEternal/RadicalShift.cs index 1d59d7a05b..4c2e1aac6e 100644 --- a/BossMod/Modules/Dawntrail/Extreme/Ex3QueenEternal/RadicalShift.cs +++ b/BossMod/Modules/Dawntrail/Extreme/Ex3QueenEternal/RadicalShift.cs @@ -7,13 +7,18 @@ public enum Rotation { None, Left, Right } private ArenaBoundsComplex? _left; private ArenaBoundsComplex? _right; private Rotation _nextRotation; - private AOEInstance? _aoe; + private AOEShapeCustom? _aoe; + private DateTime _activation; private static readonly Square[] defaultSquare = [new(Ex3QueenEternal.ArenaCenter, 20)]; private static readonly AOEShapeCustom windArena = new(defaultSquare, Trial.T03QueenEternal.T03QueenEternal.XArenaRects); private static readonly AOEShapeCustom earthArena = new(defaultSquare, Trial.T03QueenEternal.T03QueenEternal.SplitArenaRects); private static readonly AOEShapeCustom iceArena = new(defaultSquare, Ex3QueenEternal.IceRectsAll); - public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); + public override IEnumerable ActiveAOEs(int slot, Actor actor) + { + if (_aoe != null) + yield return new(_aoe, Arena.Center, default, _activation); + } public override void OnEventEnvControl(byte index, uint state) { @@ -73,17 +78,13 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell) private void UpdateAOE(ArenaBoundsComplex? platform) { - var activation = WorldState.FutureTime(6); - var center = Arena.Bounds == Ex3QueenEternal.NormalBounds ? Ex3QueenEternal.ArenaCenter - : Arena.Bounds == Ex3QueenEternal.IceBridgeBounds ? Ex3QueenEternal.IceBridgeBounds.Center - : Arena.Bounds == Ex3QueenEternal.EarthBounds ? Ex3QueenEternal.EarthBounds.Center - : Arena.Bounds == Ex3QueenEternal.WindBounds ? Ex3QueenEternal.WindBounds.Center : Arena.Center; + _activation = WorldState.FutureTime(6); if (platform == Ex3QueenEternal.WindBounds) - _aoe = new(windArena, center, default, activation); + _aoe = windArena; else if (platform == Ex3QueenEternal.EarthBounds) - _aoe = new(earthArena, center, default, activation); + _aoe = earthArena; else if (platform == Ex3QueenEternal.IceBridgeBounds) - _aoe = new(iceArena, center, default, activation); + _aoe = iceArena; } } diff --git a/BossMod/Modules/Endwalker/Savage/P9SKokytos/ArchaicRockbreaker.cs b/BossMod/Modules/Endwalker/Savage/P9SKokytos/ArchaicRockbreaker.cs index 616f900db5..9e14c39168 100644 --- a/BossMod/Modules/Endwalker/Savage/P9SKokytos/ArchaicRockbreaker.cs +++ b/BossMod/Modules/Endwalker/Savage/P9SKokytos/ArchaicRockbreaker.cs @@ -110,7 +110,7 @@ private IEnumerable SafeSpots() { var safespots = new ArcList(_aoes[0].Origin, _shapeOut.Radius + 0.25f); foreach (var f in forbidden.ActiveCasters) - safespots.ForbidCircle(f.Position, forbidden.Shape.Radius); + safespots.ForbidCircle(f.Origin, 8); if (safespots.Forbidden.Segments.Count > 0) { foreach (var a in safespots.Allowed(default)) diff --git a/BossMod/Modules/Endwalker/Ultimate/TOP/P5Delta.cs b/BossMod/Modules/Endwalker/Ultimate/TOP/P5Delta.cs index b3dc53add5..96a45aea12 100644 --- a/BossMod/Modules/Endwalker/Ultimate/TOP/P5Delta.cs +++ b/BossMod/Modules/Endwalker/Ultimate/TOP/P5Delta.cs @@ -386,7 +386,7 @@ public override void DrawArenaForeground(int pcSlot, Actor pc) var ps = _delta.Players[pcSlot]; var partner = Raid.WithSlot(true).WhereSlot(i => _delta.Players[i].IsLocal == ps.IsLocal && i != ps.PartnerSlot && _delta.Players[i].RocketPunch?.OID != ps.RocketPunch?.OID).FirstOrDefault().Item2; if (partner != null) - Arena.AddCircle(partner.Position, Shape.Radius, Colors.Safe); + Arena.AddCircle(partner.Position, 3, Colors.Safe); } } diff --git a/BossMod/Modules/RealmReborn/Extreme/Ex4Ifrit/Ex4IfritAI.cs b/BossMod/Modules/RealmReborn/Extreme/Ex4Ifrit/Ex4IfritAI.cs index ccf8c1c9a8..3bf91f0627 100644 --- a/BossMod/Modules/RealmReborn/Extreme/Ex4Ifrit/Ex4IfritAI.cs +++ b/BossMod/Modules/RealmReborn/Extreme/Ex4Ifrit/Ex4IfritAI.cs @@ -51,7 +51,7 @@ protected void AddDefaultEruptionBaiterHints(AIHints hints) // avoid non-baiters (TODO: should this be done by eruption component itself?) if (_eruption != null) foreach (var (i, p) in Raid.WithSlot().ExcludedFromMask(_eruption.Baiters)) - hints.AddForbiddenZone(ShapeDistance.Circle(p.Position, _eruption.Shape.Radius)); + hints.AddForbiddenZone(ShapeDistance.Circle(p.Position, Eruption.Radius)); } // TODO: this shouldn't be here... diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs index 317ca81c66..39a342510c 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs @@ -26,7 +26,7 @@ public enum AID : uint class MarineMayhem(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.MarineMayhem)); class ProtolithicPuncture(BossModule module) : Components.SingleTargetDelayableCast(module, ActionID.MakeSpell(AID.ProtolithicPuncture)); class PelagicCleaver1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.PelagicCleaver1), new AOEShapeCone(40, 30.Degrees())); -class PelagicCleaver2(BossModule module) : Components.LocationTargetedAOEsOther(module, ActionID.MakeSpell(AID.PelagicCleaver2), new AOEShapeCone(50, 30.Degrees())); +class PelagicCleaver2(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.PelagicCleaver2), new AOEShapeCone(50, 30.Degrees())); class TidalGuillotine1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.TidalGuillotine1), new AOEShapeCircle(13)); class TidalGuillotine2(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.TidalGuillotine2), 13); class AquaticLance(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.AquaticLance), 8); diff --git a/BossMod/Modules/Shadowbringers/Foray/CriticalEngagement/CE21FinalFurlong.cs b/BossMod/Modules/Shadowbringers/Foray/CriticalEngagement/CE21FinalFurlong.cs index 286abefd92..e242262e13 100644 --- a/BossMod/Modules/Shadowbringers/Foray/CriticalEngagement/CE21FinalFurlong.cs +++ b/BossMod/Modules/Shadowbringers/Foray/CriticalEngagement/CE21FinalFurlong.cs @@ -58,7 +58,7 @@ public override void AddHints(int slot, Actor actor, TextHints hints) var hand = _hands.FirstOrDefault(h => h.Tether.Target == actor.InstanceID); if (hand != null) { - var shouldBeFrozen = Shape.Check(hand.Position, Casters[0].CastInfo!.LocXZ); + var shouldBeFrozen = Shape.Check(hand.Position, Casters[0].Origin, new()); var isFrozen = hand.Tether.ID == (uint)TetherID.Frozen; hints.Add(shouldBeFrozen ? "Face the hand!" : "Look away from hand and kite into safezone!", shouldBeFrozen != isFrozen); } diff --git a/BossMod/Modules/Stormblood/Ultimate/UWU/P2Eruption.cs b/BossMod/Modules/Stormblood/Ultimate/UWU/P2Eruption.cs index dd36a39184..841932318c 100644 --- a/BossMod/Modules/Stormblood/Ultimate/UWU/P2Eruption.cs +++ b/BossMod/Modules/Stormblood/Ultimate/UWU/P2Eruption.cs @@ -20,7 +20,7 @@ public override void Update() public override void DrawArenaForeground(int pcSlot, Actor pc) { if (_baiters[pcSlot]) - Arena.AddCircle(pc.Position, Shape.Radius, Colors.Safe); + Arena.AddCircle(pc.Position, 8, Colors.Safe); } public override void OnCastStarted(Actor caster, ActorCastInfo spell)