From b6c6ec1d9c8536c6f9a9dddabdfd1947c0f9ebdd Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Wed, 13 Mar 2024 12:49:31 +0100 Subject: [PATCH 01/13] WIP --- .../D11LapisManalis/D130CaladriusMaturus.cs | 40 ++++++++++ .../Dungeons/D11LapisManalis/D131Albion.cs | 79 +++++++++++++++++++ .../D11LapisManalis/D132GalateaMagna.cs | 79 +++++++++++++++++++ .../D11LapisManalis/DD130AlbusGriffin.cs | 51 ++++++++++++ 4 files changed, 249 insertions(+) create mode 100644 BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs create mode 100644 BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs create mode 100644 BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs create mode 100644 BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs new file mode 100644 index 0000000000..158b6a9285 --- /dev/null +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs @@ -0,0 +1,40 @@ +// CONTRIB: made by malediktus, not checked +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D130CaladriusMaturus +{ + public enum OID : uint + { + Boss = 0x3D56, //R=3.96 + Caladrius = 0x3CE2, //R=1.8 + } + + public enum AID : uint + { + AutoAttack = 872, // Caladrius/Boss->player, no cast, single-target + TransonicBlast = 32535, // Caladrius->self, 4,0s cast, range 9 90-degree cone + }; + + class TransonicBlast : Components.SelfTargetedAOEs + { + public TransonicBlast() : base(ActionID.MakeSpell(AID.TransonicBlast), new AOEShapeCone(9, 45.Degrees())) { } + } + + class D130CaladriusMaturusStates : StateMachineBuilder + { + public D130CaladriusMaturusStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Caladrius).All(e => e.IsDead); + } + } + + [ModuleInfo(CFCID = 896, NameID = 12078)] + public class D130CaladriusMaturus : BossModule + { + public D130CaladriusMaturus(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsRect(new(47, -570.5f), 8.5f, 11.5f)) { } + } +} diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs new file mode 100644 index 0000000000..ef9bcc20f6 --- /dev/null +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -0,0 +1,79 @@ +// CONTRIB: made by malediktus, not checked +namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D131Albion +{ + public enum OID : uint + { + Boss = 0x3CFE, //R=4.6 + WildBeasts = 0x3D03, //R=0.5 + Helper = 0x233C, + _Gen_Actor3cff = 0x3CFF, // R1,320 + _Gen_Actor3d00 = 0x3D00, // R1,700 + _Gen_Actor3d02 = 0x3D02, // R4,000 + _Gen_Actor3d01 = 0x3D01, // R2,850 + _Gen_Actor3d04 = 0x3D04, // R2,000 + } + +public enum AID : uint +{ + AutoAttack = 872, // Boss->player, no cast, single-target + _Ability_ = 32812, // Boss->location, no cast, single-target + CallOfTheMountain = 31356, // Boss->self, 3,0s cast, single-target + WildlifeCrossing = 31357, // WildBeasts->self, no cast, range 7 width 10 rect + AlbionsEmbrace = 31365, // Boss->player, 5,0s cast, single-target + RightSlam = 32813, // Boss->self, 5,0s cast, range 80 width 20 rect + LeftSlam = 32814, // Boss->self, 5,0s cast, range 80 width 20 rect + KnockOnIce = 31358, // Boss->self, 4,0s cast, single-target + KnockOnIce2 = 31359, // Helper->self, 6,0s cast, range 5 circle + Icebreaker = 31361, // Boss->3D04, 5,0s cast, range 17 circle + IcyThroes = 31362, // Boss->self, no cast, single-target + IcyThroes2 = 32783, // Helper->self, 5,0s cast, range 6 circle + IcyThroes3 = 31363, // Helper->player, 5,0s cast, range 6 circle + IcyThroes4 = 32697, // Helper->self, 5,0s cast, range 6 circle + RoarOfAlbion = 31364, // Boss->self, 7,0s cast, range 60 circle +}; + +public enum IconID : uint +{ + _Gen_Icon_218 = 218, // player + _Gen_Icon_210 = 210, // _Gen_Actor3d04 + _Gen_Icon_139 = 139, // player +}; +public enum TetherID : uint +{ + _Gen_Tether_12 = 12, // Boss->_Gen_Actor3d04 +}; + + + + // class WindsOfWinter : Components.RaidwideCast + // { + // public WindsOfWinter() : base(ActionID.MakeSpell(AID.WindsOfWinter), "Stun Albus Griffin, Raidwide") { } + // } + + // class GoldenTalons : Components.SelfTargetedAOEs + // { + // public GoldenTalons() : base(ActionID.MakeSpell(AID.GoldenTalons), new AOEShapeCone(8, 45.Degrees())) { } + // } + + // class Freefall : Components.LocationTargetedAOEs + // { + // public Freefall() : base(ActionID.MakeSpell(AID.Freefall), 8) { } + // } + + class D130AlbusGriffinStates : StateMachineBuilder + { + public D130AlbusGriffinStates(BossModule module) : base(module) + { + TrivialPhase(); + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + } + } + + [ModuleInfo(CFCID = 896, NameID = 12245)] + public class D130AlbusGriffin : BossModule + { + public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(24, -744), 19.5f)) { } + } +} diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs new file mode 100644 index 0000000000..287267d09c --- /dev/null +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -0,0 +1,79 @@ +// CONTRIB: made by malediktus, not checked +namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D132GalateaMagna +{ + public enum OID : uint + { + Boss = 0x3971, //R=5.0 + WildBeasts = 0x3D03, //R=0.5 + Helper = 0x233C, + _Gen_Actor3cff = 0x3CFF, // R1,320 + _Gen_Actor3d00 = 0x3D00, // R1,700 + _Gen_Actor3d02 = 0x3D02, // R4,000 + _Gen_Actor3d01 = 0x3D01, // R2,850 + _Gen_Actor3d04 = 0x3D04, // R2,000 + } + +public enum AID : uint +{ + AutoAttack = 872, // Boss->player, no cast, single-target + _Ability_ = 32812, // Boss->location, no cast, single-target + CallOfTheMountain = 31356, // Boss->self, 3,0s cast, single-target + WildlifeCrossing = 31357, // WildBeasts->self, no cast, range 7 width 10 rect + AlbionsEmbrace = 31365, // Boss->player, 5,0s cast, single-target + RightSlam = 32813, // Boss->self, 5,0s cast, range 80 width 20 rect + LeftSlam = 32814, // Boss->self, 5,0s cast, range 80 width 20 rect + KnockOnIce = 31358, // Boss->self, 4,0s cast, single-target + KnockOnIce2 = 31359, // Helper->self, 6,0s cast, range 5 circle + Icebreaker = 31361, // Boss->3D04, 5,0s cast, range 17 circle + IcyThroes = 31362, // Boss->self, no cast, single-target + IcyThroes2 = 32783, // Helper->self, 5,0s cast, range 6 circle + IcyThroes3 = 31363, // Helper->player, 5,0s cast, range 6 circle + IcyThroes4 = 32697, // Helper->self, 5,0s cast, range 6 circle + RoarOfAlbion = 31364, // Boss->self, 7,0s cast, range 60 circle +}; + +public enum IconID : uint +{ + _Gen_Icon_218 = 218, // player + _Gen_Icon_210 = 210, // _Gen_Actor3d04 + _Gen_Icon_139 = 139, // player +}; +public enum TetherID : uint +{ + _Gen_Tether_12 = 12, // Boss->_Gen_Actor3d04 +}; + + + + // class WindsOfWinter : Components.RaidwideCast + // { + // public WindsOfWinter() : base(ActionID.MakeSpell(AID.WindsOfWinter), "Stun Albus Griffin, Raidwide") { } + // } + + // class GoldenTalons : Components.SelfTargetedAOEs + // { + // public GoldenTalons() : base(ActionID.MakeSpell(AID.GoldenTalons), new AOEShapeCone(8, 45.Degrees())) { } + // } + + // class Freefall : Components.LocationTargetedAOEs + // { + // public Freefall() : base(ActionID.MakeSpell(AID.Freefall), 8) { } + // } + + class D130AlbusGriffinStates : StateMachineBuilder + { + public D130AlbusGriffinStates(BossModule module) : base(module) + { + TrivialPhase(); + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + } + } + + [ModuleInfo(CFCID = 896, NameID = 12245)] + public class D130AlbusGriffin : BossModule + { + public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(350, -394), 19.5f)) { } + } +} diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs new file mode 100644 index 0000000000..2ddec3d7fe --- /dev/null +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs @@ -0,0 +1,51 @@ +// CONTRIB: made by malediktus, not checked +using System.Linq; + +namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D130AlbusGriffin +{ + public enum OID : uint + { + Boss = 0x3E9F, //R=4.6 + } + + public enum AID : uint + { + AutoAttack = 870, // Boss->player, no cast, single-target + WindsOfWinter = 32785, // Boss->self, 5,0s cast, range 40 circle + Freefall = 32786, // Boss->location, 3,5s cast, range 8 circle + GoldenTalons = 32787, // Boss->self, 4,5s cast, range 8 90-degree cone + }; + + class WindsOfWinter : Components.RaidwideCast + { + public WindsOfWinter() : base(ActionID.MakeSpell(AID.WindsOfWinter), "Stun Albus Griffin, Raidwide") { } + } + + class GoldenTalons : Components.SelfTargetedAOEs + { + public GoldenTalons() : base(ActionID.MakeSpell(AID.GoldenTalons), new AOEShapeCone(8, 45.Degrees())) { } + } + + class Freefall : Components.LocationTargetedAOEs + { + public Freefall() : base(ActionID.MakeSpell(AID.Freefall), 8) { } + } + + class D130AlbusGriffinStates : StateMachineBuilder + { + public D130AlbusGriffinStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); + } + } + + [ModuleInfo(CFCID = 896, NameID = 12245)] + public class D130AlbusGriffin : BossModule + { + public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsRect(new(47, -570.5f), 8.5f, 11.5f)) { } + } +} From 487bf180e90a3884cdeb8101b682b9d8e2cb9241 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Fri, 15 Mar 2024 04:40:40 +0100 Subject: [PATCH 02/13] Albion done? --- .../D11LapisManalis/D130CaladriusMaturus.cs | 10 +- .../Dungeons/D11LapisManalis/D131Albion.cs | 210 +++++++++++++----- 2 files changed, 168 insertions(+), 52 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs index 158b6a9285..758ca47650 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs @@ -1,6 +1,4 @@ // CONTRIB: made by malediktus, not checked -using System; -using System.Collections.Generic; using System.Linq; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D130CaladriusMaturus @@ -36,5 +34,13 @@ public D130CaladriusMaturusStates(BossModule module) : base(module) public class D130CaladriusMaturus : BossModule { public D130CaladriusMaturus(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsRect(new(47, -570.5f), 8.5f, 11.5f)) { } + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actor(PrimaryActor, ArenaColor.Enemy); + foreach (var s in Enemies(OID.Caladrius)) + Arena.Actor(s, ArenaColor.Enemy); + } + } } diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs index ef9bcc20f6..76eea80c49 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -1,4 +1,7 @@ // CONTRIB: made by malediktus, not checked +using System; +using System.Collections.Generic; + namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D131Albion { public enum OID : uint @@ -6,68 +9,175 @@ public enum OID : uint Boss = 0x3CFE, //R=4.6 WildBeasts = 0x3D03, //R=0.5 Helper = 0x233C, - _Gen_Actor3cff = 0x3CFF, // R1,320 - _Gen_Actor3d00 = 0x3D00, // R1,700 - _Gen_Actor3d02 = 0x3D02, // R4,000 - _Gen_Actor3d01 = 0x3D01, // R2,850 - _Gen_Actor3d04 = 0x3D04, // R2,000 + WildBeasts1 = 0x3CFF, // R1,320 + WildBeasts2 = 0x3D00, // R1,700 + WildBeasts3 = 0x3D02, // R4,000 + WildBeasts4 = 0x3D01, // R2,850 + IcyCrystal = 0x3D04, // R2,000 } -public enum AID : uint -{ - AutoAttack = 872, // Boss->player, no cast, single-target - _Ability_ = 32812, // Boss->location, no cast, single-target - CallOfTheMountain = 31356, // Boss->self, 3,0s cast, single-target - WildlifeCrossing = 31357, // WildBeasts->self, no cast, range 7 width 10 rect - AlbionsEmbrace = 31365, // Boss->player, 5,0s cast, single-target - RightSlam = 32813, // Boss->self, 5,0s cast, range 80 width 20 rect - LeftSlam = 32814, // Boss->self, 5,0s cast, range 80 width 20 rect - KnockOnIce = 31358, // Boss->self, 4,0s cast, single-target - KnockOnIce2 = 31359, // Helper->self, 6,0s cast, range 5 circle - Icebreaker = 31361, // Boss->3D04, 5,0s cast, range 17 circle - IcyThroes = 31362, // Boss->self, no cast, single-target - IcyThroes2 = 32783, // Helper->self, 5,0s cast, range 6 circle - IcyThroes3 = 31363, // Helper->player, 5,0s cast, range 6 circle - IcyThroes4 = 32697, // Helper->self, 5,0s cast, range 6 circle - RoarOfAlbion = 31364, // Boss->self, 7,0s cast, range 60 circle -}; - -public enum IconID : uint -{ - _Gen_Icon_218 = 218, // player - _Gen_Icon_210 = 210, // _Gen_Actor3d04 - _Gen_Icon_139 = 139, // player -}; -public enum TetherID : uint -{ - _Gen_Tether_12 = 12, // Boss->_Gen_Actor3d04 -}; + public enum AID : uint + { + AutoAttack = 872, // Boss->player, no cast, single-target + Teleport = 32812, // Boss->location, no cast, single-target, boss teleports mid + CallOfTheMountain = 31356, // Boss->self, 3,0s cast, single-target, boss calls wild beasts + WildlifeCrossing = 31357, // WildBeasts->self, no cast, range 7 width 10 rect + AlbionsEmbrace = 31365, // Boss->player, 5,0s cast, single-target + RightSlam = 32813, // Boss->self, 5,0s cast, range 80 width 20 rect + LeftSlam = 32814, // Boss->self, 5,0s cast, range 80 width 20 rect + KnockOnIce = 31358, // Boss->self, 4,0s cast, single-target + KnockOnIce2 = 31359, // Helper->self, 6,0s cast, range 5 circle + Icebreaker = 31361, // Boss->3D04, 5,0s cast, range 17 circle + IcyThroes = 31362, // Boss->self, no cast, single-target + IcyThroes2 = 32783, // Helper->self, 5,0s cast, range 6 circle + IcyThroes3 = 31363, // Helper->player, 5,0s cast, range 6 circle + IcyThroes4 = 32697, // Helper->self, 5,0s cast, range 6 circle + RoarOfAlbion = 31364, // Boss->self, 7,0s cast, range 60 circle + }; + + public enum IconID : uint + { + Tankbuster = 218, // player + Target = 210, // IceCrystal + Spreadmarker = 139, // player + }; + + class WildlifeCrossing : Components.GenericAOEs + //Note: this is not an accurate representation of the WildLifeCrossing mechanic (it got a weird origin and the size is also too small), only an estimation, the width is slightly bigger than the actual stampede. i might revise this in future if i can find a better solution + { + private static readonly AOEShapeRect rect1 = new(40, 1.32f); + private static readonly AOEShapeRect rect2 = new(40, 1.7f); + private static readonly AOEShapeRect rect3 = new(40, 4); + private static readonly AOEShapeRect rect4 = new(40, 2.85f); + + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) + { + foreach (var b in module.Enemies(OID.WildBeasts1)) + if (module.Bounds.Contains(b.Position)) + yield return new(rect1, b.Position, b.Rotation); + foreach (var b in module.Enemies(OID.WildBeasts2)) + if (module.Bounds.Contains(b.Position)) + yield return new(rect2, b.Position, b.Rotation); + foreach (var b in module.Enemies(OID.WildBeasts3)) + if (module.Bounds.Contains(b.Position)) + yield return new(rect3, b.Position, b.Rotation); + foreach (var b in module.Enemies(OID.WildBeasts4)) + if (module.Bounds.Contains(b.Position)) + yield return new(rect4, b.Position, b.Rotation); + } + } + + class IcyThroes : Components.GenericBaitAway + { + private readonly List _targets = new(); + + public override void OnEventIcon(BossModule module, Actor actor, uint iconID) + { + if (iconID == (uint)IconID.Spreadmarker) + { + CurrentBaits.Add(new(module.PrimaryActor, actor, new AOEShapeCircle(6))); + _targets.Add(actor); + CenterAtTarget = true; + } + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID == AID.IcyThroes3) + { + CurrentBaits.Clear(); + _targets.Clear(); + } + } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + if (_targets.Contains(actor)) + hints.Add("Bait away!"); + } + } + + class Icebreaker : Components.GenericAOEs + { + private List _casters = new(); + private static readonly AOEShapeCircle circle = new(17); + private DateTime _activation; + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) + { + if (_casters.Count > 0) + foreach (var c in _casters) + yield return new(circle, c.Position, activation: _activation); + } + + public override void OnEventIcon(BossModule module, Actor actor, uint iconID) + { + if (iconID == (uint)IconID.Target) + { + _casters.Add(actor); + _activation = module.WorldState.CurrentTime.AddSeconds(6); + } + } + + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.Icebreaker) + _activation = spell.NPCFinishAt; + } + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.Icebreaker) + _casters.Clear(); + } + } - // class WindsOfWinter : Components.RaidwideCast - // { - // public WindsOfWinter() : base(ActionID.MakeSpell(AID.WindsOfWinter), "Stun Albus Griffin, Raidwide") { } - // } + class IcyThroes2 : Components.SelfTargetedAOEs + { + public IcyThroes2() : base(ActionID.MakeSpell(AID.IcyThroes4), new AOEShapeCircle(6)) { } + } - // class GoldenTalons : Components.SelfTargetedAOEs - // { - // public GoldenTalons() : base(ActionID.MakeSpell(AID.GoldenTalons), new AOEShapeCone(8, 45.Degrees())) { } - // } - // class Freefall : Components.LocationTargetedAOEs - // { - // public Freefall() : base(ActionID.MakeSpell(AID.Freefall), 8) { } - // } + class KnockOnIce : Components.SelfTargetedAOEs + { + public KnockOnIce() : base(ActionID.MakeSpell(AID.KnockOnIce2), new AOEShapeCircle(5)) { } + } + + class RightSlam : Components.SelfTargetedAOEs + { + public RightSlam() : base(ActionID.MakeSpell(AID.RightSlam), new AOEShapeRect(20, 80, directionOffset: -90.Degrees())) { } //full width = half width in this case + angle is detected incorrectly, length and width are also switched + } + + class LeftSlam : Components.SelfTargetedAOEs + { + public LeftSlam() : base(ActionID.MakeSpell(AID.LeftSlam), new AOEShapeRect(20, 80, directionOffset: 90.Degrees())) { } //full width = half width in this case + angle is detected incorrectly, length and width are also switched + } + + class AlbionsEmbrace : Components.SingleTargetCast + { + public AlbionsEmbrace() : base(ActionID.MakeSpell(AID.AlbionsEmbrace)) { } + } + + class RoarOfAlbion : Components.CastLineOfSightAOE + { + public RoarOfAlbion() : base(ActionID.MakeSpell(AID.RoarOfAlbion), 60, false) { } + public override IEnumerable BlockerActors(BossModule module) => module.Enemies(OID.IcyCrystal); + } class D130AlbusGriffinStates : StateMachineBuilder { public D130AlbusGriffinStates(BossModule module) : base(module) { - TrivialPhase(); - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } From a0e4e358fe419baed1dfa675a60e2342686e72a1 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Fri, 15 Mar 2024 05:58:36 +0100 Subject: [PATCH 03/13] Albion done --- .../Dungeons/D11LapisManalis/D131Albion.cs | 116 +++++++++++++++--- 1 file changed, 99 insertions(+), 17 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs index 76eea80c49..0d52806538 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -1,6 +1,7 @@ // CONTRIB: made by malediktus, not checked using System; using System.Collections.Generic; +using System.Drawing; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D131Albion { @@ -43,27 +44,108 @@ public enum IconID : uint }; class WildlifeCrossing : Components.GenericAOEs - //Note: this is not an accurate representation of the WildLifeCrossing mechanic (it got a weird origin and the size is also too small), only an estimation, the width is slightly bigger than the actual stampede. i might revise this in future if i can find a better solution { - private static readonly AOEShapeRect rect1 = new(40, 1.32f); - private static readonly AOEShapeRect rect2 = new(40, 1.7f); - private static readonly AOEShapeRect rect3 = new(40, 4); - private static readonly AOEShapeRect rect4 = new(40, 2.85f); + + private static readonly AOEShapeRect rect = new(20, 5, 20); + private WPos stampede1 = default; + private WPos stampede2 = default; + private int stampede1counter; + private int stampede2counter; + private bool active1; + private bool active2; + private DateTime _reset1; + private DateTime _reset2; public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { - foreach (var b in module.Enemies(OID.WildBeasts1)) - if (module.Bounds.Contains(b.Position)) - yield return new(rect1, b.Position, b.Rotation); - foreach (var b in module.Enemies(OID.WildBeasts2)) - if (module.Bounds.Contains(b.Position)) - yield return new(rect2, b.Position, b.Rotation); - foreach (var b in module.Enemies(OID.WildBeasts3)) - if (module.Bounds.Contains(b.Position)) - yield return new(rect3, b.Position, b.Rotation); - foreach (var b in module.Enemies(OID.WildBeasts4)) - if (module.Bounds.Contains(b.Position)) - yield return new(rect4, b.Position, b.Rotation); + if (active1) + yield return new(rect, stampede1, 90.Degrees()); + if (active2) + yield return new(rect, stampede2, 90.Degrees()); + } + + public override void OnEventEnvControl(BossModule module, byte index, uint state) + { + if (state == 0x00020001) + { + if (index is 0x21 or 0x25) + if (stampede1 == default) + { + stampede1 = new(24, -759); + active1 = true; + } + else + { + stampede2 = new(24, -759); + active2 = true; + } + if (index is 0x22 or 0x26) + if (stampede1 == default) + { + stampede1 = new(24, -749); + active1 = true; + } + else + { + stampede2 = new(24, -749); + active2 = true; + } + if (index is 0x23 or 0x27) + if (stampede1 == default) + { + stampede1 = new(24, -739); + active1 = true; + } + else + { + stampede2 = new(24, -739); + active2 = true; + } + if (index is 0x24 or 0x28) + if (stampede1 == default) + { + stampede1 = new(24, -729); + active1 = true; + } + else + { + stampede2 = new(24, -729); + active2 = true; + } + } + } + + public override void Update(BossModule module) + { + if (_reset1 != default && module.WorldState.CurrentTime > _reset1) + { + active1 = false; + stampede1counter = 0; + stampede1 = default; + _reset1 = default; + } + if (_reset2 != default && module.WorldState.CurrentTime > _reset2) + { + active2 = false; + stampede2counter = 0; + stampede2 = default; + _reset2 = default; + } + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID == AID.WildlifeCrossing) + { + if (MathF.Abs(caster.Position.Z - stampede1.Z) < 1) + ++stampede1counter; + if (MathF.Abs(caster.Position.Z - stampede2.Z) < 1) + ++stampede2counter; + if (stampede1counter == 30) //sometimes stampedes only have 30 instead of 31 hits for some reason, so i take the lower value and add a 0,5s reset timer via update + _reset1 = module.WorldState.CurrentTime.AddSeconds(0.5f); + if (stampede2counter == 30) + _reset2 = module.WorldState.CurrentTime.AddSeconds(0.5f); + } } } From 0c31162f4ad2313c2dcbdafdc9bf3b3247a1740c Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Fri, 15 Mar 2024 06:00:19 +0100 Subject: [PATCH 04/13] removed pointless line --- .../Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs index 0d52806538..03f1859e5f 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -1,7 +1,6 @@ // CONTRIB: made by malediktus, not checked using System; using System.Collections.Generic; -using System.Drawing; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D131Albion { @@ -45,7 +44,6 @@ public enum IconID : uint class WildlifeCrossing : Components.GenericAOEs { - private static readonly AOEShapeRect rect = new(20, 5, 20); private WPos stampede1 = default; private WPos stampede2 = default; From f6e19b428ac2b7a16027e08716c16ab8e6295791 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Fri, 15 Mar 2024 14:17:27 +0100 Subject: [PATCH 05/13] albion improvements --- .../Dungeons/D11LapisManalis/D131Albion.cs | 185 ++++++++++++++---- .../D11LapisManalis/D132GalateaMagna.cs | 2 +- 2 files changed, 151 insertions(+), 36 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs index 03f1859e5f..2748bc7847 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -1,6 +1,7 @@ // CONTRIB: made by malediktus, not checked using System; using System.Collections.Generic; +using System.Linq; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D131Albion { @@ -45,88 +46,202 @@ public enum IconID : uint class WildlifeCrossing : Components.GenericAOEs { private static readonly AOEShapeRect rect = new(20, 5, 20); - private WPos stampede1 = default; - private WPos stampede2 = default; private int stampede1counter; private int stampede2counter; private bool active1; private bool active2; + private Angle _rotation1; + private Angle _rotation2; private DateTime _reset1; - private DateTime _reset2; + private DateTime _reset2; + private int _row1; + private int _row2; + private List beasts1 = new(); + private List beasts2 = new(); + private WPos stampede1 = default; + private WPos stampede2 = default; public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { - if (active1) + if (active1 && beasts1.Count > 0) + yield return new(new AOEShapeRect((beasts1.First().Position - beasts1.Last().Position).Length() + 25, 5), new (beasts1.Last().Position.X, _row1), _rotation1); + if (active2 && beasts2.Count > 0) + yield return new(new AOEShapeRect((beasts2.First().Position - beasts2.Last().Position).Length() + 25, 5), new (beasts2.Last().Position.X, _row2), _rotation2); + if (active1 && beasts1.Count == 0) yield return new(rect, stampede1, 90.Degrees()); - if (active2) - yield return new(rect, stampede2, 90.Degrees()); + if (active2 && beasts2.Count == 0) + yield return new(rect, stampede2, 90.Degrees()); } public override void OnEventEnvControl(BossModule module, byte index, uint state) { if (state == 0x00020001) { - if (index is 0x21 or 0x25) - if (stampede1 == default) + if (index == 0x21) + if (_row1 == default) + { + active1 = true; + _rotation1 = 90.Degrees(); + _row1 = -759; + stampede1 = new(4, -759); + } + else + { + active2 = true; + _rotation2 = 90.Degrees(); + _row2 = -759; + stampede2 = new(4, -759); + } + if (index == 0x25) + if (_row1 == default) + { + active1 = true; + _rotation1 = -90.Degrees(); + _row1 = -759; + stampede1 = new(44, -759); + } + else + { + active2 = true; + _rotation2 = -90.Degrees(); + _row2 = -759; + stampede2 = new(44, -759); + } + if (index == 0x22) + if (_row1 == default) + { + active1 = true; + _rotation1 = 90.Degrees(); + _row1 = -749; + stampede1 = new(4, -749); + } + else + { + active2 = true; + _rotation2 = 90.Degrees(); + _row2 = -749; + stampede2 = new(4, -749); + } + if (index == 0x26) + if (_row1 == default) + { + active1 = true; + _rotation1 = -90.Degrees(); + _row1 = -749; + stampede1 = new(44, -749); + } + else + { + active2 = true; + _rotation2 = -90.Degrees(); + _row2 = -749; + stampede2 = new(44, -749); + } + if (index == 0x23) + if (_row1 == default) { - stampede1 = new(24, -759); active1 = true; + _rotation1 = 90.Degrees(); + _row1 = -739; + stampede1 = new(4, -739); } else { - stampede2 = new(24, -759); active2 = true; - } - if (index is 0x22 or 0x26) - if (stampede1 == default) + _rotation2 = 90.Degrees(); + _row2 = -739; + stampede2 = new(4, -739); + } + if (index == 0x27) + if (_row1 == default) { - stampede1 = new(24, -749); active1 = true; + _rotation1 = -90.Degrees(); + _row1 = -739; + stampede1 = new(44, -739); } else { - stampede2 = new(24, -749); active2 = true; - } - if (index is 0x23 or 0x27) - if (stampede1 == default) + _rotation2 = -90.Degrees(); + _row2 = -739; + stampede2 = new(44, -739); + } + if (index == 0x24) + if (_row1 == default) { - stampede1 = new(24, -739); active1 = true; + _rotation1 = 90.Degrees(); + _row1 = -729; + stampede1 = new(4, -729); } else { - stampede2 = new(24, -739); active2 = true; - } - if (index is 0x24 or 0x28) - if (stampede1 == default) + _rotation2 = 90.Degrees(); + _row2 = -729; + stampede2 = new(4, -729); + } + if (index == 0x28) + if (_row1 == default) { - stampede1 = new(24, -729); active1 = true; + _rotation1 = -90.Degrees(); + _row1 = -729; + stampede2 = new(44, -729); } else { - stampede2 = new(24, -729); active2 = true; - } + _rotation2 = -90.Degrees(); + _row2 = -729; + stampede2 = new(44, -729); + } } } public override void Update(BossModule module) { + foreach (var b in module.Enemies(OID.WildBeasts4)) + if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + beasts1.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts3)) + if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + beasts1.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts2)) + if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + beasts1.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts1)) + if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + beasts1.Add(b); + + foreach (var b in module.Enemies(OID.WildBeasts4)) + if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + beasts2.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts3)) + if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + beasts2.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts2)) + if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + beasts2.Add(b); + foreach (var b in module.Enemies(OID.WildBeasts1)) + if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + beasts2.Add(b); + if (_reset1 != default && module.WorldState.CurrentTime > _reset1) { active1 = false; stampede1counter = 0; - stampede1 = default; + _row1 = default; + beasts1.Clear(); _reset1 = default; } if (_reset2 != default && module.WorldState.CurrentTime > _reset2) { active2 = false; stampede2counter = 0; - stampede2 = default; + _row2 = default; + beasts2.Clear(); _reset2 = default; } } @@ -135,9 +250,9 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent { if ((AID)spell.Action.ID == AID.WildlifeCrossing) { - if (MathF.Abs(caster.Position.Z - stampede1.Z) < 1) + if (MathF.Abs(caster.Position.Z - _row1) < 1) ++stampede1counter; - if (MathF.Abs(caster.Position.Z - stampede2.Z) < 1) + if (MathF.Abs(caster.Position.Z - _row2) < 1) ++stampede2counter; if (stampede1counter == 30) //sometimes stampedes only have 30 instead of 31 hits for some reason, so i take the lower value and add a 0,5s reset timer via update _reset1 = module.WorldState.CurrentTime.AddSeconds(0.5f); @@ -244,9 +359,9 @@ public RoarOfAlbion() : base(ActionID.MakeSpell(AID.RoarOfAlbion), 60, false) { public override IEnumerable BlockerActors(BossModule module) => module.Enemies(OID.IcyCrystal); } - class D130AlbusGriffinStates : StateMachineBuilder + class D131AlbionStates : StateMachineBuilder { - public D130AlbusGriffinStates(BossModule module) : base(module) + public D131AlbionStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() @@ -261,9 +376,9 @@ public D130AlbusGriffinStates(BossModule module) : base(module) } } - [ModuleInfo(CFCID = 896, NameID = 12245)] - public class D130AlbusGriffin : BossModule + [ModuleInfo(CFCID = 896, NameID = 11992)] + public class D131Albion : BossModule { - public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(24, -744), 19.5f)) { } + public D131Albion(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(24, -744), 19.5f)) { } } } diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs index 287267d09c..24f6becfe5 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -71,7 +71,7 @@ public D130AlbusGriffinStates(BossModule module) : base(module) } } - [ModuleInfo(CFCID = 896, NameID = 12245)] + [ModuleInfo(CFCID = 896, NameID = 10308)] public class D130AlbusGriffin : BossModule { public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(350, -394), 19.5f)) { } From 3b5ea0fbecc081e40d862c72bffb7457ec955153 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sat, 16 Mar 2024 02:54:26 +0100 Subject: [PATCH 06/13] code cleanup --- .../Dungeons/D11LapisManalis/D131Albion.cs | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs index 2748bc7847..ed3ba2051e 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs @@ -54,8 +54,6 @@ class WildlifeCrossing : Components.GenericAOEs private Angle _rotation2; private DateTime _reset1; private DateTime _reset2; - private int _row1; - private int _row2; private List beasts1 = new(); private List beasts2 = new(); private WPos stampede1 = default; @@ -64,9 +62,9 @@ class WildlifeCrossing : Components.GenericAOEs public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { if (active1 && beasts1.Count > 0) - yield return new(new AOEShapeRect((beasts1.First().Position - beasts1.Last().Position).Length() + 25, 5), new (beasts1.Last().Position.X, _row1), _rotation1); + yield return new(new AOEShapeRect((beasts1.First().Position - beasts1.Last().Position).Length() + 30, 5), new (beasts1.Last().Position.X, stampede1.Z), _rotation1); if (active2 && beasts2.Count > 0) - yield return new(new AOEShapeRect((beasts2.First().Position - beasts2.Last().Position).Length() + 25, 5), new (beasts2.Last().Position.X, _row2), _rotation2); + yield return new(new AOEShapeRect((beasts2.First().Position - beasts2.Last().Position).Length() + 30, 5), new (beasts2.Last().Position.X, stampede2.Z), _rotation2); if (active1 && beasts1.Count == 0) yield return new(rect, stampede1, 90.Degrees()); if (active2 && beasts2.Count == 0) @@ -75,126 +73,111 @@ public override IEnumerable ActiveAOEs(BossModule module, int slot, public override void OnEventEnvControl(BossModule module, byte index, uint state) { + var newstampede = stampede1 == default; if (state == 0x00020001) { if (index == 0x21) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = 90.Degrees(); - _row1 = -759; stampede1 = new(4, -759); } else { active2 = true; _rotation2 = 90.Degrees(); - _row2 = -759; stampede2 = new(4, -759); } if (index == 0x25) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = -90.Degrees(); - _row1 = -759; stampede1 = new(44, -759); } else { active2 = true; _rotation2 = -90.Degrees(); - _row2 = -759; stampede2 = new(44, -759); } if (index == 0x22) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = 90.Degrees(); - _row1 = -749; stampede1 = new(4, -749); } else { active2 = true; _rotation2 = 90.Degrees(); - _row2 = -749; stampede2 = new(4, -749); } if (index == 0x26) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = -90.Degrees(); - _row1 = -749; stampede1 = new(44, -749); } else { active2 = true; _rotation2 = -90.Degrees(); - _row2 = -749; stampede2 = new(44, -749); } if (index == 0x23) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = 90.Degrees(); - _row1 = -739; stampede1 = new(4, -739); } else { active2 = true; _rotation2 = 90.Degrees(); - _row2 = -739; stampede2 = new(4, -739); } if (index == 0x27) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = -90.Degrees(); - _row1 = -739; stampede1 = new(44, -739); } else { active2 = true; _rotation2 = -90.Degrees(); - _row2 = -739; stampede2 = new(44, -739); } if (index == 0x24) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = 90.Degrees(); - _row1 = -729; stampede1 = new(4, -729); } else { active2 = true; _rotation2 = 90.Degrees(); - _row2 = -729; stampede2 = new(4, -729); } if (index == 0x28) - if (_row1 == default) + if (newstampede) { active1 = true; _rotation1 = -90.Degrees(); - _row1 = -729; - stampede2 = new(44, -729); + stampede1 = new(44, -729); } else { active2 = true; _rotation2 = -90.Degrees(); - _row2 = -729; stampede2 = new(44, -729); } } @@ -203,36 +186,36 @@ public override void OnEventEnvControl(BossModule module, byte index, uint state public override void Update(BossModule module) { foreach (var b in module.Enemies(OID.WildBeasts4)) - if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + if (b.Position.InRect(new(24, stampede1.Z), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) beasts1.Add(b); foreach (var b in module.Enemies(OID.WildBeasts3)) - if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + if (b.Position.InRect(new(24, stampede1.Z), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) beasts1.Add(b); foreach (var b in module.Enemies(OID.WildBeasts2)) - if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + if (b.Position.InRect(new(24, stampede1.Z), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) beasts1.Add(b); foreach (var b in module.Enemies(OID.WildBeasts1)) - if (b.Position.InRect(new(24, _row1), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) + if (b.Position.InRect(new(24, stampede1.Z), _rotation1, 33, 33, 5) && !beasts1.Contains(b)) beasts1.Add(b); foreach (var b in module.Enemies(OID.WildBeasts4)) - if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + if (b.Position.InRect(new(24, stampede2.Z), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) beasts2.Add(b); foreach (var b in module.Enemies(OID.WildBeasts3)) - if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + if (b.Position.InRect(new(24, stampede2.Z), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) beasts2.Add(b); foreach (var b in module.Enemies(OID.WildBeasts2)) - if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + if (b.Position.InRect(new(24, stampede2.Z), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) beasts2.Add(b); foreach (var b in module.Enemies(OID.WildBeasts1)) - if (b.Position.InRect(new(24, _row2), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) + if (b.Position.InRect(new(24, stampede2.Z), _rotation2, 33, 33, 5) && !beasts2.Contains(b)) beasts2.Add(b); if (_reset1 != default && module.WorldState.CurrentTime > _reset1) { active1 = false; stampede1counter = 0; - _row1 = default; + stampede1 = default; beasts1.Clear(); _reset1 = default; } @@ -240,7 +223,7 @@ public override void Update(BossModule module) { active2 = false; stampede2counter = 0; - _row2 = default; + stampede2 = default; beasts2.Clear(); _reset2 = default; } @@ -250,9 +233,9 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent { if ((AID)spell.Action.ID == AID.WildlifeCrossing) { - if (MathF.Abs(caster.Position.Z - _row1) < 1) + if (MathF.Abs(caster.Position.Z - stampede1.Z) < 1) ++stampede1counter; - if (MathF.Abs(caster.Position.Z - _row2) < 1) + if (MathF.Abs(caster.Position.Z - stampede2.Z) < 1) ++stampede2counter; if (stampede1counter == 30) //sometimes stampedes only have 30 instead of 31 hits for some reason, so i take the lower value and add a 0,5s reset timer via update _reset1 = module.WorldState.CurrentTime.AddSeconds(0.5f); @@ -381,4 +364,4 @@ public class D131Albion : BossModule { public D131Albion(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(24, -744), 19.5f)) { } } -} +} \ No newline at end of file From 1388e822239040f61a9dfe27a4cfced00e253ea6 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 17 Mar 2024 05:50:20 +0100 Subject: [PATCH 07/13] galatea magna module --- .../D11LapisManalis/D132GalateaMagna.cs | 264 ++++++++++++++---- 1 file changed, 209 insertions(+), 55 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs index 24f6becfe5..84568e47e7 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -1,79 +1,233 @@ // CONTRIB: made by malediktus, not checked +using System; +using System.Collections.Generic; +using System.Linq; +using BossMod.Endwalker.Alliance.A10Lions; + namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D132GalateaMagna { public enum OID : uint { Boss = 0x3971, //R=5.0 - WildBeasts = 0x3D03, //R=0.5 Helper = 0x233C, - _Gen_Actor3cff = 0x3CFF, // R1,320 - _Gen_Actor3d00 = 0x3D00, // R1,700 - _Gen_Actor3d02 = 0x3D02, // R4,000 - _Gen_Actor3d01 = 0x3D01, // R2,850 - _Gen_Actor3d04 = 0x3D04, // R2,000 } -public enum AID : uint -{ - AutoAttack = 872, // Boss->player, no cast, single-target - _Ability_ = 32812, // Boss->location, no cast, single-target - CallOfTheMountain = 31356, // Boss->self, 3,0s cast, single-target - WildlifeCrossing = 31357, // WildBeasts->self, no cast, range 7 width 10 rect - AlbionsEmbrace = 31365, // Boss->player, 5,0s cast, single-target - RightSlam = 32813, // Boss->self, 5,0s cast, range 80 width 20 rect - LeftSlam = 32814, // Boss->self, 5,0s cast, range 80 width 20 rect - KnockOnIce = 31358, // Boss->self, 4,0s cast, single-target - KnockOnIce2 = 31359, // Helper->self, 6,0s cast, range 5 circle - Icebreaker = 31361, // Boss->3D04, 5,0s cast, range 17 circle - IcyThroes = 31362, // Boss->self, no cast, single-target - IcyThroes2 = 32783, // Helper->self, 5,0s cast, range 6 circle - IcyThroes3 = 31363, // Helper->player, 5,0s cast, range 6 circle - IcyThroes4 = 32697, // Helper->self, 5,0s cast, range 6 circle - RoarOfAlbion = 31364, // Boss->self, 7,0s cast, range 60 circle -}; - -public enum IconID : uint -{ - _Gen_Icon_218 = 218, // player - _Gen_Icon_210 = 210, // _Gen_Actor3d04 - _Gen_Icon_139 = 139, // player -}; -public enum TetherID : uint -{ - _Gen_Tether_12 = 12, // Boss->_Gen_Actor3d04 -}; + public enum AID : uint + { + AutoAttack = 870, // Boss->player, no cast, single-target + Teleport = 32625, // Boss->location, no cast, single-target, boss teleports to spot marked by icons 1,2,3,4 or to mid + WaningCycle0 = 32623, // Boss->self, no cast, single-target (between in->out) + WaningCycle1 = 32622, // Boss->self, 4,0s cast, range 10-40 donut + WaningCycle2 = 32624, // Helper->self, 6,0s cast, range 10 circle + WaxingCycle0 = 31378, // Boss->self, no cast, single-target (between out->in) + WaxingCycle1 = 31377, // Boss->self, 4,0s cast, range 10 circle + WaxingCycle2 = 31379, // Helper->self, 6,7s cast, range 10-40 donut + SoulScythe = 31386, // Boss->location, 6,0s cast, range 18 circle + SoulNebula = 31390, // Boss->self, 5,0s cast, range 40 circle, raidwide + ScarecrowChase = 31387, // Boss->self, 8,0s cast, single-target + ScarecrowChase2 = 31389, // Boss->self, no cast, single-target + ScarecrowChase3 = 32703, // Helper->self, 1,8s cast, range 40 width 10 cross + Tenebrism = 31382, // Boss->self, 4,0s cast, range 40 circle, small raidwide, spawns 4 towers, applies glass-eyed on tower resolve + Burst = 31383, // Helper->self, no cast, range 5 circle, tower success + BigBurst = 31384, // Helper->self, no cast, range 60 circle, tower fail + StonyGaze = 31385, // Helper->self, no cast, gaze + }; + + public enum IconID : uint + { + Icon1 = 336, // 3D06 + Icon2 = 337, // 3D06 + Icon3 = 338, // 3D06 + Icon4 = 339, // 3D06 + PlayerGaze = 73, // player + }; + + public enum SID : uint + { + SustainedDamage = 2935, // Helper->player, extra=0x0 + ScarecrowChase = 2056, // none->Boss, extra=0x22B + Doom = 3364, // Helper->player, extra=0x0 + GlassyEyed = 3511, // Boss->player, extra=0x0, takes possession of the player after status ends and does a petrifying attack in all direction + }; + + class ScarecrowChase : Components.GenericAOEs + { + private List> _casters = new(); + private List _casterssorted = new(); + private static readonly AOEShapeCross cross = new(40, 5); + private DateTime _activation; + + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) + { + var activation = 3 * (_casters.Count - _casterssorted.Count); + if (_casterssorted.Count == 1) + yield return new(cross, _casterssorted[0].Position, 45.Degrees(), _activation.AddSeconds(activation), ArenaColor.Danger); + if (_casterssorted.Count > 1) + { + yield return new(cross, _casterssorted[0].Position, 45.Degrees(), _activation.AddSeconds(activation), ArenaColor.Danger); + yield return new(cross, _casterssorted[1].Position, 45.Degrees(), _activation.AddSeconds(3 + activation)); + } + } + + public override void OnEventIcon(BossModule module, Actor actor, uint iconID) + { + if (iconID == (uint)IconID.Icon1) + { + _casters.Add(new Tuple (actor, iconID)); + _activation = module.WorldState.CurrentTime.AddSeconds(9.9f); + } + if (iconID == (uint)IconID.Icon2) + _casters.Add(new Tuple (actor, iconID)); + if (iconID == (uint)IconID.Icon3) + _casters.Add(new Tuple (actor, iconID)); + if (iconID == (uint)IconID.Icon4) + _casters.Add(new Tuple (actor, iconID)); + var _order = _casters.OrderBy(x => x.Item2); // icons can appear in random order in raw ops, so need to be sorted + _casterssorted = _order.Select(x => x.Item1).ToList(); + } + + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) + { + if (_casters.Count > 0 && _casterssorted.Count > 0 && (AID)spell.Action.ID == AID.ScarecrowChase3) + { + _casterssorted.RemoveAt(0); + if (_casterssorted.Count == 0) + _casters.Clear(); + } + } + } + + class OutInAOE : Components.ConcentricAOEs + { + private static readonly AOEShape[] _shapes = { new AOEShapeCircle(10), new AOEShapeDonut(10, 40) }; + + public OutInAOE() : base(_shapes) { } + + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.WaxingCycle1) + AddSequence(module.Bounds.Center, spell.NPCFinishAt); + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if (Sequences.Count > 0) + { + var order = (AID)spell.Action.ID switch + { + AID.WaxingCycle1 => 0, + AID.WaxingCycle2 => 1, + _ => -1 + }; + AdvanceSequence(order, caster.Position, module.WorldState.CurrentTime.AddSeconds(2.7f)); + } + } + } + class InOutAOE : Components.ConcentricAOEs + { + private static readonly AOEShape[] _shapes = [new AOEShapeDonut(10, 40), new AOEShapeCircle(10)]; + + public InOutAOE() : base(_shapes) { } + + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.WaningCycle1) + AddSequence(module.Bounds.Center, spell.NPCFinishAt); + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if (Sequences.Count > 0) + { + var order = (AID)spell.Action.ID switch + { + AID.WaningCycle1 => 0, + AID.WaningCycle2 => 1, + _ => -1 + }; + AdvanceSequence(order, caster.Position, module.WorldState.CurrentTime.AddSeconds(2)); + } + } + } + class GlassyEyed : Components.GenericGaze + { + private DateTime _activation; + private List _affected = new(); - // class WindsOfWinter : Components.RaidwideCast - // { - // public WindsOfWinter() : base(ActionID.MakeSpell(AID.WindsOfWinter), "Stun Albus Griffin, Raidwide") { } - // } + public override IEnumerable ActiveEyes(BossModule module, int slot, Actor actor) + { + foreach (var a in _affected) + if (_affected.Count > 0 && module.WorldState.CurrentTime > _activation.AddSeconds(-10)) + yield return new(a.Position, _activation); + } - // class GoldenTalons : Components.SelfTargetedAOEs - // { - // public GoldenTalons() : base(ActionID.MakeSpell(AID.GoldenTalons), new AOEShapeCone(8, 45.Degrees())) { } - // } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) + { + if ((SID)status.ID == SID.GlassyEyed) + { + _activation = status.ExpireAt; + _affected.Add(actor); + } + } - // class Freefall : Components.LocationTargetedAOEs - // { - // public Freefall() : base(ActionID.MakeSpell(AID.Freefall), 8) { } - // } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) + { + if ((SID)status.ID == SID.GlassyEyed) + _affected.Remove(actor); + } + } + + public class TenebrismTowers : Components.GenericTowers + { + public override void OnEventEnvControl(BossModule module, byte index, uint state) + { + if (state == 0x00010008 && index == 0x07) + Towers.Add(new(new(350, -404), 5, 1, 1)); + if (state == 0x00010008 && index == 0x08) + Towers.Add(new(new(360, -394), 5, 1, 1)); + if (state == 0x00010008 && index == 0x09) + Towers.Add(new(new(350, -384), 5, 1, 1)); + if (state == 0x00010008 && index == 0x0A) + Towers.Add(new(new(340, -394), 5, 1, 1)); + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID is AID.Burst or AID.BigBurst) + Towers.RemoveAll(t => t.Position.AlmostEqual(caster.Position, 1)); + } + + public override void AddAIHints(BossModule module, int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + if (Towers.Count > 0) + hints.AddForbiddenZone(ShapeDistance.InvertedCircle(Towers[0].Position, 6)); + } + } + + class SoulScythe : Components.LocationTargetedAOEs + { + public SoulScythe() : base(ActionID.MakeSpell(AID.SoulScythe), 18) { } + } - class D130AlbusGriffinStates : StateMachineBuilder + class D132GalateaMagnaStates : StateMachineBuilder { - public D130AlbusGriffinStates(BossModule module) : base(module) + public D132GalateaMagnaStates(BossModule module) : base(module) { - TrivialPhase(); - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } [ModuleInfo(CFCID = 896, NameID = 10308)] - public class D130AlbusGriffin : BossModule + public class D132GalateaMagna : BossModule { - public D130AlbusGriffin(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(350, -394), 19.5f)) { } + public D132GalateaMagna(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(350, -394), 19.5f)) { } } } From 9cc851faafc58607db58dd3d3ea263646cf87b13 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 17 Mar 2024 10:40:45 +0100 Subject: [PATCH 08/13] WIP --- ...130AlbusGriffin.cs => D130AlbusGriffin.cs} | 0 .../D11LapisManalis/D132GalateaMagna.cs | 1 - .../Dungeons/D11LapisManalis/D133Cagnazzo.cs | 67 +++++++++++++++++++ .../Dungeon/D05MtGulg/D053ForgivenWhimsy.cs | 1 + .../Dungeon/D05MtGulg/D054ForgivenRevelry.cs | 1 + .../D05MtGulg/D055ForgivenObscenity.cs | 1 + 6 files changed, 70 insertions(+), 1 deletion(-) rename BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/{DD130AlbusGriffin.cs => D130AlbusGriffin.cs} (100%) create mode 100644 BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130AlbusGriffin.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/DD130AlbusGriffin.cs rename to BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130AlbusGriffin.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs index 84568e47e7..6aefa0c999 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using BossMod.Endwalker.Alliance.A10Lions; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D132GalateaMagna { diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs new file mode 100644 index 0000000000..9f957991a8 --- /dev/null +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs @@ -0,0 +1,67 @@ +// CONTRIB: made by malediktus, not checked +using System; +using System.Collections.Generic; +using System.Linq; + +namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D133Cagnazzo +{ + public enum OID : uint + { + Boss = 0x3AE2, //R=8.0 + FearsomeFlotsam = 0x3AE3, //R=2.4 + Helper = 0x233C, + } + + public enum AID : uint + { + AutoAttack = 870, // Boss->player, no cast, single-target + StygianDeluge = 31139, // Boss->self, 5,0s cast, range 80 circle + Antediluvian = 31119, // Boss->self, 5,0s cast, single-target + Antediluvian2 = 31120, // Helper->self, 6,5s cast, range 15 circle + BodySlam = 31121, // Boss->location, 6,5s cast, single-target + BodySlam2 = 31122, // Helper->self, 7,5s cast, range 60 circle, knockback 10, away from source + BodySlam3 = 31123, // Helper->self, 7,5s cast, range 8 circle + Teleport = 31131, // Boss->location, no cast, single-target, boss teleports + HydrobombTelegraph = 32695, // Helper->location, 2,0s cast, range 4 circle + HydraulicRamTelegraph = 32693, // Helper->location, 2,0s cast, width 8 rect charge + HydraulicRam = 32692, // Boss->self, 6,0s cast, single-target + HydraulicRam2 = 32694, // Boss->location, no cast, width 8 rect charge + Hydrobomb = 32696, // Helper->location, no cast, range 4 circle + StartHydrofall = 31126, // Boss->self, no cast, single-target + Hydrofall = 31375, // Boss->self, 5,0s cast, single-target + Hydrofall2 = 31376, // Helper->players, 5,5s cast, range 6 circle + CursedTide = 31130, // Boss->self, 5,0s cast, single-target + StartLimitbreakPhase = 31132, // Boss->self, no cast, single-target + NeapTide = 31134, // Helper->player, no cast, range 6 circle + Hydrovent = 31136, // Helper->location, 5,0s cast, range 6 circle + SpringTide = 31135, // Helper->players, no cast, range 6 circle + Tsunami = 31137, // Helper->self, no cast, range 80 width 60 rect + Voidcleaver = 31110, // Boss->self, 4,0s cast, single-target + Voidcleaver2 = 31111, // Helper->self, no cast, range 100 circle + VoidMiasma = 32691, // Helper->self, 3,0s cast, range 50 30-degree cone + Lifescleaver = 31112, // Boss->self, 4,0s cast, single-target + ifescleaver2 = 31113, // Helper->self, 5,0s cast, range 50 30-degree cone + VoidTorrent = 31118, // Boss->self/player, 5,0s cast, range 60 width 8 rect + }; + + + class D133CagnazzoStates : StateMachineBuilder + { + public D133CagnazzoStates(BossModule module) : base(module) + { + TrivialPhase(); + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + // .ActivateOnEnter() + } + } + + [ModuleInfo(CFCID = 896, NameID = 11995)] + public class D133Cagnazzo : BossModule + { + public D133Cagnazzo(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(-250, 130), 20)) { } + } +} diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D053ForgivenWhimsy.cs b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D053ForgivenWhimsy.cs index 8c9d0b0ddf..e303b01f80 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D053ForgivenWhimsy.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D053ForgivenWhimsy.cs @@ -8,6 +8,7 @@ public enum OID : uint { Boss = 0x27CC, //R=20.00 Helper = 0x2E8, //R=0.5 + Helper2 = 0x233C, Brightsphere = 0x27CD, //R=1.0 Towers = 0x1EAACF, //R=0.5 } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D054ForgivenRevelry.cs b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D054ForgivenRevelry.cs index f6c9cf186b..ea62021970 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D054ForgivenRevelry.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D054ForgivenRevelry.cs @@ -8,6 +8,7 @@ public enum OID : uint { Boss = 0x28F3, //R=7.5 Helper = 0x2E8, //R=0.5 + Helper2 = 0x233C, Brightsphere = 0x2947, //R=1.0 } diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D055ForgivenObscenity.cs b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D055ForgivenObscenity.cs index d15d0bee0f..6e44d86545 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D055ForgivenObscenity.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D05MtGulg/D055ForgivenObscenity.cs @@ -9,6 +9,7 @@ public enum OID : uint Boss = 0x27CE, //R=5.0 BossClones = 0x27CF, //R=5.0 Helper = 0x2E8, //R=0.5 + Helper2 = 0x233C, Orbs = 0x27D0, //R=1.0 Rings = 0x1EAB62, } From 98931cc3ffd2d60d6a5c880a0e1743d6240d659d Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 17 Mar 2024 15:24:20 +0100 Subject: [PATCH 09/13] Cagnazzo done --- BossMod/Components/UnavoidableDamage.cs | 45 +++- .../D11LapisManalis/D132GalateaMagna.cs | 42 ++++ .../Dungeons/D11LapisManalis/D133Cagnazzo.cs | 197 +++++++++++++++++- 3 files changed, 274 insertions(+), 10 deletions(-) diff --git a/BossMod/Components/UnavoidableDamage.cs b/BossMod/Components/UnavoidableDamage.cs index 91c2807ad4..e4055c618c 100644 --- a/BossMod/Components/UnavoidableDamage.cs +++ b/BossMod/Components/UnavoidableDamage.cs @@ -1,4 +1,6 @@ -namespace BossMod.Components +using System; + +namespace BossMod.Components { // generic unavoidable raidwide cast public class RaidwideCast : CastHint @@ -12,6 +14,47 @@ public override void AddAIHints(BossModule module, int slot, Actor actor, PartyR } } + // generic unavoidable raidwide cast after NPC yell, typically used at the end of boss "limit break" phases + public class RaidwideAfterNPCYell : CastHint + { + public uint NPCYellID; + public float Delay; //delay from NPCyell for raidwide to cast event + private bool casting; + private DateTime _activation; + public RaidwideAfterNPCYell(ActionID aid, uint nPCYellid, float delay, string hint = "Raidwide") : base(aid, hint) + { + NPCYellID = nPCYellid; + Delay = delay; + } + + public override void OnActorNpcYell(BossModule module, Actor actor, ushort id) + { + if (id == NPCYellID) + { + casting = true; + _activation = module.WorldState.CurrentTime; + } + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if (spell.Action == WatchedAction) + casting = false; + } + + public override void AddAIHints(BossModule module, int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + if (casting) + hints.PredictedDamage.Add((module.Raid.WithSlot().Mask(), _activation.AddSeconds(Delay))); + } + + public override void AddGlobalHints(BossModule module, GlobalHints hints) + { + if (casting && Hint.Length > 0) + hints.Add(Hint); + } + } + // generic unavoidable single-target damage cast (typically tankbuster, but not necessary) public class SingleTargetCast : CastHint { diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs index 6aefa0c999..4c97193d2c 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -205,6 +205,47 @@ public override void AddAIHints(BossModule module, int slot, Actor actor, PartyR } } + class Doom : BossComponent + { + private List _doomed = new(); + public bool Doomed { get; private set; } + + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) + { + if ((SID)status.ID == SID.Doom) + _doomed.Add(actor); + } + + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) + { + if ((SID)status.ID == SID.Doom) + _doomed.Remove(actor); + } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + if (_doomed.Contains(actor) && !(actor.Role == Role.Healer || actor.Class == Class.BRD)) + hints.Add("You were doomed! Get cleansed fast."); + if (_doomed.Contains(actor) && (actor.Role == Role.Healer || actor.Class == Class.BRD)) + hints.Add("Cleanse yourself! (Doom)."); + foreach (var c in _doomed) + if (!_doomed.Contains(actor) && (actor.Role == Role.Healer || actor.Class == Class.BRD)) + hints.Add($"Cleanse {c.Name} (Doom)"); + } + + public override void AddAIHints(BossModule module, int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + base.AddAIHints(module, slot, actor, assignment, hints); + foreach (var c in _doomed) + { + if (_doomed.Count > 0 && actor.Role == Role.Healer) + hints.PlannedActions.Add((ActionID.MakeSpell(WHM.AID.Esuna), c, 1, false)); + if (_doomed.Count > 0 && actor.Class == Class.BRD) + hints.PlannedActions.Add((ActionID.MakeSpell(BRD.AID.WardensPaean), c, 1, false)); + } + } + } + class SoulScythe : Components.LocationTargetedAOEs { public SoulScythe() : base(ActionID.MakeSpell(AID.SoulScythe), 18) { } @@ -215,6 +256,7 @@ class D132GalateaMagnaStates : StateMachineBuilder public D132GalateaMagnaStates(BossModule module) : base(module) { TrivialPhase() + .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs index 9f957991a8..fbbad9b4b2 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs @@ -1,7 +1,6 @@ // CONTRIB: made by malediktus, not checked using System; using System.Collections.Generic; -using System.Linq; namespace BossMod.Endwalker.Dungeon.D13LapisManalis.D133Cagnazzo { @@ -40,22 +39,196 @@ public enum AID : uint Voidcleaver2 = 31111, // Helper->self, no cast, range 100 circle VoidMiasma = 32691, // Helper->self, 3,0s cast, range 50 30-degree cone Lifescleaver = 31112, // Boss->self, 4,0s cast, single-target - ifescleaver2 = 31113, // Helper->self, 5,0s cast, range 50 30-degree cone + Lifescleaver2 = 31113, // Helper->self, 5,0s cast, range 50 30-degree cone VoidTorrent = 31118, // Boss->self/player, 5,0s cast, range 60 width 8 rect }; + public enum IconID : uint + { + Stackmarker = 161, // player + Spreadmarker = 139, // player + Tankbuster = 230, // player + }; + + public enum TetherID : uint + { + LimitBreakCharger = 3, // FearsomeFlotsam->Boss + BaitAway = 1, // 3E97->player + }; + + public enum NPCYell : uint + { + LimitBreakStart = 15175, + }; + + class VoidTorrent : Components.BaitAwayCast + { + public VoidTorrent() : base(ActionID.MakeSpell(AID.VoidTorrent), new AOEShapeRect(60, 4)) { } + } + + class VoidTorrentHint : Components.SingleTargetCast + { + public VoidTorrentHint() : base(ActionID.MakeSpell(AID.VoidTorrent), "Tankbuster cleave") { } + } + + class Voidcleaver : Components.RaidwideCast + { + public Voidcleaver() : base(ActionID.MakeSpell(AID.Voidcleaver)) { } + } + + class VoidMiasmaBait : Components.BaitAwayTethers + { + public VoidMiasmaBait() : base(new AOEShapeCone(50, 15.Degrees()), (uint)TetherID.BaitAway) { } + } + + class VoidMiasma : Components.SelfTargetedAOEs + { + public VoidMiasma() : base(ActionID.MakeSpell(AID.VoidMiasma), new AOEShapeCone(50, 15.Degrees())) { } + } + + class Tsunami : Components.RaidwideAfterNPCYell + { + public Tsunami() : base(ActionID.MakeSpell(AID.Tsunami), (uint)NPCYell.LimitBreakStart, 4.5f) { } + } + + class StygianDeluge : Components.RaidwideCast + { + public StygianDeluge() : base(ActionID.MakeSpell(AID.StygianDeluge)) { } + } + + class Antediluvian : Components.SelfTargetedAOEs + { + public Antediluvian() : base(ActionID.MakeSpell(AID.Antediluvian2), new AOEShapeCircle(15)) { } + } + + class BodySlam : Components.SelfTargetedAOEs + { + public BodySlam() : base(ActionID.MakeSpell(AID.BodySlam3), new AOEShapeCircle(8)) { } + } + + class BodySlamKB : Components.KnockbackFromCastTarget + { + public BodySlamKB() : base(ActionID.MakeSpell(AID.BodySlam2), 10) { } + } + + class HydraulicRam : Components.GenericAOEs + { + private List<(WPos source, AOEShape shape, Angle direction)> _casters = new(); + private DateTime _activation; + + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) + { + if (_casters.Count > 0) + yield return new(_casters[0].shape, _casters[0].source, _casters[0].direction, _activation, ArenaColor.Danger); + for (int i = 1; i < _casters.Count; ++i) + yield return new(_casters[i].shape, _casters[i].source, _casters[i].direction, _activation); + } + + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.HydraulicRamTelegraph) + { + var dir = spell.LocXZ - caster.Position; + _casters.Add((caster.Position, new AOEShapeRect(dir.Length(), 4), Angle.FromDirection(dir))); + } + if ((AID)spell.Action.ID == AID.HydraulicRam) + _activation = spell.NPCFinishAt.AddSeconds(1.5f); //since these are charges of different length with 0s cast time, the activation times are different for each and there are different patterns, so we just pretend that they all start after the telegraphs end + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if (_casters.Count > 0 && (AID)spell.Action.ID == AID.HydraulicRam2) + _casters.RemoveAt(0); + } + } + + class Hydrobomb : Components.GenericAOEs + { + private List _casters = new(); + private static readonly AOEShapeCircle circle = new(4); + private DateTime _activation; + + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) + { + if (_casters.Count > 1) + for (int i = 0; i < 2; ++i) + yield return new(circle, _casters[i], activation: _activation.AddSeconds(6 - _casters.Count / 2), color: ArenaColor.Danger); + for (int i = 2; i < _casters.Count; ++i) + yield return new(circle, _casters[i], activation: _activation.AddSeconds(MathF.Ceiling(i / 2) + 6 - _casters.Count / 2)); + } + + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.HydrobombTelegraph) + _casters.Add(spell.LocXZ); + if ((AID)spell.Action.ID == AID.HydraulicRam) + _activation = spell.NPCFinishAt.AddSeconds(2.2f); + + } + + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if (_casters.Count > 0 && (AID)spell.Action.ID == AID.Hydrobomb) + _casters.RemoveAt(0); + } + } + + class Hydrovent : Components.LocationTargetedAOEs + { + public Hydrovent() : base(ActionID.MakeSpell(AID.Hydrovent), 6) { } + } + + class NeapTide : Components.UniformStackSpread + { + public NeapTide() : base(0, 6, alwaysShowSpreads: true) { } + public override void OnEventIcon(BossModule module, Actor actor, uint iconID) + { + if (iconID == (uint)IconID.Spreadmarker) + AddSpread(actor); + } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID == AID.NeapTide) + Spreads.Clear(); + } + } + + class Stackmarkers : Components.UniformStackSpread //Hydrofall and Springtide, both use the same icon + { + public Stackmarkers() : base(6, 0) { } + public override void OnEventIcon(BossModule module, Actor actor, uint iconID) + { + if (iconID == (uint)IconID.Stackmarker) + AddStack(actor); + } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID is AID.SpringTide or AID.Hydrofall2) + Stacks.Clear(); + } + } + class D133CagnazzoStates : StateMachineBuilder { public D133CagnazzoStates(BossModule module) : base(module) { - TrivialPhase(); - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() - // .ActivateOnEnter() + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } @@ -63,5 +236,11 @@ public D133CagnazzoStates(BossModule module) : base(module) public class D133Cagnazzo : BossModule { public D133Cagnazzo(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(-250, 130), 20)) { } + protected override void DrawEnemies(int pcSlot, Actor pc) + { + Arena.Actor(PrimaryActor, ArenaColor.Enemy); + foreach (var s in Enemies(OID.FearsomeFlotsam)) + Arena.Actor(s, ArenaColor.Enemy); + } } } From f9aea10fdad01eef379d3e13788e95620a762ca9 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 17 Mar 2024 15:25:52 +0100 Subject: [PATCH 10/13] formatting --- BossMod/Components/UnavoidableDamage.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/BossMod/Components/UnavoidableDamage.cs b/BossMod/Components/UnavoidableDamage.cs index e4055c618c..93e94e9cab 100644 --- a/BossMod/Components/UnavoidableDamage.cs +++ b/BossMod/Components/UnavoidableDamage.cs @@ -21,6 +21,7 @@ public class RaidwideAfterNPCYell : CastHint public float Delay; //delay from NPCyell for raidwide to cast event private bool casting; private DateTime _activation; + public RaidwideAfterNPCYell(ActionID aid, uint nPCYellid, float delay, string hint = "Raidwide") : base(aid, hint) { NPCYellID = nPCYellid; From 7b4ccc1df2a8fcb50e7f5c622b210a2a25769868 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 17 Mar 2024 23:47:47 +0100 Subject: [PATCH 11/13] readded mechanic i accidently deletted --- .../Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs index fbbad9b4b2..7fe064dda4 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs @@ -86,6 +86,11 @@ class VoidMiasma : Components.SelfTargetedAOEs public VoidMiasma() : base(ActionID.MakeSpell(AID.VoidMiasma), new AOEShapeCone(50, 15.Degrees())) { } } + class Lifescleaver : Components.SelfTargetedAOEs + { + public Lifescleaver() : base(ActionID.MakeSpell(AID.Lifescleaver2), new AOEShapeCone(50, 15.Degrees())) { } + } + class Tsunami : Components.RaidwideAfterNPCYell { public Tsunami() : base(ActionID.MakeSpell(AID.Tsunami), (uint)NPCYell.LimitBreakStart, 4.5f) { } @@ -215,6 +220,7 @@ public D133CagnazzoStates(BossModule module) : base(module) { TrivialPhase() .ActivateOnEnter() + .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() From b431709aabb7d7f559cff888eabdda89e674c4f3 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Fri, 22 Mar 2024 07:14:18 +0100 Subject: [PATCH 12/13] cleanup --- .../Dungeons/D11LapisManalis/D132GalateaMagna.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs index 4c97193d2c..51aa53a070 100644 --- a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs +++ b/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs @@ -51,7 +51,7 @@ public enum SID : uint class ScarecrowChase : Components.GenericAOEs { - private List> _casters = new(); + private List<(Actor actor, uint icon)> _casters = new(); private List _casterssorted = new(); private static readonly AOEShapeCross cross = new(40, 5); private DateTime _activation; @@ -72,15 +72,15 @@ public override void OnEventIcon(BossModule module, Actor actor, uint iconID) { if (iconID == (uint)IconID.Icon1) { - _casters.Add(new Tuple (actor, iconID)); + _casters.Add((actor, iconID)); _activation = module.WorldState.CurrentTime.AddSeconds(9.9f); } if (iconID == (uint)IconID.Icon2) - _casters.Add(new Tuple (actor, iconID)); + _casters.Add((actor, iconID)); if (iconID == (uint)IconID.Icon3) - _casters.Add(new Tuple (actor, iconID)); + _casters.Add((actor, iconID)); if (iconID == (uint)IconID.Icon4) - _casters.Add(new Tuple (actor, iconID)); + _casters.Add((actor, iconID)); var _order = _casters.OrderBy(x => x.Item2); // icons can appear in random order in raw ops, so need to be sorted _casterssorted = _order.Select(x => x.Item1).ToList(); } From d2118e1f219874ac757fcee4e11382150065f5e8 Mon Sep 17 00:00:00 2001 From: CarnifexOptimus Date: Sun, 24 Mar 2024 02:49:41 +0100 Subject: [PATCH 13/13] folder name fix --- .../{Dungeons => Dungeon}/D11LapisManalis/D130AlbusGriffin.cs | 0 .../{Dungeons => Dungeon}/D11LapisManalis/D130CaladriusMaturus.cs | 0 .../Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D131Albion.cs | 0 .../{Dungeons => Dungeon}/D11LapisManalis/D132GalateaMagna.cs | 0 .../{Dungeons => Dungeon}/D11LapisManalis/D133Cagnazzo.cs | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename BossMod/Modules/Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D130AlbusGriffin.cs (100%) rename BossMod/Modules/Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D130CaladriusMaturus.cs (100%) rename BossMod/Modules/Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D131Albion.cs (100%) rename BossMod/Modules/Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D132GalateaMagna.cs (100%) rename BossMod/Modules/Endwalker/{Dungeons => Dungeon}/D11LapisManalis/D133Cagnazzo.cs (100%) diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130AlbusGriffin.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D130AlbusGriffin.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130AlbusGriffin.cs rename to BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D130AlbusGriffin.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D130CaladriusMaturus.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D130CaladriusMaturus.cs rename to BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D130CaladriusMaturus.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D131Albion.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D131Albion.cs rename to BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D131Albion.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D132GalateaMagna.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D132GalateaMagna.cs rename to BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D132GalateaMagna.cs diff --git a/BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs b/BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D133Cagnazzo.cs similarity index 100% rename from BossMod/Modules/Endwalker/Dungeons/D11LapisManalis/D133Cagnazzo.cs rename to BossMod/Modules/Endwalker/Dungeon/D11LapisManalis/D133Cagnazzo.cs