Skip to content

Commit

Permalink
Merge pull request #531 from Shinryin/main
Browse files Browse the repository at this point in the history
DT A Rank AI Improvements
  • Loading branch information
CarnifexOptimus authored Dec 30, 2024
2 parents 88e6429 + 3621a4d commit 6bc497b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 70 deletions.
52 changes: 29 additions & 23 deletions BossMod/Modules/Dawntrail/Hunt/RankA/Keheniheyamewi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public enum OID : uint
public enum AID : uint
{
AutoAttack = 872, // Boss->player, no cast, single-target

Scatterscourge1 = 39807, // Boss->self, 4.0s cast, range 10-40 donut
BodyPress = 40063, // Boss->self, 4.0s cast, range 15 circle
SlipperyScatterscourge = 38648, // Boss->self, 5.0s cast, range 20 width 10 rect
Expand All @@ -17,7 +16,7 @@ public enum AID : uint
PoisonGas = 38652, // Boss->self, 5.0s cast, range 60 circle
BodyPress2 = 38651, // Boss->self, 4.0s cast, range 15 circle
MalignantMucus = 38653, // Boss->self, 5.0s cast, single-target
PoisonMucus = 38654 // Boss->location, 1.0s cast, range 6 circle
PoisonMucus = 38654, // Boss->location, 1.0s cast, range 6 circle
}

public enum SID : uint
Expand All @@ -43,20 +42,26 @@ class SlipperyScatterscourge(BossModule module) : Components.GenericAOEs(module)

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
{
if (_caster == null || _finishedCast)
if (_caster == null)
yield break;

var rectEndPosition = GetRectEndPosition(_caster.Position, _caster.Rotation, _shapeRect.LengthFront);
var rectEndPos = default(WPos);
if (!_finishedCast)
rectEndPos = GetRectEndPosition(_caster.Position, _caster.Rotation, _shapeRect.LengthFront);

foreach (var aoe in _activeAOEs)
{
if (aoe.Shape == _shapeRect)
{
yield return new(_shapeRect, _caster.Position, _caster.Rotation, aoe.Activation, aoe.Color, aoe.Risky);
if (!_finishedCast)
yield return new(_shapeRect, _caster.Position, _caster.Rotation, aoe.Activation, aoe.Color, aoe.Risky);
}
else if (aoe.Shape == _shapeDonut || aoe.Shape == _shapeCircle)
{
yield return new(aoe.Shape, rectEndPosition, aoe.Rotation, aoe.Activation, aoe.Color, aoe.Risky);
if (!_finishedCast)
yield return new(aoe.Shape, rectEndPos, aoe.Rotation, aoe.Activation, aoe.Color, aoe.Risky);
else
yield return aoe;
}
else
{
Expand All @@ -69,32 +74,36 @@ public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if (spell.Action.ID != (uint)AID.SlipperyScatterscourge)
return;

var activation = WorldState.FutureTime(10);
_caster = caster;
_finishedCast = false;
_activeAOEs.Add(new(_shapeRect, _caster.Position, _caster.Rotation, activation, Colors.Danger));

var rectEndPosition = GetRectEndPosition(_caster.Position, _caster.Rotation, _shapeRect.LengthFront);

_activeAOEs.Add(new(_shapeDonut, rectEndPosition, default, activation));
_activeAOEs.Add(new(_shapeCircle, rectEndPosition, default, activation, Colors.SafeFromAOE, false));
_activeAOEs.Add(new(_shapeRect, caster.Position, caster.Rotation, activation, Colors.Danger));
_activeAOEs.Add(new(_shapeDonut, caster.Position, default, activation));
_activeAOEs.Add(new(_shapeCircle, caster.Position, default, activation, Colors.SafeFromAOE, false));
}

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if (spell.Action.ID == (uint)AID.SlipperyScatterscourge)
{
var activation = WorldState.FutureTime(10);
var index = _activeAOEs.FindIndex(aoe => aoe.Shape == _shapeDonut);
if (index != -1)
var finalPos = GetRectEndPosition(_caster.Position, _caster.Rotation, _shapeRect.LengthFront);
var futureActivation = WorldState.FutureTime(10);

for (int i = 0; i < _activeAOEs.Count; i++)
{
_activeAOEs[index] = new(_shapeDonut, _activeAOEs[index].Origin, _activeAOEs[index].Rotation, activation, Colors.Danger);
var circleIndex = _activeAOEs.FindIndex(aoe => aoe.Shape == _shapeCircle);
if (circleIndex != -1)
var aoe = _activeAOEs[i];
if (aoe.Shape == _shapeDonut)
{
_activeAOEs[i] = new(_shapeDonut, finalPos, aoe.Rotation, futureActivation, Colors.Danger);
}
else if (aoe.Shape == _shapeCircle)
{
_activeAOEs[circleIndex] = new(_shapeCircle, _activeAOEs[circleIndex].Origin, _activeAOEs[circleIndex].Rotation, activation, Colors.SafeFromAOE, false);
_activeAOEs[i] = new(_shapeCircle, finalPos, aoe.Rotation, futureActivation, Colors.SafeFromAOE, false);
}
}

_finishedCast = true;
}
else if (spell.Action.ID == (uint)AID.Scatterscourge2)
Expand All @@ -107,9 +116,7 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell)
public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if (spell.Action.ID == (uint)AID.WildCharge && _caster != null)
{
_activeAOEs.RemoveAll(aoe => aoe.Shape == _shapeRect);
}
}

private static WPos GetRectEndPosition(WPos origin, Angle rotation, float lengthFront)
Expand All @@ -121,7 +128,7 @@ private static WPos GetRectEndPosition(WPos origin, Angle rotation, float length
}
}

class PoisonGas(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.PoisonGas), "Applies Forced March!");
class PoisonGas(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.PoisonGas), "Raidwide & Forced March (13s)");

class PoisonGasMarch(BossModule module) : Components.StatusDrivenForcedMarch(module, 3, (uint)SID.ForwardMarch, (uint)SID.AboutFace, (uint)SID.LeftFace, (uint)SID.RightFace, 5)
{
Expand Down Expand Up @@ -158,5 +165,4 @@ public KeheniheyamewiStates(BossModule module) : base(module)
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Shinryin", GroupType = BossModuleInfo.GroupType.Hunt, GroupID = (uint)BossModuleInfo.HuntRank.A, NameID = 13401)]
public class Keheniheyamewi(WorldState ws, Actor primary) : SimpleBossModule(ws, primary);

public class Keheniheyamewi(WorldState ws, Actor primary) : SimpleBossModule(ws, primary);
79 changes: 32 additions & 47 deletions BossMod/Modules/Dawntrail/Hunt/RankA/Pkuucha.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,89 +17,74 @@ public enum AID : uint
PeckingFlurry = 39760, // Boss->self, 5.0s cast, range 40 circle
PeckingFlurry2 = 39761, // Boss->self, no cast, range 40 circle
}

class MesmerizingMarch(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.MesmerizingMarch), new AOEShapeCircle(12));
class StirringSamba(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.StirringSamba), new AOEShapeCone(40, 90.Degrees()));
class GlidingSwoop(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.GlidingSwoop), new AOEShapeRect(18, 8));
class MarchingSambaHint(BossModule module) : Components.CastHint(module, ActionID.MakeSpell(AID.MarchingSamba), "Get out, then behind!");
class PeckingFlurry(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.PeckingFlurry), "Raidwide (3x)");

class MarchingSamba(BossModule module) : Components.GenericAOEs(module)
{
private List<AOEInstance> _aoes = new();
private Actor? _caster;
private readonly List<AOEInstance> _activeAOEs = [];
private static readonly AOEShapeCircle _shapeCircle = new(12);
private static readonly AOEShapeCone _shapeCone = new(40, 90.Degrees());
private DateTime _castStartTime;
private bool _circleDangerSet;
private bool _coneDrawn;
private static readonly AOEShapeCircle _circle = new(12);
private static readonly AOEShapeCone _cone = new(40, 90.Degrees());

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor)
{
if (_caster == null)
yield break;

if (!_circleDangerSet && WorldState.CurrentTime >= _castStartTime.AddSeconds(4))
return _aoes;
var updated = new List<AOEInstance>();
foreach (var aoe in _aoes)
{
_activeAOEs[0] = new(_shapeCircle, _caster.Position, default, _castStartTime.AddSeconds(4), Colors.Danger);
_circleDangerSet = true;
}

if (!_coneDrawn && WorldState.CurrentTime >= _castStartTime.AddSeconds(7))
{
_activeAOEs.Add(new(_shapeCone, _caster.Position, _caster.Rotation, _castStartTime.AddSeconds(8), Colors.Danger));
_coneDrawn = true;
}

foreach (var aoe in _activeAOEs)
{
yield return aoe;
if (aoe.Shape == _circle || aoe.Shape == _cone)
updated.Add(new(aoe.Shape, _caster.Position, _caster.Rotation, aoe.Activation, aoe.Color, aoe.Risky));
else
updated.Add(aoe);
}
return updated;
}

public override void OnCastStarted(Actor caster, ActorCastInfo spell)
{
if (spell.Action.ID != (uint)AID.MarchingSamba)
if (caster != Module.PrimaryActor)
return;

_caster = caster;
_castStartTime = WorldState.CurrentTime;
_circleDangerSet = false;
_coneDrawn = false;
_activeAOEs.Add(new(_shapeCircle, _caster.Position, default, _castStartTime.AddSeconds(10), Risky: false));
if ((AID)spell.Action.ID is AID.MarchingSamba or AID.MesmerizingMarch)
{
_caster = caster;
_aoes.Add(new(_circle, caster.Position, caster.Rotation, WorldState.CurrentTime.AddSeconds(6.5f), Colors.Danger, true));
_aoes.Add(new(_cone, caster.Position, caster.Rotation, WorldState.CurrentTime.AddSeconds(8), Colors.AOE, true));
}
}

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
{
if (spell.Action.ID == (uint)AID.MesmerizingMarch2)
if (caster != Module.PrimaryActor)
return;
if ((AID)spell.Action.ID is AID.MesmerizingMarch or AID.MesmerizingMarch2)
{
_activeAOEs.RemoveAll(aoe => aoe.Shape == _shapeCircle);
_aoes.RemoveAll(a => a.Shape == _circle);
int idx = _aoes.FindIndex(a => a.Shape == _cone);
if (idx != -1)
{
var c = _aoes[idx];
_aoes[idx] = new(_cone, c.Origin, c.Rotation, c.Activation, Colors.Danger, true);
}
}
else if (spell.Action.ID == (uint)AID.StirringSamba2)
else if ((AID)spell.Action.ID is AID.StirringSamba or AID.StirringSamba2)
{
_activeAOEs.Clear();
_caster = null;
_circleDangerSet = false;
_coneDrawn = false;
_castStartTime = DateTime.MinValue;
_aoes.RemoveAll(a => a.Shape == _cone);
}
}
}

class PeckingFlurry(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.PeckingFlurry), "Raidwide x3!");

class PkuuchaStates : StateMachineBuilder
{
public PkuuchaStates(BossModule module) : base(module)
{
TrivialPhase()
.ActivateOnEnter<MesmerizingMarch>()
.ActivateOnEnter<StirringSamba>()
.ActivateOnEnter<GlidingSwoop>()
.ActivateOnEnter<MarchingSambaHint>()
.ActivateOnEnter<MarchingSamba>()
.ActivateOnEnter<PeckingFlurry>();
}
}

[ModuleInfo(BossModuleInfo.Maturity.Verified, Contributors = "Shinryin", GroupType = BossModuleInfo.GroupType.Hunt, GroupID = (uint)BossModuleInfo.HuntRank.A, NameID = 13443)]
public class Pkuucha(WorldState ws, Actor primary) : SimpleBossModule(ws, primary);
public class Pkuucha(WorldState ws, Actor primary) : SimpleBossModule(ws, primary);

0 comments on commit 6bc497b

Please sign in to comment.