From 72e12923865e4886193fdbed2e8564c0d256f41f Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Thu, 25 Jan 2024 20:03:38 +0000 Subject: [PATCH] Stylistic fixes. --- BossMod/BossModule/StateMachineBuilder.cs | 3 +- .../MaskedCarnivale/ObstacleLayouts.cs | 67 +++++----- .../Stage01.cs | 19 ++- .../Stage02MuchAdoAboutPudding/Stage02Act1.cs | 51 ++++---- .../Stage02MuchAdoAboutPudding/Stage02Act2.cs | 16 ++- .../Stage03WaitingForGolem/Stage03.cs | 23 ++-- .../Stage04Act1.cs | 28 +++-- .../Stage04Act2.cs | 45 ++++--- .../Stage05TheThreepennyTurtles/Stage05.cs | 4 +- .../Stage06EyeSociety/Stage06Act1.cs | 88 ++++++++----- .../Stage06EyeSociety/Stage06Act2.cs | 106 ++++++++++------ .../Stage07AChorusSlime/Stage07Act1.cs | 86 +++++++------ .../Stage07AChorusSlime/Stage07Act2.cs | 83 +++++++------ .../Stage07AChorusSlime/Stage07Act3.cs | 78 ++++++------ .../Stage08Bomb-edyofErrors/Stage08Act2.cs | 110 ---------------- .../Stage08Act1.cs | 93 +++++++------- .../Stage08BombedyOfErrors/Stage08Act2.cs | 117 ++++++++++++++++++ .../Stage09ToKillaMockingslime/Stage09.cs | 22 ++-- .../Stage10ALittleKnightMusic/Stage10.cs | 41 +++--- .../Stage11Act1.cs | 9 +- .../Stage11Act2.cs | 12 +- .../Stage12Act1.cs | 7 +- .../Stage12Act2.cs | 28 +++-- .../Stage13BeautyandaBeast/Stage13Act1.cs | 17 ++- .../Stage13BeautyandaBeast/Stage13Act2.cs | 40 +++--- .../Stage14BlobsintheWoods/Stage14Act1.cs | 30 +++-- .../Stage14BlobsintheWoods/Stage14Act2.cs | 26 ++-- .../Stage15TheMeNobodyNodes/Stage15.cs | 58 ++++++--- .../Stage16Act1.cs | 10 +- .../Stage16Act2.cs | 66 ++++++---- .../Stage17TheSwordofMusic/Stage17Act1.cs | 42 +++++-- .../Stage17TheSwordofMusic/Stage17Act2.cs | 49 +++++--- .../Stage18Act1.cs | 79 +++++++----- .../Stage18Act2.cs | 80 +++++++----- .../Stage19Act1.cs | 30 +++-- .../Stage19Act2.cs | 65 ++++++---- .../Stage20MissTyphon/Stage20Act1.cs | 24 ++-- .../Stage20MissTyphon/Stage20Act2.cs | 20 ++- .../Stage20MissTyphon/Stage20Act3.cs | 79 +++++++----- 39 files changed, 1117 insertions(+), 734 deletions(-) rename BossMod/Modules/MaskedCarnivale/{Stage01All'sWellThatStartsWell => Stage01AllsWellThatStartsWell}/Stage01.cs (83%) delete mode 100644 BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act2.cs rename BossMod/Modules/MaskedCarnivale/{Stage08Bomb-edyofErrors => Stage08BombedyOfErrors}/Stage08Act1.cs (61%) create mode 100644 BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act2.cs rename BossMod/Modules/MaskedCarnivale/{Stage12ThePlant-omoftheOpera => Stage12ThePlantomOfTheOpera}/Stage12Act1.cs (92%) rename BossMod/Modules/MaskedCarnivale/{Stage12ThePlant-omoftheOpera => Stage12ThePlantomOfTheOpera}/Stage12Act2.cs (86%) rename BossMod/Modules/MaskedCarnivale/{Stage16SunsetBull-evard => Stage16SunsetBullevard}/Stage16Act1.cs (88%) rename BossMod/Modules/MaskedCarnivale/{Stage16SunsetBull-evard => Stage16SunsetBullevard}/Stage16Act2.cs (86%) rename BossMod/Modules/MaskedCarnivale/{Stage18MidsummerNight'sExplosion => Stage18MidsummerNightsExplosion}/Stage18Act1.cs (77%) rename BossMod/Modules/MaskedCarnivale/{Stage18MidsummerNight'sExplosion => Stage18MidsummerNightsExplosion}/Stage18Act2.cs (77%) diff --git a/BossMod/BossModule/StateMachineBuilder.cs b/BossMod/BossModule/StateMachineBuilder.cs index 59949f889f..77a0b9a9cf 100644 --- a/BossMod/BossModule/StateMachineBuilder.cs +++ b/BossMod/BossModule/StateMachineBuilder.cs @@ -42,7 +42,7 @@ public Phase OnExit(Action action, bool condition = true) // note: usually components are deactivated automatically on phase change - manual deactivate is needed only for components that opt out of this (useful for components that need to maintain state across multiple phases) public Phase ActivateOnEnter(bool condition = true) where C : BossComponent, new() => OnEnter(_module.ActivateComponent, condition); - public Phase DeactivateOnEnter(bool condition = true) where C : BossComponent, new() => OnEnter(_module.DeactivateComponent, condition); + public Phase DeactivateOnEnter(bool condition = true) where C : BossComponent, new() => OnEnter(_module.DeactivateComponent, condition); // TODO: reconsider... public Phase DeactivateOnExit(bool condition = true) where C : BossComponent => OnExit(_module.DeactivateComponent, condition); } @@ -73,7 +73,6 @@ public State OnExit(Action action, bool condition = true) } public State ActivateOnEnter(bool condition = true) where C : BossComponent, new() => OnEnter(_module.ActivateComponent, condition); - public State DeactivateOnEnter(bool condition = true) where C : BossComponent, new() => OnEnter(_module.DeactivateComponent, condition); public State DeactivateOnExit(bool condition = true) where C : BossComponent => OnExit(_module.DeactivateComponent, condition); public State ExecOnEnter(Action fn, bool condition = true) where C : BossComponent => OnEnter(() => { var c = _module.FindComponent(); if (c != null) fn(c); }, condition); public State ExecOnExit(Action fn, bool condition = true) where C : BossComponent => OnExit(() => { var c = _module.FindComponent(); if (c != null) fn(c); }, condition); diff --git a/BossMod/Modules/MaskedCarnivale/ObstacleLayouts.cs b/BossMod/Modules/MaskedCarnivale/ObstacleLayouts.cs index 6e1e93b1b8..8a2c2893c5 100644 --- a/BossMod/Modules/MaskedCarnivale/ObstacleLayouts.cs +++ b/BossMod/Modules/MaskedCarnivale/ObstacleLayouts.cs @@ -5,45 +5,48 @@ namespace BossMod.MaskedCarnivale public class Layout2Corners : BossComponent { public static IEnumerable Wall1() - { - yield return new WPos(85,95); - yield return new WPos(95,95); - yield return new WPos(95,89); - yield return new WPos(94.5f,89); - yield return new WPos(94.5f,94.5f); - yield return new WPos(85,94.5f); - } - public static IEnumerable Wall2() - { - yield return new WPos(105,95); - yield return new WPos(115,95); - yield return new WPos(115,94.5f); - yield return new WPos(105.5f,94.5f); - yield return new WPos(105.5f,89); - yield return new WPos(105,89); - } - public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) - { - arena.AddPolygon(Wall1(),ArenaColor.Border); - arena.AddPolygon(Wall2(),ArenaColor.Border); - } + { + yield return new WPos(85,95); + yield return new WPos(95,95); + yield return new WPos(95,89); + yield return new WPos(94.5f,89); + yield return new WPos(94.5f,94.5f); + yield return new WPos(85,94.5f); + } + + public static IEnumerable Wall2() + { + yield return new WPos(105,95); + yield return new WPos(115,95); + yield return new WPos(115,94.5f); + yield return new WPos(105.5f,94.5f); + yield return new WPos(105.5f,89); + yield return new WPos(105,89); + } + + public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) + { + arena.AddPolygon(Wall1(),ArenaColor.Border); + arena.AddPolygon(Wall2(),ArenaColor.Border); + } } + public class Layout4Quads : BossComponent { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) - { - arena.AddQuad(new(107,110),new(110,113),new(113,110),new(110,107), ArenaColor.Border, 2); - arena.AddQuad(new(93,110),new(90,107),new(87,110),new(90,113), ArenaColor.Border, 2); - arena.AddQuad(new(90,93),new(93,90),new(90,87),new(87,90), ArenaColor.Border, 2); - arena.AddQuad(new(110,93),new(113,90),new(110,87),new(107,90), ArenaColor.Border, 2); - } + { + arena.AddQuad(new(107,110),new(110,113),new(113,110),new(110,107), ArenaColor.Border, 2); + arena.AddQuad(new(93,110),new(90,107),new(87,110),new(90,113), ArenaColor.Border, 2); + arena.AddQuad(new(90,93),new(93,90),new(90,87),new(87,90), ArenaColor.Border, 2); + arena.AddQuad(new(110,93),new(113,90),new(110,87),new(107,90), ArenaColor.Border, 2); + } } public class LayoutBigQuad : BossComponent { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) - { - arena.AddQuad(new(100,107),new(107,100),new(100,93),new(93,100), ArenaColor.Border, 2); - } + { + arena.AddQuad(new(100,107),new(107,100),new(100,93),new(93,100), ArenaColor.Border, 2); + } } -} \ No newline at end of file +} diff --git a/BossMod/Modules/MaskedCarnivale/Stage01All'sWellThatStartsWell/Stage01.cs b/BossMod/Modules/MaskedCarnivale/Stage01AllsWellThatStartsWell/Stage01.cs similarity index 83% rename from BossMod/Modules/MaskedCarnivale/Stage01All'sWellThatStartsWell/Stage01.cs rename to BossMod/Modules/MaskedCarnivale/Stage01AllsWellThatStartsWell/Stage01.cs index b1adf4ed30..5b45160439 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage01All'sWellThatStartsWell/Stage01.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage01AllsWellThatStartsWell/Stage01.cs @@ -1,5 +1,6 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage01 { public enum OID : uint @@ -15,27 +16,31 @@ public enum AID : uint AutoAttack2 = 6497, // 25BE->player, no cast, single-target IronJustice = 14199, // 25BE->self, 2,5s cast, range 8+R 120-degree cone }; + class IronJustice : Components.SelfTargetedAOEs { - public IronJustice() : base(ActionID.MakeSpell(AID.IronJustice), new AOEShapeCone(9.5f,60.Degrees())) { } + public IronJustice() : base(ActionID.MakeSpell(AID.IronJustice), new AOEShapeCone(9.5f, 60.Degrees())) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("This stage is trivial.\nUse whatever skills you have to defeat these opponents."); - } - } + } + } + class Stage01States : StateMachineBuilder { public Stage01States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .DeactivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Slime).All(e => e.IsDead); + .ActivateOnEnter() + .DeactivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Slime).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 611, NameID = 8077)] public class Stage01 : BossModule { @@ -43,7 +48,9 @@ public class Stage01 : BossModule { ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Slime).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act1.cs index 1980ab7eb7..031d98be87 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act1.cs @@ -1,5 +1,6 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage02.Act1 { public enum OID : uint @@ -21,47 +22,53 @@ class GoldenTongue : Components.CastHint { public GoldenTongue() : base(ActionID.MakeSpell(AID.GoldenTongue), "Can be interrupted, increase its magic damage") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("To beat this stage in a timely manner,\nyou should have at least one spell of each element.\n(Water, Fire, Ice, Lightning, Earth and Wind)"); - } + } } + class Hints2 : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Pudding is weak to wind spells.\nMarshmallow is weak to ice spells.\nBavarois is weak to earth spells."); - } - } + } + } + class Stage02Act1States : StateMachineBuilder + { + public Stage02Act1States(BossModule module) : base(module) { - public Stage02Act1States(BossModule module) : base(module) - { - TrivialPhase() + TrivialPhase() .ActivateOnEnter() - .ActivateOnEnter() + .ActivateOnEnter() .DeactivateOnEnter() .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Marshmallow).All(e => e.IsDead) && module.Enemies(OID.Bavarois).All(e => e.IsDead); - } } + } + [ModuleInfo(CFCID = 612, NameID = 8078)] public class Stage02Act1 : BossModule + { + public Stage02Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) { - public Stage02Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) - { - ActivateComponent(); - } - protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Marshmallow).Any(e => e.InCombat) || Enemies(OID.Bavarois).Any(e => e.InCombat); } - protected override void DrawEnemies(int pcSlot, Actor pc) - { - foreach (var s in Enemies(OID.Boss)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Marshmallow)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Bavarois)) - Arena.Actor(s, ArenaColor.Enemy, false); - } + ActivateComponent(); } + + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Marshmallow).Any(e => e.InCombat) || Enemies(OID.Bavarois).Any(e => e.InCombat); } + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + foreach (var s in Enemies(OID.Boss)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Marshmallow)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Bavarois)) + Arena.Actor(s, ArenaColor.Enemy, false); + } + } } diff --git a/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act2.cs index fb4d8c9eec..16351d46a2 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage02MuchAdoAboutPudding/Stage02Act2.cs @@ -1,5 +1,6 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage02.Act2 { public enum OID : uint @@ -22,28 +23,31 @@ class GoldenTongue : Components.CastHint { public GoldenTongue() : base(ActionID.MakeSpell(AID.GoldenTongue), "Can be interrupted, increases its magic damage.") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Gelato is weak to fire spells.\nFlan is weak to lightning spells.\nLicorice is weak to water spells."); - } - } + } + } class Stage02Act2States : StateMachineBuilder { public Stage02Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Flan).All(e => e.IsDead) && module.Enemies(OID.Licorice).All(e => e.IsDead); + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Flan).All(e => e.IsDead) && module.Enemies(OID.Licorice).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 612, NameID = 8079)] public class Stage02Act2(WorldState ws, Actor primary) : BossModule(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) { protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Flan).Any(e => e.InCombat) || Enemies(OID.Licorice).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -54,4 +58,4 @@ protected override void DrawEnemies(int pcSlot, Actor pc) Arena.Actor(s, ArenaColor.Enemy, false); } } -} \ No newline at end of file +} diff --git a/BossMod/Modules/MaskedCarnivale/Stage03WaitingForGolem/Stage03.cs b/BossMod/Modules/MaskedCarnivale/Stage03WaitingForGolem/Stage03.cs index 4b3707b5c9..d21ba7fb60 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage03WaitingForGolem/Stage03.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage03WaitingForGolem/Stage03.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage03 { public enum OID : uint @@ -18,44 +19,48 @@ public enum AID : uint class BoulderClap : SelfTargetedAOEs { - public BoulderClap() : base(ActionID.MakeSpell(AID.BoulderClap), new AOEShapeCone(14,60.Degrees())) { } + public BoulderClap() : base(ActionID.MakeSpell(AID.BoulderClap), new AOEShapeCone(14, 60.Degrees())) { } } class Dreadstorm : PersistentVoidzoneAtCastTarget { public Dreadstorm() : base(6, ActionID.MakeSpell(AID.EarthenHeart), m => m.Enemies(OID.voidzone), 0) { } } + class Obliterate : RaidwideCast { public Obliterate() : base(ActionID.MakeSpell(AID.Obliterate), "Interruptible raidwide") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Zipacna is weak against water based spells.\nFlying Sardine is recommended to interrupt raidwide."); - } + } } + class Hints2 : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Zipacna is weak against water based spells.\nEarth based spells are useless against Zipacna."); - } - } + } + } class Stage03States : StateMachineBuilder { public Stage03States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 613, NameID = 8084)] public class Stage03 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act1.cs index ecce50d7da..8f9a2ff8b1 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act1.cs @@ -1,5 +1,6 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage04.Act1 { public enum OID : uint @@ -16,38 +17,43 @@ public enum AID : uint SanguineBite = 14361, // 25C8->self, no cast, range 3+R width 2 rect }; -class Hints : BossComponent + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Trivial stage. Enemies here are weak to lightning and fire.\nIn Act 2 the Ram's Voice and Ultravibration combo can be useful.\nFlying Sardine for interrupts can be beneficial."); - } + } } -class Hints2 : BossComponent + + class Hints2 : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Bats are weak to lightning.\nThe wolf is weak to fire."); - } - } -class Stage04Act1States : StateMachineBuilder + } + } + + class Stage04Act1States : StateMachineBuilder { public Stage04Act1States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .DeactivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bat).All(e => e.IsDead); + .ActivateOnEnter() + .DeactivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bat).All(e => e.IsDead); } } -[ModuleInfo(CFCID = 614, NameID = 8086)] -public class Stage04Act1 : BossModule + + [ModuleInfo(CFCID = 614, NameID = 8086)] + public class Stage04Act1 : BossModule { public Stage04Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) { ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Bat).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act2.cs index c372905f30..418b61de5c 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage04GentlemanPreferSwords/Stage04Act2.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage04.Act2 { public enum OID : uint @@ -8,57 +9,60 @@ public enum OID : uint Beetle = 0x25D6, //R=0.6 }; -public enum AID : uint -{ - AutoAttack = 6497, // 25D5->player, no cast, single-target - GrandStrike = 14366, // 25D5->self, 1,5s cast, range 75+R width 2 rect - Attack2 = 6499, // 25D6->player, no cast, single-target - MagitekField = 14369, // 25D5->self, 5,0s cast, single-target - Spoil = 14362, // 25D6->self, no cast, range 6+R circle - MagitekRay = 14368, // 25D5->location, 3,0s cast, range 6 circle -}; - + public enum AID : uint + { + AutoAttack = 6497, // 25D5->player, no cast, single-target + GrandStrike = 14366, // 25D5->self, 1,5s cast, range 75+R width 2 rect + Attack2 = 6499, // 25D6->player, no cast, single-target + MagitekField = 14369, // 25D5->self, 5,0s cast, single-target + Spoil = 14362, // 25D6->self, no cast, range 6+R circle + MagitekRay = 14368, // 25D5->location, 3,0s cast, range 6 circle + }; class GrandStrike : SelfTargetedAOEs { - public GrandStrike() : base(ActionID.MakeSpell(AID.GrandStrike), new AOEShapeRect(77.5f,2)) { } + public GrandStrike() : base(ActionID.MakeSpell(AID.GrandStrike), new AOEShapeRect(77.5f, 2)) { } } - class MagitekRay: LocationTargetedAOEs + class MagitekRay : LocationTargetedAOEs { public MagitekRay() : base(ActionID.MakeSpell(AID.MagitekRay), 6) { } } + class MagitekField : CastHint { public MagitekField() : base(ActionID.MakeSpell(AID.MagitekField), "Interruptible, increases its defenses") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Kreios is weak to lightning spells.\nDuring the fight he will spawn 6 beetles.\nIf available use the Ram's Voice + Ultravibration combo for the instant kill."); - } + } } + class Hints2 : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Kreios is weak against lightning spells and can be frozen."); - } - } + } + } class Stage04Act2States : StateMachineBuilder { public Stage04Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 614, NameID = 8087)] public class Stage04Act2 : BossModule { @@ -73,6 +77,7 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Beetle)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { base.CalculateAIHints(slot, actor, assignment, hints); diff --git a/BossMod/Modules/MaskedCarnivale/Stage05TheThreepennyTurtles/Stage05.cs b/BossMod/Modules/MaskedCarnivale/Stage05TheThreepennyTurtles/Stage05.cs index be0bca7dee..1b4d20310c 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage05TheThreepennyTurtles/Stage05.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage05TheThreepennyTurtles/Stage05.cs @@ -1,3 +1,4 @@ +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage05 { public enum OID : uint @@ -10,7 +11,7 @@ class Hints : BossComponent public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("These turtles have very high defenses.\nBring 1000 Needles or Doom to defeat them.\nAlternatively you can remove their buff with Eerie Soundwave."); - } + } } class Stage05States : StateMachineBuilder @@ -21,6 +22,7 @@ public Stage05States(BossModule module) : base(module) .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 615, NameID = 8089)] public class Stage05 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act1.cs index 90bbfa3e68..3720366af4 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act1.cs @@ -2,6 +2,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage06.Act1 { public enum OID : uint @@ -17,47 +18,56 @@ public enum AID : uint Attack = 6499, // 2700/25CD->player, no cast, single-target ColdStare = 14692, // 25CD->self, 2,5s cast, range 40+R 90-degree cone }; + public enum SID : uint { Blind = 571, // Mandragora->player, extra=0x0 - }; + class DemonEye : CastGaze { private BitMask _blinded; - public DemonEye() : base(ActionID.MakeSpell(AID.DemonEye)) {} + + public DemonEye() : base(ActionID.MakeSpell(AID.DemonEye)) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveEyes(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveEyes(module, slot, actor); } } + class ColdStare : SelfTargetedAOEs //TODO: cone based gaze { private BitMask _blinded; - public bool Blinded { get; private set; } - public ColdStare() : base(ActionID.MakeSpell(AID.ColdStare), new AOEShapeCone(42.53f,45.Degrees())) { } + + public ColdStare() : base(ActionID.MakeSpell(AID.ColdStare), new AOEShapeCone(42.53f, 45.Degrees())) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveAOEs(module, slot, actor); } } @@ -65,42 +75,49 @@ public override IEnumerable ActiveAOEs(BossModule module, int slot, class TearyTwirl : StackWithCastTargets { private BitMask _blinded; - public TearyTwirl() : base(ActionID.MakeSpell(AID.TearyTwirl), 6.3f) {} + + public TearyTwirl() : base(ActionID.MakeSpell(AID.TearyTwirl), 6.3f) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - if(_blinded[slot]) - hints.Add("Kill mandragoras last incase you need to get blinded again.", false); - if(!_blinded[slot]) - hints.Add("Stack to get blinded!", false); - } + } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + if (_blinded[slot]) + hints.Add("Kill mandragoras last incase you need to get blinded again.", false); + if (!_blinded[slot]) + hints.Add("Stack to get blinded!", false); + } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Get blinded by the Teary Twirl AOE from the mandragoras.\nBlindness makes you immune to all the gaze attacks.\nThe eyes in act 2 are weak to lightning damage."); - } + } } + class Stage06Act2States : StateMachineBuilder { public Stage06Act2States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Mandragora).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Mandragora).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 616, NameID = 8090)] public class Stage06Act2 : BossModule { @@ -111,7 +128,9 @@ public class Stage06Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Mandragora).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -119,9 +138,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Mandragora)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act2.cs index 33420a7c9e..082d5565ed 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage06EyeSociety/Stage06Act2.cs @@ -2,6 +2,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage06.Act2 { public enum OID : uint @@ -29,101 +30,121 @@ public enum SID : uint class DemonEye : CastGaze { private BitMask _blinded; - public bool Blinded { get; private set; } - public DemonEye() : base(ActionID.MakeSpell(AID.DemonEye)) {} + + public DemonEye() : base(ActionID.MakeSpell(AID.DemonEye)) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveEyes(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveEyes(module, slot, actor); } } + class ColdStare : SelfTargetedAOEs //TODO: cone based gaze { private BitMask _blinded; - public ColdStare() : base(ActionID.MakeSpell(AID.ColdStare), new AOEShapeCone(42.53f,45.Degrees())) { } + + public ColdStare() : base(ActionID.MakeSpell(AID.ColdStare), new AOEShapeCone(42.53f, 45.Degrees())) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveAOEs(module, slot, actor); } } + class TearyTwirl : StackWithCastTargets { private BitMask _blinded; - public TearyTwirl() : base(ActionID.MakeSpell(AID.TearyTwirl), 6.3f) {} + + public TearyTwirl() : base(ActionID.MakeSpell(AID.TearyTwirl), 6.3f) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - if(_blinded[slot]) - hints.Add("Kill mandragoras last incase you need to get blinded again.", false); - if(!_blinded[slot]) - hints.Add("Stack to get blinded!", false); - } + } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + if (_blinded[slot]) + hints.Add("Kill mandragoras last incase you need to get blinded again.", false); + if (!_blinded[slot]) + hints.Add("Stack to get blinded!", false); + } } class DreadGaze : SelfTargetedAOEs //TODO: cone based gaze { private BitMask _blinded; - public DreadGaze() : base(ActionID.MakeSpell(AID.DreadGaze), new AOEShapeCone(7.35f,45.Degrees())) { } + + public DreadGaze() : base(ActionID.MakeSpell(AID.DreadGaze), new AOEShapeCone(7.35f, 45.Degrees())) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveAOEs(module, slot, actor); } } -class Hints : BossComponent + + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("The eyes are weak to lightning spells."); - } + } } + class Stage06Act2States : StateMachineBuilder { public Stage06Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Mandragora).All(e => e.IsDead) && module.Enemies(OID.Eye).All(e => e.IsDead); + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Mandragora).All(e => e.IsDead) && module.Enemies(OID.Eye).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 616, NameID = 8092)] public class Stage06Act2 : BossModule { @@ -133,7 +154,9 @@ public class Stage06Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Mandragora).Any(e => e.InCombat) || Enemies(OID.Eye).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -143,9 +166,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Mandragora)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act1.cs index cd79268614..eb6fcc8b72 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act1.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage07.Act1 { public enum OID : uint @@ -11,66 +12,73 @@ public enum OID : uint public enum AID : uint { - Detonation = 14696, // 2703->self, no cast, range 6+R circle - Blizzard = 14709, // 2702->player, 1,0s cast, single-target + Detonation = 14696, // 2703->self, no cast, range 6+R circle + Blizzard = 14709, // 2702->player, 1,0s cast, single-target }; + class SlimeExplosion : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 7.6f, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 7.6f, ArenaColor.Danger); } public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 7.6f)) - { - hints.Add("In slime explosion radius!"); - } - } + { + var player = module.Raid.Player(); + if (player != null) + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 7.6f)) + { + hints.Add("In slime explosion radius!"); + } } + } + class Hints : BossComponent + { + public override void AddGlobalHints(BossModule module, GlobalHints hints) { - public override void AddGlobalHints(BossModule module, GlobalHints hints) - { - hints.Add("For this stage the spells Sticky Tongue and Snort are recommended.\nUse them to pull or push Slimes close toIce Sprites.\nThen hit the slime from a distance with anything but fire spells to set of an explosion."); - } + hints.Add("For this stage the spells Sticky Tongue and Snort are recommended.\nUse them to pull or push Slimes close toIce Sprites.\nThen hit the slime from a distance with anything but fire spells to set of an explosion."); } + } + class Hints2 : BossComponent + { + public override void AddGlobalHints(BossModule module, GlobalHints hints) { - public override void AddGlobalHints(BossModule module, GlobalHints hints) - { - hints.Add("Hit the Lava Slime from a safe distance to win this act."); - } - } + hints.Add("Hit the Lava Slime from a safe distance to win this act."); + } + } + class Stage07Act1States : StateMachineBuilder + { + public Stage07Act1States(BossModule module) : base(module) { - public Stage07Act1States(BossModule module) : base(module) - { - TrivialPhase() + TrivialPhase() .DeactivateOnEnter() .ActivateOnEnter() .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Sprite).All(e => e.IsDead); - } } + } + [ModuleInfo(CFCID = 617, NameID = 8094)] public class Stage07Act1 : BossModule + { + public Stage07Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) + { + ActivateComponent(); + ActivateComponent(); + } + + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Sprite).Any(e => e.InCombat); } + + protected override void DrawEnemies(int pcSlot, Actor pc) { - public Stage07Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) - { - ActivateComponent(); - ActivateComponent(); - } - protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Sprite).Any(e => e.InCombat); } - protected override void DrawEnemies(int pcSlot, Actor pc) - { - foreach (var s in Enemies(OID.Boss)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Sprite)) - Arena.Actor(s, ArenaColor.Enemy, false); - } + foreach (var s in Enemies(OID.Boss)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Sprite)) + Arena.Actor(s, ArenaColor.Enemy, false); } + } } diff --git a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act2.cs index dc3928a7e6..0bbb19e08d 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act2.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage07.Act2 { public enum OID : uint @@ -11,59 +12,67 @@ public enum OID : uint public enum AID : uint { - Detonation = 14696, // 2705->self, no cast, range 6+R circle - Blizzard = 14709, // 2704->player, 1,0s cast, single-target + Detonation = 14696, // 2705->self, no cast, range 6+R circle + Blizzard = 14709, // 2704->player, 1,0s cast, single-target }; + class SlimeExplosion : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 7.6f, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 7.6f, ArenaColor.Danger); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 7.6f)) - { - hints.Add("In slime explosion radius!"); - } - } + { + var player = module.Raid.Player(); + if (player != null) + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 7.6f)) + { + hints.Add("In slime explosion radius!"); + } } + } + class Hints : BossComponent + { + public override void AddGlobalHints(BossModule module, GlobalHints hints) { - public override void AddGlobalHints(BossModule module, GlobalHints hints) - { - hints.Add("Pull or push the Lava Slimes to the Ice Sprites and then hit the slimes\nfrom a distance to set of the explosions."); - } + hints.Add("Pull or push the Lava Slimes to the Ice Sprites and then hit the slimes\nfrom a distance to set of the explosions."); } - class Layout : Layout4Quads {} + } + + class Layout : Layout4Quads { } + class Stage07Act2States : StateMachineBuilder + { + public Stage07Act2States(BossModule module) : base(module) { - public Stage07Act2States(BossModule module) : base(module) - { - TrivialPhase() + TrivialPhase() .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Sprite).All(e => e.IsDead); - } } - [ModuleInfo(CFCID = 617, NameID = 8094)] + } + + [ModuleInfo(CFCID = 617, NameID = 8094)] public class Stage07Act2 : BossModule + { + public Stage07Act2(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) + { + ActivateComponent(); + ActivateComponent(); + ActivateComponent(); + } + + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Sprite).Any(e => e.InCombat); } + + protected override void DrawEnemies(int pcSlot, Actor pc) { - public Stage07Act2(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) - { - ActivateComponent(); - ActivateComponent(); - ActivateComponent(); - } - protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Sprite).Any(e => e.InCombat); } - protected override void DrawEnemies(int pcSlot, Actor pc) - { - foreach (var s in Enemies(OID.Boss)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Sprite)) - Arena.Actor(s, ArenaColor.Enemy, false); - } + foreach (var s in Enemies(OID.Boss)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Sprite)) + Arena.Actor(s, ArenaColor.Enemy, false); } + } } diff --git a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act3.cs b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act3.cs index 799c822da1..854ed53e66 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act3.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage07AChorusSlime/Stage07Act3.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage07.Act3 { public enum OID : uint @@ -15,61 +16,68 @@ public enum AID : uint Detonation = 14696, // 2707->self, no cast, range 6+R circle Object130 = 14711, // 2706->self, no cast, range 30+R circle - instant kill if you do not line of sight the towers when they die }; + class LowVoltage : GenericLineOfSightAOE { public LowVoltage() : base(ActionID.MakeSpell(AID.LowVoltage), 35, true) { } //TODO: find a way to use the obstacles on the map and draw proper AOEs, this does nothing right now } + class SlimeExplosion : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Slime).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 7.5f, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Slime).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 7.5f, ArenaColor.Danger); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - foreach (var p in module.Enemies(OID.Slime).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 7.5f)) - { - hints.Add("In slime explosion radius!"); - } - } + { + var player = module.Raid.Player(); + if (player != null) + foreach (var p in module.Enemies(OID.Slime).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 7.5f)) + { + hints.Add("In slime explosion radius!"); + } } + } class Hints : BossComponent + { + public override void AddGlobalHints(BossModule module, GlobalHints hints) { - public override void AddGlobalHints(BossModule module, GlobalHints hints) - { - hints.Add("Pull or push the Lava Slimes to the towers and then hit the slimes\nfrom a distance to set off the explosions. The towers create a damage\npulse every 12s and a deadly explosion when they die. Take cover."); - } - } + hints.Add("Pull or push the Lava Slimes to the towers and then hit the slimes\nfrom a distance to set off the explosions. The towers create a damage\npulse every 12s and a deadly explosion when they die. Take cover."); + } + } + class Stage07Act3States : StateMachineBuilder + { + public Stage07Act3States(BossModule module) : base(module) { - public Stage07Act3States(BossModule module) : base(module) - { - TrivialPhase() + TrivialPhase() .ActivateOnEnter() .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Slime).All(e => e.IsDead); - } } - [ModuleInfo(CFCID = 617, NameID = 8095)] + } + + [ModuleInfo(CFCID = 617, NameID = 8095)] public class Stage07Act3 : BossModule + { + public Stage07Act3(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) { - public Stage07Act3(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) - { - ActivateComponent(); - ActivateComponent(); - ActivateComponent(); - } - protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Slime).Any(e => e.InCombat); } - protected override void DrawEnemies(int pcSlot, Actor pc) - { - foreach (var s in Enemies(OID.Boss)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Slime)) - Arena.Actor(s, ArenaColor.Enemy, false); - } + ActivateComponent(); + ActivateComponent(); + ActivateComponent(); } + + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Slime).Any(e => e.InCombat); } + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + foreach (var s in Enemies(OID.Boss)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Slime)) + Arena.Actor(s, ArenaColor.Enemy, false); + } + } } diff --git a/BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act2.cs deleted file mode 100644 index 2f18382046..0000000000 --- a/BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act2.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Linq; -using BossMod.Components; - -namespace BossMod.MaskedCarnivale.Stage08.Act2 -{ - public enum OID : uint - { - Boss = 0x270B, //R=3.75 - Bomb = 0x270C, //R=0.6 - Snoll = 0x270D, //R=0.9 - }; - - public enum AID : uint - { - Attack = 6499, // 270C/270B->player, no cast, single-target - SelfDestruct = 14730, // 270C->self, no cast, range 6 circle - HypothermalCombustion = 14731, // 270D->self, no cast, range 6 circle - Sap = 14708, // 270B->location, 5,0s cast, range 8 circle - Burst = 14680, // 270B->self, 6,0s cast, range 50 circle - }; - class Sap : LocationTargetedAOEs - { - public Sap() : base(ActionID.MakeSpell(AID.Sap), 8) { } - } - class Burst : CastHint - { - public Burst() : base(ActionID.MakeSpell(AID.Burst), "Interrupt or wipe!") { } - } - class Selfdetonations : GenericStackSpread - { - public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) - { - foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 10, ArenaColor.Danger); - foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 6, ArenaColor.Danger); - } - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - { - foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 10)) - { - hints.Add("In bomb explosion radius!"); - } - foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 6)) - { - hints.Add("In bomb explosion radius!"); - } - } - } - } - - class Hints : BossComponent - { - public override void AddGlobalHints(BossModule module, GlobalHints hints) - { - hints.Add("Clever activation of cherry bombs will freeze the Progenitrix.\nInterrupt its burst skill or wipe. The Progenitrix is weak to wind spells."); - } - } - - class Stage08Act2States : StateMachineBuilder - { - public Stage08Act2States(BossModule module) : base(module) - { - TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bomb).All(e => e.IsDead) && module.Enemies(OID.Snoll).All(e => e.IsDead); - } - } - [ModuleInfo(CFCID = 618, NameID = 8098)] - public class Stage08Act2 : BossModule - { - public Stage08Act2(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) - { - ActivateComponent(); - ActivateComponent(); - ActivateComponent(); - } - protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Bomb).Any(e => e.InCombat) || Enemies(OID.Snoll).Any(e => e.InCombat); } - protected override void DrawEnemies(int pcSlot, Actor pc) - { - foreach (var s in Enemies(OID.Boss)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Bomb)) - Arena.Actor(s, ArenaColor.Enemy, false); - foreach (var s in Enemies(OID.Snoll)) - Arena.Actor(s, ArenaColor.Enemy, false); - } - public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) - { - base.CalculateAIHints(slot, actor, assignment, hints); - foreach (var e in hints.PotentialTargets) - { - e.Priority = (OID)e.Actor.OID switch - { - OID.Boss => 1, - OID.Snoll or OID.Bomb => 0, - _ => 0 - }; - } - } - } -} - - diff --git a/BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act1.cs similarity index 61% rename from BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act1.cs rename to BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act1.cs index 5d11dbc364..c4f901259f 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage08Bomb-edyofErrors/Stage08Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act1.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage08.Act1 { public enum OID : uint @@ -21,69 +22,76 @@ class Selfdetonations : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 10, ArenaColor.Danger); - foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 6, ArenaColor.Danger); - foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 6, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 10, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 6, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 6, ArenaColor.Danger); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + var player = module.Raid.Player(); + if (player != null) { - var player = module.Raid.Player(); - if(player!=null) + foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 10)) + { + hints.Add("In bomb explosion radius!"); + } + foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 6)) { - foreach (var p in module.Enemies(OID.Boss).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 10)) - { - hints.Add("In bomb explosion radius!"); - } - foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 6)) - { - hints.Add("In bomb explosion radius!"); - } - foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 6)) - { - hints.Add("In bomb explosion radius!"); - } + hints.Add("In bomb explosion radius!"); + } + foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 6)) + { + hints.Add("In bomb explosion radius!"); } } } -class Hints : BossComponent + } + + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("For this stage the spell Flying Sardine to interrupt the Progenitrix in Act 2\nis highly recommended. Hit the Cherry Bomb from a safe distance\nwith anything but fire damage to set of a chain reaction to win this act."); - } + } } -class Hints2 : BossComponent + + class Hints2 : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Hit the Cherry Bomb from a safe distance to win this act."); - } - } -class Stage08Act1States : StateMachineBuilder + } + } + + class Stage08Act1States : StateMachineBuilder { public Stage08Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bomb).All(e => e.IsDead) && module.Enemies(OID.Snoll).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bomb).All(e => e.IsDead) && module.Enemies(OID.Snoll).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 618, NameID = 8140)] -public class Stage08Act1 : BossModule + public class Stage08Act1 : BossModule { public Stage08Act1(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) { ActivateComponent(); ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Bomb).Any(e => e.InCombat) || Enemies(OID.Snoll).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -93,18 +101,19 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Snoll)) Arena.Actor(s, ArenaColor.Enemy, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) - { + { base.CalculateAIHints(slot, actor, assignment, hints); - foreach (var e in hints.PotentialTargets) + foreach (var e in hints.PotentialTargets) + { + e.Priority = (OID)e.Actor.OID switch { - e.Priority = (OID)e.Actor.OID switch - { - OID.Boss => 1, - OID.Snoll or OID.Bomb => 0, - _ => 0 - }; - } + OID.Boss => 1, + OID.Snoll or OID.Bomb => 0, + _ => 0 + }; } } + } } diff --git a/BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act2.cs new file mode 100644 index 0000000000..adfa8d602c --- /dev/null +++ b/BossMod/Modules/MaskedCarnivale/Stage08BombedyOfErrors/Stage08Act2.cs @@ -0,0 +1,117 @@ +using System.Linq; +using BossMod.Components; + +// CONTRIB: made by malediktus, not checked +namespace BossMod.MaskedCarnivale.Stage08.Act2 +{ + public enum OID : uint + { + Boss = 0x270B, //R=3.75 + Bomb = 0x270C, //R=0.6 + Snoll = 0x270D, //R=0.9 + }; + + public enum AID : uint + { + Attack = 6499, // 270C/270B->player, no cast, single-target + SelfDestruct = 14730, // 270C->self, no cast, range 6 circle + HypothermalCombustion = 14731, // 270D->self, no cast, range 6 circle + Sap = 14708, // 270B->location, 5,0s cast, range 8 circle + Burst = 14680, // 270B->self, 6,0s cast, range 50 circle + }; + + class Sap : LocationTargetedAOEs + { + public Sap() : base(ActionID.MakeSpell(AID.Sap), 8) { } + } + + class Burst : CastHint + { + public Burst() : base(ActionID.MakeSpell(AID.Burst), "Interrupt or wipe!") { } + } + + class Selfdetonations : GenericStackSpread + { + public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) + { + foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 10, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 6, ArenaColor.Danger); + } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + var player = module.Raid.Player(); + if (player != null) + { + foreach (var p in module.Enemies(OID.Bomb).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 10)) + { + hints.Add("In bomb explosion radius!"); + } + foreach (var p in module.Enemies(OID.Snoll).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 6)) + { + hints.Add("In bomb explosion radius!"); + } + } + } + } + + class Hints : BossComponent + { + public override void AddGlobalHints(BossModule module, GlobalHints hints) + { + hints.Add("Clever activation of cherry bombs will freeze the Progenitrix.\nInterrupt its burst skill or wipe. The Progenitrix is weak to wind spells."); + } + } + + class Stage08Act2States : StateMachineBuilder + { + public Stage08Act2States(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Bomb).All(e => e.IsDead) && module.Enemies(OID.Snoll).All(e => e.IsDead); + } + } + + [ModuleInfo(CFCID = 618, NameID = 8098)] + public class Stage08Act2 : BossModule + { + public Stage08Act2(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsCircle(new(100, 100), 25)) + { + ActivateComponent(); + ActivateComponent(); + ActivateComponent(); + } + + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Bomb).Any(e => e.InCombat) || Enemies(OID.Snoll).Any(e => e.InCombat); } + + protected override void DrawEnemies(int pcSlot, Actor pc) + { + foreach (var s in Enemies(OID.Boss)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Bomb)) + Arena.Actor(s, ArenaColor.Enemy, false); + foreach (var s in Enemies(OID.Snoll)) + Arena.Actor(s, ArenaColor.Enemy, false); + } + + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + base.CalculateAIHints(slot, actor, assignment, hints); + foreach (var e in hints.PotentialTargets) + { + e.Priority = (OID)e.Actor.OID switch + { + OID.Boss => 1, + OID.Snoll or OID.Bomb => 0, + _ => 0 + }; + } + } + } +} diff --git a/BossMod/Modules/MaskedCarnivale/Stage09ToKillaMockingslime/Stage09.cs b/BossMod/Modules/MaskedCarnivale/Stage09ToKillaMockingslime/Stage09.cs index 6cb4f1435e..3338a24774 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage09ToKillaMockingslime/Stage09.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage09ToKillaMockingslime/Stage09.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage09 { public enum OID : uint @@ -13,6 +14,7 @@ public enum OID : uint Flan = 0x2716, //R=1.8 DarkVoidzone = 0x1E9C9D, //R=0.5 }; + public enum AID : uint { DeathRay = 15056, // 242D->player, 1,0s cast, single-target @@ -25,25 +27,28 @@ public enum AID : uint Thunder = 14268, // 2715->player, 1,0s cast, single-target Water = 14271, // 2716->player, 1,0s cast, single-target }; - + class GoldenTongue : CastHint { public GoldenTongue() : base(ActionID.MakeSpell(AID.GoldenTongue), "Can be interrupted, increase its magic damage") { } } + class DarkVoidzone : PersistentVoidzoneAtCastTarget { public DarkVoidzone() : base(4, ActionID.MakeSpell(AID.Dark), m => m.Enemies(OID.DarkVoidzone), 0) { } } + class Dark : LocationTargetedAOEs { public Dark() : base(ActionID.MakeSpell(AID.Dark), 5) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Guimauve summons a total of 6 adds during the fight, one of each element.\nHealer mimikry can be helpful if you have trouble surviving."); - } + } } class Stage09States : StateMachineBuilder @@ -51,12 +56,13 @@ class Stage09States : StateMachineBuilder public Stage09States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 619, NameID = 8099)] public class Stage09 : BossModule { @@ -64,9 +70,10 @@ public class Stage09 : BossModule { ActivateComponent(); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch @@ -77,6 +84,7 @@ public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.As }; } } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage10ALittleKnightMusic/Stage10.cs b/BossMod/Modules/MaskedCarnivale/Stage10ALittleKnightMusic/Stage10.cs index 0f42a44e94..ee62ebdb47 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage10ALittleKnightMusic/Stage10.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage10ALittleKnightMusic/Stage10.cs @@ -1,11 +1,13 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage10 { public enum OID : uint { Boss = 0x2717, // R1.0/1.5/2.0/2.5 (radius increases with amount of successful King's Will casts) }; + public enum AID : uint { IronJustice1 = 14725, // Boss->self, 2,5s cast, range 8+R 120-degree cone @@ -23,41 +25,50 @@ public enum AID : uint class IronJustice1 : SelfTargetedAOEs { - public IronJustice1() : base(ActionID.MakeSpell(AID.IronJustice1), new AOEShapeCone(9,60.Degrees())) { } + public IronJustice1() : base(ActionID.MakeSpell(AID.IronJustice1), new AOEShapeCone(9, 60.Degrees())) { } } + class IronJustice2 : SelfTargetedAOEs { - public IronJustice2() : base(ActionID.MakeSpell(AID.IronJustice2), new AOEShapeCone(9.5f,60.Degrees())) { } + public IronJustice2() : base(ActionID.MakeSpell(AID.IronJustice2), new AOEShapeCone(9.5f, 60.Degrees())) { } } + class IronJustice3 : SelfTargetedAOEs { - public IronJustice3() : base(ActionID.MakeSpell(AID.IronJustice3), new AOEShapeCone(10,60.Degrees())) { } + public IronJustice3() : base(ActionID.MakeSpell(AID.IronJustice3), new AOEShapeCone(10, 60.Degrees())) { } } + class IronJustice4 : SelfTargetedAOEs { - public IronJustice4() : base(ActionID.MakeSpell(AID.IronJustice4), new AOEShapeCone(10.5f,60.Degrees())) { } + public IronJustice4() : base(ActionID.MakeSpell(AID.IronJustice4), new AOEShapeCone(10.5f, 60.Degrees())) { } } + class BlackNebula : CastHint { public BlackNebula() : base(ActionID.MakeSpell(AID.BlackNebula), "Interrupt or wipe!") { } } + class Cloudcover1 : LocationTargetedAOEs { public Cloudcover1() : base(ActionID.MakeSpell(AID.Cloudcover1), 6) { } } + class KingsWill1 : CastHint { public static readonly string hints = "Interrupt if not going for the achievement"; public KingsWill1() : base(ActionID.MakeSpell(AID.KingsWill), hints) { } } + class KingsWill2 : CastHint { public KingsWill2() : base(ActionID.MakeSpell(AID.KingsWill2), KingsWill1.hints) { } } + class KingsWill3 : CastHint { public KingsWill3() : base(ActionID.MakeSpell(AID.KingsWill3), KingsWill1.hints) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) @@ -69,23 +80,25 @@ public override void AddHints(BossModule module, int slot, Actor actor, TextHint hints.Add("Requirement for achievement: Let Crom Dubh cast King's Will 3 times.", false); } } + class Stage10States : StateMachineBuilder { public Stage10States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 620, NameID = 8100)] public class Stage10 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act1.cs index f39d481a90..e2283109e0 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act1.cs @@ -1,11 +1,13 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage11.Act1 { public enum OID : uint { Boss = 0x2718, //R=1.2 }; + public enum AID : uint { Fulmination = 14583, // 2718->self, 23,0s cast, range 60 circle @@ -16,7 +18,7 @@ class Hints : BossComponent public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("These bombs start self-destruction on combat start. Pull them together\nwith Sticky Tongue and attack them with anything to interrupt them.\nThey are weak against wind and strong against fire."); - } + } } class Stage11Act1States : StateMachineBuilder @@ -24,10 +26,11 @@ class Stage11Act1States : StateMachineBuilder public Stage11Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); + .DeactivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 621, NameID = 2280)] public class Stage11Act1 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act2.cs index 96db33e504..0cd0b15eb8 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage11SomeLikeItExcruciatinglyHot/Stage11Act2.cs @@ -1,31 +1,36 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage11.Act2 { public enum OID : uint { Boss = 0x2719, //R=1.2 }; + public enum AID : uint { Fulmination = 14583, // 2719->self, 23,0s cast, range 60 circle }; + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Same as last act, but this time there are 4 bombs. Pull them to the\nmiddle with Sticky Tongue and attack them with any AOE to keep them\ninterrupted. They are weak against wind and strong against fire."); - } + } } + class Stage11Act2States : StateMachineBuilder { public Stage11Act2States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); + .DeactivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 621, NameID = 2280)] public class Stage11Act2 : BossModule { @@ -34,6 +39,7 @@ public class Stage11Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act1.cs similarity index 92% rename from BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act1.cs rename to BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act1.cs index eae1a73cfd..40949e8e83 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act1.cs @@ -1,9 +1,11 @@ +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage12.Act1 { public enum OID : uint { Boss = 0x271A, //R=0.8 }; + public enum AID : uint { Seedvolley = 14750, // 271A->player, no cast, single-target @@ -14,7 +16,7 @@ class Hints : BossComponent public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("For this stage Ice Spikes and Bomb Toss are recommended spells.\nUse Ice Spikes to instantly kill roselets once they become aggressive.\nHydnora in act 2 is weak against water and strong against earth spells."); - } + } } class Stage12Act1States : StateMachineBuilder @@ -22,9 +24,10 @@ class Stage12Act1States : StateMachineBuilder public Stage12Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter(); + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 622, NameID = 8103)] public class Stage12Act1 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act2.cs similarity index 86% rename from BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act2.cs rename to BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act2.cs index 4151b0c642..44258f8de7 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage12ThePlant-omoftheOpera/Stage12Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage12ThePlantomOfTheOpera/Stage12Act2.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage12.Act2 { public enum OID : uint @@ -7,6 +8,7 @@ public enum OID : uint Boss = 0x271B, //R=6.96 Roselet = 0x271C, //R=0.8 }; + public enum AID : uint { WildHorn = 14751, // 271B->self, 3,5s cast, range 10+R 120-degree cone @@ -15,41 +17,48 @@ public enum AID : uint Trounce = 14754, // 271B->self, 4,5s cast, range 40+R 60-degree cone InflammableFumes = 14753, // 271B->self, 15,0s cast, range 50 circle }; + class WildHorn : SelfTargetedAOEs { - public WildHorn() : base(ActionID.MakeSpell(AID.WildHorn), new AOEShapeCone(16.96f,60.Degrees())) { } + public WildHorn() : base(ActionID.MakeSpell(AID.WildHorn), new AOEShapeCone(16.96f, 60.Degrees())) { } } + class Trounce : SelfTargetedAOEs { - public Trounce() : base(ActionID.MakeSpell(AID.Trounce), new AOEShapeCone(46.96f,30.Degrees())) { } + public Trounce() : base(ActionID.MakeSpell(AID.Trounce), new AOEShapeCone(46.96f, 30.Degrees())) { } } + class SporeSac : CastHint { public SporeSac() : base(ActionID.MakeSpell(AID.SporeSac), "Calls Roselets. Prepare Ice Spikes if available.") { } } + class InflammableFumes : CastHint { public InflammableFumes() : base(ActionID.MakeSpell(AID.InflammableFumes), "Stun him with Bomb Toss. High damage but suriveable.") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Use Bomb Toss to stun Hydnora when he casts Inflammable Fumes.\nUse Ice Spikes to instantly kill roselets once they become aggressive.\nHydnora is weak against water and strong against earth spells."); - } + } } + class Stage12Act2States : StateMachineBuilder { public Stage12Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 622, NameID = 8102)] public class Stage12Act2 : BossModule { @@ -65,9 +74,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Roselet)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act1.cs index 987af452dd..b7cf7def63 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act1.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage13.Act1 { public enum OID : uint @@ -8,21 +9,24 @@ public enum OID : uint Boss = 0x26F5, //R=1.4 Vodoriga = 0x26F6, //R=1.2 }; + public enum AID : uint { Attack = 6497, // Boss/Vodoriga->player, no cast, single-target Mow = 14879, // Boss->self, 3,0s cast, range 6+R 120-degree cone }; + class Mow : SelfTargetedAOEs { - public Mow() : base(ActionID.MakeSpell(AID.Mow), new AOEShapeCone(7.4f,60.Degrees())) { } + public Mow() : base(ActionID.MakeSpell(AID.Mow), new AOEShapeCone(7.4f, 60.Degrees())) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("The first act is trivial, almost anything will work.\nFor act 2 having Flying Sardine is recommended."); - } + } } class Stage13Act1States : StateMachineBuilder @@ -30,11 +34,12 @@ class Stage13Act1States : StateMachineBuilder public Stage13Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Vodoriga).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Vodoriga).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 623, NameID = 8104)] public class Stage13Act1 : BossModule { @@ -42,7 +47,9 @@ public class Stage13Act1 : BossModule { ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Vodoriga).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act2.cs index 925cc271fe..42b16cd3f7 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage13BeautyandaBeast/Stage13Act2.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage13.Act2 { public enum OID : uint @@ -8,6 +9,7 @@ public enum OID : uint Succubus = 0x26F7, //R=1.0 Helper = 0x233C, //R=0.5 }; + public enum AID : uint { Attack = 6497, // 26F8/26F7->player, no cast, single-target @@ -24,45 +26,53 @@ public enum AID : uint BeguilingMist = 15045, // 26F7->self, 7,0s cast, range 50+R circle, interruptable, applies hysteria FatalAllure = 14952, // 26F8->self, no cast, range 50+R circle, attract, applies terror BloodRain = 14882, // 26F8->location, 3,0s cast, range 50 circle - }; class VoidFireII : LocationTargetedAOEs { public VoidFireII() : base(ActionID.MakeSpell(AID.VoidFireII), 5) { } } + class VoidFireIV : LocationTargetedAOEs { public VoidFireIV() : base(ActionID.MakeSpell(AID.VoidFireIV), 10) { } } + class VoidFireIV3 : LocationTargetedAOEs { public VoidFireIV3() : base(ActionID.MakeSpell(AID.VoidFireIV3), 6) { } } + class VoidAero : SelfTargetedAOEs { - public VoidAero() : base(ActionID.MakeSpell(AID.VoidAero), new AOEShapeRect(42,4)) { } + public VoidAero() : base(ActionID.MakeSpell(AID.VoidAero), new AOEShapeRect(42, 4)) { } } + class DarkSabbath : CastGaze { - public DarkSabbath() : base(ActionID.MakeSpell(AID.DarkSabbath)) { } + public DarkSabbath() : base(ActionID.MakeSpell(AID.DarkSabbath)) { } } + class DarkMist : SelfTargetedAOEs { - public DarkMist() : base(ActionID.MakeSpell(AID.DarkMist), new AOEShapeCircle(10)) { } + public DarkMist() : base(ActionID.MakeSpell(AID.DarkMist), new AOEShapeCircle(10)) { } } + class CircleOfBlood : SelfTargetedAOEs { - public CircleOfBlood() : base(ActionID.MakeSpell(AID.CircleOfBlood2), new AOEShapeDonut(10,20)) { } + public CircleOfBlood() : base(ActionID.MakeSpell(AID.CircleOfBlood2), new AOEShapeDonut(10, 20)) { } } + class BeguilingMist : CastHint { public BeguilingMist() : base(ActionID.MakeSpell(AID.BeguilingMist), "Interrupt or run around uncontrollably!") { } } + class BloodRain : RaidwideCast { public BloodRain() : base(ActionID.MakeSpell(AID.BloodRain), "Harmless raidwide unless you failed to kill succubus in time") { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) @@ -70,22 +80,24 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Camilla will cast various AOEs and summons adds.\nInterrupt the adds with Flying Sardine and kill them fast.\nIf the add is still alive during the next Black Sabbath, you will be wiped."); } } + class Stage13Act2States : StateMachineBuilder { public Stage13Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 623, NameID = 8107)] public class Stage13Act2 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act1.cs index a5165e0fee..6a9f27af6f 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act1.cs @@ -1,23 +1,28 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage14.Act1 { public enum OID : uint { Boss = 0x271D, //R=2.0 }; + public enum AID : uint { TheLastSong = 14756, // 271D->self, 6,0s cast, range 60 circle }; + class LastSong : GenericLineOfSightAOE { public LastSong() : base(ActionID.MakeSpell(AID.TheLastSong), 60, true) { } //TODO: find a way to use the obstacles on the map and draw proper AOEs, this does nothing right now } + class LastSongHint : BossComponent { - public static bool casting; + public static bool casting; + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.TheLastSong) @@ -29,30 +34,34 @@ public override void OnCastFinished(BossModule module, Actor caster, ActorCastIn if ((AID)spell.Action.ID == AID.TheLastSong) casting = false; } + public override void AddGlobalHints(BossModule module, GlobalHints hints) { - if(casting) - hints.Add("Take cover behind a barricade!"); - } + if (casting) + hints.Add("Take cover behind a barricade!"); + } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { - hints.Add("These slimes start casting Final Song after death.\nWhile FInal Song is not deadly, it does heavy damage and applies silence\nto you. Take cover! For act 2 the spell Loom is strongly recommended.\nThe slimes are strong against blunt melee damage such as J Kick."); - } + hints.Add("These slimes start casting Final Song after death.\nWhile Final Song is not deadly, it does heavy damage and applies silence\nto you. Take cover! For act 2 the spell Loom is strongly recommended.\nThe slimes are strong against blunt melee damage such as J Kick."); + } } + class Stage14Act1States : StateMachineBuilder { public Stage14Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && !LastSongHint.casting; + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && !LastSongHint.casting; } } + [ModuleInfo(CFCID = 624, NameID = 8108)] public class Stage14Act1 : BossModule { @@ -61,6 +70,7 @@ public class Stage14Act1 : BossModule ActivateComponent(); ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act2.cs index 8a0f0cae56..cddd8b1b4d 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage14BlobsintheWoods/Stage14Act2.cs @@ -1,12 +1,14 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage14.Act2 { public enum OID : uint { Boss = 0x271E, //R=2.0 }; + public enum AID : uint { Syrup = 14757, // 271E->player, no cast, range 4 circle, applies heavy to player @@ -17,9 +19,11 @@ class LastSong : GenericLineOfSightAOE { public LastSong() : base(ActionID.MakeSpell(AID.TheLastSong), 60, true) { } //TODO: find a way to use the obstacles on the map and draw proper AOEs, this does nothing right now } + class LastSongHint : BossComponent { - public static bool casting; + public static bool casting; + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.TheLastSong) @@ -33,28 +37,31 @@ public override void OnCastFinished(BossModule module, Actor caster, ActorCastIn } public override void AddGlobalHints(BossModule module, GlobalHints hints) { - if(casting) - hints.Add("Use the cube to take cover!"); - } + if (casting) + hints.Add("Use the cube to take cover!"); + } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Same as first act, but the slimes will apply heavy to you.\nUse Loom to get out of line of sight as soon as Final Song gets casted."); - } + } } + class Stage14Act2States : StateMachineBuilder { public Stage14Act2States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && !LastSongHint.casting; + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && !LastSongHint.casting; } } + [ModuleInfo(CFCID = 624, NameID = 8108)] public class Stage14Act2 : BossModule { @@ -63,6 +70,7 @@ public class Stage14Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage15TheMeNobodyNodes/Stage15.cs b/BossMod/Modules/MaskedCarnivale/Stage15TheMeNobodyNodes/Stage15.cs index f23a6f19ae..84da11e054 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage15TheMeNobodyNodes/Stage15.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage15TheMeNobodyNodes/Stage15.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage15 { public enum OID : uint @@ -10,6 +11,7 @@ public enum OID : uint Serpent = 0x26FB, //R=1.2 Helper = 0x233C, //R=0.5 }; + public enum AID : uint { HighVoltage = 14890, // 26F9->self, 7,0s cast, range 50+R circle, paralysis + summon add @@ -27,19 +29,23 @@ public enum AID : uint Superstorm2 = 14970, // 233C->self, 3,5s cast, range 8-20 donut Disseminate = 14899, // 26FB->self, 2,0s cast, range 6+R circle, casts on death of serpents }; + class HighVoltage : CastHint { public HighVoltage() : base(ActionID.MakeSpell(AID.HighVoltage), "Interrupt!") { } } + class Ballast : GenericAOEs { private bool casting2; private bool casting3; private bool casting4; private Angle _rotation; + private static readonly AOEShapeCone cone2 = new(5.5f, 135.Degrees()); private static readonly AOEShapeDonutSector cone3 = new(5.5f, 10.5f, 135.Degrees()); private static readonly AOEShapeDonutSector cone4 = new(10.5f, 15.5f, 135.Degrees()); + public override IEnumerable ActiveAOEs(BossModule module, int slot, Actor actor) { if (casting2) @@ -49,17 +55,19 @@ public override IEnumerable ActiveAOEs(BossModule module, int slot, if (casting4) yield return new(cone4, module.PrimaryActor.Position, _rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.Ballast0) - { + { casting2 = true; casting3 = true; casting4 = true; _rotation = module.PrimaryActor.Rotation; } } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) { base.OnEventCast(module, caster, spell); @@ -71,35 +79,43 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent casting4 = false; } } + class PiercingLaser : SelfTargetedAOEs { - public PiercingLaser() : base(ActionID.MakeSpell(AID.PiercingLaser), new AOEShapeRect(32.3f,4)) { } + public PiercingLaser() : base(ActionID.MakeSpell(AID.PiercingLaser), new AOEShapeRect(32.3f, 4)) { } } + class RepellingCannons : SelfTargetedAOEs { - public RepellingCannons() : base(ActionID.MakeSpell(AID.RepellingCannons), new AOEShapeCircle(12.3f)) { } + public RepellingCannons() : base(ActionID.MakeSpell(AID.RepellingCannons), new AOEShapeCircle(12.3f)) { } } + class Superstorm : SelfTargetedAOEs { - public Superstorm() : base(ActionID.MakeSpell(AID.Superstorm2), new AOEShapeDonut(8,20)) { } + public Superstorm() : base(ActionID.MakeSpell(AID.Superstorm2), new AOEShapeDonut(8, 20)) { } } + class Spellsword : SelfTargetedAOEs { - public Spellsword() : base(ActionID.MakeSpell(AID.Spellsword), new AOEShapeCone(7.1f,60.Degrees())) { } + public Spellsword() : base(ActionID.MakeSpell(AID.Spellsword), new AOEShapeCone(7.1f, 60.Degrees())) { } } + class Disseminate : SelfTargetedAOEs { - public Disseminate() : base(ActionID.MakeSpell(AID.Disseminate), new AOEShapeCircle(7.2f)) { } + public Disseminate() : base(ActionID.MakeSpell(AID.Disseminate), new AOEShapeCircle(7.2f)) { } } + class BallastKB : Knockback //actual knockbacks are 0.274s after snapshot { private bool casting2; private bool casting3; private bool casting4; private Angle _rotation; + private static readonly AOEShapeCone cone2 = new(5.5f, 135.Degrees()); private static readonly AOEShapeDonutSector cone3 = new(5.5f, 10.5f, 135.Degrees()); private static readonly AOEShapeDonutSector cone4 = new(10.5f, 15.5f, 135.Degrees()); + public override IEnumerable Sources(BossModule module, int slot, Actor actor) { if (casting2) @@ -109,17 +125,19 @@ public override IEnumerable Sources(BossModule module, int slot, Actor a if (casting4) yield return new(module.PrimaryActor.Position, 20, default, cone4, _rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.Ballast0) - { + { casting2 = true; casting3 = true; casting4 = true; _rotation = module.PrimaryActor.Rotation; } } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) { base.OnEventCast(module, caster, spell); @@ -131,6 +149,7 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent casting4 = false; } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) @@ -138,22 +157,24 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("For this stage Flying Sardine and Acorn Bomb are highly recommended.\nUse Flying Sardine to interrupt High Voltage.\nUse Acorn Bomb to put Shabtis to sleep until their buff runs out."); } } + class Stage15States : StateMachineBuilder { public Stage15States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 625, NameID = 8109)] public class Stage15 : BossModule { @@ -171,15 +192,16 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Serpent)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch { OID.Shabti => 2, //TODO: ideally AI would use Acorn Bomb to put it to sleep until buff runs out instead of attacking them directly - OID.Serpent => 1, + OID.Serpent => 1, OID.Boss => 0, _ => 0 }; diff --git a/BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act1.cs similarity index 88% rename from BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act1.cs rename to BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act1.cs index ebc00e6ded..d7fd272abc 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act1.cs @@ -1,23 +1,24 @@ using System.Linq; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage16.Act1 { public enum OID : uint { Boss = 0x26F2, //R=3.2 }; + public enum AID : uint { Attack = 6497, // 26F2->player, no cast, single-target }; - class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("The cyclops are very slow, but will instantly kill you, if they catch you.\nKite them or kill them with the self-destruct combo. (Toad Oil->Bristle->\nMoonflute->Swiftcast->Self-destruct) If you don't use the self-destruct\ncombo in act 1, you can bring the Final Sting combo for act 2.\n(Off-guard->Bristle->Moonflute->Final Sting)\nDiamondback is highly recommended in act 2."); - } + } } class Stage16Act1States : StateMachineBuilder @@ -25,10 +26,11 @@ class Stage16Act1States : StateMachineBuilder public Stage16Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); + .DeactivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 626, NameID = 8112)] public class Stage16Act1 : BossModule { diff --git a/BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act2.cs similarity index 86% rename from BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act2.cs rename to BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act2.cs index 91e3158e74..feda51ab58 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage16SunsetBull-evard/Stage16Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage16SunsetBullevard/Stage16Act2.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage16.Act2 { public enum OID : uint @@ -10,6 +11,7 @@ public enum OID : uint Cyclops = 0x26F3, //R=3.2 Helper = 0x233C, //R=0.5 }; + public enum AID : uint { AutoAttack = 6497, // 26F4->player, no cast, single-target @@ -29,42 +31,51 @@ class OneOneOneOneTonzeSwing : CastHint { public OneOneOneOneTonzeSwing() : base(ActionID.MakeSpell(AID.OneOneOneOneTonzeSwing), "Diamondback!") { } } - + class TenTonzeSlash : SelfTargetedAOEs { - public TenTonzeSlash() : base(ActionID.MakeSpell(AID.TenTonzeSlash), new AOEShapeCone(44,30.Degrees())) { } + public TenTonzeSlash() : base(ActionID.MakeSpell(AID.TenTonzeSlash), new AOEShapeCone(44, 30.Degrees())) { } } + class OneOneOneTonzeSwing : SelfTargetedAOEs { - public OneOneOneTonzeSwing() : base(ActionID.MakeSpell(AID.OneOneOneTonzeSwing), new AOEShapeCircle(12)) { } + public OneOneOneTonzeSwing() : base(ActionID.MakeSpell(AID.OneOneOneTonzeSwing), new AOEShapeCircle(12)) { } } + class CryOfRage : CastGaze { - public CryOfRage() : base(ActionID.MakeSpell(AID.CryOfRage)) { } + public CryOfRage() : base(ActionID.MakeSpell(AID.CryOfRage)) { } } + class TenTonzeWave : SelfTargetedAOEs { - public TenTonzeWave() : base(ActionID.MakeSpell(AID.TenTonzeWave), new AOEShapeCone(44,30.Degrees())) { } + public TenTonzeWave() : base(ActionID.MakeSpell(AID.TenTonzeWave), new AOEShapeCone(44, 30.Degrees())) { } } + class TenTonzeWave2 : SelfTargetedAOEs { - public TenTonzeWave2() : base(ActionID.MakeSpell(AID.TenTonzeWave2), new AOEShapeDonut(10,20)) { } + public TenTonzeWave2() : base(ActionID.MakeSpell(AID.TenTonzeWave2), new AOEShapeDonut(10, 20)) { } } + class OneOneOneTonzeSwingKB : Knockback //actual knockback happens a whole 1,462s after snapshot { private bool casting; + private readonly AOEShapeCircle circle = new(12); + public override IEnumerable Sources(BossModule module, int slot, Actor actor) { if (casting) yield return new(module.PrimaryActor.Position, 20, default, circle, module.PrimaryActor.Rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.OneOneOneTonzeSwing) casting = true; } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) { base.OnEventCast(module, caster, spell); @@ -72,9 +83,11 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent casting = false; } } + class ZoomIn : GenericWildCharge { - public ZoomIn() : base(4,ActionID.MakeSpell(AID.ZoomIn)) { } + public ZoomIn() : base(4, ActionID.MakeSpell(AID.ZoomIn)) { } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) @@ -90,30 +103,34 @@ public override void OnCastStarted(BossModule module, Actor caster, ActorCastInf public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) - { + { Source = null; - } + } } - } + } + class ZoomInKB : Knockback { private DateTime Time; private bool watched; + public override IEnumerable Sources(BossModule module, int slot, Actor actor) { if (watched && module.WorldState.CurrentTime < Time.AddSeconds(4.5f)) yield return new(module.PrimaryActor.Position, 20, default, default, module.PrimaryActor.Rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.ZoomIn) - { + { watched = true; Time = module.WorldState.CurrentTime; } } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) @@ -121,23 +138,25 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Tikbalang will spawn a cyclops a few seconds into the fight. Make sure\nto kill it before it reaches you. After that you can just slowly take down the\nboss. Use Diamondback to survive the 1111 Tonze Swing. Alternatively\nyou can try the Final Sting combo when he drops to about 75% health.\n(Off-guard->Bristle->Moonflute->Final Sting)"); } } + class Stage16Act2States : StateMachineBuilder { public Stage16Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 626, NameID = 8113)] public class Stage16Act2 : BossModule { @@ -153,14 +172,15 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Cyclops)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch { - OID.Cyclops => 1, + OID.Cyclops => 1, OID.Boss => 0, _ => 0 }; diff --git a/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act1.cs index a1d1bba89f..6bf736daf6 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act1.cs @@ -2,6 +2,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage17.Act1 { public enum OID : uint @@ -9,37 +10,45 @@ public enum OID : uint Boss = 0x2720, //R=2.0 RightClaw = 0x271F, //R=2.0 }; + public enum AID : uint { AutoAttack = 6499, // 2720/271F->player, no cast, single-target TheHand = 14760, // 271F/2720->self, 3,0s cast, range 6+R 120-degree cone, knockback from source, dist 10, knockback delayed by 0.9s after snapshot Shred = 14759, // 2720/271F->self, 2,5s cast, range 4+R width 4 rect, stuns player }; + class TheHand : SelfTargetedAOEs { - public TheHand() : base(ActionID.MakeSpell(AID.TheHand), new AOEShapeCone(8,60.Degrees())) { } + public TheHand() : base(ActionID.MakeSpell(AID.TheHand), new AOEShapeCone(8, 60.Degrees())) { } } + class Shred : SelfTargetedAOEs { - public Shred() : base(ActionID.MakeSpell(AID.Shred), new AOEShapeRect(6,2)) { } + public Shred() : base(ActionID.MakeSpell(AID.Shred), new AOEShapeRect(6, 2)) { } } + class TheHandKB : Knockback //actual knockback happens a whole 0,9s after snapshot { private bool casting; private Actor? _caster; - private readonly AOEShapeCone cone = new(8,60.Degrees()); + + private readonly AOEShapeCone cone = new(8, 60.Degrees()); + public override IEnumerable Sources(BossModule module, int slot, Actor actor) { if (casting && _caster != null) yield return new(_caster.Position, 10, default, cone, _caster.Rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.TheHand) casting = true; - _caster = caster; //this works because left hand and right hand never cast The Hand at the same time. if left claw uses the hand right claw uses shred and vice versa + _caster = caster; //this works because left hand and right hand never cast The Hand at the same time. if left claw uses the hand right claw uses shred and vice versa } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) { base.OnEventCast(module, caster, spell); @@ -47,9 +56,10 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent casting = false; } } + class Hints2 : BossComponent { - public override void AddGlobalHints(BossModule module, GlobalHints hints) + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (!module.Enemies(OID.Boss).All(e => e.IsDead)) hints.Add("Left claw counters magical damage!"); @@ -57,26 +67,29 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Right claw counters physical damage!"); } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("The left claw counters magical attacks, the right claw counts physical\nattacks. If you have healing spells you can just tank the counter damage\nand kill them however you like anyway. All opponents in this stage are\nweak to lightning.\nThe Ram's Voice and Ultravibration combo can be used in Act 2."); - } + } } + class Stage17Act1States : StateMachineBuilder { public Stage17Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.RightClaw).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.RightClaw).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 627, NameID = 8115)] public class Stage17Act1 : BossModule { @@ -84,7 +97,9 @@ public class Stage17Act1 : BossModule { ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.RightClaw).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -92,9 +107,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.RightClaw)) Arena.Actor(s, ArenaColor.Enemy, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act2.cs index a247b8b3ca..a642e64688 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage17TheSwordofMusic/Stage17Act2.cs @@ -2,6 +2,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage17.Act2 { public enum OID : uint @@ -11,6 +12,7 @@ public enum OID : uint RightClaw = 0x2723, //R=2.0 MagitekRayVoidzone = 0x1E8D9B, //R=0.5 }; + public enum AID : uint { AutoAttack = 6497, // 2721->player, no cast, single-target @@ -21,43 +23,53 @@ public enum AID : uint Shred = 14759, // 2723/2722->self, 2,5s cast, range 4+R width 4 rect MagitekRay = 15048, // 2721->location, 3,0s cast, range 6 circle, voidzone, interruptible }; + class GrandStrike : SelfTargetedAOEs { - public GrandStrike() : base(ActionID.MakeSpell(AID.GrandStrike), new AOEShapeRect(77.5f,2)) { } + public GrandStrike() : base(ActionID.MakeSpell(AID.GrandStrike), new AOEShapeRect(77.5f, 2)) { } } + class MagitekField : CastHint { public MagitekField() : base(ActionID.MakeSpell(AID.MagitekField), "Interruptible, increases its defenses") { } } + class MagitekRay : PersistentVoidzoneAtCastTarget { public MagitekRay() : base(6, ActionID.MakeSpell(AID.MagitekRay), m => m.Enemies(OID.MagitekRayVoidzone), 0) { } } + class TheHand : SelfTargetedAOEs { - public TheHand() : base(ActionID.MakeSpell(AID.TheHand), new AOEShapeCone(8,60.Degrees())) { } + public TheHand() : base(ActionID.MakeSpell(AID.TheHand), new AOEShapeCone(8, 60.Degrees())) { } } + class Shred : SelfTargetedAOEs { - public Shred() : base(ActionID.MakeSpell(AID.Shred), new AOEShapeRect(6,2)) { } + public Shred() : base(ActionID.MakeSpell(AID.Shred), new AOEShapeRect(6, 2)) { } } + class TheHandKB : Knockback //actual knockback happens a whole 0,9s after snapshot { private bool casting; private Actor? _caster; - private readonly AOEShapeCone cone = new(8,60.Degrees()); + + private readonly AOEShapeCone cone = new(8, 60.Degrees()); + public override IEnumerable Sources(BossModule module, int slot, Actor actor) { if (casting && _caster != null) yield return new(_caster.Position, 10, default, cone, _caster.Rotation, new()); } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.TheHand) casting = true; - _caster = caster; //this works because left hand and right hand never cast The Hand at the same time. if left claw uses the hand right claw uses shred and vice versa + _caster = caster; //this works because left hand and right hand never cast The Hand at the same time. if left claw uses the hand right claw uses shred and vice versa } + public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent spell) { base.OnEventCast(module, caster, spell); @@ -65,9 +77,10 @@ public override void OnEventCast(BossModule module, Actor caster, ActorCastEvent casting = false; } } + class Hints2 : BossComponent { - public override void AddGlobalHints(BossModule module, GlobalHints hints) + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (!module.Enemies(OID.LeftClaw).All(e => e.IsDead)) hints.Add("Left claw counters magical damage!"); @@ -75,28 +88,31 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Right claw counters physical damage!"); } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Kreios is weak to lightning spells.\nDuring the fight he will spawn one of each claws as known from act 1.\nIf available use the Ram's Voice + Ultravibration combo for instant kill."); - } + } } + class Stage17Act2States : StateMachineBuilder { public Stage17Act2States(BossModule module) : base(module) { TrivialPhase() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .DeactivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); } } + [ModuleInfo(CFCID = 627, NameID = 8087)] public class Stage17Act2 : BossModule { @@ -114,9 +130,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.RightClaw)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act1.cs similarity index 77% rename from BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act1.cs rename to BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act1.cs index fa2e10f681..02ec87c75d 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act1.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage18.Act1 { public enum OID : uint @@ -8,6 +9,7 @@ public enum OID : uint Boss = 0x2724, //R=3.0 Keg = 0x2726, //R=0.65 }; + public enum AID : uint { WildCharge = 15055, // 2724->players, 3,5s cast, width 8 rect charge @@ -20,24 +22,30 @@ public enum AID : uint class Explosion : SelfTargetedAOEs { - public Explosion() : base(ActionID.MakeSpell(AID.Explosion), new AOEShapeCircle(10)) { } + public Explosion() : base(ActionID.MakeSpell(AID.Explosion), new AOEShapeCircle(10)) { } } - class Fireball: LocationTargetedAOEs + + class Fireball : LocationTargetedAOEs { public Fireball() : base(ActionID.MakeSpell(AID.Fireball), 6) { } } + class RipperClaw : SelfTargetedAOEs { - public RipperClaw() : base(ActionID.MakeSpell(AID.RipperClaw), new AOEShapeCone(8,45.Degrees())) { } + public RipperClaw() : base(ActionID.MakeSpell(AID.RipperClaw), new AOEShapeCone(8, 45.Degrees())) { } } + class TailSmash : SelfTargetedAOEs { - public TailSmash() : base(ActionID.MakeSpell(AID.TailSmash), new AOEShapeCone(15,45.Degrees())) { } + public TailSmash() : base(ActionID.MakeSpell(AID.TailSmash), new AOEShapeCone(15, 45.Degrees())) { } } + class WildCharge : GenericWildCharge { private bool casting; - public WildCharge() : base(4,ActionID.MakeSpell(AID.WildCharge)) { } + + public WildCharge() : base(4, ActionID.MakeSpell(AID.WildCharge)) { } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) @@ -54,62 +62,68 @@ public override void OnCastStarted(BossModule module, Actor caster, ActorCastInf public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) - { + { Source = null; casting = false; - } + } } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { - if(casting && !module.Enemies(OID.Keg).All(e => e.IsDead)) - hints.Add("Aim charge at a keg!"); + if (casting && !module.Enemies(OID.Keg).All(e => e.IsDead)) + hints.Add("Aim charge at a keg!"); } } + class WildChargeKB : KnockbackFromCastTarget { public WildChargeKB() : base(ActionID.MakeSpell(AID.WildCharge), 10, kind: Kind.DirForward) { } //knockback actually delayed by 0.5s to 1s, maybe it depends on the rectangle length of the charge - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) {} + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { } } + class KegExplosion : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 10, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 10, ArenaColor.Danger); } public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 10)) - { - hints.Add("In keg explosion radius!"); - } - } + { + var player = module.Raid.Player(); + if (player != null) + foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 10)) + { + hints.Add("In keg explosion radius!"); + } } + } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Make the manticores run to the kegs and their attacks will make them\nblow up. They take 2500 damage per keg explosion.\nThe Ram's Voice and Ultravibration combo can be used to kill manticores."); - } + } } + class Stage18Act2States : StateMachineBuilder { public Stage18Act2States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Keg).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Keg).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 628, NameID = 8116)] public class Stage18Act2 : BossModule { @@ -118,7 +132,9 @@ public class Stage18Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Keg).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -126,9 +142,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Keg)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act2.cs similarity index 77% rename from BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act2.cs rename to BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act2.cs index eb4545a4b5..dfd1fb2e9c 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNight'sExplosion/Stage18Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage18MidsummerNightsExplosion/Stage18Act2.cs @@ -1,6 +1,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage18.Act2 { public enum OID : uint @@ -8,6 +9,7 @@ public enum OID : uint Boss = 0x2725, //R=3.0 Keg = 0x2726, //R=0.65 }; + public enum AID : uint { WildCharge = 15055, // 2725->players, 3,5s cast, width 8 rect charge @@ -20,24 +22,30 @@ public enum AID : uint class Explosion : SelfTargetedAOEs { - public Explosion() : base(ActionID.MakeSpell(AID.Explosion), new AOEShapeCircle(10)) { } + public Explosion() : base(ActionID.MakeSpell(AID.Explosion), new AOEShapeCircle(10)) { } } - class Fireball: LocationTargetedAOEs + + class Fireball : LocationTargetedAOEs { public Fireball() : base(ActionID.MakeSpell(AID.Fireball), 6) { } } + class RipperClaw : SelfTargetedAOEs { - public RipperClaw() : base(ActionID.MakeSpell(AID.RipperClaw), new AOEShapeCone(8,45.Degrees())) { } + public RipperClaw() : base(ActionID.MakeSpell(AID.RipperClaw), new AOEShapeCone(8, 45.Degrees())) { } } + class TailSmash : SelfTargetedAOEs { - public TailSmash() : base(ActionID.MakeSpell(AID.TailSmash), new AOEShapeCone(15,45.Degrees())) { } + public TailSmash() : base(ActionID.MakeSpell(AID.TailSmash), new AOEShapeCone(15, 45.Degrees())) { } } + class WildCharge : GenericWildCharge { private bool casting; - public WildCharge() : base(4,ActionID.MakeSpell(AID.WildCharge)) { } + + public WildCharge() : base(4, ActionID.MakeSpell(AID.WildCharge)) { } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) @@ -54,62 +62,69 @@ public override void OnCastStarted(BossModule module, Actor caster, ActorCastInf public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { if (spell.Action == WatchedAction) - { + { Source = null; casting = false; - } + } } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { - if(casting && !module.Enemies(OID.Keg).All(e => e.IsDead)) - hints.Add("Aim charge at a keg!"); + if (casting && !module.Enemies(OID.Keg).All(e => e.IsDead)) + hints.Add("Aim charge at a keg!"); } } + class WildChargeKB : KnockbackFromCastTarget { public WildChargeKB() : base(ActionID.MakeSpell(AID.WildCharge), 10, kind: Kind.DirForward) { } //knockback actually delayed by 0.5s to 1s, maybe it depends on the rectangle length of the charge - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) {} + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { } } + class KegExplosion : GenericStackSpread { public override void DrawArenaForeground(BossModule module, int pcSlot, Actor pc, MiniArena arena) { - foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) - arena.AddCircle(p.Position, 10, ArenaColor.Danger); + foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) + arena.AddCircle(p.Position, 10, ArenaColor.Danger); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - var player = module.Raid.Player(); - if(player!=null) - foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) - if(player.Position.InCircle(p.Position, 10)) - { - hints.Add("In keg explosion radius!"); - } - } + { + var player = module.Raid.Player(); + if (player != null) + foreach (var p in module.Enemies(OID.Keg).Where(x => x.HP.Cur > 0)) + if (player.Position.InCircle(p.Position, 10)) + { + hints.Add("In keg explosion radius!"); + } } + } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Same as last stage. Make the manticores run to the kegs and their attacks\nwill make them blow up. Their attacks will also do friendly fire damage\nto each other.\nThe Ram's Voice and Ultravibration combo can be used to kill manticores."); - } + } } + class Stage18Act2States : StateMachineBuilder { public Stage18Act2States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Keg).All(e => e.IsDead); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .Raw.Update = () => module.Enemies(OID.Boss).All(e => e.IsDead) && module.Enemies(OID.Keg).All(e => e.IsDead); } } + [ModuleInfo(CFCID = 628, NameID = 8116)] public class Stage18Act2 : BossModule { @@ -118,7 +133,9 @@ public class Stage18Act2 : BossModule ActivateComponent(); ActivateComponent(); } + protected override bool CheckPull() { return PrimaryActor.IsTargetable && PrimaryActor.InCombat || Enemies(OID.Keg).Any(e => e.InCombat); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -126,9 +143,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Keg)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch diff --git a/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act1.cs index b5e7f3386d..b203a2fa88 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act1.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage19.Act1 { public enum OID : uint @@ -7,6 +8,7 @@ public enum OID : uint Boss = 0x2727, //R=5.775 voidzone = 0x1EA9F9, //R=0.5 }; + public enum AID : uint { Reflect = 15073, // 2727->self, 3,0s cast, single-target, boss starts reflecting all melee attacks @@ -15,6 +17,7 @@ public enum AID : uint VineProbe = 15075, // 2727->self, 2,5s cast, range 6+R width 8 rect OffalBreath = 15076, // 2727->location, 3,5s cast, range 6 circle, interruptible, voidzone }; + public enum SID : uint { Reflect = 518, // Boss->Boss, extra=0x0 @@ -29,28 +32,34 @@ public enum SID : uint Pollen = 19, // none->player, extra=0x0 Stun = 149, // 2729->player, extra=0x0 }; + class BadBreath : SelfTargetedAOEs { - public BadBreath() : base(ActionID.MakeSpell(AID.BadBreath), new AOEShapeCone(17.775f,60.Degrees())) { } + public BadBreath() : base(ActionID.MakeSpell(AID.BadBreath), new AOEShapeCone(17.775f, 60.Degrees())) { } } + class VineProbe : SelfTargetedAOEs { - public VineProbe() : base(ActionID.MakeSpell(AID.VineProbe), new AOEShapeRect(11.775f,4)) { } + public VineProbe() : base(ActionID.MakeSpell(AID.VineProbe), new AOEShapeRect(11.775f, 4)) { } } + class OffalBreath : PersistentVoidzoneAtCastTarget { public OffalBreath() : base(6, ActionID.MakeSpell(AID.OffalBreath), m => m.Enemies(OID.voidzone), 0) { } } + class Reflect : BossComponent { private bool reflect; private bool casting; + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.Reflect) casting = true; } + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); @@ -60,6 +69,7 @@ public override void OnCastFinished(BossModule module, Actor caster, ActorCastIn casting = false; } } + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (casting) @@ -68,25 +78,28 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Boss reflects all magic damage!");//TODO: could use an AI hint to never use magic abilities after this is casted } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("At the start of the fight Rebekkah will cast Reflect. This will reflect all\nmagic damage back to you. Useful skills: Sharpened Knife,\nFlying Sardine, Ink Jet (Act 2), Exuviation (Act 2), potentially a Final Sting\ncombo. (Off-guard->Bristle->Moonflute->Final Sting)"); - } + } } + class Stage19Act1States : StateMachineBuilder { public Stage19Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter(); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } + [ModuleInfo(CFCID = 629, NameID = 8117)] public class Stage19Act1 : BossModule { @@ -94,6 +107,7 @@ public class Stage19Act1 : BossModule { ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act2.cs index d07cc15969..3441e7f862 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage19OnaClearDayYouCanSmellForever/Stage19Act2.cs @@ -2,6 +2,7 @@ using System.Linq; using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage19.Act2 { public enum OID : uint @@ -10,6 +11,7 @@ public enum OID : uint HotHip = 0x2779, //R=1.50 voidzone = 0x1EA9F9, //R=0.5 }; + public enum AID : uint { Reflect = 15073, // 2728->self, 3,0s cast, single-target, boss starts reflecting all melee attacks @@ -20,6 +22,7 @@ public enum AID : uint ExplosiveDehiscence = 15078, // 2729->self, 6,0s cast, range 50 circle, gaze BadBreath = 15074, // 2728->self, 3,5s cast, range 12+R 120-degree cone, interruptible, voidzone }; + public enum SID : uint { Reflect = 518, // Boss->Boss, extra=0x0 @@ -34,33 +37,41 @@ public enum SID : uint Pollen = 19, // none->player, extra=0x0 Stun = 149, // 2729->player, extra=0x0 }; + class ExplosiveDehiscence : CastGaze { public static BitMask _blinded; - public ExplosiveDehiscence() : base(ActionID.MakeSpell(AID.ExplosiveDehiscence)) {} + + public ExplosiveDehiscence() : base(ActionID.MakeSpell(AID.ExplosiveDehiscence)) { } + public override void OnStatusGain(BossModule module, Actor actor, ActorStatus status) - { - if ((SID)status.ID == SID.Blind) + { + if ((SID)status.ID == SID.Blind) _blinded.Set(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override void OnStatusLose(BossModule module, Actor actor, ActorStatus status) - { + { if ((SID)status.ID == SID.Blind) _blinded.Clear(module.Raid.FindSlot(actor.InstanceID)); - } + } + public override IEnumerable ActiveEyes(BossModule module, int slot, Actor actor) - { + { return _blinded[slot] ? Enumerable.Empty() : base.ActiveEyes(module, slot, actor); } } + class GazeHint : BossComponent { public static bool casting; - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) - { - if (!ExplosiveDehiscence._blinded[slot] && casting) - hints.Add("Cast Ink Jet on boss to get blinded!"); - } + + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) + { + if (!ExplosiveDehiscence._blinded[slot] && casting) + hints.Add("Cast Ink Jet on boss to get blinded!"); + } + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { if ((AID)spell.Action.ID == AID.Schizocarps) @@ -78,12 +89,14 @@ class Reflect : BossComponent { private bool reflect; private bool casting; + public override void OnCastStarted(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); if ((AID)spell.Action.ID == AID.Reflect) casting = true; } + public override void OnCastFinished(BossModule module, Actor caster, ActorCastInfo spell) { base.OnCastStarted(module, caster, spell); @@ -93,6 +106,7 @@ public override void OnCastFinished(BossModule module, Actor caster, ActorCastIn casting = false; } } + public override void AddGlobalHints(BossModule module, GlobalHints hints) { if (casting) @@ -101,39 +115,45 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Boss reflects all magic damage!");//TODO: could use an AI hint to never use magic abilities after this is casted } } + class BadBreath : SelfTargetedAOEs { - public BadBreath() : base(ActionID.MakeSpell(AID.BadBreath), new AOEShapeCone(17.775f,60.Degrees())) { } + public BadBreath() : base(ActionID.MakeSpell(AID.BadBreath), new AOEShapeCone(17.775f, 60.Degrees())) { } } + class VineProbe : SelfTargetedAOEs { - public VineProbe() : base(ActionID.MakeSpell(AID.VineProbe), new AOEShapeRect(11.775f,4)) { } + public VineProbe() : base(ActionID.MakeSpell(AID.VineProbe), new AOEShapeRect(11.775f, 4)) { } } + class OffalBreath : PersistentVoidzoneAtCastTarget { public OffalBreath() : base(6, ActionID.MakeSpell(AID.OffalBreath), m => m.Enemies(OID.voidzone), 0) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Same as first act, but this time the boss will cast a gaze from all directions.\nThe easiest counter for this is to blind yourself by casting Ink Jet on the\nboss after it casted Schizocarps.\nThe Final Sting combo window opens at around 75% health.\n(Off-guard->Bristle->Moonflute->Final Sting)"); - } + } } + class Stage19Act1States : StateMachineBuilder { public Stage19Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter(); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } + [ModuleInfo(CFCID = 629, NameID = 8117)] public class Stage19Act1 : BossModule { @@ -141,6 +161,7 @@ public class Stage19Act1 : BossModule { ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act1.cs b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act1.cs index b7fe64def7..2ad1d676ec 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act1.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act1.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage20.Act1 { public enum OID : uint @@ -15,41 +16,47 @@ public enum AID : uint Fireball2 = 14707, // 272A->player, no cast, range 8 circle, 3 casts after snort }; - class Fireball: LocationTargetedAOEs + class Fireball : LocationTargetedAOEs { public Fireball() : base(ActionID.MakeSpell(AID.Fireball), 8) { } } + class Snort : CastHint { - public Snort() : base(ActionID.MakeSpell(AID.Snort), "Use Diamondback!") { } + public Snort() : base(ActionID.MakeSpell(AID.Snort), "Use Diamondback!") { } } + class SnortKB : KnockbackFromCastTarget { public SnortKB() : base(ActionID.MakeSpell(AID.Snort), 30, kind: Kind.AwayFromOrigin) { } //knockback actually delayed by 0.7s - public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) {} + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { } } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) { hints.Add("Diamondback and Flying Sardine are essential for this stage. The Final\nSting combo (Off-guard->Bristle->Moonflute->Final Sting) can make act 3\nincluding the achievement much easier. Ultros in act 2 and 3 is weak to\nfire."); } + public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { hints.Add("Requirement for achievement: Don't kill any tentacles in act 3", false); - } + } } + class Stage20Act1States : StateMachineBuilder { public Stage20Act1States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter(); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } + [ModuleInfo(CFCID = 630, NameID = 3046)] public class Stage20Act1 : BossModule { @@ -57,6 +64,7 @@ public class Stage20Act1 : BossModule { ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act2.cs b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act2.cs index d8bdc14f03..07a2b7f80c 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act2.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act2.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage20.Act2 { public enum OID : uint @@ -7,6 +8,7 @@ public enum OID : uint Boss = 0x272B, //R=5.1 Helper = 0x233C, //R=0.5 }; + public enum AID : uint { AquaBreath = 14713, // 272B->self, 2,5s cast, range 8+R 90-degree cone @@ -15,25 +17,30 @@ public enum AID : uint Waterspout = 14718, // 233C->location, 2,5s cast, range 4 circle LightningBolt = 14717, // 233C->location, 3,0s cast, range 3 circle }; + class AquaBreath : SelfTargetedAOEs { - public AquaBreath() : base(ActionID.MakeSpell(AID.AquaBreath), new AOEShapeCone(13.1f,45.Degrees())) { } + public AquaBreath() : base(ActionID.MakeSpell(AID.AquaBreath), new AOEShapeCone(13.1f, 45.Degrees())) { } } + class Megavolt : SelfTargetedAOEs { - public Megavolt() : base(ActionID.MakeSpell(AID.Megavolt), new AOEShapeCircle(11.1f)) { } + public Megavolt() : base(ActionID.MakeSpell(AID.Megavolt), new AOEShapeCircle(11.1f)) { } } - class Waterspout: LocationTargetedAOEs + + class Waterspout : LocationTargetedAOEs { public Waterspout() : base(ActionID.MakeSpell(AID.Waterspout), 4) { } } - class LightningBolt: LocationTargetedAOEs + + class LightningBolt : LocationTargetedAOEs { public LightningBolt() : base(ActionID.MakeSpell(AID.LightningBolt), 3) { } } + class ImpSong : CastHint { - public ImpSong() : base(ActionID.MakeSpell(AID.ImpSong), "Interrupt Ultros!") { } + public ImpSong() : base(ActionID.MakeSpell(AID.ImpSong), "Interrupt Ultros!") { } } class Hints : BossComponent @@ -43,6 +50,7 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) hints.Add("Ultros is weak to fire. Interrupt Imp Song."); } } + class Stage20Act2States : StateMachineBuilder { public Stage20Act2States(BossModule module) : base(module) @@ -57,6 +65,7 @@ public Stage20Act2States(BossModule module) : base(module) .ActivateOnEnter(); } } + [ModuleInfo(CFCID = 630, NameID = 7111)] public class Stage20Act2 : BossModule { @@ -64,6 +73,7 @@ public class Stage20Act2 : BossModule { ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) diff --git a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act3.cs b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act3.cs index ca70e8b757..84d57f1bfb 100644 --- a/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act3.cs +++ b/BossMod/Modules/MaskedCarnivale/Stage20MissTyphon/Stage20Act3.cs @@ -1,5 +1,6 @@ using BossMod.Components; +// CONTRIB: made by malediktus, not checked namespace BossMod.MaskedCarnivale.Stage20.Act3 { public enum OID : uint @@ -9,55 +10,65 @@ public enum OID : uint Tentacle = 0x272E, //R=7.2 }; -public enum AID : uint -{ - Fungah = 14705, // 272C->self, no cast, range 8+R ?-degree cone, knockback 20 away from source - Fireball = 14706, // 272C->location, 3,5s cast, range 8 circle - Snort = 14704, // 272C->self, 7,0s cast, range 50+R circle - Fireball2 = 14707, // 272C->player, no cast, range 8 circle - Tentacle = 14747, // 272E->self, 3,0s cast, range 8 circle - Wallop = 14748, // 272E->self, 3,5s cast, range 50+R width 10 rect, knockback 20 away from source - Clearout = 14749, // 272E->self, no cast, range 13+R ?-degree cone, knockback 20 away from source - AquaBreath = 14745, // 272D->self, 2,5s cast, range 8+R 90-degree cone - Megavolt = 14746, // 272D->self, 3,0s cast, range 6+R circle - ImpSong = 14744, // 272D->self, 6,0s cast, range 50+R circle -}; + public enum AID : uint + { + Fungah = 14705, // 272C->self, no cast, range 8+R ?-degree cone, knockback 20 away from source + Fireball = 14706, // 272C->location, 3,5s cast, range 8 circle + Snort = 14704, // 272C->self, 7,0s cast, range 50+R circle + Fireball2 = 14707, // 272C->player, no cast, range 8 circle + Tentacle = 14747, // 272E->self, 3,0s cast, range 8 circle + Wallop = 14748, // 272E->self, 3,5s cast, range 50+R width 10 rect, knockback 20 away from source + Clearout = 14749, // 272E->self, no cast, range 13+R ?-degree cone, knockback 20 away from source + AquaBreath = 14745, // 272D->self, 2,5s cast, range 8+R 90-degree cone + Megavolt = 14746, // 272D->self, 3,0s cast, range 6+R circle + ImpSong = 14744, // 272D->self, 6,0s cast, range 50+R circle + }; + class AquaBreath : SelfTargetedAOEs { - public AquaBreath() : base(ActionID.MakeSpell(AID.AquaBreath), new AOEShapeCone(13.1f,45.Degrees())) { } + public AquaBreath() : base(ActionID.MakeSpell(AID.AquaBreath), new AOEShapeCone(13.1f, 45.Degrees())) { } } + class Megavolt : SelfTargetedAOEs { - public Megavolt() : base(ActionID.MakeSpell(AID.Megavolt), new AOEShapeCircle(11.1f)) { } + public Megavolt() : base(ActionID.MakeSpell(AID.Megavolt), new AOEShapeCircle(11.1f)) { } } + class Tentacle : SelfTargetedAOEs { - public Tentacle() : base(ActionID.MakeSpell(AID.Tentacle), new AOEShapeCircle(8)) { } + public Tentacle() : base(ActionID.MakeSpell(AID.Tentacle), new AOEShapeCircle(8)) { } } + class Wallop : SelfTargetedAOEs { - public Wallop() : base(ActionID.MakeSpell(AID.Wallop), new AOEShapeRect(57.2f,5)) { } + public Wallop() : base(ActionID.MakeSpell(AID.Wallop), new AOEShapeRect(57.2f, 5)) { } } + class WallopKB : KnockbackFromCastTarget { public WallopKB() : base(ActionID.MakeSpell(AID.Wallop), 20, kind: Kind.AwayFromOrigin) { } //knockback actually delayed by 0.8s } - class Fireball: LocationTargetedAOEs + + class Fireball : LocationTargetedAOEs { public Fireball() : base(ActionID.MakeSpell(AID.Fireball), 8) { } } + class ImpSong : CastHint { - public ImpSong() : base(ActionID.MakeSpell(AID.ImpSong), "Interrupt Ultros!") { } + public ImpSong() : base(ActionID.MakeSpell(AID.ImpSong), "Interrupt Ultros!") { } } + class Snort : CastHint { - public Snort() : base(ActionID.MakeSpell(AID.Snort), "Use Diamondback!") { } + public Snort() : base(ActionID.MakeSpell(AID.Snort), "Use Diamondback!") { } } + class SnortKB : KnockbackFromCastTarget { public SnortKB() : base(ActionID.MakeSpell(AID.Snort), 30, kind: Kind.AwayFromOrigin) { } //knockback actually delayed by 0.7s } + class Hints : BossComponent { public override void AddGlobalHints(BossModule module, GlobalHints hints) @@ -67,25 +78,27 @@ public override void AddGlobalHints(BossModule module, GlobalHints hints) public override void AddHints(BossModule module, int slot, Actor actor, TextHints hints, MovementHints? movementHints) { hints.Add("Requirement for achievement: Don't kill any tentacles in this act", false); - } + } } + class Stage20Act3States : StateMachineBuilder { public Stage20Act3States(BossModule module) : base(module) { TrivialPhase() - .DeactivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter() - .ActivateOnEnter(); + .DeactivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); } } + [ModuleInfo(CFCID = 630, NameID = 3046)] public class Stage20Act3 : BossModule { @@ -93,6 +106,7 @@ public class Stage20Act3 : BossModule { ActivateComponent(); } + protected override void DrawEnemies(int pcSlot, Actor pc) { foreach (var s in Enemies(OID.Boss)) @@ -102,9 +116,10 @@ protected override void DrawEnemies(int pcSlot, Actor pc) foreach (var s in Enemies(OID.Tentacle)) Arena.Actor(s, ArenaColor.Object, false); } + public override void CalculateAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { - base.CalculateAIHints(slot, actor, assignment, hints); + base.CalculateAIHints(slot, actor, assignment, hints); foreach (var e in hints.PotentialTargets) { e.Priority = (OID)e.Actor.OID switch