From a2ff2a5aed559de4dcec460807590a162c0631f7 Mon Sep 17 00:00:00 2001 From: edewen Date: Mon, 29 Jun 2026 08:47:49 -0400 Subject: [PATCH 1/4] Retarget ranged shots for tanks --- WrathCombo/Combos/CustomComboPreset.cs | 21 ++- WrathCombo/Combos/PvE/DRK/DRK.cs | 26 +++ WrathCombo/Combos/PvE/DRK/DRK_Config.cs | 140 +++++++------- WrathCombo/Combos/PvE/GNB/GNB.cs | 27 +++ WrathCombo/Combos/PvE/GNB/GNB_Config.cs | 9 +- WrathCombo/Combos/PvE/PLD/PLD.cs | 23 ++- WrathCombo/Combos/PvE/PLD/PLD_Config.cs | 25 ++- WrathCombo/Combos/PvE/WAR/WAR.cs | 28 +++ WrathCombo/Combos/PvE/WAR/WAR_Config.cs | 11 +- WrathCombo/CustomCombo/SimpleTarget.cs | 7 + WrathCombo/Extensions/GameObjectExtensions.cs | 7 + .../JobConfigs/Generics.Designer.cs | 46 ++++- .../Localization/JobConfigs/Generics.resx | 12 ++ .../Presets/CustomComboPresets.Designer.cs | 173 ++++++++++++------ .../Presets/CustomComboPresets.resx | 23 ++- 15 files changed, 429 insertions(+), 149 deletions(-) diff --git a/WrathCombo/Combos/CustomComboPreset.cs b/WrathCombo/Combos/CustomComboPreset.cs index 6e1c4ba6a3..ce22ae884d 100644 --- a/WrathCombo/Combos/CustomComboPreset.cs +++ b/WrathCombo/Combos/CustomComboPreset.cs @@ -2841,9 +2841,14 @@ public enum Preset [JobInfo(Job.DRK)] [Retargeted(DRK.Shadowstride)] DRK_RetargetShadowstride = 5135, + + [ReplaceSkill(DRK.Unmend)] + [JobInfo(Job.DRK)] + [Retargeted(DRK.Unmend)] + DRK_Retarget_Unmend = 5136, #endregion - // Last value = 5135 + // Last value = 5136 #endregion // Last value = 5135 @@ -3534,9 +3539,14 @@ public enum Preset [JobInfo(Job.GNB)] [Retargeted(GNB.Trajectory)] GNB_RetargetTrajectory = 7091, + + [ReplaceSkill(GNB.LightningShot)] + [JobInfo(Job.GNB)] + [Retargeted(GNB.LightningShot)] + GNB_RetargetLightningShot = 7094, #endregion - // Last Value = 7093 + // Last Value = 7094 #endregion #region MACHINIST @@ -7655,9 +7665,14 @@ public enum Preset [JobInfo(Job.WAR)] [Retargeted(WAR.Holmgang)] WAR_RetargetHolmgang = 18130, + + [ReplaceSkill(WAR.Tomahawk)] + [JobInfo(Job.WAR)] + [Retargeted(WAR.Tomahawk)] + WAR_RetargetTomahawk = 18156, #endregion - // Last value = 18155 + // Last value = 18156 #endregion #region WHITE MAGE diff --git a/WrathCombo/Combos/PvE/DRK/DRK.cs b/WrathCombo/Combos/PvE/DRK/DRK.cs index e0a2d9e8b9..b068dab2c9 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK.cs @@ -449,6 +449,32 @@ protected override uint Invoke(uint actionID) : actionID; } } + + internal class DRK_RetargetUnmend : CustomCombo + { + protected internal override Preset Preset => Preset.DRK_Retarget_Unmend; + + protected override uint Invoke(uint actionID) + { + if (actionID is not Unmend) + return actionID; + + IGameObject? target = + //Mouseover Retarget + (DRK_Retarget_Unmend_FieldMO + ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Unmend.ActionRange()) + : null) ?? + + (DRK_Retarget_Unmend_NearestOOR + ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(Unmend.ActionRange()) + : null); + + return target != null + ? actionID.Retarget(target) + : actionID; + } + } + #endregion diff --git a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs index fb046a7264..d6425c3e0e 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs @@ -7,6 +7,7 @@ using WrathCombo.Extensions; using WrathCombo.Resources.Localization.JobConfigs; using WrathCombo.Window.Functions; +using static WrathCombo.Window.Functions.UserConfig; using BossAvoidance = WrathCombo.Combos.PvE.All.Enums.BossAvoidance; using PartyRequirement = WrathCombo.Combos.PvE.All.Enums.PartyRequirement; using static WrathCombo.Window.Text; @@ -38,48 +39,48 @@ internal static void Draw(Preset preset) #region Simple case Preset.DRK_ST_Simple: - UserConfig.DrawHorizontalRadioButton(DRK_ST_SimpleMitigation, + DrawHorizontalRadioButton(DRK_ST_SimpleMitigation, "Include Mitigations", "Enables the use of mitigations in Simple Mode.", (int)SimpleMitigation.On); - UserConfig.DrawHorizontalRadioButton(DRK_ST_SimpleMitigation, + DrawHorizontalRadioButton(DRK_ST_SimpleMitigation, "Exclude Mitigations", "Disables the use of mitigations in Simple Mode.", (int)SimpleMitigation.Off); break; case Preset.DRK_AoE_Simple: - UserConfig.DrawHorizontalRadioButton(DRK_AoE_SimpleMitigation, + DrawHorizontalRadioButton(DRK_AoE_SimpleMitigation, "Include Mitigations", "Enables the use of mitigations in Simple Mode.", (int)SimpleMitigation.On); - UserConfig.DrawHorizontalRadioButton(DRK_AoE_SimpleMitigation, + DrawHorizontalRadioButton(DRK_AoE_SimpleMitigation, "Exclude Mitigations", "Disables the use of mitigations in Simple Mode.", (int)SimpleMitigation.Off); break; case Preset.DRK_ST_Adv: - UserConfig.DrawHorizontalRadioButton(DRK_ST_AdvancedMitigation, + DrawHorizontalRadioButton(DRK_ST_AdvancedMitigation, "Include Mitigations", "Enables the use of advanced mitigations", (int)SimpleMitigation.On); - UserConfig.DrawHorizontalRadioButton(DRK_ST_AdvancedMitigation, + DrawHorizontalRadioButton(DRK_ST_AdvancedMitigation, "Exclude Mitigations", "Disables the use of advanced mitigations", (int)SimpleMitigation.Off); break; case Preset.DRK_AoE_Adv: - UserConfig.DrawHorizontalRadioButton(DRK_AoE_AdvancedMitigation, + DrawHorizontalRadioButton(DRK_AoE_AdvancedMitigation, "Include Mitigations", "Enables the use of advanced mitigations", (int)SimpleMitigation.On); - UserConfig.DrawHorizontalRadioButton(DRK_AoE_AdvancedMitigation, + DrawHorizontalRadioButton(DRK_AoE_AdvancedMitigation, "Exclude Mitigations", "Disables the use of advanced mitigations ", (int)SimpleMitigation.Off); @@ -91,7 +92,7 @@ internal static void Draw(Preset preset) case Preset.DRK_Mitigation_NonBoss: ImGui.Indent(); - UserConfig.DrawSliderFloat(0, 100, + DrawSliderFloat(0, 100, DRK_Mit_NonBoss_Threshold, Generics.StopEnemyHpPercent, itemWidth: medium, decimals: 0); @@ -99,46 +100,46 @@ internal static void Draw(Preset preset) break; case Preset.DRK_Mitigation_NonBoss_LivingDead: - UserConfig.DrawSliderInt(1, 100, + DrawSliderInt(1, 100, DRK_Mit_NonBoss_LivingDead_Health, startUsingAtDescription, itemWidth: medium, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_Mitigation_Boss_BlackestNight_OnCD: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_BlackestNight_OnCD_Difficulty, DRK_Boss_Mit_DifficultyListSet, "Select what difficulties TBN should be used on CD:"); - UserConfig.DrawSliderInt(1, 100, + DrawSliderInt(1, 100, DRK_Mit_Boss_BlackestNight_Health, Generics.StopFriendlyHpPercent100, itemWidth: medium, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_Mitigation_Boss_BlackestNight_TB: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_BlackestNight_TankBuster_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); - UserConfig.DrawSliderInt( + DrawSliderInt( 0, 4, DRK_Mitigation_Boss_BlackestNightDelay, FormatAndCache(Generics.DelayMit, BlackestNight.ActionName()), sliderIncrement: 1); break; case Preset.DRK_Mitigation_Boss_Rampart: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_Rampart_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); break; case Preset.DRK_Mitigation_Boss_ShadowWall: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_ShadowWall_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); - UserConfig.DrawAdditionalBoolChoice( + DrawAdditionalBoolChoice( DRK_Mit_Boss_ShadowWall_First, "Use ShadowWall/Shadowed Vigil First", "Uses ShadowWall/Shadowed Vigil before Rampart", @@ -146,17 +147,17 @@ internal static void Draw(Preset preset) break; case Preset.DRK_Mitigation_Boss_DarkMind: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_DarkMind_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); ImGui.Indent(); - UserConfig.DrawSliderFloat(1, 100, + DrawSliderFloat(1, 100, DRK_Mit_Boss_DarkMind_Threshold, Generics.StopFriendlyHpPercent100, decimals: 0); ImGui.Unindent(); - UserConfig.DrawAdditionalBoolChoice(DRK_Mit_Boss_DarkMind_Align, + DrawAdditionalBoolChoice(DRK_Mit_Boss_DarkMind_Align, "Align Dark Mind", "Tries to align Dark Mind with Rampart for tankbusters.\n" + "(as it is lesser than Shadow Wall/Shadowed Vigil)", @@ -164,21 +165,21 @@ internal static void Draw(Preset preset) break; case Preset.DRK_Mitigation_Boss_Oblation: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_Oblation_TankBuster_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); break; case Preset.DRK_Mitigation_Boss_DarkMissionary: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_DarkMissionary_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); break; case Preset.DRK_Mitigation_Boss_Reprisal: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_Boss_Reprisal_Difficulty, DRK_Boss_Mit_DifficultyListSet, Generics.SelectWhatKindOfContentThisOptionAppliesTo); @@ -190,28 +191,28 @@ internal static void Draw(Preset preset) case Preset.DRK_ST_BalanceOpener: ImGui.Indent(); - UserConfig.DrawBossOnlyChoice(DRK_ST_OpenerDifficulty); + DrawBossOnlyChoice(DRK_ST_OpenerDifficulty); ImGui.Unindent(); ImGui.NewLine(); ImGui.Indent(); ImGui.Text("Choose the action to pull with: (hover each for more info)"); ImGui.Unindent(); ImGui.NewLine(); - UserConfig.DrawRadioButton(DRK_ST_OpenerAction, + DrawRadioButton(DRK_ST_OpenerAction, "Unmend (Standard)", "Will use Unmend to pull, if selected.\n" + "Should start at -1.0 seconds.\n\n" + "Recommended by The Balance.", outputValue: (int)PullAction.Unmend, descriptionAsTooltip: true); - UserConfig.DrawRadioButton(DRK_ST_OpenerAction, + DrawRadioButton(DRK_ST_OpenerAction, "Shadowstride", "Will use Shadowstride to pull, if selected.\n" + "Will use an extra Hard Slash before Disesteem.\n" + "Should start at -0.7 seconds.", outputValue: (int)PullAction.Shadowstride, descriptionAsTooltip: true); - UserConfig.DrawRadioButton(DRK_ST_OpenerAction, + DrawRadioButton(DRK_ST_OpenerAction, "Hard Slash (Face or Manual Pulling)", "Will use nothing to pull, if selected, just going straight to Hard Slash.\n" + "Will use an extra Hard Slash before Disesteem.\n" + @@ -221,11 +222,11 @@ internal static void Draw(Preset preset) break; case Preset.DRK_ST_CDs: - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_ST_CDsBossRequirement, Generics.AllEnemies, "Will use Cooldowns regardless of the type of enemy.", outputValue: (int)BossRequirement.Off, itemWidth: 125f); - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_ST_CDsBossRequirement, "Only Bosses", "Will try to use Cooldowns only when you're in a boss fight.\n" + "(Note: don't rely on this 100%, square sometimes marks enemies inconsistently)", @@ -234,10 +235,10 @@ internal static void Draw(Preset preset) break; case Preset.DRK_ST_CD_Delirium: - UserConfig.DrawSliderInt(0, 25, DRK_ST_DeliriumThreshold, + DrawSliderInt(0, 25, DRK_ST_DeliriumThreshold, Generics.StopEnemyHpPercent, itemWidth: little, sliderIncrement: SliderIncrements.Fives); - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_ST_DeliriumThresholdDifficulty, DRK_ST_DeliriumThresholdDifficultyListSet ); @@ -245,10 +246,10 @@ internal static void Draw(Preset preset) break; case Preset.DRK_ST_CD_Shadow: - UserConfig.DrawSliderInt(0, 30, DRK_ST_LivingShadowThreshold, + DrawSliderInt(0, 30, DRK_ST_LivingShadowThreshold, Generics.StopEnemyHpPercent, itemWidth: little, sliderIncrement: SliderIncrements.Fives); - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_ST_LivingShadowThresholdDifficulty, DRK_ST_LivingShadowThresholdDifficultyListSet ); @@ -256,17 +257,17 @@ internal static void Draw(Preset preset) break; case Preset.DRK_ST_Sp_BloodOvercap: - UserConfig.DrawSliderInt(50, 100, DRK_ST_BloodOvercapThreshold, + DrawSliderInt(50, 100, DRK_ST_BloodOvercapThreshold, startUsingAboveDescription, itemWidth: medium, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_ST_Sp_Edge: - UserConfig.DrawSliderInt(0, 3000, DRK_ST_ManaSpenderPooling, + DrawSliderInt(0, 3000, DRK_ST_ManaSpenderPooling, "Mana to always save for TBN (0 = Use All)", itemWidth: biggest, sliderIncrement: SliderIncrements.Thousands); - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_ST_ManaSpenderPoolingDifficulty, DRK_ST_ManaSpenderPoolingDifficultyListSet ); @@ -274,7 +275,7 @@ internal static void Draw(Preset preset) break; case Preset.DRK_ST_Sp_ManaOvercap: - UserConfig.DrawSliderInt(0, 30, DRK_ST_BurstSoonThreshold, + DrawSliderInt(0, 30, DRK_ST_BurstSoonThreshold, "Seconds before Burst to save (allowing capping)", itemWidth: little, sliderIncrement: SliderIncrements.Fives); @@ -285,10 +286,10 @@ internal static void Draw(Preset preset) #region Adv AoE case Preset.DRK_AoE_CD_Delirium: - UserConfig.DrawSliderInt(0, 60, DRK_AoE_DeliriumThreshold, + DrawSliderInt(0, 60, DRK_AoE_DeliriumThreshold, Generics.StopEnemyHpPercent, itemWidth: bigger, sliderIncrement: SliderIncrements.Fives); - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_AoE_DeliriumThresholdDifficulty, DRK_AoE_DeliriumThresholdDifficultyListSet ); @@ -296,10 +297,10 @@ internal static void Draw(Preset preset) break; case Preset.DRK_AoE_CD_Shadow: - UserConfig.DrawSliderInt(0, 60, DRK_AoE_LivingShadowThreshold, + DrawSliderInt(0, 60, DRK_AoE_LivingShadowThreshold, Generics.StopEnemyHpPercent, itemWidth: bigger, sliderIncrement: SliderIncrements.Fives); - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_AoE_LivingShadowThresholdDifficulty, DRK_AoE_LivingShadowThresholdDifficultyListSet ); @@ -307,28 +308,28 @@ internal static void Draw(Preset preset) break; case Preset.DRK_AoE_CD_Salt: - UserConfig.DrawSliderInt(0, 60, DRK_AoE_SaltThreshold, + DrawSliderInt(0, 60, DRK_AoE_SaltThreshold, Generics.StopEnemyHpPercent, itemWidth: bigger, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_AoE_CD_Drain: - UserConfig.DrawSliderInt(20, 100, DRK_AoE_DrainThreshold, + DrawSliderInt(20, 100, DRK_AoE_DrainThreshold, Generics.StopFriendlyHpPercent100, itemWidth: bigger, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_AoE_Sp_BloodOvercap: - UserConfig.DrawSliderInt(50, 100, DRK_AoE_BloodOvercapThreshold, + DrawSliderInt(50, 100, DRK_AoE_BloodOvercapThreshold, startUsingAboveDescription, itemWidth: medium, sliderIncrement: SliderIncrements.Fives); break; case Preset.DRK_AoE_Sp_Flood: - UserConfig.DrawSliderInt(0, 3000, DRK_AoE_ManaSpenderPooling, + DrawSliderInt(0, 3000, DRK_AoE_ManaSpenderPooling, "Mana to save for TBN (0 = Use All)", itemWidth: biggest, sliderIncrement: SliderIncrements.Thousands); @@ -340,38 +341,38 @@ internal static void Draw(Preset preset) #region One-Button Mitigation case Preset.DRK_Mit_LivingDead_Max: - UserConfig.DrawDifficultyMultiChoice( + DrawDifficultyMultiChoice( DRK_Mit_EmergencyLivingDead_Difficulty, DRK_Mit_EmergencyLivingDead_DifficultyListSet, "Select what difficulties Emergency Living Dead should be used in:" ); - UserConfig.DrawSliderInt(1, 100, DRK_Mit_LivingDead_Health, + DrawSliderInt(1, 100, DRK_Mit_LivingDead_Health, startUsingAtDescription, itemWidth: medium, sliderIncrement: SliderIncrements.Ones); break; case Preset.DRK_Mit_TheBlackestNight: - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 0, "The Blackest Night Priority:"); break; case Preset.DRK_Mit_Oblation: - UserConfig.DrawSliderInt(0, 1, DRK_Mit_Oblation_Charges, + DrawSliderInt(0, 1, DRK_Mit_Oblation_Charges, Generics.HowManyChargesToKeepReady, itemWidth: little, sliderIncrement: SliderIncrements.Ones); - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 1, "Oblation Priority:"); break; case Preset.DRK_Mit_Reprisal: - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 2, "Reprisal Priority:"); @@ -379,33 +380,33 @@ internal static void Draw(Preset preset) case Preset.DRK_Mit_DarkMissionary: ImGui.Indent(); - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_Mit_DarkMissionary_PartyRequirement, "Require party", "Will not use Dark Missionary unless there are 2 or more party members.", outputValue: (int)PartyRequirement.Yes, itemWidth: medium); - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_Mit_DarkMissionary_PartyRequirement, "Use Always", "Will not require a party for Dark Missionary.", outputValue: (int)PartyRequirement.No, itemWidth: medium); ImGui.Unindent(); - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 3, "Dark Missionary Priority:"); break; case Preset.DRK_Mit_Rampart: - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 4, "Rampart Priority:"); break; case Preset.DRK_Mit_DarkMind: - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 5, "Dark Mind Priority:"); @@ -413,32 +414,32 @@ internal static void Draw(Preset preset) case Preset.DRK_Mit_ArmsLength: ImGui.Indent(); - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_Mit_ArmsLength_Boss, Generics.AllEnemies, "Will use Arm's Length regardless of the type of enemy.", outputValue: (int)BossAvoidance.Off, itemWidth: 125f); - UserConfig.DrawHorizontalRadioButton( + DrawHorizontalRadioButton( DRK_Mit_ArmsLength_Boss, "Avoid Bosses", "Will try not to use Arm's Length when in a boss fight.", outputValue: (int)BossAvoidance.On, itemWidth: 125f); ImGui.Unindent(); - UserConfig.DrawSliderInt(0, 5, DRK_Mit_ArmsLength_EnemyCount, + DrawSliderInt(0, 5, DRK_Mit_ArmsLength_EnemyCount, "How many enemies should be nearby? (0 = No Requirement)", itemWidth: little, sliderIncrement: SliderIncrements.Ones); - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 6, "Arm's Length Priority:"); break; case Preset.DRK_Mit_ShadowWall: - UserConfig.DrawSliderInt(1, 100, DRK_Mit_ShadowWall_Health, + DrawSliderInt(1, 100, DRK_Mit_ShadowWall_Health, Generics.StopFriendlyHpPercent100, itemWidth: medium, sliderIncrement: SliderIncrements.Ones); - UserConfig.DrawPriorityInput(DRK_Mit_Priorities, + DrawPriorityInput(DRK_Mit_Priorities, numberMitigationOptions, 7, "Shadow Wall / Vigil Priority:"); @@ -467,9 +468,18 @@ internal static void Draw(Preset preset) break; case Preset.DRK_Retarget_Oblation_DoubleProtection: - UserConfig.DrawSliderInt(0, 5, DRK_RetargetOblationDuration, + DrawSliderInt(0, 5, DRK_RetargetOblationDuration, "Time Remaining on Oblation to allow within\n(0 = Oblation must not be on the target)"); break; + + case Preset.DRK_Retarget_Unmend: + DrawAdditionalBoolChoice(DRK_Retarget_Unmend_FieldMO, + Generics.Mouseover, + FormatAndCache(Generics.MouseoverRetargetHostile, Unmend.ActionName())); + DrawAdditionalBoolChoice(DRK_Retarget_Unmend_NearestOOR, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, Unmend.ActionName())); + break; #endregion } @@ -986,6 +996,10 @@ public static readonly UserInt public static readonly UserInt DRK_RetargetOblationDuration = new("DRK_RetargetOblationDuration"); + + public static readonly UserBool + DRK_Retarget_Unmend_FieldMO = new("DRK_Retarget_Unmend_FieldMO"), + DRK_Retarget_Unmend_NearestOOR = new("DRK_Retarget_Unmend_NearestOOR"); #endregion diff --git a/WrathCombo/Combos/PvE/GNB/GNB.cs b/WrathCombo/Combos/PvE/GNB/GNB.cs index 2a38f9386d..b95c58ba1f 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB.cs @@ -706,6 +706,33 @@ protected override uint Invoke(uint actionID) } } #endregion + + #region Lightning Shot Retargeting + internal class GNB_RetargetLightningShot : CustomCombo + { + protected internal override Preset Preset => Preset.GNB_RetargetLightningShot; + + protected override uint Invoke(uint actionID) + { + if (actionID is not LightningShot) + return actionID; + + IGameObject? target = + //Mouseover Retarget + (GNB_RetargetLightningShot_FieldMO + ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(LightningShot.ActionRange()) + : null) ?? + + (GNB_RetargetLightningShot_NearestOOR + ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(LightningShot.ActionRange()) + : null); + + return target != null + ? actionID.Retarget(target) + : actionID; + } + } + #endregion #region Basic Combos internal class GNB_ST_BasicCombo : CustomCombo diff --git a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs index a141f6d461..d7c0887f42 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs @@ -60,7 +60,9 @@ public static UserFloat public static UserBool GNB_Mit_Advanced_Boss_Camouflage_Align = new("GNB_Mit_Advanced_Boss_Camouflage_Align", true), - GNB_Mit_Advanced_Boss_Nebula_First = new("GNB_Mit_Advanced_Boss_Nebula_First", true); + GNB_Mit_Advanced_Boss_Nebula_First = new("GNB_Mit_Advanced_Boss_Nebula_First", true), + GNB_RetargetLightningShot_FieldMO = new("GNB_RetargetLightningShot_FieldMO", true), + GNB_RetargetLightningShot_NearestOOR = new("GNB_RetargetLightningShot_NearestOOR", true); public static UserIntArray GNB_Mit_OneButton_Priorities = new("GNB_Mit_OneButton_Priorities"); @@ -384,6 +386,11 @@ internal static void Draw(Preset preset) DrawHorizontalRadioButton(GNB_FC_Continuation_Procs, "Only Fated Brand", $"Only uses {FatedBrand.ActionName()} regardless of other {Continuation.ActionName()} procs currently available", 1); break; + + case Preset.GNB_RetargetLightningShot: + DrawAdditionalBoolChoice(GNB_RetargetLightningShot_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, LightningShot.ActionName())); + DrawAdditionalBoolChoice(GNB_RetargetLightningShot_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, LightningShot.ActionName())); + break; #endregion } } diff --git a/WrathCombo/Combos/PvE/PLD/PLD.cs b/WrathCombo/Combos/PvE/PLD/PLD.cs index 64f726c184..1c3d7e1837 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD.cs @@ -262,11 +262,26 @@ protected override uint Invoke(uint actionID) { if (actionID is not ShieldLob) return actionID; + + IGameObject? target = + //Mouseover Retarget + (PLD_ShieldLob_Feature_FieldMO + ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(ShieldLob.ActionRange()) + : null) ?? - if (LevelChecked(HolySpirit) && GetResourceCost(HolySpirit) <= LocalPlayer.CurrentMp && (TimeMoving.Ticks == 0 || HasStatusEffect(Buffs.DivineMight))) - return HolySpirit; - - return actionID; + (PLD_ShieldLob_Feature_NearestOOR + ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(ShieldLob.ActionRange()) + : null); + + if (PLD_ShieldLob_Feature_HolySpirit && LevelChecked(HolySpirit) && GetResourceCost(HolySpirit) <= LocalPlayer.CurrentMp && + (TimeMoving.Ticks == 0 || HasStatusEffect(Buffs.DivineMight))) + return target != null + ? HolySpirit.Retarget(ShieldLob, target) + : HolySpirit; + + return target != null + ? actionID.Retarget(target) + : actionID; } } diff --git a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs index 5b372fb39a..861cf49342 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs @@ -213,6 +213,13 @@ internal static void Draw(Preset preset) #endregion #region Standalones + case Preset.PLD_ShieldLob_Feature: + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, ShieldLob.ActionName())); + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, ShieldLob.ActionName())); + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_HolySpirit, "Smart Holy Spirit", + "Replaces Shield Lob with Holy Spirit when available. Retargeting features will also apply to Holy Spirit" + + "\n Must be under the effect of Divine Might or not moving."); + break; case Preset.PLD_Requiescat_Options: DrawHorizontalRadioButton(PLD_Requiescat_SubOption, FormatAndCache(Generics.DontUse0, FightOrFlight.ActionName()), "", 0); @@ -368,19 +375,23 @@ public static UserFloat PLD_AoE_InterveneTimeStill = new("PLD_AoE_InterveneTimeStill", 2.5f); public static UserBool - PLD_ST_AdvancedMode_CircleOfScorn_ManualPooling = new ("PLD_ST_AdvancedMode_CircleOfScorn_ManualPooling"), - PLD_ST_AdvancedMode_SpiritsWithin_ManualPooling = new ("PLD_ST_AdvancedMode_SpiritsWithin_ManualPooling"), - PLD_ST_AdvancedMode_Intervene_ManualPooling = new ("PLD_ST_AdvancedMode_Intervene_ManualPooling"), - PLD_AoE_AdvancedMode_CircleOfScorn_ManualPooling = new ("PLD_AoE_AdvancedMode_CircleOfScorn_ManualPooling"), - PLD_AoE_AdvancedMode_SpiritsWithin_ManualPooling = new ("PLD_AoE_AdvancedMode_SpiritsWithin_ManualPooling"), - PLD_AoE_AdvancedMode_Intervene_ManualPooling = new ("PLD_AoE_AdvancedMode_Intervene_ManualPooling"), + PLD_ST_AdvancedMode_CircleOfScorn_ManualPooling = new("PLD_ST_AdvancedMode_CircleOfScorn_ManualPooling"), + PLD_ST_AdvancedMode_SpiritsWithin_ManualPooling = new("PLD_ST_AdvancedMode_SpiritsWithin_ManualPooling"), + PLD_ST_AdvancedMode_Intervene_ManualPooling = new("PLD_ST_AdvancedMode_Intervene_ManualPooling"), + PLD_AoE_AdvancedMode_CircleOfScorn_ManualPooling = new("PLD_AoE_AdvancedMode_CircleOfScorn_ManualPooling"), + PLD_AoE_AdvancedMode_SpiritsWithin_ManualPooling = new("PLD_AoE_AdvancedMode_SpiritsWithin_ManualPooling"), + PLD_AoE_AdvancedMode_Intervene_ManualPooling = new("PLD_AoE_AdvancedMode_Intervene_ManualPooling"), PLD_RetargetStunLockout = new("PLD_RetargetStunLockout"), PLD_Mitigation_Boss_Bulwark_Align = new("PLD_Mitigation_Boss_Bulwark_Align"), PLD_Mitigation_Boss_Sentinel_First = new("PLD_Mitigation_Boss_Sentinel_First"), PLD_HolySpirit_Standalone = new("PLD_HolySpirit_Standalone"), PLD_HolyCircle_Standalone = new("PLD_HolyCircle_Standalone"), PLD_SpiritsWithin_SubOption = new("PLD_SpiritsWithin_SubOption"), - PLD_Requiescat_SubOption_GoringBlade = new("PLD_Requiescat_SubOption_GoringBlade"); + PLD_Requiescat_SubOption_GoringBlade = new("PLD_Requiescat_SubOption_GoringBlade"), + PLD_ShieldLob_Feature_FieldMO = new("PLD_ShieldLob_Feature_FieldMO"), + PLD_ShieldLob_Feature_NearestOOR = new("PLD_ShieldLob_Feature_NearestOOR"), + PLD_ShieldLob_Feature_HolySpirit = new("PLD_ShieldLob_Feature_HolySpirit"); + public static UserIntArray PLD_Mit_Priorities = new("PLD_Mit_Priorities"); diff --git a/WrathCombo/Combos/PvE/WAR/WAR.cs b/WrathCombo/Combos/PvE/WAR/WAR.cs index 19162fd215..eb5b0c016e 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR.cs @@ -1,5 +1,6 @@ using Dalamud.Game.ClientState.Objects.Types; using System; +using ECommons; using WrathCombo.Core; using WrathCombo.CustomComboNS; using WrathCombo.Data; @@ -405,6 +406,33 @@ internal class WAR_RetargetHolmgang : CustomCombo protected override uint Invoke(uint actionID) => actionID != Holmgang ? actionID : actionID.Retarget(SimpleTarget.Self); } #endregion + + #region Tomahawk Retargeting + internal class WAR_RetargetTomahawk : CustomCombo + { + protected internal override Preset Preset => Preset.WAR_RetargetTomahawk; + + protected override uint Invoke(uint actionID) + { + if (actionID is not Tomahawk) + return actionID; + + IGameObject? target = + //Mouseover Retarget + (WAR_RetargetTomahawk_FieldMO + ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Tomahawk.ActionRange()) + : null) ?? + + (WAR_RetargetTomahawk_NearestOOR + ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(Tomahawk.ActionRange()) + : null); + + return target != null + ? actionID.Retarget(target) + : actionID; + } + } + #endregion #region Basic Combos internal class WAR_ST_StormsPathCombo : CustomCombo diff --git a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs index 7b553162d5..02c5ea04a5 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs @@ -428,7 +428,11 @@ internal static void Draw(Preset preset) case Preset.WAR_ArmsLengthLockout: DrawSliderInt(0, 5, WAR_ArmsLengthLockout_Time, "Time (In Seconds) remaining on Inner Strength to Lock out Arm's Length until."); break; - + + case Preset.WAR_RetargetTomahawk: + DrawAdditionalBoolChoice(WAR_RetargetTomahawk_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, Tomahawk.ActionName())); + DrawAdditionalBoolChoice(WAR_RetargetTomahawk_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, Tomahawk.ActionName())); + break; #endregion } } @@ -528,7 +532,10 @@ public static UserBool WAR_AoE_Decimate_Pooling = new("WAR_AoE_Decimate_Pooling"), WAR_AoE_Decimate_Pooling_BossOnly = new("WAR_AoE_Decimate_Pooling_BossOnly"), WAR_AoE_Decimate_Smart = new("WAR_AoE_Decimate_Smart"), - WAR_AoE_Onslaught_ManualPooling = new("WAR_AoE_Onslaught_ManualPooling"); + WAR_AoE_Onslaught_ManualPooling = new("WAR_AoE_Onslaught_ManualPooling"), + + WAR_RetargetTomahawk_FieldMO = new("WAR_RetargetTomahawk_FieldMO"), + WAR_RetargetTomahawk_NearestOOR = new("WAR_RetargetTomahawk_NearestOOR"); public static UserIntArray WAR_Mit_Priorities = new("WAR_Mit_Priorities"); diff --git a/WrathCombo/CustomCombo/SimpleTarget.cs b/WrathCombo/CustomCombo/SimpleTarget.cs index 0199b33df7..f42fde9b7f 100644 --- a/WrathCombo/CustomCombo/SimpleTarget.cs +++ b/WrathCombo/CustomCombo/SimpleTarget.cs @@ -347,6 +347,13 @@ public static IGameObject? UIMouseOverTarget .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsInCombat() && x.IsNotInvincible()) .OrderBy(x => GetTargetDistance(x)) .FirstOrDefault(); + + public static IGameObject? NearstEnemyOver5YalmsAway => + Svc.Objects + .OfType() + .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsNotInvincible() && x.IsAtLeastFiveYalmsAway()) + .OrderBy(x => GetTargetDistance(x)) + .FirstOrDefault(); public static IGameObject? NearestEnemyToTarget (IGameObject? target, float maximumRangeFromPlayer = 35f) => diff --git a/WrathCombo/Extensions/GameObjectExtensions.cs b/WrathCombo/Extensions/GameObjectExtensions.cs index 7466d55b43..eb1d4faab3 100644 --- a/WrathCombo/Extensions/GameObjectExtensions.cs +++ b/WrathCombo/Extensions/GameObjectExtensions.cs @@ -266,6 +266,13 @@ public bool IsNotThePlayer() => /// public bool IsWithinRange(float range = 25) => obj != null && IsInRange(obj, range); + + /// + /// Can be chained onto a to make it a quick + /// boolean check for if the target is within range. + /// + public bool IsAtLeastFiveYalmsAway(float range = 5) => + obj != null && !IsInRange(obj, range); /// /// Can be chained onto a to make it a quick diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs index 8909659e44..7e11cb45ad 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs @@ -202,18 +202,16 @@ internal static string Align0With1 { return ResourceManager.GetString("Align0With1", resourceCulture); } } - + /// /// Looks up a localized string similar to Keep {0} aligned with manual use of {1}.. /// - internal static string Align0WithManual1 - { - get - { + internal static string Align0WithManual1 { + get { return ResourceManager.GetString("Align0WithManual1", resourceCulture); } } - + /// /// Looks up a localized string similar to All Content. /// @@ -742,6 +740,24 @@ internal static string MinimumNumberOfEnemies { } } + /// + /// Looks up a localized string similar to Mouseover. + /// + internal static string Mouseover { + get { + return ResourceManager.GetString("Mouseover", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will retarget {0} at your mouseover target (if Hostile).. + /// + internal static string MouseoverRetargetHostile { + get { + return ResourceManager.GetString("MouseoverRetargetHostile", resourceCulture); + } + } + /// /// Looks up a localized string similar to Movement Option. /// @@ -769,6 +785,24 @@ internal static string MPLessOrEqual { } } + /// + /// Looks up a localized string similar to Nearest Out of Range. + /// + internal static string NearestOOR { + get { + return ResourceManager.GetString("NearestOOR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will {0} at the nearest hostile outside of 5 Yalms.. + /// + internal static string NearestOORRetarget { + get { + return ResourceManager.GetString("NearestOORRetarget", resourceCulture); + } + } + /// /// Looks up a localized string similar to No Movement. /// diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx index 11dce1d8ca..c5545ed57e 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx @@ -345,6 +345,12 @@ Set to Zero to disable this check. Minimum Number of enemies in range to use. + + Mouseover + + + Will retarget {0} at your mouseover target (if Hostile). + Movement Option @@ -357,6 +363,12 @@ Set to Zero to disable this check. No Movement + + Nearest Out of Range + + + Will {0} at the nearest hostile outside of 5 Yalms. + Non-boss Encounters Only diff --git a/WrathCombo/Resources/Localization/Presets/CustomComboPresets.Designer.cs b/WrathCombo/Resources/Localization/Presets/CustomComboPresets.Designer.cs index d5d7aecc15..fca8e90dcd 100644 --- a/WrathCombo/Resources/Localization/Presets/CustomComboPresets.Designer.cs +++ b/WrathCombo/Resources/Localization/Presets/CustomComboPresets.Designer.cs @@ -9074,6 +9074,24 @@ internal static string DRK_Retarget_TBN_TT_Name { } } + /// + /// Looks up a localized string similar to Will retarget Unmend according to below settings.. + /// + internal static string DRK_Retarget_Unmend_Desc { + get { + return ResourceManager.GetString("DRK_Retarget_Unmend_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retarget Unmend Option. + /// + internal static string DRK_Retarget_Unmend_Name { + get { + return ResourceManager.GetString("DRK_Retarget_Unmend_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Will retarget Shadowstride to your field or UI mouseover target (If Hostile) or the nearest hostile target to your mouseover target (If friendly).. /// @@ -11370,6 +11388,24 @@ internal static string GNB_NM_Zone_Name { } } + /// + /// Looks up a localized string similar to Will retarget Lighting Shot according to below settings.. + /// + internal static string GNB_RetargetLightningShot_Desc { + get { + return ResourceManager.GetString("GNB_RetargetLightningShot_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retarget Lightning Shot Option. + /// + internal static string GNB_RetargetLightningShot_Name { + get { + return ResourceManager.GetString("GNB_RetargetLightningShot_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Retargets Trajectory to your Field or UI Mouseover target (if Hostile) or the nearest hostile target to your Mouseover target (if Friendly).. /// @@ -11914,7 +11950,7 @@ internal static string MCH_AoE_Adv_Hypercharge_Name { return ResourceManager.GetString("MCH_AoE_Adv_Hypercharge_Name", resourceCulture); } } - + /// /// Looks up a localized string similar to s, wait to Hypercharge until Tool cooldowns are at least this value. /// @@ -11923,7 +11959,7 @@ internal static string MCH_AoE_Adv_HyperchargeToolHold { return ResourceManager.GetString("MCH_AoE_Adv_HyperchargeToolHold", resourceCulture); } } - + /// /// Looks up a localized string similar to Uses Head Graze to interrupt during the rotation, where applicable.. /// @@ -19054,8 +19090,7 @@ internal static string PLD_RetargetShieldBash_Name { } /// - /// Looks up a localized string similar to Replaces Shield Lob with Holy Spirit when available. - ///- Must be under the effect of Divine Might or not moving.. + /// Looks up a localized string similar to Replacement and Retargeting Features for Shield Lob . /// internal static string PLD_ShieldLob_Feature_Desc { get { @@ -19064,7 +19099,7 @@ internal static string PLD_ShieldLob_Feature_Desc { } /// - /// Looks up a localized string similar to Shield Lob / Holy Spirit Feature. + /// Looks up a localized string similar to Shield Lob/Holy Spirit Retarget Feature. /// internal static string PLD_ShieldLob_Feature_Name { get { @@ -21702,6 +21737,61 @@ internal static string RPR_ArcaneCirclePlentifulHarvest_Name { } } + /// + /// Looks up a localized string similar to Adds (Executioner's) Gibbet and Gallows on Blood Stalk. + ///Adds (Executioner's) Guillotine on Grim Swathe.. + /// + internal static string RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Desc { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Gibbet and Gallows/Guillotine on Blood Stalk/Grim Swathe Feature. + /// + internal static string RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Name { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adds Gibbet/Gallows and Enshroud combo on Blood Stalk and Grim Swathe without replacing them with Gluttony. Conflicts with Gluttony on Blood Stalk/Grim Swathe.. + /// + internal static string RPR_BloodStalkEnshroudCombo_Desc { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adds Enshroud combo (Void/Cross Reaping, Communio, Lemure's Slice, Sacrificium and Perfectio) on Blood Stalk and Grim Swathe.. + /// + internal static string RPR_BloodStalkEnshroudCombo_Enshroud_Desc { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Enshroud_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enshroud Combo Option. + /// + internal static string RPR_BloodStalkEnshroudCombo_Enshroud_Name { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Enshroud_Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blood Stalk/Grim Swathe Combos (No Gluttony). + /// + internal static string RPR_BloodStalkEnshroudCombo_Name { + get { + return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Adds Communio to Gibbet/Gallows and Guillotine.. /// @@ -21847,61 +21937,6 @@ internal static string RPR_GluttonyBloodSwathe_Sacrificium_Name { } } - /// - /// Looks up a localized string similar to Blood Stalk/Grim Swathe Combos (No Gluttony). - /// - internal static string RPR_BloodStalkEnshroudCombo_Name { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Name", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adds Gibbet/Gallows and Enshroud combo on Blood Stalk and Grim Swathe without replacing them with Gluttony. Conflicts with Gluttony on Blood Stalk/Grim Swathe.. - /// - internal static string RPR_BloodStalkEnshroudCombo_Desc { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Desc", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Gibbet and Gallows/Guillotine on Blood Stalk/Grim Swathe Feature. - /// - internal static string RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Name { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Name", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adds (Executioner's) Gibbet and Gallows on Blood Stalk. - ///Adds (Executioner's) Guillotine on Grim Swathe.. - /// - internal static string RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Desc { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_BloodSwatheCombo_Desc", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Enshroud Combo Option. - /// - internal static string RPR_BloodStalkEnshroudCombo_Enshroud_Name { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Enshroud_Name", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adds Enshroud combo (Void/Cross Reaping, Communio, Lemure's Slice, Sacrificium and Perfectio) on Blood Stalk and Grim Swathe.. - /// - internal static string RPR_BloodStalkEnshroudCombo_Enshroud_Desc { - get { - return ResourceManager.GetString("RPR_BloodStalkEnshroudCombo_Enshroud_Desc", resourceCulture); - } - } - /// /// Looks up a localized string similar to Adds Lemure's Slice to Gibbet/Gallows and Lemure's Scythe to Guillotine.. /// @@ -31230,6 +31265,24 @@ internal static string WAR_RetargetOnslaught_Name { } } + /// + /// Looks up a localized string similar to Will retarget Tomahawk to according to below settings.. + /// + internal static string WAR_RetargetTomahawk_Desc { + get { + return ResourceManager.GetString("WAR_RetargetTomahawk_Desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retarget Tomahawk Option. + /// + internal static string WAR_RetargetTomahawk_Name { + get { + return ResourceManager.GetString("WAR_RetargetTomahawk_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Replaces Heavy Swing with a full one-button single target rotation. ///These features are ideal if you want to customize the rotation.. diff --git a/WrathCombo/Resources/Localization/Presets/CustomComboPresets.resx b/WrathCombo/Resources/Localization/Presets/CustomComboPresets.resx index 52155bca5a..49f627fe53 100644 --- a/WrathCombo/Resources/Localization/Presets/CustomComboPresets.resx +++ b/WrathCombo/Resources/Localization/Presets/CustomComboPresets.resx @@ -3258,6 +3258,12 @@ NOTE: Will not use unless there is a target within range to prevent waste. Include Target's Target + + Will retarget Unmend according to below settings. + + + Retarget Unmend Option + Replaces Hard Slash with a full one-button single target rotation. These features are ideal if you want to customize the rotation. @@ -4030,6 +4036,12 @@ This feature is ideal for any fresh newcomers to the job. Zone Option + + Will retarget Lighting Shot according to below settings. + + + Retarget Lightning Shot Option + Retargets Trajectory to your Field or UI Mouseover target (if Hostile) or the nearest hostile target to your Mouseover target (if Friendly). @@ -6656,11 +6668,10 @@ NOTE: Will not use unless there is a target within range to prevent wasteRetarget Shield Bash - Replaces Shield Lob with Holy Spirit when available. -- Must be under the effect of Divine Might or not moving. + Replacement and Retargeting Features for Shield Lob - Shield Lob / Holy Spirit Feature + Shield Lob/Holy Spirit Retarget Feature Replaces Spirits Within with Circle of Scorn when available. @@ -10810,6 +10821,12 @@ NOTE: even if disabled, will still try to use Thrill Of Battle as the lowest pri Mouseover Onslaught Option + + Will retarget Tomahawk to according to below settings. + + + Retarget Tomahawk Option + Replaces Heavy Swing with a full one-button single target rotation. These features are ideal if you want to customize the rotation. From 14f996ca738c7e7733cc3599ed832c7a1074178b Mon Sep 17 00:00:00 2001 From: edewen Date: Mon, 29 Jun 2026 08:59:38 -0400 Subject: [PATCH 2/4] Update GameObjectExtensions.cs --- WrathCombo/Extensions/GameObjectExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WrathCombo/Extensions/GameObjectExtensions.cs b/WrathCombo/Extensions/GameObjectExtensions.cs index eb1d4faab3..722021011a 100644 --- a/WrathCombo/Extensions/GameObjectExtensions.cs +++ b/WrathCombo/Extensions/GameObjectExtensions.cs @@ -269,7 +269,7 @@ public bool IsWithinRange(float range = 25) => /// /// Can be chained onto a to make it a quick - /// boolean check for if the target is within range. + /// boolean check for if the target is outside of range. /// public bool IsAtLeastFiveYalmsAway(float range = 5) => obj != null && !IsInRange(obj, range); From 14bca8d96d04b0d21dc8af52db4ab774d1e1249f Mon Sep 17 00:00:00 2001 From: edewen Date: Mon, 29 Jun 2026 15:56:33 -0400 Subject: [PATCH 3/4] More options --- WrathCombo/Combos/PvE/DRK/DRK.cs | 12 ++++- WrathCombo/Combos/PvE/DRK/DRK_Config.cs | 32 +++++++++--- WrathCombo/Combos/PvE/GNB/GNB.cs | 14 ++++-- WrathCombo/Combos/PvE/GNB/GNB_Config.cs | 26 +++++++++- WrathCombo/Combos/PvE/PLD/PLD.cs | 12 ++++- WrathCombo/Combos/PvE/PLD/PLD_Config.cs | 32 ++++++++++-- WrathCombo/Combos/PvE/WAR/WAR.cs | 15 ++++-- WrathCombo/Combos/PvE/WAR/WAR_Config.cs | 30 ++++++++++-- WrathCombo/Core/ActionRetargeting.cs | 3 +- WrathCombo/CustomCombo/SimpleTarget.cs | 25 +++++++++- .../JobConfigs/Generics.Designer.cs | 49 ++++++++++++++++++- .../Localization/JobConfigs/Generics.resx | 19 ++++++- 12 files changed, 236 insertions(+), 33 deletions(-) diff --git a/WrathCombo/Combos/PvE/DRK/DRK.cs b/WrathCombo/Combos/PvE/DRK/DRK.cs index b068dab2c9..7dee4cd7e4 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK.cs @@ -464,9 +464,17 @@ protected override uint Invoke(uint actionID) (DRK_Retarget_Unmend_FieldMO ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Unmend.ActionRange()) : null) ?? + + (DRK_Retarget_Unmend_SmartTargeting == 1 + ? DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Unmend.ActionRange()) + : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(Unmend.ActionRange()) + : null) ?? - (DRK_Retarget_Unmend_NearestOOR - ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(Unmend.ActionRange()) + (DRK_Retarget_Unmend_SmartTargeting == 2 + ? DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Unmend.ActionRange()) + : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(Unmend.ActionRange()) : null); return target != null diff --git a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs index d6425c3e0e..2fd8900fa2 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs @@ -1,5 +1,6 @@ #region +using System.Numerics; using Dalamud.Interface.Colors; using ECommons.ImGuiMethods; using WrathCombo.CustomComboNS.Functions; @@ -473,12 +474,28 @@ internal static void Draw(Preset preset) break; case Preset.DRK_Retarget_Unmend: - DrawAdditionalBoolChoice(DRK_Retarget_Unmend_FieldMO, - Generics.Mouseover, - FormatAndCache(Generics.MouseoverRetargetHostile, Unmend.ActionName())); - DrawAdditionalBoolChoice(DRK_Retarget_Unmend_NearestOOR, + DrawAdditionalBoolChoice(DRK_Retarget_Unmend_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, Unmend.ActionName())); + + ImGui.Indent(12f.Scale()); + ImGui.NewLine(); + DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, + Generics.OffRangeBasedTargeting, "", 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, Unmend.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, Generics.NearestOOR, - FormatAndCache(Generics.NearestOORRetarget, Unmend.ActionName())); + FormatAndCache(Generics.NearestOORRetarget, Unmend.ActionName()), 2, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + if (DRK_Retarget_Unmend_SmartTargeting > 0) + { + DrawAdditionalBoolChoice(DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + } + ImGui.Unindent(); + break; break; #endregion @@ -995,11 +1012,12 @@ public static readonly UserInt #region Standalones public static readonly UserInt - DRK_RetargetOblationDuration = new("DRK_RetargetOblationDuration"); + DRK_RetargetOblationDuration = new("DRK_RetargetOblationDuration"), + DRK_Retarget_Unmend_SmartTargeting = new("DRK_Retarget_Unmend_SmartTargeting"); public static readonly UserBool DRK_Retarget_Unmend_FieldMO = new("DRK_Retarget_Unmend_FieldMO"), - DRK_Retarget_Unmend_NearestOOR = new("DRK_Retarget_Unmend_NearestOOR"); + DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer = new("DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer"); #endregion diff --git a/WrathCombo/Combos/PvE/GNB/GNB.cs b/WrathCombo/Combos/PvE/GNB/GNB.cs index b95c58ba1f..3ec132cecd 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB.cs @@ -716,15 +716,23 @@ protected override uint Invoke(uint actionID) { if (actionID is not LightningShot) return actionID; - + IGameObject? target = //Mouseover Retarget (GNB_RetargetLightningShot_FieldMO ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(LightningShot.ActionRange()) : null) ?? + + (GNB_RetargetLightningShot_SmartTargeting == 1 + ? GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(LightningShot.ActionRange()) + : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(LightningShot.ActionRange()) + : null) ?? - (GNB_RetargetLightningShot_NearestOOR - ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(LightningShot.ActionRange()) + (GNB_RetargetLightningShot_SmartTargeting == 2 + ? GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(LightningShot.ActionRange()) + : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(LightningShot.ActionRange()) : null); return target != null diff --git a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs index d7c0887f42..264baa71d2 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs @@ -1,4 +1,6 @@ +using System.Numerics; using Dalamud.Interface.Colors; +using ECommons.ImGuiMethods; using WrathCombo.CustomComboNS.Functions; using WrathCombo.Data; using WrathCombo.Extensions; @@ -46,6 +48,7 @@ public static UserInt GNB_GF_Overcap_Choice = new("GNB_GF_Overcap_Choice"), GNB_GF_BurstStrike_Setup = new("GNB_GF_BurstStrike_Setup"), GNB_ST_Balance_Content = new("GNB_ST_Balance_Content", 1), + GNB_RetargetLightningShot_SmartTargeting = new("GNB_RetargetLightningShot_SmartTargeting"), GNB_Mit_OneButton_Superbolide_Health = new("GNB_Mit_OneButton_Superbolide_Health", 30), GNB_Mit_OneButton_Corundum_Health = new("GNB_Mit_OneButton_Corundum_Health", 60), GNB_Mit_OneButton_Aurora_Charges = new("GNB_Mit_OneButton_Aurora_Charges"), @@ -62,7 +65,7 @@ public static UserBool GNB_Mit_Advanced_Boss_Camouflage_Align = new("GNB_Mit_Advanced_Boss_Camouflage_Align", true), GNB_Mit_Advanced_Boss_Nebula_First = new("GNB_Mit_Advanced_Boss_Nebula_First", true), GNB_RetargetLightningShot_FieldMO = new("GNB_RetargetLightningShot_FieldMO", true), - GNB_RetargetLightningShot_NearestOOR = new("GNB_RetargetLightningShot_NearestOOR", true); + GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer = new("GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer", true); public static UserIntArray GNB_Mit_OneButton_Priorities = new("GNB_Mit_OneButton_Priorities"); @@ -389,7 +392,26 @@ internal static void Draw(Preset preset) case Preset.GNB_RetargetLightningShot: DrawAdditionalBoolChoice(GNB_RetargetLightningShot_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, LightningShot.ActionName())); - DrawAdditionalBoolChoice(GNB_RetargetLightningShot_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, LightningShot.ActionName())); + + ImGui.Indent(12f.Scale()); + ImGui.NewLine(); + DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, + Generics.OffRangeBasedTargeting, "", 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, LightningShot.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, LightningShot.ActionName()), 2, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + if (GNB_RetargetLightningShot_SmartTargeting > 0) + { + DrawAdditionalBoolChoice(GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + } + ImGui.Unindent(); break; #endregion } diff --git a/WrathCombo/Combos/PvE/PLD/PLD.cs b/WrathCombo/Combos/PvE/PLD/PLD.cs index 1c3d7e1837..bb267a8228 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD.cs @@ -268,9 +268,17 @@ protected override uint Invoke(uint actionID) (PLD_ShieldLob_Feature_FieldMO ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(ShieldLob.ActionRange()) : null) ?? + + (PLD_ShieldLob_Feature_SmartTargeting == 1 + ? PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(ShieldLob.ActionRange()) + : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(ShieldLob.ActionRange()) + : null) ?? - (PLD_ShieldLob_Feature_NearestOOR - ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(ShieldLob.ActionRange()) + (PLD_ShieldLob_Feature_SmartTargeting == 2 + ? PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(ShieldLob.ActionRange()) + : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(ShieldLob.ActionRange()) : null); if (PLD_ShieldLob_Feature_HolySpirit && LevelChecked(HolySpirit) && GetResourceCost(HolySpirit) <= LocalPlayer.CurrentMp && diff --git a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs index 861cf49342..689547a40a 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs @@ -1,3 +1,4 @@ +using System.Numerics; using Dalamud.Interface.Colors; using ECommons.ImGuiMethods; using FFXIVClientStructs.FFXIV.Client.System.Input.SoftKeyboards; @@ -214,11 +215,31 @@ internal static void Draw(Preset preset) #region Standalones case Preset.PLD_ShieldLob_Feature: - DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, ShieldLob.ActionName())); - DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, ShieldLob.ActionName())); DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_HolySpirit, "Smart Holy Spirit", - "Replaces Shield Lob with Holy Spirit when available. Retargeting features will also apply to Holy Spirit" + - "\n Must be under the effect of Divine Might or not moving."); + "Replaces Shield Lob with Holy Spirit when available. " + + "\nMust be under the effect of Divine Might or not moving." + + "\nRetargeting features will also apply to Holy Spirit."); + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, ShieldLob.ActionName())); + + ImGui.Indent(12f.Scale()); + ImGui.NewLine(); + DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, + Generics.OffRangeBasedTargeting, "", 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, ShieldLob.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, ShieldLob.ActionName()), 2, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + if (PLD_ShieldLob_Feature_SmartTargeting > 0) + { + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + } + ImGui.Unindent(); break; case Preset.PLD_Requiescat_Options: @@ -360,6 +381,7 @@ public static UserInt PLD_RetargetClemency_Health = new("PLD_RetargetClemency_Health", 30), PLD_RetargetShieldBash_Strength = new("PLD_RetargetShieldBash_Strength", 3), PLD_RetargetCover_Health = new("PLD_RetargetCover_Health", 30), + PLD_ShieldLob_Feature_SmartTargeting = new("PLD_ShieldLob_Feature_SmartTargeting"), //One-Button Mitigation PLD_Mit_HallowedGround_Max_Health = new("PLD_Mit_HallowedGround_Max_Health", 20), @@ -389,7 +411,7 @@ public static UserBool PLD_SpiritsWithin_SubOption = new("PLD_SpiritsWithin_SubOption"), PLD_Requiescat_SubOption_GoringBlade = new("PLD_Requiescat_SubOption_GoringBlade"), PLD_ShieldLob_Feature_FieldMO = new("PLD_ShieldLob_Feature_FieldMO"), - PLD_ShieldLob_Feature_NearestOOR = new("PLD_ShieldLob_Feature_NearestOOR"), + PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer = new("PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer"), PLD_ShieldLob_Feature_HolySpirit = new("PLD_ShieldLob_Feature_HolySpirit"); diff --git a/WrathCombo/Combos/PvE/WAR/WAR.cs b/WrathCombo/Combos/PvE/WAR/WAR.cs index eb5b0c016e..f59871e00c 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR.cs @@ -416,16 +416,25 @@ protected override uint Invoke(uint actionID) { if (actionID is not Tomahawk) return actionID; - + IGameObject? target = //Mouseover Retarget (WAR_RetargetTomahawk_FieldMO ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Tomahawk.ActionRange()) : null) ?? + + (WAR_RetargetTomahawk_SmartTargeting == 1 + ? WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Tomahawk.ActionRange()) + : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(Tomahawk.ActionRange()) + : null) ?? - (WAR_RetargetTomahawk_NearestOOR - ? SimpleTarget.NearstEnemyOver5YalmsAway .IfWithinRange(Tomahawk.ActionRange()) + (WAR_RetargetTomahawk_SmartTargeting == 2 + ? WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer + ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Tomahawk.ActionRange()) + : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(Tomahawk.ActionRange()) : null); + return target != null ? actionID.Retarget(target) diff --git a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs index 02c5ea04a5..69d58b84a4 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs @@ -1,4 +1,6 @@ +using System.Numerics; using Dalamud.Interface.Colors; +using Dalamud.Interface.Style; using ECommons.ImGuiMethods; using WrathCombo.CustomComboNS.Functions; using WrathCombo.Data; @@ -428,10 +430,29 @@ internal static void Draw(Preset preset) case Preset.WAR_ArmsLengthLockout: DrawSliderInt(0, 5, WAR_ArmsLengthLockout_Time, "Time (In Seconds) remaining on Inner Strength to Lock out Arm's Length until."); break; - + case Preset.WAR_RetargetTomahawk: DrawAdditionalBoolChoice(WAR_RetargetTomahawk_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, Tomahawk.ActionName())); - DrawAdditionalBoolChoice(WAR_RetargetTomahawk_NearestOOR, Generics.NearestOOR, FormatAndCache(Generics.NearestOORRetarget, Tomahawk.ActionName())); + + ImGui.Indent(12f.Scale()); + ImGui.NewLine(); + DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, + Generics.OffRangeBasedTargeting, "", 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, Tomahawk.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, Tomahawk.ActionName()), 2, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + if (WAR_RetargetTomahawk_SmartTargeting > 0) + { + DrawAdditionalBoolChoice(WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + } + ImGui.Unindent(); break; #endregion } @@ -491,6 +512,7 @@ public static UserInt WAR_FC_PrimalRend_Movement = new("WAR_FC_PrimalRend_Movement"), WAR_FC_PrimalRend_EarlyLate = new("WAR_FC_PrimalRend_EarlyLate"), WAR_ArmsLengthLockout_Time = new("WAR_ArmsLengthLockout_Time", 3), + WAR_RetargetTomahawk_SmartTargeting = new("WAR_RetargetTomahawk_SmartTargeting"), //One Button Mitigation WAR_Mit_Holmgang_Health = new("WAR_Mit_Holmgang_Health", 20), @@ -535,7 +557,9 @@ public static UserBool WAR_AoE_Onslaught_ManualPooling = new("WAR_AoE_Onslaught_ManualPooling"), WAR_RetargetTomahawk_FieldMO = new("WAR_RetargetTomahawk_FieldMO"), - WAR_RetargetTomahawk_NearestOOR = new("WAR_RetargetTomahawk_NearestOOR"); + WAR_RetargetTomahawk_FurthestOOR = new("WAR_RetargetTomahawk_FurthestOOR"), + WAR_RetargetTomahawk_NearestOOR = new("WAR_RetargetTomahawk_NearestOOR"), + WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer = new("WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer"); public static UserIntArray WAR_Mit_Priorities = new("WAR_Mit_Priorities"); diff --git a/WrathCombo/Core/ActionRetargeting.cs b/WrathCombo/Core/ActionRetargeting.cs index 1332be0271..0760280bb0 100644 --- a/WrathCombo/Core/ActionRetargeting.cs +++ b/WrathCombo/Core/ActionRetargeting.cs @@ -401,7 +401,8 @@ internal void ClearCachedRetargets() private void ClearCachedRetargetsOnConfigChange (object? _, Configuration.ConfigChangeEventArgs args) { - if (args.Type == Configuration.ConfigChangeType.Preset) + if (args.Type is (Configuration.ConfigChangeType.Preset or + Configuration.ConfigChangeType.UserData)) // todo: restrict this to only clear the retargets associated // with the preset, once Retargeting is based on Presets. ClearCachedRetargets(); diff --git a/WrathCombo/CustomCombo/SimpleTarget.cs b/WrathCombo/CustomCombo/SimpleTarget.cs index f42fde9b7f..5ca90ed3ac 100644 --- a/WrathCombo/CustomCombo/SimpleTarget.cs +++ b/WrathCombo/CustomCombo/SimpleTarget.cs @@ -348,12 +348,35 @@ public static IGameObject? UIMouseOverTarget .OrderBy(x => GetTargetDistance(x)) .FirstOrDefault(); - public static IGameObject? NearstEnemyOver5YalmsAway => + public static IGameObject? NearestEnemyOver5YalmsAway => Svc.Objects .OfType() .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsNotInvincible() && x.IsAtLeastFiveYalmsAway()) .OrderBy(x => GetTargetDistance(x)) .FirstOrDefault(); + + public static IGameObject? NearestEnemyOver5YalmsAwayNotTargetingPlayer => + Svc.Objects + .OfType() + .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsNotInvincible() && x.IsAtLeastFiveYalmsAway() && + x.TargetObjectId != LocalPlayer?.GameObjectId) + .OrderBy(x => GetTargetDistance(x)) + .FirstOrDefault(); + + public static IGameObject? FurthestEnemyOver5YalmsAway => + Svc.Objects + .OfType() + .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsNotInvincible() && x.IsAtLeastFiveYalmsAway()) + .OrderByDescending(x => GetTargetDistance(x)) + .FirstOrDefault(); + + public static IGameObject? FurthestEnemyOver5YalmsAwayNotTargetingPlayer => + Svc.Objects + .OfType() + .Where(x => x.IsHostile() && x.IsTargetable && x.IsWithinRange() && x.IsNotInvincible() && x.IsAtLeastFiveYalmsAway() && + x.TargetObjectId != LocalPlayer?.GameObjectId) + .OrderByDescending(x => GetTargetDistance(x)) + .FirstOrDefault(); public static IGameObject? NearestEnemyToTarget (IGameObject? target, float maximumRangeFromPlayer = 35f) => diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs index 7e11cb45ad..06068f9931 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs @@ -496,6 +496,24 @@ internal static string FocusTarget { } } + /// + /// Looks up a localized string similar to Furthest outside of 5y. + /// + internal static string FurthestOOR { + get { + return ResourceManager.GetString("FurthestOOR", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will {0} at the furthest hostile outside of 5 Yalms.. + /// + internal static string FurthestOORRetarget { + get { + return ResourceManager.GetString("FurthestOORRetarget", resourceCulture); + } + } + /// /// Looks up a localized string similar to Use {0} in Opener. /// @@ -750,7 +768,7 @@ internal static string Mouseover { } /// - /// Looks up a localized string similar to Will retarget {0} at your mouseover target (if Hostile).. + /// Looks up a localized string similar to Will retarget {0} at your mouseover target (if Hostile). Highest Priority.. /// internal static string MouseoverRetargetHostile { get { @@ -786,7 +804,7 @@ internal static string MPLessOrEqual { } /// - /// Looks up a localized string similar to Nearest Out of Range. + /// Looks up a localized string similar to Nearest outside of 5y. /// internal static string NearestOOR { get { @@ -875,6 +893,15 @@ internal static string NotInBossEncounters { } } + /// + /// Looks up a localized string similar to Range Based Targeting Off. + /// + internal static string OffRangeBasedTargeting { + get { + return ResourceManager.GetString("OffRangeBasedTargeting", resourceCulture); + } + } + /// /// Looks up a localized string similar to On {0}. /// @@ -1123,6 +1150,24 @@ internal static string ShieldCheckPartyMemberNeedPercent { } } + /// + /// Looks up a localized string similar to Smart Targeting. + /// + internal static string SmartTargeting { + get { + return ResourceManager.GetString("SmartTargeting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nearest and Farthest Options will only target enemies not targeting the player.. + /// + internal static string SmartTargetingNotTargetingPlayer { + get { + return ResourceManager.GetString("SmartTargetingNotTargetingPlayer", resourceCulture); + } + } + /// /// Looks up a localized string similar to Soft Target. /// diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx index c5545ed57e..eba98bf5f6 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx @@ -263,6 +263,12 @@ Set to Zero to disable this check. Focus Target + + Furthest outside of 5y + + + Will {0} at the furthest hostile outside of 5 Yalms. + Use {0} in Opener @@ -349,7 +355,7 @@ Set to Zero to disable this check. Mouseover - Will retarget {0} at your mouseover target (if Hostile). + Will retarget {0} at your mouseover target (if Hostile). Highest Priority. Movement Option @@ -364,7 +370,7 @@ Set to Zero to disable this check. No Movement - Nearest Out of Range + Nearest outside of 5y Will {0} at the nearest hostile outside of 5 Yalms. @@ -390,6 +396,9 @@ Set to Zero to disable this check. Not In Boss Encounters + + Range Based Targeting Off + On {0} Used for simple "On {Action}" strings @@ -477,6 +486,12 @@ Set to 100 to disable this check. Shield Check: Percentage of Party Members without shields to check for. + + Smart Targeting + + + Nearest and Farthest Options will only target enemies not targeting the player. + Soft Target From 7ca1dfee86407abc5fbe9113e0e29ae515c40dc5 Mon Sep 17 00:00:00 2001 From: edewen Date: Mon, 29 Jun 2026 20:25:24 -0400 Subject: [PATCH 4/4] UI v3 --- WrathCombo/Combos/PvE/DRK/DRK.cs | 4 +- WrathCombo/Combos/PvE/DRK/DRK_Config.cs | 37 +++++++++-------- WrathCombo/Combos/PvE/GNB/GNB.cs | 6 +-- WrathCombo/Combos/PvE/GNB/GNB_Config.cs | 40 ++++++++++--------- WrathCombo/Combos/PvE/PLD/PLD.cs | 4 +- WrathCombo/Combos/PvE/PLD/PLD_Config.cs | 36 +++++++++-------- WrathCombo/Combos/PvE/WAR/WAR.cs | 4 +- WrathCombo/Combos/PvE/WAR/WAR_Config.cs | 38 +++++++++--------- .../JobConfigs/Generics.Designer.cs | 27 ++++++++----- .../Localization/JobConfigs/Generics.resx | 9 +++-- 10 files changed, 113 insertions(+), 92 deletions(-) diff --git a/WrathCombo/Combos/PvE/DRK/DRK.cs b/WrathCombo/Combos/PvE/DRK/DRK.cs index 7dee4cd7e4..cf60cdd7fc 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK.cs @@ -465,13 +465,13 @@ protected override uint Invoke(uint actionID) ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Unmend.ActionRange()) : null) ?? - (DRK_Retarget_Unmend_SmartTargeting == 1 + (DRK_Retarget_Unmend_SmartTargeting == 0 && DRK_Retarget_Unmend_RangeBasedTargeting ? DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Unmend.ActionRange()) : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(Unmend.ActionRange()) : null) ?? - (DRK_Retarget_Unmend_SmartTargeting == 2 + (DRK_Retarget_Unmend_SmartTargeting == 1 && DRK_Retarget_Unmend_RangeBasedTargeting ? DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Unmend.ActionRange()) : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(Unmend.ActionRange()) diff --git a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs index 2fd8900fa2..26ddc31fc8 100644 --- a/WrathCombo/Combos/PvE/DRK/DRK_Config.cs +++ b/WrathCombo/Combos/PvE/DRK/DRK_Config.cs @@ -475,29 +475,27 @@ internal static void Draw(Preset preset) case Preset.DRK_Retarget_Unmend: DrawAdditionalBoolChoice(DRK_Retarget_Unmend_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, Unmend.ActionName())); - - ImGui.Indent(12f.Scale()); - ImGui.NewLine(); - DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, - Generics.OffRangeBasedTargeting, "", 0, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, - Generics.FurthestOOR, - FormatAndCache(Generics.FurthestOORRetarget, Unmend.ActionName()), 1, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, - Generics.NearestOOR, - FormatAndCache(Generics.NearestOORRetarget, Unmend.ActionName()), 2, - descriptionColor:ImGuiColors.DalamudWhite); - ImGuiEx.Spacing(new Vector2(0, 5)); - if (DRK_Retarget_Unmend_SmartTargeting > 0) + DrawAdditionalBoolChoice(DRK_Retarget_Unmend_RangeBasedTargeting, Generics.RangeBasedTargeting, Generics.RangeBasedTargetingDesc); + if (DRK_Retarget_Unmend_RangeBasedTargeting) { + ImGui.Indent(); + ImGui.NewLine(); + DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, Unmend.ActionName()), 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(DRK_Retarget_Unmend_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, Unmend.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + ImGui.Unindent(); + + ImGui.Indent(10f.Scale()); DrawAdditionalBoolChoice(DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + ImGui.Unindent(); } - ImGui.Unindent(); break; - break; - #endregion } } @@ -1017,6 +1015,7 @@ public static readonly UserInt public static readonly UserBool DRK_Retarget_Unmend_FieldMO = new("DRK_Retarget_Unmend_FieldMO"), + DRK_Retarget_Unmend_RangeBasedTargeting = new("DRK_Retarget_Unmend_RangeBasedTargeting"), DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer = new("DRK_Retarget_Unmend_SmartTargeting_NotTargetingPlayer"); #endregion diff --git a/WrathCombo/Combos/PvE/GNB/GNB.cs b/WrathCombo/Combos/PvE/GNB/GNB.cs index 3ec132cecd..113be8859f 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB.cs @@ -719,17 +719,17 @@ protected override uint Invoke(uint actionID) IGameObject? target = //Mouseover Retarget - (GNB_RetargetLightningShot_FieldMO + (GNB_RetargetLightningShot_FieldMO ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(LightningShot.ActionRange()) : null) ?? - (GNB_RetargetLightningShot_SmartTargeting == 1 + (GNB_RetargetLightningShot_SmartTargeting == 0 && GNB_RetargetLightningShot_RangeBasedTargeting ? GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(LightningShot.ActionRange()) : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(LightningShot.ActionRange()) : null) ?? - (GNB_RetargetLightningShot_SmartTargeting == 2 + (GNB_RetargetLightningShot_SmartTargeting == 1 && GNB_RetargetLightningShot_RangeBasedTargeting ? GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(LightningShot.ActionRange()) : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(LightningShot.ActionRange()) diff --git a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs index 264baa71d2..c0deb63e0c 100644 --- a/WrathCombo/Combos/PvE/GNB/GNB_Config.cs +++ b/WrathCombo/Combos/PvE/GNB/GNB_Config.cs @@ -64,8 +64,9 @@ public static UserFloat public static UserBool GNB_Mit_Advanced_Boss_Camouflage_Align = new("GNB_Mit_Advanced_Boss_Camouflage_Align", true), GNB_Mit_Advanced_Boss_Nebula_First = new("GNB_Mit_Advanced_Boss_Nebula_First", true), - GNB_RetargetLightningShot_FieldMO = new("GNB_RetargetLightningShot_FieldMO", true), - GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer = new("GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer", true); + GNB_RetargetLightningShot_FieldMO = new("GNB_RetargetLightningShot_FieldMO"), + GNB_RetargetLightningShot_RangeBasedTargeting = new("GNB_RetargetLightningShot_RangeBasedTargeting"), + GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer = new("GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer"); public static UserIntArray GNB_Mit_OneButton_Priorities = new("GNB_Mit_OneButton_Priorities"); @@ -393,26 +394,29 @@ internal static void Draw(Preset preset) case Preset.GNB_RetargetLightningShot: DrawAdditionalBoolChoice(GNB_RetargetLightningShot_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, LightningShot.ActionName())); - ImGui.Indent(12f.Scale()); - ImGui.NewLine(); - DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, - Generics.OffRangeBasedTargeting, "", 0, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, - Generics.FurthestOOR, - FormatAndCache(Generics.FurthestOORRetarget, LightningShot.ActionName()), 1, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, - Generics.NearestOOR, - FormatAndCache(Generics.NearestOORRetarget, LightningShot.ActionName()), 2, - descriptionColor:ImGuiColors.DalamudWhite); - ImGuiEx.Spacing(new Vector2(0, 5)); - if (GNB_RetargetLightningShot_SmartTargeting > 0) + DrawAdditionalBoolChoice(GNB_RetargetLightningShot_RangeBasedTargeting, Generics.RangeBasedTargeting, Generics.RangeBasedTargetingDesc); + + if (GNB_RetargetLightningShot_RangeBasedTargeting) { + ImGui.Indent(); + ImGui.NewLine(); + DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, LightningShot.ActionName()), 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(GNB_RetargetLightningShot_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, LightningShot.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + ImGui.Unindent(); + + ImGui.Indent(10f.Scale()); DrawAdditionalBoolChoice(GNB_RetargetLightningShot_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + ImGui.Unindent(); } - ImGui.Unindent(); break; + #endregion } } diff --git a/WrathCombo/Combos/PvE/PLD/PLD.cs b/WrathCombo/Combos/PvE/PLD/PLD.cs index bb267a8228..ac16a84fa2 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD.cs @@ -269,13 +269,13 @@ protected override uint Invoke(uint actionID) ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(ShieldLob.ActionRange()) : null) ?? - (PLD_ShieldLob_Feature_SmartTargeting == 1 + (PLD_ShieldLob_Feature_SmartTargeting == 0 && PLD_ShieldLob_Feature_RangeBasedTargeting ? PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(ShieldLob.ActionRange()) : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(ShieldLob.ActionRange()) : null) ?? - (PLD_ShieldLob_Feature_SmartTargeting == 2 + (PLD_ShieldLob_Feature_SmartTargeting == 1 && PLD_ShieldLob_Feature_RangeBasedTargeting ? PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(ShieldLob.ActionRange()) : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(ShieldLob.ActionRange()) diff --git a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs index 689547a40a..563625c668 100644 --- a/WrathCombo/Combos/PvE/PLD/PLD_Config.cs +++ b/WrathCombo/Combos/PvE/PLD/PLD_Config.cs @@ -221,25 +221,28 @@ internal static void Draw(Preset preset) "\nRetargeting features will also apply to Holy Spirit."); DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, ShieldLob.ActionName())); - ImGui.Indent(12f.Scale()); - ImGui.NewLine(); - DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, - Generics.OffRangeBasedTargeting, "", 0, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, - Generics.FurthestOOR, - FormatAndCache(Generics.FurthestOORRetarget, ShieldLob.ActionName()), 1, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, - Generics.NearestOOR, - FormatAndCache(Generics.NearestOORRetarget, ShieldLob.ActionName()), 2, - descriptionColor:ImGuiColors.DalamudWhite); - ImGuiEx.Spacing(new Vector2(0, 5)); - if (PLD_ShieldLob_Feature_SmartTargeting > 0) + DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_RangeBasedTargeting, Generics.RangeBasedTargeting, Generics.RangeBasedTargetingDesc); + + if (PLD_ShieldLob_Feature_RangeBasedTargeting) { + ImGui.Indent(); + ImGui.NewLine(); + DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, ShieldLob.ActionName()), 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(PLD_ShieldLob_Feature_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, ShieldLob.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + ImGui.Unindent(); + + ImGui.Indent(10f.Scale()); DrawAdditionalBoolChoice(PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + ImGui.Unindent(); } - ImGui.Unindent(); + break; case Preset.PLD_Requiescat_Options: @@ -412,6 +415,7 @@ public static UserBool PLD_Requiescat_SubOption_GoringBlade = new("PLD_Requiescat_SubOption_GoringBlade"), PLD_ShieldLob_Feature_FieldMO = new("PLD_ShieldLob_Feature_FieldMO"), PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer = new("PLD_ShieldLob_Feature_SmartTargeting_NotTargetingPlayer"), + PLD_ShieldLob_Feature_RangeBasedTargeting = new("PLD_ShieldLob_Feature_RangeBasedTargeting"), PLD_ShieldLob_Feature_HolySpirit = new("PLD_ShieldLob_Feature_HolySpirit"); diff --git a/WrathCombo/Combos/PvE/WAR/WAR.cs b/WrathCombo/Combos/PvE/WAR/WAR.cs index f59871e00c..b7da6b1674 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR.cs @@ -423,13 +423,13 @@ protected override uint Invoke(uint actionID) ? SimpleTarget.Stack.MouseOver.IfHostile().IfWithinRange(Tomahawk.ActionRange()) : null) ?? - (WAR_RetargetTomahawk_SmartTargeting == 1 + (WAR_RetargetTomahawk_SmartTargeting == 0 && WAR_RetargetTomahawk_RangeBasedTargeting ? WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer ? SimpleTarget.FurthestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Tomahawk.ActionRange()) : SimpleTarget.FurthestEnemyOver5YalmsAway.IfWithinRange(Tomahawk.ActionRange()) : null) ?? - (WAR_RetargetTomahawk_SmartTargeting == 2 + (WAR_RetargetTomahawk_SmartTargeting == 1 && WAR_RetargetTomahawk_RangeBasedTargeting ? WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer ? SimpleTarget.NearestEnemyOver5YalmsAwayNotTargetingPlayer.IfWithinRange(Tomahawk.ActionRange()) : SimpleTarget.NearestEnemyOver5YalmsAway.IfWithinRange(Tomahawk.ActionRange()) diff --git a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs index 69d58b84a4..cf7d3aa471 100644 --- a/WrathCombo/Combos/PvE/WAR/WAR_Config.cs +++ b/WrathCombo/Combos/PvE/WAR/WAR_Config.cs @@ -434,26 +434,29 @@ internal static void Draw(Preset preset) case Preset.WAR_RetargetTomahawk: DrawAdditionalBoolChoice(WAR_RetargetTomahawk_FieldMO, Generics.Mouseover, FormatAndCache(Generics.MouseoverRetargetHostile, Tomahawk.ActionName())); - ImGui.Indent(12f.Scale()); - ImGui.NewLine(); - DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, - Generics.OffRangeBasedTargeting, "", 0, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, - Generics.FurthestOOR, - FormatAndCache(Generics.FurthestOORRetarget, Tomahawk.ActionName()), 1, - descriptionColor:ImGuiColors.DalamudWhite); - DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, - Generics.NearestOOR, - FormatAndCache(Generics.NearestOORRetarget, Tomahawk.ActionName()), 2, - descriptionColor:ImGuiColors.DalamudWhite); - ImGuiEx.Spacing(new Vector2(0, 5)); - if (WAR_RetargetTomahawk_SmartTargeting > 0) + DrawAdditionalBoolChoice(WAR_RetargetTomahawk_RangeBasedTargeting, Generics.RangeBasedTargeting, Generics.RangeBasedTargetingDesc); + + if (WAR_RetargetTomahawk_RangeBasedTargeting) { + ImGui.Indent(); + ImGui.NewLine(); + DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, + Generics.FurthestOOR, + FormatAndCache(Generics.FurthestOORRetarget, Tomahawk.ActionName()), 0, + descriptionColor:ImGuiColors.DalamudWhite); + DrawHorizontalRadioButton(WAR_RetargetTomahawk_SmartTargeting, + Generics.NearestOOR, + FormatAndCache(Generics.NearestOORRetarget, Tomahawk.ActionName()), 1, + descriptionColor:ImGuiColors.DalamudWhite); + ImGuiEx.Spacing(new Vector2(0, 5)); + ImGui.Unindent(); + + ImGui.Indent(10f.Scale()); DrawAdditionalBoolChoice(WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer, Generics.SmartTargeting, Generics.SmartTargetingNotTargetingPlayer); + ImGui.Unindent(); } - ImGui.Unindent(); break; + #endregion } } @@ -557,8 +560,7 @@ public static UserBool WAR_AoE_Onslaught_ManualPooling = new("WAR_AoE_Onslaught_ManualPooling"), WAR_RetargetTomahawk_FieldMO = new("WAR_RetargetTomahawk_FieldMO"), - WAR_RetargetTomahawk_FurthestOOR = new("WAR_RetargetTomahawk_FurthestOOR"), - WAR_RetargetTomahawk_NearestOOR = new("WAR_RetargetTomahawk_NearestOOR"), + WAR_RetargetTomahawk_RangeBasedTargeting = new("WAR_RetargetTomahawk_RangeBasedTargeting"), WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer = new("WAR_RetargetTomahawk_SmartTargeting_NotTargetingPlayer"); public static UserIntArray WAR_Mit_Priorities = new("WAR_Mit_Priorities"); diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs index 06068f9931..f6a8aec653 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.Designer.cs @@ -893,15 +893,6 @@ internal static string NotInBossEncounters { } } - /// - /// Looks up a localized string similar to Range Based Targeting Off. - /// - internal static string OffRangeBasedTargeting { - get { - return ResourceManager.GetString("OffRangeBasedTargeting", resourceCulture); - } - } - /// /// Looks up a localized string similar to On {0}. /// @@ -1069,6 +1060,24 @@ internal static string Priority { } } + /// + /// Looks up a localized string similar to Range Based Targeting. + /// + internal static string RangeBasedTargeting { + get { + return ResourceManager.GetString("RangeBasedTargeting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose to retarget to the nearest of furthest enemy outside of 5y.. + /// + internal static string RangeBasedTargetingDesc { + get { + return ResourceManager.GetString("RangeBasedTargetingDesc", resourceCulture); + } + } + /// /// Looks up a localized string similar to Replace {0} with {1} / {2}.. /// diff --git a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx index eba98bf5f6..a9b07063f1 100644 --- a/WrathCombo/Resources/Localization/JobConfigs/Generics.resx +++ b/WrathCombo/Resources/Localization/JobConfigs/Generics.resx @@ -396,10 +396,13 @@ Set to Zero to disable this check. Not In Boss Encounters - - Range Based Targeting Off + + Range Based Targeting - + + Choose to retarget to the nearest of furthest enemy outside of 5y. + + On {0} Used for simple "On {Action}" strings