diff --git a/RotationSolver.Basic/Actions/ActionTargetInfo.cs b/RotationSolver.Basic/Actions/ActionTargetInfo.cs index b864b567e..47971824d 100644 --- a/RotationSolver.Basic/Actions/ActionTargetInfo.cs +++ b/RotationSolver.Basic/Actions/ActionTargetInfo.cs @@ -6,6 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using RotationSolver.Basic.Configuration; +using static RotationSolver.Basic.Configuration.ConfigTypes; namespace RotationSolver.Basic.Actions; @@ -39,23 +40,6 @@ public struct ActionTargetInfo(IBaseAction action) /// public readonly bool IsTargetFriendly => action.Setting.IsFriendly; - private static bool NoAOE - { - get - { - if (!Service.Config.UseAoeAction) return true; - - if (DataCenter.IsManual) - { - if (!Service.Config.UseAoeWhenManual) return true; - } - - return Service.Config.ChooseAttackMark - && !Service.Config.CanAttackMarkAoe - && MarkingHelper.HaveAttackChara; - } - } - #region Target Finder. private readonly IEnumerable GetCanTargets(bool skipStatusProvideCheck, TargetType type) { @@ -409,8 +393,8 @@ private readonly IEnumerable GetAffects(BattleChara tar, IEnumerabl private readonly IEnumerable GetMostCanTargetObjects(IEnumerable canTargets, IEnumerable canAffects, int aoeCount) { if (IsSingleTarget || EffectRange <= 0) return canTargets; - if (!action.Setting.IsFriendly && NoAOE) return []; - if (aoeCount > 1 && DataCenter.IsManual) return []; + if (!action.Setting.IsFriendly && Service.Config.AoEType == AoEType.Off) return []; + if (aoeCount > 1 && Service.Config.AoEType == AoEType.Cleave) return []; List objectMax = new(canTargets.Count()); diff --git a/RotationSolver.Basic/Configuration/ConfigTypes.cs b/RotationSolver.Basic/Configuration/ConfigTypes.cs new file mode 100644 index 000000000..0b9c303c7 --- /dev/null +++ b/RotationSolver.Basic/Configuration/ConfigTypes.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RotationSolver.Basic.Configuration +{ + /// + /// Various types used in the configuration. + /// + public class ConfigTypes + { + /// + /// The type of AoE actions to use. + /// + public enum AoEType + { + /// + /// No AoE. + /// + Off = 0, + + /// + /// Only single-target AoE. + /// + Cleave = 1, + + /// + /// Full AoE. + /// + Full = 2, + } + } +} diff --git a/RotationSolver.Basic/Configuration/Configs.cs b/RotationSolver.Basic/Configuration/Configs.cs index 337eef2af..b3f390003 100644 --- a/RotationSolver.Basic/Configuration/Configs.cs +++ b/RotationSolver.Basic/Configuration/Configs.cs @@ -3,6 +3,7 @@ using ECommons.ExcelServices; using Newtonsoft.Json.Linq; using RotationSolver.Basic.Configuration.Timeline; +using static RotationSolver.Basic.Configuration.ConfigTypes; namespace RotationSolver.Basic.Configuration; @@ -40,6 +41,8 @@ public const string public MacroInfo DutyStart { get; set; } = new MacroInfo(); public MacroInfo DutyEnd { get; set; } = new MacroInfo(); + public AoEType AoEType { get; set; } = AoEType.Full; + [ConditionBool, UI("Show RSR logo animation", Filter = UiWindows)] private static readonly bool _drawIconAnimation = false; @@ -205,7 +208,7 @@ public const string private static readonly bool _startOnAttackedBySomeone = false; [ConditionBool, UI("Don't attack new mobs by AoE. (Dangerous)", Description = "Never use any AoE action when this may attack the mobs that are not hostile targets.", - Parent =nameof(UseAoeAction))] + Filter = BasicAutoSwitch)] private static readonly bool _noNewHostiles = false; [ConditionBool, UI("Use healing abilities when playing a non-healer role.", @@ -327,12 +330,6 @@ public const string Filter =UiInformation)] private static readonly bool _showToastsAboutDoAction = false; - [ConditionBool, UI("Use AoE actions", Filter = AutoActionUsage)] - private static readonly bool _useAOEAction = true; - - [ConditionBool, UI("Use single target AoE actions in manual mode.", Parent = nameof(UseAoeAction))] - private static readonly bool _useAOEWhenManual = false; - [ConditionBool, UI("Automatically trigger dps burst phase.", Filter = AutoActionCondition)] private static readonly bool _autoBurst = true; diff --git a/RotationSolver.Basic/Data/RSCommandType.cs b/RotationSolver.Basic/Data/RSCommandType.cs index 343ae6f5c..1dc680b02 100644 --- a/RotationSolver.Basic/Data/RSCommandType.cs +++ b/RotationSolver.Basic/Data/RSCommandType.cs @@ -99,7 +99,7 @@ public enum StateCommandType : byte /// /// [Description("Stop the addon. Always remember to turn it off when it is not in use!")] - Cancel, + Off, /// /// diff --git a/RotationSolver/Commands/RSCommands_Actions.cs b/RotationSolver/Commands/RSCommands_Actions.cs index 38891782d..80d911788 100644 --- a/RotationSolver/Commands/RSCommands_Actions.cs +++ b/RotationSolver/Commands/RSCommands_Actions.cs @@ -21,7 +21,7 @@ public static void IncrementState() if (!DataCenter.State) { DoStateCommandType(StateCommandType.Auto); return; } if (DataCenter.State && !DataCenter.IsManual && DataCenter.TargetingType == TargetingType.Big) { DoStateCommandType(StateCommandType.Auto); return; } if (DataCenter.State && !DataCenter.IsManual) { DoStateCommandType(StateCommandType.Manual); return; } - if (DataCenter.State && DataCenter.IsManual) { DoStateCommandType(StateCommandType.Cancel); return; } + if (DataCenter.State && DataCenter.IsManual) { DoStateCommandType(StateCommandType.Off); return; } } internal static unsafe bool CanDoAnAction(bool isGCD) @@ -170,7 +170,7 @@ internal static void ResetSpecial() } internal static void CancelState() { - if (DataCenter.State) DoStateCommandType(StateCommandType.Cancel); + if (DataCenter.State) DoStateCommandType(StateCommandType.Off); } static float _lastCountdownTime = 0; diff --git a/RotationSolver/Commands/RSCommands_OtherCommand.cs b/RotationSolver/Commands/RSCommands_OtherCommand.cs index 5b37f944e..473d665a4 100644 --- a/RotationSolver/Commands/RSCommands_OtherCommand.cs +++ b/RotationSolver/Commands/RSCommands_OtherCommand.cs @@ -40,58 +40,66 @@ private static void DoOtherCommand(OtherCommandType otherType, string str) private static void DoSettingCommand(string str) { var strs = str.Split(' '); + var settingName = strs[0]; var value = strs.LastOrDefault(); - - foreach (var property in typeof(Configs).GetRuntimeProperties() - .Where(p => p.GetMethod?.IsPublic ?? false)) + foreach (var property in typeof(Configs).GetRuntimeProperties().Where(p => p.GetMethod?.IsPublic ?? false)) { - if (!str.StartsWith(property.Name, StringComparison.OrdinalIgnoreCase)) continue; + if (!settingName.Equals(property.Name, StringComparison.OrdinalIgnoreCase)) + continue; var type = property.PropertyType; - if (type == typeof(ConditionBoolean)) - { type = typeof(bool); - } - - object v; - try { v = Convert.ChangeType(value, type); } - catch { v = null; } - if (v == null && type == typeof(bool)) + object convertedValue = null; + try { - var config = property.GetValue(Service.Config); - if (config is ConditionBoolean relay) + if (type.IsEnum) { - relay.Value = !relay.Value; - v = relay.Value; + convertedValue = Enum.Parse(type, value, ignoreCase: true); + } + else + { + convertedValue = Convert.ChangeType(value, type); } } - - if (property.PropertyType == typeof(ConditionBoolean)) + catch { - var relay = (ConditionBoolean)property.GetValue(Service.Config)!; - relay.Value = (bool)v!; - v = relay; + if (type == typeof(bool)) + { + // Toggle the boolean value if no value is specified + var config = property.GetValue(Service.Config) as ConditionBoolean; + if (config != null) + { + config.Value = !config.Value; + convertedValue = config.Value; + } + } } - if (v == null) + if (convertedValue == null) { #if DEBUG - Svc.Chat.Print("Failed to get the value."); + Svc.Chat.Print("Failed to parse the value."); #endif continue; } - property.SetValue(Service.Config, v); - value = v.ToString(); + // If it's a ConditionBoolean, handle it specifically + if (property.PropertyType == typeof(ConditionBoolean)) + { + var relay = (ConditionBoolean)property.GetValue(Service.Config)!; + relay.Value = (bool)convertedValue; + convertedValue = relay; + } - //Say out. - Svc.Chat.Print(string.Format(UiString.CommandsChangeSettingsValue.Local(), property.Name, value)); + property.SetValue(Service.Config, convertedValue); + value = convertedValue.ToString(); + // Notify the user of the change + Svc.Chat.Print(string.Format(UiString.CommandsChangeSettingsValue.Local(), property.Name, value)); return; - } Svc.Chat.PrintError(UiString.CommandsCannotFindConfig.Local()); diff --git a/RotationSolver/Commands/RSCommands_StateSpecialCommand.cs b/RotationSolver/Commands/RSCommands_StateSpecialCommand.cs index e5df570d9..1f6937840 100644 --- a/RotationSolver/Commands/RSCommands_StateSpecialCommand.cs +++ b/RotationSolver/Commands/RSCommands_StateSpecialCommand.cs @@ -29,13 +29,13 @@ private static unsafe void DoStateCommandType(StateCommandType stateType, int in if (DataCenter.IsManual && stateType == StateCommandType.Manual && Service.Config.ToggleManual) { - stateType = StateCommandType.Cancel; + stateType = StateCommandType.Off; } else if (stateType == StateCommandType.Auto) { if (Service.Config.ToggleAuto) { - stateType = StateCommandType.Cancel; + stateType = StateCommandType.Off; } else { @@ -51,7 +51,7 @@ private static unsafe void DoStateCommandType(StateCommandType stateType, int in switch (stateType) { - case StateCommandType.Cancel: + case StateCommandType.Off: DataCenter.State = false; break; diff --git a/RotationSolver/Localization/EnumTranslations.cs b/RotationSolver/Localization/EnumTranslations.cs index 768705c08..9b3788563 100644 --- a/RotationSolver/Localization/EnumTranslations.cs +++ b/RotationSolver/Localization/EnumTranslations.cs @@ -12,7 +12,7 @@ internal static class EnumTranslations internal static string ToSayout(this StateCommandType type, JobRole role) => type switch { - StateCommandType.Cancel => UiString.SpecialCommandType_Cancel.Local(), + StateCommandType.Off => UiString.SpecialCommandType_Cancel.Local(), _ => type.ToStateString(role), }; @@ -50,7 +50,7 @@ internal static class EnumTranslations { StateCommandType.Auto => UiString.SpecialCommandType_Smart.Local() + DataCenter.TargetingType.Local(), StateCommandType.Manual => UiString.SpecialCommandType_Manual.Local(), - StateCommandType.Cancel => UiString.SpecialCommandType_Off.Local(), + StateCommandType.Off => UiString.SpecialCommandType_Off.Local(), _ => string.Empty, }; } diff --git a/RotationSolver/UI/ControlWindow.cs b/RotationSolver/UI/ControlWindow.cs index 79b7444f5..076791363 100644 --- a/RotationSolver/UI/ControlWindow.cs +++ b/RotationSolver/UI/ControlWindow.cs @@ -2,6 +2,7 @@ using Dalamud.Interface.Internal; using Dalamud.Interface.Utility.Raii; using ECommons.DalamudServices; +using RotationSolver.Basic.Configuration; using RotationSolver.Commands; using RotationSolver.Data; using RotationSolver.Localization; @@ -40,71 +41,31 @@ public override unsafe void Draw() ImGui.NewLine(); ImGui.Spacing(); - - DrawCommandAction(61751, StateCommandType.Manual, ImGuiColors.DPSRed); - - ImGui.SameLine(); - DrawCommandAction(61764, StateCommandType.Cancel, ImGuiColors.DalamudWhite2); - + DrawCommandAction(61822, StateCommandType.Auto, ImGuiColors.DPSRed); ImGui.SameLine(); + DrawCommandAction(61751, StateCommandType.Manual, ImGuiColors.DPSRed); columnWidth = Math.Max(columnWidth, ImGui.GetCursorPosX()); - ImGui.NewLine(); - - DrawCommandAction(61822, StateCommandType.Auto, ImGuiColors.DPSRed); - ImGui.SameLine(); + DrawCommandAction(61764, StateCommandType.Off, ImGuiColors.DalamudWhite2); + ImGui.Spacing(); + columnWidth = Math.Max(columnWidth, ImGui.GetCursorPosX()); - ImGui.BeginGroup(); - - ImGui.TextColored(ImGuiColors.DPSRed, DataCenter.TargetingType.Local()); + var autoMode = DataCenter.TargetingType; + ImGui.Text(" Targeting: " + autoMode.Local()); - var value = Service.Config.IsControlWindowLock ? 0 : 1; - if (ImGuiHelper.SelectableCombo("Rotation Solver Lock the Control Window", - [ - UiString.InfoWindowNoMove.Local(), - UiString.InfoWindowMove.Local(), - ], ref value)) + var aoeType = Service.Config.AoEType; + if (ImGuiHelper.SelectableButton("AoE: " + aoeType.ToString())) { - Service.Config.IsControlWindowLock.Value = value == 0; + aoeType = (ConfigTypes.AoEType)(((int)aoeType + 1) % 3); + Service.Config.AoEType = aoeType; } - - ImGui.EndGroup(); - - ImGui.SameLine(); - columnWidth = Math.Max(columnWidth, ImGui.GetCursorPosX()); - ImGui.NewLine(); - - var color = *ImGui.GetStyleColorVec4(ImGuiCol.TextDisabled); - - var isAoe = Service.Config.UseAoeAction && (!DataCenter.IsManual || Service.Config.UseAoeWhenManual); - // Track whether the style color was pushed bool pushedStyleColor = false; - if (!isAoe) - { - ImGui.PushStyleColor(ImGuiCol.Text, color); - pushedStyleColor = true; // Indicate that a style color has been pushed - } - - if (ImGuiHelper.SelectableButton("AOE")) - { - Service.Config.UseAoeAction.Value = !isAoe; - Service.Config.UseAoeWhenManual.Value = !isAoe; - } - - // Ensure PopStyleColor is called only if PushStyleColor was called - if (pushedStyleColor) - { - ImGui.PopStyleColor(); - } - - - ImGui.SameLine(); - var isBurst = Service.Config.AutoBurst; // Track whether the style color was pushed pushedStyleColor = false; + var color = *ImGui.GetStyleColorVec4(ImGuiCol.TextDisabled); if (!isBurst) { @@ -123,10 +84,18 @@ public override unsafe void Draw() ImGui.PopStyleColor(); } ImGui.SameLine(); - columnWidth = Math.Max(columnWidth, ImGui.GetCursorPosX()); - ImGui.NewLine(); - ImGui.SetColumnWidth(0, columnWidth); + var value = Service.Config.IsControlWindowLock ? 0 : 1; + if (ImGuiHelper.SelectableCombo("Rotation Solver Lock the Control Window", + [ + UiString.InfoWindowNoMove.Local(), + UiString.InfoWindowMove.Local(), + ], ref value)) + { + Service.Config.IsControlWindowLock.Value = value == 0; + } + columnWidth = Math.Max(columnWidth, ImGui.GetCursorPosX()); + ImGui.SetColumnWidth(0, columnWidth + 10); ImGui.NextColumn(); ImGui.NextColumn(); @@ -247,7 +216,7 @@ static void DrawCommandAction(IAction? gcd, IAction? ability, SpecialCommandType { if (subGroup) { - ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(0, width / 2 - strWidth / 2)); + ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(2, width / 2 - strWidth / 2)); ImGui.TextColored(color, str); var help = command.Local(); @@ -347,7 +316,6 @@ static void DrawCommandAction(IDalamudTextureWrap texture, SpecialCommandType co ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(0, strWidth / 2 - width / 2)); if (texture != null) DrawIAction(texture.ImGuiHandle, baseId, abilityW, command, help); - } } @@ -380,7 +348,7 @@ static void DrawCommandAction(uint iconId, StateCommandType command, Vector4 col { if (group) { - ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(0, width / 2 - strWidth / 2)); + ImGui.SetCursorPosX(ImGui.GetCursorPosX() + Math.Max(0, width / 2 - strWidth / 2) - 3.5f); ImGui.TextColored(color, str); var help = command.Local(); @@ -400,7 +368,7 @@ static void DrawCommandAction(uint iconId, StateCommandType command, Vector4 col { case StateCommandType.Auto when DataCenter.State && !DataCenter.IsManual: case StateCommandType.Manual when DataCenter.State && DataCenter.IsManual: - case StateCommandType.Cancel when !DataCenter.State: + case StateCommandType.Off when !DataCenter.State: isMatch = true; break; } diff --git a/RotationSolver/UI/RotationConfigWindow.cs b/RotationSolver/UI/RotationConfigWindow.cs index 3b31b5882..a89b3d0f9 100644 --- a/RotationSolver/UI/RotationConfigWindow.cs +++ b/RotationSolver/UI/RotationConfigWindow.cs @@ -725,7 +725,7 @@ private static void DrawAboutMacros() StateCommandType.Manual.DisplayCommandHelp(getHelp: LocalizationManager.Local); - StateCommandType.Cancel.DisplayCommandHelp(getHelp: LocalizationManager.Local); + StateCommandType.Off.DisplayCommandHelp(getHelp: LocalizationManager.Local); OtherCommandType.NextAction.DisplayCommandHelp(getHelp: LocalizationManager.Local);