From 87264351b15e5447eff1212732438fd8f04c4441 Mon Sep 17 00:00:00 2001 From: LTS-FFXIV <127939494+LTS-FFXIV@users.noreply.github.com> Date: Tue, 14 Jan 2025 20:07:39 -0600 Subject: [PATCH] Refactor Swiftcast/Raise logic, add SGE options, enhance robustness Refactor Swiftcast and Raise logic to use a merged status flag (AutoStatus.Raise) across multiple files (AST_Default.cs, SCH_Default.cs, SGE_Default.cs, WHM_Default.cs). Introduce new configuration options and methods for handling Eukrasian actions in SGE_Default.cs. Modify BRD_Default.cs to skip time-to-kill check for WindbitePvE and VenomousBitePvE actions. Enhance robustness by adding exception handling and null checks in DataCenter.cs, ObjectHelper.cs, CustomRotation_Invoke.cs, RSCommands_Actions.cs, and TargetUpdater.cs. Refine logic for determining valid raise targets in TargetUpdater.cs. --- BasicRotations/Healer/AST_Default.cs | 6 +- BasicRotations/Healer/SCH_Default.cs | 12 +- BasicRotations/Healer/SGE_Default.cs | 106 ++++++++++++++---- BasicRotations/Healer/WHM_Default.cs | 9 +- BasicRotations/Ranged/BRD_Default.cs | 4 +- ECommons | 2 +- RotationSolver.Basic/DataCenter.cs | 18 ++- RotationSolver.Basic/Helpers/ObjectHelper.cs | 31 +++-- .../Rotations/CustomRotation_Invoke.cs | 14 ++- RotationSolver/Commands/RSCommands_Actions.cs | 15 ++- RotationSolver/Updaters/TargetUpdater.cs | 76 +++---------- 11 files changed, 169 insertions(+), 124 deletions(-) diff --git a/BasicRotations/Healer/AST_Default.cs b/BasicRotations/Healer/AST_Default.cs index c8ab6ebb9..ea94af961 100644 --- a/BasicRotations/Healer/AST_Default.cs +++ b/BasicRotations/Healer/AST_Default.cs @@ -237,8 +237,8 @@ protected override bool HealSingleGCD(out IAction? act) { act = null; if (BubbleProtec && Player.HasStatus(true, StatusID.CollectiveUnconscious_848)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (MicroPrio && Player.HasStatus(true, StatusID.Macrocosmos)) return false; - if (HasSwift && SwiftLogic && AscendPvE.CanUse(out _)) return false; if (AspectedBeneficPvE.CanUse(out act) && (IsMoving @@ -255,8 +255,8 @@ protected override bool HealAreaGCD(out IAction? act) { act = null; if (BubbleProtec && Player.HasStatus(true, StatusID.CollectiveUnconscious_848)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (MicroPrio && Player.HasStatus(true, StatusID.Macrocosmos)) return false; - if (HasSwift && SwiftLogic && AscendPvE.CanUse(out _)) return false; if (AspectedHeliosPvE.CanUse(out act)) return true; if (HeliosPvE.CanUse(out act)) return true; @@ -267,7 +267,7 @@ protected override bool GeneralGCD(out IAction? act) { act = null; if (BubbleProtec && Player.HasStatus(true, StatusID.CollectiveUnconscious_848)) return false; - if (HasSwift && SwiftLogic) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (GravityPvE.CanUse(out act)) return true; diff --git a/BasicRotations/Healer/SCH_Default.cs b/BasicRotations/Healer/SCH_Default.cs index 2944bf376..41e4c30e6 100644 --- a/BasicRotations/Healer/SCH_Default.cs +++ b/BasicRotations/Healer/SCH_Default.cs @@ -171,8 +171,7 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act) protected override bool HealAreaGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (SuccorPvE.CanUse(out act)) return true; if (ConcitationPvE.CanUse(out act, skipCastingCheck: true)) return true; @@ -185,8 +184,7 @@ protected override bool HealAreaGCD(out IAction? act) protected override bool HealSingleGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (AdloquiumPvE.CanUse(out act)) return true; if (ManifestationPvE.CanUse(out act, skipCastingCheck: true)) return true; @@ -199,8 +197,7 @@ protected override bool HealSingleGCD(out IAction? act) protected override bool DefenseAreaGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (SuccorPvE.CanUse(out act)) return true; if (ConcitationPvE.CanUse(out act, skipCastingCheck: true)) return true; @@ -212,8 +209,7 @@ protected override bool DefenseAreaGCD(out IAction? act) protected override bool GeneralGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && ResurrectionPvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; // Summon Eos if (SummonEosPvE.CanUse(out act)) return true; diff --git a/BasicRotations/Healer/SGE_Default.cs b/BasicRotations/Healer/SGE_Default.cs index 90dd8a9db..6b6382bb5 100644 --- a/BasicRotations/Healer/SGE_Default.cs +++ b/BasicRotations/Healer/SGE_Default.cs @@ -1,5 +1,3 @@ -using static FFXIVClientStructs.FFXIV.Client.UI.Misc.DataCenterHelper; - namespace RebornRotations.Healer; [Rotation("Default", CombatType.PvE, GameVersion = "7.15")] @@ -8,6 +6,9 @@ namespace RebornRotations.Healer; public sealed class SGE_Default : SageRotation { #region Config Options + [RotationConfig(CombatType.PvE, Name = "Use new Eukrasian Logic")] + public bool NewELogic { get; set; } = true; + [RotationConfig(CombatType.PvE, Name = "Use spells with cast times to heal. (Ignored if you are the only healer in party)")] public bool GCDHeal { get; set; } = false; @@ -80,22 +81,8 @@ public sealed class SGE_Default : SageRotation #endregion #region oGCD Logic - [RotationDesc(ActionID.PsychePvE)] - protected override bool AttackAbility(IAction nextGCD, out IAction? act) - { - if (PsychePvE.CanUse(out act)) return true; - - return base.AttackAbility(nextGCD, out act); - } - protected override bool EmergencyAbility(IAction nextGCD, out IAction? act) { - 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, @@ -127,6 +114,14 @@ protected override bool EmergencyAbility(IAction nextGCD, out IAction? act) return base.EmergencyAbility(nextGCD, out act); } + [RotationDesc(ActionID.PsychePvE)] + protected override bool AttackAbility(IAction nextGCD, out IAction? act) + { + if (PsychePvE.CanUse(out act)) return true; + + return base.AttackAbility(nextGCD, out act); + } + [RotationDesc(ActionID.PanhaimaPvE, ActionID.KeracholePvE, ActionID.HolosPvE)] protected override bool DefenseAreaAbility(IAction nextGCD, out IAction? act) { @@ -340,6 +335,66 @@ private bool DoEukrasia(out IAction? act) } return false; } + + // Attempts to perform a Eukrasia action, based on the current game state and conditions. + private bool DoEukrasianPrognosis(out IAction? act) + { + act = null; + + if (_EukrasiaActionAim != null && (_EukrasiaActionAim == EukrasianPrognosisPvE || _EukrasiaActionAim == EukrasianPrognosisIiPvE) && _EukrasiaActionAim.CanUse(out act)) + { + if (EukrasiaPvE.CanUse(out act)) return true; + + act = _EukrasiaActionAim; + return true; + } + return false; + } + + // Attempts to perform a Eukrasia action, based on the current game state and conditions. + private bool DoEukrasianDiagnosis(out IAction? act) + { + act = null; + + if (_EukrasiaActionAim != null && _EukrasiaActionAim == EukrasianDiagnosisPvE && _EukrasiaActionAim.CanUse(out act)) + { + if (EukrasiaPvE.CanUse(out act)) return true; + + act = _EukrasiaActionAim; + return true; + } + return false; + } + + // Attempts to perform a Eukrasia action, based on the current game state and conditions. + private bool DoEukrasianDyskrasia(out IAction? act) + { + act = null; + + if (_EukrasiaActionAim != null && _EukrasiaActionAim == EukrasianDyskrasiaPvE && _EukrasiaActionAim.CanUse(out act)) + { + if (EukrasiaPvE.CanUse(out act)) return true; + + act = _EukrasiaActionAim; + return true; + } + return false; + } + + // Attempts to perform a Eukrasia action, based on the current game state and conditions. + private bool DoEukrasianDosis(out IAction? act) + { + act = null; + + if (_EukrasiaActionAim != null && (_EukrasiaActionAim == EukrasianDosisPvE || _EukrasiaActionAim == EukrasianDosisIiPvE || _EukrasiaActionAim == EukrasianDosisIiiPvE) && _EukrasiaActionAim.CanUse(out act)) + { + if (EukrasiaPvE.CanUse(out act)) return true; + + act = _EukrasiaActionAim; + return true; + } + return false; + } #endregion #region GCD Logic @@ -347,15 +402,14 @@ private bool DoEukrasia(out IAction? act) protected override bool HealAreaGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && EgeiroPvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (PartyMembersAverHP < PneumaAOEPartyHeal || DyskrasiaPvE.CanUse(out _) && PartyMembers.GetJobCategory(JobRole.Tank).Any(t => t.GetHealthRatio() < PneumaAOETankHeal)) { if (PneumaPvE.CanUse(out act)) return true; } - if (!DoEukrasia(out _) && PrognosisPvE.CanUse(out act)) + if (_EukrasiaActionAim != null && PrognosisPvE.CanUse(out act)) { return true; } @@ -367,10 +421,9 @@ protected override bool HealAreaGCD(out IAction? act) protected override bool HealSingleGCD(out IAction? act) { act = null; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; - if (HasSwift && SwiftLogic && EgeiroPvE.CanUse(out _)) return false; - - if (!DoEukrasia(out _) && DiagnosisPvE.CanUse(out act)) + if (_EukrasiaActionAim != null && DiagnosisPvE.CanUse(out act)) { return true; } @@ -380,7 +433,7 @@ 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 (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (PhlegmaPvE.CanUse(out act, usedUp: IsMoving)) return true; @@ -391,11 +444,16 @@ protected override bool GeneralGCD(out IAction? act) if (IsMoving && ToxikonPvE.CanUse(out act)) return true; + if (NewELogic && DoEukrasianDyskrasia(out act)) return true; + if ((_EukrasiaActionAim != EukrasianDiagnosisPvE || _EukrasiaActionAim != EukrasianPrognosisPvE || _EukrasiaActionAim != EukrasianPrognosisIiPvE || _EukrasiaActionAim != EukrasianDyskrasiaPvE) && DyskrasiaPvE.CanUse(out act)) return true; - if (DoEukrasia(out act)) return true; + if (NewELogic && DoEukrasianPrognosis(out act)) return true; + if (NewELogic && DoEukrasianDiagnosis(out act)) return true; + if (!NewELogic && DoEukrasia(out act)) return true; + if (NewELogic && DoEukrasianDosis(out act)) return true; if (DosisPvE.CanUse(out act)) return true; if (!InCombat && !Player.HasStatus(true, StatusID.Eukrasia) && EukrasiaPvE.CanUse(out act)) return true; diff --git a/BasicRotations/Healer/WHM_Default.cs b/BasicRotations/Healer/WHM_Default.cs index f6a75f99e..2530725bd 100644 --- a/BasicRotations/Healer/WHM_Default.cs +++ b/BasicRotations/Healer/WHM_Default.cs @@ -170,8 +170,7 @@ protected override bool AttackAbility(IAction nextGCD, out IAction? act) protected override bool HealAreaGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && RaisePvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (AfflatusRapturePvE.CanUse(out act)) return true; @@ -190,8 +189,7 @@ protected override bool HealAreaGCD(out IAction? act) protected override bool HealSingleGCD(out IAction? act) { act = null; - - if (HasSwift && SwiftLogic && RaisePvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; if (AfflatusSolacePvE.CanUse(out act)) return true; @@ -206,9 +204,8 @@ protected override bool HealSingleGCD(out IAction? act) protected override bool GeneralGCD(out IAction? act) { - act = null; - if (HasSwift && SwiftLogic && RaisePvE.CanUse(out _)) return false; + if (HasSwift && SwiftLogic && MergedStatus.HasFlag(AutoStatus.Raise)) return false; //if (NotInCombatDelay && RegenDefense.CanUse(out act)) return true; diff --git a/BasicRotations/Ranged/BRD_Default.cs b/BasicRotations/Ranged/BRD_Default.cs index 8aa7f6132..bca080323 100644 --- a/BasicRotations/Ranged/BRD_Default.cs +++ b/BasicRotations/Ranged/BRD_Default.cs @@ -243,8 +243,8 @@ protected override bool GeneralGCD(out IAction? act) } else { - if (WindbitePvE.CanUse(out act)) return true; - if (VenomousBitePvE.CanUse(out act)) return true; + if (WindbitePvE.CanUse(out act, skipTTKCheck: true)) return true; + if (VenomousBitePvE.CanUse(out act, skipTTKCheck: true)) return true; } diff --git a/ECommons b/ECommons index 3de0ce6a4..d6eea1e99 160000 --- a/ECommons +++ b/ECommons @@ -1 +1 @@ -Subproject commit 3de0ce6a4acb79e058a2ab09ccbc9113c8b15bfc +Subproject commit d6eea1e999a069c2716a4fa07ff40209c1c28118 diff --git a/RotationSolver.Basic/DataCenter.cs b/RotationSolver.Basic/DataCenter.cs index 1692fdaeb..f93b4c629 100644 --- a/RotationSolver.Basic/DataCenter.cs +++ b/RotationSolver.Basic/DataCenter.cs @@ -804,10 +804,7 @@ internal static void AddDamageRec(float damageRatio) public static bool IsCastingTankVfx() { - // Create a copy of the VfxDataQueue to avoid modification during enumeration - var vfxDataQueueCopy = VfxDataQueue.ToList(); - - return IsCastingVfx(vfxDataQueueCopy, s => + return IsCastingVfx(VfxDataQueue, s => { if (!s.Path.StartsWith("vfx/lockon/eff/tank_lockon")) return false; if (!Player.Available) return false; @@ -867,8 +864,17 @@ public static bool IsHostileCastingBase(IBattleChara h, Func check // Check if h is null if (h == null) return false; - // Check if the hostile character is casting - if (!h.IsCasting) return false; + try + { + // Check if the hostile character is casting + if (!h.IsCasting) return false; + } + catch (AccessViolationException ex) + { + // Log the exception and return false + Svc.Log.Error($"AccessViolationException: {ex.Message}"); + return false; + } // Check if the cast is interruptible if (h.IsCastInterruptible) return false; diff --git a/RotationSolver.Basic/Helpers/ObjectHelper.cs b/RotationSolver.Basic/Helpers/ObjectHelper.cs index 11e27567a..265cb5dac 100644 --- a/RotationSolver.Basic/Helpers/ObjectHelper.cs +++ b/RotationSolver.Basic/Helpers/ObjectHelper.cs @@ -89,6 +89,9 @@ internal static bool IsAttackable(this IBattleChara battleChara) // Check if the target is invincible. if (battleChara.IsJeunoBossImmune()) return false; + // Ensure StatusList is not null before accessing it + if (battleChara.StatusList == null) return false; + foreach (var status in battleChara.StatusList) { if (StatusHelper.IsInvincible(status) && (DataCenter.IsPvP && !Service.Config.IgnorePvPInvincibility || !DataCenter.IsPvP)) return false; @@ -427,20 +430,28 @@ internal static bool IsTopPriorityHostile(this IGameObject obj) /// internal static bool CanInterrupt(this IGameObject o) { - if (o is not IBattleChara b) return false; + try + { + if (o is not IBattleChara b) return false; - var baseCheck = b.IsCasting && b.IsCastInterruptible && b.TotalCastTime >= 2; - if (!baseCheck) return false; - if (!Service.Config.InterruptibleMoreCheck) return false; + var baseCheck = b.IsCasting && b.IsCastInterruptible && b.TotalCastTime >= 2; + if (!baseCheck) return false; + if (!Service.Config.InterruptibleMoreCheck) return false; - var id = b.CastActionId; - if (_effectRangeCheck.TryGetValue(id, out var check)) return check; + var id = b.CastActionId; + if (_effectRangeCheck.TryGetValue(id, out var check)) return check; - var act = Service.GetSheet().GetRow(b.CastActionId); - if (act.RowId == 0) return _effectRangeCheck[id] = false; - if (act.CastType == 3 || act.CastType == 4 || (act.EffectRange > 0 && act.EffectRange < 8)) return _effectRangeCheck[id] = false; + var act = Service.GetSheet().GetRow(b.CastActionId); + if (act.RowId == 0) return _effectRangeCheck[id] = false; + if (act.CastType == 3 || act.CastType == 4 || (act.EffectRange > 0 && act.EffectRange < 8)) return _effectRangeCheck[id] = false; - return _effectRangeCheck[id] = true; + return _effectRangeCheck[id] = true; + } + catch (AccessViolationException ex) + { + Svc.Log.Error($"Access violation in CanInterrupt: {ex}"); + return false; + } } internal static bool IsDummy(this IBattleChara obj) => obj?.NameId == 541; diff --git a/RotationSolver.Basic/Rotations/CustomRotation_Invoke.cs b/RotationSolver.Basic/Rotations/CustomRotation_Invoke.cs index 90bfcf1eb..f94648c70 100644 --- a/RotationSolver.Basic/Rotations/CustomRotation_Invoke.cs +++ b/RotationSolver.Basic/Rotations/CustomRotation_Invoke.cs @@ -106,8 +106,18 @@ private void UpdateDefenseActions(out IAction? act) ActionDefenseSingleGCD = DefenseSingleGCD(out act) ? act : null; IBaseAction.TargetOverride = null; - ActionDefenseAreaAbility = DefenseAreaAbility(AddlePvE, out act) ? act : null; - ActionDefenseSingleAbility = DefenseSingleAbility(AddlePvE, out act) ? act : null; + try + { + ActionDefenseAreaAbility = DefenseAreaAbility(AddlePvE, out act) ? act : null; + ActionDefenseSingleAbility = DefenseSingleAbility(AddlePvE, out act) ? act : null; + } + catch (MissingMethodException ex) + { + // Log the exception or handle it as needed + WarningHelper.AddSystemWarning($"Exception in UpdateDefenseActions method: {ex.Message}"); + // Optionally, set actions to null in case of an exception + ActionDefenseAreaAbility = ActionDefenseSingleAbility = null; + } } private void UpdateDispelAndRaiseActions(JobRole role, out IAction? act) diff --git a/RotationSolver/Commands/RSCommands_Actions.cs b/RotationSolver/Commands/RSCommands_Actions.cs index 0daf43610..187249820 100644 --- a/RotationSolver/Commands/RSCommands_Actions.cs +++ b/RotationSolver/Commands/RSCommands_Actions.cs @@ -175,12 +175,20 @@ internal static void UpdateRotationState() ActionUpdater.AutoCancelTime = DateTime.MinValue; } + var playerObject = Player.Object; + if (playerObject == null) + { + if (Service.Config.InDebug) + Svc.Log.Error("Player object is null."); + return; + } + var target = DataCenter.AllHostileTargets - .FirstOrDefault(t => t != null && t.TargetObjectId == Player.Object?.GameObjectId); + .FirstOrDefault(t => t != null && t.TargetObjectId == playerObject.GameObjectId); if (Svc.Condition[ConditionFlag.LoggingOut] || - (Service.Config.AutoOffWhenDead && DataCenter.Territory?.IsPvP == false && Player.Available && Player.Object?.CurrentHp == 0) || - (Service.Config.AutoOffWhenDeadPvP && DataCenter.Territory?.IsPvP == true && Player.Available && Player.Object?.CurrentHp == 0) || + (Service.Config.AutoOffWhenDead && DataCenter.Territory?.IsPvP == false && Player.Available && playerObject.CurrentHp == 0) || + (Service.Config.AutoOffWhenDeadPvP && DataCenter.Territory?.IsPvP == true && Player.Available && playerObject.CurrentHp == 0) || (Service.Config.AutoOffPvPMatchEnd && Svc.Condition[ConditionFlag.PvPDisplayActive]) || (Service.Config.AutoOffCutScene && Svc.Condition[ConditionFlag.OccupiedInCutSceneEvent]) || (Service.Config.AutoOffSwitchClass && Player.Job != _previousJob) || @@ -247,5 +255,6 @@ internal static void UpdateRotationState() Svc.Log.Error(ex, "Exception in UpdateRotationState"); } } + } } diff --git a/RotationSolver/Updaters/TargetUpdater.cs b/RotationSolver/Updaters/TargetUpdater.cs index e9f8e9e1f..3c3220853 100644 --- a/RotationSolver/Updaters/TargetUpdater.cs +++ b/RotationSolver/Updaters/TargetUpdater.cs @@ -168,9 +168,16 @@ private static List GetAllHostileTargets() { foreach (var target in DataCenter.AllHostileTargets) { - if (predicate(target)) + try { - return target; + if (predicate(target)) + { + return target; + } + } + catch (Exception ex) + { + Svc.Log.Error($"Error in GetFirstHostileTarget: {ex.Message}"); } } return null; @@ -204,47 +211,27 @@ private static List GetAllHostileTargets() { validRaiseTargets.AddRange(deathParty); } - - if (raisetype == RaiseType.PartyAndAllianceSupports) + else if (raisetype == RaiseType.PartyAndAllianceSupports) { validRaiseTargets.AddRange(raisePartyAndAllianceSupports); } - - if (raisetype == RaiseType.PartyAndAllianceHealers) + else if (raisetype == RaiseType.PartyAndAllianceHealers) { validRaiseTargets.AddRange(raisePartyAndAllianceHealers); } - - if (raisetype == RaiseType.All) + else if (raisetype == RaiseType.All) { validRaiseTargets.AddRange(deathAll); } - if (Service.Config.FriendlyPartyNpcHealRaise2) + if (Service.Config.FriendlyPartyNpcHealRaise2 || Service.Config.FocusTargetIsParty) { validRaiseTargets.AddRange(deathNPC); } - if (Service.Config.FocusTargetIsParty) - { - validRaiseTargets.AddRange(deathNPC); - } - - var deathTarget = GetPriorityDeathTarget(validRaiseTargets, RaiseType.PartyOnly); - if (deathTarget != null) return deathTarget; - - deathTarget = GetPriorityDeathTarget(validRaiseTargets, RaiseType.PartyAndAllianceSupports); - if (deathTarget != null) return deathTarget; - - deathTarget = GetPriorityDeathTarget(validRaiseTargets, RaiseType.PartyAndAllianceHealers); - if (deathTarget != null) return deathTarget; - - deathTarget = GetPriorityDeathTarget(validRaiseTargets, RaiseType.All); - if (deathTarget != null) return deathTarget; - - if (Service.Config.FriendlyPartyNpcHealRaise2) + foreach (var type in Enum.GetValues(typeof(RaiseType)).Cast()) { - deathTarget = GetPriorityDeathTarget(validRaiseTargets, Service.Config.RaiseType); + var deathTarget = GetPriorityDeathTarget(validRaiseTargets, type); if (deathTarget != null) return deathTarget; } } @@ -280,38 +267,9 @@ private static List GetAllHostileTargets() } } - if (raiseType == RaiseType.PartyAndAllianceHealers) - { - foreach (var chara in validRaiseTargets) - { - if (chara.IsJobCategory(JobRole.Healer)) - { - deathHealers.Add(chara); - } - } - } - else if (raiseType == RaiseType.PartyAndAllianceSupports) - { - foreach (var chara in validRaiseTargets) - { - if (chara.IsJobCategory(JobRole.Tank)) - { - deathTanks.Add(chara); - } - else if (chara.IsJobCategory(JobRole.Healer)) - { - deathHealers.Add(chara); - } - else - { - deathOthers.Add(chara); - } - } - } - - if (raiseType == RaiseType.PartyAndAllianceHealers) + if (raiseType == RaiseType.PartyAndAllianceHealers && deathHealers.Count > 0) { - if (deathHealers.Count > 0) return deathHealers[0]; + return deathHealers[0]; } if (deathTanks.Count > 1) return deathTanks[0];