Skip to content

Commit

Permalink
Merge pull request #385 from FFXIV-CombatReborn/mergeWIP
Browse files Browse the repository at this point in the history
merge VBM
  • Loading branch information
CarnifexOptimus authored Oct 1, 2024
2 parents 3157c52 + 99430a6 commit 1ab6193
Show file tree
Hide file tree
Showing 61 changed files with 1,260 additions and 109 deletions.
2 changes: 1 addition & 1 deletion BossMod/AI/AIBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private Targeting SelectPrimaryTarget(Actor player, Actor master)
// now give class module a chance to improve targeting
// typically it would switch targets for multidotting, or to hit more targets with AOE
// in case of ties, it should prefer to return original target - this would prevent useless switches
var targeting = new Targeting(target!, autorot.Hints.RecommendedRangeToTarget - 0.1f);
var targeting = new Targeting(target!, player.Role is Role.Melee or Role.Tank ? 2.9f : 24.5f);

var pos = autorot.Hints.RecommendedPositional;
if (pos.Target != null && targeting.Target.Actor == pos.Target)
Expand Down
4 changes: 2 additions & 2 deletions BossMod/AI/AIRotationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace BossMod.AI;

public abstract class AIRotationModule(RotationModuleManager manager, Actor player) : RotationModule(manager, player)
{
protected float Deadline(DateTime deadline) => Math.Max(0, (float)(deadline - Manager.WorldState.CurrentTime).TotalSeconds);
protected float Deadline(DateTime deadline) => Math.Max(0, (float)(deadline - World.CurrentTime).TotalSeconds);
protected float Speed() => Player.FindStatus(50) != null ? 7.8f : 6;

protected bool InMeleeRange(Actor target)
Expand Down Expand Up @@ -47,7 +47,7 @@ protected WPos MoveTarget(Actor target, WPos desired, float nextAction, float ta
var playerDotTargetMove = targetMoveDir.Dot(ideal - Player.Position);
if (playerDotTargetMove < 0)
ideal -= playerDotTargetMove * targetMoveDir; // don't move towards boss, though
var targetRemaining = (ideal - target.Position).Length() - target.HitboxRadius - targetMeleeRange - (target.Position - target.PrevPosition).Length() / Manager.WorldState.Frame.Duration * nextAction - Speed() * nextAction;
var targetRemaining = (ideal - target.Position).Length() - target.HitboxRadius - targetMeleeRange - (target.Position - target.PrevPosition).Length() / World.Frame.Duration * nextAction - Speed() * nextAction;
if (targetRemaining > 0)
ideal += targetRemaining * (target.Position - ideal).Normalized();
return ideal;
Expand Down
3 changes: 3 additions & 0 deletions BossMod/ActionTweaks/ActionTweaksConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public enum ModifierKey
[PropertyDisplay("Use custom queueing for manually pressed actions", tooltip: "This setting allows better integration with autorotations and will prevent you from triple-weaving or drifting GCDs if you press a healing ability while autorotation is going on")]
public bool UseManualQueue = false;

[PropertyDisplay("Automatically manage auto attacks", tooltip: "This setting prevents starting autos early during countdown, starts them automatically at pull, when switching targets and when using any actions that don't explicitly cancel autos.")]
public bool AutoAutos = false;

[PropertyDisplay("Automatically dismount to execute actions")]
public bool AutoDismount = true;

Expand Down
38 changes: 38 additions & 0 deletions BossMod/ActionTweaks/AutoAutosTweak.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace BossMod;

// This tweak controls auto attacks to prevent early pulls and to enable them asap when pulling, changing targets or starting casts.
public sealed class AutoAutosTweak(WorldState ws, AIHints hints)
{
private readonly ActionTweaksConfig _config = Service.Config.Get<ActionTweaksConfig>();
private bool _lastActionDisabledAutos;

public const float PrePullThreshold = 0.5f; // effect result delay for autos

public bool Enabled => _config.AutoAutos;

public bool ShouldPreventAutoActivation(uint spellId)
{
var actionData = Service.LuminaRow<Lumina.Excel.GeneratedSheets.Action>(spellId);
_lastActionDisabledAutos = actionData?.Unknown50 is 3 or 6 or 7;
return Enabled && ws.Client.CountdownRemaining > PrePullThreshold && !(ws.Party.Player()?.InCombat ?? false);
}

public bool GetDesiredState(bool currentState)
{
if (!Enabled || _lastActionDisabledAutos)
return currentState;

var player = ws.Party.Player();
if (player == null || player.Statuses.Any(s => s.ID is 418 or 2648)) // transcendent
return currentState;

var target = ws.Actors.Find(player.TargetID);
if (target == null || target.IsAlly)
return currentState;

if (_config.PyreticThreshold > 0 && hints.ImminentSpecialMode.mode == AIHints.SpecialMode.Pyretic && hints.ImminentSpecialMode.activation < ws.FutureTime(_config.PyreticThreshold))
return false; // pyretic => disable autos

return player.InCombat || ws.Client.CountdownRemaining <= PrePullThreshold; // no reason not to enable autos!
}
}
2 changes: 1 addition & 1 deletion BossMod/ActionTweaks/OutOfCombatActionsTweak.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace BossMod;

[ConfigDisplay(Name = "Automatic out-of-combat utility actions", Parent = typeof(ActionTweaksConfig))]
[ConfigDisplay(Name = "Automatic out-of-combat utility actions", Parent = typeof(ActionTweaksConfig), Since = "7.2.0.146")]
class OutOfCombatActionsConfig : ConfigNode
{
[PropertyDisplay("Enable the feature")]
Expand Down
2 changes: 1 addition & 1 deletion BossMod/ActionTweaks/SmartRotationTweak.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace BossMod;

[ConfigDisplay(Name = "Smart character orientation", Parent = typeof(ActionTweaksConfig))]
[ConfigDisplay(Name = "Smart character orientation", Parent = typeof(ActionTweaksConfig), Since = "7.2.0.146")]
class SmartRotationConfig : ConfigNode
{
[PropertyDisplay("Enable the feature", tooltip: "Replace in-game 'auto face target' option with a smarter alternative.\nWhen using an action, changes direction only if target is not in frontal cone.\nDuring cast, keep character facing the target.")]
Expand Down
1 change: 0 additions & 1 deletion BossMod/Autorotation/RotationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public ConfigRef<Index> AddAssociatedActions<AID>(params AID[] aids) where AID :

// base class for rotation modules
// each rotation module should contain a `public static RotationModuleDefinition Definition()` function
// TODO: i don't think it should know about manager, rework this...
public abstract class RotationModule(RotationModuleManager manager, Actor player)
{
public readonly RotationModuleManager Manager = manager;
Expand Down
18 changes: 16 additions & 2 deletions BossMod/Autorotation/Standard/StandardWAR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
// special case for use as gapcloser - it has to be very high priority
var (prio, basePrio) = stratOnsOpt == OnslaughtStrategy.GapClose ? (OGCDPriority.GapcloseOnslaught, ActionQueue.Priority.High)
: LostBloodRageStacks is > 0 and < 4 ? (OGCDPriority.LostBanner, ActionQueue.Priority.Medium)
: (OGCDPriority.Onslaught, OnslaughtCD < GCDLength ? ActionQueue.Priority.VeryLow : ActionQueue.Priority.Low);
: (OGCDPriority.Onslaught, OnslaughtCapIn < GCDLength ? ActionQueue.Priority.Low : ActionQueue.Priority.VeryLow);
QueueOGCD(WAR.AID.Onslaught, target, stratOns.Value.PriorityOverride, prio, basePrio);
}
}
Expand All @@ -350,6 +350,18 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
Hints.ActionsToExecute.Push(BozjaActionID.GetNormal(BozjaHolsterID.LostFontOfPower), Player, ActionQueue.Priority.Low + (int)OGCDPriority.LostFont);
if (ShouldUseLostBuff(LostBannerCD, 90))
Hints.ActionsToExecute.Push(BozjaActionID.GetNormal(BozjaHolsterID.BannerHonoredSacrifice), Player, ActionQueue.Priority.Low + (int)OGCDPriority.LostBanner);

// ai hints for positioning
var goalST = primaryTarget != null ? Hints.GoalSingleTarget(primaryTarget, 3) : null;
var goalAOE = Hints.GoalAOECircle(3);
var goal = aoeStrategy switch
{
AOEStrategy.SingleTarget => goalST,
AOEStrategy.ForceAOE => goalAOE,
_ => goalST != null ? Hints.GoalCombined(goalST, goalAOE, 3) : goalAOE
};
if (goal != null)
Hints.GoalZones.Add(goal);
}

private void QueueGCD(WAR.AID aid, Actor? target, GCDPriority prio)
Expand Down Expand Up @@ -712,7 +724,9 @@ private GCDPriority FellCleavePriorityBerserk()
}
}
var nextAction = wantAOEAction ? NextComboAOE(comboStepsRemaining == 0) : NextComboSingleTarget(wantSERoute, comboStepsRemaining == 0);
var riskOvercappingGauge = Gauge + GaugeGainedFromAction(nextAction) > 100;

var needInfuriateSoon = Unlocked(WAR.AID.Infuriate) && !CanFitGCD(InfuriateCD - InfuriateCDReduction - InfuriateCDLeeway, 1);
var riskOvercappingGauge = Gauge + GaugeGainedFromAction(nextAction) > (needInfuriateSoon ? 50 : 100);

// first deal with forced combo; for ST extension, we generally want to minimize overcap by using combo finisher as late as possible
// TODO: reconsider what to do if we can't fit in combo - do we still want to do partial combo? especially if it would cause gauge overcap
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassDRKUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa

var dashStrategy = strategy.Option(Track.Shadowstride).As<DashStrategy>();
if (ShouldUseDash(dashStrategy, primaryTarget))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), Player, obl.Priority());
Hints.ActionsToExecute.Push(ActionID.MakeSpell(DRK.AID.Shadowstride), primaryTarget, obl.Priority());
}
private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch
{
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassGNBUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa

var dashStrategy = strategy.Option(Track.Trajectory).As<DashStrategy>();
if (ShouldUseDash(dashStrategy, primaryTarget))
Hints.ActionsToExecute.Push(ActionID.MakeSpell(GNB.AID.Trajectory), Player, hoc.Priority());
Hints.ActionsToExecute.Push(ActionID.MakeSpell(GNB.AID.Trajectory), primaryTarget, hoc.Priority());
}
private bool ShouldUseDash(DashStrategy strategy, Actor? primaryTarget) => strategy switch
{
Expand Down
17 changes: 7 additions & 10 deletions BossMod/Autorotation/Utility/ClassSCHUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

public sealed class ClassSCHUtility(RotationModuleManager manager, Actor player) : RoleHealerUtility(manager, player)
{
public enum Track
{
WhisperingDawn = SharedTrack.Count, Adloquium, Succor, FeyIllumination, Lustrate, SacredSoil, Indomitability, DeploymentTactics,
EmergencyTactics, Dissipation, Excogitation, Aetherpact, Recitation, FeyBlessing, Consolation, Protraction, Expedient, Seraphism, Resurrection, PetActions
}
public enum Track { WhisperingDawn = SharedTrack.Count, Adloquium, Succor, FeyIllumination, Lustrate, SacredSoil, Indomitability, DeploymentTactics, EmergencyTactics, Dissipation, Excogitation, Aetherpact, Recitation, FeyBlessing, Consolation, Protraction, Expedient, Seraphism, Resurrection, Summons }
public enum SuccorOption { None, Succor, Concitation }
public enum DeployOption { None, Use, UseEx }
public enum AetherpactOption { None, Use, End }
Expand Down Expand Up @@ -64,7 +60,7 @@ public static RotationModuleDefinition Definition()
DefineSimpleConfig(res, Track.Resurrection, "Resurrection", "Raise", 10, SCH.AID.Resurrection);

// Pet Summons
res.Define(Track.PetActions).As<PetOption>("Pet", "", 180)
res.Define(Track.Summons).As<PetOption>("Pet", "", 180)
.AddOption(PetOption.None, "None", "Do not use automatically")
.AddOption(PetOption.Eos, "Eos", "Summon Eos", 2, 0, ActionTargets.Self, 4)
.AddOption(PetOption.Seraph, "Seraph", "Summon Seraph", 120, 22, ActionTargets.Self, 80)
Expand Down Expand Up @@ -120,14 +116,15 @@ public override void Execute(StrategyValues strategy, Actor? primaryTarget, floa
if (recit.As<RecitationOption>() != RecitationOption.None)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(SCH.AID.Recitation), Player, recit.Priority(), recit.Value.ExpireIn);

var pet = strategy.Option(Track.PetActions);
var petAction = pet.As<PetOption>() switch
var pet = strategy.Option(Track.Summons);
var petSummons = pet.As<PetOption>() switch
{
PetOption.Eos => SCH.AID.SummonEos,
PetOption.Seraph => SCH.AID.SummonSeraph,
_ => default
};
if (petAction != default)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(petAction), Player, pet.Priority(), pet.Value.ExpireIn);
if (petSummons != default)
Hints.ActionsToExecute.Push(ActionID.MakeSpell(petSummons), Player, pet.Priority(), pet.Value.ExpireIn);

}
}
10 changes: 6 additions & 4 deletions BossMod/Autorotation/xan/Casters/RDM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ public override void Exec(StrategyValues strategy, Actor? primaryTarget)
(BestLineTarget, NumLineTargets) = SelectTarget(strategy, primaryTarget, 25, Is25yRectTarget);
(BestConeTarget, NumConeTargets) = SelectTarget(strategy, primaryTarget, 8, (primary, other) => Hints.TargetInAOECone(other, Player.Position, 8, Player.DirectionTo(primary), 60.Degrees()));

if (Swordplay > 0 || LowestMana >= 50 || InCombo)
Hints.RecommendedRangeToTarget = 3;
// TODO: fixme xan!
//if (Swordplay > 0 || LowestMana >= 50 || InCombo)
// Hints.RecommendedRangeToTarget = 3;

if (CountdownRemaining > 0)
{
Expand All @@ -118,8 +119,9 @@ public override void Exec(StrategyValues strategy, Actor? primaryTarget)
return;
}

if (Swordplay > 0 || LowestMana >= 50 || InCombo)
Hints.RecommendedRangeToTarget = 3f;
// TODO: fixme xan!
//if (Swordplay > 0 || LowestMana >= 50 || InCombo)
// Hints.RecommendedRangeToTarget = 3f;

OGCD(strategy, primaryTarget);

Expand Down
5 changes: 3 additions & 2 deletions BossMod/Autorotation/xan/Healers/SCH.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ public override void Exec(StrategyValues strategy, Actor? primaryTarget)

if (NumAOETargets >= needAOETargets)
{
if (needAOETargets == 1)
Hints.RecommendedRangeToTarget = 5f;
// TODO: fixme xan!
//if (needAOETargets == 1)
// Hints.RecommendedRangeToTarget = 5f;

PushGCD(AID.ArtOfWar1, Player);
}
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/xan/Melee/MNK.cs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ private void WindsReply()
}

private float DesiredFireWindow => GCDLength * 10;
private float EarliestRoF(float estimatedDelay) => MathF.Max(estimatedDelay + 0.6f, 20.6f - DesiredFireWindow);
private float EarliestRoF(float estimatedDelay) => MathF.Max(estimatedDelay + 0.8f, 20.6f - DesiredFireWindow);

private void Potion() => Hints.ActionsToExecute.Push(ActionDefinitions.IDPotionStr, Player, ActionQueue.Priority.Low + 100 + (float)OGCDPriority.Potion);

Expand Down
Loading

0 comments on commit 1ab6193

Please sign in to comment.