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

Refactor and enhance party and alliance member handling #566

Merged
merged 1 commit into from
Jan 13, 2025
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
56 changes: 35 additions & 21 deletions BasicRotations/Healer/SGE_Default.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using static FFXIVClientStructs.FFXIV.Client.UI.Misc.DataCenterHelper;

namespace RebornRotations.Healer;

[Rotation("Default", CombatType.PvE, GameVersion = "7.15")]
Expand Down Expand Up @@ -62,6 +64,10 @@ public sealed class SGE_Default : SageRotation

#endregion

#region Tracking Properties
private IBaseAction? _lastEukrasiaActionAim = null;
#endregion

#region Countdown Logic
protected override IAction? CountDownAction(float remainTime)
{
Expand All @@ -84,7 +90,24 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)

protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
{
if (base.EmergencyAbility(nextGCD, out act)) return true;
if ((_EukrasiaActionAim == EukrasianDosisIiiPvE || _EukrasiaActionAim == EukrasianDosisIiPvE || _EukrasiaActionAim == EukrasianDosisPvE)
&& (DyskrasiaPvE.CanUse(out _) || DyskrasiaIiPvE.CanUse(out _) || EukrasianDyskrasiaPvE.CanUse(out _)))
{
ClearEukrasia();
}

// If the last action performed matches any of a list of specific actions, it clears the Eukrasia aim.
// This serves as a reset/cleanup mechanism to ensure the decision logic starts fresh for the next cycle.
if (IsLastGCD(false, EukrasianPrognosisIiPvE, EukrasianPrognosisPvE,
EukrasianDiagnosisPvE, EukrasianDyskrasiaPvE, EukrasianDosisIiiPvE, EukrasianDosisIiPvE,
EukrasianDosisPvE) || !InCombat)
{
ClearEukrasia();
}

if (ChoiceEukrasia(out act)) return true;

//if (base.EmergencyAbility(nextGCD, out act)) return true;

if (nextGCD.IsTheSameTo(false, PneumaPvE, EukrasianPrognosisPvE, EukrasianPrognosisIiPvE))
{
Expand Down Expand Up @@ -230,7 +253,7 @@ private void SetEukrasia(IBaseAction act)
{
if (act == null) return;

if (_EukrasiaActionAim != null && IsLastGCD(false, _EukrasiaActionAim)) return;
if (_EukrasiaActionAim != null && IsLastGCD(true, _EukrasiaActionAim)) return;

if (_EukrasiaActionAim != act)
{
Expand All @@ -243,6 +266,7 @@ private void ClearEukrasia()
{
if (_EukrasiaActionAim != null)
{
_lastEukrasiaActionAim = _EukrasiaActionAim;
_EukrasiaActionAim = null;
}
}
Expand All @@ -251,16 +275,8 @@ private bool ChoiceEukrasia(out IAction? act)
{
act = null;

// If the last action performed matches any of a list of specific actions, it clears the Eukrasia aim.
// This serves as a reset/cleanup mechanism to ensure the decision logic starts fresh for the next cycle.
if (IsLastGCD(true, EukrasianPrognosisIiPvE, EukrasianPrognosisPvE,
EukrasianDiagnosisPvE, EukrasianDyskrasiaPvE, EukrasianDosisIiiPvE, EukrasianDosisIiPvE,
EukrasianDosisPvE) || !InCombat)
{
ClearEukrasia();
}

if (!EukrasiaPvE.CanUse(out _)) return false;

// Checks for Eukrasia status.
// Attempts to set correct Eurkrasia action based on availablity and MergedStatus.
if (EukrasianPrognosisIiPvE.CanUse(out _) && EukrasianPrognosisIiPvE.EnoughLevel && MergedStatus.HasFlag(AutoStatus.DefenseArea))
Expand All @@ -281,25 +297,25 @@ private bool ChoiceEukrasia(out IAction? act)
return false;
}

if (EukrasianDyskrasiaPvE.CanUse(out _) && EukrasianDyskrasiaPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseSingle)))
if (EukrasianDyskrasiaPvE.CanUse(out _) && EukrasianDyskrasiaPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseArea)))
{
SetEukrasia(EukrasianDyskrasiaPvE);
return false;
}

if (EukrasianDosisIiiPvE.CanUse(out _) && EukrasianDosisIiiPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseSingle)))
if ((!EukrasianDyskrasiaPvE.CanUse(out _) || !DyskrasiaPvE.CanUse(out _)) && EukrasianDosisIiiPvE.CanUse(out _) && EukrasianDosisIiiPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseArea)))
{
SetEukrasia(EukrasianDosisIiiPvE);
return false;
}

if (EukrasianDosisIiPvE.CanUse(out _) && EukrasianDosisIiPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseSingle)))
if ((!EukrasianDyskrasiaPvE.CanUse(out _) || !DyskrasiaPvE.CanUse(out _)) && EukrasianDosisIiPvE.CanUse(out _) && EukrasianDosisIiPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseArea)))
{
SetEukrasia(EukrasianDosisIiPvE);
return false;
}

if (EukrasianDosisPvE.CanUse(out _) && EukrasianDosisPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseSingle)))
if ((!EukrasianDyskrasiaPvE.CanUse(out _) || !DyskrasiaPvE.CanUse(out _)) && EukrasianDosisPvE.CanUse(out _) && EukrasianDosisPvE.EnoughLevel && (!MergedStatus.HasFlag(AutoStatus.DefenseSingle) || !MergedStatus.HasFlag(AutoStatus.DefenseArea)))
{
SetEukrasia(EukrasianDosisPvE);
return false;
Expand Down Expand Up @@ -364,11 +380,8 @@ protected override bool HealSingleGCD(out IAction? act)
protected override bool GeneralGCD(out IAction? act)
{
act = null;

if (HasSwift && SwiftLogic && EgeiroPvE.CanUse(out _)) return false;

if (PhlegmaIiiPvE.CanUse(out act, usedUp: IsMoving)) return true;
if (PhlegmaIiPvE.CanUse(out act, usedUp: IsMoving)) return true;
if (PhlegmaPvE.CanUse(out act, usedUp: IsMoving)) return true;

if (PartyMembers.Any(b => b.GetHealthRatio() < PneumaSTPartyHeal && !b.IsDead) || PartyMembers.GetJobCategory(JobRole.Tank).Any(t => t.GetHealthRatio() < PneumaSTTankHeal && !t.IsDead))
Expand All @@ -378,10 +391,10 @@ protected override bool GeneralGCD(out IAction? act)

if (IsMoving && ToxikonPvE.CanUse(out act)) return true;

if (ChoiceEukrasia(out act)) return true;
if (DoEukrasia(out act)) return true;
if ((_EukrasiaActionAim != EukrasianDiagnosisPvE || _EukrasiaActionAim != EukrasianPrognosisPvE || _EukrasiaActionAim != EukrasianPrognosisIiPvE || _EukrasiaActionAim != EukrasianDyskrasiaPvE)
&& DyskrasiaPvE.CanUse(out act)) return true;

if (DyskrasiaPvE.CanUse(out act)) return true;
if (DoEukrasia(out act)) return true;

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

Expand All @@ -398,6 +411,7 @@ protected override bool GeneralGCD(out IAction? act)
public override void DisplayStatus()
{
ImGui.Text($"Eukrasian Action: {_EukrasiaActionAim}");
ImGui.Text($"Last Eukrasian Action: {_lastEukrasiaActionAim}");
ImGui.Text("HasEukrasia: " + HasEukrasia.ToString());
ImGui.Text("Addersgall: " + Addersgall.ToString());
ImGui.Text("Addersting: " + Addersting.ToString());
Expand Down
8 changes: 1 addition & 7 deletions BasicRotations/Magical/RDM_Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,7 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act)
ActionID.EnchantedMoulinetPvE,
ActionID.MoulinetPvE
//I dont know at this point if nextGCD.IsTheSameTo even working, but stil gonna left it in here.
}) && !nextGCD.IsTheSameTo(new[]
{
ActionID.RipostePvE,
ActionID.EnchantedRipostePvE,
ActionID.MoulinetPvE,
ActionID.EnchantedMoulinetPvE
});
}) && !nextGCD.IsTheSameTo(true, ActionID.RipostePvE, ActionID.EnchantedRipostePvE, ActionID.MoulinetPvE, ActionID.EnchantedMoulinetPvE);

//i really hate this.
bool ambatumelee = Player.HasStatus(true, StatusID.Manafication, StatusID.MagickedSwordplay);
Expand Down
3 changes: 2 additions & 1 deletion BasicRotations/Melee/NIN_Default.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act)
// Initializes the action to null, indicating no action has been chosen yet.
act = null;

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

// If Ninjutsu is available or not in combat, defers to the base class's emergency ability logic.
if (!NoNinjutsu || !InCombat) return base.EmergencyAbility(nextGCD, out act);

Expand Down Expand Up @@ -413,7 +415,6 @@ 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 (((!InCombat && CommbatMudra && HasHostilesInMaxRange) || !CombatElapsedLess(7)) && DoNinjutsu(out act)) return true;

//No Ninjutsu
Expand Down
2 changes: 1 addition & 1 deletion ECommons
10 changes: 10 additions & 0 deletions RotationSolver.Basic/Actions/ActionBasicInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ public readonly struct ActionBasicInfo
/// </summary>
public readonly uint ID => _action.Action.RowId;

/// <summary>
/// The Range of the action.
/// </summary>
public readonly sbyte Range => _action.Action.Range;

/// <summary>
/// The EffectRange of the action.
/// </summary>
public readonly byte EffectRange => _action.Action.EffectRange;

/// <summary>
/// The icon of the action.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion RotationSolver.Basic/Actions/ActionTargetInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ private bool CheckTimeToKill(IGameObject gameObject)
{
if (DataCenter.Territory?.ContentType == TerritoryContentType.Trials ||
(DataCenter.Territory?.ContentType == TerritoryContentType.Raids &&
DataCenter.AllianceMembers.Count(p => p is IPlayerCharacter) == 8))
DataCenter.AllianceMembers.Count(p => p is IPlayerCharacter) >= 8))
{
var fallbackPoints = new[] { Vector3.Zero, new Vector3(100, 0, 100) };
var closestFallback = fallbackPoints.MinBy(p => Vector3.Distance(player.Position, p));
Expand Down
6 changes: 3 additions & 3 deletions RotationSolver.Basic/Configuration/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,13 @@ public const string
Filter = HealingActionCondition, Section = 3)]
private static readonly bool _healOutOfCombat = false;

[ConditionBool, UI("Heal solo instance NPCs", Description = "Experimental.",
[ConditionBool, UI("Heal solo instance NPCs (Only enable as needed)", Description = "Experimental.",
Filter = HealingActionCondition, Section = 3)]
private static readonly bool _friendlyBattleNPCHeal = false;

[ConditionBool, UI("Heal and raise Party NPCs.", Description = "Experimental, only enable as needed.",
[ConditionBool, UI("Heal and raise Party NPCs.",
Filter = HealingActionCondition, Section = 3)]
private static readonly bool _friendlyPartyNPCHealRaise2 = false;
private static readonly bool _friendlyPartyNPCHealRaise2 = true;

[ConditionBool, UI("Heal/Dance partner your chocobo", Description = "Experimental.",
Filter = HealingActionCondition, Section = 3)]
Expand Down
14 changes: 10 additions & 4 deletions RotationSolver.Basic/Data/RaiseType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ public enum RaiseType : byte
PartyOnly,

/// <summary>
/// Raise party and alliance members.
/// Raise party members and alliance supports.
/// </summary>
[Description("Raise all.")]
PartyAndAlliance,
[Description("Raise party members and alliance supports.")]
PartyAndAllianceSupports,

/// <summary>
/// Raise party members and alliance healers.
/// </summary>
[Description("Raise party members and non-party healers.")]
[Description("Raise party members and alliance healers.")]
PartyAndAllianceHealers,

/// <summary>
/// Raise all.
/// </summary>
[Description("Raise All.")]
All,
}
16 changes: 9 additions & 7 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,10 @@ internal static void AddDamageRec(float damageRatio)

public static bool IsCastingTankVfx()
{
return IsCastingVfx(s =>
// Create a copy of the VfxDataQueue to avoid modification during enumeration
var vfxDataQueueCopy = VfxDataQueue.ToList();

return IsCastingVfx(vfxDataQueueCopy, s =>
{
if (!s.Path.StartsWith("vfx/lockon/eff/tank_lockon")) return false;
if (!Player.Available) return false;
Expand All @@ -816,20 +819,19 @@ public static bool IsCastingTankVfx()

public static bool IsCastingAreaVfx()
{
return IsCastingVfx(s => s.Path.StartsWith("vfx/lockon/eff/coshare"));
var vfxDataQueueCopy = VfxDataQueue.ToArray();
return IsCastingVfx([.. vfxDataQueueCopy], s => s.Path.StartsWith("vfx/lockon/eff/coshare"));
}

public static bool IsCastingVfx(Func<VfxNewData, bool> isVfx)
public static bool IsCastingVfx(List<VfxNewData> vfxDataQueueCopy, Func<VfxNewData, bool> isVfx)
{
// Ensure the list is not empty
if (VfxDataQueue.Count == 0)
if (vfxDataQueueCopy.Count == 0)
{
return false;
}

// Create a copy of the VfxDataQueue to avoid modification during enumeration
var vfxDataQueueCopy = VfxDataQueue.ToList();

// Iterate over the copied list
foreach (var vfx in vfxDataQueueCopy)
{
if (isVfx(vfx))
Expand Down
7 changes: 4 additions & 3 deletions RotationSolver.Basic/Helpers/IActionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,19 @@ public static bool IsLastActionAbility()
/// <returns>True if the action is the same as any of the provided actions, otherwise false.</returns>
public static bool IsTheSameTo(this IAction action, bool isAdjust, params IAction[] actions)
{
return actions != null && action.IsTheSameTo(GetIDFromActions(isAdjust, actions));
return actions != null && action.IsTheSameTo(isAdjust, GetIDFromActions(isAdjust, actions));
}

/// <summary>
/// Determines if the action is the same as any of the provided action IDs.
/// </summary>
/// <param name="action">The action to check.</param>
/// <param name="isAdjust">Whether to use the adjusted ID.</param>
/// <param name="actions">The action IDs to check against.</param>
/// <returns>True if the action is the same as any of the provided action IDs, otherwise false.</returns>
public static bool IsTheSameTo(this IAction action, params ActionID[] actions)
public static bool IsTheSameTo(this IAction action, bool isAdjust, params ActionID[] actions)
{
return action != null && actions != null && IsActionID((ActionID)action.AdjustedID, actions);
return action != null && actions != null && IsActionID(isAdjust ? (ActionID)action.AdjustedID : (ActionID)action.ID, actions);
}

/// <summary>
Expand Down
Loading