-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
469 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
BossMod/Modules/Dawntrail/Dungeon/D03SkydeepCenote/D031FeatherRay.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
namespace BossMod.Dawntrail.Dungeon.D03SkydeepCenote.D031FeatherRay; | ||
|
||
public enum OID : uint | ||
{ | ||
Boss = 0x41D3, // R5.000, x1 | ||
AiryBubble = 0x41D4, // R1.100-2.200, x36 | ||
Helper = 0x233C, // R0.500, x5, Helper type | ||
} | ||
|
||
public enum AID : uint | ||
{ | ||
AutoAttack = 872, // Boss->player, no cast, single-target | ||
Immersion = 36739, // Boss->self, 5.0s cast, range 24 circle, raidwide | ||
TroublesomeTail = 36727, // Boss->self, 4.0s cast, range 24 circle, raidwide + mirror debuff | ||
WorrisomeWave = 36728, // Boss->self, 4.0s cast, range 24 30-degree cone | ||
WorrisomeWaveNuisance = 36729, // Helper->self, no cast, range 24 30-degree cone | ||
HydroRing = 36733, // Boss->self, 5.0s cast, range 12-24 donut, leaves persistent voidzone | ||
BlowingBubbles = 36732, // Boss->self, 3.0s cast, single-target, visual (start spawning small bubbles from boss) | ||
BubbleBomb = 36735, // Boss->self, 3.0s cast, single-target, visual (spawn large bubbles) | ||
RollingCurrent = 36737, // Boss->self, 5.0s cast, single-target, visual (move bubbles) | ||
RollingCurrentAOE = 38185, // Helper->self, 5.0s cast, range 68 width 32 rect, knock-forward 8 on bubbles | ||
Burst = 36738, // AiryBubble->self, 1.5s cast, range 6 circle | ||
TroubleBubbles = 38787, // Boss->self, 3.0s cast, single-target, visual (start spawning small bubbles from players) | ||
Pop = 36734, // AiryBubble->player, no cast, single-target, damage if bubble is touched | ||
} | ||
|
||
public enum IconID : uint | ||
{ | ||
Nuisance = 514, // player | ||
} | ||
|
||
class Immersion(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.Immersion)); | ||
class TroublesomeTail(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.TroublesomeTail)); | ||
class WorrisomeWave(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WorrisomeWave), new AOEShapeCone(24, 15.Degrees())); | ||
|
||
class WorrisomeWaveNuisance(BossModule module) : Components.BaitAwayIcon(module, new AOEShapeCone(24, 15.Degrees()), (uint)IconID.Nuisance, ActionID.MakeSpell(AID.WorrisomeWaveNuisance), 5.4f) | ||
{ | ||
public override Actor? BaitSource(Actor target) => target; | ||
} | ||
|
||
class HydroRing(BossModule module) : Components.GenericAOEs(module, ActionID.MakeSpell(AID.HydroRing)) | ||
{ | ||
private AOEInstance? _aoe; | ||
|
||
private static readonly AOEShapeDonut _shape = new(12, 24); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => Utils.ZeroOrOne(_aoe); | ||
|
||
public override void OnCastStarted(Actor caster, ActorCastInfo spell) | ||
{ | ||
if (spell.Action == WatchedAction) | ||
_aoe = new(_shape, caster.Position, spell.Rotation, Module.CastFinishAt(spell)); | ||
} | ||
|
||
public override void OnEventEnvControl(byte index, uint state) | ||
{ | ||
if (index == 19 && state == 0x00080004) | ||
_aoe = null; | ||
} | ||
} | ||
|
||
class AiryBubbles(BossModule module) : Components.GenericAOEs(module) | ||
{ | ||
private readonly List<Actor> _bubbles = []; | ||
|
||
private static readonly AOEShapeCircle _shape = new(1.1f); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => _bubbles.Select(b => new AOEInstance(_shape, b.Position)); | ||
|
||
public override void OnActorPlayActionTimelineEvent(Actor actor, ushort id) | ||
{ | ||
if ((OID)actor.OID != OID.AiryBubble || actor.HitboxRadius > _shape.Radius + 0.01f) | ||
return; | ||
switch (id) | ||
{ | ||
case 0x1E46: | ||
_bubbles.Add(actor); | ||
break; | ||
case 0x1E3C: | ||
_bubbles.Remove(actor); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
class BubbleBomb(BossModule module) : Components.GenericAOEs(module, ActionID.MakeSpell(AID.Burst)) | ||
{ | ||
private readonly List<AOEInstance> _aoes = []; | ||
private bool _directionKnown; | ||
|
||
private static readonly AOEShapeCircle _shape = new(6); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => _directionKnown ? _aoes : []; | ||
|
||
public override void OnActorPlayActionTimelineEvent(Actor actor, ushort id) | ||
{ | ||
if ((OID)actor.OID == OID.AiryBubble && actor.HitboxRadius > 2.1f && id == 0x1E46) | ||
_aoes.Add(new(_shape, actor.Position, default, WorldState.FutureTime(10.6f))); | ||
} | ||
|
||
public override void OnCastStarted(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID == AID.RollingCurrentAOE) | ||
{ | ||
var offset = 8 * spell.Rotation.ToDirection(); | ||
foreach (ref var aoe in _aoes.AsSpan()) | ||
aoe.Origin += offset; | ||
_directionKnown = true; | ||
} | ||
} | ||
|
||
public override void OnCastFinished(Actor caster, ActorCastInfo spell) | ||
{ | ||
if (spell.Action == WatchedAction) | ||
{ | ||
_directionKnown = false; | ||
var count = _aoes.RemoveAll(aoe => aoe.Origin.AlmostEqual(caster.Position, 1)); | ||
if (count != 1) | ||
ReportError($"Failed to find aoe @ {caster.Position}"); | ||
} | ||
} | ||
} | ||
|
||
class D031FeatherRayStates : StateMachineBuilder | ||
{ | ||
public D031FeatherRayStates(BossModule module) : base(module) | ||
{ | ||
TrivialPhase() | ||
.ActivateOnEnter<Immersion>() | ||
.ActivateOnEnter<TroublesomeTail>() | ||
.ActivateOnEnter<WorrisomeWave>() | ||
.ActivateOnEnter<WorrisomeWaveNuisance>() | ||
.ActivateOnEnter<HydroRing>() | ||
.ActivateOnEnter<AiryBubbles>() | ||
.ActivateOnEnter<BubbleBomb>(); | ||
} | ||
} | ||
|
||
[ModuleInfo(BossModuleInfo.Maturity.Verified, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 829, NameID = 12755)] | ||
public class D031FeatherRay(WorldState ws, Actor primary) : BossModule(ws, primary, new(-105, -160), new ArenaBoundsSquare(15)); |
98 changes: 98 additions & 0 deletions
98
BossMod/Modules/Dawntrail/Dungeon/D03SkydeepCenote/D032Firearms.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
namespace BossMod.Dawntrail.Dungeon.D03SkydeepCenote.D032Firearms; | ||
|
||
public enum OID : uint | ||
{ | ||
Boss = 0x4184, // R4.620, x1 | ||
Helper = 0x233C, // R0.500, x20, Helper type | ||
} | ||
|
||
public enum AID : uint | ||
{ | ||
AutoAttack = 872, // Boss->player, no cast, single-target | ||
Teleport = 36451, // Boss->location, no cast, single-target | ||
DynamicDominance = 36448, // Boss->self, 5.0s cast, range 70 circle, raidwide | ||
MirrorManeuver = 39139, // Boss->self, 3.0s cast, single-target, visual (mirrors & orbs) | ||
ThunderlightBurst = 36443, // Boss->self, 8.0s cast, single-target, visual (laser) | ||
ThunderlightBurstAOERect1 = 38581, // Helper->self, 8.2s cast, range 42 width 8 rect | ||
ThunderlightBurstAOERect2 = 38582, // Helper->self, 8.2s cast, range 49 width 8 rect | ||
ThunderlightBurstAOERect3 = 38583, // Helper->self, 8.2s cast, range 35 width 8 rect | ||
ThunderlightBurstAOERect4 = 38584, // Helper->self, 8.2s cast, range 36 width 8 rect | ||
ThunderlightBurstAOECircle = 36445, // Helper->self, 10.9s cast, range 35 circle | ||
AncientArtillery = 36442, // Boss->self, 3.0s cast, single-target, visual (show expanding square) | ||
EmergentArtillery = 39000, // Boss->self, 3.0s cast, single-target, visual (expand & explode square) | ||
ArtilleryAOE1 = 38660, // Helper->self, 8.5s cast, range 10 width 10 rect | ||
ArtilleryAOE2 = 38661, // Helper->self, 8.5s cast, range 10 width 10 rect | ||
ArtilleryAOE3 = 38662, // Helper->self, 8.5s cast, range 10 width 10 rect | ||
ArtilleryAOE4 = 38663, // Helper->self, 8.5s cast, range 10 width 10 rect | ||
Pummel = 36447, // Boss->player, 5.0s cast, single-target, tankbuster | ||
ThunderlightFlurry = 36450, // Helper->player, 5.0s cast, range 6 circle spread | ||
} | ||
|
||
public enum IconID : uint | ||
{ | ||
Pummel = 218, // player | ||
ThunderlightFlurry = 139, // player | ||
} | ||
|
||
class DynamicDominance(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.DynamicDominance)); | ||
class ThunderlightBurstRect1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ThunderlightBurstAOERect1), new AOEShapeRect(42, 4)); | ||
class ThunderlightBurstRect2(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ThunderlightBurstAOERect2), new AOEShapeRect(49, 4)); | ||
class ThunderlightBurstRect3(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ThunderlightBurstAOERect3), new AOEShapeRect(35, 4)); | ||
class ThunderlightBurstRect4(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ThunderlightBurstAOERect4), new AOEShapeRect(36, 4)); | ||
class ThunderlightBurstCircle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ThunderlightBurstAOECircle), new AOEShapeCircle(35)); | ||
|
||
class Artillery(BossModule module) : Components.GenericAOEs(module) | ||
{ | ||
public readonly List<AOEInstance> AOEs = []; | ||
|
||
private static readonly AOEShapeRect _shape = new(5, 5, 5); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => AOEs; | ||
|
||
public override void OnCastStarted(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.ArtilleryAOE1 or AID.ArtilleryAOE2 or AID.ArtilleryAOE3 or AID.ArtilleryAOE4) | ||
AOEs.Add(new(_shape, caster.Position, spell.Rotation, Module.CastFinishAt(spell))); | ||
} | ||
|
||
public override void OnCastFinished(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.ArtilleryAOE1 or AID.ArtilleryAOE2 or AID.ArtilleryAOE3 or AID.ArtilleryAOE4) | ||
AOEs.RemoveAll(aoe => aoe.Origin.AlmostEqual(caster.Position, 1)); | ||
} | ||
|
||
} | ||
|
||
class Pummel(BossModule module) : Components.SingleTargetCast(module, ActionID.MakeSpell(AID.Pummel)); | ||
|
||
class ThunderlightFlurry(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.ThunderlightFlurry), 6) | ||
{ | ||
private readonly Artillery? _artillery = module.FindComponent<Artillery>(); | ||
|
||
public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints) | ||
{ | ||
// start adding hints only after overlapping artillery is resolved | ||
if (_artillery == null || _artillery.AOEs.Count == 0) | ||
base.AddAIHints(slot, actor, assignment, hints); | ||
} | ||
} | ||
|
||
class D032FirearmsStates : StateMachineBuilder | ||
{ | ||
public D032FirearmsStates(BossModule module) : base(module) | ||
{ | ||
TrivialPhase() | ||
.ActivateOnEnter<DynamicDominance>() | ||
.ActivateOnEnter<ThunderlightBurstRect1>() | ||
.ActivateOnEnter<ThunderlightBurstRect2>() | ||
.ActivateOnEnter<ThunderlightBurstRect3>() | ||
.ActivateOnEnter<ThunderlightBurstRect4>() | ||
.ActivateOnEnter<ThunderlightBurstCircle>() | ||
.ActivateOnEnter<Artillery>() | ||
.ActivateOnEnter<Pummel>() | ||
.ActivateOnEnter<ThunderlightFlurry>(); | ||
} | ||
} | ||
|
||
[ModuleInfo(BossModuleInfo.Maturity.Verified, GroupType = BossModuleInfo.GroupType.CFC, GroupID = 829, NameID = 12888)] | ||
public class D032Firearms(WorldState ws, Actor primary) : BossModule(ws, primary, new(-85, -155), new ArenaBoundsSquare(20)); |
Oops, something went wrong.