forked from awgil/ffxiv_bossmod
-
Notifications
You must be signed in to change notification settings - Fork 35
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
20 changed files
with
1,537 additions
and
29 deletions.
There are no files selected for viewing
4 changes: 1 addition & 3 deletions
4
BossMod/Modules/Endwalker/Variant/V01SS/V011Geryon/V011GeryonEnums.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
127 changes: 127 additions & 0 deletions
127
BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021Yozakura.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,127 @@ | ||
namespace BossMod.Endwalker.Variant.V02MR.V021Yozakura; | ||
|
||
class ArtOfTheFireblossom(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ArtOfTheFireblossom), new AOEShapeCircle(9)); | ||
class ArtOfTheWindblossom(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ArtOfTheWindblossom), new AOEShapeDonut(5, 60)); | ||
class KugeRantsui(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.KugeRantsui)); | ||
class OkaRanman(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.OkaRanman)); | ||
//Temporary below, ninja mechanics are basically all previs dependent, timers are too short to be super useful | ||
|
||
class SealOfTheFireblossom1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SealOfTheFireblossom1), new AOEShapeCircle(9)); | ||
class SealOfTheWindblossom1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SealOfTheWindblossom1), new AOEShapeDonut(5, 60)); | ||
class SealOfTheRainblossom1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SealOfTheRainblossom1), new AOEShapeCone(70, 22.5f.Degrees())); | ||
class SealOfTheLevinblossom1(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SealOfTheLevinblossom1), new AOEShapeCone(70, 22.5f.Degrees())); | ||
|
||
class SeasonOfFire(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SeasonOfFire), new AOEShapeRect(46, 2.5f)); | ||
class SeasonOfWater(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SeasonOfWater), new AOEShapeRect(46, 2.5f)); | ||
class SeasonOfLightning(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SeasonOfLightning), new AOEShapeCone(70, 22.5f.Degrees())); | ||
class SeasonOfEarth(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.SeasonOfEarth), new AOEShapeCone(70, 22.5f.Degrees())); | ||
|
||
//Left Windy | ||
class WindblossomWhirl2(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WindblossomWhirl2), new AOEShapeDonut(5.5f, 60)); | ||
class WindblossomWhirl3(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WindblossomWhirl3), new AOEShapeDonut(5.5f, 60)); | ||
class LevinblossomStrike2(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.LevinblossomStrike2), 3); | ||
class DriftingPetals(BossModule module) : Components.KnockbackFromCastTarget(module, ActionID.MakeSpell(AID.DriftingPetals), 15, stopAtWall: true); | ||
|
||
//Left Rainy | ||
class MudrainAOE(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.MudrainAOE), 5); //persistent AOE, needs to be handled differently | ||
class IcebloomRest(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.IcebloomRest), 6); | ||
class ShadowflightAOE(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.ShadowflightAOE), new AOEShapeRect(10, 3)); | ||
class MudPieAOE(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.MudPieAOE), new AOEShapeRect(60, 3)); | ||
|
||
//Middle Rope Pulled | ||
class FireblossomFlare2(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.FireblossomFlare2), 6); | ||
class ArtOfTheFluff1(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ArtOfTheFluff1)); | ||
class ArtOfTheFluff2(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.ArtOfTheFluff2)); | ||
|
||
//Middle Rope Unpulled | ||
class TatamiGaeshiAOE(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.RockRootArrangementVisual), new AOEShapeCircle(4)); | ||
class LevinblossomLance(BossModule module) : Components.GenericRotatingAOE(module) | ||
{ | ||
private Angle _increment; | ||
private Angle _rotation; | ||
private DateTime _activation; | ||
|
||
private static readonly AOEShapeRect _shape = new AOEShapeRect(60, 3.5f, 60); | ||
|
||
public override void OnEventIcon(Actor actor, uint iconID) | ||
{ | ||
var increment = (IconID)iconID switch | ||
{ | ||
IconID.RotateCW => -22.5f.Degrees(), | ||
IconID.RotateCCW => 22.5f.Degrees(), | ||
_ => default | ||
}; | ||
if (increment != default) | ||
{ | ||
_increment = increment; | ||
InitIfReady(actor); | ||
} | ||
} | ||
|
||
public override void OnCastStarted(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID == AID.LevinblossomLanceFirst) | ||
{ | ||
_rotation = spell.Rotation; | ||
_activation = spell.NPCFinishAt; | ||
} | ||
if (_rotation != default) | ||
InitIfReady(caster); | ||
} | ||
|
||
public override void OnEventCast(Actor caster, ActorCastEvent spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.LevinblossomLanceFirst or AID.LevinblossomLanceRest) | ||
AdvanceSequence(0, WorldState.CurrentTime); | ||
} | ||
|
||
private void InitIfReady(Actor source) | ||
{ | ||
if (_rotation != default && _increment != default) | ||
{ | ||
Sequences.Add(new(_shape, source.Position, _rotation, _increment, _activation, 1, 5)); | ||
_rotation = default; | ||
_increment = default; | ||
} | ||
} | ||
} | ||
|
||
//Right No Dogu | ||
class RootArrangement : Components.StandardChasingAOEs | ||
{ | ||
public RootArrangement(BossModule module) : base(module, new AOEShapeCircle(4), ActionID.MakeSpell(AID.RockRootArrangementFirst), ActionID.MakeSpell(AID.RockRootArrangementRest), 4, 1, 4) | ||
{ | ||
ExcludedTargets = Raid.WithSlot(true).Mask(); | ||
} | ||
|
||
public override void OnEventIcon(Actor actor, uint iconID) | ||
{ | ||
if (iconID == (uint)IconID.RootArrangement) | ||
ExcludedTargets.Clear(Raid.FindSlot(actor.InstanceID)); | ||
} | ||
} | ||
|
||
//Right Dogu | ||
|
||
class Witherwind(BossModule module) : Components.GenericAOEs(module) | ||
{ | ||
private IReadOnlyList<Actor> _spirits = module.Enemies(OID.AutumnalTempest); | ||
|
||
private static readonly AOEShapeCircle _shape = new(3); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => _spirits.Where(actor => !actor.IsDead).Select(b => new AOEInstance(_shape, b.Position)); | ||
} | ||
|
||
[ModuleInfo(BossModuleInfo.Maturity.WIP, Contributors = "CombatReborn Team", GroupType = BossModuleInfo.GroupType.CFC, GroupID = 945, NameID = 12325)] | ||
public class V021Yozakura(WorldState ws, Actor primary) : BossModule(ws, primary, new ArenaBoundsSquare(new(-775, 16), 20)) | ||
{ | ||
protected override void UpdateModule() | ||
{ | ||
if (Enemies(OID.Boss).Any(e => e.Position.AlmostEqual(new(-775, 16), 50))) | ||
Arena.Bounds = new ArenaBoundsSquare(new(-775, 16), 20); | ||
if (Enemies(OID.Boss).Any(e => e.Position.AlmostEqual(new(737, 220), 50))) | ||
Arena.Bounds = new ArenaBoundsSquare(new(737, 220), 20); | ||
if (Enemies(OID.Boss).Any(e => e.Position.AlmostEqual(new(47, 93), 50))) | ||
Arena.Bounds = new ArenaBoundsSquare(new(47, 93), 20); | ||
} | ||
} |
129 changes: 129 additions & 0 deletions
129
BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraEnums.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,129 @@ | ||
namespace BossMod.Endwalker.Variant.V02MR.V021Yozakura; | ||
|
||
public enum OID : uint | ||
{ | ||
Boss = 0x3EDB, // R3.450, x1 | ||
Helper = 0x233C, // R0.500, x13, 523 type | ||
Helper2 = 0x3F53, // R0.500, x4 | ||
ShishuYamabiko = 0x3F00, // R0.800, x1 | ||
MirroredYozakura = 0x3EDC, // R3.450, x4 | ||
MudBubble = 0x3EDD, // R4.000, x0 (spawn during fight) | ||
Kuromaru = 0x3EDF, // R0.400, x1 (spawn during fight) | ||
Shiromaru = 0x3EE0, // R0.400, x1 (spawn during fight) | ||
Shibamaru = 0x3EDE, // R0.400, x1 (spawn during fight) | ||
AccursedSeedling = 0x3EE1, // R0.750, x0 (spawn during fight) | ||
AutumnalTempest = 0x3EE3, // R0.800, x0 (spawn during fight) | ||
} | ||
|
||
public enum AID : uint | ||
{ | ||
AutoAttack = 6497, // Boss->player, no cast, single-target | ||
GloryNeverlasting = 33705, // Boss->player, 5.0s cast, single-target //tankbuster | ||
|
||
ArtOfTheFireblossom = 33640, // Boss->self, 3.0s cast, range 9 circle | ||
ArtOfTheWindblossom = 33641, // Boss->self, 5.0s cast, range 6-60 donut | ||
|
||
KugeRantsui = 33706, // Boss->self, 5.0s cast, range 60 circle //raidwide | ||
OkaRanman = 33646, // Boss->self, 5.0s cast, range 60 circle //raidwide | ||
|
||
SealOfRiotousBloom = 33652, // Boss->self, 5.0s cast, single-target | ||
|
||
SealOfTheWindblossom1 = 33654, // Helper->self, 2.0s cast, range 6-60 donut //Donut AoE centered on Yozakura | ||
SealOfTheWindblossom2 = 33659, // Boss->location, no cast, single-target | ||
|
||
SealOfTheFireblossom1 = 33653, // Helper->self, 2.0s cast, range 9 circle //Point-blank AoE centered on Yozakura | ||
SealOfTheFireblossom2 = 33658, // Boss->location, no cast, single-target | ||
|
||
SealOfTheRainblossom1 = 33655, // Helper->self, 2.0s cast, range 70 45-degree cone //Four cone AoEs from Yozakura's hitbox in the intercardinal directions | ||
SealOfTheRainblossom2 = 33661, // Boss->location, no cast, single-target | ||
|
||
SealOfTheLevinblossom1 = 33656, // Helper->self, 1.8s cast, range 70 45-degree cone //Four cone AoEs from Yozakura's hitbox in the cardinal directions | ||
SealOfTheLevinblossom2 = 33660, // Boss->location, no cast, single-target | ||
|
||
SealOfTheFleeting = 33657, // Boss->self, 3.0s cast, single-target //Yozakura tethers to the petal piles | ||
|
||
SeasonsOfTheFleeting1 = 33665, // Boss->self, 10.0s cast, single-target //telegraph four sequential AoEs | ||
|
||
SeasonsOfTheFleeting2 = 33666, // Boss->self, no cast, single-target | ||
FireAndWaterVisual = 33667, // Helper->self, 2.0s cast, range 46 width 5 rect | ||
EarthAndLightningVisual = 33668, // Helper->self, 2.0s cast, range 60 ?-degree cone | ||
|
||
SeasonOfFire = 33669, // Helper->self, 0.8s cast, range 46 width 5 rect | ||
SeasonOfWater = 33670, // Helper->self, 0.8s cast, range 46 width 5 rect | ||
SeasonOfLightning = 33671, // Helper->self, 0.8s cast, range 70 ?-degree cone | ||
SeasonOfEarth = 33672, // Helper->self, 0.8s cast, range 70 ?-degree cone | ||
|
||
UnknownAbility = 34322, // Boss->location, no cast, single-target | ||
|
||
//Left Windy | ||
WindblossomWhirl1 = 33679, // Boss->self, 3.0s cast, single-target | ||
WindblossomWhirl2 = 33680, // Helper->self, 5.0s cast, range ?-60 donut | ||
WindblossomWhirl3 = 34544, // Helper->self, 3.0s cast, range 5.5-60 donut | ||
LevinblossomStrike1 = 33681, // Boss->self, 2.3s cast, single-target | ||
LevinblossomStrike2 = 33682, // Helper->location, 3.0s cast, range 3 circle | ||
DriftingPetals = 33683, // Boss->self, 5.0s cast, range 60 circle //knockback | ||
|
||
//Left Rainy | ||
Bunshin = 33662, // Boss->self, 5.0s cast, single-target | ||
Shadowflight = 33663, // Boss->self, 3.0s cast, single-target | ||
ShadowflightAOE = 33664, // MirroredYozakura->self, 2.5s cast, range 10 width 6 rect | ||
Mudrain = 33673, // Boss->self, 3.0s cast, single-target | ||
MudrainAOE = 33674, // Helper->location, 3.8s cast, range 5 circle | ||
IcebloomFirst = 33675, // Boss->self, 3.0s cast, single-target | ||
IcebloomRest = 33676, // Helper->location, 3.0s cast, range 6 circle | ||
MudPie = 33677, // Boss->self, 3.0s cast, single-target | ||
MudPieAOE = 33678, // MudBubble->self, 4.0s cast, range 60 width 6 rect | ||
|
||
//Middle Rope Pulled | ||
ArtOfTheFluff1 = 33693, // Shibamaru/Kuromaru->self, 6.5s cast, range 60 circle //gaze | ||
ArtOfTheFluff2 = 33694, // Shiromaru->self, 6.5s cast, range 60 circle //gaze | ||
|
||
FireblossomFlare1 = 33695, // Boss->self, 3.0s cast, single-target | ||
FireblossomFlare2 = 33696, // Helper->location, 3.0s cast, range 6 circle | ||
|
||
DondenGaeshi = 33692, // Boss->self, 3.0s cast, single-target // Indicates platforms | ||
SilentWhistle = 33691, // Boss->self, 3.0s cast, single-target //Dog summons | ||
|
||
//Middle Rope Unpulled | ||
LevinblossomLance1 = 33687, // Boss->self, 5.0s cast, single-target | ||
LevinblossomLance2 = 33688, // Boss->self, 5.0s cast, single-target | ||
LevinblossomLanceFirst = 33689, // Helper->self, 5.8s cast, range 60 width 7 rect | ||
LevinblossomLanceRest = 33690, // Helper->self, no cast, range 60 width 7 rect | ||
|
||
TatamiTrap = 33684, // Boss->self, 3.0s cast, single-target | ||
TatamiGaeshi = 33685, // Boss->self, 3.0s cast, single-target | ||
TatamiGaeshiAOE = 33686, // Helper->self, 3.8s cast, range 40 width 10 rect | ||
|
||
//Right No Dogu | ||
RockMebuki = 33697, // Boss->self, 3.0s cast, single-target | ||
RockRootArrangementVisual = 33700, // Boss->self, 5.0s cast, single-target | ||
RockRootArrangementFirst = 33701, // Helper->location, 3.0s cast, range 4 circle | ||
RockRootArrangementRest = 33702, // Helper->location, no cast, range 4 circle | ||
|
||
//Right Dogu | ||
Witherwind = 33703, // Boss->self, 3.0s cast, single-target | ||
|
||
} | ||
public enum SID : uint | ||
{ | ||
SeasonsOfTheFleeting = 3623, // none->Boss, extra=0x0 | ||
Unknown = 2056, // none->3EE1, extra=0x243 | ||
} | ||
|
||
public enum IconID : uint | ||
{ | ||
Tankbuster = 218, // player | ||
Icon374 = 374, // Shibamaru/Shiromaru/Kuromaru | ||
RotateCW = 167, // Boss | ||
RotateCCW = 168, // Boss | ||
RootArrangement = 197, // player | ||
} | ||
|
||
public enum TetherID : uint | ||
{ | ||
Tether_6 = 6, // Helper2->Boss | ||
Tether_4 = 4, // Helper2->Boss | ||
Tether_3 = 3, // Helper2->Boss | ||
Tether_5 = 5, // Helper2->Boss | ||
Tether_79 = 79, // Helper2->Boss | ||
} |
43 changes: 43 additions & 0 deletions
43
BossMod/Modules/Endwalker/Variant/V02MR/V021Yozakura/V021YozakuraStates.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,43 @@ | ||
namespace BossMod.Endwalker.Variant.V02MR.V021Yozakura; | ||
|
||
class V021YozakuraStates : StateMachineBuilder | ||
{ | ||
public V021YozakuraStates(BossModule module) : base(module) | ||
{ | ||
TrivialPhase() | ||
//Right No Dogu | ||
.ActivateOnEnter<RootArrangement>() | ||
//Right Dogu | ||
.ActivateOnEnter<Witherwind>() | ||
//Left Windy | ||
.ActivateOnEnter<WindblossomWhirl2>() | ||
.ActivateOnEnter<WindblossomWhirl3>() | ||
.ActivateOnEnter<LevinblossomStrike2>() | ||
.ActivateOnEnter<DriftingPetals>() | ||
//Left Rainy | ||
.ActivateOnEnter<MudrainAOE>() | ||
.ActivateOnEnter<IcebloomRest>() | ||
.ActivateOnEnter<ShadowflightAOE>() | ||
.ActivateOnEnter<MudPieAOE>() | ||
//Middle Rope Pulled | ||
.ActivateOnEnter<FireblossomFlare2>() | ||
.ActivateOnEnter<ArtOfTheFluff1>() | ||
.ActivateOnEnter<ArtOfTheFluff2>() | ||
//Middle Rope Unpulled | ||
.ActivateOnEnter<LevinblossomLance>() | ||
.ActivateOnEnter<TatamiGaeshiAOE>() | ||
//Standard | ||
.ActivateOnEnter<KugeRantsui>() | ||
.ActivateOnEnter<OkaRanman>() | ||
.ActivateOnEnter<SealOfTheFireblossom1>() | ||
.ActivateOnEnter<SealOfTheWindblossom1>() | ||
.ActivateOnEnter<SealOfTheRainblossom1>() | ||
.ActivateOnEnter<SealOfTheLevinblossom1>() | ||
.ActivateOnEnter<SeasonOfFire>() | ||
.ActivateOnEnter<SeasonOfWater>() | ||
.ActivateOnEnter<SeasonOfLightning>() | ||
.ActivateOnEnter<SeasonOfEarth>() | ||
.ActivateOnEnter<ArtOfTheFireblossom>() | ||
.ActivateOnEnter<ArtOfTheWindblossom>(); | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
BossMod/Modules/Endwalker/Variant/V02MR/V022Moko/AzureAuspice.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,83 @@ | ||
namespace BossMod.Endwalker.Variant.V02MR.V022Moko; | ||
|
||
// note: each initial line sends out two 'exaflares' to the left & right | ||
// each subsequent exaflare moves by distance 5, and happen approximately 2s apart | ||
// each wave is 5 subsequent lines, except for two horizontal ones that go towards edges - they only have 1 line - meaning there's a total 32 'rest' casts | ||
class Upwell(BossModule module) : Components.GenericAOEs(module) | ||
{ | ||
private class LineSequence | ||
{ | ||
public WPos NextOrigin; | ||
public WDir Advance; | ||
public Angle Rotation; | ||
public DateTime NextActivation; | ||
public AOEShapeRect? NextShape; // wide for first line, null for first line mirror, narrow for remaining lines | ||
} | ||
|
||
private List<LineSequence> _lines = new(); | ||
|
||
private static readonly AOEShapeRect _shapeWide = new(30, 5, 30); | ||
private static readonly AOEShapeRect _shapeNarrow = new(30, 2.5f, 30); | ||
|
||
public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) | ||
{ | ||
// TODO: think about imminent/future color/risk, esp for overlapping lines | ||
var imminentDeadline = WorldState.FutureTime(5); | ||
foreach (var l in _lines) | ||
if (l.NextShape != null && l.NextActivation <= imminentDeadline) | ||
yield return new(l.NextShape, l.NextOrigin, l.Rotation, l.NextActivation); | ||
} | ||
|
||
public override void OnCastStarted(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.UpwellFirst) | ||
{ | ||
var advance = spell.Rotation.ToDirection().OrthoR() * 5; | ||
_lines.Add(new() { NextOrigin = caster.Position, Advance = advance, Rotation = spell.Rotation, NextActivation = spell.NPCFinishAt, NextShape = _shapeWide }); | ||
_lines.Add(new() { NextOrigin = caster.Position, Advance = -advance, Rotation = (spell.Rotation + 180.Degrees()).Normalized(), NextActivation = spell.NPCFinishAt }); | ||
} | ||
} | ||
|
||
public override void OnCastFinished(Actor caster, ActorCastInfo spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.UpwellFirst) | ||
{ | ||
++NumCasts; | ||
var index = _lines.FindIndex(l => l.NextOrigin.AlmostEqual(caster.Position, 1) && l.NextShape == _shapeWide && l.Rotation.AlmostEqual(spell.Rotation, 0.1f)); | ||
if (index < 0 || index + 1 >= _lines.Count) | ||
{ | ||
ReportError($"Unexpected exaline end"); | ||
} | ||
else | ||
{ | ||
Advance(_lines[index]); | ||
Advance(_lines[index + 1]); | ||
} | ||
} | ||
} | ||
|
||
public override void OnEventCast(Actor caster, ActorCastEvent spell) | ||
{ | ||
if ((AID)spell.Action.ID is AID.UpwellRest) | ||
{ | ||
++NumCasts; | ||
var index = _lines.FindIndex(l => l.NextOrigin.AlmostEqual(caster.Position, 1) && l.NextShape == _shapeNarrow && l.Rotation.AlmostEqual(caster.Rotation, 0.1f)); | ||
if (index < 0) | ||
{ | ||
ReportError($"Unexpected exaline @ {caster.Position} / {caster.Rotation}"); | ||
} | ||
else | ||
{ | ||
Advance(_lines[index]); | ||
} | ||
} | ||
} | ||
|
||
private void Advance(LineSequence line) | ||
{ | ||
line.NextOrigin += line.Advance; | ||
line.NextActivation = WorldState.FutureTime(2); | ||
var offset = (line.NextOrigin - Module.Bounds.Center).Abs(); | ||
line.NextShape = offset.X < 19 && offset.Z < 19 ? _shapeNarrow : null; | ||
} | ||
} |
Oops, something went wrong.