diff --git a/BossMod/Components/CastHint.cs b/BossMod/Components/CastHint.cs index ac5ef1de78..119d2123e3 100644 --- a/BossMod/Components/CastHint.cs +++ b/BossMod/Components/CastHint.cs @@ -46,8 +46,9 @@ public CastInterruptHint(BossModule module, ActionID aid, bool canBeInterrupted public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - foreach (var c in Casters) + for (var i = 0; i < Casters.Count; ++i) { + var c = Casters[i]; var e = hints.PotentialTargets.Find(e => e.Actor == c); if (e != null) { diff --git a/BossMod/Components/Gaze.cs b/BossMod/Components/Gaze.cs index f402daa6e4..82019174e3 100644 --- a/BossMod/Components/Gaze.cs +++ b/BossMod/Components/Gaze.cs @@ -17,7 +17,7 @@ public record struct Eye( private const float _eyeOuterR = (_eyeOuterH * _eyeOuterH + _eyeOuterV * _eyeOuterV) / (2 * _eyeOuterV); private const float _eyeOffsetV = _eyeOuterR - _eyeOuterV; - private static readonly float _eyeHalfAngle = MathF.Asin(_eyeOuterH / _eyeOuterR); + private static readonly float _eyeHalfAngle = (float)Math.Asin(_eyeOuterH / _eyeOuterR); private static readonly Vector2 offset = new(0, _eyeOffsetV); private static readonly float halfPIHalfAngleP = Angle.HalfPi + _eyeHalfAngle; private static readonly float halfPIHalfAngleM = Angle.HalfPi - _eyeHalfAngle; diff --git a/BossMod/Data/Actor.cs b/BossMod/Data/Actor.cs index 5909600ccc..1ed79a41ff 100644 --- a/BossMod/Data/Actor.cs +++ b/BossMod/Data/Actor.cs @@ -109,7 +109,7 @@ public sealed class Actor(ulong instanceID, uint oid, int spawnIndex, string nam public bool IsDeadOrDestroyed => IsDead || IsDestroyed; public static readonly Actor FakeActor = new(0, 0, -1, "dummy", 0, ActorType.None, Class.None, 0, new(100, 0, 100, 0)); - private static readonly HashSet ignoreNPC = [0x2EFE]; // friendly NPCs that should not count as party members + private static readonly HashSet ignoreNPC = [0x2EFE, 0x418F]; // friendly NPCs that should not count as party members public bool IsFriendlyNPC => Type == ActorType.Enemy && IsAlly && IsTargetable && !ignoreNPC.Contains(OID); public ActorStatus? FindStatus(uint sid) diff --git a/BossMod/Data/PartyState.cs b/BossMod/Data/PartyState.cs index 4cba9adc98..73ae5ac756 100644 --- a/BossMod/Data/PartyState.cs +++ b/BossMod/Data/PartyState.cs @@ -51,7 +51,7 @@ void assign(ulong instanceID, Actor? actor) // select non-null and optionally alive raid members public IEnumerable WithoutSlot(bool includeDead = false, bool excludeAlliance = false, bool excludeNPCs = false) { - for (int i = 0; i < MaxAllies; ++i) + for (var i = 0; i < MaxAllies; ++i) { if (excludeNPCs && i >= MaxAllianceSize) break; @@ -68,7 +68,7 @@ public IEnumerable WithoutSlot(bool includeDead = false, bool excludeAlli public IEnumerable<(int, Actor)> WithSlot(bool includeDead = false, bool excludeAlliance = false) { - for (int i = 0; i < MaxAllies; ++i) + for (var i = 0; i < MaxAllies; ++i) { if (excludeAlliance && i is >= MaxPartySize and < MaxAllianceSize) continue; @@ -87,7 +87,7 @@ public IEnumerable WithoutSlot(bool includeDead = false, bool excludeAlli // find a slot index containing specified player (by name); returns -1 if not found public int FindSlot(ReadOnlySpan name, StringComparison cmp = StringComparison.CurrentCultureIgnoreCase) { - for (int i = 0; i < Members.Length; ++i) + for (var i = 0; i < Members.Length; ++i) if (name.Equals(Members[i].Name, cmp)) return i; return -1; diff --git a/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D051Livia.cs b/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D051Livia.cs index b965bc5f24..6f123edd59 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D051Livia.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D051Livia.cs @@ -103,5 +103,5 @@ public D051LiviaStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus, LTS)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 786, NameID = 10290)] public class D051Livia(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-6, 471), 19.5f / MathF.Cos(MathF.PI / 36), 36)], [new Rectangle(new(-6, 491.8f), 20, 2)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-6, 471), 19.5f * CosPI.Pi36th, 36)], [new Rectangle(new(-6, 491.8f), 20, 2)]); } diff --git a/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D053Amon.cs b/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D053Amon.cs index a65859140a..17d873ff4e 100644 --- a/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D053Amon.cs +++ b/BossMod/Modules/Endwalker/Dungeon/D05Aitiascope/D053Amon.cs @@ -39,7 +39,7 @@ public enum AID : uint class CurtainCallArenaChange(BossModule module) : BossComponent(module) { - private static readonly Shape[] circle = [new Polygon(new(11, -490), 6.4f / MathF.Cos(MathF.PI / 20), 20, 9.Degrees())]; + private static readonly Shape[] circle = [new Polygon(new(11, -490), 6.4f * CosPI.Pi20th, 20, 9.Degrees())]; public static readonly ArenaBoundsComplex CurtaincallArena = new(D053Amon.union, [.. D053Amon.difference, .. circle]); public override void OnEventEnvControl(byte index, uint state) diff --git a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs index e88ccd38e9..ed6b162d7a 100644 --- a/BossMod/Modules/Endwalker/FATE/Daivadipa.cs +++ b/BossMod/Modules/Endwalker/FATE/Daivadipa.cs @@ -59,7 +59,6 @@ class LitPath(BossModule module) : Components.GenericAOEs(module) private bool redblue2; private bool bluered1; private bool bluered2; - private const float maxError = MathF.PI / 180; public override IEnumerable ActiveAOEs(int slot, Actor actor) { @@ -67,16 +66,16 @@ public override IEnumerable ActiveAOEs(int slot, Actor actor) { foreach (var o in Module.Enemies(OID.OrbOfImmolationBlue)) { - if (bluered1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) + if (bluered1 && (o.Rotation.AlmostEqual(90.Degrees(), Angle.DegToRad) || o.Rotation.AlmostEqual(180.Degrees(), Angle.DegToRad))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(1.9f)); - if (redblue2 && !redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) + if (redblue2 && !redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), Angle.DegToRad) || o.Rotation.AlmostEqual(180.Degrees(), Angle.DegToRad))) 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(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) + if (bluered2 && !bluered1 && (o.Rotation.AlmostEqual(90.Degrees(), Angle.DegToRad) || o.Rotation.AlmostEqual(180.Degrees(), Angle.DegToRad))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(4)); - if (redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), maxError) || o.Rotation.AlmostEqual(180.Degrees(), maxError))) + if (redblue1 && (o.Rotation.AlmostEqual(90.Degrees(), Angle.DegToRad) || o.Rotation.AlmostEqual(180.Degrees(), Angle.DegToRad))) yield return new(rect, o.Position, o.Rotation, _activation.AddSeconds(1.9f)); } } diff --git a/BossMod/Modules/Endwalker/Ultimate/DSW2/P2SanctityOfTheWard1.cs b/BossMod/Modules/Endwalker/Ultimate/DSW2/P2SanctityOfTheWard1.cs index 62086995a7..7ca54f3969 100644 --- a/BossMod/Modules/Endwalker/Ultimate/DSW2/P2SanctityOfTheWard1.cs +++ b/BossMod/Modules/Endwalker/Ultimate/DSW2/P2SanctityOfTheWard1.cs @@ -220,7 +220,7 @@ public override void Update() var severDirEast = _severStartDir; if (severDirEast.Rad < 0) severDirEast += 180.Degrees(); - var severDiagonalSE = severDirEast.Rad < MathF.PI / 2; + var severDiagonalSE = severDirEast.Rad < MathF.PI * 0.5f; var chargeCW = _flares.ChargeAngle.Rad < 0; _chargeEarly = severDiagonalSE == chargeCW; } diff --git a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D111ZuroRoggo.cs b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D111ZuroRoggo.cs index 9ab7915a15..d54dbe58df 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D111ZuroRoggo.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D111ZuroRoggo.cs @@ -151,7 +151,7 @@ public D111ZuroRoggoStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 141, NameID = 4805)] public class D111ZuroRoggo(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-365, -250), 19.5f / MathF.Cos(MathF.PI / 32), 32)], [new Rectangle(new(-365, -230), 20, 2.01f), + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-365, -250), 19.5f * CosPI.Pi32th, 32)], [new Rectangle(new(-365, -230), 20, 2.01f), new Rectangle(new(-365, -270), 20, 1.75f)]); protected override void DrawEnemies(int pcSlot, Actor pc) diff --git a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D112Ziggy.cs b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D112Ziggy.cs index a2ee109f29..2928b91837 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D112Ziggy.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D112Ziggy.cs @@ -102,6 +102,6 @@ public D112ZiggyStates(BossModule module) : base(module) public class D112Ziggy(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { public static readonly WPos ArenaCenter = new(185.8f, 137.5f); - private static readonly ArenaBoundsComplex arena = new([new Polygon(ArenaCenter, 20.06f / MathF.Cos(MathF.PI / 36), 36)], [new Rectangle(new(166, 138), 20, 1.1f, 90.Degrees()), + private static readonly ArenaBoundsComplex arena = new([new Polygon(ArenaCenter, 20.06f * CosPI.Pi36th, 36)], [new Rectangle(new(166, 138), 20, 1.1f, 90.Degrees()), new Rectangle(new(207, 137), 20, 2.6f, 90.Degrees())]); } diff --git a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D113Calcabrina.cs b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D113Calcabrina.cs index 89afae4509..7f6d9aaa0b 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D113Calcabrina.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D11Antitower/D113Calcabrina.cs @@ -131,7 +131,7 @@ public D113CalcabrinaStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 141, NameID = 4813)] public class D113Calcabrina(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(232, -182), 19.5f / MathF.Cos(MathF.PI / 36), 36)], [new Rectangle(new(252, -182), 20, 1.15f, 90.Degrees())]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(232, -182), 19.5f * CosPI.Pi36th, 36)], [new Rectangle(new(252, -182), 20, 1.15f, 90.Degrees())]); protected override void DrawEnemies(int pcSlot, Actor pc) { diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150ChasmHarpeia.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150ChasmHarpeia.cs new file mode 100644 index 0000000000..15b8deb5e1 --- /dev/null +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150ChasmHarpeia.cs @@ -0,0 +1,203 @@ +namespace BossMod.Heavensward.Dungeon.D15Xelphatol.D150ChasmHarpeia; + +public enum OID : uint +{ + Boss = 0x17AF, // R1.2 + SwiftwaterHakulaq = 0x17AE, // R2.16 + AbalathianSlug = 0x17AB, // R0.8 + ChasmCobra = 0x17AC, // R1.44 + VelodynaToad = 0x17AD, // R4.32 + FallenRock = 0xD25 // R0.5 +} + +public enum AID : uint +{ + AutoAttack1 = 872, // AbalathianSlug->player, no cast, single-target + AutoAttack2 = 870, // SwiftwaterHakulaq/ChasmCobra->player, no cast, single-target + AutoAttack3 = 871, // Boss->player, no cast, single-target + + LaboredLeap = 1006, // VelodynaToad->self, 4.0s cast, range 6+R circle + Lap = 976, // VelodynaToad->player, no cast, single-target + + FallingRock = 6852, // FallenRock->location, 5.0s cast, range 4 circle + FlashFlood = 1656, // SwiftwaterHakulaq->self, 2.5s cast, range 6+R 120-degree cone + DrippingFang = 409, // ChasmCobra->player, no cast, single-target + WingsOfWoe = 2478, // Boss->location, 2.5s cast, range 6 circle + WildRattle = 408, // ChasmCobra->player, no cast, single-target +} + +class FlashFlood(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.FlashFlood), new AOEShapeCone(8.16f, 60.Degrees())); +class LaboredLeap(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.LaboredLeap), new AOEShapeCircle(10.32f)); +class FallenRock(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.FallingRock), 4); +class WingsOfWoe(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.WingsOfWoe), 6); + +class D150ChasmHarpeiaStates : StateMachineBuilder +{ + public D150ChasmHarpeiaStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => Module.WorldState.Actors.Where(x => x.IsTargetable && !x.IsAlly && x.Position.AlmostEqual(Module.Arena.Center, Module.Bounds.Radius)) + .All(x => x.IsDeadOrDestroyed); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5253, SortOrder = 1)] +public class D150ChasmHarpeia(WorldState ws, Actor primary) : BossModule(ws, primary, IsArena1(primary) ? arena1.Center : arena2.Center, IsArena1(primary) ? arena1 : arena2) +{ + private static bool IsArena1(Actor primary) => primary.Position.X < -130; + private static readonly WPos[] vertices1 = [new(-116.6f, 153.39f), new(-116.25f, 153.86f), new(-114.35f, 154.36f), new(-113.7f, 154.48f), new(-111.05f, 154.59f), + new(-110.39f, 154.71f), new(-106.02f, 160.42f), new(-106.51f, 160.64f), new(-106.66f, 161.15f), new(-105.65f, 165.95f), + new(-105.49f, 166.42f), new(-106.31f, 170.45f), new(-106.4f, 171.14f), new(-106.59f, 171.61f), new(-106.97f, 172.2f), + new(-108.27f, 174.61f), new(-108.98f, 176.61f), new(-110.17f, 177.12f), new(-111.99f, 179.14f), new(-112.65f, 179.2f), + new(-113.86f, 179.05f), new(-114.44f, 179.03f), new(-114.91f, 179.49f), new(-116.13f, 181.18f), new(-116.45f, 181.83f), + new(-116.7f, 182.47f), new(-117.28f, 185.68f), new(-116.97f, 186.18f), new(-116.81f, 186.85f), new(-116.71f, 188.23f), + new(-118.6f, 192.97f), new(-118.98f, 193.54f), new(-120.4f, 194.72f), new(-120.7f, 195.15f), new(-120.38f, 196.45f), + new(-120.56f, 197.11f), new(-121.76f, 198.64f), new(-124.65f, 201.37f), new(-125.22f, 201.79f), new(-126.55f, 201.71f), + new(-127.16f, 201.72f), new(-128.82f, 202.76f), new(-129.44f, 203.04f), new(-130.71f, 203.41f), new(-131.28f, 203.67f), + new(-132.35f, 204.47f), new(-132.97f, 204.78f), new(-134.77f, 205.41f), new(-135.1f, 205.86f), new(-135.59f, 207.08f), + new(-135.62f, 207.73f), new(-135.47f, 209.04f), new(-135.28f, 209.63f), new(-134.19f, 211.55f), new(-134.05f, 212.06f), + new(-134.1f, 212.61f), new(-134.62f, 212.94f), new(-134.86f, 219.11f), new(-135.36f, 222.6f), new(-135.29f, 223.3f), + new(-135.17f, 223.91f), new(-133.35f, 228.29f), new(-132.91f, 228.64f), new(-132.4f, 232.12f), new(-132.85f, 232.36f), + new(-135.39f, 233.28f), new(-136.02f, 233.59f), new(-137.76f, 234.73f), new(-138.43f, 235.08f), new(-138.91f, 235.3f), + new(-141.55f, 235.2f), new(-142.16f, 235.37f), new(-142.43f, 236), new(-142.83f, 237.41f), new(-143.11f, 238.12f), + new(-143.62f, 238.12f), new(-144.93f, 238.01f), new(-145.56f, 237.87f), new(-147.99f, 236.86f), new(-148.47f, 236.4f), + new(-148.95f, 236.24f), new(-149.59f, 236.2f), new(-150.74f, 235.72f), new(-151.33f, 235.81f), new(-151.95f, 235.97f), + new(-152.64f, 235.96f), new(-154.06f, 234.75f), new(-154.63f, 234.8f), new(-157.62f, 235.69f), new(-158.26f, 235.57f), + new(-158.86f, 235.39f), new(-160.13f, 235.38f), new(-160.75f, 235.16f), new(-162.09f, 233.8f), new(-162.59f, 233.64f), + new(-163.16f, 233.33f), new(-163.46f, 232.76f), new(-163.77f, 232.26f), new(-168.69f, 228.97f), new(-169.27f, 228.91f), + new(-171.21f, 229.05f), new(-172.32f, 229.42f), new(-172.91f, 229.09f), new(-173.49f, 228.93f), new(-174.16f, 229.12f), + new(-174.83f, 229.22f), new(-175.41f, 228.93f), new(-175.98f, 228.86f), new(-177.91f, 229.02f), new(-178.46f, 229.12f), + new(-178.66f, 229.62f), new(-178.69f, 230.34f), new(-178.54f, 231.73f), new(-178.52f, 233.24f), new(-178.58f, 233.9f), + new(-179.08f, 235.18f), new(-179.11f, 235.85f), new(-180.48f, 237.31f), new(-180.98f, 237.73f), new(-181.52f, 238.02f), + new(-181.92f, 238.5f), new(-182.25f, 239.08f), new(-182.48f, 239.63f), new(-183.07f, 239.67f), new(-184.21f, 239.02f), + new(-187.36f, 238.15f), new(-188.62f, 238.12f), new(-189.23f, 238.44f), new(-190.09f, 239.32f), new(-190.82f, 239.4f), + new(-190.98f, 238.91f), new(-191.04f, 238.3f), new(-191.33f, 237.82f), new(-191.78f, 237.34f), new(-193.03f, 235.64f), + new(-193.2f, 235.03f), new(-193.74f, 233.81f), new(-194.27f, 233.52f), new(-194.74f, 233.35f), new(-195.35f, 233.24f), + new(-196.54f, 233.94f), new(-197.11f, 234.34f), new(-197.5f, 234.8f), new(-199.69f, 236.37f), new(-201, 237.64f), + new(-201.28f, 238.18f), new(-202.19f, 242.49f), new(-202.37f, 244.38f), new(-202.37f, 244.94f), new(-201.98f, 246.15f), + new(-201.34f, 247.22f), new(-199.2f, 248.8f), new(-198.63f, 248.8f), new(-198.01f, 248.68f), new(-195.59f, 247.81f), + new(-194.92f, 247.68f), new(-194.27f, 247.72f), new(-193.61f, 247.71f), new(-191.18f, 246.84f), new(-190.73f, 246.55f), + new(-190.44f, 247.01f), new(-189.53f, 248.75f), new(-189.25f, 249.36f), new(-188.18f, 251.04f), new(-187.75f, 251.43f), + new(-184.18f, 252.84f), new(-183.73f, 253.08f), new(-183.39f, 253.62f), new(-182.88f, 254.06f), new(-180.44f, 256.36f), + new(-180.03f, 256.88f), new(-179.78f, 257.51f), new(-179.72f, 258.17f), new(-179.75f, 260.16f), new(-179.84f, 260.83f), + new(-180.07f, 261.46f), new(-180.35f, 262.05f), new(-181.04f, 263.16f), new(-181.46f, 263.66f), new(-181.92f, 264.13f), + new(-182.43f, 264.55f), new(-182.99f, 264.91f), new(-183.6f, 265.16f), new(-184.23f, 265.34f), new(-187.39f, 265.71f), + new(-187.95f, 265.85f), new(-189.39f, 267.06f), new(-190.08f, 267.08f), new(-216.73f, 259.73f), new(-217.3f, 259.3f), + new(-217.71f, 258.83f), new(-218.09f, 258.23f), new(-213.82f, 255.18f), new(-212.37f, 252.28f), new(-212.54f, 251.69f), + new(-213.01f, 251.22f), new(-213.11f, 250.64f), new(-214.73f, 247.06f), new(-206.6f, 219.24f), new(-204.82f, 219.05f), + new(-204.23f, 218.9f), new(-201.21f, 217.61f), new(-197.44f, 215.15f), new(-197.15f, 214.62f), new(-196.12f, 212.23f), + new(-195.68f, 211.71f), new(-192.68f, 210.45f), new(-190.07f, 210.11f), new(-189.38f, 210.16f), new(-187.4f, 211.82f), + new(-186.9f, 212.16f), new(-180.3f, 213.78f), new(-179.63f, 213.99f), new(-177.35f, 216.43f), new(-174.72f, 218.4f), + new(-172.4f, 220.72f), new(-171.88f, 220.87f), new(-168.72f, 220.89f), new(-165.51f, 220.47f), new(-164.87f, 220.71f), + new(-160.51f, 224.41f), new(-160.04f, 224.75f), new(-156.48f, 226.04f), new(-155.91f, 225.97f), new(-155.28f, 225.72f), + new(-154.58f, 225.69f), new(-153.97f, 225.98f), new(-153.49f, 226.39f), new(-152.99f, 226.65f), new(-151.75f, 226.85f), + new(-151.12f, 226.86f), new(-150.6f, 226.47f), new(-150.48f, 225.84f), new(-150.57f, 225.24f), new(-151.04f, 224.99f), + new(-151.73f, 224.97f), new(-153.14f, 225), new(-153.82f, 224.74f), new(-153.8f, 224.1f), new(-154.43f, 222.99f), + new(-154.86f, 219.86f), new(-155.95f, 218.12f), new(-155.82f, 217.48f), new(-155.19f, 216.42f), new(-155.22f, 215.88f), + new(-155.7f, 214.73f), new(-155.57f, 214.08f), new(-154.7f, 213.13f), new(-154.54f, 212.59f), new(-155.17f, 211.45f), + new(-155.36f, 210.74f), new(-153.08f, 209.48f), new(-152.71f, 209.09f), new(-152.42f, 207.22f), new(-152.21f, 206.53f), + new(-149.77f, 206.06f), new(-149.59f, 205.55f), new(-149.46f, 204.27f), new(-149.2f, 203.62f), new(-148.79f, 203.1f), + new(-148.23f, 202.64f), new(-147.6f, 202.94f), new(-147.05f, 203.01f), new(-146.52f, 202.73f), new(-146.1f, 202.23f), + new(-145.62f, 201.82f), new(-145.07f, 201.42f), new(-144.44f, 201.1f), new(-141.9f, 200.52f), new(-141.54f, 200.16f), + new(-141.67f, 199.58f), new(-142.11f, 198.37f), new(-141.62f, 197.86f), new(-140.52f, 197.06f), new(-139.84f, 196.93f), + new(-138.56f, 197.13f), new(-138, 196.98f), new(-134.97f, 195.39f), new(-134.65f, 194.86f), new(-134.09f, 193.59f), + new(-133.71f, 193.02f), new(-132.7f, 192.31f), new(-132.36f, 191.87f), new(-132.18f, 190.56f), new(-131.95f, 189.94f), + new(-129.76f, 188.83f), new(-129.64f, 188.29f), new(-129.65f, 187.65f), new(-129.55f, 186.97f), new(-129.02f, 186.58f), + new(-128.59f, 186.19f), new(-128.63f, 185.63f), new(-129.05f, 183.71f), new(-126.83f, 182.42f), new(-126.38f, 182.02f), + new(-126.21f, 180), new(-126.2f, 179.31f), new(-126.33f, 177.29f), new(-126.46f, 176.8f), new(-130.99f, 174.6f), + new(-130.93f, 173.91f), new(-130.63f, 172.12f), new(-130.94f, 171.68f), new(-133.41f, 170.6f), new(-133.53f, 169.91f), + new(-133.53f, 168.66f), new(-135.31f, 166.64f), new(-135.64f, 166.22f), new(-134.17f, 164.02f), new(-134.25f, 163.46f), + new(-135.28f, 160.93f), new(-135.24f, 160.27f), new(-134.93f, 158.3f), new(-134.45f, 158.12f), new(-130.68f, 157.55f), + new(-130.38f, 157.97f), new(-130.1f, 158.57f), new(-129.81f, 159.1f), new(-129.2f, 159.17f), new(-128.61f, 159.14f), + new(-128.21f, 158.71f), new(-127.66f, 158.29f), new(-117.08f, 153.3f)]; + private static readonly WPos[] vertices2 = [new(-84.63f, -42.88f), new(-83.93f, -42.42f), new(-84.48f, -42.18f), new(-84.79f, -41.69f), new(-85.87f, -39.26f), + new(-86.44f, -38.87f), new(-87.05f, -38.6f), new(-87.6f, -38.28f), new(-88.05f, -37.87f), new(-89.01f, -36.1f), + new(-89.67f, -35.81f), new(-90.25f, -35.71f), new(-90.74f, -35.36f), new(-91.66f, -32.91f), new(-92.11f, -32.43f), + new(-93.68f, -31.38f), new(-98.11f, -30.79f), new(-99.45f, -31.04f), new(-100.04f, -31.23f), new(-100.62f, -31.21f), + new(-101.11f, -30.8f), new(-101.59f, -30.33f), new(-102.23f, -30.15f), new(-102.9f, -30.06f), new(-103.52f, -30.27f), + new(-104.09f, -30.31f), new(-104.84f, -29.39f), new(-105.85f, -28.51f), new(-106.27f, -28.01f), new(-106.93f, -27.94f), + new(-107.6f, -27.82f), new(-107.9f, -27.4f), new(-107.85f, -26.81f), new(-107.55f, -25.57f), new(-107.3f, -25.09f), + new(-106.72f, -25.05f), new(-106.11f, -25.27f), new(-105.52f, -25.54f), new(-102.84f, -26.3f), new(-100.99f, -26.16f), + new(-100.41f, -26.2f), new(-95.67f, -27.91f), new(-94.96f, -27.82f), new(-94.29f, -27.66f), new(-92.38f, -26.95f), + new(-91.94f, -26.69f), new(-89.69f, -24.87f), new(-89.27f, -24.35f), new(-87, -20.87f), new(-86.49f, -20.49f), + new(-85.39f, -19.79f), new(-84.94f, -19.2f), new(-84.99f, -18.49f), new(-85.14f, -17.85f), new(-85.81f, -15.86f), + new(-87.62f, -13.23f), new(-87.39f, -11.31f), new(-87.79f, -10.75f), new(-88.79f, -9.73f), new(-89.16f, -9.24f), + new(-89.41f, -8.57f), new(-90.99f, -7.22f), new(-91.63f, -7), new(-92.93f, -6.96f), new(-95.81f, -6.32f), + new(-96.36f, -6.06f), new(-96.75f, -5.61f), new(-97.34f, -5.28f), new(-97.86f, -5.17f), new(-98.73f, -3.48f), + new(-99.87f, -1.69f), new(-100.31f, -1.39f), new(-100.82f, -1.88f), new(-101.83f, -3.51f), new(-102.04f, -4.2f), + new(-102.14f, -4.83f), new(-102.38f, -5.49f), new(-102.68f, -6.09f), new(-103.12f, -6.48f), new(-103.71f, -6.8f), + new(-105.33f, -7.88f), new(-105.71f, -8.43f), new(-106.1f, -8.9f), new(-106.53f, -9.34f), new(-107, -9.58f), + new(-107.65f, -9.74f), new(-108.16f, -9.61f), new(-108.63f, -9.18f), new(-109.43f, -8.25f), new(-109.77f, -7.69f), + new(-110.05f, -7.05f), new(-111.19f, -5.51f), new(-111.53f, -4.99f), new(-112.36f, -3.28f), new(-112.36f, -2.63f), + new(-111.87f, 1.4f), new(-111.72f, 2.02f), new(-111.62f, 2.65f), new(-111.47f, 3.27f), new(-111.25f, 3.83f), + new(-110.52f, 4.81f), new(-110.08f, 5.23f), new(-109.61f, 5.61f), new(-107.82f, 6.27f), new(-107.23f, 6.42f), + new(-106.66f, 6.39f), new(-106.09f, 6.08f), new(-103.38f, 4.05f), new(-102.68f, 3.85f), new(-102.02f, 3.62f), + new(-100.97f, 2.8f), new(-100.32f, 2.47f), new(-98.52f, 6.38f), new(-98.23f, 6.9f), new(-97.78f, 7.14f), + new(-94.17f, 5.7f), new(-93.46f, 5.69f), new(-92.93f, 6.19f), new(-92.41f, 6.53f), new(-90.46f, 7.14f), + new(-90.51f, 7.67f), new(-91.38f, 11.59f), new(-91.36f, 12.2f), new(-91.18f, 12.84f), new(-89.64f, 16.71f), + new(-89.31f, 17.31f), new(-88.84f, 20.85f), new(-88.92f, 21.46f), new(-88.48f, 21.91f), new(-87.91f, 21.91f), + new(-87.27f, 21.82f), new(-86.7f, 21.45f), new(-86.28f, 21.79f), new(-84.11f, 24.25f), new(-82.47f, 27.13f), + new(-82.59f, 27.8f), new(-83.8f, 29.46f), new(-86.95f, 30.74f), new(-87.42f, 31.12f), new(-88.92f, 32.55f), + new(-90.62f, 33.79f), new(-91.08f, 34.21f), new(-92.88f, 37), new(-93.69f, 38.86f), new(-93.52f, 39.4f), + new(-93.14f, 39.91f), new(-93.01f, 40.58f), new(-93.26f, 41.18f), new(-93.68f, 41.77f), new(-94.56f, 42.72f), + new(-95.14f, 43.03f), new(-95.78f, 42.96f), new(-96.28f, 43.24f), new(-96.75f, 43.73f), new(-97.24f, 44.16f), + new(-97.79f, 44.55f), new(-98.45f, 44.64f), new(-100.28f, 44.15f), new(-100.82f, 43.82f), new(-101.42f, 43.67f), + new(-102.01f, 43.58f), new(-102.66f, 43.55f), new(-103.29f, 43.66f), new(-103.91f, 43.68f), new(-105.78f, 43.67f), + new(-106.18f, 43.99f), new(-106.94f, 45.77f), new(-107.97f, 46.72f), new(-108.45f, 46.95f), new(-108.89f, 46.47f), + new(-109.47f, 46.38f), new(-110.07f, 46.39f), new(-110.68f, 46.66f), new(-110.88f, 47.17f), new(-111.42f, 47.58f), + new(-112.01f, 47.83f), new(-112.48f, 48.2f), new(-135.36f, 80.87f), new(-135.25f, 81.44f), new(-135.53f, 82.06f), + new(-135.89f, 82.59f), new(-136.08f, 83.15f), new(-135.99f, 83.74f), new(-135.54f, 84.08f), new(-136.03f, 84.48f), + new(-136.19f, 85.08f), new(-136.29f, 85.7f), new(-136.31f, 86.29f), new(-135.94f, 86.78f), new(-134.7f, 88.19f), + new(-132.96f, 88.97f), new(-132.5f, 89.54f), new(-132.25f, 90.17f), new(-132.71f, 91.3f), new(-132.48f, 91.82f), + new(-130.69f, 92.69f), new(-130.6f, 93.84f), new(-130.67f, 95.1f), new(-130.62f, 95.67f), new(-129.61f, 96.41f), + new(-129.56f, 96.93f), new(-129.76f, 97.59f), new(-130.06f, 98.18f), new(-130.42f, 98.77f), new(-130.98f, 99.23f), + new(-131.62f, 99.6f), new(-132.04f, 99.95f), new(-131.92f, 100.46f), new(-131.66f, 101.07f), new(-131.44f, 101.75f), + new(-131.68f, 103.09f), new(-132.16f, 103.65f), new(-132.65f, 104.06f), new(-133.35f, 104.25f), new(-134.39f, 104.27f), + new(-135.47f, 104.88f), new(-135.95f, 105.24f), new(-136.12f, 105.81f), new(-136.12f, 106.46f), new(-136.45f, 107.07f), + new(-137.31f, 108.14f), new(-138.78f, 108.15f), new(-139.41f, 108.42f), new(-139.57f, 108.92f), new(-139.49f, 109.45f), + new(-139.09f, 110), new(-139.36f, 110.53f), new(-139.28f, 111.15f), new(-129.07f, 133.18f), new(-129.09f, 133.8f), + new(-131.66f, 135.65f), new(-132.22f, 135.96f), new(-132.83f, 136.12f), new(-133.45f, 136.22f), new(-133.97f, 136.26f), + new(-134.62f, 136.01f), new(-135.04f, 135.46f), new(-145.02f, 114.04f), new(-145.49f, 113.86f), new(-145.95f, 113.43f), + new(-146.21f, 112.87f), new(-146.53f, 112.33f), new(-147.08f, 111.96f), new(-147.62f, 110.84f), new(-148.14f, 110.64f), + new(-148.83f, 110.64f), new(-149.53f, 110.7f), new(-152.8f, 110.68f), new(-153.41f, 110.77f), new(-154.01f, 111.05f), + new(-159.84f, 109.45f), new(-161.17f, 109.32f), new(-161.82f, 109.06f), new(-162.31f, 108.62f), new(-162.68f, 108.02f), + new(-162.81f, 107.31f), new(-162.58f, 106.66f), new(-161.71f, 104.83f), new(-161.87f, 104.33f), new(-162.62f, 103.3f), + new(-162.76f, 102.62f), new(-162.31f, 101.36f), new(-162.18f, 100.78f), new(-162.51f, 100.3f), new(-163.81f, 98.68f), + new(-164.34f, 97.49f), new(-164.37f, 96.82f), new(-164.12f, 96.23f), new(-164.18f, 95.68f), new(-164.93f, 94.58f), + new(-164.76f, 94.09f), new(-163.25f, 92.46f), new(-163.11f, 91.91f), new(-163.49f, 91.48f), new(-163.97f, 91.03f), + new(-164.21f, 90.41f), new(-164.23f, 89.72f), new(-163.45f, 88.57f), new(-162.78f, 88.23f), new(-162.17f, 88.38f), + new(-161.53f, 88.02f), new(-161.13f, 87.62f), new(-161.11f, 87), new(-162.16f, 85.41f), new(-162.4f, 83.41f), + new(-160.98f, 81.87f), new(-158.32f, 82.09f), new(-157.85f, 81.76f), new(-156.86f, 80.84f), new(-156.3f, 80.42f), + new(-154.91f, 80.48f), new(-154.44f, 80.67f), new(-154.03f, 81.01f), new(-153.44f, 81.08f), new(-152.83f, 81.07f), + new(-151.59f, 80.62f), new(-151.06f, 80.29f), new(-148.32f, 79.44f), new(-145.77f, 80.2f), new(-145.22f, 79.96f), + new(-144.26f, 79.11f), new(-143.66f, 78.81f), new(-143.04f, 78.83f), new(-142.44f, 78.68f), new(-142.08f, 78.29f), + new(-141.74f, 77.69f), new(-141.15f, 77.48f), new(-140.58f, 77.23f), new(-117.63f, 44.45f), new(-117.56f, 43.92f), + new(-117.62f, 43.31f), new(-117.22f, 42.83f), new(-116.86f, 42.29f), new(-116.8f, 41.78f), new(-117.13f, 41.17f), + new(-116.36f, 40.38f), new(-115.56f, 39.29f), new(-115.38f, 38.74f), new(-115.32f, 38.05f), new(-115.05f, 37.43f), + new(-114.56f, 37.03f), new(-114.15f, 36.65f), new(-114.12f, 36.02f), new(-114.17f, 34.05f), new(-115.01f, 30.89f), + new(-117.13f, 27.54f), new(-118.24f, 25.08f), new(-118.41f, 24.4f), new(-117.12f, 21.79f), new(-117.16f, 21.24f), + new(-118.22f, 19.6f), new(-118.72f, 19.19f), new(-121.39f, 17.32f), new(-122.49f, 16.75f), new(-123.43f, 15.97f), + new(-124.03f, 15.77f), new(-124.6f, 15.48f), new(-125.62f, 14.8f), new(-126.04f, 14.24f), new(-126.6f, 12.46f), + new(-126.66f, 11.22f), new(-126.85f, 10.68f), new(-127.82f, 9.91f), new(-127.81f, 9.28f), new(-125.23f, 5.31f), + new(-124.93f, 4.77f), new(-126.55f, 0.22f), new(-126.88f, -0.26f), new(-128.67f, -2.15f), new(-128.83f, -2.82f), + new(-128.71f, -7.79f), new(-128.4f, -10.55f), new(-125.33f, -16.17f), new(-125.4f, -16.77f), new(-125.94f, -19.36f), + new(-125.12f, -21.95f), new(-123.91f, -22.58f), new(-123.41f, -22.96f), new(-121.17f, -25.24f), new(-120.85f, -25.74f), + new(-119.7f, -28.07f), new(-119.22f, -30.67f), new(-117.55f, -32), new(-116.36f, -33.56f), new(-115.88f, -34.08f), + new(-114.19f, -35.23f), new(-113.74f, -35.63f), new(-112.28f, -38.55f), new(-110.93f, -38.84f), new(-110.23f, -38.88f), + new(-108.96f, -38.56f), new(-108.4f, -38.55f), new(-106.51f, -39.25f), new(-105.83f, -39.25f), new(-104.69f, -38.66f), + new(-101.53f, -39.13f), new(-99.03f, -40.18f), new(-98.54f, -40.58f), new(-93.73f, -46.65f), new(-93.18f, -47.1f)]; + + private static readonly ArenaBoundsComplex arena1 = new([new PolygonCustom(vertices1)]); + private static readonly ArenaBoundsComplex arena2 = new([new PolygonCustom(vertices2)]); + + protected override bool CheckPull() => WorldState.Actors.Any(x => x.InCombat && x.Position.AlmostEqual(Arena.Center, Bounds.Radius)); + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(WorldState.Actors.Where(x => !x.IsAlly && x.Position.AlmostEqual(Arena.Center, Bounds.Radius))); + } +} diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150SiegeGobbue.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150SiegeGobbue.cs new file mode 100644 index 0000000000..4fd4aed991 --- /dev/null +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150SiegeGobbue.cs @@ -0,0 +1,123 @@ +namespace BossMod.Heavensward.Dungeon.D15Xelphatol.D150SiegeGobbue; + +public enum OID : uint +{ + Boss = 0x17B5, // R2.85 + XelphatolBravewing = 0x17B2, // R1.08 + XelphatolWhirltalon = 0x17B1, // R1.08 + XelphatolStrongbeak = 0x17B3, // R1.08 +} + +public enum AID : uint +{ + AutoAttack1 = 870, // XelphatolWhirltalon/XelphatolBravewing/Boss->player, no cast, single-target + AutoAttack2 = 871, // XelphatolStrongbeak->player, no cast, single-target + + Overpower = 720, // XelphatolBravewing->self, 2.5s cast, range 6+R 90-degree cone + FastBlade = 717, // XelphatolWhirltalon->player, no cast, single-target + ComingStorm = 423, // XelphatolWhirltalon/XelphatolStrongbeak->self, 2.5s cast, single-target + TrueThrust = 722, // XelphatolStrongbeak->player, no cast, single-target + Sneeze = 6625, // Boss->self, 4.0s cast, range 20+R 90-degree cone +} + +class ArenaChange(BossModule module) : Components.GenericAOEs(module) +{ + private const int Vertices = 8; + private const int InnerRadius = 11; + private const int OuterRadius = 16; // 15.5 if adjusted for hitbox radius, but not needed here + private static readonly Angle a225 = 22.5f.Degrees(); + private static readonly WPos arena1center = new(70.5f, -56); + private static readonly WPos arena2center = new(178.083f, -4.225f); + private static readonly PolygonCustom verticesDiff1 = new([new(62.562f, -68.197f), new(58.33f, -63.967f), new(59.195f, -63.239f), + new(63.214f, -63.273f), new(63.267f, -67.123f)]); + private static readonly PolygonCustom verticesDiff2 = new([new(181.034f, -18.5f), new(175.119f, -18.5f), new(175.522f, -17.112f), + new(178.095f, -14.489f), new(180.889f, -17.318f)]); + private static readonly Shape[] difference1 = [new Polygon(arena1center, InnerRadius, Vertices, a225), verticesDiff1, new Rectangle(new(59, -67.5f), 10, 2.1f, 135.Degrees())]; + private static readonly Shape[] difference2 = [new Polygon(arena2center, InnerRadius, Vertices, a225), verticesDiff2]; + private static readonly AOEShapeCustom poly1 = new([new Polygon(arena1center, OuterRadius, Vertices, a225)], difference1); + private static readonly AOEShapeCustom poly2 = new([new Polygon(arena2center, OuterRadius, Vertices, a225)], difference2); + private AOEInstance? _aoe; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); + + public override void OnActorNpcYell(Actor actor, ushort id) + { + if (_aoe == null && actor.Position.Z < -10) + _aoe = new(poly1, Arena.Center, default, WorldState.FutureTime(4)); + } + + public override void Update() + { + if (_aoe == null && Module.PrimaryActor.Position.Z > -10) // for some reason NPC yells that are exactly at the start of a module do not get recognized despite appearing in replay? + _aoe = new(poly2, Arena.Center, default, WorldState.FutureTime(4)); + } +} + +class Overpower(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Overpower), new AOEShapeCone(7.08f, 45.Degrees())); +class Sneeze(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Sneeze), new AOEShapeCone(20.85f, 45.Degrees())); +class SneezeHint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.Sneeze), true, true, showNameInHint: true); + +class D150SiegeGobbueStates : StateMachineBuilder +{ + public D150SiegeGobbueStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => Module.WorldState.Actors.Where(x => x.IsTargetable && !x.IsAlly && x.Position.AlmostEqual(Module.Arena.Center, Module.Bounds.Radius)).All(x => x.IsDeadOrDestroyed); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5254, SortOrder = 3)] +public class D150SiegeGobbue(WorldState ws, Actor primary) : BossModule(ws, primary, IsArena1(primary) ? arena1.Center : arena2.Center, IsArena1(primary) ? arena1 : arena2) +{ + private static bool IsArena1(Actor primary) => primary.Position.Z < -10; + private static readonly WPos[] vertices1 = [new(37.14f, -107.01f), new(38.84f, -105.21f), new(39.33f, -104.79f), new(41.89f, -104.55f), new(42.35f, -104.03f), + new(42.82f, -103.73f), new(43.26f, -103.23f), new(43.91f, -102.16f), new(44.17f, -101.58f), new(44.63f, -100.24f), + new(45.31f, -97.65f), new(45.54f, -97.07f), new(46.05f, -96.92f), new(47.88f, -96.82f), new(48.35f, -96.39f), + new(48.66f, -95.81f), new(48.79f, -95.3f), new(48.72f, -94.66f), new(48.16f, -92.22f), new(48.24f, -91.62f), + new(48.84f, -89.08f), new(48.49f, -88.71f), new(47.85f, -88.36f), new(47.34f, -88.17f), new(47.02f, -87.7f), + new(47.19f, -87.16f), new(47.45f, -86.57f), new(47.81f, -86.12f), new(49.42f, -85.05f), new(49.44f, -84.36f), + new(48.2f, -84.03f), new(47.76f, -83.71f), new(47.47f, -83.15f), new(47.32f, -82.62f), new(47.52f, -82.04f), + new(47.65f, -81.41f), new(47.81f, -80.84f), new(48.2f, -80.48f), new(48.82f, -80.19f), new(49.3f, -79.79f), + new(49.9f, -79.42f), new(61.27f, -68.05f), new(61.74f, -67.71f), new(62.2f, -67.96f), new(64.14f, -69.9f), + new(64.7f, -70.33f), new(76.31f, -70.33f), new(76.9f, -69.96f), new(84.9f, -61.8f), new(84.9f, -50.09f), + new(84.46f, -49.58f), new(83.91f, -49.16f), new(79.33f, -49.16f), new(78.81f, -49.34f), new(77.57f, -49.08f), + new(77.38f, -48.41f), new(77.38f, -42.62f), new(76.96f, -42.07f), new(76.45f, -41.61f), new(64.79f, -41.61f), + new(64.33f, -41.84f), new(56.16f, -50.07f), new(56.18f, -61.74f), new(56.54f, -62.32f), new(57.5f, -63.28f), + new(57.99f, -63.58f), new(58.39f, -64.04f), new(58.73f, -64.52f), new(58.58f, -65.14f), new(47.32f, -76.44f), + new(47.05f, -77.03f), new(46.71f, -77.57f), new(45.45f, -79.03f), new(44.96f, -79.45f), new(44.42f, -79.8f), + new(43.86f, -80.05f), new(43.4f, -79.71f), new(43, -79.2f), new(42.91f, -78.69f), new(43.15f, -78.09f), + new(43.58f, -77.64f), new(43.54f, -76.99f), new(44.29f, -76.24f), new(44.29f, -75.59f), new(43.87f, -75.28f), + new(42.67f, -76.6f), new(39.76f, -78.38f), new(39.2f, -78.59f), new(36.64f, -76.64f), new(34.84f, -75.89f), + new(34.19f, -76.08f), new(32.64f, -77.1f), new(32.1f, -77.23f), new(30.5f, -76.22f), new(29.83f, -76.31f), + new(28.55f, -77), new(27.99f, -76.89f), new(25.5f, -76.06f), new(23.94f, -78.65f), new(19.71f, -79.74f), + new(19.54f, -80.21f), new(18.74f, -82.81f), new(18.98f, -83.42f), new(19.92f, -84.32f), new(20.43f, -84.7f), + new(20.45f, -85.26f), new(20.21f, -87.24f), new(20.04f, -87.78f), new(17.86f, -89.17f), new(17.34f, -89.27f), + new(12.21f, -88.09f), new(10.2f, -88.22f), new(9.78f, -87.89f), new(9.16f, -86.75f), new(8.49f, -86.6f), + new(7.82f, -86.55f), new(5.17f, -85.69f), new(4.63f, -85.33f), new(4.36f, -84.83f), new(4.1f, -83.49f), + new(3.57f, -82.98f), new(3.19f, -83.3f), new(2.72f, -83.78f), new(2.29f, -84.14f), new(1.64f, -84.22f), + new(0.99f, -84.36f), new(0.37f, -84.62f), new(-0.2f, -84.97f), new(-0.73f, -85.4f), new(-1.12f, -85.96f), + new(-2.05f, -87.77f), new(-2.21f, -88.45f), new(-2.24f, -89.12f), new(-2.12f, -89.77f), new(-2.1f, -90.39f), + new(-1.27f, -93.59f), new(-1.03f, -94.25f), new(-0.15f, -95.9f), new(0.36f, -96.31f), new(2.13f, -97.31f), + new(2.64f, -97.29f), new(4.03f, -96.92f), new(9.22f, -98.31f), new(9.78f, -98.53f), new(11.98f, -99.71f), + new(14.62f, -99.89f), new(18.29f, -98.54f), new(18.85f, -98.54f), new(19.4f, -98.86f), new(20.05f, -99.16f), + new(20.67f, -99.18f), new(21.35f, -99.35f), new(24.6f, -99.51f), new(25.11f, -99.81f), new(26.76f, -101.71f), + new(27.14f, -102.23f), new(29.46f, -106.03f), new(30.16f, -106.21f), new(33.5f, -106.35f), new(36.64f, -107)]; + private static readonly WPos[] vertices2 = [new(177.66f, -18.69f), new(183.93f, -18.6f), new(184.47f, -18.16f), new(192.47f, -10.16f), new(192.43f, 1.63f), + new(192.03f, 2.15f), new(184.37f, 9.81f), new(182.97f, 10.14f), new(182.41f, 9.79f), new(178.41f, 5.79f), + new(177.9f, 5.66f), new(173.72f, 9.83f), new(173.06f, 10.15f), new(172.22f, 10.15f), new(171.69f, 9.74f), + new(163.7f, 1.69f), new(163.72f, -10.19f), new(171.84f, -18.26f), new(174.94f, -18.6f), new(177.66f, -18.69f)]; + + private static readonly ArenaBoundsComplex arena1 = new([new PolygonCustom(vertices1)]); + private static readonly ArenaBoundsComplex arena2 = new([new PolygonCustom(vertices2)]); + + protected override bool CheckPull() => WorldState.Actors.Any(x => x.InCombat && x.Position.AlmostEqual(Arena.Center, Bounds.Radius)); + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(WorldState.Actors.Where(x => !x.IsAlly && x.Position.AlmostEqual(Arena.Center, Bounds.Radius))); + } +} diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSkycaller.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSkycaller.cs new file mode 100644 index 0000000000..a98efb565f --- /dev/null +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSkycaller.cs @@ -0,0 +1,66 @@ +namespace BossMod.Heavensward.Dungeon.D15Xelphatol.D150XelphatolSkycaller; + +public enum OID : uint +{ + Boss = 0x17B8, // R1.8 + AbalathianHornbill = 0x17B7 // R1.8 +} + +public enum AID : uint +{ + AutoAttack = 871, // AbalathianHornbill->player, no cast, single-target + + Aero = 969, // Boss->player, 1.0s cast, single-target + Gust = 6627, // AbalathianHornbill->location, 3.0s cast, range 5 circle + Tornado = 6413, // Boss->player, 5.0s cast, range 6 circle + IxaliAeroIII = 6629, // Boss->self, 3.0s cast, range 30+R circle + IxaliAeroII = 6628 // Boss->self, 3.0s cast, range 40+R width 8 rect +} + +class Tornado(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.Tornado), 6); +class TornadoHint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.Tornado), true, true, showNameInHint: true); +class IxaliAeroIII(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.IxaliAeroIII)); +class IxaliAeroIIIHint(BossModule module) : Components.CastInterruptHint(module, ActionID.MakeSpell(AID.IxaliAeroIII), true, true, showNameInHint: true); +class IxaliAeroII(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.IxaliAeroII), new AOEShapeRect(41.8f, 4)); +class Gust(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.Gust), 5); + +class D150XelphatolSkycallerStates : StateMachineBuilder +{ + public D150XelphatolSkycallerStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => Module.WorldState.Actors.Where(x => x.IsTargetable && !x.IsAlly && x.Position.AlmostEqual(Module.Arena.Center, Module.Bounds.Radius)) + .All(x => x.IsDeadOrDestroyed); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5264, SortOrder = 5)] +public class D150XelphatolSkycaller(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) +{ + private static readonly WPos[] vertices = [new(363.26f, -414.76f), new(365.28f, -414.44f), new(366.58f, -414.09f), new(368.51f, -413.30f), new(370.19f, -412.29f), + new(371.67f, -411.09f), new(372.58f, -410.18f), new(373.79f, -408.64f), new(374.75f, -406.99f), new(375.48f, -405.23f), + new(375.95f, -403.36f), new(376.16f, -401.34f), new(376.08f, -400.81f), new(376.16f, -400.25f), new(376.49f, -399.83f), + new(377.07f, -399.65f), new(377.24f, -398.97f), new(377, -396.94f), new(375.64f, -392.92f), new(375.18f, -393.24f), + new(374.64f, -393.43f), new(374.11f, -393.21f), new(373.64f, -392.77f), new(372.82f, -391.72f), new(371.39f, -390.26f), + new(369.78f, -389.07f), new(368.12f, -388.15f), new(366.92f, -387.66f), new(365.1f, -387.14f), new(363.28f, -386.88f), + new(361.21f, -386.87f), new(359.31f, -387.14f), new(357.49f, -387.66f), new(354.6f, -389.1f), new(353.05f, -390.3f), + new(351.57f, -391.81f), new(350.7f, -392.96f), new(349.73f, -394.6f), new(348.97f, -396.41f), new(348.48f, -398.39f), + new(348.28f, -399.75f), new(348.25f, -400.41f), new(348.31f, -400.98f), new(349.44f, -400.61f), new(350.02f, -400.64f), + new(350.62f, -400.85f), new(351.19f, -401), new(351.4f, -401.57f), new(351.28f, -402.08f), new(350.76f, -402.5f), + new(350.69f, -403.09f), new(350.14f, -403.35f), new(350.07f, -403.86f), new(350.87f, -406.19f), new(351.38f, -406.03f), + new(352.53f, -406.46f), new(353.12f, -406.38f), new(353.53f, -406.74f), new(353.48f, -407.25f), new(353.19f, -407.79f), + new(352.69f, -408.28f), new(352.36f, -408.67f), new(351.78f, -408.87f), new(351.05f, -409.21f), new(351.78f, -410.13f), + new(353.19f, -411.45f), new(356.06f, -413.34f), new(357.81f, -414.06f), new(359.74f, -414.53f)]; + private static readonly ArenaBoundsComplex arena = new([new PolygonCustom(vertices)]); + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(WorldState.Actors.Where(x => !x.IsAlly && x.Position.AlmostEqual(Arena.Center, Bounds.Radius))); + } +} diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSwiftbeak.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSwiftbeak.cs new file mode 100644 index 0000000000..180010d742 --- /dev/null +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D150XelphatolSwiftbeak.cs @@ -0,0 +1,201 @@ +namespace BossMod.Heavensward.Dungeon.D15Xelphatol.D150XelphatolSwiftbeak; + +public enum OID : uint +{ + Boss = 0x17BA, // R0.9 + XelphatolFatecaller = 0x17B4, // R1.08 + XelphatolStrongbeak = 0x17B3, // R1.08 + XelphatolBravewing = 0x17B2, // R1.08 + XelphatolWhirltalon = 0x17B1, // R1.08 + XelphatolWindtalon = 0x17B9, // R0.9 + XelphatolFogcaller = 0x17BB, // R0.9 + XelphatolWatchwolf = 0x17B6, // R1.65 + AbalathianHornbill = 0x17B7, // R1.8 + BoneKey = 0x1EA165, // R1.8 + Airstone1 = 0x1EA167, + Airstone2 = 0x1EA166 +} + +public enum AID : uint +{ + AutoAttack1 = 871, // XelphatolStrongbeak/XelphatolSwiftbeak/AbalathianHornbill->player, no cast, single-target + AutoAttack2 = 870, // XelphatolWhirltalon/XelphatolWindtalon/XelphatolBravewing/XelphatolWatchwolf->player, no cast, single-target + + ComingStorm = 423, // XelphatolWhirltalon/XelphatolSwiftbeak/XelphatolStrongbeak/XelphatolWindtalon->self, 2.5s cast, single-target + Aero = 969, // Boss/XelphatolFogcaller->player, 1.0s cast, single-target + TrueThrust = 722, // XelphatolStrongbeak/XelphatolSwiftbeak->player, no cast, single-target + FoulBite = 510, // XelphatolWatchwolf->player, no cast, single-target + FastBlade = 717, // XelphatolWhirltalon/XelphatolWindtalon->player, no cast, single-target + Overpower = 720, // XelphatolBravewing->self, 2.5s cast, range 6+R 90-degree cone + Gust = 6627, // AbalathianHornbill->location, 3.0s cast, range 5 circle + Breakbeak = 6626 // AbalathianHornbill->player, no cast, single-target +} + +class Overpower(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Overpower), new AOEShapeCone(7.08f, 45.Degrees())); +class Gust(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.Gust), 5); + +class D150XelphatolSwiftbeakStates : StateMachineBuilder +{ + public D150XelphatolSwiftbeakStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => Module.WorldState.Actors.Where(x => x.IsTargetable && !x.IsAlly && x.Position.AlmostEqual(Module.Arena.Center, Module.Bounds.Radius)) + .All(x => x.IsDestroyed) || Module.Enemies(OID.Airstone1).Concat(Module.Enemies(OID.Airstone2)).Concat(Module.Enemies(OID.BoneKey)).Any(x => x.IsTargetable); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5261, SortOrder = 4)] +public class D150XelphatolSwiftbeak(WorldState ws, Actor primary) : BossModule(ws, primary, IsArena1(primary) ? arena1.Center : IsArena2(primary) ? arena3.Center : arena2.Center, +IsArena1(primary) ? arena1 : IsArena2(primary) ? arena3 : arena2) +{ + private static bool IsArena1(Actor primary) => primary.Position.X < 200 && primary.Position.Z > -200; + private static bool IsArena2(Actor primary) => primary.Position.Z < -200; + private static readonly WPos[] vertices1 = [new(152.49f, -71.52f), new(150.27f, -69.29f), new(149.68f, -68.8f), new(147.76f, -70.72f), new(147.27f, -71.05f), + new(146.79f, -70.79f), new(146.28f, -70.33f), new(145.76f, -70.31f), new(145.3f, -69.98f), new(143.97f, -68.28f), + new(143.63f, -67.66f), new(144.19f, -67.53f), new(145.39f, -68.3f), new(145.89f, -68.72f), new(146.5f, -69.06f), + new(149.91f, -65.65f), new(152.35f, -62.06f), new(152.74f, -61.62f), new(153.26f, -61.56f), new(153.85f, -61.7f), + new(154.35f, -61.97f), new(159.95f, -67.57f), new(160.34f, -67.18f), new(160.7f, -66.57f), new(161.26f, -66.2f), + new(162.47f, -65.89f), new(164.88f, -63.55f), new(164.81f, -62.38f), new(164.64f, -61.73f), new(164.91f, -61.26f), + new(165.38f, -60.99f), new(165.98f, -61.15f), new(166.64f, -61.08f), new(167.12f, -61.39f), new(167.75f, -61.26f), + new(169.19f, -59.76f), new(169.14f, -59.07f), new(169.03f, -58.52f), new(168.95f, -57.24f), new(169.38f, -56.81f), + new(169.94f, -56.81f), new(170.57f, -57.01f), new(171.25f, -56.81f), new(171.89f, -56.45f), new(172.42f, -56), + new(173.84f, -54.58f), new(174.09f, -53.44f), new(174.98f, -52.51f), new(175.31f, -51.9f), new(158.57f, -35.16f), + new(158.14f, -34.88f), new(155.17f, -37.89f), new(154.78f, -38.48f), new(155.14f, -38.86f), new(155.17f, -39.47f), + new(155.05f, -40.14f), new(154.66f, -40.57f), new(154.04f, -40.79f), new(153.59f, -40.42f), new(153.45f, -39.48f), + new(153.14f, -39.9f), new(152.46f, -39.78f), new(151.91f, -39.51f), new(123.63f, -11.23f), new(123.65f, -10.19f), + new(122.66f, -9.44f), new(122.22f, -9), new(122.04f, -8.43f), new(122.38f, -7.94f), new(122.78f, -7.6f), + new(123.28f, -7.83f), new(123.8f, -8.22f), new(124.06f, -8.72f), new(124.53f, -9.02f), new(129.44f, -4.09f), + new(129.9f, -3.78f), new(130.4f, -4.08f), new(144.24f, -17.92f), new(144.73f, -17.74f), new(150.94f, -11.52f), + new(151.27f, -10.89f), new(147.57f, -7.19f), new(146.88f, -6.96f), new(145.51f, -6.86f), new(145.28f, -6.4f), + new(145.14f, -5.74f), new(145.13f, -5.01f), new(145.22f, -4.45f), new(146.19f, -3.62f), new(146.67f, -3.44f), + new(148.54f, -5.25f), new(149.17f, -5.59f), new(151.44f, -3.3f), new(151.72f, -2.85f), new(145.31f, 3.56f), + new(144.7f, 3.95f), new(144.3f, 3.6f), new(142.37f, 1.63f), new(142.13f, 1.16f), new(143.98f, -0.69f), + new(144.31f, -1.17f), new(144.23f, -2.46f), new(141.94f, -3.9f), new(141.44f, -3.82f), new(141.49f, -3.27f), + new(141.8f, -2.73f), new(142.22f, -2.29f), new(142.04f, -1.69f), new(136.81f, 3.55f), new(136.15f, 3.94f), + new(135.98f, 3.41f), new(135.5f, 3.05f), new(134.89f, 2.84f), new(134.31f, 3.03f), new(133.87f, 3.39f), + new(133.63f, 4), new(133.79f, 4.55f), new(134.27f, 5.05f), new(134.88f, 5.5f), new(132.13f, 8.26f), + new(131.67f, 7.94f), new(123.71f, 0.04f), new(123.21f, 0.2f), new(121.82f, 1.58f), new(121.42f, 1.93f), + new(117.11f, -2.41f), new(117.09f, -2.93f), new(116.83f, -3.39f), new(116.23f, -3.58f), new(115.52f, -3.64f), + new(115.02f, -3.41f), new(114.59f, -2.81f), new(114.14f, -2.36f), new(97.01f, 2.27f), new(91.6f, 0.34f), + new(88.26f, -1.92f), new(87.89f, -2.28f), new(88.29f, -2.67f), new(92.38f, -5.24f), new(92.88f, -5.38f), + new(102.76f, -2.94f), new(108.8f, -5.14f), new(109.41f, -5.47f), new(110.12f, -5.63f), new(110.77f, -5.9f), + new(111.35f, -6.29f), new(111.78f, -6.82f), new(111.85f, -7.35f), new(111.52f, -7.97f), new(109.03f, -10.51f), + new(106.15f, -13.34f), new(106.35f, -13.96f), new(107.7f, -15.31f), new(107.86f, -15.82f), new(107.48f, -16.28f), + new(99.82f, -23.94f), new(99.91f, -24.46f), new(102.28f, -26.84f), new(102.67f, -26.28f), new(103.27f, -25.88f), + new(103.85f, -25.73f), new(104.48f, -25.95f), new(104.85f, -26.39f), new(105.02f, -27.01f), new(104.79f, -27.49f), + new(104.36f, -27.94f), new(103.79f, -28.39f), new(105.79f, -30.36f), new(107.44f, -31.8f), new(107.89f, -32.3f), + new(107.84f, -32.86f), new(104.66f, -36.06f), new(104.39f, -36.68f), new(110.73f, -43.03f), new(111.3f, -43.47f), + new(115.04f, -39.71f), new(115.35f, -39.12f), new(115.26f, -38.43f), new(115.25f, -37.76f), new(115.66f, -37.37f), + new(117.68f, -37.35f), new(118.27f, -37.43f), new(118.58f, -37.82f), new(118.81f, -38.47f), new(118.71f, -38.96f), + new(117.36f, -40.32f), new(116.89f, -40.86f), new(117.26f, -41.85f), new(119.14f, -43.68f), new(119.94f, -43.31f), + new(125.96f, -37.24f), new(126.29f, -36.81f), new(123.91f, -34.45f), new(123.44f, -34.24f), new(121.6f, -36.07f), + new(121.15f, -36.4f), new(120.67f, -36.19f), new(120.18f, -35.7f), new(119.68f, -35.61f), new(118.96f, -35.57f), + new(118.51f, -35.21f), new(118.14f, -34.65f), new(117.83f, -34.09f), new(118.47f, -33.76f), new(119.1f, -33.62f), + new(119.58f, -33.89f), new(120.06f, -34.37f), new(120.59f, -34.17f), new(122.08f, -32.61f), new(111.86f, -22.43f), + new(111.7f, -21.91f), new(112.06f, -21.47f), new(115.95f, -17.58f), new(116.41f, -17.03f), new(116.17f, -16.43f), + new(116, -15.86f), new(115.96f, -15.25f), new(116.28f, -14.78f), new(116.79f, -14.58f), new(117.36f, -14.78f), + new(117.82f, -15.25f), new(119.11f, -15.74f), new(147.2f, -43.79f), new(147.6f, -44.28f), new(147.75f, -44.97f), + new(147.98f, -45.51f), new(148.1f, -46.11f), new(147.77f, -46.57f), new(147.32f, -46.94f), new(146.74f, -47.23f), + new(146.09f, -47.47f), new(145.4f, -47.64f), new(142.51f, -50.56f), new(142.14f, -51.12f), new(141.71f, -51.63f), + new(141.13f, -51.6f), new(137.4f, -47.93f), new(136.97f, -47.57f), new(132.04f, -52.51f), new(132.09f, -53.05f), + new(131.82f, -53.57f), new(130.88f, -54.62f), new(130.32f, -55.07f), new(129.78f, -54.98f), new(129.21f, -54.7f), + new(128.72f, -54.39f), new(128.54f, -53.84f), new(128.06f, -53.39f), new(127.43f, -53.4f), new(126.98f, -53.89f), + new(126.89f, -54.4f), new(127.25f, -54.95f), new(129.7f, -57.25f), new(129.54f, -57.74f), new(129, -57.94f), + new(128.47f, -57.74f), new(127.64f, -56.93f), new(127.26f, -57.31f), new(127.13f, -57.94f), new(127.16f, -58.54f), + new(127.13f, -59.17f), new(129.4f, -61.42f), new(129.91f, -61.77f), new(130.78f, -62.57f), new(130.78f, -63.16f), + new(127.34f, -66.63f), new(127.1f, -67.12f), new(128.18f, -67.39f), new(128.97f, -68.43f), new(128.92f, -69.11f), + new(128.68f, -69.67f), new(128.38f, -70.2f), new(127.51f, -71.06f), new(126.93f, -71.06f), new(126.39f, -70.86f), + new(124.4f, -68.9f), new(123.93f, -69.09f), new(122.03f, -71), new(121.61f, -71.66f), new(128.23f, -78.23f), + new(128.89f, -78.2f), new(130.78f, -76.28f), new(131.2f, -75.66f), new(129.56f, -74.52f), new(129.04f, -74.09f), + new(129, -73.4f), new(129.26f, -72.85f), new(129.73f, -72.38f), new(129.96f, -71.93f), new(130.5f, -70.54f), + new(130.8f, -70.11f), new(131.38f, -70.01f), new(131.74f, -70.44f), new(131.89f, -71.05f), new(131.45f, -71.84f), + new(132.12f, -71.93f), new(132.8f, -72.2f), new(133.36f, -72.58f), new(133.81f, -72.32f), new(136.85f, -69.29f), + new(137.38f, -69.4f), new(139.79f, -71.82f), new(140.43f, -72.12f), new(141.1f, -72.26f), new(141.49f, -72.61f), + new(141.86f, -72.27f), new(143.06f, -71.57f), new(143.65f, -71.37f), new(144.29f, -71.67f), new(144.85f, -72.05f), + new(144.97f, -72.75f), new(145, -73.4f), new(144.61f, -73.89f), new(143.22f, -75.27f), new(142.79f, -75.87f), + new(145.52f, -78.54f)]; + private static readonly WPos[] vertices2 = [new(302.73f, -161.99f), new(302.61f, -161.34f), new(302.15f, -160.81f), new(301.76f, -160.27f), new(301.49f, -159.68f), + new(301.72f, -159.14f), new(302.11f, -158.57f), new(302.6f, -158.31f), new(303.27f, -158.45f), new(304.24f, -159.21f), + new(304.75f, -159.2f), new(306.85f, -156.59f), new(307.13f, -155.99f), new(307.64f, -155.48f), new(308.16f, -155.03f), + new(308.75f, -154.68f), new(308.83f, -153.97f), new(308.59f, -153.25f), new(308.56f, -152.71f), new(309.04f, -152.36f), + new(309.59f, -152.37f), new(309.75f, -152.94f), new(310.04f, -154.92f), new(309.84f, -156.95f), new(309.96f, -158.15f), + new(310.72f, -159.25f), new(311.42f, -159.33f), new(312.07f, -159.33f), new(312.7f, -159.08f), new(314.34f, -157.83f), + new(314.92f, -157.76f), new(316.86f, -157.94f), new(317.52f, -157.65f), new(318.14f, -157.27f), new(318.67f, -156.82f), + new(319.22f, -156.47f), new(319.82f, -156.53f), new(320.53f, -156.38f), new(321.72f, -155.61f), new(322.33f, -155.48f), + new(323.71f, -155.58f), new(324.37f, -155.3f), new(325.38f, -154.31f), new(325.61f, -153.85f), new(326.17f, -151.95f), + new(326.14f, -151.28f), new(326.35f, -150.68f), new(326.72f, -150.27f), new(327.29f, -150.43f), new(327.81f, -150.82f), + new(328.45f, -150.68f), new(331.62f, -146.53f), new(331.83f, -146.07f), new(331.35f, -143.4f), new(331.49f, -142.83f), + new(331.8f, -142.22f), new(331.7f, -141.53f), new(331.32f, -140.23f), new(331.22f, -139.61f), new(332.49f, -137.38f), + new(332.23f, -136.73f), new(331.51f, -135.55f), new(331.73f, -134.92f), new(332.03f, -134.33f), new(332.06f, -133.63f), + new(332.2f, -132.97f), new(332.54f, -132.34f), new(339.24f, -123.51f), new(339.45f, -122.84f), new(331.97f, -117.15f), + new(331.35f, -117.47f), new(325.74f, -124.85f), new(325.59f, -125.51f), new(325.4f, -126.11f), new(325.08f, -126.77f), + new(324.68f, -127.37f), new(324.19f, -127.85f), new(323.62f, -128.16f), new(323.03f, -128.15f), new(322.75f, -127.55f), + new(322.64f, -126.96f), new(322.89f, -126.4f), new(323.27f, -125.68f), new(321.29f, -125.78f), new(320.82f, -125.57f), + new(319.98f, -124.59f), new(319.3f, -124.45f), new(317.9f, -124.58f), new(317.2f, -124.59f), new(316.51f, -124.48f), + new(315.83f, -124.29f), new(315.17f, -124.04f), new(314.69f, -123.64f), new(314.7f, -121.7f), new(314.53f, -121.02f), + new(313.61f, -118.49f), new(314.35f, -116.04f), new(312.59f, -111.89f), new(312.18f, -111.33f), new(307.85f, -107.41f), + new(307.42f, -106.91f), new(305.03f, -103.72f), new(304.75f, -103.19f), new(304.67f, -102.54f), new(304.04f, -102.45f), + new(302.13f, -103.34f), new(301.7f, -103.59f), new(295.22f, -108.33f), new(295.48f, -108.79f), new(295.95f, -109.27f), + new(297.15f, -109.62f), new(297.67f, -109.86f), new(299.36f, -111.79f), new(299.66f, -112.33f), new(300.11f, -113.51f), + new(300, -114.07f), new(299.83f, -114.67f), new(299.93f, -115.34f), new(300.82f, -116.26f), new(300.93f, -116.76f), + new(300.33f, -117.87f), new(300.45f, -118.52f), new(301.44f, -119.45f), new(302.2f, -120.51f), new(302.03f, -121.02f), + new(301.74f, -121.63f), new(301.74f, -122.31f), new(302.13f, -122.89f), new(302.42f, -123.44f), new(302.17f, -123.89f), + new(301.23f, -124.96f), new(300.79f, -125.62f), new(301.72f, -126.25f), new(304.12f, -128.51f), new(304.07f, -129.17f), + new(302.29f, -130.96f), new(299.44f, -134.59f), new(296.95f, -136.83f), new(296.82f, -137.5f), new(296.94f, -138.8f), + new(297.35f, -139.3f), new(299.5f, -140.68f), new(299.55f, -141.21f), new(299.22f, -142.45f), new(299.55f, -142.85f), + new(301.13f, -144.1f), new(301.12f, -144.67f), new(300.86f, -146.6f), new(301.01f, -147.85f), new(296.9f, -153.28f), + new(297.14f, -153.73f), new(297.68f, -154.12f), new(298.14f, -154.56f), new(298.4f, -155.12f), new(298.28f, -155.68f), + new(298.26f, -156.33f), new(297.75f, -156.65f), new(297.15f, -156.84f), new(296.68f, -156.64f), new(296.25f, -156.18f), + new(295.69f, -155.83f), new(295.06f, -156.04f), new(294.51f, -156.41f), new(293.27f, -158.04f), new(293.17f, -158.54f), + new(300.31f, -163.97f), new(300.93f, -164.37f)]; + private static readonly WPos[] vertices3 = [new(424.15f, -281.72f), new(425.91f, -280.7f), new(426.84f, -279.74f), new(427.41f, -279.61f), new(428.02f, -279.57f), + new(428.68f, -279.45f), new(430.08f, -278.06f), new(430.61f, -278.11f), new(431.83f, -278.47f), new(432.46f, -278.33f), + new(433.89f, -276.3f), new(434.46f, -276.19f), new(436.98f, -275.94f), new(443.23f, -277.15f), new(442.81f, -276.87f), + new(442.67f, -276.35f), new(442.88f, -275.7f), new(443.19f, -275.18f), new(443.63f, -274.71f), new(444.16f, -274.62f), + new(444.75f, -274.8f), new(445.24f, -275.12f), new(445.38f, -275.73f), new(445.34f, -276.33f), new(445.22f, -276.97f), + new(445.54f, -277.54f), new(446.18f, -277.73f), new(448.77f, -278.22f), new(450.58f, -268.77f), new(450.12f, -268.37f), + new(447.58f, -267.92f), new(447.11f, -268.36f), new(446.58f, -269.62f), new(446.22f, -270.05f), new(445.64f, -270.09f), + new(445.02f, -269.99f), new(444.49f, -269.77f), new(444.31f, -269.2f), new(444.25f, -268.6f), new(443.97f, -267.96f), + new(443.45f, -267.49f), new(438.03f, -266.4f), new(437.38f, -266.19f), new(436.8f, -265.83f), new(436.7f, -265.32f), + new(437.11f, -264.95f), new(437.78f, -264.75f), new(438.39f, -264.76f), new(439.01f, -264.84f), new(438.14f, -262.98f), + new(438.27f, -262.31f), new(438.63f, -261.81f), new(438.86f, -261.17f), new(438.81f, -260.46f), new(435.89f, -254.52f), + new(435.44f, -253.98f), new(433.8f, -252.73f), new(431.91f, -252.15f), new(431.38f, -251.84f), new(429.92f, -250.38f), + new(427.96f, -249.81f), new(427.56f, -249.46f), new(426.75f, -247.02f), new(426.58f, -244.48f), new(426.19f, -243.21f), + new(425.3f, -242.25f), new(424.96f, -241.77f), new(425.16f, -241.23f), new(425.8f, -240.01f), new(424.49f, -237.92f), + new(424.29f, -237.36f), new(424.14f, -236.73f), new(423.9f, -236.12f), new(420.21f, -233.59f), new(419.49f, -232.57f), + new(419.01f, -232.07f), new(417.74f, -231.73f), new(415.19f, -229.65f), new(413.84f, -228.3f), new(413.45f, -227.85f), + new(413.16f, -226.55f), new(412.68f, -226.82f), new(406.34f, -232.53f), new(405.89f, -233.08f), new(405.51f, -233.61f), + new(405.18f, -234.22f), new(405, -234.84f), new(405.28f, -235.45f), new(405.8f, -235.82f), new(406.38f, -236.17f), + new(407.72f, -236.09f), new(409.72f, -237.73f), new(410.14f, -238.16f), new(410.84f, -239.23f), new(410.89f, -239.85f), + new(410.87f, -240.46f), new(411.18f, -241.03f), new(411.61f, -241.46f), new(411.95f, -241.93f), new(412.15f, -242.43f), + new(412.07f, -242.99f), new(411.39f, -243.96f), new(411.68f, -244.4f), new(412.2f, -244.84f), new(412.92f, -244.89f), + new(413.43f, -245.07f), new(413.9f, -245.57f), new(414.2f, -246.04f), new(414.01f, -246.6f), new(413.46f, -246.98f), + new(413.52f, -247.57f), new(414.13f, -247.85f), new(414.62f, -248.23f), new(415.01f, -248.64f), new(414.84f, -249.15f), + new(414.33f, -249.53f), new(413.39f, -250.45f), new(413.48f, -250.96f), new(413.72f, -251.55f), new(413.8f, -252.16f), + new(413.69f, -252.72f), new(410.03f, -254.04f), new(409.58f, -254.55f), new(409, -254.52f), new(406.5f, -254.04f), + new(405.85f, -253.97f), new(403.3f, -253.44f), new(402.79f, -253.41f), new(402.27f, -254.66f), new(401.96f, -255.15f), + new(401.52f, -255.6f), new(400.32f, -255.46f), new(399.89f, -255.08f), new(399.73f, -254.43f), new(399.88f, -253.89f), + new(400.29f, -253.37f), new(400.14f, -252.87f), new(399.45f, -252.68f), new(396.37f, -252.08f), new(394.57f, -261.32f), + new(394.54f, -261.84f), new(397.04f, -262.31f), new(397.79f, -262.4f), new(398.24f, -261.23f), new(398.59f, -260.65f), + new(399.07f, -260.21f), new(400.36f, -260.26f), new(400.74f, -260.73f), new(400.91f, -261.38f), new(401.17f, -262.07f), + new(401.94f, -263.13f), new(402.41f, -263.37f), new(405.2f, -263.92f), new(406.48f, -263.95f), new(407.09f, -264.04f), + new(407.63f, -264.27f), new(407.59f, -264.95f), new(407.24f, -265.45f), new(406.67f, -265.77f), new(405.51f, -266.3f), + new(404.9f, -266.65f), new(404.36f, -267.06f), new(404.05f, -267.64f), new(403.73f, -268.9f), new(403.88f, -269.59f), + new(404.11f, -270.2f), new(404.68f, -270.62f), new(406.62f, -271.35f), new(406.95f, -271.79f), new(407.08f, -273.02f), + new(407.34f, -273.64f), new(407.85f, -274.13f), new(409.21f, -274.58f), new(409.71f, -274.82f), new(409.88f, -275.4f), + new(410.21f, -276.01f), new(411.4f, -276.57f), new(411.93f, -276.89f), new(412.75f, -278.54f), new(413.24f, -278.36f), + new(414.29f, -277.67f), new(418.52f, -278.64f), new(418.68f, -279.2f), new(418.61f, -279.82f), new(418.67f, -280.5f), + new(419.3f, -280.72f), new(419.95f, -280.81f), new(421.2f, -280.81f), new(423.68f, -281.65f)]; + private static readonly ArenaBoundsComplex arena1 = new([new PolygonCustom(vertices1)]); + private static readonly ArenaBoundsComplex arena2 = new([new PolygonCustom(vertices2)]); + private static readonly ArenaBoundsComplex arena3 = new([new PolygonCustom(vertices3)]); + + protected override bool CheckPull() => WorldState.Actors.Any(x => x.InCombat && x.Position.AlmostEqual(Arena.Center, Bounds.Radius)); + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actors(WorldState.Actors.Where(x => !x.IsAlly && x.Position.AlmostEqual(Arena.Center, Bounds.Radius))); + } +} diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D151NuzalHueloc.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D151NuzalHueloc.cs index 9a0522a717..7a246e415d 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D151NuzalHueloc.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D151NuzalHueloc.cs @@ -80,7 +80,7 @@ public D151NuzalHuelocStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5265)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5265, SortOrder = 2)] public class D151NuzalHueloc(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { private static readonly WPos[] vertices = [new(-73.36f, -91.53f), new(-67.17f, -90.22f), new(-66.55f, -89.97f), new(-64.94f, -89.05f), new(-64.45f, -88.60f), @@ -93,7 +93,7 @@ public class D151NuzalHueloc(WorldState ws, Actor primary) : BossModule(ws, prim protected override void DrawEnemies(int pcSlot, Actor pc) { - Arena.Actors(Enemies(OID.IxaliStitcher).Concat([PrimaryActor]).Concat(Enemies(OID.FloatingTurret)).Concat(Enemies(OID.Airstone))); + Arena.Actors(WorldState.Actors.Where(x => !x.IsAlly)); } protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D152DotoliCiloc.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D152DotoliCiloc.cs index 6b853ddd7e..cfa919cc12 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D152DotoliCiloc.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D152DotoliCiloc.cs @@ -189,14 +189,13 @@ public D152DotoliCilocStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5269)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5269, SortOrder = 6)] public class D152DotoliCiloc(WorldState ws, Actor primary) : BossModule(ws, primary, ArenaCenter, StartingBounds) { public static readonly WPos ArenaCenter = new(245.289f, 13.626f); - private static readonly float multi = 1 / MathF.Cos(MathF.PI / 16); private const float offset = 0.42f; - public static readonly Polygon[] StartingBoundsP = [new Polygon(ArenaCenter, 29.45f * multi, 16, 11.25f.Degrees())]; - public static readonly Polygon[] DefaultBoundsP = [new Polygon(ArenaCenter, 20 * multi, 16, 11.25f.Degrees())]; + public static readonly Polygon[] StartingBoundsP = [new Polygon(ArenaCenter, 29.45f * CosPI.Pi16th, 16, 11.25f.Degrees())]; + public static readonly Polygon[] DefaultBoundsP = [new Polygon(ArenaCenter, 20 * CosPI.Pi16th, 16, 11.25f.Degrees())]; private static readonly WPos[] verticesW = [new(227.1f, 17.333f), new(226.122f, 13.411f), new(227, 10.126f), new(225.087f, 9.583f), new(224.016f, 13.541f), new(225.124f, 17.756f)]; private static readonly WPos[] verticesN = GenerateRotatedVertices(verticesW, 90); private static readonly WPos[] verticesE = GenerateRotatedVertices(verticesW, 180); diff --git a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D153TozolHuatotl.cs b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D153TozolHuatotl.cs index 5c2543c502..d05f312e64 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D153TozolHuatotl.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D15Xelphatol/D153TozolHuatotl.cs @@ -58,8 +58,8 @@ public D153TozolHuatotlStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5272)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 182, NameID = 5272, SortOrder = 7)] public class D153TozolHuatotl(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(317.8f, -416.19f), 19.5f / MathF.Cos(MathF.PI / 48), 48)], [new Rectangle(new(336.69f, -409.415f), 20, 1, -70.Degrees())]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(317.8f, -416.19f), 19.5f * CosPI.Pi48th, 48)], [new Rectangle(new(336.69f, -409.415f), 20, 1, -70.Degrees())]); } diff --git a/BossMod/Modules/RealmReborn/Dungeon/D13CastrumMeridianum/D133Livia.cs b/BossMod/Modules/RealmReborn/Dungeon/D13CastrumMeridianum/D133Livia.cs index 5a917a7e13..66e4bd4fdb 100644 --- a/BossMod/Modules/RealmReborn/Dungeon/D13CastrumMeridianum/D133Livia.cs +++ b/BossMod/Modules/RealmReborn/Dungeon/D13CastrumMeridianum/D133Livia.cs @@ -218,6 +218,6 @@ public D133LiviaStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "veyn, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 15, NameID = 2118)] public class D133Livia(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-98, -33), 19.5f / MathF.Cos(MathF.PI / 36), 36)], + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-98, -33), 19.5f * CosPI.Pi36th, 36)], [new Rectangle(new(-78.187f, -36.886f), 20, 1.25f, 79.Degrees())]); } diff --git a/BossMod/Modules/RealmReborn/Dungeon/D14Praetorium/D141Colossus.cs b/BossMod/Modules/RealmReborn/Dungeon/D14Praetorium/D141Colossus.cs index e97581434c..dd5fca4410 100644 --- a/BossMod/Modules/RealmReborn/Dungeon/D14Praetorium/D141Colossus.cs +++ b/BossMod/Modules/RealmReborn/Dungeon/D14Praetorium/D141Colossus.cs @@ -42,6 +42,6 @@ public D141ColossusStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "veyn, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 16, NameID = 2134)] public class D141Colossus(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(192, 0), 14.5f / MathF.Cos(MathF.PI / 48), 48)], + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(192, 0), 14.5f * CosPI.Pi48th, 48)], [new Rectangle(new(207, 0), 20, 1.25f, 90.Degrees()), new Rectangle(new(177, 0), 20, 1.8f, 90.Degrees())]); } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D031Lozatl.cs b/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D031Lozatl.cs index e52b63d010..10fe5d722a 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D031Lozatl.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D031Lozatl.cs @@ -68,5 +68,5 @@ public D031LozatlStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 651, NameID = 8231)] public class D031Lozatl(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, 315), 19.5f / MathF.Cos(MathF.PI / 40), 40)], [new Rectangle(new(0, 335.1f), 20, 2), new Rectangle(new(0, 294.5f), 20, 2)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, 315), 19.5f * CosPI.Pi40th, 40)], [new Rectangle(new(0, 335.1f), 20, 2), new Rectangle(new(0, 294.5f), 20, 2)]); } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D032Batsquatch.cs b/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D032Batsquatch.cs index 68d83f50ef..da1ebec24f 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D032Batsquatch.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D03QitanaRavel/D032Batsquatch.cs @@ -77,5 +77,5 @@ public D032BatsquatchStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 651, NameID = 8232)] public class D032Batsquatch(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(62, -35), 14.5f / MathF.Cos(MathF.PI / 28), 28)], [new Rectangle(new(61.9f, -20), 20, 2), new Rectangle(new(61.9f, -50), 20, 2)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(62, -35), 14.5f * CosPI.Pi28th, 28)], [new Rectangle(new(61.9f, -20), 20, 2), new Rectangle(new(61.9f, -50), 20, 2)]); } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D072Mithridates.cs b/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D072Mithridates.cs index b73c7fd4fb..85d7028cac 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D072Mithridates.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D072Mithridates.cs @@ -61,6 +61,6 @@ public D072MithridatesStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 655, NameID = 8165)] public class D072Mithridates(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(200, 68), 19.5f / MathF.Cos(MathF.PI / 36), 36)], + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(200, 68), 19.5f * CosPI.Pi36th, 36)], [new Rectangle(new(200, 88), 20, 1.25f), new Rectangle(new(200, 48), 20, 1.25f)]); } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D073TheTycoon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D073TheTycoon.cs index f121b0f0fb..b12ca15a41 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D073TheTycoon.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D07Twinning/D073TheTycoon.cs @@ -71,5 +71,5 @@ public D073TheTycoonStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 655, NameID = 8167)] public class D073TheTycoon(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, -329), 19.5f / MathF.Cos(MathF.PI / 36), 36)], [new Rectangle(new(0, -309), 20, 1.25f)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, -329), 19.5f * CosPI.Pi36th, 36)], [new Rectangle(new(0, -309), 20, 1.25f)]); } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs index 5477142619..317ca81c66 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D081Cladoselache.cs @@ -52,7 +52,7 @@ public D081CladoselacheStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 661, NameID = 8235)] public class D081Cladoselache(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-305, 211.5f), 19.5f / MathF.Cos(MathF.PI / 60), 60)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(-305, 211.5f), 19.5f * CosPI.Pi60th, 60)]); protected override void DrawEnemies(int pcSlot, Actor pc) { diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D082MorbolMarquis.cs b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D082MorbolMarquis.cs index 88e63ae8ef..e6b3a55867 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D082MorbolMarquis.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D082MorbolMarquis.cs @@ -136,7 +136,7 @@ public class D082MorbolMarquis(WorldState ws, Actor primary) : BossModule(ws, pr private const int X = -224, InnerRadius = 10, OuterRadius = 15, Radius = 25, Edges = 12; private static readonly WPos ArenaCenter = new(X, -38); public static readonly Angle A45 = 45.Degrees(), a135 = 135.Degrees(); - private static readonly Polygon[] defaultCircle = [new(ArenaCenter, 24.5f / MathF.Cos(MathF.PI / 48), 48)]; + private static readonly Polygon[] defaultCircle = [new(ArenaCenter, 24.5f * CosPI.Pi48th, 48)]; private static readonly Rectangle[] defaultDifference = [new(new(X, -13), Radius, 1.1f), new(new(X, -63), Radius, 1.1f)]; private static readonly Shape[] blueBlossom = [new ConeV(ArenaCenter, InnerRadius, A45, A45, Edges), new ConeV(ArenaCenter, InnerRadius, -a135, A45, Edges), new DonutSegmentV(ArenaCenter, OuterRadius, Radius, A45, A45, Edges), new DonutSegmentV(ArenaCenter, OuterRadius, Radius, -a135, A45, Edges)]; diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D083Quetzalcoatl.cs b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D083Quetzalcoatl.cs index d67179190c..7a10860596 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D083Quetzalcoatl.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D08AkadaemiaAnyder/D083Quetzalcoatl.cs @@ -140,5 +140,5 @@ public D083QuetzalcoatlStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 661, NameID = 8273)] public class D083Quetzalcoatl(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, -379), 19.5f / MathF.Cos(MathF.PI / 48), 48)], [new Rectangle(new(0, -359), 20, 1.1f)]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, -379), 19.5f * CosPI.Pi48th, 48)], [new Rectangle(new(0, -359), 20, 1.1f)]); } diff --git a/BossMod/Modules/Stormblood/Dungeon/D02ShisuiOfTheVioletTides/D021Amikiri.cs b/BossMod/Modules/Stormblood/Dungeon/D02ShisuiOfTheVioletTides/D021Amikiri.cs index bf95df97f1..b6670c2f49 100644 --- a/BossMod/Modules/Stormblood/Dungeon/D02ShisuiOfTheVioletTides/D021Amikiri.cs +++ b/BossMod/Modules/Stormblood/Dungeon/D02ShisuiOfTheVioletTides/D021Amikiri.cs @@ -99,7 +99,7 @@ public D021AmikiriStates(BossModule module) : base(module) [ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 235, NameID = 6237)] public class D021Amikiri(WorldState ws, Actor primary) : BossModule(ws, primary, arena.Center, arena) { - private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, 69.221f), 19.5f / MathF.Cos(MathF.PI / 8), 8, 22.5f.Degrees())]); + private static readonly ArenaBoundsComplex arena = new([new Polygon(new(0, 69.221f), 19.5f * CosPI.Pi8th, 8, 22.5f.Degrees())]); protected override void DrawEnemies(int pcSlot, Actor pc) { diff --git a/BossMod/Network/PacketDecoder.cs b/BossMod/Network/PacketDecoder.cs index bf5bc36d25..cd9e6df6a2 100644 --- a/BossMod/Network/PacketDecoder.cs +++ b/BossMod/Network/PacketDecoder.cs @@ -8,8 +8,8 @@ public abstract unsafe class PacketDecoder protected DateTime Now; private const float Hundredth = 1e-2f; private const float Thousandth = 1e-3f; - private const float TwoKD65k = 2000f / 65535; - private const float Inv65k = 1f / 65535; + private const float TwoKD65k = (float)(2000d / 65535); + private const float Inv65k = (float)(1d / 65535); public class TextNode(string text) { diff --git a/BossMod/Util/Angle.cs b/BossMod/Util/Angle.cs index 42e6c5051f..8df49bef3c 100644 --- a/BossMod/Util/Angle.cs +++ b/BossMod/Util/Angle.cs @@ -4,10 +4,10 @@ // when describing rotation in world, common convention is 0 for 'south'/'down'/(0, -1) and increasing counterclockwise - so +90 is 'east'/'right'/(1, 0) public record struct Angle(float Rad) { - public const float RadToDeg = 180 / MathF.PI; - public const float DegToRad = MathF.PI / 180; - public const float HalfPi = MathF.PI / 2; - public const float DoublePI = 2 * MathF.PI; + public const float RadToDeg = (float)(180 / Math.PI); + public const float DegToRad = (float)(Math.PI / 180); + public const float HalfPi = (float)(Math.PI / 2); + public const float DoublePI = (float)(2 * Math.PI); public static readonly Angle[] AnglesIntercardinals = [-45.003f.Degrees(), 44.998f.Degrees(), 134.999f.Degrees(), -135.005f.Degrees()]; public static readonly Angle[] AnglesCardinals = [-90.004f.Degrees(), -0.003f.Degrees(), 180.Degrees(), 89.999f.Degrees()]; @@ -32,11 +32,11 @@ public readonly WDir ToDirection() public static bool operator <=(Angle a, Angle b) => a.Rad <= b.Rad; public readonly Angle Abs() => new(Math.Abs(Rad)); - public readonly float Sin() => MathF.Sin(Rad); - public readonly float Cos() => MathF.Cos(Rad); - public readonly float Tan() => MathF.Tan(Rad); - public static Angle Asin(float x) => new(MathF.Asin(x)); - public static Angle Acos(float x) => new(MathF.Acos(x)); + public readonly float Sin() => (float)Math.Sin(Rad); + public readonly float Cos() => (float)Math.Cos(Rad); + public readonly float Tan() => (float)Math.Tan(Rad); + public static Angle Asin(float x) => new((float)Math.Asin(x)); + public static Angle Acos(float x) => new((float)Math.Acos(x)); public readonly Angle Normalized() { @@ -59,3 +59,16 @@ public static class AngleExtensions public static Angle Degrees(this float degrees) => new(degrees * Angle.DegToRad); public static Angle Degrees(this int degrees) => new(degrees * Angle.DegToRad); } + +public static class CosPI +{ + public static readonly float Pi8th = (float)(1 / Math.Cos(Math.PI / 8)); + public static readonly float Pi16th = (float)(1 / Math.Cos(Math.PI / 16)); + public static readonly float Pi20th = (float)(1 / Math.Cos(Math.PI / 20)); + public static readonly float Pi28th = (float)(1 / Math.Cos(Math.PI / 28)); + public static readonly float Pi32th = (float)(1 / Math.Cos(Math.PI / 32)); + public static readonly float Pi36th = (float)(1 / Math.Cos(Math.PI / 36)); + public static readonly float Pi40th = (float)(1 / Math.Cos(Math.PI / 40)); + public static readonly float Pi48th = (float)(1 / Math.Cos(Math.PI / 48)); + public static readonly float Pi60th = (float)(1 / Math.Cos(Math.PI / 60)); +} diff --git a/BossMod/Util/Polygon.cs b/BossMod/Util/Polygon.cs index 4a2a012253..58e53b4c56 100644 --- a/BossMod/Util/Polygon.cs +++ b/BossMod/Util/Polygon.cs @@ -17,13 +17,21 @@ public RelPolygonWithHoles(List simpleVertices) : this(simpleVertices, []) public ReadOnlySpan AllVertices => Vertices.AsSpan(); public ReadOnlySpan Exterior => AllVertices[..ExteriorEnd]; public ReadOnlySpan Interior(int index) => AllVertices[HoleStarts[index]..HoleEnd(index)]; - public IEnumerable Holes => Enumerable.Range(0, HoleStarts.Count); + public IEnumerable Holes + { + get + { + for (var i = 0; i < HoleStarts.Count; ++i) + yield return i; + } + } + public IEnumerable<(WDir, WDir)> ExteriorEdges => PolygonUtil.EnumerateEdges(Vertices.Take(ExteriorEnd)); public IEnumerable<(WDir, WDir)> InteriorEdges(int index) => PolygonUtil.EnumerateEdges(Vertices.Skip(HoleStarts[index]).Take(HoleEnd(index) - HoleStarts[index])); private ContourEdgeBuckets? _exteriorEdgeBuckets; private List _holeEdgeBuckets = []; - private const int BucketCount = 10; + private const int BucketCount = 20; private const float Epsilon = 1e-8f; private int ExteriorEnd => HoleStarts.Count > 0 ? HoleStarts[0] : Vertices.Count; @@ -68,17 +76,20 @@ public bool Contains(WDir p) if (_exteriorEdgeBuckets == null) { var holecount = HoleStarts.Count; - _exteriorEdgeBuckets = BuildEdgeBucketsForContour(Exterior); - if (holecount > 0) - { - _holeEdgeBuckets = new List(new ContourEdgeBuckets[holecount]); - Parallel.For(0, holecount, i => - { - _holeEdgeBuckets[i] = BuildEdgeBucketsForContour(Interior(i)); - }); - } + if (holecount == 0) + _exteriorEdgeBuckets = BuildEdgeBucketsForContour(Exterior); + else + Parallel.Invoke( + () => _exteriorEdgeBuckets = BuildEdgeBucketsForContour(Exterior), + () => + { + _holeEdgeBuckets = new List(new ContourEdgeBuckets[holecount]); + Parallel.For(0, holecount, i => + { + _holeEdgeBuckets[i] = BuildEdgeBucketsForContour(Interior(i)); + }); + }); } - if (!InSimplePolygon(p, _exteriorEdgeBuckets!)) return false; for (var i = 0; i < _holeEdgeBuckets.Count; ++i) @@ -125,7 +136,7 @@ private static ContourEdgeBuckets BuildEdgeBucketsForContour(ReadOnlySpan var invBucketHeight = BucketCount / (maxY - minY + Epsilon); var edgeBucketsArray = new List[BucketCount]; - for (var b = 0; b < BucketCount; b++) + for (var b = 0; b < BucketCount; ++b) { edgeBucketsArray[b] = []; } @@ -142,7 +153,7 @@ private static ContourEdgeBuckets BuildEdgeBucketsForContour(ReadOnlySpan bucketStart = Math.Clamp(bucketStart, 0, BucketCount - 1); bucketEnd = Math.Clamp(bucketEnd, 0, BucketCount - 1); - for (var b = bucketStart; b <= bucketEnd; b++) + for (var b = bucketStart; b <= bucketEnd; ++b) { edgeBucketsArray[b].Add(edge); } @@ -151,7 +162,7 @@ private static ContourEdgeBuckets BuildEdgeBucketsForContour(ReadOnlySpan } var edgeBuckets = new Edges[BucketCount][]; - for (var b = 0; b < BucketCount; b++) + for (var b = 0; b < BucketCount; ++b) { edgeBuckets[b] = [.. edgeBucketsArray[b]]; } diff --git a/BossMod/Util/WPosDir.cs b/BossMod/Util/WPosDir.cs index c0419ed81d..ce34211776 100644 --- a/BossMod/Util/WPosDir.cs +++ b/BossMod/Util/WPosDir.cs @@ -15,7 +15,12 @@ public WDir(Vector2 v) : this(v.X, v.Y) { } public static WDir operator -(WDir a, WPos b) => new(a.X - b.X, a.Z - b.Z); public static WDir operator *(WDir a, float b) => new(a.X * b, a.Z * b); public static WDir operator *(float a, WDir b) => new(a * b.X, a * b.Z); - public static WDir operator /(WDir a, float b) => new(a.X / b, a.Z / b); + public static WDir operator /(WDir a, float b) + { + var invB = 1 / b; + return new(a.X * invB, a.Z * invB); + } + public readonly WDir Abs() => new(Math.Abs(X), Math.Abs(Z)); public readonly WDir Sign() => new(Math.Sign(X), Math.Sign(Z)); public readonly WDir OrthoL() => new(Z, -X); // CCW, same length @@ -36,7 +41,7 @@ public WDir(Vector2 v) : this(v.X, v.Y) { } public readonly bool AlmostEqual(WDir b, float eps) => AlmostZero(this - b, eps); public readonly WDir Scaled(float multiplier) => new(X * multiplier, Z * multiplier); public readonly WDir Rounded() => new(MathF.Round(X), MathF.Round(Z)); - public readonly WDir Rounded(float precision) => Scaled(1.0f / precision).Rounded().Scaled(precision); + public readonly WDir Rounded(float precision) => Scaled(1f / precision).Rounded().Scaled(precision); public readonly WDir Floor() => new(MathF.Floor(X), MathF.Floor(Z)); public override readonly string ToString() => $"({X:f3}, {Z:f3})"; @@ -60,8 +65,17 @@ public WPos(Vector2 v) : this(v.X, v.Y) { } public static WPos operator *(WPos a, float b) => new(a.X * b, a.Z * b); public static WPos operator +(WPos a, float b) => new(a.X + b, a.Z + b); - public static WPos operator /(WPos a, int b) => new(a.X / b, a.Z / b); - public static WPos operator /(WPos a, float b) => new(a.X / b, a.Z / b); + public static WPos operator /(WPos a, int b) + { + var invB = 1f / b; + return new(a.X * invB, a.Z * invB); + } + + public static WPos operator /(WPos a, float b) + { + var invB = 1 / b; + return new(a.X * invB, a.Z * invB); + } public static WPos operator +(WPos a, WDir b) => new(a.X + b.X, a.Z + b.Z); public static WPos operator +(WDir a, WPos b) => new(a.X + b.X, a.Z + b.Z); public static WPos operator -(WPos a, WDir b) => new(a.X - b.X, a.Z - b.Z); @@ -70,14 +84,14 @@ public WPos(Vector2 v) : this(v.X, v.Y) { } public readonly bool AlmostEqual(WPos b, float eps) => (this - b).AlmostZero(eps); public readonly WPos Scaled(float multiplier) => new(X * multiplier, Z * multiplier); public readonly WPos Rounded() => new(MathF.Round(X), MathF.Round(Z)); - public readonly WPos Rounded(float precision) => Scaled(1.0f / precision).Rounded().Scaled(precision); + public readonly WPos Rounded(float precision) => Scaled(1f / precision).Rounded().Scaled(precision); public static WPos Lerp(WPos from, WPos to, float progress) => new(from.ToVec2() * (1 - progress) + to.ToVec2() * progress); - public static WPos RotateAroundOrigin(float rotateByDegrees, WPos origin, WPos caster) + public static WPos RotateAroundOrigin(float rotateByDegrees, WPos origin, WPos point) { var (sin, cos) = ((float, float))Math.SinCos(rotateByDegrees * Angle.DegToRad); - var deltaX = caster.X - origin.X; - var deltaZ = caster.Z - origin.Z; + var deltaX = point.X - origin.X; + var deltaZ = point.Z - origin.Z; var rotatedX = cos * deltaX - sin * deltaZ; var rotatedZ = sin * deltaX + cos * deltaZ; return new(origin.X + rotatedX, origin.Z + rotatedZ);