Skip to content

Commit

Permalink
Merge pull request #605 from FFXIV-CombatReborn/ninjustsuFixes
Browse files Browse the repository at this point in the history
Refactor Ninjutsu logic and improve burst phase handling
  • Loading branch information
LTS-FFXIV authored Jan 29, 2025
2 parents a004360 + 90e1661 commit 76b9c10
Showing 1 changed file with 88 additions and 27 deletions.
115 changes: 88 additions & 27 deletions BasicRotations/Melee/NIN_Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public sealed class NIN_Default : NinjaRotation

#region Tracking Properties
// Properties to track RabbitMediumPvE failures and related information.
private int _rabbitMediumFailures = 0;
//private int _rabbitMediumFailures = GetActionUsageCount((uint)ActionID.RabbitMediumPvE);
private IBaseAction? _lastNinActionAim = null;
#endregion

Expand Down Expand Up @@ -99,6 +99,7 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)

// First priority is given to Kassatsu if it's available, allowing for an immediate powerful Ninjutsu.
if (NoNinjutsu && KassatsuPvE.CanUse(out act)) return true;
if ((!TenChiJinPvE.Cooldown.IsCoolingDown || Player.WillStatusEndGCD(2, 0, true, StatusID.ShadowWalker)) && MeisuiPvE.CanUse(out act)) return true;

if (TenriJindoPvE.CanUse(out act)) return true;

Expand All @@ -116,8 +117,6 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
if (TrickAttackPvE.Cooldown.IsCoolingDown && !TrickAttackPvE.Cooldown.WillHaveOneCharge(19) && TenChiJinPvE.Cooldown.IsCoolingDown && MeisuiPvE.CanUse(out act)) return true;
}

if ((TenChiJinPvE.Cooldown.IsCoolingDown || Player.WillStatusEndGCD(2, 0, true, StatusID.ShadowWalker)) && MeisuiPvE.CanUse(out act)) return true;

// If none of the specific conditions are met, falls back to the base class's emergency ability logic.
return base.EmergencyAbility(nextGCD, out act);
}
Expand Down Expand Up @@ -177,11 +176,14 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
#region Ninjutsu Logic
private void SetNinjutsu(IBaseAction act)
{
if (act == null || AdjustId(ActionID.NinjutsuPvE) == ActionID.RabbitMediumPvE || (_ninActionAim != null && IsLastAction(true, _ninActionAim))) return;
if (act == null || AdjustId(ActionID.NinjutsuPvE) == ActionID.RabbitMediumPvE) return;

if (_ninActionAim != null && IsLastAction(false, TenPvE, JinPvE, ChiPvE, FumaShurikenPvE_18873, FumaShurikenPvE_18874, FumaShurikenPvE_18875)) return;

_ninActionAim = act;
if (_ninActionAim != act)
{
_ninActionAim = act;
}
}

// Clears the ninjutsu action aim, effectively resetting any planned ninjutsu action.
Expand All @@ -199,8 +201,6 @@ private bool ChoiceNinjutsu(out IAction? act)
{
act = null;

if (!TenPvE.CanUse(out _) && !HasKassatsu) return false;

// Ensures that the action ID currently considered for Ninjutsu is actually valid for Ninjutsu execution.
//if (AdjustId(ActionID.NinjutsuPvE) != ActionID.NinjutsuPvE) return false;
// If more than 4.5 seconds have passed since the last action, it clears any pending Ninjutsu to avoid stale actions.
Expand Down Expand Up @@ -236,7 +236,7 @@ private bool ChoiceNinjutsu(out IAction? act)
}
else return false;
}
else
else if (TenPvE.CanUse(out _, usedUp: InTrickAttack))
{
// Chooses buffs or AoE actions based on combat conditions and cooldowns.
// For instance, setting Huton for speed buff or choosing AoE Ninjutsu like Katon or Doton based on enemy positioning.
Expand Down Expand Up @@ -287,7 +287,6 @@ private bool DoRabbitMedium(out IAction? act)
uint ninjutsunId = AdjustId(NinjutsuPvE.ID);
if (ninjutsunId == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
if (RabbitMediumPvE.CanUse(out act)) return true;
ClearNinjutsu();
}
Expand Down Expand Up @@ -343,14 +342,18 @@ private bool DoSuiton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == SuitonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand All @@ -361,7 +364,7 @@ private bool DoSuiton(out IAction? act)
//Can't use.
if (!Player.HasStatus(true, StatusID.Kassatsu, StatusID.TenChiJin)
&& !TenPvE.CanUse(out _, usedUp: true)
&& !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![0]))
&& !IsLastAction(true, _ninActionAim.Setting.Ninjutsu![0]))
{
return false;
}
Expand All @@ -382,7 +385,7 @@ private bool DoSuiton(out IAction? act)
else if ((uint)id == FumaShurikenPvE.ID)
{
if (_ninActionAim.Setting.Ninjutsu!.Length > 1
&& !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![1]))
&& !IsLastAction(true, _ninActionAim.Setting.Ninjutsu![1]))
{
act = _ninActionAim.Setting.Ninjutsu![1];
return true;
Expand All @@ -392,7 +395,7 @@ private bool DoSuiton(out IAction? act)
else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
{
if (_ninActionAim.Setting.Ninjutsu!.Length > 2
&& !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
&& !IsLastAction(true, _ninActionAim.Setting.Ninjutsu![2]))
{
act = _ninActionAim.Setting.Ninjutsu![2];
return true;
Expand All @@ -409,14 +412,18 @@ private bool DoHyoshoRanryu(out IAction? act)
{
act = null;

if (_ninActionAim != null && (_ninActionAim == HyoshoRanryuPvE) && HasKassatsu)
//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == HyoshoRanryuPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -475,14 +482,18 @@ private bool DoGokaMekkyaku(out IAction? act)
{
act = null;

if (_ninActionAim != null && (_ninActionAim == GokaMekkyakuPvE) && HasKassatsu)
//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == GokaMekkyakuPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -541,14 +552,18 @@ private bool DoDoton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == DotonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -607,14 +622,18 @@ private bool DoHuton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == HutonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -673,14 +692,18 @@ private bool DoHyoton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == HyotonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -739,14 +762,18 @@ private bool DoRaiton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == RaitonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -805,14 +832,18 @@ private bool DoKaton(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == KatonPvE))
{
var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand Down Expand Up @@ -871,17 +902,18 @@ private bool DoFumaShuriken(out IAction? act)
{
act = null;

//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(3, false, StatusID.Kassatsu)
&& HasKassatsu && !InTrickAttack) return false;
if (_ninActionAim == null) return false;

if (_ninActionAim != null && (_ninActionAim == FumaShurikenPvE))
{
//Keep Kassatsu in Burst.
if (!Player.WillStatusEnd(4, true, StatusID.Kassatsu) && !InTrickAttack) return false;

var id = AdjustId(ActionID.NinjutsuPvE);

//Failed
if ((uint)id == RabbitMediumPvE.ID)
{
_rabbitMediumFailures++;
ClearNinjutsu();
act = null;
return false;
Expand All @@ -899,6 +931,17 @@ private bool DoFumaShuriken(out IAction? act)
act = _ninActionAim.Setting.Ninjutsu![0];
return true;
}
//Second
else if ((uint)id == _ninActionAim.ID)
{
if (_ninActionAim.CanUse(out act, skipAoeCheck: true)) return true;
if (_ninActionAim.ID == DotonPvE.ID && !InCombat)
{
act = _ninActionAim;
return true;
}
}
//Third
else if ((uint)id == FumaShurikenPvE.ID)
{
if (_ninActionAim.Setting.Ninjutsu!.Length > 1
Expand All @@ -908,6 +951,19 @@ private bool DoFumaShuriken(out IAction? act)
return true;
}
}
//Finished
else if ((uint)id == KatonPvE.ID || (uint)id == RaitonPvE.ID || (uint)id == HyotonPvE.ID)
{
if (_ninActionAim.Setting.Ninjutsu!.Length > 2
&& !IsLastAction(false, _ninActionAim.Setting.Ninjutsu![2]))
{
act = _ninActionAim.Setting.Ninjutsu![2];
return true;
}
}

act = _ninActionAim;
return true;
}
return false;
}
Expand All @@ -928,6 +984,9 @@ protected override bool GeneralGCD(out IAction? act)
if (ForkedUse && ForkedRaijuPvE.CanUse(out act)) return true;
}

if ((InCombat || (CommbatMudra && HasHostilesInMaxRange)) && ChoiceNinjutsu(out act)) return true;


if (DoTenChiJin(out act)) return true;
if (DoRabbitMedium(out act)) return true;

Expand All @@ -947,6 +1006,8 @@ protected override bool GeneralGCD(out IAction? act)
if (DoRaiton(out act)) return true;
if (DoFumaShuriken(out act)) return true;

if (IsExecutingMudra) return base.GeneralGCD(out act);

//Single
if (AeolianEdgePvE.EnoughLevel)
{
Expand Down Expand Up @@ -989,7 +1050,7 @@ protected override bool GeneralGCD(out IAction? act)
public override void DisplayStatus()
{
ImGui.Text($"Ninjutsu Action: {_ninActionAim}");
ImGui.Text($"Mudra Failure Count: {_rabbitMediumFailures}");
//ImGui.Text($"Mudra Failure Count: {_rabbitMediumFailures}");
ImGui.Text($"Last Ninjutsu Action Cleared From Queue: {_lastNinActionAim}");
ImGui.Text($"Ninki: {Ninki}");
ImGui.Text($"Kazematoi: {Kazematoi}");
Expand Down

0 comments on commit 76b9c10

Please sign in to comment.