From 5bd2c35820d7bb684861917e252dc0e362cab265 Mon Sep 17 00:00:00 2001 From: LTS-FFXIV <127939494+LTS-FFXIV@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:43:34 -0600 Subject: [PATCH] Refactor PrioTarget system and enhance various functionalities Replaced PrioTargetNames with PrioTargetId HashSet across the codebase, updating initialization, saving, and resetting methods. Improved DataCenter's IsCastingVfx method to avoid modifying collections during enumeration. Extended IActionHelper with IsLastActionGCD and IsLastActionAbility methods. Updated ObjectHelper to remove PrioTargetNames logic and enhance ChooseAttackMark condition. Enhanced PriorityTargetHelper to handle priority target IDs via JSON. Updated solution file to include PrioTargetId.json. Refined UiString and RotationConfigWindow for new target priority system. Improved MajorUpdater's VfxNewData handling. Added PrioTargetId.json for storing priority target IDs. --- PrioTargetId.json | 4 ++ .../Configuration/OtherConfiguration.cs | 16 +++-- RotationSolver.Basic/DataCenter.cs | 18 ++---- RotationSolver.Basic/Helpers/IActionHelper.cs | 18 ++++++ RotationSolver.Basic/Helpers/ObjectHelper.cs | 12 +--- .../Helpers/PriorityTargetHelper.cs | 30 ++++++--- RotationSolver.sln | 7 ++- RotationSolver/Data/UiString.cs | 8 +-- RotationSolver/UI/RotationConfigWindow.cs | 63 +------------------ .../UI/RotationConfigWindow_Config.cs | 41 ++++++++++++ RotationSolver/Updaters/MajorUpdater.cs | 11 ++-- 11 files changed, 117 insertions(+), 111 deletions(-) create mode 100644 PrioTargetId.json diff --git a/PrioTargetId.json b/PrioTargetId.json new file mode 100644 index 000000000..dc910c28f --- /dev/null +++ b/PrioTargetId.json @@ -0,0 +1,4 @@ +[ + 0x415E, + 0x4642 +] \ No newline at end of file diff --git a/RotationSolver.Basic/Configuration/OtherConfiguration.cs b/RotationSolver.Basic/Configuration/OtherConfiguration.cs index 5d2ab0c2b..4533aa532 100644 --- a/RotationSolver.Basic/Configuration/OtherConfiguration.cs +++ b/RotationSolver.Basic/Configuration/OtherConfiguration.cs @@ -10,7 +10,6 @@ internal class OtherConfiguration public static SortedList AnimationLockTime = []; - public static Dictionary PrioTargetNames = []; public static Dictionary NoHostileNames = []; public static Dictionary NoProvokeNames = []; public static Dictionary BeneficialPositions = []; @@ -19,6 +18,7 @@ internal class OtherConfiguration public static HashSet PriorityStatus = []; public static HashSet InvincibleStatus = []; public static HashSet NoCastingStatus = []; + public static HashSet PrioTargetId = []; public static RotationSolverRecord RotationSolverRecord = new(); @@ -32,7 +32,7 @@ public static void Init() Task.Run(() => InitOne(ref DangerousStatus, nameof(DangerousStatus))); Task.Run(() => InitOne(ref PriorityStatus, nameof(PriorityStatus))); Task.Run(() => InitOne(ref InvincibleStatus, nameof(InvincibleStatus))); - Task.Run(() => InitOne(ref PrioTargetNames, nameof(PrioTargetNames))); + Task.Run(() => InitOne(ref PrioTargetId, nameof(PrioTargetId))); Task.Run(() => InitOne(ref NoHostileNames, nameof(NoHostileNames))); Task.Run(() => InitOne(ref NoProvokeNames, nameof(NoProvokeNames))); Task.Run(() => InitOne(ref AnimationLockTime, nameof(AnimationLockTime))); @@ -51,7 +51,7 @@ public static Task Save() await SavePriorityStatus(); await SaveDangerousStatus(); await SaveInvincibleStatus(); - await SavePrioTargetNames(); + await SavePrioTargetId(); await SaveNoHostileNames(); await SaveAnimationLockTime(); await SaveHostileCastingArea(); @@ -159,9 +159,15 @@ public static Task SaveBeneficialPositions() return Task.Run(() => Save(BeneficialPositions, nameof(BeneficialPositions))); } - public static Task SavePrioTargetNames() + public static void ResetPrioTargetId() { - return Task.Run(() => Save(PrioTargetNames, nameof(PrioTargetNames))); + InitOne(ref PrioTargetId, nameof(PrioTargetId), true, true); + SaveHostileCastingKnockback().Wait(); + } + + public static Task SavePrioTargetId() + { + return Task.Run(() => Save(PrioTargetId, nameof(PrioTargetId))); } public static Task SaveNoHostileNames() diff --git a/RotationSolver.Basic/DataCenter.cs b/RotationSolver.Basic/DataCenter.cs index b2e84d374..dc8bff228 100644 --- a/RotationSolver.Basic/DataCenter.cs +++ b/RotationSolver.Basic/DataCenter.cs @@ -809,24 +809,16 @@ public static bool IsCastingAreaVfx() public static bool IsCastingVfx(Func isVfx) { - if (isVfx == null) return false; - if (DataCenter.VfxDataQueue == null) return false; + // Create a copy of the VfxDataQueue to avoid modifying the collection while enumerating + var vfxDataQueueCopy = VfxDataQueue.ToList(); - try + foreach (var vfx in vfxDataQueueCopy) { - foreach (var item in DataCenter.VfxDataQueue.OrderBy(v => v.TimeDuration)) + if (isVfx(vfx)) { - if (item.TimeDuration.TotalSeconds is > 1 and < 5) - { - if (isVfx(item)) return true; - } + return true; } } - catch (Exception ex) - { - Svc.Log.Error(ex, "Exception in IsCastingVfx"); - } - return false; } diff --git a/RotationSolver.Basic/Helpers/IActionHelper.cs b/RotationSolver.Basic/Helpers/IActionHelper.cs index 6f1901ab4..4eb8f1937 100644 --- a/RotationSolver.Basic/Helpers/IActionHelper.cs +++ b/RotationSolver.Basic/Helpers/IActionHelper.cs @@ -85,6 +85,24 @@ internal static bool IsLastAction(params ActionID[] ids) return IsActionID(DataCenter.LastAction, ids); } + /// + /// Determines if the last action was a GCD. + /// + /// True if the last action was a GCD, otherwise false. + public static bool IsLastActionGCD() + { + return DataCenter.LastAction == DataCenter.LastGCD; + } + + /// + /// Determines if the last action was an ability. + /// + /// True if the last action was an ability, otherwise false. + public static bool IsLastActionAbility() + { + return DataCenter.LastAction == DataCenter.LastAbility; + } + /// /// Determines if the action is the same as any of the provided actions. /// diff --git a/RotationSolver.Basic/Helpers/ObjectHelper.cs b/RotationSolver.Basic/Helpers/ObjectHelper.cs index 6a3bc2e9c..12979cde4 100644 --- a/RotationSolver.Basic/Helpers/ObjectHelper.cs +++ b/RotationSolver.Basic/Helpers/ObjectHelper.cs @@ -310,16 +310,6 @@ internal static bool IsTopPriorityNamedHostile(this IGameObject obj) { if (obj == null) return false; - // Fetch prioritized target names - if (OtherConfiguration.PrioTargetNames.TryGetValue(Svc.ClientState.TerritoryType, out var prioTargetNames)) - { - // If the target's name matches any prioritized names, it is attackable - if (obj is IBattleChara bpnc && prioTargetNames.Any(n => !string.IsNullOrEmpty(n) && new Regex(n).Match(bpnc.Name.TextValue).Success)) - { - return true; - } - } - if (obj is IBattleChara npc && DataCenter.PrioritizedNameIds.Contains(npc.NameId)) return true; return false; @@ -348,7 +338,7 @@ internal static bool IsTopPriorityHostile(this IGameObject obj) if (b.StatusList != null && b.StatusList.Any(StatusHelper.IsPriority)) return true; } - if (Service.Config.ChooseAttackMark && MarkingHelper.GetAttackSignTargets().FirstOrDefault(id => id != 0) == (long)obj.GameObjectId) return true; + if (Service.Config.ChooseAttackMark && MarkingHelper.GetAttackSignTargets().FirstOrDefault(id => id != 0) == (long)obj.GameObjectId && obj.IsEnemy()) return true; // Fate if (Service.Config.TargetFatePriority && fateId != 0 && obj.FateId() == fateId) return true; diff --git a/RotationSolver.Basic/Helpers/PriorityTargetHelper.cs b/RotationSolver.Basic/Helpers/PriorityTargetHelper.cs index 7377615da..8d4c2e9bf 100644 --- a/RotationSolver.Basic/Helpers/PriorityTargetHelper.cs +++ b/RotationSolver.Basic/Helpers/PriorityTargetHelper.cs @@ -1,14 +1,16 @@ -namespace RotationSolver.Basic.Helpers +using System.IO; +using System.Text.Json; +using JsonSerializer = System.Text.Json.JsonSerializer; +using RotationSolver.Basic.Configuration; + +namespace RotationSolver.Basic.Helpers { internal class PriorityTargetHelper { + private static readonly string FilePath = "PriorityId.json"; + // List of OIDs (DataId) - private static readonly HashSet priorityOids = new HashSet - { - 0x415E, // Crystalline Debris in D022Kahderyor - 0x4642 // Raw Electrope in D09YuweyawataFieldStation - // Add more OIDs here - }; + private static HashSet priorityOids = LoadPriorityOids(); // Method to check if the given DataId is a priority target public static bool IsPriorityTarget(uint dataId) @@ -22,7 +24,19 @@ public static void AddPriorityTarget(uint dataId) if (!priorityOids.Contains(dataId)) { priorityOids.Add(dataId); + OtherConfiguration.SavePrioTargetId(); + } + } + + // Method to load priority OIDs from JSON file + private static HashSet LoadPriorityOids() + { + if (File.Exists(FilePath)) + { + var json = File.ReadAllText(FilePath); + return JsonSerializer.Deserialize>(json) ?? new HashSet(); } + return new HashSet(); } } -} +} \ No newline at end of file diff --git a/RotationSolver.sln b/RotationSolver.sln index 84642ec36..a37c776aa 100644 --- a/RotationSolver.sln +++ b/RotationSolver.sln @@ -6,14 +6,15 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8948C02A-914E-4A51-B1FE-2C608492EBF5}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + Resources\AnimationLockTime.json = Resources\AnimationLockTime.json Directory.Build.props = Directory.Build.props - Resources\IncompatiblePlugins.json = Resources\IncompatiblePlugins.json Resources\HostileCastingArea.json = Resources\HostileCastingArea.json Resources\HostileCastingKnockback.json = Resources\HostileCastingKnockback.json Resources\HostileCastingTank.json = Resources\HostileCastingTank.json - Resources\AnimationLockTime.json = Resources\AnimationLockTime.json + Resources\IncompatiblePlugins.json = Resources\IncompatiblePlugins.json manifest.json = manifest.json .github\workflows\publish.yaml = .github\workflows\publish.yaml + PrioTargetId.json = PrioTargetId.json UpdateDownloads.ts = UpdateDownloads.ts EndProjectSection EndProject @@ -29,7 +30,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RotationSolver.GameData", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RotationSolver.DummyRotations", "RotationSolver.DummyRotations\RotationSolver.DummyRotations.csproj", "{2C9BACA6-A791-478C-84BB-8A798123468A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RebornRotations", "BasicRotations\RebornRotations.csproj", "{054B46FA-5639-45A0-A5A1-4A8ED860DDC9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RebornRotations", "BasicRotations\RebornRotations.csproj", "{054B46FA-5639-45A0-A5A1-4A8ED860DDC9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/RotationSolver/Data/UiString.cs b/RotationSolver/Data/UiString.cs index e0ac8a501..8dbd913c5 100644 --- a/RotationSolver/Data/UiString.cs +++ b/RotationSolver/Data/UiString.cs @@ -274,9 +274,6 @@ internal enum UiString [Description("Add Action")] ConfigWindow_List_AddAction, - [Description("Prio Target")] - ConfigWindow_List_PrioTarget, - [Description("Don't target")] ConfigWindow_List_NoHostile, @@ -286,7 +283,7 @@ internal enum UiString [Description("Beneficial AoE locations")] ConfigWindow_List_BeneficialPositions, - [Description("Enemies that will be prioritized.")] + [Description("Enemies that will be prioritized. This system is under construction and experimental, but should be stable.")] ConfigWindow_List_PrioTargetDesc, [Description("Enemies that will never be targeted.")] @@ -451,6 +448,9 @@ internal enum UiString [Description("Hostile")] ConfigWindow_List_Hostile, + [Description("Target Priority")] + ConfigWindow_List_TargetPriority, + [Description("Enemy targeting logic. Adding more options cycles them when using /rotation Auto.\nUse /rotation Settings TargetingTypes add