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