Skip to content

Commit

Permalink
DRS duel.
Browse files Browse the repository at this point in the history
  • Loading branch information
awgil committed Apr 2, 2024
1 parent 457104f commit 55cb5a2
Show file tree
Hide file tree
Showing 6 changed files with 621 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace BossMod.Shadowbringers.Foray.DelubrumReginae.DRS2StygimolochWarrior;

class ViciousSwipe : Components.SelfTargetedAOEs
{
public ViciousSwipe() : base(ActionID.MakeSpell(AID.ViciousSwipe), new AOEShapeCircle(15)) { }
}

class CrazedRampage : Components.KnockbackFromCastTarget
{
public CrazedRampage() : base(ActionID.MakeSpell(AID.CrazedRampage), 13) { }
}

class Coerce : Components.StatusDrivenForcedMarch
{
public Coerce() : base(4, (uint)SID.ForwardMarch, (uint)SID.AboutFace, (uint)SID.LeftFace, (uint)SID.RightFace) { }
}

public class DRS2 : BossModule
{
public DRS2(WorldState ws, Actor primary) : base(ws, primary, new ArenaBoundsSquare(new(-160, 78), 17.5f)) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
namespace BossMod.Shadowbringers.Foray.DelubrumReginae.DRS2StygimolochWarrior;

public enum OID : uint
{
Boss = 0x30AB, // R4.000, x1
Helper = 0x233C, // R0.500, x24, 523 type
HiddenTrap = 0x18D6, // R0.500, x2, and more spawn during fight
TrapNormal = 0x1EB0E3, // R0.500, EventObj type, spawn during fight when discovered by perception
TrapToad = 0x1EB0E4, // R0.500, EventObj type, spawn during fight
TrapIce = 0x1EB0E5, // R0.500, EventObj type, spawn during fight
TrapMini = 0x1EB0E6, // R0.500, EventObj type, spawn during fight
};

public enum AID : uint
{
AutoAttack = 6497, // Boss->player, no cast, single-target
Teleport = 22396, // Boss->location, no cast, single-target
SurgeOfVigor = 22422, // Boss->self, 3.0s cast, single-target, applies damage up
UnrelentingCharge = 22425, // Boss->self, 3.0s cast, single-target, visual (knockbacks)
UnrelentingChargeAOE = 22426, // Boss->player, no cast, single-target, charge + knockback 10

Entrapment = 22397, // Boss->self, 3.0s cast, single-target, visual (spawn first traps)
EntrapmentAttract = 22398, // Helper->self, no cast, range 60 circle, attract to southern point
LethalBlow = 22399, // Boss->self, 20.0s cast, range 44 width 48 rect
InescapableEntrapment = 22400, // Boss->self, 3.0s cast, single-target, visual (spawn second traps)
SurgingFlames = 22401, // Boss->self, 13.0s cast, single-target, visual (resolve by freezing)
SurgingFlamesAOE = 22402, // Helper->self, no cast, range 50 circle, deadly raidwide unless frozen
SurgingFlood = 22403, // Boss->self, 10.0s cast, single-target, visual (resolve by toading)
SurgingFloodAOE = 22404, // Helper->self, no cast, range 50 circle, attract into devour unless toad?
WitheringCurse = 22405, // Boss->self, 13.0s cast, single-target, visual (resolve by minimizing)
WitheringCurseAOE = 22406, // Helper->player, no cast, single-target, deadly raidwide unless minimized
DevourVisual = 22407, // Boss->self, no cast, single-target, visual (attract)
DevourAttract = 22408, // Helper->self, no cast, range 60 circle, attract 60 for devour
Devour = 22409, // Boss->self, 2.0s cast, range 6 120-degree cone, deadly?
LeapingSpark = 22410, // Boss->self, 8.0s cast, single-target, visual (resolve by untoading)
LeapingSparkAOE = 22411, // Helper->player, no cast, range 5 circle
MassiveExplosion = 22430, // HiddenTrap->location, no cast, range 3 circle, trap explosion
TrappedUnderIce = 22431, // HiddenTrap->location, no cast, range 3 circle
Toad = 22432, // HiddenTrap->location, no cast, range 3 circle
Mini = 22433, // HiddenTrap->location, no cast, range 3 circle

ViciousSwipe = 22423, // Boss->self, 4.0s cast, range 15 circle aoe
CrazedRampage = 22424, // Helper->self, 6.0s cast, range 50 circle, knockback 13
FocusedTremor = 22414, // Boss->self, 3.0s cast, single-target, visual (staggered aoes)
FocusedTremorAOELarge = 22415, // Helper->self, 8.0s cast, range 20 width 20 rect aoe
FocusedTremorExtra = 22416, // Helper->self, no cast, range 10 width 10 rect, ???
FocusedTremorAOESmall = 22417, // Helper->self, 15.0s cast, range 10 width 10 rect aoe
ForcefulStrike = 22418, // Boss->self, 15.0s cast, range 44 width 48 rect
FlailingStrikeFirst = 22412, // Boss->self, 3.0s cast, range 40 60-degree cone
FlailingStrikeRest = 22413, // Boss->self, 0.5s cast, range 40 ?-degree cone
Coerce = 22420, // Boss->self, 3.0s cast, single-target, visual (apply forced march)

SunsIre = 22394, // Boss->self, 12.0s cast, single-target, visual (enrage)
SunsIreAOE = 22446, // Helper->self, no cast, range 50 circle, enrage
SunsIreRepeat = 22395, // Boss->self, no cast, single-target, enrage repeat every 2s
};

public enum SID : uint
{
ForwardMarch = 1293, // none->player, extra=0x0
AboutFace = 1294, // none->player, extra=0x0
LeftFace = 1295, // none->player, extra=0x0
RightFace = 1296, // none->player, extra=0x0
ForcedMarch = 1257, // none->player, extra=0x4/0x1/0x2/0x8
}

public enum IconID : uint
{
FlailingStrike = 4, // player
};

public enum TetherID : uint
{
FlailingStrike = 17, // Boss->player
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
namespace BossMod.Shadowbringers.Foray.DelubrumReginae.DRS2StygimolochWarrior;

class DRS2States : StateMachineBuilder
{
public DRS2States(BossModule module) : base(module)
{
DeathPhase(0, SinglePhase)
.ActivateOnEnter<Devour>(); // TODO: reconsider...
}

private void SinglePhase(uint id)
{
SurgeOfVigor(id, 8.2f);
UnrelentingCharge(id + 0x10000, 9.2f);
Entrapment(id + 0x20000, 9.0f);
ViciousSwipeCrazedRampage(id + 0x30000, 1.1f);
FocusedTremorForcefulStrike(id + 0x40000, 8.2f);
InescapableEntrapment1(id + 0x50000, 11.5f);
SurgeOfVigor(id + 0x60000, 9.4f); // 12.6 if previous was withering curse
FocusedTremorFlailingStrike(id + 0x70000, 11.2f);
InescapableEntrapment2(id + 0x80000, 9.8f);
FocusedTremorCoerceForcefulStrike(id + 0x90000, 9.7f);
SurgeOfVigor(id + 0xA0000, 10.2f);
UnrelentingCharge(id + 0xB0000, 11.2f);
ViciousSwipeCrazedRampage(id + 0xC0000, 1.6f);
SunsIre(id + 0xD0000, 9.5f);
}

private void SurgeOfVigor(uint id, float delay)
{
// note: it could be preceeded by optional devour cast, ignore it
Condition(id, delay, () => Module.PrimaryActor.CastInfo?.IsSpell(AID.SurgeOfVigor) ?? false, maxOverdue: 100)
.SetHint(StateMachine.StateHint.BossCastStart);
CastEnd(id + 1, 3, "Damage up");
}

private void UnrelentingCharge(uint id, float delay)
{
Cast(id, AID.UnrelentingCharge, delay, 3)
.ActivateOnEnter<UnrelentingCharge>();
ComponentCondition<UnrelentingCharge>(id + 0x10, 0.3f, comp => comp.NumCasts >= 1, "Knockback 1");
ComponentCondition<UnrelentingCharge>(id + 0x11, 1.6f, comp => comp.NumCasts >= 2, "Knockback 2");
ComponentCondition<UnrelentingCharge>(id + 0x12, 1.6f, comp => comp.NumCasts >= 3, "Knockback 3")
.DeactivateOnExit<UnrelentingCharge>();
}

private void Entrapment(uint id, float delay)
{
Cast(id, AID.Entrapment, delay, 3)
.ActivateOnEnter<EntrapmentAttract>();
ComponentCondition<EntrapmentAttract>(id + 0x10, 0.8f, comp => comp.NumCasts > 0, "Traps")
.DeactivateOnExit<EntrapmentAttract>();

Cast(id + 0x20, AID.LethalBlow, 1.3f, 20, "Traps deadline")
.ActivateOnEnter<LethalBlow>()
.ActivateOnEnter<EntrapmentNormal>()
.DeactivateOnExit<LethalBlow>();
ComponentCondition<Entrapment>(id + 0x30, 1.0f, comp => comp.NumCasts >= 16, "Traps resolve")
.DeactivateOnExit<Entrapment>();
}

private void InescapableEntrapment1(uint id, float delay)
{
Cast(id, AID.InescapableEntrapment, delay, 3, "Traps")
.ActivateOnEnter<EntrapmentInescapable>();
CastMulti(id + 0x10, [AID.SurgingFlames, AID.WitheringCurse], 8.2f, 13, "Traps resolve (ice/mini)") // note: different start delay depending on cast
.DeactivateOnExit<EntrapmentInescapable>();
// note: withering curse is followed by devour here
}

private void InescapableEntrapment2(uint id, float delay)
{
Cast(id, AID.InescapableEntrapment, delay, 3, "Traps")
.ActivateOnEnter<EntrapmentInescapable>();
CastMulti(id + 0x10, [AID.SurgingFlames, AID.WitheringCurse], 3.2f, 13, "Traps resolve (ice/mini)"); // note: different start delay depending on cast
// note: withering curse is followed by devour here

Condition(id + 0x100, 6.6f, () => Module.PrimaryActor.CastInfo?.IsSpell(AID.SurgingFlood) ?? false, maxOverdue: 100) // 4.2 if previous was surging flames
.SetHint(StateMachine.StateHint.BossCastStart);
CastEnd(id + 0x101, 10, "Traps resolve (toad)");
Cast(id + 0x110, AID.LeapingSpark, 0.3f, 8, "Remove toad")
.DeactivateOnExit<EntrapmentInescapable>();
ComponentCondition<LeapingSpark>(id + 0x120, 0.5f, comp => comp.NumCasts >= 1)
.ActivateOnEnter<LeapingSpark>()
.SetHint(StateMachine.StateHint.Raidwide);
ComponentCondition<LeapingSpark>(id + 0x121, 1.1f, comp => comp.NumCasts >= 2)
.SetHint(StateMachine.StateHint.Raidwide);
ComponentCondition<LeapingSpark>(id + 0x122, 1.1f, comp => comp.NumCasts >= 3, "Raidwide x3")
.DeactivateOnExit<LeapingSpark>()
.SetHint(StateMachine.StateHint.Raidwide);
}

private void ViciousSwipeCrazedRampage(uint id, float delay)
{
Cast(id, AID.ViciousSwipe, delay, 4, "Out")
.ActivateOnEnter<ViciousSwipe>()
.ActivateOnEnter<CrazedRampage>() // starts at the same time
.DeactivateOnExit<ViciousSwipe>();
ComponentCondition<CrazedRampage>(id + 0x10, 2, comp => comp.NumCasts > 0, "Knockback")
.DeactivateOnExit<CrazedRampage>();
}

private State FocusedTremorForcefulStrike(uint id, float delay)
{
Cast(id, AID.FocusedTremor, delay, 3);
ComponentCondition<FocusedTremorLarge>(id + 0x10, 0.8f, comp => comp.Casters.Count > 0)
.ActivateOnEnter<FocusedTremorLarge>();

CastStart(id + 0x20, AID.ForcefulStrike, 2.7f);
ComponentCondition<FocusedTremorLarge>(id + 0x30, 5.2f, comp => comp.NumCasts >= 1, "Tile 1");
ComponentCondition<FocusedTremorLarge>(id + 0x31, 2.0f, comp => comp.NumCasts >= 2, "Tile 2");
ComponentCondition<FocusedTremorLarge>(id + 0x32, 2.0f, comp => comp.NumCasts >= 3, "Tile 3");
ComponentCondition<FocusedTremorLarge>(id + 0x33, 2.0f, comp => comp.NumCasts >= 4, "Tile 4")
.ActivateOnEnter<ForcefulStrike>()
.DeactivateOnExit<FocusedTremorLarge>();
return CastEnd(id + 0x40, 3.8f, "Cleave")
.DeactivateOnExit<ForcefulStrike>();
}

private void FocusedTremorFlailingStrike(uint id, float delay)
{
Cast(id, AID.FocusedTremor, delay, 3);
ComponentCondition<FocusedTremorSmall>(id + 0x10, 0.8f, comp => comp.Casters.Count > 0)
.ActivateOnEnter<FocusedTremorSmall>();

ComponentCondition<FlailingStrikeBait>(id + 0x20, 4.7f, comp => comp.CurrentBaits.Count > 0)
.ActivateOnEnter<FlailingStrikeBait>();
CastStart(id + 0x30, AID.FlailingStrikeFirst, 6.1f, "Cone bait")
.DeactivateOnExit<FlailingStrikeBait>();
CastEnd(id + 0x31, 3, "Cone 1")
.ActivateOnEnter<FlailingStrike>()
.ExecOnEnter<FocusedTremorSmall>(comp => comp.Activate());
ComponentCondition<FocusedTremorSmall>(id + 0x40, 1.2f, comp => comp.NumCasts >= 1, "Tile 1");

ComponentCondition<FlailingStrike>(id + 0x100, 7.5f, comp => comp.NumCasts >= 6, "Cone 6")
.DeactivateOnExit<FlailingStrike>();
ViciousSwipeCrazedRampage(id + 0x200, 0.8f);
ComponentCondition<FocusedTremorSmall>(id + 0x300, 0.7f, comp => comp.NumCasts >= 16, "Tiles resolve")
.DeactivateOnExit<FocusedTremorSmall>();
}

private void FocusedTremorCoerceForcefulStrike(uint id, float delay)
{
Cast(id, AID.Coerce, delay, 3)
.ActivateOnEnter<Coerce>(); // face debuff appears ~0.7s after cast end
SurgeOfVigor(id + 0x10, 3.2f);

Cast(id + 0x100, AID.FocusedTremor, 9.2f, 3);
ComponentCondition<FocusedTremorLarge>(id + 0x110, 0.8f, comp => comp.Casters.Count > 0)
.ActivateOnEnter<FocusedTremorLarge>();

CastStart(id + 0x120, AID.ForcefulStrike, 2.7f);
ComponentCondition<FocusedTremorLarge>(id + 0x130, 5.2f, comp => comp.NumCasts >= 1, "Tile 1");
ComponentCondition<Coerce>(id + 0x131, 1.6f, comp => comp.NumActiveForcedMarches > 0, "Forced march");
ComponentCondition<FocusedTremorLarge>(id + 0x132, 0.4f, comp => comp.NumCasts >= 2, "Tile 2");
ComponentCondition<FocusedTremorLarge>(id + 0x133, 2.0f, comp => comp.NumCasts >= 3, "Tile 3");
ComponentCondition<FocusedTremorLarge>(id + 0x134, 2.0f, comp => comp.NumCasts >= 4, "Tile 4")
.ActivateOnEnter<ForcefulStrike>()
.DeactivateOnExit<FocusedTremorLarge>()
.DeactivateOnExit<Coerce>();
CastEnd(id + 0x140, 3.8f, "Cleave")
.DeactivateOnExit<ForcefulStrike>();
}

private void SunsIre(uint id, float delay)
{
Cast(id, AID.SunsIre, delay, 12);
SimpleState(id + 0x10, 0.7f, "Enrage");
}
}
Loading

0 comments on commit 55cb5a2

Please sign in to comment.