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

Gnb fix #215

Merged
merged 18 commits into from
Jan 7, 2024
3 changes: 2 additions & 1 deletion BossMod/Autorotation/DRG/DRGActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Actions : CommonActions
private DRGConfig _config;
private Rotation.State _state;
private Rotation.Strategy _strategy;
private bool _aoe;

public Actions(Autorotation autorot, Actor player)
: base(autorot, player, Definitions.UnlockQuests, Definitions.SupportedActions)
Expand Down Expand Up @@ -115,7 +116,7 @@ protected override NextAction CalculateAutomaticOGCD(float deadline)
//if (_state.CanWeave(deadline - _state.OGCDSlotLength)) // first ogcd slot
//res = Rotation.GetNextBestOGCD(_state, _strategy, deadline - _state.OGCDSlotLength);
if (!res && _state.CanWeave(deadline)) // second/only ogcd slot
res = Rotation.GetNextBestOGCD(_state, _strategy, deadline);
res = Rotation.GetNextBestOGCD(_state, _strategy, deadline, _aoe);

var target = res == ActionID.MakeSpell(AID.DragonSight) ? FindBestDragonSightTarget() : Autorot.PrimaryTarget;
return MakeResult(res, target);
Expand Down
87 changes: 80 additions & 7 deletions BossMod/Autorotation/DRG/DRGRotation.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@


namespace BossMod.DRG
{
public static class Rotation
Expand Down Expand Up @@ -49,6 +48,15 @@ public override string ToString()
// strategy configuration
public class Strategy : CommonRotation.Strategy
{
public enum TrueNorthUse : uint
{
Automatic = 0,

[PropertyDisplay("Delay", 0x800000ff)]
Delay = 1,
[PropertyDisplay("Force", 0x8000ff00)]
Force = 2,
}
public enum SpineShatteruse : uint
{
Automatic = 0, // always keep one charge reserved, use other charges under raidbuffs or prevent overcapping
Expand All @@ -66,6 +74,7 @@ public enum SpineShatteruse : uint
UseOutsideMelee = 4, // use immediately if outside melee range
}

public TrueNorthUse TrueNorthStrategy;
public SpineShatteruse SpineShatterStrategy; // how are we supposed to use spineshatter dive
public int NumAOEGCDTargets; // range 10 width 4 rect
public bool UseAOERotation;
Expand All @@ -79,10 +88,13 @@ public void ApplyStrategyOverrides(uint[] overrides)
{
if (overrides.Length >= 8)
{
SpineShatterStrategy = (SpineShatteruse)overrides[0];
TrueNorthStrategy = (TrueNorthUse)overrides[0];
SpineShatterStrategy = (SpineShatteruse)overrides[1];

}
else
{
TrueNorthStrategy = TrueNorthUse.Automatic;
SpineShatterStrategy = SpineShatteruse.Automatic;
}
}
Expand Down Expand Up @@ -253,6 +265,60 @@ public static (Positional, bool) GetNextPositional(State state, Strategy strateg
}
}

public static bool ShouldUseTrueNorth(State state, Strategy strategy)
{
switch (strategy.TrueNorthStrategy)
{
case Strategy.TrueNorthUse.Delay:
return false;

default:
if (!state.TargetingEnemy)
return false;
if (state.TrueNorthLeft > state.AnimationLock || state.RightEyeLeft > state.AnimationLock)
return false;
if (GetNextPositional(state, strategy).Item2 && strategy.NextPositionalCorrect)
return false;
if (GetNextPositional(state, strategy).Item2 && !strategy.NextPositionalCorrect)
return true;
return false;
}
}

public static bool ShouldUseGeirskogul(State state, Strategy strategy)
{
if (state.EyeCount == 2 && state.CD(CDGroup.LanceCharge) < 40)
return false;
if (state.EyeCount == 2 && state.LanceChargeLeft > state.AnimationLock)
return true;
if (state.EyeCount == 1 && state.LanceChargeLeft > state.AnimationLock)
{
if (state.DiveReadyLeft > state.AnimationLock && state.CD(CDGroup.HighJump) > 10)
return false;
}
if (state.EyeCount != 2 && state.CD(CDGroup.LanceCharge) < 40)
{
return true;
}
if (state.EyeCount == 0)
{
return true;
}
return true;
}

public static bool ShouldUseWyrmWindThrust(State state, Strategy strategy)
{
bool nextGCDisRaiden = state.DraconianFireLeft > state.AnimationLock && (state.ComboLastMove == AID.WheelingThrust || state.ComboLastMove == AID.FangAndClaw) && state.WheelInMotionLeft < state.AnimationLock && state.FangAndClawBaredLeft < state.AnimationLock;
if (state.FirstmindFocusCount >= 2 && state.CD(CDGroup.LanceCharge) > 10)
return true;
if (state.FirstmindFocusCount >= 2 && state.LanceChargeLeft > state.AnimationLock)
return true;
if (state.FirstmindFocusCount >= 2 && state.CD(CDGroup.LanceCharge) < 10 && !nextGCDisRaiden)
return false;
return false;
}

public static AID GetNextBestGCD(State state, Strategy strategy)
{
// prepull
Expand Down Expand Up @@ -284,14 +350,15 @@ public static AID GetNextBestGCD(State state, Strategy strategy)
}
}

public static ActionID GetNextBestOGCD(State state, Strategy strategy, float deadline)
public static ActionID GetNextBestOGCD(State state, Strategy strategy, float deadline, bool aoe)
{
bool canJump = strategy.PositionLockIn > state.AnimationLock;
bool wantSpineShatter = state.Unlocked(AID.SpineshatterDive) && state.TargetingEnemy && UseSpineShatterDive(state, strategy);


if (state.PowerSurgeLeft > state.GCD)
{
if (state.Unlocked(AID.LanceCharge) && state.CanWeave(CDGroup.LanceCharge, 0.6f, deadline) && ((state.CD(CDGroup.DragonSight) < state.GCD) || (state.CD(CDGroup.DragonSight) < 65) && (state.CD(CDGroup.DragonSight) > 55)))
if (state.Unlocked(AID.LanceCharge) && state.CanWeave(CDGroup.LanceCharge, 0.6f, deadline - state.OGCDSlotLength) && ((state.CD(CDGroup.DragonSight) < state.GCD) || (state.CD(CDGroup.DragonSight) < 65) && (state.CD(CDGroup.DragonSight) > 55)))
return ActionID.MakeSpell(AID.LanceCharge);
if (state.Unlocked(AID.DragonSight) && state.CanWeave(CDGroup.DragonSight, 0.6f, deadline) && state.CD(CDGroup.BattleLitany) < state.GCD + 2.5)
return ActionID.MakeSpell(AID.DragonSight);
Expand All @@ -307,17 +374,21 @@ public static ActionID GetNextBestOGCD(State state, Strategy strategy, float dea

if (state.CD(CDGroup.LanceCharge) > 5 && state.CD(CDGroup.DragonSight) > 5 && state.CD(CDGroup.BattleLitany) > 5)
{
if (state.Unlocked(AID.Geirskogul) && state.CanWeave(CDGroup.Geirskogul, 0.6f, deadline))
if (state.CanWeave(CDGroup.WyrmwindThrust, 0.6f, deadline) && ShouldUseWyrmWindThrust(state, strategy) && (GetNextBestGCD(state, strategy) == AID.DraconianFury || GetNextBestGCD(state, strategy) == AID.RaidenThrust))
return ActionID.MakeSpell(AID.WyrmwindThrust);
if (state.Unlocked(AID.Geirskogul) && state.CanWeave(CDGroup.Geirskogul, 0.6f, deadline) && ShouldUseGeirskogul(state, strategy))
return ActionID.MakeSpell(AID.Geirskogul);
if (canJump && state.Unlocked(AID.Jump) && state.CanWeave(state.Unlocked(AID.HighJump) ? CDGroup.HighJump : CDGroup.Jump, 0.8f, deadline))
return ActionID.MakeSpell(state.BestJump);
if (state.DiveReadyLeft > state.AnimationLock && state.CanWeave(CDGroup.MirageDive, 0.6f, deadline) && state.EyeCount == 1 && state.CD(CDGroup.Geirskogul) < state.AnimationLock && state.LanceChargeLeft > state.AnimationLock)
return ActionID.MakeSpell(AID.MirageDive);
if (canJump && state.Unlocked(AID.DragonfireDive) && state.CanWeave(CDGroup.DragonfireDive, 0.8f, deadline))
return ActionID.MakeSpell(AID.DragonfireDive);
if (wantSpineShatter && state.CanWeave(state.CD(CDGroup.SpineshatterDive), 0.8f, deadline))
return ActionID.MakeSpell(AID.SpineshatterDive);
if (canJump && state.Unlocked(AID.Stardiver) && state.LifeOfTheDragonLeft > state.AnimationLock && state.CanWeave(CDGroup.Stardiver, 1.5f, deadline))
return ActionID.MakeSpell(AID.Stardiver);
if (state.FirstmindFocusCount >= 2 && state.CanWeave(CDGroup.WyrmwindThrust, 0.6f, deadline))
if (state.CanWeave(CDGroup.WyrmwindThrust, 0.6f, deadline) && ShouldUseWyrmWindThrust(state, strategy))
return ActionID.MakeSpell(AID.WyrmwindThrust);
if (wantSpineShatter && state.RangeToTarget > 3)
return ActionID.MakeSpell(AID.SpineshatterDive);
Expand All @@ -331,11 +402,13 @@ public static ActionID GetNextBestOGCD(State state, Strategy strategy, float dea
// return ActionID.MakeSpell(AID.MirageDive);
//if (state.DiveReadyLeft > state.AnimationLock && state.CanWeave(CDGroup.MirageDive, 0.6f, deadline) && state.EyeCount != 2 && state.LifeOfTheDragonLeft < state.AnimationLock)
// return ActionID.MakeSpell(AID.MirageDive);
if (state.DiveReadyLeft > state.AnimationLock && state.CanWeave(CDGroup.MirageDive, 0.6f, deadline) && state.EyeCount != 2)
if (state.DiveReadyLeft > state.AnimationLock && state.CanWeave(CDGroup.MirageDive, 0.6f, deadline) && (state.EyeCount != 2 || state.DiveReadyLeft < state.GCD))
return ActionID.MakeSpell(AID.MirageDive);
}
}

if (ShouldUseTrueNorth(state, strategy) && state.CanWeave(CDGroup.TrueNorth - 45, 0.6f, deadline) && !aoe && state.GCD < 0.8)
return ActionID.MakeSpell(AID.TrueNorth);

// no suitable oGCDs...
return new();
Expand Down
12 changes: 9 additions & 3 deletions BossMod/Autorotation/GNB/GNBActions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.JobGauge.Types;
using System;
using System.Linq;

Expand Down Expand Up @@ -27,6 +28,10 @@ public Actions(Autorotation autorot, Actor player)
SupportedSpell(AID.HeartOfStone).TransformAction = SupportedSpell(AID.HeartOfCorundum).TransformAction = () => ActionID.MakeSpell(_state.BestHeart);
SupportedSpell(AID.Continuation).TransformAction = SupportedSpell(AID.JugularRip).TransformAction = SupportedSpell(AID.AbdomenTear).TransformAction = SupportedSpell(AID.EyeGouge).TransformAction = SupportedSpell(AID.Hypervelocity).TransformAction = () => ActionID.MakeSpell(_state.BestContinuation);
SupportedSpell(AID.GnashingFang).TransformAction = SupportedSpell(AID.SavageClaw).TransformAction = SupportedSpell(AID.WickedTalon).TransformAction = () => ActionID.MakeSpell(_state.BestGnash);
SupportedSpell(AID.Continuation).Condition = _ => _state.ReadyToRip ? ActionID.MakeSpell(AID.JugularRip) : ActionID.MakeSpell(AID.None);
SupportedSpell(AID.Continuation).Condition = _ => _state.ReadyToTear ? ActionID.MakeSpell(AID.AbdomenTear) : ActionID.MakeSpell(AID.None);
SupportedSpell(AID.Continuation).Condition = _ => _state.ReadyToGouge ? ActionID.MakeSpell(AID.EyeGouge) : ActionID.MakeSpell(AID.None);
SupportedSpell(AID.Continuation).Condition = _ => _state.ReadyToBlast ? ActionID.MakeSpell(AID.Hypervelocity) : ActionID.MakeSpell(AID.None);

SupportedSpell(AID.Aurora).Condition = _ => Player.HP.Cur < Player.HP.Max;
SupportedSpell(AID.Reprisal).Condition = _ => Autorot.Hints.PotentialTargets.Any(e => e.Actor.Position.InCircle(Player.Position, 5 + e.Actor.HitboxRadius)); // TODO: consider checking only target?..
Expand Down Expand Up @@ -106,10 +111,12 @@ private void UpdatePlayerState()
{
FillCommonPlayerState(_state);
_state.HaveTankStance = Player.FindStatus(SID.RoyalGuard) != null;
if (_state.ComboLastMove == AID.SolidBarrel)
_state.ComboTimeLeft = 0;

_state.Ammo = Service.JobGauges.Get<GNBGauge>().Ammo;
_state.GunComboStep = Service.JobGauges.Get<GNBGauge>().AmmoComboStep;
_state.MaxCartridges = _state.Level >= 88 ? 3 : 2;
_state.MaxCartridges = _state.Unlocked(TraitID.CartridgeChargeII) ? 3 : 2;

_state.NoMercyLeft = StatusDetails(Player, SID.NoMercy, Player.InstanceID).Left;
_state.ReadyToRip = Player.FindStatus(SID.ReadyToRip) != null;
Expand All @@ -132,7 +139,6 @@ private void OnConfigModified(object? sender, EventArgs args)
SupportedSpell(AID.DemonSlaughter).TransformAction = _config.AOECombos ? () => ActionID.MakeSpell(Rotation.GetNextAOEComboAction(ComboLastMove)) : null;

// smart targets
SupportedSpell(AID.HeartOfCorundum).TransformTarget = _config.SmartHeartofCorundumShirkTarget ? SmartTargetCoTank : null;
SupportedSpell(AID.Shirk).TransformTarget = _config.SmartHeartofCorundumShirkTarget ? SmartTargetCoTank : null;
SupportedSpell(AID.Provoke).TransformTarget = _config.ProvokeMouseover ? SmartTargetHostile : null; // TODO: also interject/low-blow
}
Expand Down
3 changes: 3 additions & 0 deletions BossMod/Autorotation/GNB/GNBConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ class GNBConfig : ConfigNode

[PropertyDisplay("Early No Mercy in Opener")]
public bool EarlyNoMercy = true;

[PropertyDisplay("Early Sonic Break in Opener")]
public bool EarlySonicBreak = true;
}
}
Loading