Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BA support fate module #625

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BossMod/Modules/Stormblood/Foray/Hydatos/Ceto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public CetoStates(BossModule module) : base(module)
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1421, SortOrder = 9)]
public class Ceto(WorldState ws, Actor primary) : BossModule(ws, primary, new(747.8959f, -878.8765f), new ArenaBoundsCircle(80f, 1f, true))
public class Ceto(WorldState ws, Actor primary) : BossModule(ws, primary, new(747.8959f, -878.8765f), SharedBounds.Circle)
{
private static readonly uint[] trash = [(uint)OID.FaithlessGuard, (uint)OID.HydatosDelphyne, (uint)OID.DarkGargoyle];
protected override void DrawEnemies(int pcSlot, Actor pc)
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Modules/Stormblood/Foray/Hydatos/Daphne.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public DaphneStates(BossModule module) : base(module)
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1417, SortOrder = 5)]
public class Daphne(WorldState ws, Actor primary) : BossModule(ws, primary, new(207.8475f, -736.8179f), new ArenaBoundsCircle(80f, 1f, true))
public class Daphne(WorldState ws, Actor primary) : BossModule(ws, primary, new(207.8475f, -736.8179f), SharedBounds.Circle)
{
protected override void DrawEnemies(int pcSlot, Actor pc)
{
Expand Down
38 changes: 30 additions & 8 deletions BossMod/Modules/Stormblood/Foray/Hydatos/Molech.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ namespace BossMod.Stormblood.Foray.Hydatos.Molech;

public enum OID : uint
{
Boss = 0x275D, // R6.000, x1
Adulator = 0x275E // R2.800, x3
Boss = 0x275D, // R6.0
Adulator = 0x275E // R2.8
}

public enum AID : uint
{
AutoAttack = 15492, // Boss->player, no cast, single-target

W11TonzeSwipeAdds = 14978, // Adulator->player, no cast, single-target
W11TonzeSwipe = 14972, // Boss->self, 3.0s cast, range 9 ?-degree cone
W111TonzeSwing = 14973, // Boss->self, 4.0s cast, range 13 circle
OrderToStandFast = 14976, // Boss->self, 3.0s cast, range 100 circle
OrderToAssault = 14975, // Boss->self, 3.0s cast, range 100 circle, buffs Adulators
OrderToStandFast = 14976, // Boss->self, 3.0s cast, range 100 circle, buffs Adulators
W111TonzeSwingAdds = 14979, // Adulator->self, 3.0s cast, range 13 circle
W111TonzeSwingBig = 14974, // Boss->self, 4.0s cast, range 20 circle
OrderToAssault = 14975, // Boss->self, 3.0s cast, range 100 circle
ZoomIn = 14980 // Adulator->location, 3.0s cast, width 8 rect charge
}

class Adds(BossModule module) : Components.AddsPointless(module, (uint)OID.Adulator);
class W11TonzeSwipe(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.W11TonzeSwipe), new AOEShapeCone(9f, 75f.Degrees()));
class W111TonzeSwing(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.W111TonzeSwing), 13f);
class W111TonzeSwingAdds(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.W111TonzeSwingAdds), 13f);
Expand All @@ -30,7 +31,6 @@ class MolechStates : StateMachineBuilder
public MolechStates(BossModule module) : base(module)
{
TrivialPhase()
.ActivateOnEnter<Adds>()
.ActivateOnEnter<W11TonzeSwipe>()
.ActivateOnEnter<W111TonzeSwing>()
.ActivateOnEnter<W111TonzeSwingAdds>()
Expand All @@ -39,6 +39,28 @@ public MolechStates(BossModule module) : base(module)
}
}

[ModuleInfo(BossModuleInfo.Maturity.Contributed, GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1414, Contributors = "xan", SortOrder = 3)]
public class Molech(WorldState ws, Actor primary) : BossModule(ws, primary, new(-676.8632f, -441.8009f), new ArenaBoundsCircle(80f, 1f, true));
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1414, SortOrder = 3)]
public class Molech(WorldState ws, Actor primary) : BossModule(ws, primary, new(-676.8632f, -441.8009f), SharedBounds.Circle)
{
protected override void DrawEnemies(int pcSlot, Actor pc)
{
Arena.Actor(PrimaryActor);
Arena.Actors(Enemies((uint)OID.Adulator));
}

protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var count = hints.PotentialTargets.Count;
for (var i = 0; i < count; ++i)
{
var e = hints.PotentialTargets[i];
e.Priority = e.Actor.OID switch
{
(uint)OID.Boss => 1,
(uint)OID.Adulator => AIHints.Enemy.PriorityPointless,
_ when e.Actor.InCombat => 0,
_ => AIHints.Enemy.PriorityUndesirable
};
}
}
}
43 changes: 37 additions & 6 deletions BossMod/Modules/Stormblood/Foray/Hydatos/Ovni.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

public enum OID : uint
{
Boss = 0x2685, // R16.000, x1
Boss = 0x2685, // R16.0
UnfoundOgre = 0x26BF, // R1.3
}

public enum AID : uint
{
AutoAttack1 = 14781, // Boss->player, no cast, single-target
AutoAttack2 = 15228, // UnfoundOgre->player, no cast, single-target

RockHard = 14786, // Boss->location, 3.0s cast, range 8 circle
TorrentialTorment = 14785, // Boss->self, 5.0s cast, range 40+R 45-degree cone
Fluorescence = 14789, // Boss->self, 3.0s cast, single-target
Expand All @@ -16,11 +20,13 @@ public enum AID : uint
IonStorm = 14788, // Boss->players, no cast, range 20 circle
VitriolicBarrage = 14790, // Boss->self, 4.0s cast, range 25+R circle
ConcussiveOscillation = 14783, // Boss->self, 5.0s cast, range 24 circle
StraightPunch = 15430, // UnfoundOgre->player, no cast, single-target
PlainPound = 15431 // UnfoundOgre->self, 3.0s cast, range 6 circle
}

public enum IconID : uint
{
IonShower = 111, // player->self
IonShower = 111 // player->self
}

class PullOfTheVoid(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.PullOfTheVoid), 30f, kind: Kind.TowardsOrigin, minDistanceBetweenHitboxes: true);
Expand All @@ -29,6 +35,7 @@ class ConcussiveOscillation(BossModule module) : Components.SimpleAOEs(module, A
class VitriolicBarrage(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.VitriolicBarrage));
class RockHard(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.RockHard), 8);
class TorrentialTorment(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.TorrentialTorment), new AOEShapeCone(56f, 22.5f.Degrees()));

class IonShower(BossModule module) : Components.GenericStackSpread(module, alwaysShowSpreads: true, raidwideOnResolve: false)
{
private int _numCasts;
Expand All @@ -38,7 +45,7 @@ public override void OnEventIcon(Actor actor, uint iconID, ulong targetID)
if (iconID == (uint)IconID.IonShower && WorldState.Actors.Find(targetID) is { } target)
{
_numCasts = 0;
Spreads.Add(new(target, 20, WorldState.FutureTime(5d)));
Spreads.Add(new(target, 20f, WorldState.FutureTime(5d)));
}
}

Expand Down Expand Up @@ -67,6 +74,8 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme
}
}

class PlainPound(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.PlainPound), 6);

class OvniStates : StateMachineBuilder
{
public OvniStates(BossModule module) : base(module)
Expand All @@ -78,10 +87,32 @@ public OvniStates(BossModule module) : base(module)
.ActivateOnEnter<VitriolicBarrage>()
.ActivateOnEnter<RockHard>()
.ActivateOnEnter<TorrentialTorment>()
.ActivateOnEnter<IonShower>();
.ActivateOnEnter<IonShower>()
.ActivateOnEnter<PlainPound>();
}
}

[ModuleInfo(BossModuleInfo.Maturity.Contributed, GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1424, Contributors = "xan", SortOrder = 11)]
public class Ovni(WorldState ws, Actor primary) : BossModule(ws, primary, new(266.1068f, -97.09414f), new ArenaBoundsCircle(80f, 1f, true));
[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "xan, Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1424, SortOrder = 11)]
public class Ovni(WorldState ws, Actor primary) : BossModule(ws, primary, new(266.1068f, -97.09414f), SharedBounds.Circle)
{
protected override void DrawEnemies(int pcSlot, Actor pc)
{
Arena.Actor(PrimaryActor);
Arena.Actors(Enemies((uint)OID.UnfoundOgre));
}

protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var count = hints.PotentialTargets.Count;
for (var i = 0; i < count; ++i)
{
var e = hints.PotentialTargets[i];
e.Priority = e.Actor.OID switch
{
(uint)OID.Boss => 1,
_ when e.Actor.InCombat => 0,
_ => AIHints.Enemy.PriorityUndesirable
};
}
}
}
6 changes: 6 additions & 0 deletions BossMod/Modules/Stormblood/Foray/Hydatos/SharedBounds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace BossMod.Stormblood.Foray.Hydatos;

public static class SharedBounds
{
public static readonly ArenaBoundsCircle Circle = new(80f, 1f, true);
}
172 changes: 172 additions & 0 deletions BossMod/Modules/Stormblood/Foray/Hydatos/Tristitia.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
using BossMod.Shadowbringers.Hunt.RankS.Ixtab;

namespace BossMod.Stormblood.Foray.Hydatos.Tristitia;

public enum OID : uint
{
Boss = 0x2741, // R4.0
Tristitia = 0x2740, // R6.0
}

public enum AID : uint
{
AutoAttack1 = 14923, // Boss->player, no cast, single-target
AutoAttack2 = 14919, // Tristitia->player, no cast, single-target

WatergaIII = 14922, // Tristitia->location, 3.0s cast, range 8 circle
SpineLash1 = 14924, // Boss->self, 3.0s cast, range 5+R 90-degree cone
SpineLash2 = 14921, // Tristitia->self, 3.0s cast, range 5+R 90-degree cone
ShockSpikes = 14920, // Tristitia->self, 5.0s cast, single-target, applies shock spike buff
TornadoII1 = 15914, // Tristitia->self, 5.0s cast, range 5-40 donut
TornadoII2 = 15915, // Tristitia->self, no cast, range 5-40 donut
AerogaIV1 = 15912, // Tristitia->self, 3.5s cast, range 10 circle
AerogaIV2 = 15913, // Tristitia->self, no cast, range 10 circle
MightyStrikes = 15910, // Tristitia->self, 3.0s cast, single-target, applies critical strikes buff
Meteor = 15911, // Tristitia->self, 5.0s cast, range 40 circle
Dualcast = 15909 // Tristitia->self, 2.0s cast, single-target
}

class WatergaIII(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.WatergaIII), 8f);
class SpineLash1(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SpineLash1), new AOEShapeCone(9f, 45f.Degrees()));
class SpineLash2(BossModule module) : Components.SimpleAOEs(module, ActionID.MakeSpell(AID.SpineLash2), new AOEShapeCone(11f, 45f.Degrees()));
class Meteor(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Meteor));

class TornadoIIAerogaIVDualCast(BossModule module) : Components.GenericAOEs(module)
{
private static readonly AOEShapeCircle circle = new(10f);
private static readonly AOEShapeDonut donut = new(5f, 40f);
private bool dualCast;
public readonly List<AOEInstance> _aoes = new(2);

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
{
var count = _aoes.Count;
if (count == 0)
return [];
var aoes = new AOEInstance[count];
for (var i = 0; i < count; ++i)
{
var aoe = _aoes[i];
if (i == 0)
aoes[i] = count > 1 ? aoe with { Color = Colors.Danger } : aoe;
else
aoes[i] = aoe with { Risky = false };
}
return aoes;
}

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
void AddAOE(AOEShape shape, float delay = 0f) => _aoes.Add(new(shape, spell.LocXZ, default, Module.CastFinishAt(spell, delay)));
void AddAOEs(AOEShape shape1, AOEShape shape2)
{
AddAOE(shape1);
AddAOE(shape2, 3.1f);
dualCast = false;
}
switch (spell.Action.ID)
{
case (uint)AID.Dualcast:
dualCast = true;
break;
case (uint)AID.TornadoII1:
if (!dualCast)
AddAOE(donut);
else
AddAOEs(donut, circle);
break;
case (uint)AID.AerogaIV1:
if (!dualCast)
AddAOE(circle);
else
AddAOEs(circle, donut);
break;
}
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if (_aoes.Count != 0)
switch (spell.Action.ID)
{
case (uint)AID.TornadoII1:
case (uint)AID.TornadoII2:
case (uint)AID.AerogaIV1:
case (uint)AID.AerogaIV2:
_aoes.RemoveAt(0);
break;
}
}
}

class PhuaboStates : StateMachineBuilder
{
public PhuaboStates(BossModule module) : base(module)
{
TrivialPhase()
.ActivateOnEnter<SpineLash1>()
.Raw.Update = () =>
{
var adds = module.Enemies((uint)OID.Boss);
var countadds = adds.Count;
var areAddsDestroyed = true;
for (var i = 0; i < countadds; ++i)
{
if (!adds[i].IsDestroyed)
areAddsDestroyed = false;
}
var boss = module.Enemies((uint)OID.Tristitia);
var countBoss = boss.Count;
var isBossTargetable = false;
for (var i = 0; i < countBoss; ++i)
{
if (boss[i].IsTargetable)
isBossTargetable = true;
}
return areAddsDestroyed || isBossTargetable;
};
}
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1422, SortOrder = 12)]
public class Phuabo(WorldState ws, Actor primary) : BASupportFate(ws, primary);

class TristitiaStates : StateMachineBuilder
{
public TristitiaStates(BossModule module) : base(module)
{
TrivialPhase()
.ActivateOnEnter<WatergaIII>()
.ActivateOnEnter<TornadoIIAerogaIVDualCast>()
.ActivateOnEnter<SpineLash2>()
.ActivateOnEnter<Meteor>();
}
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Malediktus", GroupType = BossModuleInfo.GroupType.EurekaNM, GroupID = 639, NameID = 1422, PrimaryActorOID = (uint)OID.Tristitia, SortOrder = 13)]
public class Tristitia(WorldState ws, Actor primary) : BASupportFate(ws, primary);

public abstract class BASupportFate(WorldState ws, Actor primary) : BossModule(ws, primary, new(-123.4f, -128.283f), SharedBounds.Circle)
{
public static readonly uint[] All = [(uint)OID.Boss, (uint)OID.Tristitia];
protected override void DrawEnemies(int pcSlot, Actor pc)
{
Arena.Actor(PrimaryActor);
Arena.Actors(Enemies(All));
}

protected override void CalculateModuleAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var count = hints.PotentialTargets.Count;
for (var i = 0; i < count; ++i)
{
var e = hints.PotentialTargets[i];
e.Priority = e.Actor.OID switch
{
(uint)OID.Boss or (uint)OID.Tristitia => 1,
_ when e.Actor.InCombat => 0,
_ => AIHints.Enemy.PriorityUndesirable
};
}
}
}