Check delineations, enforce synth helper max display count
This commit is contained in:
@@ -188,9 +188,11 @@ public partial class Configuration
|
|||||||
public bool SuggestMacroAutomatically { get; set; }
|
public bool SuggestMacroAutomatically { get; set; }
|
||||||
public bool ShowCommunityMacros { get; set; } = true;
|
public bool ShowCommunityMacros { get; set; } = true;
|
||||||
public bool SearchCommunityMacroAutomatically { get; set; }
|
public bool SearchCommunityMacroAutomatically { get; set; }
|
||||||
public int SynthHelperStepCount { get; set; } = 3;
|
public int SynthHelperStepCount { get; set; } = 1;
|
||||||
|
public int SynthHelperMaxDisplayCount { get; set; } = 5;
|
||||||
public bool SynthHelperDisplayOnlyFirstStep { get; set; }
|
public bool SynthHelperDisplayOnlyFirstStep { get; set; }
|
||||||
public bool SynthHelperAbilityAnts { get; set; }
|
public bool SynthHelperAbilityAnts { get; set; }
|
||||||
|
public bool CheckDelineations { get; set; } = true;
|
||||||
|
|
||||||
public bool PinSynthHelperToWindow { get; set; } = true;
|
public bool PinSynthHelperToWindow { get; set; } = true;
|
||||||
public bool PinRecipeNoteToWindow { get; set; } = true;
|
public bool PinRecipeNoteToWindow { get; set; } = true;
|
||||||
|
|||||||
@@ -98,10 +98,10 @@ public static unsafe class Gearsets
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
|
public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation, bool checkDelineations) =>
|
||||||
CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation);
|
CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation, checkDelineations);
|
||||||
|
|
||||||
public static CharacterStats CalculateCharacterStats(GearsetStats gearsetStats, GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
|
public static CharacterStats CalculateCharacterStats(GearsetStats gearsetStats, GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation, bool checkDelineations) =>
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
CP = gearsetStats.CP,
|
CP = gearsetStats.CP,
|
||||||
@@ -110,9 +110,12 @@ public static unsafe class Gearsets
|
|||||||
Level = characterLevel,
|
Level = characterLevel,
|
||||||
CanUseManipulation = canUseManipulation,
|
CanUseManipulation = canUseManipulation,
|
||||||
HasSplendorousBuff = gearsetItems.Any(IsSplendorousTool),
|
HasSplendorousBuff = gearsetItems.Any(IsSplendorousTool),
|
||||||
IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal),
|
IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal) && (!checkDelineations || HasDelineations()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static bool HasDelineations() =>
|
||||||
|
InventoryManager.Instance()->GetInventoryItemCount(28724) > 0;
|
||||||
|
|
||||||
public static bool IsItem(GearsetItem item, uint itemId) =>
|
public static bool IsItem(GearsetItem item, uint itemId) =>
|
||||||
item.ItemId == itemId;
|
item.ItemId == itemId;
|
||||||
|
|
||||||
|
|||||||
@@ -213,10 +213,13 @@ internal sealed class SimulatedMacro
|
|||||||
TryRecalculateFrom(Math.Min(fromIdx, toIdx));
|
TryRecalculateFrom(Math.Min(fromIdx, toIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Enqueue(ActionType action)
|
public int Enqueue(ActionType action, int? maxSize = null)
|
||||||
{
|
{
|
||||||
lock (QueueLock)
|
lock (QueueLock)
|
||||||
{
|
{
|
||||||
|
if (maxSize is { } size && QueuedSteps.Count + Macro.Count >= size)
|
||||||
|
return size;
|
||||||
|
|
||||||
QueuedSteps.Add(new(action));
|
QueuedSteps.Add(new(action));
|
||||||
return QueuedSteps.Count + Macro.Count;
|
return QueuedSteps.Count + Macro.Count;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
|
|||||||
|
|
||||||
gearItems = Gearsets.GetGearsetItems(container);
|
gearItems = Gearsets.GetGearsetItems(container);
|
||||||
|
|
||||||
var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation());
|
var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation(), Service.Configuration.CheckDelineations);
|
||||||
if (characterStats != CharacterStats)
|
if (characterStats != CharacterStats)
|
||||||
{
|
{
|
||||||
CharacterStats = characterStats;
|
CharacterStats = characterStats;
|
||||||
|
|||||||
@@ -96,10 +96,10 @@ public sealed class Settings : Window, IDisposable
|
|||||||
private static void DrawOption(string label, string tooltip, string value, Action<string> setter, ref bool isDirty)
|
private static void DrawOption(string label, string tooltip, string value, Action<string> setter, ref bool isDirty)
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(OptionWidth);
|
ImGui.SetNextItemWidth(OptionWidth);
|
||||||
var text = value.ToString();
|
var text = value;
|
||||||
if (ImGui.InputText(label, ref text, 255, ImGuiInputTextFlags.AutoSelectAll))
|
if (ImGui.InputText(label, ref text, 255, ImGuiInputTextFlags.AutoSelectAll))
|
||||||
{
|
{
|
||||||
if (value != text)
|
if (!string.Equals(value, text, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
setter(text);
|
setter(text);
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
@@ -223,6 +223,15 @@ public sealed class Settings : Window, IDisposable
|
|||||||
ref isDirty
|
ref isDirty
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DrawOption(
|
||||||
|
"Check For Delineations",
|
||||||
|
"Your inventory will be checked to ensure that you have delineations available " +
|
||||||
|
"before suggesting any specialist acitons.",
|
||||||
|
Config.CheckDelineations,
|
||||||
|
v => Config.CheckDelineations = v,
|
||||||
|
ref isDirty
|
||||||
|
);
|
||||||
|
|
||||||
DrawOption(
|
DrawOption(
|
||||||
"Reliability Trial Count",
|
"Reliability Trial Count",
|
||||||
"When testing for reliability of a macro in the editor, this many trials will be " +
|
"When testing for reliability of a macro in the editor, this many trials will be " +
|
||||||
@@ -943,8 +952,9 @@ public sealed class Settings : Window, IDisposable
|
|||||||
);
|
);
|
||||||
|
|
||||||
DrawOption(
|
DrawOption(
|
||||||
"Step Count",
|
"Solver Step Count",
|
||||||
"The minimum number of future steps to solve for during an in-game craft.",
|
"The minimum number of future steps to solve for during an in-game craft. " +
|
||||||
|
"The solver may still give more than this amount if it's at no cost to you.",
|
||||||
Config.SynthHelperStepCount,
|
Config.SynthHelperStepCount,
|
||||||
1,
|
1,
|
||||||
100,
|
100,
|
||||||
@@ -952,6 +962,17 @@ public sealed class Settings : Window, IDisposable
|
|||||||
ref isDirty
|
ref isDirty
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DrawOption(
|
||||||
|
"Max Step Display Count",
|
||||||
|
"Enforces a maximum number of steps to display in the synth helper to " +
|
||||||
|
"get rid of clutter.",
|
||||||
|
Config.SynthHelperMaxDisplayCount,
|
||||||
|
1,
|
||||||
|
100,
|
||||||
|
v => Config.SynthHelperMaxDisplayCount = v,
|
||||||
|
ref isDirty
|
||||||
|
);
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
|||||||
@@ -66,10 +66,9 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
private SimulationState currentState;
|
private SimulationState currentState;
|
||||||
private SimulatedMacro Macro { get; } = new();
|
private SimulatedMacro Macro { get; } = new();
|
||||||
|
|
||||||
private CancellationTokenSource? HelperTaskTokenSource { get; set; }
|
private BackgroundTask<int>? SolverTask { get; set; }
|
||||||
private Exception? HelperTaskException { get; set; }
|
private bool SolverRunning => (!SolverTask?.Completed) ?? false;
|
||||||
private Solver.Solver? HelperTaskObject { get; set; }
|
private Solver.Solver? SolverObject { get; set; }
|
||||||
private bool HelperTaskRunning => HelperTaskTokenSource != null;
|
|
||||||
|
|
||||||
private IFontHandle AxisFont { get; }
|
private IFontHandle AxisFont { get; }
|
||||||
|
|
||||||
@@ -124,7 +123,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
if (WasCalculatable)
|
if (WasCalculatable)
|
||||||
{
|
{
|
||||||
IsCrafting = false;
|
IsCrafting = false;
|
||||||
HelperTaskTokenSource?.Cancel();
|
SolverTask?.Cancel();
|
||||||
}
|
}
|
||||||
else if (Macro.Count == 0)
|
else if (Macro.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -263,7 +262,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
|
|
||||||
DrawMacroActions();
|
DrawMacroActions();
|
||||||
|
|
||||||
if (HelperTaskRunning && HelperTaskObject is { } solver)
|
if (SolverRunning && SolverObject is { } solver)
|
||||||
{
|
{
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
DrawHelperTaskProgress(solver);
|
DrawHelperTaskProgress(solver);
|
||||||
@@ -334,7 +333,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
lastState = state;
|
lastState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rows = (int)Math.Max(1, MathF.Ceiling(Service.Configuration.SynthHelperStepCount / itemsPerRow));
|
var rows = (int)Math.Max(1, MathF.Ceiling(Service.Configuration.SynthHelperMaxDisplayCount / itemsPerRow));
|
||||||
for (var i = 0; i < rows; ++i)
|
for (var i = 0; i < rows; ++i)
|
||||||
{
|
{
|
||||||
if (count <= i * itemsPerRow)
|
if (count <= i * itemsPerRow)
|
||||||
@@ -452,9 +451,9 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
|
|
||||||
private void DrawMacroActions()
|
private void DrawMacroActions()
|
||||||
{
|
{
|
||||||
if (HelperTaskRunning)
|
if (SolverRunning)
|
||||||
{
|
{
|
||||||
if (HelperTaskTokenSource?.IsCancellationRequested ?? false)
|
if (SolverTask?.Cancelling ?? false)
|
||||||
{
|
{
|
||||||
using var _disabled = ImRaii.Disabled();
|
using var _disabled = ImRaii.Disabled();
|
||||||
ImGui.Button("Stopping", new(-1, 0));
|
ImGui.Button("Stopping", new(-1, 0));
|
||||||
@@ -464,7 +463,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ImGui.Button("Stop", new(-1, 0)))
|
if (ImGui.Button("Stop", new(-1, 0)))
|
||||||
HelperTaskTokenSource?.Cancel();
|
SolverTask?.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -511,7 +510,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
|
|
||||||
var gearItems = Gearsets.GetGearsetItems(container);
|
var gearItems = Gearsets.GetGearsetItems(container);
|
||||||
|
|
||||||
var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation());
|
var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation(), Service.Configuration.CheckDelineations);
|
||||||
if (characterStats != CharacterStats)
|
if (characterStats != CharacterStats)
|
||||||
{
|
{
|
||||||
CharacterStats = characterStats;
|
CharacterStats = characterStats;
|
||||||
@@ -606,9 +605,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
|
|
||||||
private void CalculateBestMacro()
|
private void CalculateBestMacro()
|
||||||
{
|
{
|
||||||
HelperTaskTokenSource?.Cancel();
|
SolverTask?.Cancel();
|
||||||
HelperTaskTokenSource = new();
|
|
||||||
HelperTaskException = null;
|
|
||||||
Macro.ClearQueue();
|
Macro.ClearQueue();
|
||||||
Macro.Clear();
|
Macro.Clear();
|
||||||
|
|
||||||
@@ -619,55 +616,34 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
Macro.RecalculateState();
|
Macro.RecalculateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = HelperTaskTokenSource.Token;
|
|
||||||
var state = CurrentState;
|
var state = CurrentState;
|
||||||
var task = Task.Run(() => CalculateBestMacroTask(state, token), token);
|
SolverTask = new(token => CalculateBestMacroTask(state, token));
|
||||||
_ = task.ContinueWith(t =>
|
SolverTask.Start();
|
||||||
{
|
|
||||||
if (token == HelperTaskTokenSource.Token)
|
|
||||||
{
|
|
||||||
HelperTaskTokenSource = null;
|
|
||||||
HelperTaskObject = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_ = task.ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (token.IsCancellationRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
t.Exception!.Flatten().Handle(ex => ex is TaskCanceledException or OperationCanceledException);
|
|
||||||
}
|
|
||||||
catch (AggregateException e)
|
|
||||||
{
|
|
||||||
HelperTaskException = e;
|
|
||||||
Log.Error(e, "Calculating macro failed");
|
|
||||||
}
|
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateBestMacroTask(SimulationState state, CancellationToken token)
|
private int CalculateBestMacroTask(SimulationState state, CancellationToken token)
|
||||||
{
|
{
|
||||||
var config = Service.Configuration.SynthHelperSolverConfig;
|
var config = Service.Configuration.SynthHelperSolverConfig;
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
using (HelperTaskObject = new Solver.Solver(config, state) { Token = token })
|
var solver = new Solver.Solver(config, state) { Token = token };
|
||||||
{
|
solver.OnLog += Log.Debug;
|
||||||
HelperTaskObject.OnLog += Log.Debug;
|
solver.OnNewAction += EnqueueAction;
|
||||||
HelperTaskObject.OnNewAction += EnqueueAction;
|
SolverObject = solver;
|
||||||
HelperTaskObject.Start();
|
solver.Start();
|
||||||
_ = HelperTaskObject.GetTask().GetAwaiter().GetResult();
|
_ = solver.GetTask().GetAwaiter().GetResult();
|
||||||
}
|
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnqueueAction(ActionType action)
|
private void EnqueueAction(ActionType action)
|
||||||
{
|
{
|
||||||
if (Macro.Enqueue(action) >= Service.Configuration.SynthHelperStepCount)
|
var newSize = Macro.Enqueue(action, Service.Configuration.SynthHelperMaxDisplayCount);
|
||||||
HelperTaskTokenSource?.Cancel();
|
if (newSize >= Service.Configuration.SynthHelperStepCount || newSize >= Service.Configuration.SynthHelperMaxDisplayCount)
|
||||||
|
SolverTask?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Sim CreateSim(in SimulationState state) =>
|
private static Sim CreateSim(in SimulationState state) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user