Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DT dungeon fixes #382

Merged
merged 6 commits into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BossMod/AI/AIBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void UpdateMovement(Actor player, Actor master, Targeting target, Action
var toDest = _naviDecision.Destination != null ? _naviDecision.Destination.Value - player.Position : new();
var distSq = toDest.LengthSq();
ctrl.NaviTargetPos = _naviDecision.Destination;
//_ctrl.NaviTargetRot = distSq >= 0.01f ? toDest.Normalized() : null;
ctrl.NaviTargetRot = null;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly no idea what should be here. Don't mind it...

ctrl.NaviTargetVertical = master != player ? master.PosRot.Y : null;
ctrl.AllowInterruptingCastByMovement = player.CastInfo != null && _naviDecision.LeewaySeconds <= (player.CastInfo.FinishAt - WorldState.CurrentTime).TotalSeconds - 0.5;
ctrl.ForceCancelCast = player.CastInfo != null && TargetIsForbidden(player.CastInfo.TargetID);
Expand Down
81 changes: 31 additions & 50 deletions BossMod/Modules/Dawntrail/Dungeon/D01Ihuykatumu/D013Apollyon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,78 +30,57 @@ class Blade(BossModule module) : Components.SingleTargetCast(module, ActionID.Ma
class HighWind(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.HighWind));
class BladesOfFamine(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.BladesOfFamine), new AOEShapeRect(50, 6));
class WingOfLightning(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WingOfLightning), new AOEShapeCone(40, 22.5f.Degrees()), maxCasts: 8);
class LightningHelper(BossModule module) : Components.PersistentVoidzone(module, 4, m => m.Enemies(OID.LightningAOE));
class LightningHelper(BossModule module) : Components.PersistentVoidzone(module, 4, m => m.Enemies(OID.LightningAOE).Where(x => x.EventState != 7));
class ThunderIII(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.ThunderIII), 6);
class BladeAOE(BossModule module) : Components.BaitAwayCast(module, ActionID.MakeSpell(AID.BladeAOE), new AOEShapeCircle(6), centerAtTarget: true);
class WindSickle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WindSickle), new AOEShapeDonut(6, 60));
class WindSickle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.WindSickle), new AOEShapeDonut(5, 60));
class RazorStorm(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.RazorStorm), new AOEShapeRect(40, 20));
class Levinsickle(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.Levinsickle), 4);
class LevinsickleSpark(BossModule module) : Components.LocationTargetedAOEs(module, ActionID.MakeSpell(AID.LevinsickleSpark), 4);

// first aoe is 10 seconds after windwhistle
// rest are 8 seconds after previous
class Whirlwind(BossModule module) : Components.GenericAOEs(module)
class CuttingWind(BossModule module) : Components.GenericAOEs(module)
{
private int _activations;
private DateTime _nextActivation;
private readonly List<AOEInstance> _aoes = [];
private static readonly AOEShapeRect Shape = new(36, 4, 36);

public override IEnumerable<AOEInstance> ActiveAOEs(int slot, Actor actor) => _aoes.Take(4);

private readonly List<WPos> _northPositions = [new(-111.69f, 253.94f), new(-102.28f, 264.31f), new(-108.92f, 276.53f)];
private readonly List<WPos> _southPositions = [new(-102.93f, 274.36f), new(-108.68f, 262.22f), new(-105.73f, 252.34f)];

private static readonly float[] CastTimers = [8.9f, 16.9f, 24.9f];
private static readonly List<Angle> Rotations = [0.Degrees(), 45.Degrees(), 90.Degrees(), 135.Degrees()];

public override void OnCastFinished(Actor caster, ActorCastInfo spell)
private void AddAOEs(WPos pos, float delay)
{
if ((AID)spell.Action.ID == AID.Windwhistle)
_nextActivation = WorldState.FutureTime(10);
foreach (var angle in Rotations)
_aoes.Add(new(Shape, pos, angle, Module.WorldState.FutureTime(delay)));
}

public override void DrawArenaBackground(int pcSlot, Actor pc)
public override void OnActorCreated(Actor actor)
{
foreach (var c in ActiveAOEs(pcSlot, pc))
if ((OID)actor.OID == OID.Whirlwind)
{
c.Shape.Draw(Arena, c.Origin, c.Rotation, c.Color);
c.Shape.Outline(Arena, c.Origin, c.Rotation, ArenaColor.AOE);
var coords = actor.Position.Z < 265 ? _northPositions : _southPositions;
foreach (var (c, d) in coords.Zip(CastTimers))
AddAOEs(c, d);
}
}

public override void OnEventCast(Actor caster, ActorCastEvent spell)
{
if ((AID)spell.Action.ID == AID.Cuttingwind)
{
_activations += 1;
_nextActivation = WorldState.FutureTime(8);
}
}

public override void OnActorDestroyed(Actor actor)
{
_activations = 0;
_nextActivation = default;
}

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

var whirlwind = Module.Enemies(OID.Whirlwind).FirstOrDefault();
if (whirlwind == null)
yield break;

var whirlyHelper = Module.Enemies(OID.Helper).FirstOrDefault(x => x.NameID == 12715);
if (whirlyHelper == null)
yield break;

foreach (var angle in Rotations)
{
yield return new AOEInstance(new AOEShapeRect(72, 4, 72), whirlwind.Position, angle, _nextActivation, Shade(_nextActivation), _nextActivation < WorldState.FutureTime(4));
}
if (_aoes.Count > 0 && (AID)spell.Action.ID == AID.Cuttingwind)
_aoes.RemoveAt(0);
}
}

private uint Shade(DateTime activation)
class Whirlwind(BossModule module) : Components.PersistentVoidzone(module, 4, m => m.Enemies(OID.Whirlwind))
{
public override void AddAIHints(int slot, Actor actor, PartyRolesConfig.Assignment assignment, AIHints hints)
{
var clampedETA = Math.Clamp((activation - WorldState.CurrentTime).TotalSeconds, 0, 4);
var opacity = 1 - clampedETA / 4;
var alpha = (uint)(opacity * 96) + 32;
return 0x008080 + alpha * 0x1000000;
base.AddAIHints(slot, actor, assignment, hints);
if (Sources(Module).FirstOrDefault() is Actor w)
hints.AddForbiddenZone(new AOEShapeRect(6, 4, 4), w.Position, w.Rotation);
}
}

Expand All @@ -122,7 +101,9 @@ public D013ApollyonStates(BossModule module) : base(module)
.ActivateOnEnter<RazorStorm>()
.ActivateOnEnter<Levinsickle>()
.ActivateOnEnter<LevinsickleSpark>()
.ActivateOnEnter<Whirlwind>();
.ActivateOnEnter<CuttingWind>()
.ActivateOnEnter<Whirlwind>()
;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public enum AID : uint

public enum SID : uint
{
// frozen adds always get both 3944 and 3445, no idea what the difference is. i just picked my favorite
Frozen = 3944, // none->_Gen_RorrlohTeh/_Gen_QorrlohTeh1, extra=0x0
Frozen2 = 3445
}

class FrostingFracas(BossModule module) : Components.RaidwideCast(module, ActionID.MakeSpell(AID.FrostingFracas));
Expand Down Expand Up @@ -64,7 +64,7 @@ public override void OnCastFinished(Actor caster, ActorCastInfo spell)

public override void OnStatusGain(Actor actor, ActorStatus status)
{
if ((SID)status.ID is SID.Frozen && _casters.ContainsKey(actor))
if ((SID)status.ID is SID.Frozen or SID.Frozen2 && _casters.ContainsKey(actor))
{
_casters[actor] = true;
_numFrozen += 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public override void AddHints(int slot, Actor actor, TextHints hints)
}
}
class SeedCrystals(BossModule module) : Components.SpreadFromCastTargets(module, ActionID.MakeSpell(AID.SeedCrystals), 6);
class CyclonicRing(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.CyclonicRing), new AOEShapeDonut(15, 40));
class CyclonicRing(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.CyclonicRing), new AOEShapeDonut(7.5f, 40));
class StalagmiteCircle(BossModule module) : Components.SelfTargetedAOEs(module, ActionID.MakeSpell(AID.StalagmiteCircle), new AOEShapeCircle(15));
class EyeOfTheFierce(BossModule module) : Components.CastGaze(module, ActionID.MakeSpell(AID.EyeOfTheFierce));

Expand Down
Loading