From 7b0cb3b5ff1fde1d520af59c4002988038186b51 Mon Sep 17 00:00:00 2001 From: Leontopodium Nival Date: Thu, 26 Sep 2024 03:59:12 -0400 Subject: [PATCH 01/19] POTD 110-140 + Lower POTD Updates -> Created modules for the following: 110, 120, 130, and 140 -> Went through and made the folllowing changes: -> Added a global hint for floor 100, gave a tip for using a resolution there for the Adds -> Floor 110 forgot to add the Contributor field (woops) -> Floor 20 -> I forgot to add the Palace Hornets to show up in the minimap, also gave them a priority of targeting if using AI mode -> Floor 30 -> Made the formatting the same as floor 130 (personal preference of naming scheme) + made it show a different hint to tell players to move to the center of the arena after x4 cast are made. -> Floor 40 -> Added priority targeting for the NightmareBhoots if using VBM's targeting system (they need to die first) -> ARF module -> 3rd boss -> formatting error? surprised that slipped through the cracks --- .../PalaceOfTheDead/D100NybethObdilord.cs | 13 +++- .../PalaceOfTheDead/D110Alicanto.cs | 2 +- .../PalaceOfTheDead/D120Kirtimukha.cs | 57 +++++++++++++++++ .../DeepDungeon/PalaceOfTheDead/D130Alfard.cs | 64 +++++++++++++++++++ .../DeepDungeon/PalaceOfTheDead/D140AhPuch.cs | 59 +++++++++++++++++ .../DeepDungeon/PalaceOfTheDead/D20Spurge.cs | 14 ++++ .../PalaceOfTheDead/D30Ningishzida.cs | 26 ++++++-- .../DeepDungeon/PalaceOfTheDead/D40Ixtab.cs | 14 +++- .../D063LahabreaIgeyorhm.cs | 1 - 9 files changed, 240 insertions(+), 10 deletions(-) create mode 100644 BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D120Kirtimukha.cs create mode 100644 BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D130Alfard.cs create mode 100644 BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs index b43586272..6fa4662a0 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs @@ -27,7 +27,15 @@ class Catapult(BossModule module) : Components.LocationTargetedAOEs(module, Acti class CorseAdds(BossModule module) : Components.AddsMulti(module, [(uint)OID.BicephalicCorse, (uint)OID.GiantCorse, (uint)OID.IronCorse]); class Doom(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Doom), new AOEShapeCone(47.4f, 60.Degrees())); class Shackle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Shackle), new AOEShapeRect(52.4f, 4, 0)); -class SummonDarkness(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SummonDarkness), "Summoning the corses, use Resolution if you want them permanently dead"); +class SummonDarkness(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SummonDarkness), "Summoning the corses, incoming Adds!"); + +class EncounterHints(BossModule module) : BossComponent(module) +{ + public override void AddGlobalHints(GlobalHints hints) + { + hints.Add($"There is 3 sets of adds that spawn at HP %'s -> (90%, 65%, 40%) \nA resolution can make the adds permanently dissapear once they are at 0% HP/the corpse are just laying on the floor.\nResolution is also does high damage to the adds + 0.3% to the Boss\nSolo tip: Either pop a resolution on all add packs, or pop lust -> resolution on 2nd ad pack. Make sure to keep regen up!"); + } +} class D100NybethObdilordStates : StateMachineBuilder { @@ -39,7 +47,8 @@ public D100NybethObdilordStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .ActivateOnEnter() + .ActivateOnEnter(); } } diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D110Alicanto.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D110Alicanto.cs index 86c40231a..72d074d7a 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D110Alicanto.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D110Alicanto.cs @@ -32,5 +32,5 @@ public D110AlicantoStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.Contributed, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 209, NameID = 5371)] +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 209, NameID = 5371)] public class D110Alicanto(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -235), new ArenaBoundsCircle(25)); diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D120Kirtimukha.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D120Kirtimukha.cs new file mode 100644 index 000000000..4f53e73f8 --- /dev/null +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D120Kirtimukha.cs @@ -0,0 +1,57 @@ +namespace BossMod.Modules.Heavensward.DeepDungeon.PalaceOfTheDead.D120Kirtimukha; + +public enum OID : uint +{ + Boss = 0x1819, // R3.600, x1 + DeepPalaceHornet = 0x1905, // R0.400, x0 (spawn during fight) +} + +public enum AID : uint +{ + AutoAttack = 6499, // Boss->player, no cast, single-target + AutoAttackAdds = 6498, // DeepPalaceHornet->player, no cast, single-target + AcidMist = 7134, // Boss->self, 3.0s cast, range 6+R circle + BloodyCaress = 7133, // Boss->self, no cast, range 8+R 120-degree cone + FinalSting = 919, // DeepPalaceHornet->player, 3.0s cast, single-target + GoldDust = 7135, // Boss->location, 3.0s cast, range 8 circle + Leafstorm = 7136, // Boss->self, 3.0s cast, range 50 circle + RottenStench = 7137, // Boss->self, 3.0s cast, range 45+R width 12 rect +} + +class AcidMist(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.AcidMist), new AOEShapeCircle(9.6f)); +class BossAdds(BossModule module) : Components.Adds(module, (uint)OID.DeepPalaceHornet) +{ + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + foreach (var e in hints.PotentialTargets) + e.Priority = (OID)e.Actor.OID switch + { + OID.DeepPalaceHornet => 2, + OID.Boss => 1, + _ => 0 + }; + } +} +class BloodyCaress(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.BloodyCaress), new AOEShapeCone(11.6f, 60.Degrees()), activeWhileCasting: false); +class FinalSting(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.FinalSting), "Final sting is being cast! \nKill the add or take 98% of your hp!"); +class GoldDust(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.GoldDust), 8); +class Leafstorm(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Leafstorm)); +class RottenStench(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.RottenStench), new AOEShapeRect(47.6f, 6)); + +class D120KirtimukhaStates : StateMachineBuilder +{ + public D120KirtimukhaStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 210, NameID = 5384)] +public class D120Kirtimukha(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -235), new ArenaBoundsCircle(24)); diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D130Alfard.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D130Alfard.cs new file mode 100644 index 000000000..26a0ed712 --- /dev/null +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D130Alfard.cs @@ -0,0 +1,64 @@ +using BossMod.Heavensward.Dungeon.D06AetherochemicalResearchFacility.D062Harmachis; + +namespace BossMod.Modules.Heavensward.DeepDungeon.PalaceOfTheDead.D130Alfard; + +public enum OID : uint +{ + Boss = 0x181A, // R4.800, x1 + FireVoidPuddle = 0x1E8D9B, // R0.500, x0 (spawn during fight), EventObj type + IceVoidPuddle = 0x1E8D9C, // R0.500, x0 (spawn during fight), EventObj type +} + +public enum AID : uint +{ + AutoAttack = 6501, // Boss->players, no cast, range 6+R ?-degree cone + BallOfFire = 7139, // Boss->location, no cast, range 6 circle + BallOfIce = 7140, // Boss->location, no cast, range 6 circle + Dissever = 7138, // Boss->self, no cast, range 6+R 90-degree cone + FearItself = 7141, // Boss->self, 2.0s cast, range 54+R circle +} + +class Dissever(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.Dissever), new AOEShapeCone(10.8f, 45.Degrees()), activeWhileCasting: false); +class BallofFire(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.FireVoidPuddle).Where(z => z.EventState != 7)); +class BallofIce(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.IceVoidPuddle).Where(z => z.EventState != 7)); +class FearItself(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.FearItself), new AOEShapeDonut(5, 50)); + +class Hints(BossModule module) : BossComponent(module) +{ + public int NumCasts { get; private set; } + + public override void OnEventCast(Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID is AID.BallOfFire or AID.BallOfIce or AID.FearItself) + ++NumCasts; + + if (NumCasts >= 5) + { + NumCasts = 0; + } + } + + public override void AddGlobalHints(GlobalHints hints) + { + if (NumCasts < 4) + hints.Add($"Bait the boss away from the middle of the arena. \n{Module.PrimaryActor.Name} will cast x2 Fire Puddles & x2 Ice Puddles. \nAfter the 4th puddle is dropped, run to the middle."); + if (NumCasts >= 4) + hints.Add($"Run to the middle of the arena! \n{Module.PrimaryActor.Name} is about to cast a donut AOE!"); + } +} + +class D130AlfardStates : StateMachineBuilder +{ + public D130AlfardStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 211, NameID = 5397)] +public class D130Alfard(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -235), new ArenaBoundsCircle(25)); diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs new file mode 100644 index 000000000..87ab3f3df --- /dev/null +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs @@ -0,0 +1,59 @@ +namespace BossMod.Modules.Heavensward.DeepDungeon.PalaceOfTheDead.D140AhPuch; + +public enum OID : uint +{ + Boss = 0x181B, // R3.800, x1 + DeepPalaceFollower = 0x1906, // R1.800, x0 (spawn during fight) + AccursedPoxVoidZone = 0x1E8EA9, // R0.500, x0 (spawn during fight), EventObj type +} + +public enum AID : uint +{ + AutoAttack = 6498, // Boss->player, no cast, single-target + AccursedPox = 7146, // Boss->location, 3.0s cast, range 8 circle + AncientEruption = 7142, // Boss->location, 2.5s cast, range 4 circle + Blizzard = 967, // DeepPalaceFollower->player, 1.0s cast, single-target + EntropicFlame = 7143, // Boss->self, 3.0s cast, range 50+R width 8 rect + Scream = 7145, // Boss->self, 3.0s cast, range 30 circle + ShadowFlare = 7144, // Boss->self, 3.0s cast, range 25+R circle +} + +class Adds(BossModule module) : Components.Adds(module, (uint)OID.DeepPalaceFollower) +{ + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + foreach (var e in hints.PotentialTargets) + e.Priority = (OID)e.Actor.OID switch + { + OID.DeepPalaceFollower => 2, + OID.Boss => 1, + _ => 0 + }; + } +} +class AccursedPox(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.AccursedPox), 8); +class AncientEruption(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.AncientEruption), 4); +class AncientEruptionZone(BossModule module) : Components.PersistentInvertibleVoidzone(module, 4, m => m.Enemies(OID.AccursedPoxVoidZone).Where(z => z.EventState != 7)); +class EntropicFlame(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.EntropicFlame), new AOEShapeRect(53.8f, 4)); +class Scream(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Scream), "Raidwide + Fear, Adds need to be dead by now"); +class ShadowFlare(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.ShadowFlare)); + + + +class D140AhPuchStates : StateMachineBuilder +{ + public D140AhPuchStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 212, NameID = 5410)] +public class D140AhPuch(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -237), new ArenaBoundsCircle(25)); diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D20Spurge.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D20Spurge.cs index f715f22ee..b3ac72354 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D20Spurge.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D20Spurge.cs @@ -19,6 +19,19 @@ public enum AID : uint RottenStench = 6425, // Boss->self, 3.0s cast, range 45+R width 12 rect } +class BossAdds(BossModule module) : Components.Adds(module, (uint)OID.PalaceHornet) +{ + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + foreach (var e in hints.PotentialTargets) + e.Priority = (OID)e.Actor.OID switch + { + OID.PalaceHornet => 2, + OID.Boss => 1, + _ => 0 + }; + } +} class AcidMist(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.AcidMist), new AOEShapeCircle(9.6f)); class BloodyCaress(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.BloodyCaress), new AOEShapeCone(11.6f, 60.Degrees()), activeWhileCasting: false); class GoldDust(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.GoldDust), 8); @@ -30,6 +43,7 @@ class D20SpurgeStates : StateMachineBuilder public D20SpurgeStates(BossModule module) : base(module) { TrivialPhase() + .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D30Ningishzida.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D30Ningishzida.cs index 18393b767..d79713361 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D30Ningishzida.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D30Ningishzida.cs @@ -3,8 +3,8 @@ namespace BossMod.Heavensward.DeepDungeon.PalaceoftheDead.D30Ningishzida; public enum OID : uint { Boss = 0x16AC, // R4.800, x1 - BallofFirePuddle = 0x1E8D9B, // R0.500, x0 (spawn during fight), EventObj type - BallofIcePuddle = 0x1E8D9C, // R0.500, x0 (spawn during fight), EventObj type + FireVoidPuddle = 0x1E8D9B, // R0.500, x0 (spawn during fight), EventObj type + IceVoidPuddle = 0x1E8D9C, // R0.500, x0 (spawn during fight), EventObj type } public enum AID : uint @@ -17,15 +17,31 @@ public enum AID : uint } class Dissever(BossModule module) : Components.Cleave(module, ActionID.MakeSpell(AID.Dissever), new AOEShapeCone(10.8f, 45.Degrees()), activeWhileCasting: false); -class BallofFire(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.BallofFirePuddle).Where(z => z.EventState != 7)); -class BallofIce(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.BallofIcePuddle).Where(z => z.EventState != 7)); +class BallofFire(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.FireVoidPuddle).Where(z => z.EventState != 7)); +class BallofIce(BossModule module) : Components.PersistentVoidzone(module, 6, m => m.Enemies(OID.IceVoidPuddle).Where(z => z.EventState != 7)); class FearItself(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.FearItself), new AOEShapeDonut(5, 50)); class Hints(BossModule module) : BossComponent(module) { + public int NumCasts { get; private set; } + + public override void OnEventCast(Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID is AID.BallOfFire or AID.BallOfIce or AID.FearItself) + ++NumCasts; + + if (NumCasts >= 5) + { + NumCasts = 0; + } + } + public override void AddGlobalHints(GlobalHints hints) { - hints.Add($" Bait the boss away from the middle of the arena. \n {Module.PrimaryActor.Name} will cast x2 Fire Puddles & x2 Ice Puddles, after the 4th puddle is dropped, run to the middle."); + if (NumCasts < 4) + hints.Add($"Bait the boss away from the middle of the arena. \n{Module.PrimaryActor.Name} will cast x2 Fire Puddles & x2 Ice Puddles. \nAfter the 4th puddle is dropped, run to the middle."); + if (NumCasts >= 4) + hints.Add($"Run to the middle of the arena! \n{Module.PrimaryActor.Name} is about to cast a donut AOE!"); } } diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D40Ixtab.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D40Ixtab.cs index 8d9cb9538..8a5370dbd 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D40Ixtab.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D40Ixtab.cs @@ -19,7 +19,19 @@ public enum AID : uint ShadowFlare = 6432, // Boss->self, 3.0s cast, range 25+R circle } -class Adds(BossModule module) : Components.Adds(module, (uint)OID.NightmareBhoot); +class Adds(BossModule module) : Components.Adds(module, (uint)OID.NightmareBhoot) +{ + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + foreach (var e in hints.PotentialTargets) + e.Priority = (OID)e.Actor.OID switch + { + OID.NightmareBhoot => 2, + OID.Boss => 1, + _ => 0 + }; + } +} class AccursedPox(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.AccursedPox), 8); class AncientEruption(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.AncientEruption), 4); class AncientEruptionZone(BossModule module) : Components.PersistentInvertibleVoidzone(module, 4, m => m.Enemies(OID.AccursedPoxVoidZone).Where(z => z.EventState != 7)); diff --git a/BossMod/Modules/Heavensward/Dungeon/D06TheAetherochemicalResearchFacility/D063LahabreaIgeyorhm.cs b/BossMod/Modules/Heavensward/Dungeon/D06TheAetherochemicalResearchFacility/D063LahabreaIgeyorhm.cs index ef7a532a8..76e0eadad 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D06TheAetherochemicalResearchFacility/D063LahabreaIgeyorhm.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D06TheAetherochemicalResearchFacility/D063LahabreaIgeyorhm.cs @@ -43,7 +43,6 @@ public enum AID : uint ShadowFlare = 31885, // Igeyorhm/Boss->self, 5.0s cast, range 40 circle } - public enum TetherID : uint { StarTether = 110 // BurningStar/FrozenStar->BurningStar/FrozenStar From 13dc2739f4627f826ca26637955b0c07abea9df6 Mon Sep 17 00:00:00 2001 From: ace Date: Thu, 26 Sep 2024 10:12:43 -0700 Subject: [PATCH 02/19] Enable planning for Criterion dungeon bosses --- .../Endwalker/Criterion/C01ASS/C011Silkie/C011Silkie.cs | 4 ++-- .../Endwalker/Criterion/C01ASS/C012Gladiator/C012Gladiator.cs | 4 ++-- .../Criterion/C01ASS/C013Shadowcaster/C013Shadowcaster.cs | 4 ++-- .../Endwalker/Criterion/C02AMR/C021Shishio/C021Shishio.cs | 4 ++-- .../Modules/Endwalker/Criterion/C02AMR/C022Gorai/C022Gorai.cs | 4 ++-- .../Modules/Endwalker/Criterion/C02AMR/C023Moko/C023Moko.cs | 4 ++-- .../Endwalker/Criterion/C03AAI/C031Ketuduke/C031Ketuduke.cs | 4 ++-- .../Modules/Endwalker/Criterion/C03AAI/C032Lala/C032Lala.cs | 4 ++-- .../Endwalker/Criterion/C03AAI/C033Statice/C033Statice.cs | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/BossMod/Modules/Endwalker/Criterion/C01ASS/C011Silkie/C011Silkie.cs b/BossMod/Modules/Endwalker/Criterion/C01ASS/C011Silkie/C011Silkie.cs index 06d5bfd00..b83387997 100644 --- a/BossMod/Modules/Endwalker/Criterion/C01ASS/C011Silkie/C011Silkie.cs +++ b/BossMod/Modules/Endwalker/Criterion/C01ASS/C011Silkie/C011Silkie.cs @@ -35,8 +35,8 @@ class SFizzlingDusterPuff(BossModule module) : FizzlingDusterPuff(module, AID.SF public static readonly AOEShapeCone ShapeYellow = new(60, 22.5f.Degrees()); } -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11369, SortOrder = 5)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11369, SortOrder = 5, PlanLevel = 90)] public class C011NSilkie(WorldState ws, Actor primary) : C011Silkie(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11369, SortOrder = 5)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11369, SortOrder = 5, PlanLevel = 90)] public class C011SSilkie(WorldState ws, Actor primary) : C011Silkie(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C01ASS/C012Gladiator/C012Gladiator.cs b/BossMod/Modules/Endwalker/Criterion/C01ASS/C012Gladiator/C012Gladiator.cs index 9b3a65b43..aab355678 100644 --- a/BossMod/Modules/Endwalker/Criterion/C01ASS/C012Gladiator/C012Gladiator.cs +++ b/BossMod/Modules/Endwalker/Criterion/C01ASS/C012Gladiator/C012Gladiator.cs @@ -10,8 +10,8 @@ class SRushOfMightBack(BossModule module) : RushOfMightBack(module, AID.SRushOfM public abstract class C012Gladiator(WorldState ws, Actor primary) : BossModule(ws, primary, new(-35, -271), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11387, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11387, SortOrder = 8, PlanLevel = 90)] public class C012NGladiator(WorldState ws, Actor primary) : C012Gladiator(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11387, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11387, SortOrder = 8, PlanLevel = 90)] public class C012SGladiator(WorldState ws, Actor primary) : C012Gladiator(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C01ASS/C013Shadowcaster/C013Shadowcaster.cs b/BossMod/Modules/Endwalker/Criterion/C01ASS/C013Shadowcaster/C013Shadowcaster.cs index 07107cffc..e8d967bad 100644 --- a/BossMod/Modules/Endwalker/Criterion/C01ASS/C013Shadowcaster/C013Shadowcaster.cs +++ b/BossMod/Modules/Endwalker/Criterion/C01ASS/C013Shadowcaster/C013Shadowcaster.cs @@ -15,8 +15,8 @@ class SPureFire(BossModule module) : PureFire(module, AID.SPureFireAOE); public abstract class C013Shadowcaster(WorldState ws, Actor primary) : BossModule(ws, primary, new(289, -105), new ArenaBoundsRect(15, 20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11393, SortOrder = 9)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 878, NameID = 11393, SortOrder = 9, PlanLevel = 90)] public class C013NShadowcaster(WorldState ws, Actor primary) : C013Shadowcaster(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11393, SortOrder = 9)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 879, NameID = 11393, SortOrder = 9, PlanLevel = 90)] public class C013SShadowcaster(WorldState ws, Actor primary) : C013Shadowcaster(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C02AMR/C021Shishio/C021Shishio.cs b/BossMod/Modules/Endwalker/Criterion/C02AMR/C021Shishio/C021Shishio.cs index 07bcaf5df..ececbefe7 100644 --- a/BossMod/Modules/Endwalker/Criterion/C02AMR/C021Shishio/C021Shishio.cs +++ b/BossMod/Modules/Endwalker/Criterion/C02AMR/C021Shishio/C021Shishio.cs @@ -10,8 +10,8 @@ class SThunderVortex(BossModule module) : ThunderVortex(module, AID.SThunderVort public abstract class C021Shishio(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, -100), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12428, SortOrder = 4)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12428, SortOrder = 4, PlanLevel = 90)] public class C021NShishio(WorldState ws, Actor primary) : C021Shishio(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12428, SortOrder = 4)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12428, SortOrder = 4, PlanLevel = 90)] public class C021SShishio(WorldState ws, Actor primary) : C021Shishio(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C02AMR/C022Gorai/C022Gorai.cs b/BossMod/Modules/Endwalker/Criterion/C02AMR/C022Gorai/C022Gorai.cs index e26e21dd6..5c6b8a5b1 100644 --- a/BossMod/Modules/Endwalker/Criterion/C02AMR/C022Gorai/C022Gorai.cs +++ b/BossMod/Modules/Endwalker/Criterion/C02AMR/C022Gorai/C022Gorai.cs @@ -6,8 +6,8 @@ class SUnenlightenment(BossModule module) : Unenlightenment(module, AID.SUnenlig public abstract class C022Gorai(WorldState ws, Actor primary) : BossModule(ws, primary, new(300, -120), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12373, SortOrder = 7)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12373, SortOrder = 7, PlanLevel = 90)] public class C022NGorai(WorldState ws, Actor primary) : C022Gorai(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12373, SortOrder = 7)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12373, SortOrder = 7, PlanLevel = 90)] public class C022SGorai(WorldState ws, Actor primary) : C022Gorai(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/C023Moko.cs b/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/C023Moko.cs index 7d73a7b66..e8d63021d 100644 --- a/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/C023Moko.cs +++ b/BossMod/Modules/Endwalker/Criterion/C02AMR/C023Moko/C023Moko.cs @@ -6,8 +6,8 @@ class SLateralSlice(BossModule module) : LateralSlice(module, AID.SLateralSlice) public abstract class C023Moko(WorldState ws, Actor primary) : BossModule(ws, primary, new(-200, 0), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12357, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 946, NameID = 12357, SortOrder = 8, PlanLevel = 90)] public class C023NMoko(WorldState ws, Actor primary) : C023Moko(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12357, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 947, NameID = 12357, SortOrder = 8, PlanLevel = 90)] public class C023SMoko(WorldState ws, Actor primary) : C023Moko(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C03AAI/C031Ketuduke/C031Ketuduke.cs b/BossMod/Modules/Endwalker/Criterion/C03AAI/C031Ketuduke/C031Ketuduke.cs index 4c3294d69..b6351e26e 100644 --- a/BossMod/Modules/Endwalker/Criterion/C03AAI/C031Ketuduke/C031Ketuduke.cs +++ b/BossMod/Modules/Endwalker/Criterion/C03AAI/C031Ketuduke/C031Ketuduke.cs @@ -16,8 +16,8 @@ class SHydrobomb(BossModule module) : Hydrobomb(module, AID.SHydrobombAOE); public abstract class C031Ketuduke(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, 0), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12605, SortOrder = 5)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12605, SortOrder = 5, PlanLevel = 90)] public class C031NKetuduke(WorldState ws, Actor primary) : C031Ketuduke(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12605, SortOrder = 5)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12605, SortOrder = 5, PlanLevel = 90)] public class C031SKetuduke(WorldState ws, Actor primary) : C031Ketuduke(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C03AAI/C032Lala/C032Lala.cs b/BossMod/Modules/Endwalker/Criterion/C03AAI/C032Lala/C032Lala.cs index 0e7da10b9..96c035f16 100644 --- a/BossMod/Modules/Endwalker/Criterion/C03AAI/C032Lala/C032Lala.cs +++ b/BossMod/Modules/Endwalker/Criterion/C03AAI/C032Lala/C032Lala.cs @@ -6,8 +6,8 @@ class SArcaneBlight(BossModule module) : ArcaneBlight(module, AID.SArcaneBlightA public abstract class C032Lala(WorldState ws, Actor primary) : BossModule(ws, primary, new(200, 0), new ArenaBoundsSquare(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12639, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12639, SortOrder = 8, PlanLevel = 90)] public class C032NLala(WorldState ws, Actor primary) : C032Lala(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12639, SortOrder = 8)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12639, SortOrder = 8, PlanLevel = 90)] public class C032SLala(WorldState ws, Actor primary) : C032Lala(ws, primary); diff --git a/BossMod/Modules/Endwalker/Criterion/C03AAI/C033Statice/C033Statice.cs b/BossMod/Modules/Endwalker/Criterion/C03AAI/C033Statice/C033Statice.cs index 9f37f9961..99a538bef 100644 --- a/BossMod/Modules/Endwalker/Criterion/C03AAI/C033Statice/C033Statice.cs +++ b/BossMod/Modules/Endwalker/Criterion/C03AAI/C033Statice/C033Statice.cs @@ -12,8 +12,8 @@ class SFaerieRing(BossModule module) : FaerieRing(module, AID.SFaerieRing); public abstract class C033Statice(WorldState ws, Actor primary) : BossModule(ws, primary, new(-200, 0), new ArenaBoundsCircle(20)); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12506, SortOrder = 9)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.NBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 979, NameID = 12506, SortOrder = 9, PlanLevel = 90)] public class C033NStatice(WorldState ws, Actor primary) : C033Statice(ws, primary); -[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12506, SortOrder = 9)] +[ModuleInfo(BossModuleInfo.Maturity.Verified, PrimaryActorOID = (uint)OID.SBoss, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 980, NameID = 12506, SortOrder = 9, PlanLevel = 90)] public class C033SStatice(WorldState ws, Actor primary) : C033Statice(ws, primary); From 725b82eca317998a6c49e6788bc58a8aa01664f4 Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:44:27 -0400 Subject: [PATCH 03/19] funny bridge --- .../Dungeon/D02DohnMheg/D023AencThon.cs | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs new file mode 100644 index 000000000..3601f3ef6 --- /dev/null +++ b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs @@ -0,0 +1,131 @@ +namespace BossMod.Shadowbringers.Dungeon.D02DohnMheg.D023AencThon; + +public enum OID : uint +{ + Boss = 0xF14, // R=2.5-6.875 + LiarsLyre = 0xF63, // R=2.5 + Helper = 0x233C +} + +public enum AID : uint +{ + AutoAttack = 870, // Boss->player, no cast, single-target + AutoAttack2 = 872, // Boss->player, no cast, single-target + Teleport = 13206, // Boss->location, no cast, single-target + + CripplingBlow = 13732, // Boss->player, 4.0s cast, single-target + VirtuosicCapriccio = 13708, // Boss->self, 5.0s cast, range 80+R circle + ImpChoir = 13552, // Boss->self, 4.0s cast, range 80+R circle + ToadChoir = 13551, // Boss->self, 4.0s cast, range 17+R 120-degree cone + + FunambulistsFantasia = 13498, // Boss->self, 4.0s cast, single-target, changes arena to planks over a chasm + FunambulistsFantasiaPull = 13519, // Helper->self, 4.0s cast, range 50 circle, pull 50, between hitboxes + + ChangelingsFantasia = 13521, // Boss->self, 3.0s cast, single-target + ChangelingsFantasia2 = 13522, // Helper->self, 1.0s cast, single-target + + Malaise = 13549, // Boss->self, no cast, single-target + BileBombardment = 13550, // Helper->location, 4.0s cast, range 8 circle + CorrosiveBileFirst = 13547, // Boss->self, 4.0s cast, range 18+R 120-degree cone + CorrosiveBileRest = 13548, // Helper->self, no cast, range 18+R 120-degree cone + FlailingTentaclesVisual = 13952, // Boss->self, 5.0s cast, single-target + FlailingTentacles = 13953, // Helper->self, no cast, range 32+R width 7 rect + + Finale = 15723, // LiarsLyre->self, 60.0s cast, single-target + FinaleEnrage = 13520 // Boss->self, 60.0s cast, range 80+R circle +} + +public enum SID : uint +{ + Bleeding = 273, // Boss->player, extra=0x0 + Imp = 1134, // Boss->player, extra=0x30 + Toad = 439, // Boss->player, extra=0x1 + Stun = 149, // Helper->player, extra=0x0 + Staggered = 715, // Helper->player, extra=0xECA + FoolsTightrope = 385, // Boss->Boss/LiarsLyre, extra=0x0 + FoolsTumble = 387, // none->player, extra=0x1823 + Unfooled = 386, // none->player, extra=0x0 + FoolsFigure = 388 // none->Boss, extra=0x123 +} + +class CripplingBlow(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.CripplingBlow)); +class VirtuosicCapriccio(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.VirtuosicCapriccio)); +class ImpChoir(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ImpChoir)); +class ToadChoir(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ToadChoir), new AOEShapeCone(19.5f, 60.Degrees())); +class BileBombardment(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.BileBombardment), 8); + +internal class Bounds(BossModule module) : BossComponent(module) +{ + private bool Bridge = false; + + private static readonly List tightrope = + [ + new(-142.32f, -233.89f), new(-140.6f, -245.85f), new(-129.91f, -241.9f), new(-113.72f, -243.84f), + new(-113.81f, -244.74f), new(-125.19f, -249.54f), new(-123.72f, -254.08f), new(-124.58f, -254.05f), + new(-126.13f, -249.73f), new(-126.39f, -249.05f), + new(-115.51f, -244.47f), new(-129.9f, -242.73f), new(-140.47f, -246.47f), new(-141.19f, -246.74f), + new(-143.12f, -233.92f) + ]; + + private void Activate() + { + Bridge = true; + Arena.Bounds = BuildHoleBounds(); + } + + private void Deactivate() + { + Bridge = false; + Arena.Bounds = new ArenaBoundsCircle(19.5f); + } + + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + if (Bridge) + hints.RecommendedRangeToTarget = 0; + } + + public override void OnStatusLose(Actor actor, ActorStatus status) + { + if ((SID)status.ID == SID.FoolsTightrope) + Deactivate(); + } + + private ArenaBoundsCustom BuildHoleBounds() + { + var clipper = Module.Arena.Bounds.Clipper; + + var basic = new PolygonClipper.Operand(CurveApprox.Circle(19.5f, 0.01f)); + + var hole = new PolygonClipper.Operand(CurveApprox.Rect(new(20, 0), new(0, 10))); + var withHole = clipper.Difference(basic, hole); + + var rope = new RelSimplifiedComplexPolygon(tightrope.Select(t => t - Module.Arena.Center)); + + var final = clipper.Union(new(withHole), new(rope)); + return new(19.5f, final, 0.25f); + } + + public override void OnEventCast(Actor caster, ActorCastEvent spell) + { + if (spell.Action.ID == (uint)AID.FunambulistsFantasiaPull) + Activate(); + } +} + +internal class AencThonLordOfTheLengthsomeGaitStates : StateMachineBuilder +{ + public AencThonLordOfTheLengthsomeGaitStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.WIP, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 649, NameID = 8146)] +public class AencThonLordOfTheLengthsomeGait(WorldState ws, Actor primary) : BossModule(ws, primary, new(-128.5f, -244), new ArenaBoundsCircle(19.5f)); From 8527f053baece0dcc6a37b4429481a94e766e8b0 Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:46:01 -0400 Subject: [PATCH 04/19] enlarge toad --- .../Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs index 3601f3ef6..217fa6579 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs @@ -51,7 +51,7 @@ public enum SID : uint class CripplingBlow(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.CripplingBlow)); class VirtuosicCapriccio(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.VirtuosicCapriccio)); class ImpChoir(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ImpChoir)); -class ToadChoir(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ToadChoir), new AOEShapeCone(19.5f, 60.Degrees())); +class ToadChoir(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ToadChoir), new AOEShapeCone(19.5f, 75.Degrees())); class BileBombardment(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.BileBombardment), 8); internal class Bounds(BossModule module) : BossComponent(module) From 80b29185f86fdbd8c5bf4af9c7b6d3ac7d2b3bfd Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:52:08 -0400 Subject: [PATCH 05/19] fix module info --- .../Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs index 217fa6579..16111531b 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs @@ -56,7 +56,7 @@ class BileBombardment(BossModule module) : Components.LocationTargetedAOEs(modul internal class Bounds(BossModule module) : BossComponent(module) { - private bool Bridge = false; + private bool Bridge; private static readonly List tightrope = [ @@ -127,5 +127,5 @@ public AencThonLordOfTheLengthsomeGaitStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.WIP, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 649, NameID = 8146)] +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 649, NameID = 8146)] public class AencThonLordOfTheLengthsomeGait(WorldState ws, Actor primary) : BossModule(ws, primary, new(-128.5f, -244), new ArenaBoundsCircle(19.5f)); From 8efa32bf24619815734b8f640d79dd636d187c6f Mon Sep 17 00:00:00 2001 From: ace Date: Fri, 27 Sep 2024 07:08:39 -0700 Subject: [PATCH 06/19] ClassSCHUtility.cs fix --- BossMod/Autorotation/Utility/ClassSCHUtility.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/BossMod/Autorotation/Utility/ClassSCHUtility.cs b/BossMod/Autorotation/Utility/ClassSCHUtility.cs index 097a6f930..3b53bc16c 100644 --- a/BossMod/Autorotation/Utility/ClassSCHUtility.cs +++ b/BossMod/Autorotation/Utility/ClassSCHUtility.cs @@ -2,7 +2,7 @@ public sealed class ClassSCHUtility(RotationModuleManager manager, Actor player) : RoleHealerUtility(manager, player) { - public enum Track { WhisperingDawn = SharedTrack.Count, Adloquium, Succor, FeyIllumination, Lustrate, SacredSoil, Indomitability, DeploymentTactics, EmergencyTactics, Dissipation, Excogitation, Aetherpact, Recitation, FeyBlessing, Consolation, Protraction, Expedient, Seraphism, Resurrection, Summons, PetActions } + public enum Track { WhisperingDawn = SharedTrack.Count, Adloquium, Succor, FeyIllumination, Lustrate, SacredSoil, Indomitability, DeploymentTactics, EmergencyTactics, Dissipation, Excogitation, Aetherpact, Recitation, FeyBlessing, Consolation, Protraction, Expedient, Seraphism, Resurrection, Summons } public enum SuccorOption { None, Succor, Concitation } public enum DeployOption { None, Use, UseEx } public enum AetherpactOption { None, Use, End } @@ -81,7 +81,6 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa ExecuteSimple(strategy.Option(Track.EmergencyTactics), SCH.AID.EmergencyTactics, Player); ExecuteSimple(strategy.Option(Track.Dissipation), SCH.AID.Dissipation, Player); ExecuteSimple(strategy.Option(Track.Excogitation), SCH.AID.Excogitation, null); - ExecuteSimple(strategy.Option(Track.Aetherpact), SCH.AID.Aetherpact, null); ExecuteSimple(strategy.Option(Track.FeyBlessing), SCH.AID.FeyBlessing, Player); ExecuteSimple(strategy.Option(Track.Consolation), SCH.AID.Consolation, Player); ExecuteSimple(strategy.Option(Track.Protraction), SCH.AID.Protraction, null); @@ -104,7 +103,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa Hints.ActionsToExecute.Push(ActionID.MakeSpell(SCH.AID.DeploymentTactics), Player, deploy.Priority(), deploy.Value.ExpireIn); var pact = strategy.Option(Track.Aetherpact); - var pactAction = succ.As() switch + var pactAction = pact.As() switch { AetherpactOption.Use => SCH.AID.Aetherpact, AetherpactOption.End => SCH.AID.DissolveUnion, @@ -117,15 +116,15 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa if (recit.As() != RecitationOption.None) Hints.ActionsToExecute.Push(ActionID.MakeSpell(SCH.AID.Recitation), Player, recit.Priority(), recit.Value.ExpireIn); - var pet = strategy.Option(Track.PetActions); - var petAction = succ.As() switch + var pet = strategy.Option(Track.Summons); + var petSummons = pet.As() switch { PetOption.Eos => SCH.AID.SummonEos, PetOption.Seraph => SCH.AID.SummonSeraph, _ => default }; - if (petAction != default) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(petAction), Player, pet.Priority(), pet.Value.ExpireIn); + if (petSummons != default) + Hints.ActionsToExecute.Push(ActionID.MakeSpell(petSummons), Player, pet.Priority(), pet.Value.ExpireIn); } } From a3070711b4cd420512690eda479808047278f40e Mon Sep 17 00:00:00 2001 From: Leontopodium Nival Date: Fri, 27 Sep 2024 14:50:52 -0400 Subject: [PATCH 07/19] More DD Updates Orthos: -> Floor 20/40/60 Boss modules were added, gave some global as well pre-pull. POTD: -> Floor 80: Added a hint pre-pull telling players to stay close to him/where the cone AOE's are going to happen, need to go back and add a cast counter to give a hint on *-when-* it's going to though. -> Floor 100 boss now has a hint pre-pull to tell people to use resolution to kill the adds permanently/what HP% they spawn at -> Floor 140 removed un-necessary spacing -> floor 150 module created, not *-entirely-* happy with the zombies part (they jump onto you and just kinda hold you down if you get caught) gave them a persistantvoidzone for now, but feel like this could be improved on still, otherwise perfect --- .../EurekaOrthos/DD20CloningNode.cs | 103 ++++++++++++++++++ .../EurekaOrthos/DD40TwintaniasClone.cs | 97 +++++++++++++++++ .../DD60ServomechanicalMinotaur.cs | 56 +++++++--- .../PalaceOfTheDead/D100NybethObdilord.cs | 18 ++- .../DeepDungeon/PalaceOfTheDead/D140AhPuch.cs | 2 - .../PalaceOfTheDead/D150Tisiphone.cs | 74 +++++++++++++ .../DeepDungeon/PalaceOfTheDead/D80Gudanna.cs | 7 +- 7 files changed, 334 insertions(+), 23 deletions(-) create mode 100644 BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs create mode 100644 BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs create mode 100644 BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D150Tisiphone.cs diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs new file mode 100644 index 000000000..585aec87a --- /dev/null +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD20CloningNode.cs @@ -0,0 +1,103 @@ +namespace BossMod.Endwalker.DeepDungeon.EurekaOrthos.DD20CloningNode; + +public enum OID : uint +{ + Boss = 0x3E77, // R6.0 + ClonedShieldDragon = 0x3E78, // R3.445 + Helper = 0x233C +} + +public enum AID : uint +{ + AutoAttack = 32817, // Boss->player, no cast, single-target + Teleport = 32554, // ClonedShieldDragon->location, no cast, single-target + + FlameBreath = 32864, // Helper->self, 3.5s cast, range 50 30-degree cone + FlameBreathVisual1 = 32544, // ClonedShieldDragon->self, 2.0+1,5s cast, single-target + FlameBreathVisual2 = 32553, // ClonedShieldDragon->self, no cast, single-target + FlameBreathVisual3 = 32552, // ClonedShieldDragon->self, no cast, single-target + OffensiveCommand = 32543, // Boss->self, 5.0s cast, single-target + OrderRelay = 32545, // Boss->self, 8.0s cast, single-target // problematic child + PiercingLaser = 32547, // Boss->self, 2.5s cast, range 40 width 5 rect +} +class PiercingLaser(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.PiercingLaser), new AOEShapeRect(40, 2.5f)); +class FlameBreath(BossModule module) : Components.GenericAOEs(module) +{ + private readonly List _aoes = []; + private static readonly AOEShapeCone cone = new(50, 15.Degrees()); + private static readonly float intercardinalDistance = 16 * MathF.Sqrt(2); + private static readonly Angle[] AnglesIntercardinals = [-45.003f.Degrees(), 44.998f.Degrees(), 134.999f.Degrees(), -135.005f.Degrees()]; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) + { + if (_aoes.Count > 0) + foreach (var a in _aoes) + if ((a.Activation - _aoes[0].Activation).TotalSeconds <= 1) + yield return a; + } + + public override void OnEventCast(Actor caster, ActorCastEvent spell) + { + if ((AID)spell.Action.ID == AID.FlameBreathVisual3) + { + var activation = WorldState.FutureTime(9.6f); + + if ((caster.Position - Arena.Center).LengthSq() > 625) + _aoes.Add(new(cone, CalculatePosition(caster), caster.Rotation, activation)); + else + _aoes.Add(new(cone, RoundPosition(caster.Position), caster.Rotation, activation)); + } + } + + public override void OnCastFinished(Actor caster, ActorCastInfo spell) + { + if (_aoes.Count > 0 && (AID)spell.Action.ID == AID.FlameBreath) + _aoes.RemoveAt(0); + } + + private static WPos CalculatePosition(Actor caster) + { + var isIntercardinal = IsCasterIntercardinal(caster); + var distance = isIntercardinal ? intercardinalDistance : 22; + var position = caster.Position + distance * caster.Rotation.ToDirection(); + return RoundPosition(position); + } + + private static bool IsCasterIntercardinal(Actor caster) + { + foreach (var angle in AnglesIntercardinals) + if (caster.Rotation.AlmostEqual(angle, Angle.DegToRad)) + return true; + return false; + } + + private static WPos RoundPosition(WPos position) => new(MathF.Round(position.X * 2) / 2, MathF.Round(position.Z * 2) / 2); +} + +class EncounterHints(BossModule module) : BossComponent(module) +{ + public override void AddGlobalHints(GlobalHints hints) + { + hints.Add($"{Module.PrimaryActor.Name} will tether to the clones on the edge of the arena. Those are the dragons that will be casting a cone.\nAfter a certain point, the boss will tether x2 sets of adds, find the first safe spot, rotate into the next."); + } +} + +class DD20CloningNodeStates : StateMachineBuilder +{ + public DD20CloningNodeStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 898, NameID = 12261)] +public class DD20CloningNode : BossModule +{ + public DD20CloningNode(WorldState ws, Actor primary) : base(ws, primary, new(-300, -300), new ArenaBoundsCircle(19.5f)) + { + ActivateComponent(); + } +} diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs new file mode 100644 index 000000000..0dbd88cf6 --- /dev/null +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD40TwintaniasClone.cs @@ -0,0 +1,97 @@ +namespace BossMod.Endwalker.DeepDungeon.EurekaOrthos.DD40TwintaniasClone; + +public enum OID : uint +{ + Boss = 0x3D1D, // R6.0 + Twister = 0x1E8910, // R0.5 + BitingWind = 0x3D1E, // R1.0 + Helper = 0x233C +} + +public enum AID : uint +{ + AutoAttack = 6497, // Boss->player, no cast, single-target + + BitingWind = 31464, // BitingWind->self, no cast, range 5 circle + Gust = 31463, // Helper->location, 4.0s cast, range 5 circle + MeracydianCyclone = 31462, // Boss->self, 3.0s cast, single-target + MeracydianSquall = 31466, // Helper->location, 5.0s cast, range 5 circle + MeracydianSquallVisual = 31465, // Boss->self, 3.0s cast, single-target + Turbine = 31467, // Boss->self, 6.0s cast, range 60 circle, knockback 15, away from source + TwisterTouch = 31470, // Helper->player, no cast, single-target, player got hit by twister + TwisterVisual = 31468, // Boss->self, 5.0s cast, single-target + TwistingDive = 31471 // Boss->self, 5.0s cast, range 50 width 15 rect +} + +class Twister(BossModule module) : Components.CastTwister(module, 1, (uint)OID.Twister, ActionID.MakeSpell(AID.TwisterVisual), 0.4f, 0.25f); +class BitingWind(BossModule module) : Components.PersistentVoidzoneAtCastTarget(module, 5, ActionID.MakeSpell(AID.BitingWind), m => m.Enemies(OID.BitingWind).Where(z => z.EventState != 7), 0.9f); +class MeracydianSquall(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.MeracydianSquall), 5); +class TwistersHint(BossModule module, AID aid) : Components.CastHint(module, ActionID.MakeSpell(aid), "Twisters spawning, keep moving!"); +class Twisters1(BossModule module) : TwistersHint(module, AID.TwisterVisual); +class Twisters2(BossModule module) : TwistersHint(module, AID.TwistingDive); + +class TwistingDive(BossModule module) : Components.GenericAOEs(module) +{ + private AOEInstance? _aoe; + private static readonly AOEShapeRect rect = new(50, 7.5f); + private bool preparing; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); + + public override void OnActorPlayActionTimelineEvent(Actor actor, ushort id) + { + if (actor == Module.PrimaryActor) + { + if (id == 0x1E3A) + preparing = true; + else if (preparing && id == 0x1E43) + _aoe = new(rect, actor.Position, actor.Rotation, WorldState.FutureTime(6.9f)); + } + } + + public override void OnCastFinished(Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.TwistingDive) + { + _aoe = null; + preparing = false; + } + } +} + +class Turbine(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.Turbine), 15) +{ + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + var forbidden = new List>(); + var component = Module.FindComponent()?.ActiveAOEs(slot, actor)?.ToList(); + var source = Sources(slot, actor).FirstOrDefault(); + if (source != default && component != null) + { + forbidden.Add(ShapeDistance.InvertedCircle(Arena.Center, 5)); + forbidden.AddRange(component.Select(c => ShapeDistance.Cone(Arena.Center, 20, Angle.FromDirection(c.Origin - Arena.Center), 20.Degrees()))); + if (forbidden.Count > 0) + hints.AddForbiddenZone(p => forbidden.Select(f => f(p)).Min(), source.Activation); + } + } + + public override bool DestinationUnsafe(int slot, Actor actor, WPos pos) => (Module.FindComponent()?.ActiveAOEs(slot, actor).Any(z => z.Shape.Check(pos, z.Origin, z.Rotation)) ?? false) || !Module.InBounds(pos); +} + +class DD40TwintaniasCloneStates : StateMachineBuilder +{ + public DD40TwintaniasCloneStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 900, NameID = 12263)] +public class DD40TwintaniasClone(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600, -300), new ArenaBoundsCircle(20)); diff --git a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur.cs b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur.cs index 150322625..8991f465a 100644 --- a/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur.cs +++ b/BossMod/Modules/Endwalker/DeepDungeon/EurekaOrthos/DD60ServomechanicalMinotaur.cs @@ -10,25 +10,54 @@ public enum OID : uint public enum AID : uint { AutoAttack = 6499, // Boss->player, no cast, single-target - //Weaponskill_ = 31867, // Helper->self, 1.0s cast, range 40 ?-degree cone // Displays the order of the aoe's going off - OctupleSwipe = 31872, // Boss->self, 10.8s cast, range 40 ?-degree cone // Windup Cast for N/E/S/W - BullishSwipe4 = 31871, // Boss->self, no cast, range 40 ?-degree cone - BullishSwipe3 = 31870, // Boss->self, no cast, range 40 ?-degree cone - BullishSwipe2 = 31869, // Boss->self, no cast, range 40 ?-degree cone + BullishSwing = 31875, // Boss->self, 5.0s cast, range 13 circle, PB Circle AOE + BullishSwipeSingle = 32795, // Boss->self, 5.0s cast, range 40 90-degree cone, usually used after KB to try and catch off guard + DisorientingGroan = 31876, // Boss->self, 5.0s cast, range 60 circle, 15 yalm KB + Shock = 31874, // BallOfLevin->self, 2.5s cast, range 5 circle // Cast, but going to be a persistent void zone + Thundercall = 31873, // Boss->self, 5.0s cast, range 60 circle + + // Boss telegraphs with the helper, then cast Swipes 1-4 in a pattern. (Either same pattern twice, or 1-4 -> 4->1) BullishSwipe1 = 31868, // Boss->self, no cast, range 40 ?-degree cone - DisorientingGroan = 31876, // Boss->self, 5.0s cast, range 60 circle, 15 yalm KB // done - BullishSwipeSingle = 32795, // Boss->self, 5.0s cast, range 40 90-degree cone, usually used after KB to try and catch off guard // done - Thundercall = 31873, // Boss->self, 5.0s cast, range 60 circle - Shock = 31874, // BallOfLevin->self, 2.5s cast, range 5 circle - BullishSwing = 31875, // Boss->self, 5.0s cast, range 13 circle, PB Circle AOE // done + BullishSwipe2 = 31869, // Boss->self, no cast, range 40 ?-degree cone + BullishSwipe3 = 31870, // Boss->self, no cast, range 40 ?-degree cone + BullishSwipe4 = 31871, // Boss->self, no cast, range 40 ?-degree cone + OctupleSwipe = 31872, // Boss->self, 10.8s cast, range 40 ?-degree cone // Windup Cast for N/E/S/W + OctupleSwipeTelegraph = 31867, // Helper->self, 1.0s cast, range 40 ?-degree cone // Displays the order of the aoe's going off } class BullishSwing(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.BullishSwing), new AOEShapeCircle(13)); class BullishSwipeSingle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.BullishSwipeSingle), new AOEShapeCone(40, 45.Degrees())); class DisorientingGroan(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.DisorientingGroan), 15, true); -class Shock(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Shock), new AOEShapeCircle(5)); +class Shock(BossModule module) : Components.PersistentVoidzone(module, 5, m => m.Enemies(OID.BallOfLevin)); +class Thundercall(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Thundercall), "Raidwide + Summoning Orbs"); + +class OctupleSwipe(BossModule module) : Components.GenericAOEs(module) +{ + private readonly List _aoes = []; + private static readonly AOEShapeCone cone = new(40, 45.Degrees()); + private static readonly HashSet castEnd = [AID.OctupleSwipe, AID.BullishSwipe1, AID.BullishSwipe2, AID.BullishSwipe3, AID.BullishSwipe4]; + + public override IEnumerable ActiveAOEs(int slot, Actor actor) + { + if (_aoes.Count > 0) + yield return _aoes[0] with { Color = ArenaColor.Danger }; + if (_aoes.Count > 1) + for (var i = 1; i < Math.Clamp(_aoes.Count, 0, 3); ++i) + yield return _aoes[i]; + } + + public override void OnCastStarted(Actor caster, ActorCastInfo spell) + { + if ((AID)spell.Action.ID == AID.OctupleSwipeTelegraph) + _aoes.Add(new(cone, caster.Position, spell.Rotation, _aoes.Count == 0 ? Module.CastFinishAt(spell, 8.7f + 2 * _aoes.Count) : _aoes[0].Activation.AddSeconds(_aoes.Count * 2))); + } -// Need to figure out how to telegraph the 8 cleaves going off still + public override void OnEventCast(Actor caster, ActorCastEvent spell) + { + if (_aoes.Count > 0 && castEnd.Contains((AID)spell.Action.ID)) + _aoes.RemoveAt(0); + } +} class DD60ServomechanicalMinotaurStates : StateMachineBuilder { @@ -38,9 +67,10 @@ public DD60ServomechanicalMinotaurStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() + .ActivateOnEnter() .ActivateOnEnter(); } } -[ModuleInfo(BossModuleInfo.Maturity.WIP, Contributors = "Puni.sh Team", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 902, NameID = 12267)] +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 902, NameID = 12267)] public class DD60ServomechanicalMinotaur(WorldState ws, Actor primary) : BossModule(ws, primary, new(-600, -300), new ArenaBoundsCircle(20)); diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs index 6fa4662a0..db1076396 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D100NybethObdilord.cs @@ -15,10 +15,10 @@ public enum AID : uint Abyss = 6872, // Boss->player, 2.0s cast, range 6 circle // kinda like a tankbuster? It's a circle on the player ButterflyFloat = 6879, // IronCorse->player, 3.0s cast, single-target Catapult = 6878, // BicephalicCorse->location, 3.0s cast, range 6 circle - Doom = 6875, // Boss->self, 5.0s cast, range 45+R 120-degree cone, feels like this is wrong, + Doom = 6875, // Boss->self, 5.0s cast, range 45+R 120-degree cone, feels like this is wrong, GlassPunch = 6877, // GiantCorse/BicephalicCorse->self, no cast, range 6+R ?-degree cone Shackle = 6874, // Boss->self, 3.0s cast, range 50+R width 8 rect - SummonDarkness = 6876, // Boss->self, 3.0s cast, ???, Summons Corse's, + SummonDarkness = 6876, // Boss->self, 3.0s cast, ???, Summons Corse's, WordOfPain = 6873, // Boss->self, no cast, range 40+R circle } @@ -27,13 +27,13 @@ class Catapult(BossModule module) : Components.LocationTargetedAOEs(module, Acti class CorseAdds(BossModule module) : Components.AddsMulti(module, [(uint)OID.BicephalicCorse, (uint)OID.GiantCorse, (uint)OID.IronCorse]); class Doom(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Doom), new AOEShapeCone(47.4f, 60.Degrees())); class Shackle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Shackle), new AOEShapeRect(52.4f, 4, 0)); -class SummonDarkness(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SummonDarkness), "Summoning the corses, incoming Adds!"); +class SummonDarkness(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.SummonDarkness), "Summoning the corse, incoming Adds! \nRemember to use a resolution to make them permanently disappear"); class EncounterHints(BossModule module) : BossComponent(module) { public override void AddGlobalHints(GlobalHints hints) { - hints.Add($"There is 3 sets of adds that spawn at HP %'s -> (90%, 65%, 40%) \nA resolution can make the adds permanently dissapear once they are at 0% HP/the corpse are just laying on the floor.\nResolution is also does high damage to the adds + 0.3% to the Boss\nSolo tip: Either pop a resolution on all add packs, or pop lust -> resolution on 2nd ad pack. Make sure to keep regen up!"); + hints.Add($"There is 3 sets of adds that spawn at HP %'s -> (90%, 65%, 40%) \nA resolution can make the adds permanently disappear once they are at 0% HP/the corpse are just laying on the floor.\nResolution is also does high damage to the adds + 0.3% to the Boss\nSolo tip: Either pop a resolution on all add packs, or pop lust -> resolution on 2nd ad pack. Make sure to keep regen up!"); } } @@ -48,9 +48,15 @@ public D100NybethObdilordStates(BossModule module) : base(module) .ActivateOnEnter() .ActivateOnEnter() .ActivateOnEnter() - .ActivateOnEnter(); + .DeactivateOnEnter(); } } [ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 208, NameID = 5356)] -public class D100NybethObdilord(WorldState ws, Actor primary) : BossModule(ws, primary, new(300, 300), new ArenaBoundsCircle(24)); +public class D100NybethObdilord : BossModule +{ + public D100NybethObdilord(WorldState ws, Actor primary) : base(ws, primary, new(300, 300), new ArenaBoundsCircle(24)) + { + ActivateComponent(); + } +} diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs index 87ab3f3df..1cee369db 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D140AhPuch.cs @@ -38,8 +38,6 @@ class AncientEruptionZone(BossModule module) : Components.PersistentInvertibleVo class Scream(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Scream), "Raidwide + Fear, Adds need to be dead by now"); class ShadowFlare(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.ShadowFlare)); - - class D140AhPuchStates : StateMachineBuilder { public D140AhPuchStates(BossModule module) : base(module) diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D150Tisiphone.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D150Tisiphone.cs new file mode 100644 index 000000000..f8b38828c --- /dev/null +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D150Tisiphone.cs @@ -0,0 +1,74 @@ +namespace BossMod.Modules.Heavensward.DeepDungeon.PalaceOfTheDead.D150Tisiphone; + +public enum OID : uint +{ + Boss = 0x181C, // R2.000, x1 + FanaticGargoyle = 0x18EB, // R2.300, x0 (spawn during fight) + FanaticSuccubus = 0x18EE, // R1.000, x0 (spawn during fight) + FanaticVodoriga = 0x18EC, // R1.200, x0 (spawn during fight) + FanaticZombie = 0x18ED, // R0.500, x0 (spawn during fight) +} + +public enum AID : uint +{ + AutoAttack = 6497, // Boss/FanaticSuccubus->player, no cast, single-target + BloodRain = 7153, // Boss->location, 5.0s cast, range 100 circle + BloodSword = 7111, // Boss->FanaticSuccubus, no cast, single-target + DarkMist = 7108, // Boss->self, 3.0s cast, range 8+R circle + Desolation = 7112, // FanaticGargoyle->self, 4.0s cast, range 55+R(57.3) width 6 rect + FatalAllure = 7110, // Boss->FanaticSuccubus, 2.0s cast, single-target, sucks the HP that remained off the FanaticSuccubus and transfers it to boss + SummonDarkness = 7107, // Boss->self, no cast, single-target + SweetSteel = 7148, // FanaticSuccubus->self, no cast, range 6+R(7) 90?-degree cone, currently a safe bet on the cone angel, needs to be confirmed + TerrorEye = 7113, // FanaticVodoriga->location, 4.0s cast, range 6 circle + VoidAero = 7177, // Boss->self, 3.0s cast, range 40+R(42.3) width 8 rect + VoidFireII = 7150, // FanaticSuccubus->location, 3.0s cast, range 5 circle + VoidFireIV = 7109, // Boss->location, 3.5s cast, range 10 circle +} + +class BloodRain(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.BloodRain), "Heavy Raidwide damage! Also killing any add that is currently up"); +class BossAdds(BossModule module) : Components.AddsMulti(module, [(uint)OID.FanaticZombie, (uint)OID.FanaticSuccubus]); +class DarkMist(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.DarkMist), new AOEShapeCircle(10)); +class Desolation(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Desolation), new AOEShapeRect(57.3f, 3)); +class FatalAllure(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.FatalAllure), "Boss is life stealing from the succubus"); +class SweetSteel(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SweetSteel), new AOEShapeCone(7, 45.Degrees())); +class TerrorEye(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.TerrorEye), 6); +class VoidFireII(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.VoidFireII), 5); +class VoidFireIV(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.VoidFireIV), 10); +class ZombieGrab(BossModule module) : Components.PersistentVoidzone(module, 2, m => m.Enemies(OID.FanaticZombie)); // Future note to Ice(self): Not entirely sure if I'm happy with this per se? It shows to essentially stay away from the zombies but, maybe a better hint when I can think of one + +class EncounterHints(BossModule module) : BossComponent(module) +{ + public override void AddGlobalHints(GlobalHints hints) + { + hints.Add($"{Module.PrimaryActor.Name} will spawn 4 zombies, you can either kite them or kill them. The BloodRain raidwide will also kill them if they're still alive. \nThe boss will also life-steal however much HP is left of the Succubus, you're choice if you want to kill it or not."); + } +} + +class D150TisiphoneStates : StateMachineBuilder +{ + public D150TisiphoneStates(BossModule module) : base(module) + { + TrivialPhase() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .ActivateOnEnter() + .DeactivateOnEnter(); + } +} + +[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "LegendofIceman", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 213, NameID = 5424)] +//public class D150Tisiphone(WorldState ws, Actor primary) : BossModule(ws, primary, new(-300, -237.17f), new ArenaBoundsCircle(24)); +public class D150Tisiphone : BossModule +{ + public D150Tisiphone(WorldState ws, Actor primary) : base(ws, primary, new(-300, -237.17f), new ArenaBoundsCircle(24)) + { + ActivateComponent(); + } +} diff --git a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D80Gudanna.cs b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D80Gudanna.cs index 28a4dd6f2..ec7a9f4cb 100644 --- a/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D80Gudanna.cs +++ b/BossMod/Modules/Heavensward/DeepDungeon/PalaceOfTheDead/D80Gudanna.cs @@ -10,7 +10,7 @@ public enum OID : uint public enum AID : uint { Attack = 6497, // Boss->player, no cast, single-target - Charybdis = 7096, // Boss->location, 3.0s cast, range 6 circle // Cast that sets the tornado location + Charybdis = 7096, // Boss->location, 3.0s cast, range 6 circle // Cast that sets the tornado location TornadoVoidzone = 7164, // 18F0->self, no cast, range 6 circle EclipticMeteor = 7099, // Boss->self, 20.0s cast, range 50 circle Maelstrom = 7167, // 18F0->self, 1.3s cast, range 10 circle @@ -24,11 +24,14 @@ class Maelstrom(BossModule module) : Components.PersistentVoidzone(module, 10, m class EclipticMeteor(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.EclipticMeteor), "Kill him before he kills you! 80% max HP damage incoming!"); class Thunderbolt(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.Thunderbolt), new AOEShapeCone(16.6f, 60.Degrees())); +// things to do: +// add a hint counter to tell the player where the boss is going to cast Trounce next +// It's always East wall -> West wall -> East... ect class Hints(BossModule module) : BossComponent(module) { public override void AddGlobalHints(GlobalHints hints) { - hints.Add($"{Module.PrimaryActor.Name} will use Ecliptic Meteor.\nYou must either kill him before he cast it multiple times, or heal through it."); + hints.Add($"{Module.PrimaryActor.Name} will cast Trounce (Cone AOE) from the East and West wall. \nMake sure to stay near him to dodge the AOE. \n{Module.PrimaryActor.Name} will also cast Ecliptic Meteor at 10% HP, plan accordingly!"); } } From 96385e72356ca2e3a0d02a6c2b2c3cb7cad7f315 Mon Sep 17 00:00:00 2001 From: xanunderscore <149614526+xanunderscore@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:46:17 -0400 Subject: [PATCH 08/19] Update MNK.cs --- BossMod/Autorotation/xan/Melee/MNK.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Autorotation/xan/Melee/MNK.cs b/BossMod/Autorotation/xan/Melee/MNK.cs index 6191ecfe9..0d217440d 100644 --- a/BossMod/Autorotation/xan/Melee/MNK.cs +++ b/BossMod/Autorotation/xan/Melee/MNK.cs @@ -416,7 +416,7 @@ private void WindsReply() } private float DesiredFireWindow => GCDLength * 10; - private float EarliestRoF(float estimatedDelay) => MathF.Max(estimatedDelay + 0.6f, 20.6f - DesiredFireWindow); + private float EarliestRoF(float estimatedDelay) => MathF.Max(estimatedDelay + 0.8f, 20.6f - DesiredFireWindow); private void Potion() => Hints.ActionsToExecute.Push(ActionDefinitions.IDPotionStr, Player, ActionQueue.Priority.Low + 100 + (float)OGCDPriority.Potion); From fc4f243a9eb9cbc621c7f2b72283d3a47a283e00 Mon Sep 17 00:00:00 2001 From: AceAkechi123 Date: Sat, 28 Sep 2024 00:45:49 -0700 Subject: [PATCH 09/19] tank dash fixes --- BossMod/Autorotation/Utility/ClassDRKUtility.cs | 2 +- BossMod/Autorotation/Utility/ClassGNBUtility.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BossMod/Autorotation/Utility/ClassDRKUtility.cs b/BossMod/Autorotation/Utility/ClassDRKUtility.cs index b779414c9..4f21fb6ce 100644 --- a/BossMod/Autorotation/Utility/ClassDRKUtility.cs +++ b/BossMod/Autorotation/Utility/ClassDRKUtility.cs @@ -74,7 +74,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa var dashStrategy = strategy.Option(Track.Shadowstride).As(); if (ShouldUseDash(dashStrategy, primaryTarget)) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), Player, obl.Priority()); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), primaryTarget, obl.Priority()); } private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch { diff --git a/BossMod/Autorotation/Utility/ClassGNBUtility.cs b/BossMod/Autorotation/Utility/ClassGNBUtility.cs index 65fe38203..bfcb69136 100644 --- a/BossMod/Autorotation/Utility/ClassGNBUtility.cs +++ b/BossMod/Autorotation/Utility/ClassGNBUtility.cs @@ -73,7 +73,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa var dashStrategy = strategy.Option(Track.Trajectory).As(); if (ShouldUseDash(dashStrategy, primaryTarget)) - Hints.ActionsToExecute.Push(ActionID.MakeSpell(GNB.AID.Trajectory), Player, hoc.Priority()); + Hints.ActionsToExecute.Push(ActionID.MakeSpell(GNB.AID.Trajectory), primaryTarget, hoc.Priority()); } private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch { From e482176ddddd5575a0086f80abda5376bf78173c Mon Sep 17 00:00:00 2001 From: VeraNala Date: Sat, 28 Sep 2024 11:49:18 -0600 Subject: [PATCH 10/19] ExtendRects --- .../Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs b/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs index 863ec838b..d12376d82 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs @@ -45,7 +45,7 @@ class SacredFlame(BossModule module) : Components.RaidwideCast(module, ActionID. class March(BossModule module) : Components.GenericAOEs(module) { private readonly List _knights = []; - private static readonly AOEShapeRect rect = new(8, 2, -1); + private static readonly AOEShapeRect rect = new(12, 2, -1); private static readonly AOEShapeCircle circ = new(2.5f); public override IEnumerable ActiveAOEs(int slot, Actor actor) { From 16229ce09147c758b0e77254e1e593fe87c603de Mon Sep 17 00:00:00 2001 From: VeraNala Date: Sat, 28 Sep 2024 12:32:45 -0600 Subject: [PATCH 11/19] Add Capsule ForbiddenZone to March --- .../Heavensward/Dungeon/D04Vault/D043SerCharibert.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs b/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs index d12376d82..61b964309 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D04Vault/D043SerCharibert.cs @@ -69,6 +69,14 @@ public override void OnActorDestroyed(Actor actor) _knights.Remove(actor); } } + public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) + { + foreach (var b in _knights) + { + hints.AddForbiddenZone(ShapeDistance.Capsule(b.Position, b.Rotation.ToDirection(), 12, 2)); + hints.AddForbiddenZone(ShapeDistance.Circle(b.Position, 2.5f)); + } + } }; class AddsModule(BossModule module) : Components.Adds(module, (uint)OID.HolyFlame) { From 2e478fbc71b6ed8bdd56ce2713170d21893da226 Mon Sep 17 00:00:00 2001 From: VeraNala Date: Sat, 28 Sep 2024 13:28:00 -0600 Subject: [PATCH 12/19] Update D053EverlivingBibliotaph.cs --- .../D05GreatGubalLibrary/D053EverlivingBibliotaph.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/BossMod/Modules/Heavensward/Dungeon/D05GreatGubalLibrary/D053EverlivingBibliotaph.cs b/BossMod/Modules/Heavensward/Dungeon/D05GreatGubalLibrary/D053EverlivingBibliotaph.cs index 3badd759a..6e155fe94 100644 --- a/BossMod/Modules/Heavensward/Dungeon/D05GreatGubalLibrary/D053EverlivingBibliotaph.cs +++ b/BossMod/Modules/Heavensward/Dungeon/D05GreatGubalLibrary/D053EverlivingBibliotaph.cs @@ -109,7 +109,7 @@ public override void OnActorDestroyed(Actor actor) if ((OID)actor.OID is OID.SummonPad) { _pads.Remove(actor); - _towers.RemoveAll(t => t.Position.AlmostEqual(actor.Position, 1)); + _towers.RemoveAll(t => t.Position.AlmostEqual(actor.Position, 0.5f)); } } @@ -139,23 +139,23 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme var maxEval = -1; foreach (var t in _towers) { - var curEval = Raid.WithSlot().InRadius(t.Position, 2).Count(); + var curEval = Raid.WithSlot().InRadius(t.Position, 1.5f).Count(); if (curEval > maxEval) { maxEval = curEval; bestTower = t; } } - var curSoakers = Raid.WithSlot().InRadius(bestTower.Position, 2).Count(); + var curSoakers = Raid.WithSlot().InRadius(bestTower.Position, 1.5f).Count(); if (minSoakers == 3 && curSoakers == 2 || minSoakers == 2 && curSoakers == 1 || minSoakers == 1 && curSoakers == 0) { - hints.AddForbiddenZone(new AOEShapeDonut(2, 50), bestTower.Position); + hints.AddForbiddenZone(new AOEShapeDonut(1.5f, 50), bestTower.Position); } else if (curSoakers < minSoakers) { - hints.AddForbiddenZone(new AOEShapeDonut(2, 50), bestTower.Position); + hints.AddForbiddenZone(new AOEShapeDonut(1.5f, 50), bestTower.Position); } else _towers.Remove(bestTower); From 700af1008ad6b9260165fdc3345a7e68ad43751d Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 13:05:42 +0100 Subject: [PATCH 13/19] Some a-rank bugfixes. --- BossMod/Modules/Dawntrail/Hunt/RankA/Heshuala.cs | 2 +- BossMod/Modules/Dawntrail/Hunt/RankA/SallyTheSweeper.cs | 4 +++- TODO | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/BossMod/Modules/Dawntrail/Hunt/RankA/Heshuala.cs b/BossMod/Modules/Dawntrail/Hunt/RankA/Heshuala.cs index 833ce4bcb..a154b6db6 100644 --- a/BossMod/Modules/Dawntrail/Hunt/RankA/Heshuala.cs +++ b/BossMod/Modules/Dawntrail/Hunt/RankA/Heshuala.cs @@ -79,7 +79,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) if (offset != default) { for (int i = 0; i < _numCharges; ++i) - _aoes.Add(new(_shapeSpinshock, caster.Position, spell.Rotation + i * 90.Degrees(), Module.CastFinishAt(spell, i * 2.7f))); + _aoes.Add(new(_shapeSpinshock, caster.Position, spell.Rotation + i * offset, Module.CastFinishAt(spell, i * 2.7f))); _aoes.Add(new(_shapeCross, caster.Position, spell.Rotation + _crossOffset, Module.CastFinishAt(spell, _numCharges * 2.7f + 3.7f))); } } diff --git a/BossMod/Modules/Dawntrail/Hunt/RankA/SallyTheSweeper.cs b/BossMod/Modules/Dawntrail/Hunt/RankA/SallyTheSweeper.cs index 989811ccf..6dec563d1 100644 --- a/BossMod/Modules/Dawntrail/Hunt/RankA/SallyTheSweeper.cs +++ b/BossMod/Modules/Dawntrail/Hunt/RankA/SallyTheSweeper.cs @@ -27,6 +27,7 @@ class ExecutionModel(BossModule module) : Components.GenericAOEs(module) private readonly List _shapes = []; private bool _reverse; private DateTime _activation; + private Angle _rotation; private static readonly AOEShapeCircle _shapeCircle = new(10); private static readonly AOEShapeDonut _shapeDonut = new(10, 40); @@ -35,7 +36,7 @@ class ExecutionModel(BossModule module) : Components.GenericAOEs(module) public override IEnumerable ActiveAOEs(int slot, Actor actor) { if (_activation != default && _shapes.Count > 0) - yield return new(_shapes[_reverse ? ^1 : 0], Module.PrimaryActor.Position, Module.PrimaryActor.Rotation, _activation); + yield return new(_shapes[_reverse ? ^1 : 0], Module.PrimaryActor.Position, _rotation, _activation); } public override void OnCastStarted(Actor caster, ActorCastInfo spell) @@ -50,6 +51,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell) break; case AID.ExecutionModelCross: _shapes.Add(_shapeCross); + _rotation = spell.Rotation; break; case AID.CodeExecutionFirstCircle: case AID.CodeExecutionFirstDonut: diff --git a/TODO b/TODO index fa547df35..43cf26261 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ immediate plans +- nechuciho - seen incorrect rotations... - merge prs! - collisions for pathfinding - brd rotation From a0c163e55110a8e62489b3acec7113ff693549ae Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 13:21:52 +0100 Subject: [PATCH 14/19] Fixes after merges. --- .../Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs | 5 ++++- TODO | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs index 16111531b..3c4a4e213 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs @@ -82,7 +82,10 @@ private void Deactivate() public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) { if (Bridge) - hints.RecommendedRangeToTarget = 0; + { + var goal = Module.PrimaryActor.Position; + hints.GoalZones.Add(p => (goal - p).LengthSq() < 0.25f ? 100 : 0); + } } public override void OnStatusLose(Actor actor, ActorStatus status) diff --git a/TODO b/TODO index 43cf26261..d409fd034 100644 --- a/TODO +++ b/TODO @@ -34,6 +34,7 @@ general: --- target is not a priority, but damaging it is a nice bonus (lower priority than max target) -- use that for targeting utils in aihints - debug utility to play action animations, spawn actors, play vfx, etc... +- encounter hints (to show before pull) boss modules: - timers From d3ca903fc639bc1e4574749e6676444a603d73d4 Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 13:52:03 +0100 Subject: [PATCH 15/19] Some tweaks to the changelog - still not sure about saving behaviour - don't like that new node appears in ui... --- ...ChangelogDisplay.cs => ConfigChangelog.cs} | 106 ++++++++---------- BossMod/Framework/Plugin.cs | 3 +- 2 files changed, 50 insertions(+), 59 deletions(-) rename BossMod/Config/{ChangelogDisplay.cs => ConfigChangelog.cs} (63%) diff --git a/BossMod/Config/ChangelogDisplay.cs b/BossMod/Config/ConfigChangelog.cs similarity index 63% rename from BossMod/Config/ChangelogDisplay.cs rename to BossMod/Config/ConfigChangelog.cs index 62854f5dc..80330f60a 100644 --- a/BossMod/Config/ChangelogDisplay.cs +++ b/BossMod/Config/ConfigChangelog.cs @@ -2,35 +2,46 @@ using ImGuiNET; using System.Reflection; -namespace BossMod.Config; +namespace BossMod; -public sealed class ChangelogProperties : ConfigNode +public sealed class ConfigChangelogProperties : ConfigNode { public Version BossModVersion { get; set; } = new(0, 0, 0, 0); } -public class ChangelogWindow(Version old, List fields) : UIWindow("VBM Changelog", false, new(400, 300)) +public sealed record class VersionedField(ConfigNode Node, FieldInfo FieldInfo, Version AddedVersion) { - private readonly List ProcessedFields = []; + public string FieldKey => $"{Node}.{FieldInfo.Name}"; +} - private void SetOption(VersionedField field, bool value) +public class ConfigChangelogWindow : UIWindow +{ + private readonly Version PreviousVersion; + private readonly List Fields; + + public ConfigChangelogWindow() : base("VBM Changelog", true, new(400, 300)) { - field.FieldInfo.SetValue(field.Node, value); - ProcessedFields.Add(field.FieldKey); - if (ProcessedFields.Count >= fields.Count) + var props = Service.Config.Get(); + PreviousVersion = GetPreviousPluginVersion(props); + props.BossModVersion = GetCurrentPluginVersion(); + + Fields = GetAllFields().Where(f => f.AddedVersion > PreviousVersion).ToList(); + if (Fields.Count == 0) { + // nothing interesting to show... IsOpen = false; - Service.Config.Modified.Fire(); + Dispose(); } } public override void Draw() { - ImGui.TextUnformatted($"The following config options have been added since version {old}:"); + ImGui.TextUnformatted($"The following config options have been added since version {PreviousVersion}:"); ImGui.Separator(); - foreach (var group in fields.Where(f => !ProcessedFields.Contains(f.FieldKey)).GroupBy(f => f.Node.GetType())) + Action? postIteration = null; + foreach (var group in Fields.GroupBy(f => f.Node.GetType())) { ImGui.TextUnformatted(group.Key.GetCustomAttribute()?.Name ?? ""); foreach (var f in group) @@ -46,44 +57,24 @@ public override void Draw() ImGui.TextUnformatted(disp?.Label ?? "unknown"); ImGui.SameLine(); if (ImGui.Button("Enable")) - { - SetOption(f, true); - return; - } + postIteration += () => SetOption(f, true); ImGui.SameLine(); if (ImGui.Button("Disable")) - { - SetOption(f, false); - return; - } + postIteration += () => SetOption(f, false); } } - } -} - -public record VersionedField(ConfigNode Node, FieldInfo FieldInfo, Version AddedVersion) -{ - public string FieldKey => $"{Node}.{FieldInfo.Name}"; -} - -public static class ChangelogDisplay -{ - private static Version GetCurrentPluginVersion() - { -#if DEBUG - // version is always 0.0.0.0 in debug, making it useless for testing - return new(0, 0, 0, 999); -#endif - return Assembly.GetExecutingAssembly().GetName().Version!; + postIteration?.Invoke(); } - private static Version GetPreviousPluginVersion(ChangelogProperties props) + private void SetOption(VersionedField field, bool value) { -#if DEBUG - // change value to something sensible if you want to test the changelog stuff - return new(0, 0, 0, 999); -#endif - return props.BossModVersion; + field.FieldInfo.SetValue(field.Node, value); + Fields.Remove(field); + if (Fields.Count == 0) + { + IsOpen = false; + Service.Config.Modified.Fire(); + } } private static IEnumerable GetAllFields() @@ -100,28 +91,29 @@ private static IEnumerable GetAllFields() if (sinceNode != null) yield return new(n, f, Version.Parse(sinceNode)); - else if (f.GetCustomAttribute()?.Since is string sinceVersion) yield return new(n, f, Version.Parse(sinceVersion)); } } } - public static void UpdateAndNotifyUser() + private static Version GetCurrentPluginVersion() { - var props = Service.Config.Get(); - var previousVersion = GetPreviousPluginVersion(props); - var currentVersion = GetCurrentPluginVersion(); - - props.BossModVersion = currentVersion; +#if DEBUG + // version is always 0.0.0.0 in debug, making it useless for testing + return new(0, 0, 0, 999); +#else + return Assembly.GetExecutingAssembly().GetName().Version!; +#endif + } - var fields = GetAllFields().Where(f => f.AddedVersion > previousVersion).ToList(); - if (fields.Count > 0) - { - var win = new ChangelogWindow(previousVersion, fields) - { - IsOpen = true - }; - } + private static Version GetPreviousPluginVersion(ConfigChangelogProperties props) + { +#if DEBUG + // change value to something sensible if you want to test the changelog stuff + return new(0, 0, 0, 999); +#else + return props.BossModVersion; +#endif } } diff --git a/BossMod/Framework/Plugin.cs b/BossMod/Framework/Plugin.cs index 64a9ae335..1ebaca353 100644 --- a/BossMod/Framework/Plugin.cs +++ b/BossMod/Framework/Plugin.cs @@ -1,5 +1,4 @@ using BossMod.Autorotation; -using BossMod.Config; using Dalamud.Common; using Dalamud.Game; using Dalamud.Game.ClientState.Conditions; @@ -99,7 +98,7 @@ public unsafe Plugin(IDalamudPluginInterface dalamud, ICommandManager commandMan dalamud.UiBuilder.Draw += DrawUI; dalamud.UiBuilder.OpenConfigUi += () => OpenConfigUI(); - ChangelogDisplay.UpdateAndNotifyUser(); + _ = new ConfigChangelogWindow(); } public void Dispose() From a36a14a14b66b29d0ee415bed84a3c805b25ff64 Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 16:06:18 +0100 Subject: [PATCH 16/19] More changelog tweaks. --- BossMod/Config/ConfigChangelog.cs | 29 +++++++++++++++-------------- BossMod/Config/ConfigRoot.cs | 3 +++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/BossMod/Config/ConfigChangelog.cs b/BossMod/Config/ConfigChangelog.cs index 80330f60a..47bc9c30e 100644 --- a/BossMod/Config/ConfigChangelog.cs +++ b/BossMod/Config/ConfigChangelog.cs @@ -4,11 +4,6 @@ namespace BossMod; -public sealed class ConfigChangelogProperties : ConfigNode -{ - public Version BossModVersion { get; set; } = new(0, 0, 0, 0); -} - public sealed record class VersionedField(ConfigNode Node, FieldInfo FieldInfo, Version AddedVersion) { public string FieldKey => $"{Node}.{FieldInfo.Name}"; @@ -21,11 +16,18 @@ public class ConfigChangelogWindow : UIWindow public ConfigChangelogWindow() : base("VBM Changelog", true, new(400, 300)) { - var props = Service.Config.Get(); - PreviousVersion = GetPreviousPluginVersion(props); - props.BossModVersion = GetCurrentPluginVersion(); + PreviousVersion = GetPreviousPluginVersion(); + Service.Config.AssemblyVersion = GetCurrentPluginVersion(); + if (Service.Config.AssemblyVersion != PreviousVersion) + { + Service.Config.Modified.Fire(); + Fields = GetAllFields().Where(f => f.AddedVersion > PreviousVersion).ToList(); + } + else + { + Fields = []; + } - Fields = GetAllFields().Where(f => f.AddedVersion > PreviousVersion).ToList(); if (Fields.Count == 0) { // nothing interesting to show... @@ -69,12 +71,11 @@ public override void Draw() private void SetOption(VersionedField field, bool value) { field.FieldInfo.SetValue(field.Node, value); + Service.Config.Modified.Fire(); + Fields.Remove(field); if (Fields.Count == 0) - { IsOpen = false; - Service.Config.Modified.Fire(); - } } private static IEnumerable GetAllFields() @@ -107,13 +108,13 @@ private static Version GetCurrentPluginVersion() #endif } - private static Version GetPreviousPluginVersion(ConfigChangelogProperties props) + private static Version GetPreviousPluginVersion() { #if DEBUG // change value to something sensible if you want to test the changelog stuff return new(0, 0, 0, 999); #else - return props.BossModVersion; + return Service.Config.AssemblyVersion; #endif } } diff --git a/BossMod/Config/ConfigRoot.cs b/BossMod/Config/ConfigRoot.cs index 65f39b9ca..e557a58d0 100644 --- a/BossMod/Config/ConfigRoot.cs +++ b/BossMod/Config/ConfigRoot.cs @@ -10,6 +10,7 @@ public class ConfigRoot private const int _version = 10; public Event Modified = new(); + public Version AssemblyVersion = new(); // we use this to show newly added config options private readonly Dictionary _nodes = []; public IEnumerable Nodes => _nodes.Values; @@ -45,6 +46,7 @@ public void LoadFromFile(FileInfo file) var node = type != null ? _nodes.GetValueOrDefault(type) : null; node?.Deserialize(jconfig.Value, ser); } + AssemblyVersion = json.RootElement.TryGetProperty(nameof(AssemblyVersion), out var jver) ? new(jver.GetString() ?? "") : new(); } catch (Exception e) { @@ -66,6 +68,7 @@ public void SaveToFile(FileInfo file) n.Serialize(jwriter, ser); } jwriter.WriteEndObject(); + jwriter.WriteString(nameof(AssemblyVersion), AssemblyVersion.ToString()); }); } catch (Exception e) From 31205db663182ae56e4caa312bc5b210d635cece Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 16:54:50 +0100 Subject: [PATCH 17/19] Marked SbH D023 as WIP --- .../Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs index 3c4a4e213..54556ab24 100644 --- a/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs +++ b/BossMod/Modules/Shadowbringers/Dungeon/D02DohnMheg/D023AencThon.cs @@ -130,5 +130,5 @@ public AencThonLordOfTheLengthsomeGaitStates(BossModule module) : base(module) } } -[ModuleInfo(BossModuleInfo.Maturity.Contributed, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 649, NameID = 8146)] +[ModuleInfo(BossModuleInfo.Maturity.WIP, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 649, NameID = 8146)] public class AencThonLordOfTheLengthsomeGait(WorldState ws, Actor primary) : BossModule(ws, primary, new(-128.5f, -244), new ArenaBoundsCircle(19.5f)); From e4d05e9a1c51cf4b1872ffe6eeaaafb3de117c5b Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 22:23:23 +0100 Subject: [PATCH 18/19] Less chance to overcap gauge. --- BossMod/Autorotation/Standard/StandardWAR.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BossMod/Autorotation/Standard/StandardWAR.cs b/BossMod/Autorotation/Standard/StandardWAR.cs index 417405d64..59d776f79 100644 --- a/BossMod/Autorotation/Standard/StandardWAR.cs +++ b/BossMod/Autorotation/Standard/StandardWAR.cs @@ -724,7 +724,9 @@ private GCDPriority FellCleavePriorityBerserk() } } var nextAction = wantAOEAction ? NextComboAOE(comboStepsRemaining == 0) : NextComboSingleTarget(wantSERoute, comboStepsRemaining == 0); - var riskOvercappingGauge = Gauge + GaugeGainedFromAction(nextAction) > 100; + + var needInfuriateSoon = Unlocked(WAR.AID.Infuriate) && !CanFitGCD(InfuriateCD - InfuriateCDReduction - InfuriateCDLeeway, 1); + var riskOvercappingGauge = Gauge + GaugeGainedFromAction(nextAction) > (needInfuriateSoon ? 50 : 100); // first deal with forced combo; for ST extension, we generally want to minimize overcap by using combo finisher as late as possible // TODO: reconsider what to do if we can't fit in combo - do we still want to do partial combo? especially if it would cause gauge overcap From a56c4500732cbc2d7744c6adf06bbdd127dea944 Mon Sep 17 00:00:00 2001 From: Andrew Gilewsky Date: Sun, 29 Sep 2024 22:38:10 +0100 Subject: [PATCH 19/19] Fix CA warning. --- BossMod/Config/ConfigChangelog.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/BossMod/Config/ConfigChangelog.cs b/BossMod/Config/ConfigChangelog.cs index 47bc9c30e..e731c3819 100644 --- a/BossMod/Config/ConfigChangelog.cs +++ b/BossMod/Config/ConfigChangelog.cs @@ -108,6 +108,7 @@ private static Version GetCurrentPluginVersion() #endif } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1024:Use properties where appropriate")] private static Version GetPreviousPluginVersion() { #if DEBUG