diff --git a/RotationSolver.Basic/Actions/ActionTargetInfo.cs b/RotationSolver.Basic/Actions/ActionTargetInfo.cs index cac1a8e1..f7ffda9b 100644 --- a/RotationSolver.Basic/Actions/ActionTargetInfo.cs +++ b/RotationSolver.Basic/Actions/ActionTargetInfo.cs @@ -254,27 +254,39 @@ private bool CheckStatus(IGameObject gameObject, bool skipStatusProvideCheck) /// private bool CheckResistance(IGameObject gameObject) { - if (action.Info.AttackType == AttackType.Magic) + if (gameObject == null) return false; + + try { - if (gameObject.HasStatus(false, StatusHelper.MagicResistance)) + if (action.Info.AttackType == AttackType.Magic) { - return false; + if (gameObject.HasStatus(false, StatusHelper.MagicResistance)) + { + return false; + } } - } - else if (action.Info.Aspect != Aspect.Piercing) // Physical - { - if (gameObject.HasStatus(false, StatusHelper.PhysicalResistance)) + else if (action.Info.Aspect != Aspect.Piercing) // Physical { - return false; + if (gameObject.HasStatus(false, StatusHelper.PhysicalResistance)) + { + return false; + } } - } - if (Range >= 20) // Range - { - if (gameObject.HasStatus(false, StatusID.RangedResistance, StatusID.EnergyField)) + if (Range >= 20) // Range { - return false; + if (gameObject.HasStatus(false, StatusID.RangedResistance, StatusID.EnergyField)) + { + return false; + } } } + catch (Exception ex) + { + // Log the exception for debugging purposes + Svc.Log.Error($"Error checking resistance: {ex.Message}"); + return false; + } + return true; } diff --git a/RotationSolver.Basic/Helpers/ObjectHelper.cs b/RotationSolver.Basic/Helpers/ObjectHelper.cs index 26e955dc..11e27567 100644 --- a/RotationSolver.Basic/Helpers/ObjectHelper.cs +++ b/RotationSolver.Basic/Helpers/ObjectHelper.cs @@ -132,12 +132,12 @@ internal static bool IsAttackable(this IBattleChara battleChara) { TargetHostileType.AllTargetsCanAttack => true, TargetHostileType.TargetsHaveTarget => battleChara.TargetObject is IBattleChara, - TargetHostileType.AllTargetsWhenSolo => DataCenter.PartyMembers.Count < 2 || battleChara.TargetObject is IBattleChara, - TargetHostileType.AllTargetsWhenSoloInDuty => (DataCenter.PartyMembers.Count < 2 && (Svc.Condition[ConditionFlag.BoundByDuty] || Svc.Condition[ConditionFlag.BoundByDuty56])) + TargetHostileType.AllTargetsWhenSolo => DataCenter.PartyMembers.Count == 1 || battleChara.TargetObject is IBattleChara, + TargetHostileType.AllTargetsWhenSoloInDuty => (DataCenter.PartyMembers.Count == 1 && (Svc.Condition[ConditionFlag.BoundByDuty] || Svc.Condition[ConditionFlag.BoundByDuty56])) || battleChara.TargetObject is IBattleChara, TargetHostileType.TargetIsInEnemiesList => battleChara.TargetObject is IBattleChara target && target.IsInEnemiesList(), - TargetHostileType.AllTargetsWhenSoloTargetIsInEnemiesList => (DataCenter.PartyMembers.Count < 2 && (Svc.Condition[ConditionFlag.BoundByDuty] || Svc.Condition[ConditionFlag.BoundByDuty56])) || battleChara.TargetObject is IBattleChara target && target.IsInEnemiesList(), - TargetHostileType.AllTargetsWhenSoloInDutyTargetIsInEnemiesList => DataCenter.PartyMembers.Count < 2 || battleChara.TargetObject is IBattleChara target && target.IsInEnemiesList(), + TargetHostileType.AllTargetsWhenSoloTargetIsInEnemiesList => (DataCenter.PartyMembers.Count == 1 && (Svc.Condition[ConditionFlag.BoundByDuty] || Svc.Condition[ConditionFlag.BoundByDuty56])) || battleChara.TargetObject is IBattleChara target && target.IsInEnemiesList(), + TargetHostileType.AllTargetsWhenSoloInDutyTargetIsInEnemiesList => DataCenter.PartyMembers.Count == 1 || battleChara.TargetObject is IBattleChara target && target.IsInEnemiesList(), _ => true, }; } diff --git a/RotationSolver.Basic/Helpers/StatusHelper.cs b/RotationSolver.Basic/Helpers/StatusHelper.cs index bb9f21c9..4c1ab3e9 100644 --- a/RotationSolver.Basic/Helpers/StatusHelper.cs +++ b/RotationSolver.Basic/Helpers/StatusHelper.cs @@ -1,5 +1,6 @@ using Dalamud.Game.ClientState.Statuses; using ECommons.Automation; +using ECommons.DalamudServices; using ECommons.GameHelpers; using ECommons.Logging; using RotationSolver.Basic.Configuration; @@ -339,11 +340,27 @@ private static IEnumerable GetAllStatus(this IGameObject obj, bool isFro if (obj is not IBattleChara b) return Enumerable.Empty(); var playerId = Player.Object?.GameObjectId ?? 0; - // Ensure b.StatusList is not null - return b.StatusList?.Where(status => !isFromSelf - || status.SourceId == playerId - || status.SourceObject?.OwnerId == playerId) - ?? Enumerable.Empty(); + + try + { + // Ensure b.StatusList is not null + if (b.StatusList == null) + { + PluginLog.Error("StatusList is null. Cannot get statuses."); + return Enumerable.Empty(); + } + + return b.StatusList.Where(status => !isFromSelf + || status.SourceId == playerId + || status.SourceObject?.OwnerId == playerId) + ?? Enumerable.Empty(); + } + catch (Exception ex) + { + // Log the exception + Svc.Log.Error($"Failed to get statuses: {ex.Message}"); + return Enumerable.Empty(); + } } /// diff --git a/RotationSolver.Basic/Rotations/Basic/NinjaRotation.cs b/RotationSolver.Basic/Rotations/Basic/NinjaRotation.cs index e293d1e6..9a1cd0ff 100644 --- a/RotationSolver.Basic/Rotations/Basic/NinjaRotation.cs +++ b/RotationSolver.Basic/Rotations/Basic/NinjaRotation.cs @@ -528,7 +528,7 @@ protected sealed override bool MoveForwardAbility(IAction nextGCD, out IAction? [RotationDesc(ActionID.FeintPvE)] protected sealed override bool DefenseAreaAbility(IAction nextGCD, out IAction? act) { - if (FeintPvE.CanUse(out act)) return true; + if (FeintPvE.CanUse(out act) && !Player.HasStatus(true, StatusID.Mudra)) return true; return base.DefenseAreaAbility(nextGCD, out act); } diff --git a/RotationSolver.Basic/Rotations/Basic/SageRotation.cs b/RotationSolver.Basic/Rotations/Basic/SageRotation.cs index 02ca79ac..b8bae7e8 100644 --- a/RotationSolver.Basic/Rotations/Basic/SageRotation.cs +++ b/RotationSolver.Basic/Rotations/Basic/SageRotation.cs @@ -199,6 +199,7 @@ static partial void ModifyZoePvE(ref ActionSetting setting) static partial void ModifyPepsisPvE(ref ActionSetting setting) { + setting.StatusNeed = [StatusID.EukrasianPrognosis]; setting.CreateConfig = () => new ActionConfig() { AoeCount = 1, diff --git a/RotationSolver.Basic/Rotations/CustomRotation_Ability.cs b/RotationSolver.Basic/Rotations/CustomRotation_Ability.cs index a48c7e35..55e85313 100644 --- a/RotationSolver.Basic/Rotations/CustomRotation_Ability.cs +++ b/RotationSolver.Basic/Rotations/CustomRotation_Ability.cs @@ -40,7 +40,7 @@ private bool Ability(IAction nextGCD, out IAction? act) var role = DataCenter.Role; IBaseAction.TargetOverride = TargetType.Interrupt; - if (DataCenter.MergedStatus.HasFlag(AutoStatus.Interrupt) && MyInterruptAbility(role, nextGCD, out act)) + if (DataCenter.MergedStatus.HasFlag(AutoStatus.Interrupt) && !Player.HasStatus(true, StatusID.Mudra) && MyInterruptAbility(role, nextGCD, out act)) { return true; } @@ -71,7 +71,7 @@ private bool Ability(IAction nextGCD, out IAction? act) { IBaseAction.ShouldEndSpecial = true; } - if (DataCenter.MergedStatus.HasFlag(AutoStatus.AntiKnockback) && AntiKnockback(role, nextGCD, out act)) + if (DataCenter.MergedStatus.HasFlag(AutoStatus.AntiKnockback) && !Player.HasStatus(true, StatusID.Mudra) && AntiKnockback(role, nextGCD, out act)) { return true; } @@ -81,7 +81,7 @@ private bool Ability(IAction nextGCD, out IAction? act) { IBaseAction.ShouldEndSpecial = true; } - if (DataCenter.MergedStatus.HasFlag(AutoStatus.Positional) && TrueNorthPvE.Cooldown.CurrentCharges > 0 && !IsLastAbility(true, TrueNorthPvE) && TrueNorthPvE.CanUse(out act, skipComboCheck: true, usedUp: true)) + if (DataCenter.MergedStatus.HasFlag(AutoStatus.Positional) && !Player.HasStatus(true, StatusID.Mudra) && TrueNorthPvE.Cooldown.CurrentCharges > 0 && !IsLastAbility(true, TrueNorthPvE) && TrueNorthPvE.CanUse(out act, skipComboCheck: true, usedUp: true)) { return true; } @@ -271,7 +271,7 @@ private bool MyInterruptAbility(JobRole role, IAction nextGCD, out IAction? act) break; case JobRole.Melee: - if (LegSweepPvE.CanUse(out act)) return true; + if (LegSweepPvE.CanUse(out act) && !Player.HasStatus(true, StatusID.Mudra)) return true; break; case JobRole.RangedPhysical: @@ -312,7 +312,7 @@ private bool AntiKnockback(JobRole role, IAction nextGCD, out IAction? act) { case JobRole.Tank: case JobRole.Melee: - if (ArmsLengthPvE.CanUse(out act)) return true; + if (ArmsLengthPvE.CanUse(out act) && !Player.HasStatus(true, StatusID.Mudra)) return true; break; case JobRole.Healer: case JobRole.RangedMagical: @@ -372,8 +372,8 @@ private bool GeneralUsingAbility(JobRole role, IAction nextGCD, out IAction? act break; case JobRole.Melee: - if (SecondWindPvE.CanUse(out act)) return true; - if (BloodbathPvE.CanUse(out act)) return true; + if (SecondWindPvE.CanUse(out act) && !Player.HasStatus(true, StatusID.Mudra)) return true; + if (BloodbathPvE.CanUse(out act) && !Player.HasStatus(true, StatusID.Mudra)) return true; break; case JobRole.Healer: diff --git a/RotationSolver/Commands/RSCommands_Actions.cs b/RotationSolver/Commands/RSCommands_Actions.cs index 52dd1b70..0daf4361 100644 --- a/RotationSolver/Commands/RSCommands_Actions.cs +++ b/RotationSolver/Commands/RSCommands_Actions.cs @@ -190,7 +190,9 @@ internal static void UpdateRotationState() (DataCenter.RightSet.SwitchCancelConditionSet?.IsTrue(DataCenter.RightNowRotation) ?? false)) { CancelState(); +#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null' if (Player.Job != null && Player.Job != _previousJob) _previousJob = Player.Job; +#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null' if (ActionUpdater.AutoCancelTime != DateTime.MinValue) ActionUpdater.AutoCancelTime = DateTime.MinValue; } else if ((Service.Config.AutoOnPvPMatchStart && Svc.Condition[ConditionFlag.BetweenAreas] &&