Skip to content

Commit

Permalink
Merge pull request #460 from FFXIV-CombatReborn/moar
Browse files Browse the repository at this point in the history
Refactor PrioTarget system and enhance various functionalities
  • Loading branch information
LTS-FFXIV authored Dec 4, 2024
2 parents 87b2254 + 5bd2c35 commit 4492670
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 111 deletions.
4 changes: 4 additions & 0 deletions PrioTargetId.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
0x415E,
0x4642
]
16 changes: 11 additions & 5 deletions RotationSolver.Basic/Configuration/OtherConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ internal class OtherConfiguration

public static SortedList<uint, float> AnimationLockTime = [];

public static Dictionary<uint, string[]> PrioTargetNames = [];
public static Dictionary<uint, string[]> NoHostileNames = [];
public static Dictionary<uint, string[]> NoProvokeNames = [];
public static Dictionary<uint, Vector3[]> BeneficialPositions = [];
Expand All @@ -19,6 +18,7 @@ internal class OtherConfiguration
public static HashSet<uint> PriorityStatus = [];
public static HashSet<uint> InvincibleStatus = [];
public static HashSet<uint> NoCastingStatus = [];
public static HashSet<uint> PrioTargetId = [];

public static RotationSolverRecord RotationSolverRecord = new();

Expand All @@ -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)));
Expand All @@ -51,7 +51,7 @@ public static Task Save()
await SavePriorityStatus();
await SaveDangerousStatus();
await SaveInvincibleStatus();
await SavePrioTargetNames();
await SavePrioTargetId();
await SaveNoHostileNames();
await SaveAnimationLockTime();
await SaveHostileCastingArea();
Expand Down Expand Up @@ -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()
Expand Down
18 changes: 5 additions & 13 deletions RotationSolver.Basic/DataCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -809,24 +809,16 @@ public static bool IsCastingAreaVfx()

public static bool IsCastingVfx(Func<VfxNewData, bool> 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;
}

Expand Down
18 changes: 18 additions & 0 deletions RotationSolver.Basic/Helpers/IActionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ internal static bool IsLastAction(params ActionID[] ids)
return IsActionID(DataCenter.LastAction, ids);
}

/// <summary>
/// Determines if the last action was a GCD.
/// </summary>
/// <returns>True if the last action was a GCD, otherwise false.</returns>
public static bool IsLastActionGCD()
{
return DataCenter.LastAction == DataCenter.LastGCD;
}

/// <summary>
/// Determines if the last action was an ability.
/// </summary>
/// <returns>True if the last action was an ability, otherwise false.</returns>
public static bool IsLastActionAbility()
{
return DataCenter.LastAction == DataCenter.LastAbility;
}

/// <summary>
/// Determines if the action is the same as any of the provided actions.
/// </summary>
Expand Down
12 changes: 1 addition & 11 deletions RotationSolver.Basic/Helpers/ObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
30 changes: 22 additions & 8 deletions RotationSolver.Basic/Helpers/PriorityTargetHelper.cs
Original file line number Diff line number Diff line change
@@ -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<uint> priorityOids = new HashSet<uint>
{
0x415E, // Crystalline Debris in D022Kahderyor
0x4642 // Raw Electrope in D09YuweyawataFieldStation
// Add more OIDs here
};
private static HashSet<uint> priorityOids = LoadPriorityOids();

// Method to check if the given DataId is a priority target
public static bool IsPriorityTarget(uint dataId)
Expand All @@ -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<uint> LoadPriorityOids()
{
if (File.Exists(FilePath))
{
var json = File.ReadAllText(FilePath);
return JsonSerializer.Deserialize<HashSet<uint>>(json) ?? new HashSet<uint>();
}
return new HashSet<uint>();
}
}
}
}
7 changes: 4 additions & 3 deletions RotationSolver.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
8 changes: 4 additions & 4 deletions RotationSolver/Data/UiString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand All @@ -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.")]
Expand Down Expand Up @@ -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 <option> to add,\n/rotation Settings TargetingTypes remove <option> to remove,\nand /rotation Settings TargetingTypes removeall to remove all options.")]
ConfigWindow_Param_HostileDesc,

Expand Down
63 changes: 2 additions & 61 deletions RotationSolver/UI/RotationConfigWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2363,9 +2363,6 @@ private static void DrawListTerritories()
ImGui.TableNextColumn();
ImGui.TableHeader(UiString.ConfigWindow_List_NoHostile.GetDescription());

ImGui.TableNextColumn();
ImGui.TableHeader(UiString.ConfigWindow_List_PrioTarget.GetDescription());

ImGui.TableNextColumn();
ImGui.TableHeader(UiString.ConfigWindow_List_NoProvoke.GetDescription());

Expand Down Expand Up @@ -2414,64 +2411,6 @@ private static void DrawListTerritories()
OtherConfiguration.SaveNoHostileNames();
}




// Begin new column for Prioritized Target Names
ImGui.TableNextColumn();
ImGui.TextWrapped(UiString.ConfigWindow_List_PrioTargetDesc.GetDescription());

width = ImGui.GetColumnWidth() - ImGuiEx.CalcIconSize(FontAwesomeIcon.Ban).X - ImGui.GetStyle().ItemSpacing.X - 10 * Scale;

// Check if PrioritizedNames for the current territory exists
if (!OtherConfiguration.PrioTargetNames.TryGetValue(territoryId, out var prioNames))
{
// Initialize it as an empty list
OtherConfiguration.PrioTargetNames[territoryId] = prioNames = [];
}

// Add an empty entry if none exists
if (!prioNames.Any(string.IsNullOrEmpty))
{
OtherConfiguration.PrioTargetNames[territoryId] = [.. prioNames, string.Empty];
}

// Variable to track if we need to remove any entry
removeIndex = -1;

// Loop over each prioritized name to render input fields
for (int i = 0; i < prioNames.Length; i++)
{
ImGui.SetNextItemWidth(width);

// Render input field for prioritized name with a placeholder hint
if (ImGui.InputTextWithHint($"##Rotation Solver Prioritized Target Name {i}", UiString.ConfigWindow_List_PrioTargetName.GetDescription(), ref prioNames[i], 1024))
{
// If input changes, update the list
OtherConfiguration.PrioTargetNames[territoryId] = prioNames;
OtherConfiguration.SavePrioTargetNames();
}
ImGui.SameLine();

// Render a button to remove a name
if (ImGuiEx.IconButton(FontAwesomeIcon.Ban, $"##Rotation Solver Remove Prioritized Target Name {i}"))
{
removeIndex = i;
}
}

// If a remove button was clicked, remove the corresponding entry
if (removeIndex > -1)
{
var list = prioNames.ToList();
list.RemoveAt(removeIndex);
OtherConfiguration.PrioTargetNames[territoryId] = [.. list];
OtherConfiguration.SavePrioTargetNames();
}




ImGui.TableNextColumn();
ImGui.TextWrapped(UiString.ConfigWindow_List_NoProvokeDesc.GetDescription());

Expand Down Expand Up @@ -2844,6 +2783,8 @@ private static void DrawLastAction()
DrawAction(DataCenter.LastAbility, nameof(DataCenter.LastAbility));
DrawAction(DataCenter.LastGCD, nameof(DataCenter.LastGCD));
DrawAction(DataCenter.LastComboAction, nameof(DataCenter.LastComboAction));
ImGui.Text($"IsLastActionAbility: {IActionHelper.IsLastActionAbility()}");
ImGui.Text($"IsLastActionGCD: {IActionHelper.IsLastActionGCD()}");
}

private static void DrawOthers()
Expand Down
41 changes: 41 additions & 0 deletions RotationSolver/UI/RotationConfigWindow_Config.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Dalamud.Game.ClientState.Keys;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility.Raii;
using ECommons.DalamudServices;
using ECommons.ImGuiMethods;
using Lumina.Excel.Sheets;
using RotationSolver.Basic.Configuration;
using RotationSolver.Basic.Configuration.Conditions;
using RotationSolver.Data;
Expand Down Expand Up @@ -377,6 +379,7 @@ private static void DrawTarget()
{
{ UiString.ConfigWindow_Target_Config.GetDescription, DrawTargetConfig },
{ UiString.ConfigWindow_List_Hostile.GetDescription, DrawTargetHostile },
{ UiString.ConfigWindow_List_TargetPriority.GetDescription, DrawTargetPriority },
});

/// <summary>
Expand Down Expand Up @@ -438,6 +441,44 @@ void Down()
(Down, new[] { VirtualKey.DOWN }));
}
}

private static void DrawTargetPriority()
{
// Convert HashSet<uint> to string[] for ImGui input
var prioIdSet = OtherConfiguration.PrioTargetId;
string[] prioId = prioIdSet.Select(id => id.ToString()).ToArray();

// Begin new column for Prioritized Target Names
ImGui.TableNextColumn();
ImGui.TextWrapped(UiString.ConfigWindow_List_PrioTargetDesc.GetDescription());

// List all DataIds in the current list
ImGui.Text("Current Priority DataIds:");
foreach (var id in prioIdSet)
{
ImGui.Text(id.ToString());
}

ImGui.TableNextColumn();
if (ImGui.Button("Reset and Update Target Priority List"))
{
OtherConfiguration.ResetPrioTargetId();
}

// Render a button to add the DataId of the current target
if (ImGui.Button("Add Current Target"))
{
var currentTarget = Svc.Targets.Target;
if (currentTarget != null)
{
uint dataId = currentTarget.DataId;
PriorityTargetHelper.AddPriorityTarget(dataId);
prioIdSet.Add(dataId);
OtherConfiguration.PrioTargetId = prioIdSet;
OtherConfiguration.SavePrioTargetId();
}
}
}
#endregion

#region Extra
Expand Down
Loading

0 comments on commit 4492670

Please sign in to comment.