Skip to content

Commit

Permalink
matoyas relic modules
Browse files Browse the repository at this point in the history
  • Loading branch information
CarnifexOptimus committed Oct 1, 2024
1 parent c38f948 commit 0caa351
Show file tree
Hide file tree
Showing 19 changed files with 949 additions and 191 deletions.
2 changes: 1 addition & 1 deletion BossMod/BossModule/ArenaBounds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ private Pathfinding.Map BuildMap()
for (var i = 0; i < 9; i++)
{
var samplePoint = relativeCenter + sampleOffsets[i];
if (!Poly.Contains(samplePoint))
if (!polygon.Contains(samplePoint))
{
allInside = false;
break;
Expand Down
8 changes: 4 additions & 4 deletions BossMod/Components/BaitAway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ private void AddTargetSpecificHints(Actor actor, Bait bait, AIHints hints)
break;

case AOEShapeCone cone:
if (Raid.WithoutSlot().Exclude(actor).InShape(cone, bait.Source.Position, bait.Rotation).Any())
hints.AddForbiddenZone(ShapeDistance.Cone(bait.Source.Position, 100, bait.Rotation, cone.HalfAngle), bait.Activation);
foreach (var a in Raid.WithoutSlot().Exclude(actor))
hints.AddForbiddenZone(ShapeDistance.Cone(bait.Source.Position, 100, bait.Source.AngleTo(a), cone.HalfAngle), bait.Activation);
break;

case AOEShapeRect rect:
if (Raid.WithoutSlot().Exclude(actor).InShape(rect, bait.Source.Position, bait.Rotation).Any())
hints.AddForbiddenZone(ShapeDistance.Rect(bait.Source.Position, bait.Rotation, 100, default, rect.HalfWidth), bait.Activation);
foreach (var a in Raid.WithoutSlot().Exclude(actor))
hints.AddForbiddenZone(ShapeDistance.Rect(bait.Source.Position, bait.Source.AngleTo(a), 100, default, rect.HalfWidth), bait.Activation);
break;
case AOEShapeCross cross:
foreach (var a in Raid.WithoutSlot().Exclude(actor))
Expand Down
12 changes: 6 additions & 6 deletions BossMod/Components/Cleave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignme
if (actor != target)
hints.AddForbiddenZone(Shape, origin.Position, angle, NextExpected);
else
AddTargetSpecificHints(actor, origin.Position, angle, hints);
AddTargetSpecificHints(actor, origin, angle, hints);
}

private void AddTargetSpecificHints(Actor actor, WPos origin, Angle angle, AIHints hints)
private void AddTargetSpecificHints(Actor actor, Actor source, Angle angle, AIHints hints)
{
switch (Shape)
{
Expand All @@ -41,13 +41,13 @@ private void AddTargetSpecificHints(Actor actor, WPos origin, Angle angle, AIHin
break;

case AOEShapeCone cone:
if (Raid.WithoutSlot().Exclude(actor).InShape(cone, origin, angle).Any())
hints.AddForbiddenZone(ShapeDistance.Cone(origin, 100, angle, cone.HalfAngle));
foreach (var a in Raid.WithoutSlot().Exclude(actor))
hints.AddForbiddenZone(ShapeDistance.Cone(source.Position, 100, source.AngleTo(a), cone.HalfAngle));
break;

case AOEShapeRect rect:
if (Raid.WithoutSlot().Exclude(actor).InShape(rect, origin, angle).Any())
hints.AddForbiddenZone(ShapeDistance.Rect(origin, angle, 100, default, rect.HalfWidth));
foreach (var a in Raid.WithoutSlot().Exclude(actor))
hints.AddForbiddenZone(ShapeDistance.Rect(source.Position, source.AngleTo(a), 100, default, rect.HalfWidth));
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class WorrisomeWavePlayer(BossModule module) : Components.GenericBaitAway(module
public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.WorrisomeWave1)
CurrentBaits.AddRange(Raid.WithoutSlot().Select(p => new Bait(p, p, cone)));
CurrentBaits.AddRange(Raid.WithoutSlot().Select(p => new Bait(p, p, cone, WorldState.FutureTime(6.3f))));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ public D091SeekerOfSolitudeStates(BossModule module) : base(module)
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 692, NameID = 9041)]
public class D091SeekerOfSolitude(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, 187), new ArenaBoundsRect(20.5f, 14.5f));
public class D091SeekerOfSolitude(WorldState ws, Actor primary) : BossModule(ws, primary, new(0, 187), new ArenaBoundsRect(20.5f, 14.5f));
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum OID : uint
public enum AID : uint
{
AutoAttack = 870, // Boss->player, no cast, single-target

ScorchingLeft = 18275, // Boss->self, 5.0s cast, range 40 180-degree cone
ScorchingRight = 18274, // Boss->self, 5.0s cast, range 40 180-degree cone
BlackFlame = 18269, // Helper->players, no cast, range 6 circle
Expand Down Expand Up @@ -184,8 +185,11 @@ public override void AddHints(int slot, Actor actor, TextHints hints)
}

class OtherworldlyHeat(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.OtherworldlyHeat), new AOEShapeCross(10, 2));
class ScorchingLeft(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ScorchingLeft), new AOEShapeCone(40, 90.Degrees()));
class ScorchingRight(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ScorchingRight), new AOEShapeCone(40, 90.Degrees()));

abstract class Scorching(BossModule module, AID aid) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(aid), new AOEShapeCone(40, 90.Degrees()));
class ScorchingLeft(BossModule module) : Scorching(module, AID.ScorchingLeft);
class ScorchingRight(BossModule module) : Scorching(module, AID.ScorchingRight);

class CullingBlade(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.CullingBlade));
class CaptiveBolt(BossModule module) : Components.SingleTargetDelayableCast(module, ActionID.MakeSpell(AID.CaptiveBolt));
class FiresIre(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.FiresIre), new AOEShapeCone(20, 45.Degrees()));
Expand Down
183 changes: 183 additions & 0 deletions BossMod/Modules/Shadowbringers/Dungeon/D12MatoyasRelict/D121Mudman.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
namespace BossMod.Shadowbringers.Dungeon.D12MatoyasRelict.D121Mudman;

public enum OID : uint
{
Boss = 0x300C, // R3.500, x1
MudVoidzone = 0x1EB145, // R0.5
MudmansDouble = 0x300D, // R3.5
MudBubble1 = 0x300E, // R2.0-4.0
MudBubble2 = 0x3009, // R4.0
Helper = 0x233C
}

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

HardRock = 21631, // Boss->player, 5.0s cast, single-target
Quagmire = 21633, // Helper->location, 4.0s cast, range 6 circle

PetrifiedPeat = 21632, // Boss->self, 4.0s cast, single-target
PeatPelt = 21634, // Boss->self, 4.0s cast, single-target

RockyRollVisual1 = 21639, // MudBubble2/MudBubble1->location, no cast, width 0 rect charge, bubble disappears
RockyRollVisual2 = 21635, // MudBubble1->player, 8.0s cast, single-target
RockyRoll1 = 21636, // MudBubble1->location, no cast, width 4 rect charge
RockyRoll2 = 21637, // MudBubble1->location, no cast, width 6 rect charge
RockyRoll3 = 21640, // MudBubble1->location, no cast, width 8 rect charge

BrittleBrecciaVisual = 21645, // Boss->self, 4.0s cast, single-target
BrittleBreccia1 = 21646, // Helper->self, 4.3s cast, range 6+R 270-degree cone
BrittleBreccia2 = 21647, // Helper->self, 4.3s cast, range 12+R 270-degree donut segment
BrittleBreccia3 = 21648, // Helper->self, 4.3s cast, range 18+R 270-degree donut segment

StoneAgeVisual = 21649, // Boss->self, 5.0s cast, single-target
StoneAge = 21650, // Helper->self, 5.3s cast, range 20 circle

TasteDirt = 21641, // MudmansDouble->self, 7.5s cast, single-target

FallingRockVisual = 21651, // Boss->self, 5.0s cast, single-target, stack
FallingRock = 21652 // Helper->player, 5.0s cast, range 6 circle
}

public enum TetherID : uint
{
Mudball = 7 // MudBubble1->player
}

class StoneAge(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.StoneAge));
class HardRock(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.HardRock));
class MudVoidzone(BossModule module) : Components.PersistentVoidzone(module, 5, m => m.Enemies(OID.MudVoidzone));
class Quagmire(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.Quagmire), 6);
class FallingRock(BossModule module) : Components.StackWithCastTargets(module, ActionID.MakeSpell(AID.FallingRock), 6, 4, 4);

class BrittleBreccia(BossModule module) : Components.ConcentricAOEs(module, _shapes)
{
private static readonly AOEShape[] _shapes = [new AOEShapeCone(6.5f, 135.Degrees()), new AOEShapeDonutSector(6.5f, 12.5f, 135.Degrees()), new AOEShapeDonutSector(12.5f, 18.5f, 135.Degrees())];

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.BrittleBreccia1)
AddSequence(caster.Position, Module.CastFinishAt(spell), spell.Rotation);
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if (Sequences.Count > 0)
{
var order = (AID)spell.Action.ID switch
{
AID.BrittleBreccia1 => 0,
AID.BrittleBreccia2 => 1,
AID.BrittleBreccia3 => 2,
_ => -1
};
AdvanceSequence(order, caster.Position, WorldState.FutureTime(1.5f), spell.Rotation);
}
}
}

class RockyRoll(BossModule module) : Components.GenericBaitAway(module)
{
private static readonly AOEShapeRect rect1 = new(60, 2);
private static readonly AOEShapeRect rect2 = new(60, 3);
private static readonly AOEShapeRect rect3 = new(60, 4);
private readonly List<WPos> activeHoles = [];

private static readonly Dictionary<byte, WPos> holePositions = new()
{
{ 0x0A, new(-202.627f, -162.627f) },
{ 0x0B, new(-157.373f, -162.627f) },
{ 0x0C, new(-202.627f, -117.373f) },
{ 0x0D, new(-157.373f, -117.373f) }
};

public override void OnEventEnvControl(byte index, uint state)
{
if (holePositions.TryGetValue(index, out var value))
{
if (state == 0x00020001)
activeHoles.Add(value);
else if (state == 0x00080004)
activeHoles.Remove(value);
}
}

public override void OnTethered(Actor source, ActorTetherInfo tether)
{
if (tether.ID == (uint)TetherID.Mudball)
CurrentBaits.Add(new(source, WorldState.Actors.Find(tether.Target)!, rect1, WorldState.FutureTime(8.2f)));
}

public override void OnUntethered(Actor source, ActorTetherInfo tether)
{
if (tether.ID == (uint)TetherID.Mudball)
CurrentBaits.RemoveAll(x => x.Source == source);
}

public override void DrawArenaForeground(int pcSlot, Actor pc)
{
base.DrawArenaForeground(pcSlot, pc);
foreach (var h in activeHoles)
Arena.AddCircle(h, 5, Colors.Safe, 5);
}

public override void Update()
{
if (CurrentBaits.Count == 0)
return;

for (var i = 0; i < CurrentBaits.Count; i++)
{
var b = CurrentBaits[i];
var activation = WorldState.FutureTime(9.7f);
if (b.Source.HitboxRadius is > 2 and <= 3 && b.Shape == rect1)
{
b.Shape = rect2;
b.Activation = activation;
}
else if (b.Source.HitboxRadius > 3 && b.Shape == rect2)
{
b.Shape = rect3;
b.Activation = activation;
}
CurrentBaits[i] = b;
}
}

public override void AddHints(int slot, Actor actor, TextHints hints)
{
base.AddHints(slot, actor, hints);
if (CurrentBaits.Any(x => x.Source == actor))
hints.Add("Bait into a hole!");
}

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
base.AddAIHints(slot, actor, assignment, hints);
var forbidden = new List<Func<WPos, float>>();
foreach (var b in ActiveBaitsOn(actor))
foreach (var h in activeHoles)
forbidden.Add(ShapeDistance.InvertedRect(b.Source.Position, h, 1));
if (forbidden.Count > 0)
hints.AddForbiddenZone(p => forbidden.Select(f => f(p)).Max());
}
}

class D121MudmanStates : StateMachineBuilder
{
public D121MudmanStates(BossModule module) : base(module)
{
TrivialPhase()
.ActivateOnEnter<BrittleBreccia>()
.ActivateOnEnter<FallingRock>()
.ActivateOnEnter<MudVoidzone>()
.ActivateOnEnter<Quagmire>()
.ActivateOnEnter<HardRock>()
.ActivateOnEnter<StoneAge>()
.ActivateOnEnter<RockyRoll>();
}
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "The Combat Reborn Team (Malediktus)", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 746, NameID = 9735)]
public class D121Mudman(WorldState ws, Actor primary) : BossModule(ws, primary, new(-180, -140), new ArenaBoundsCircle(19.5f));
Loading

0 comments on commit 0caa351

Please sign in to comment.