Skip to content

Commit

Permalink
Multi action support (#15)
Browse files Browse the repository at this point in the history
* Update README
* Add GitHub actions
  • Loading branch information
herulume authored Jul 24, 2024
1 parent fffc313 commit 9121064
Show file tree
Hide file tree
Showing 14 changed files with 1,336 additions and 1,244 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ReleaseCheck.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ jobs:
- name: Build
run: |
dotnet build --no-restore --configuration Release
- name: Tests
run: |
dotnet test
3 changes: 3 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ jobs:
- name: Build
run: |
dotnet build --no-restore --configuration Release
- name: Tests
run: |
dotnet test
66 changes: 63 additions & 3 deletions OpenerCreator/Actions/GroupOfActions.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dalamud.Interface.Textures;
using OpenerCreator.Helpers;

namespace OpenerCreator.Actions;

public readonly struct GroupOfActions(string name, string iconLocation, IEnumerable<uint> actions, bool isGCD = true)
public readonly struct GroupOfActions(int id, string name, Jobs job, IEnumerable<uint> actions, bool isGCD = true)

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'job' is unread.

Check warning on line 9 in OpenerCreator/Actions/GroupOfActions.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isGCD' is unread.
{
public ISharedImmediateTexture texture => OpenerCreator.TextureProvider.GetFromGame(iconLocation);
public ISharedImmediateTexture texture => throw new NotImplementedException();

public bool isMember(uint a)
public bool IsMember(uint a)
{
return actions.Contains(a);
}

public bool HasId(int i)
{
return id == i;
}

public static IEnumerable<GroupOfActions> DefaultGroups()
{
return new[]
{
new GroupOfActions(
-1,
"Dancer Steps",
Jobs.DNC,
new List<uint>
{
15999, // Emboite
16000, // Entrechat
160001, // Jete
160002 // Pirouette
}
),
new GroupOfActions(
-2,
"Mudras",
Jobs.NIN,
new List<uint>
{
2259, // Ten
18805, // Ten
2261, // Chi
18806, // Chi
2263, // Jin
18807 // Jin
}
),
new GroupOfActions(
-3,
"Refulgent Arrow Proc",
Jobs.BRD,
new List<uint>
{
16495, // Burst Shot
7409 // Refulgent Arrow
}
),
new GroupOfActions(
-4,
"Venthunder/Veraero",
Jobs.RDM,
new List<uint>
{
25855, // Verthunder III
25855 // Veraero III
}
)
};
}
}
17 changes: 4 additions & 13 deletions OpenerCreator/Actions/PvEActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public class PvEActions : IActionManager
private static readonly object LockObject = new();
private readonly IEnumerable<LuminaAction> actionsSheet;
private readonly Dictionary<uint, LuminaAction> actionsSheetDictionary;
private readonly IEnumerable<GroupOfActions> groupOfActions;

private PvEActions()
{
Expand All @@ -22,14 +21,6 @@ private PvEActions()
.ToList();
actionsSheetDictionary = pve.ToDictionary(a => a.RowId);
actionsSheet = pve;
groupOfActions = new[]
{
new GroupOfActions(
"Dancer Steps",
"lmao",
new List<uint> { 1, 2, 3, 4, 5 }
)
};
}

public static uint TrueNorthId => 7546;
Expand Down Expand Up @@ -62,11 +53,11 @@ public bool SameActionsByName(string name, uint aId)
return GetActionName(aId).Contains(name, StringComparison.CurrentCultureIgnoreCase);
}

public List<uint> ActionsIdList(ActionTypes actionType)
public List<int> ActionsIdList(ActionTypes actionType)
{
return actionsSheet
.Where(a => ActionTypesExtension.GetType(a) == actionType || actionType == ActionTypes.ANY)
.Select(a => a.RowId)
.Select(a => (int)a.RowId)
.ToList();
}

Expand All @@ -83,7 +74,7 @@ public LuminaAction GetAction(uint id)
}


public List<uint> GetNonRepeatedActionsByName(string name, Jobs job, ActionTypes actionType)
public List<int> GetNonRepeatedActionsByName(string name, Jobs job, ActionTypes actionType)
{
return actionsSheet
.AsParallel()
Expand All @@ -94,7 +85,7 @@ public List<uint> GetNonRepeatedActionsByName(string name, Jobs job, ActionTypes
&& a.ClassJobCategory.Value.Name.ToString().Contains(job.ToString()))
|| job == Jobs.ANY)
)
.Select(a => a.RowId)
.Select(a => (int)a.RowId)
.OrderBy(id => id)
.ToList();
}
Expand Down
16 changes: 8 additions & 8 deletions OpenerCreator/Helpers/LoadedActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace OpenerCreator.Helpers;
internal class LoadedActions
{
private readonly HashSet<int> wrongActionsIndex = [];
private List<uint> actions = [];
public string Name = ""; // needs to be public for ImGui refs
private List<int> actions = []; // int instead of uint until c# has tagged unions
public string Name = ""; // needs to be public for ImGui refs


internal bool IsWrongActionAt(int i)
Expand All @@ -31,12 +31,12 @@ internal int ActionsCount()
return actions.Count;
}

internal uint GetActionAt(int i)
internal int GetActionAt(int i)
{
return actions[i];
}

internal void AddAction(uint action)
internal void AddAction(int action)
{
actions.Add(action);
}
Expand All @@ -46,12 +46,12 @@ internal void RemoveActionAt(int i)
actions.RemoveAt(i);
}

internal void InsertActionAt(int i, uint action)
internal void InsertActionAt(int i, int action)
{
actions.Insert(i, action);
}

internal List<uint> GetActionsByRef()
internal List<int> GetActionsByRef()
{
return actions;
}
Expand All @@ -61,7 +61,7 @@ internal void ClearActions()
actions.Clear();
}

internal void AddActionsByRef(List<uint> l)
internal void AddActionsByRef(List<int> l)
{
actions = l;
}
Expand All @@ -73,6 +73,6 @@ internal bool HasName()

public bool HasTrueNorth()
{
return actions.Contains(PvEActions.TrueNorthId);
return actions.Contains((int)PvEActions.TrueNorthId);
}
}
10 changes: 5 additions & 5 deletions OpenerCreator/Hooks/OnUsedActionHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class UsedActionHook : IDisposable
private const int MaxItemCount = 50;

private readonly ExcelSheet<LuminaAction>? sheet = OpenerCreator.DataManager.GetExcelSheet<LuminaAction>();
private readonly List<uint> used = new(MaxItemCount);
private readonly List<int> used = new(MaxItemCount);
private readonly Hook<UsedActionDelegate>? usedActionHook;
private bool ignoreTrueNorth;

Expand Down Expand Up @@ -82,8 +82,8 @@ private void DetourUsedAction(
var player = OpenerCreator.ClientState.LocalPlayer;
if (player == null || sourceId != player.EntityId) return;

var actionId = (uint)Marshal.ReadInt32(effectHeader, 0x8);
var action = sheet!.GetRow(actionId);
var actionId = Marshal.ReadInt32(effectHeader, 0x8);
var action = sheet!.GetRow((uint)actionId);
var isActionTrueNorth = actionId == PvEActions.TrueNorthId;
var analyseWhenTrueNorth = !(ignoreTrueNorth && isActionTrueNorth); //nand
if (action != null && PvEActions.IsPvEAction(action) && analyseWhenTrueNorth)
Expand All @@ -98,7 +98,7 @@ private void DetourUsedAction(
var loadedLength = OpenerManager.Instance.Loaded.Count;
var index = loadedLength - nActions;
var intendedAction = OpenerManager.Instance.Loaded[index];
var intendedName = PvEActions.Instance.GetActionName(intendedAction);
var intendedName = PvEActions.Instance.GetActionName((uint)intendedAction);
if (OpenerCreator.Config.StopAtFirstMistake &&
!OpenerManager.Instance.AreActionsEqual(intendedAction, intendedName, actionId)
)
Expand All @@ -107,7 +107,7 @@ private void DetourUsedAction(
var f = new Feedback();
f.AddMessage(
Feedback.MessageType.Error,
$"Difference in action {index + 1}: Substituted {intendedName} for {PvEActions.Instance.GetActionName(actionId)}"
$"Difference in action {index + 1}: Substituted {intendedName} for {PvEActions.Instance.GetActionName((uint)actionId)}"
);
provideFeedback(f);
StopRecording();
Expand Down
46 changes: 24 additions & 22 deletions OpenerCreator/Managers/OpenerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class OpenerManager(IActionManager actions)
{
private static OpenerManager? SingletonInstance;
private static readonly object LockObject = new();
private readonly Dictionary<Jobs, Dictionary<string, List<uint>>> defaultOpeners = new();
private readonly Dictionary<Jobs, Dictionary<string, List<uint>>> openers = new();
private readonly Dictionary<Jobs, Dictionary<string, List<int>>> defaultOpeners = new();
private readonly Dictionary<Jobs, Dictionary<string, List<int>>> openers = new();

private OpenerManager(IActionManager actions, ValueTuple _) : this(actions)
{
Expand All @@ -23,7 +23,7 @@ private OpenerManager(IActionManager actions, ValueTuple _) : this(actions)
"openers.json"));
}

public List<uint> Loaded { get; set; } = [];
public List<int> Loaded { get; set; } = [];
private string OpenersFile { get; init; } = "empty";

public static OpenerManager Instance
Expand All @@ -42,28 +42,28 @@ public static OpenerManager Instance
}
}

public void AddOpener(string name, Jobs job, IEnumerable<uint> actions)
public void AddOpener(string name, Jobs job, IEnumerable<int> opener)
{
if (!openers.TryGetValue(job, out var value))
{
value = new Dictionary<string, List<uint>>();
value = new Dictionary<string, List<int>>();
openers[job] = value;
}

value[name] = [..actions];
value[name] = [..opener];
}

public List<Tuple<Jobs, List<string>>> GetDefaultNames()
{
return defaultOpeners.Select(x => Tuple.Create(x.Key, x.Value.Keys.ToList())).ToList();
}

public List<uint> GetDefaultOpener(string name, Jobs job)
public List<int> GetDefaultOpener(string name, Jobs job)
{
return [..defaultOpeners[job][name]];
}

public List<uint> GetOpener(string name, Jobs job)
public List<int> GetOpener(string name, Jobs job)
{
return [..openers[job][name]];
}
Expand All @@ -82,7 +82,7 @@ public void DeleteOpener(string name, Jobs job)
}
}

public void Compare(List<uint> used, Action<Feedback> provideFeedback, Action<int> wrongAction)
public void Compare(List<int> used, Action<Feedback> provideFeedback, Action<int> wrongAction)
{
var feedback = new Feedback();
used = used.Take(Loaded.Count).ToList();
Expand All @@ -106,7 +106,7 @@ public void Compare(List<uint> used, Action<Feedback> provideFeedback, Action<in
{
error = true;
feedback.AddMessage(Feedback.MessageType.Error,
$"Difference in action {i + 1}: Substituted {intended} for {actions.GetActionName(actual)}");
$"Difference in action {i + 1}: Substituted {intended} for {actions.GetActionName((uint)actual)}");
wrongAction(openerIndex);

if (ShouldShift(openerIndex, size, used[i])) shift++;
Expand All @@ -126,40 +126,42 @@ public void Compare(List<uint> used, Action<Feedback> provideFeedback, Action<in
}

private bool AreActionsEqual(
IReadOnlyList<uint> used, int openerIndex, int usedIndex, out string intended, out uint actual)
IReadOnlyList<int> used, int openerIndex, int usedIndex, out string intended, out int actualId)
{
var intendedId = Loaded[openerIndex];
intended = actions.GetActionName(intendedId);
actual = used[usedIndex];
intended = actions.GetActionName((uint)intendedId);
actualId = used[usedIndex];

return AreActionsEqual(intendedId, intended, actual);
return AreActionsEqual(intendedId, intended, actualId);
}

public bool AreActionsEqual(uint intendedId, string intendedName, uint actualId)
public bool AreActionsEqual(int intendedId, string intendedName, int actualId)
{
if (intendedId < 0)
return GroupOfActions.DefaultGroups().First(g => g.HasId(intendedId)).IsMember((uint)actualId);
return intendedId == actualId ||
intendedId == IActionManager.CatchAllActionId ||
actions.SameActionsByName(intendedName, actualId);
actions.SameActionsByName(intendedName, (uint)actualId);
}

private bool ShouldShift(int openerIndex, int size, uint usedValue)
private bool ShouldShift(int openerIndex, int size, int usedValue)
{
var nextIntended = actions.GetActionName(Loaded[openerIndex]);
var nextIntended = actions.GetActionName((uint)Loaded[openerIndex]);
return openerIndex + 1 < size &&
(Loaded[openerIndex + 1] == usedValue || actions.SameActionsByName(nextIntended, usedValue));
(Loaded[openerIndex + 1] == usedValue || actions.SameActionsByName(nextIntended, (uint)usedValue));
}

private static Dictionary<Jobs, Dictionary<string, List<uint>>> LoadOpeners(string path)
private static Dictionary<Jobs, Dictionary<string, List<int>>> LoadOpeners(string path)
{
try
{
var jsonData = File.ReadAllText(path);
return JsonSerializer.Deserialize<Dictionary<Jobs, Dictionary<string, List<uint>>>>(jsonData)!;
return JsonSerializer.Deserialize<Dictionary<Jobs, Dictionary<string, List<int>>>>(jsonData)!;
}
catch (Exception e)
{
OpenerCreator.PluginLog.Error("Failed to load Openers", e);
return new Dictionary<Jobs, Dictionary<string, List<uint>>>();
return new Dictionary<Jobs, Dictionary<string, List<int>>>();
}
}

Expand Down
12 changes: 12 additions & 0 deletions OpenerCreator/OpenerCreator.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Platforms>x64</Platforms>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<Import Project="Dalamud.Plugin.Bootstrap.targets"/>

<PropertyGroup>
Expand All @@ -13,6 +24,7 @@
<IsPackable>false</IsPackable>
</PropertyGroup>


<ItemGroup>
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
Expand Down
Loading

0 comments on commit 9121064

Please sign in to comment.