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

[akechi/Utility] fixes, adjustments, & new additions #557

Merged
merged 34 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9b3f5aa
tweaks
Akechi-kun Dec 14, 2024
82c1137
Merge branch 'hmph' of https://github.com/Akechi-kun/ffxiv_bossmod in…
Akechi-kun Dec 14, 2024
630a145
Merge branch 'hmph' of https://github.com/Akechi-kun/ffxiv_bossmod in…
Akechi-kun Dec 14, 2024
e38e75f
xdd
Akechi-kun Dec 14, 2024
7255a30
xdd
Akechi-kun Dec 14, 2024
de6ce0b
xdd
Akechi-kun Dec 14, 2024
b7bf556
fix Github error
Akechi-kun Dec 14, 2024
1a1d867
DIves Strategy + major cleanup
Akechi-kun Dec 14, 2024
5a6d8e5
xdd
Akechi-kun Dec 14, 2024
15121cc
xdd
Akechi-kun Dec 14, 2024
eab48da
ok ok ok ok done
Akechi-kun Dec 14, 2024
f7200ce
hoo boy some big changes to my modules :)
Akechi-kun Dec 18, 2024
82bcb1b
more tweaks & cleanup for DRG
Akechi-kun Dec 18, 2024
500a79c
Blasting Zone & Continuation post-refactor fixes
Akechi-kun Dec 19, 2024
fca9d6b
Merge branch 'awgil:master' into hmph
Akechi-kun Dec 19, 2024
be99c5f
Utility: DRK Oblation & TBN status fixes
Akechi-kun Dec 21, 2024
752c36e
Utility: PLD Cover targeting fix
Akechi-kun Dec 21, 2024
fd788cb
Utility: GNB Aurora fix
Akechi-kun Dec 21, 2024
a0b4b62
fuck it we just fix all Utility targeting shit
Akechi-kun Dec 21, 2024
30bcee6
last little tweaks i can think of for now, looking super spiffy
Akechi-kun Dec 21, 2024
480fcf6
Sacred Soil fix
Akechi-kun Dec 24, 2024
c53725e
.
Akechi-kun Dec 24, 2024
351750d
Merge branch 'awgil:master' into hmph
Akechi-kun Dec 24, 2024
18e21cb
AST Earthly Star addition
Akechi-kun Dec 25, 2024
57e0c26
NIN Shukuchi addition
Akechi-kun Dec 25, 2024
6674d37
SCH WIP
Akechi-kun Dec 25, 2024
3f6c88d
AkechiSCH done
Akechi-kun Dec 25, 2024
1128228
Energy Drain planning
Akechi-kun Dec 25, 2024
c605c84
oh, this is an oGCD lol
Akechi-kun Dec 25, 2024
525d636
SCH ok
Akechi-kun Dec 26, 2024
0199c12
NM fixes
Akechi-kun Dec 26, 2024
271d5c6
actual nm fixes
Akechi-kun Dec 26, 2024
36ac1c0
leeway for 9th GCD
Akechi-kun Dec 26, 2024
df2559d
Merge branch 'awgil:master' into hmph
Akechi-kun Dec 29, 2024
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
10 changes: 9 additions & 1 deletion BossMod/ActionQueue/Healers/SCH.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,18 @@ public enum SID : uint
Sleep = 3, // applied by Repose to target
BanefulImpaction = 3883, // applied by Baneful Impaction to target
ImpactImminent = 3882, // applied by Chain Stratagem to self
ChainStratagem = 1221, // applied by Chain Stratagem to target
FeyUnion = 1222, // applied by Aetherpact to target
Seraphism = 3884, // applied by Seraphism to self

//Shared
Swiftcast = ClassShared.SID.Swiftcast, // applied by Swiftcast to self
}

public sealed class Definitions : IDisposable
{
private readonly SCHConfig _config = Service.Config.Get<SCHConfig>();

public Definitions(ActionDefinitions d)
{
d.RegisterSpell(AID.AngelFeathers, castAnimLock: 8.10f); // animLock=8.100s?
Expand Down Expand Up @@ -159,6 +164,9 @@ public void Dispose() { }

private void Customize(ActionDefinitions d)
{
// *** add any properties that can't be autogenerated here ***
d.Spell(AID.Broil1)!.ForbidExecute = (ws, player, _, _) => _config.ForbidEarlyBroil && !player.InCombat && ws.Client.CountdownRemaining > 1.5f;
d.Spell(AID.Broil2)!.ForbidExecute = (ws, player, _, _) => _config.ForbidEarlyBroil && !player.InCombat && ws.Client.CountdownRemaining > 1.5f;
d.Spell(AID.Broil3)!.ForbidExecute = (ws, player, _, _) => _config.ForbidEarlyBroil && !player.InCombat && ws.Client.CountdownRemaining > 1.5f;
d.Spell(AID.Broil4)!.ForbidExecute = (ws, player, _, _) => _config.ForbidEarlyBroil && !player.InCombat && ws.Client.CountdownRemaining > 1.5f;
}
}
1 change: 1 addition & 0 deletions BossMod/ActionQueue/Melee/DRG.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public enum SID : uint
NastrondReady = 3844, // applied by Geirskogul to self
DragonsFlight = 3845, // applied by Dragonfire Dive to self
StarcrossReady = 3846, // applied by Stardiver to self
EnhancedPiercingTalon = 1870, // applied by Elusive Jump to self

//Shared
Feint = ClassShared.SID.Feint, // applied by Feint to target
Expand Down
1 change: 1 addition & 0 deletions BossMod/ActionQueue/Melee/SAM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public enum SID : uint
Tengentsu = 3853, // applied by Tengentsu to self
ZanshinReady = 3855, // applied by Ikishoten to self
Tendo = 3856, // applied by Meikyo Shisui to self
TsubameReady = 4216, // applied by Midare Setsugekka to self

//Shared
Feint = ClassShared.SID.Feint, // applied by Feint to target
Expand Down
15 changes: 8 additions & 7 deletions BossMod/ActionQueue/Tanks/DRK.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,14 @@ public enum TraitID : uint
public enum SID : uint
{
None = 0,
Oblation = 2682,
BloodWeapon = 742,
Grit = 743,
SaltedEarth = 749,
Delirium = 1972,
EnhancedDelirium = 3836,
Scorn = 3837,
BloodWeapon = 742, // applied by BloodWeapon to self
Grit = 743, // applied by Grit to self
SaltedEarth = 749, // applied by Salted Earth
TheBlackestNight = 1308, // applied by The Blackest Night to target
Delirium = 1972, // applied by Delirium to self
Oblation = 2682, // applied by Oblation to target
EnhancedDelirium = 3836, // applied by Delirium to self (Lv96+)
Scorn = 3837, // applied by Living Shadow to self

//Shared
Reprisal = ClassShared.SID.Reprisal, // applied by Reprisal to target
Expand Down
8 changes: 8 additions & 0 deletions BossMod/ActionTweaks/ClassActions/SCHConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace BossMod;

[ConfigDisplay(Parent = typeof(ActionTweaksConfig))]
class SCHConfig : ConfigNode
{
[PropertyDisplay("Prevent use of 'Broil' too early when in pre-pull")]
public bool ForbidEarlyBroil = true;
}
101 changes: 90 additions & 11 deletions BossMod/Autorotation/Utility/ClassASTUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

public sealed class ClassASTUtility(RotationModuleManager manager, Actor player) : RoleHealerUtility(manager, player)
{
public enum Track { Helios = SharedTrack.Count, Lightspeed, BeneficII, EssentialDignity, AspectedBenefic, AspectedHelios, Synastry, CollectiveUnconscious, CelestialOpposition, CelestialIntersection, Horoscope, NeutralSect, Exaltation, Macrocosmos, SunSign }
public enum Track { Helios = SharedTrack.Count, Lightspeed, BeneficII, EssentialDignity, AspectedBenefic, AspectedHelios, Synastry, CollectiveUnconscious, CelestialOpposition, EarthlyStar, CelestialIntersection, Horoscope, NeutralSect, Exaltation, Macrocosmos, SunSign }
public enum StarOption { None, Use, End }
public enum HoroscopeOption { None, Use, End }
public enum MacrocosmosOption { None, Use, End }
public enum HeliosOption { None, Use, UseEx }
public bool HasEffect<SID>(SID sid) where SID : Enum => Player.FindStatus((uint)(object)sid, Player.InstanceID) != null; //Checks if Status effect is on self
public float GetStatusDetail(Actor target, AST.SID sid) => StatusDetails(target, sid, Player.InstanceID).Left; //Checks if Status effect is on target
public bool HasEffect(Actor target, AST.SID sid, float duration) => GetStatusDetail(target, sid) < duration; //Checks if anyone has a status effect
public Actor? TargetChoice(StrategyValues.OptionRef strategy) => ResolveTargetOverride(strategy.Value);

public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(AST.AID.AstralStasis);

Expand All @@ -30,6 +33,13 @@ public static RotationModuleDefinition Definition()
DefineSimpleConfig(res, Track.Synastry, "Synastry", "", 200, AST.AID.Synastry, 20); //ST oGCD "kardia"-like heal, 120s CD, 20s effect duration
DefineSimpleConfig(res, Track.CollectiveUnconscious, "CollectiveUnconscious", "C.Uncon", 100, AST.AID.CollectiveUnconscious, 5); //AoE oGCD mit/regen, 60s CD, 5s mitigation / 15s regen effect durations
DefineSimpleConfig(res, Track.CelestialOpposition, "CelestialOpposition", "C.Oppo", 100, AST.AID.CelestialOpposition, 15); //AoE oGCD heal/regen, 60s CD, 15s effect duration

res.Define(Track.EarthlyStar).As<StarOption>("EarthlyStar", "E.Star", 200) //AoE GCD heal, 60s CD, 10s + 10s effect duration
.AddOption(StarOption.None, "None", "Do not use automatically")
.AddOption(StarOption.Use, "Earthly Star", "Use Earthly Star", 60, 10, ActionTargets.Hostile, 62)
.AddOption(StarOption.End, "Stellar Detonation", "Use Stellar Detonation", 0, 1, ActionTargets.Hostile, 62)
.AddAssociatedActions(AST.AID.EarthlyStar, AST.AID.StellarDetonation);

DefineSimpleConfig(res, Track.CelestialIntersection, "CelestialIntersection", "C.Inter", 100, AST.AID.CelestialIntersection, 30); //ST oGCD heal/shield, 30s CD (60s Total), 2 charges

res.Define(Track.Horoscope).As<HoroscopeOption>("Horoscope", "Horo", 130) //Conditional AoE heal, 60s CD, 30s effect duration
Expand All @@ -56,19 +66,29 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
{
ExecuteShared(strategy, IDLimitBreak3, primaryTarget);
ExecuteSimple(strategy.Option(Track.Lightspeed), AST.AID.Lightspeed, Player);
ExecuteSimple(strategy.Option(Track.BeneficII), AST.AID.BeneficII, primaryTarget ?? Player);
ExecuteSimple(strategy.Option(Track.EssentialDignity), AST.AID.EssentialDignity, primaryTarget ?? Player);
ExecuteSimple(strategy.Option(Track.AspectedBenefic), AST.AID.AspectedBenefic, primaryTarget ?? Player);
ExecuteSimple(strategy.Option(Track.Synastry), AST.AID.Synastry, primaryTarget ?? Player);
ExecuteSimple(strategy.Option(Track.BeneficII), AST.AID.BeneficII, TargetChoice(strategy.Option(Track.BeneficII)) ?? Player);
ExecuteSimple(strategy.Option(Track.EssentialDignity), AST.AID.EssentialDignity, TargetChoice(strategy.Option(Track.EssentialDignity)) ?? Player);
ExecuteSimple(strategy.Option(Track.AspectedBenefic), AST.AID.AspectedBenefic, TargetChoice(strategy.Option(Track.AspectedBenefic)) ?? Player);
ExecuteSimple(strategy.Option(Track.Synastry), AST.AID.Synastry, TargetChoice(strategy.Option(Track.Synastry)) ?? Player);
ExecuteSimple(strategy.Option(Track.CollectiveUnconscious), AST.AID.CollectiveUnconscious, Player);
ExecuteSimple(strategy.Option(Track.CelestialOpposition), AST.AID.CelestialOpposition, Player);
ExecuteSimple(strategy.Option(Track.CelestialIntersection), AST.AID.CelestialIntersection, Player);
ExecuteSimple(strategy.Option(Track.NeutralSect), AST.AID.NeutralSect, Player);
ExecuteSimple(strategy.Option(Track.Exaltation), AST.AID.Exaltation, primaryTarget ?? Player);
ExecuteSimple(strategy.Option(Track.Exaltation), AST.AID.Exaltation, TargetChoice(strategy.Option(Track.Exaltation)) ?? Player);
ExecuteSimple(strategy.Option(Track.SunSign), AST.AID.SunSign, Player);

var star = strategy.Option(Track.EarthlyStar);
var starAction = star.As<StarOption>() switch
{
StarOption.Use => AST.AID.EarthlyStar,
StarOption.End => AST.AID.StellarDetonation,
_ => default
};
if (starAction != default)
QueueOGCD(starAction, TargetChoice(star) ?? primaryTarget ?? Player);

//Aspected Helios full execution
var heliosUp = HasEffect(AST.SID.AspectedHelios) || HasEffect(AST.SID.HeliosConjunction);
var heliosUp = HasEffect(Player, AST.SID.AspectedHelios, 15) || HasEffect(Player, AST.SID.HeliosConjunction, 15);
var helios = strategy.Option(Track.AspectedHelios);
var heliosAction = helios.As<HeliosOption>() switch
{
Expand All @@ -77,7 +97,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
_ => default
};
if (heliosAction != default && !heliosUp)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(heliosAction), Player, helios.Priority(), helios.Value.ExpireIn);
QueueGCD(heliosAction, Player);

//Horoscope full execution
var horo = strategy.Option(Track.Horoscope);
Expand All @@ -88,7 +108,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
_ => default
};
if (horoAction != default)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(horoAction), Player, horo.Priority(), horo.Value.ExpireIn);
QueueOGCD(horoAction, Player);

var cosmos = strategy.Option(Track.Macrocosmos);
var cosmosAction = cosmos.As<MacrocosmosOption>() switch
Expand All @@ -98,7 +118,66 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
_ => default
};
if (cosmosAction != default)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(cosmosAction), Player, cosmos.Priority(), cosmos.Value.ExpireIn);
QueueOGCD(cosmosAction, primaryTarget);
}

#region Core Execution Helpers

public AST.AID NextGCD; //Next global cooldown action to be used
public void QueueGCD<P>(AST.AID aid, Actor? target, P priority, float delay = 0) where P : Enum
=> QueueGCD(aid, target, (int)(object)priority, delay);

public void QueueGCD(AST.AID aid, Actor? target, int priority = 8, float delay = 0)
{
var NextGCDPrio = 0;

if (priority == 0)
return;

if (QueueAction(aid, target, ActionQueue.Priority.High, delay) && priority > NextGCDPrio)
{
NextGCD = aid;
}
}

public void QueueOGCD<P>(AST.AID aid, Actor? target, P priority, float delay = 0) where P : Enum
=> QueueOGCD(aid, target, (int)(object)priority, delay);

public void QueueOGCD(AST.AID aid, Actor? target, int priority = 4, float delay = 0)
{
if (priority == 0)
return;

QueueAction(aid, target, ActionQueue.Priority.Medium + priority, delay);
}

public bool QueueAction(AST.AID aid, Actor? target, float priority, float delay)
{
if ((uint)(object)aid == 0)
return false;

var def = ActionDefinitions.Instance.Spell(aid);
if (def == null)
return false;

if (def.Range != 0 && target == null)
{
return false;
}

Vector3 targetPos = default;

if (def.AllowedTargets.HasFlag(ActionTargets.Area))
{
if (def.Range == 0)
targetPos = Player.PosRot.XYZ();
else if (target != null)
targetPos = target.PosRot.XYZ();
}

Hints.ActionsToExecute.Push(ActionID.MakeSpell(aid), target, priority, delay: delay, targetPos: targetPos);
return true;
}
#endregion

}
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassBLMUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
var dashTarget = ResolveTargetOverride(dash.Value) ?? primaryTarget; //Smart-Targeting
var dashStrategy = strategy.Option(Track.AetherialManipulation).As<DashStrategy>();
if (ShouldUseDash(dashStrategy, dashTarget))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(BLM.AID.AetherialManipulation), dashTarget, dash.Priority());
Hints.ActionsToExecute.Push(ActionID.MakeSpell(BLM.AID.AetherialManipulation), dashTarget, dash.Priority(), dash.Value.ExpireIn);
}
private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch
{
Expand Down
12 changes: 7 additions & 5 deletions BossMod/Autorotation/Utility/ClassDRGUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
public sealed class ClassDRGUtility(RotationModuleManager manager, Actor player) : RoleMeleeUtility(manager, player)
{
public enum Track { WingedGlide = SharedTrack.Count }
public enum DashStrategy { None, GapClose }
public bool InMeleeRange(Actor? target) => Player.DistanceToHitbox(target) <= 3; //Checks if we're inside melee range
public enum DashStrategy { None, GapClose, GapCloseHold1 }

public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(DRG.AID.DragonsongDive);

Expand All @@ -15,7 +14,8 @@ public static RotationModuleDefinition Definition()

res.Define(Track.WingedGlide).As<DashStrategy>("Winged Glide", "Dash", 20)
.AddOption(DashStrategy.None, "Automatic", "No use.")
.AddOption(DashStrategy.GapClose, "GapClose", "Use as gapcloser if outside melee range", 60, 0, ActionTargets.Hostile, 45)
.AddOption(DashStrategy.GapClose, "GapClose", "Use Winged Glide as gapcloser if outside melee range", 60, 0, ActionTargets.Hostile, 45)
.AddOption(DashStrategy.GapCloseHold1, "GapCloseHold1", "Use Winged Glide as gapcloser if outside melee range; conserves 1 charge for manual usage", 60, 0, ActionTargets.Hostile, 84)
.AddAssociatedActions(DRG.AID.WingedGlide);

return res;
Expand All @@ -26,14 +26,16 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
ExecuteShared(strategy, IDLimitBreak3, primaryTarget);

var dash = strategy.Option(Track.WingedGlide);
var dashTarget = ResolveTargetOverride(dash.Value) ?? primaryTarget;
var dashStrategy = strategy.Option(Track.WingedGlide).As<DashStrategy>();
if (ShouldUseDash(dashStrategy, primaryTarget))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRG.AID.WingedGlide), primaryTarget, dash.Priority());
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRG.AID.WingedGlide), dashTarget, dash.Priority(), dash.Value.ExpireIn);
}
private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch
{
DashStrategy.None => false,
DashStrategy.GapClose => !InMeleeRange(primaryTarget),
DashStrategy.GapClose => Player.DistanceToHitbox(primaryTarget) is > 3 and <= 20,
DashStrategy.GapCloseHold1 => Player.DistanceToHitbox(primaryTarget) is > 3 and <= 20 && World.Client.Cooldowns[ActionDefinitions.Instance.Spell(DRG.AID.WingedGlide)!.MainCooldownGroup].Remaining <= 59.9f,
_ => false,
};
}
36 changes: 18 additions & 18 deletions BossMod/Autorotation/Utility/ClassDRKUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
public sealed class ClassDRKUtility(RotationModuleManager manager, Actor player) : RoleTankUtility(manager, player)
{
public enum Track { DarkMind = SharedTrack.Count, ShadowWall, LivingDead, TheBlackestNight, Oblation, DarkMissionary, Shadowstride }
public enum WallOption { None, ShadowWall, ShadowedVigil }
public enum TBNStrategy { None, Force }
public enum OblationStrategy { None, Force }
public enum WallOption { None, ShadowWall, ShadowedVigil } //ShadowWall strategy
public enum TBNStrategy { None, Force } //TheBlackestNight strategy
public enum OblationStrategy { None, Force } //Oblation strategy
public enum DashStrategy { None, GapClose } //GapCloser strategy
public bool InMeleeRange(Actor? target) => Player.DistanceToHitbox(target) <= 3; //Checks if we're inside melee range
public bool TargetHasEffect<SID>(Actor target, SID sid) where SID : Enum => target?.FindStatus((uint)(object)sid, Player.InstanceID) != null; //Checks if Status effect is on target
public float GetStatusDetail(Actor target, DRK.SID sid) => StatusDetails(target, sid, Player.InstanceID).Left; //Checks if Status effect is on target
public bool HasEffect(Actor target, DRK.SID sid, float duration) => GetStatusDetail(target, sid) < duration; //Checks if anyone has a status effect

public static readonly ActionID IDLimitBreak3 = ActionID.MakeSpell(DRK.AID.DarkForce);
public static readonly ActionID IDStanceApply = ActionID.MakeSpell(DRK.AID.Grit);
Expand Down Expand Up @@ -57,28 +58,24 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
ExecuteSimple(strategy.Option(Track.DarkMissionary), DRK.AID.DarkMissionary, Player); //Execution of DarkMissionary

//TBN execution
var canTBN = ActionUnlocked(ActionID.MakeSpell(DRK.AID.TheBlackestNight)) && Player.HPMP.CurMP >= 3000;
var tbn = strategy.Option(Track.TheBlackestNight);
var tbnTarget = ResolveTargetOverride(tbn.Value) ?? CoTank() ?? primaryTarget ?? Player; //Smart-Targets Co-Tank if set to Automatic, if no Co-Tank then targets self
var tbnight = tbn.As<TBNStrategy>() switch
{
TBNStrategy.Force => DRK.AID.TheBlackestNight,
_ => default
};
if (tbnight != default && Player.HPMP.CurMP >= 3000)
if (tbn.As<TBNStrategy>() == TBNStrategy.Force &&
canTBN &&
!HasEffect(tbnTarget, DRK.SID.TheBlackestNight, 7))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.TheBlackestNight), tbnTarget, tbn.Priority(), tbn.Value.ExpireIn);

//Oblation execution
var canObl = ActionUnlocked(ActionID.MakeSpell(DRK.AID.Oblation));
var obl = strategy.Option(Track.Oblation);
var oblTarget = ResolveTargetOverride(obl.Value) ?? primaryTarget ?? Player; //Smart-Targets Co-Tank if set to Automatic, if no Co-Tank then targets self
var oblStatus = TargetHasEffect(oblTarget, DRK.SID.Oblation); //Checks if status is present
var oblat = obl.As<OblationStrategy>() switch
{
OblationStrategy.Force => DRK.AID.Oblation,
_ => default
};
if (oblat != default && !oblStatus)
if (obl.As<OblationStrategy>() == OblationStrategy.Force &&
canObl &&
!HasEffect(oblTarget, DRK.SID.Oblation, 9))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Oblation), oblTarget, obl.Priority(), obl.Value.ExpireIn);

//Shadow Wall / Vigil execution
var wall = strategy.Option(Track.ShadowWall);
var wallAction = wall.As<WallOption>() switch
{
Expand All @@ -89,9 +86,12 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
if (wallAction != default)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(wallAction), Player, wall.Priority(), wall.Value.ExpireIn); //Checking proper use of said option

//Shadowstride execution
var dash = strategy.Option(Track.Shadowstride);
var dashTarget = ResolveTargetOverride(dash.Value) ?? primaryTarget;
var dashStrategy = strategy.Option(Track.Shadowstride).As<DashStrategy>();
if (ShouldUseDash(dashStrategy, primaryTarget))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), primaryTarget, obl.Priority());
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), dashTarget, dash.Priority(), dash.Value.ExpireIn);
}
private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch
{
Expand Down
Loading
Loading