Skip to content

Commit

Permalink
updated Valigarmanda module
Browse files Browse the repository at this point in the history
  • Loading branch information
CarnifexOptimus committed Oct 12, 2024
1 parent 1a5277c commit 9aa809c
Show file tree
Hide file tree
Showing 18 changed files with 407 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ public enum AID : uint
Spikesicle = 36850, // Boss->self, 10.0+0.5s cast, single-target, visual (curved aoes)
SpikesicleRepeat = 36851, // Boss->self, no cast, single-target, visual (second+ curve)
SpikesicleEnd = 36852, // Boss->self, no cast, single-target, visual (mechanic end)
SpikesicleAOE1 = 36853, // Helper->self, 1.7s cast, range ?-25 donut
SpikesicleAOE2 = 36854, // Helper->self, 1.7s cast, range ?-30 donut
SpikesicleAOE3 = 36855, // Helper->self, 1.7s cast, range ?-35 donut
SpikesicleAOE4 = 36856, // Helper->self, 1.7s cast, range ?-40 donut
SpikesicleAOE1 = 36853, // Helper->self, 1.7s cast, range 20-25 donut
SpikesicleAOE2 = 36854, // Helper->self, 1.7s cast, range 25-30 donut
SpikesicleAOE3 = 36855, // Helper->self, 1.7s cast, range 30-35 donut
SpikesicleAOE4 = 36856, // Helper->self, 1.7s cast, range 35-40 donut
SpikesicleAOE5 = 36857, // Helper->self, 1.7s cast, range 40 width 5 rect
SphereShatter = 39261, // IceBoulder->self, 1.5s cast, range 13 circle

SusurrantBreathThunder = 36805, // Boss->self, 6.5s cast, single-target, visual (cone in thunder phase)
SusurrantBreathIce = 36806, // Boss->self, 6.5s cast, single-target, visual (cone in ice phase)
SusurrantBreathFire = 36807, // Boss->self, 6.5s cast, single-target, visual (cone in fire phase)
SusurrantBreathAOE = 36808, // Helper->self, 7.3s cast, range 50 ?-degree cone
SusurrantBreathAOE = 36808, // Helper->self, 7.3s cast, range 50 80-degree cone
SlitheringStrikeThunder = 36809, // Boss->self, 6.5s cast, single-target, visual (out in thunder phase)
SlitheringStrikeIce = 36810, // Boss->self, 6.5s cast, single-target, visual (out in ice phase)
SlitheringStrikeFire = 36811, // Boss->self, 6.5s cast, single-target, visual (out in fire phase)
Expand Down Expand Up @@ -110,7 +110,7 @@ public enum AID : uint
BlightedBoltFail = 36832, // Helper->player, no cast, range 3 circle, ??? (second hit if mechanic failed)
BlightedBoltAOE = 36833, // Helper->FeatherOfRuin, 5.8s cast, range 8 circle
ThunderousBreath = 36834, // Boss->self, 7.0+0.9s cast, single-target, visual (lines + require levitation)
ThunderousBreathAOE = 36835, // Helper->self, 7.9s cast, range 50 ?-degree cone
ThunderousBreathAOE = 36835, // Helper->self, 7.9s cast, range 50 135-degree cone
ArcaneLightning = 39002, // ArcaneSphere->self, 1.0s cast, range 50 width 5 rect
Ruinfall = 36860, // Boss->self, 4.0+1.6s cast, single-target, visual (shared tankbuster tower + knockbacks)
RuinfallTower = 36861, // Helper->self, 5.6s cast, range 6 circle, 2-man tankbuster tower
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public override void OnEventEnvControl(byte index, uint state)
_ => default
};
if (offset != default)
AOE = new(_shape, Module.Center, -126.875f.Degrees() + offset, WorldState.FutureTime(9.2f));
AOE = new(_shape, Arena.Center, -126.875f.Degrees() + offset, WorldState.FutureTime(9.2f));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
AID.SusurrantBreathAOE => (_shapeCone, new(100, 75)),
AID.SlitheringStrikeAOE => (_shapeOut, caster.Position),
AID.StranglingCoilAOE => (_shapeIn, Module.Center),
AID.StranglingCoilAOE => (_shapeIn, Arena.Center),
_ => ((AOEShape?)null, default(WPos))
};
if (shape != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
namespace BossMod.Dawntrail.Extreme.Ex1Valigarmanda;

class ThunderPlatform(BossModule module) : BossComponent(module)
class ThunderPlatform(BossModule module) : Components.GenericAOEs(module)
{
public BitMask RequireLevitating;
public BitMask RequireHint;
private BitMask _levitating;

private static readonly AOEShapeRect _shape = new(5, 5, 5);

public override void AddHints(int slot, Actor actor, TextHints hints)
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
{
if (RequireHint[slot])
hints.Add(RequireLevitating[slot] ? "Levitate" : "Stay on ground", RequireLevitating[slot] != _levitating[slot]);
}

public override void DrawArenaBackground(int pcSlot, Actor pc)
{
if (RequireHint[pcSlot])
{
var highlightLevitate = RequireLevitating[pcSlot];
var highlightLevitate = RequireLevitating[slot];
for (var x = 0; x < 2; ++x)
{
for (var z = 0; z < 3; ++z)
{
var cellLevitating = ((x ^ z) & 1) != 0;
if (cellLevitating != highlightLevitate)
{
_shape.Draw(Arena, Module.Center + new WDir(-5 - 10 * x, -10 + 10 * z), default, Colors.AOE);
_shape.Draw(Arena, Module.Center + new WDir(+5 + 10 * x, -10 + 10 * z), default, Colors.AOE);
yield return new(_shape, Arena.Center + new WDir(-5 - 10 * x, -10 + 10 * z));
yield return new(_shape, Arena.Center + new WDir(+5 + 10 * x, -10 + 10 * z));
}
}
}
}
}

public override void AddHints(int slot, Actor actor, TextHints hints)
{
if (RequireHint[slot])
hints.Add(RequireLevitating[slot] ? "Levitate" : "Stay on ground", RequireLevitating[slot] != _levitating[slot]);
}

public override void OnStatusGain(Actor actor, ActorStatus status)
{
if ((SID)status.ID == SID.Levitate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public override IEnumerable<Source> Sources(int slot, Actor actor)

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
base.AddAIHints(slot, actor, assignment, hints);
var towers = Module.FindComponent<BarbarousBarrageTower>()!.Towers;
var isDelayDeltaLow = (towers.FirstOrDefault().Activation - WorldState.CurrentTime).TotalSeconds < 5;
var isActorInsideTower = towers.Any(x => x.IsInside(actor));
Expand Down
21 changes: 21 additions & 0 deletions BossMod/Modules/Dawntrail/Trial/T01Valigarmanda/ArcaneLightning.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace BossMod.Dawntrail.Trial.T01Valigarmanda;

class ArcaneLightning(BossModule module) : Components.GenericAOEs(module)
{
private static readonly AOEShapeRect rect = new(50, 2.5f);
public readonly List<AOEInstance> AOEs = [];

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => AOEs;

public override void OnActorCreated(Actor actor)
{
if ((OID)actor.OID == OID.ArcaneSphere1)
AOEs.Add(new(rect, actor.Position, actor.Rotation, WorldState.FutureTime(8.6f)));
}

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.ArcaneLightning)
AOEs.Clear();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace BossMod.Dawntrail.Trial.T01Valigarmanda;

class ChillingCataclysm(BossModule module) : Components.GenericAOEs(module)
{
public readonly List<AOEInstance> AOEs = [];

private static readonly AOEShapeCross _shape = new(40, 2.5f);

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => AOEs;

public override void OnActorCreated(Actor actor)
{
if ((OID)actor.OID == OID.ArcaneSphere2)
{
AOEs.Add(new(_shape, actor.Position, -0.003f.Degrees(), WorldState.FutureTime(7.1f)));
AOEs.Add(new(_shape, actor.Position, 44.998f.Degrees(), WorldState.FutureTime(7.1f)));
}
}

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.ChillingCataclysm)
AOEs.Clear();
}
}
29 changes: 29 additions & 0 deletions BossMod/Modules/Dawntrail/Trial/T01Valigarmanda/NorthernCross.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace BossMod.Dawntrail.Trial.T01Valigarmanda;

class NorthernCross(BossModule module) : Components.GenericAOEs(module)
{
public AOEInstance? _aoe;
private static readonly AOEShapeRect _shape = new(25, 30);

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe);

public override void OnEventEnvControl(byte index, uint state)
{
if (index != 0x02)
return;
var offset = state switch
{
0x00200010 => -90.Degrees(),
0x00020001 => 90.Degrees(),
_ => default
};
if (offset != default)
_aoe = new(_shape, Arena.Center, -126.875f.Degrees() + offset, WorldState.FutureTime(9.2f));
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if ((AID)spell.Action.ID is AID.NorthernCross1 or AID.NorthernCross2)
_aoe = null;
}
}
34 changes: 34 additions & 0 deletions BossMod/Modules/Dawntrail/Trial/T01Valigarmanda/Ruinfall.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace BossMod.Dawntrail.Trial.T01Valigarmanda;

class RuinfallAOE(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.RuinfallAOE), new AOEShapeCircle(6));

class RuinfallKB(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.RuinfallKB), 21, stopAfterWall: true, kind: Kind.DirForward)
{
public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var source = Sources(slot, actor).FirstOrDefault();
if (source != default && actor.Role != Role.Tank)
{
hints.AddForbiddenZone(ShapeDistance.InvertedRect(Module.PrimaryActor.Position, new Angle(), 1, 0, 20), source.Activation);
}
}
}

class RuinfallTower(BossModule module) : Components.CastTowers(module, ActionID.MakeSpell(AID.RuinfallTower), 6, 2, 2)
{
public override void Update()
{
if (Towers.Count == 0)
return;
var forbidden = Raid.WithSlot().WhereActor(p => p.Role != Role.Tank).Mask();
foreach (ref var t in Towers.AsSpan())
t.ForbiddenSoakers = forbidden;
}

public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
base.AddAIHints(slot, actor, assignment, hints);
if (Towers.Count > 0 && Towers.Any(x => x.IsInside(actor) && (Towers.FirstOrDefault().Activation - WorldState.CurrentTime).TotalSeconds < 5))
hints.ActionsToExecute.Push(ActionID.MakeSpell(ClassShared.AID.ArmsLength), actor, ActionQueue.Priority.High);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace BossMod.Dawntrail.Trial.T01Valigarmanda;

class StranglingCoilSusurrantBreath(BossModule module) : Components.GenericAOEs(module)
{
private static readonly AOEShapeDonut donut = new(8, 30);
private static readonly AOEShapeCone cone = new(50, 40.Degrees());
private readonly ArcaneLightning aoe = module.FindComponent<ArcaneLightning>()!;
private AOEInstance? _aoe;

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => aoe.AOEs.Count == 0 ? Utils.ZeroOrOne(_aoe) : ([]);

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID == AID.StranglingCoil)
_aoe = new(donut, Arena.Center, default, Module.CastFinishAt(spell));
else if ((AID)spell.Action.ID == AID.SusurrantBreath)
_aoe = new(cone, new(100, 75), default, Module.CastFinishAt(spell));
}

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if ((AID)spell.Action.ID is AID.StranglingCoil or AID.SusurrantBreath)
_aoe = null;
}
}
Loading

0 comments on commit 9aa809c

Please sign in to comment.