Refactor and move around config/settings window

This commit is contained in:
Asriel Camora
2024-03-22 23:59:00 -07:00
parent 28c271c714
commit 895e2a4460
7 changed files with 189 additions and 97 deletions
+6 -1
View File
@@ -85,10 +85,15 @@ public class Configuration : IPluginConfiguration
public IReadOnlyList<Macro> Macros => macros;
public int ReliabilitySimulationCount { get; set; } = 500;
public bool ConditionRandomness { get; set; } = true;
[JsonConverter(typeof(PopulateConverter))]
public SolverConfig SimulatorSolverConfig { get; set; } = SolverConfig.SimulatorDefault;
[JsonProperty(PropertyName = "SimulatorSolverConfig")]
public SolverConfig RecipeNoteSolverConfig { get; set; } = SolverConfig.RecipeNoteDefault;
[JsonConverter(typeof(PopulateConverter))]
public SolverConfig EditorSolverConfig { get; set; } = SolverConfig.EditorDefault;
[JsonConverter(typeof(PopulateConverter))]
public SolverConfig SynthHelperSolverConfig { get; set; } = SolverConfig.SynthHelperDefault;
public bool EnableSynthHelper { get; set; } = true;
public bool DisableSynthHelperOnMacro { get; set; } = true;
public bool ShowOptimalMacroStat { get; set; } = true;
+1 -1
View File
@@ -1603,7 +1603,7 @@ public sealed class MacroEditor : Window, IDisposable
private void CalculateBestMacroTask(SimulationState state, CancellationToken token)
{
var config = Service.Configuration.SimulatorSolverConfig;
var config = Service.Configuration.EditorSolverConfig;
token.ThrowIfCancellationRequested();
+1 -1
View File
@@ -239,7 +239,7 @@ public sealed class MacroList : Window, IDisposable
if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.Edit, miniRowHeight))
OpenEditor(macro);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip("Open in Simulator");
ImGuiUtils.Tooltip("Open in Macro Editor");
ImGui.SameLine(0, spacing);
if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.PencilAlt, miniRowHeight))
ShowRenamePopup(macro);
+5 -5
View File
@@ -400,7 +400,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
if (ImGui.Button("View Saved Macros", new(availWidth, 0)))
Service.Plugin.OpenMacroListWindow();
if (ImGui.Button("Open in Simulator", new(availWidth, 0)))
if (ImGui.Button("Open in Macro Editor", new(availWidth, 0)))
Service.Plugin.OpenMacroEditor(CharacterStats!, RecipeData!, new(Service.ClientState.LocalPlayer!.StatusList), Enumerable.Empty<ActionType>(), null);
}
@@ -932,7 +932,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.Edit, miniRowHeight))
Service.Plugin.OpenMacroEditor(CharacterStats!, RecipeData!, new(Service.ClientState.LocalPlayer!.StatusList), actions, state.MacroEditorSetter);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip("Open in Simulator");
ImGuiUtils.Tooltip("Open in Macro Editor");
if (ImGuiUtils.IconButtonSquare(FontAwesomeIcon.Paste, miniRowHeight))
Service.Plugin.CopyMacro(actions);
if (ImGui.IsItemHovered())
@@ -1085,7 +1085,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo);
var state = new SimulationState(input);
var config = Service.Configuration.SimulatorSolverConfig;
var config = Service.Configuration.RecipeNoteSolverConfig;
var mctsConfig = new MCTSConfig(config);
var simulator = new SimulatorNoRandom();
List<Macro> macros = new(Service.Configuration.Macros);
@@ -1116,7 +1116,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo);
var state = new SimulationState(input);
var config = Service.Configuration.SimulatorSolverConfig;
var config = Service.Configuration.RecipeNoteSolverConfig;
token.ThrowIfCancellationRequested();
@@ -1140,7 +1140,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo);
var state = new SimulationState(input);
var config = Service.Configuration.SimulatorSolverConfig;
var config = Service.Configuration.RecipeNoteSolverConfig;
var mctsConfig = new MCTSConfig(config);
var simulator = new SimulatorNoRandom();
var macros = Service.CommunityMacros.RetrieveRotations(input.Recipe.RLvl, token).GetAwaiter().GetResult();
+80 -53
View File
@@ -165,7 +165,8 @@ public sealed class Settings : Window, IDisposable
if (ImGui.BeginTabBar("settingsTabBar"))
{
DrawTabGeneral();
DrawTabSimulator();
DrawTabRecipeNote();
DrawTabMacroEditor();
if (Config.EnableSynthHelper)
DrawTabSynthHelper();
DrawTabAbout();
@@ -194,51 +195,6 @@ public sealed class Settings : Window, IDisposable
ref isDirty
);
DrawOption(
"Pin Crafting Log Window",
"Pins the helper window to the right of your crafting log. Disabling this will " +
"allow you to move it around.",
Config.PinRecipeNoteToWindow,
v => Config.PinRecipeNoteToWindow = v,
ref isDirty
);
DrawOption(
"Automatically Suggest Macro in Crafting Log",
"(Can cause frame drops!) When navigating to a new recipe or changing your gear " +
"stats, automatically suggest a new macro (equivalent to clicking \"Generate\" " +
"in the Macro Editor). This can cause harsh frame drops on some computers or " +
"recipes when underleveled while navigating the crafting log. Turning this off " +
"provides a button to allow you to manually suggest a macro only when you need it.",
Config.SuggestMacroAutomatically,
v => Config.SuggestMacroAutomatically = v,
ref isDirty
);
DrawOption(
"Enable Community Macros in Crafting Log",
"Use FFXIV Teamcraft's community rotations to search for and find the best possible" +
"crowd-sourced macro for your craft. This sends a request to their servers to retrieve " +
"a list of macros that apply to your craft's rlvl. Requests are only sent once per rlvl " +
"and are always cached to reduce server load.",
Config.ShowCommunityMacros,
v => Config.ShowCommunityMacros = v,
ref isDirty
);
if (Config.ShowCommunityMacros)
{
DrawOption(
"Automatically Search for Community Macro",
"When navigating to a new recipe or changing your gear stats, automatically search " +
"online for a new community macro.\n" +
"This is turned off by default so you don't hammer their servers :)",
Config.SearchCommunityMacroAutomatically,
v => Config.SearchCommunityMacroAutomatically = v,
ref isDirty
);
}
DrawOption(
"Show Only One Macro Stat in Crafting Log",
"Only one stat will be shown for a macro. If a craft will be finished, quality " +
@@ -470,7 +426,7 @@ public sealed class Settings : Window, IDisposable
"as necessary to get a more favorable outcome.",
config.Iterations,
1000,
500000,
1000000,
v => config = config with { Iterations = v },
ref isDirty
);
@@ -809,9 +765,9 @@ public sealed class Settings : Window, IDisposable
}
}
private void DrawTabSimulator()
private void DrawTabRecipeNote()
{
using var tab = TabItem("Simulator");
using var tab = TabItem("Crafting Log");
if (!tab)
return;
@@ -819,11 +775,82 @@ public sealed class Settings : Window, IDisposable
var isDirty = false;
var solverConfig = Config.SimulatorSolverConfig;
DrawSolverConfig(ref solverConfig, SolverConfig.SimulatorDefault, out var isSolverDirty);
DrawOption(
"Pin Helper Window",
"Pins the helper window to the right of your crafting log. Disabling this will " +
"allow you to move it around.",
Config.PinRecipeNoteToWindow,
v => Config.PinRecipeNoteToWindow = v,
ref isDirty
);
DrawOption(
"Automatically Suggest Macro",
"(Can cause frame drops!) When navigating to a new recipe or changing your gear " +
"stats, automatically suggest a new macro (equivalent to clicking \"Generate\" " +
"in the Macro Editor). This can cause harsh frame drops on some computers or " +
"recipes when underleveled while navigating the crafting log. Turning this off " +
"provides a button to allow you to manually suggest a macro only when you need it.",
Config.SuggestMacroAutomatically,
v => Config.SuggestMacroAutomatically = v,
ref isDirty
);
DrawOption(
"Enable Community Macros",
"Use FFXIV Teamcraft's community rotations to search for and find the best possible " +
"crowd-sourced macro for your craft. This sends a request to their servers to retrieve " +
"a list of macros that apply to your craft's rlvl. Requests are only sent once per rlvl " +
"and are always cached to reduce server load.",
Config.ShowCommunityMacros,
v => Config.ShowCommunityMacros = v,
ref isDirty
);
if (Config.ShowCommunityMacros)
{
DrawOption(
"Automatically Search for Community Macro",
"When navigating to a new recipe or changing your gear stats, automatically search " +
"online for a new community macro.\n" +
"This is turned off by default so you don't hammer their servers :)",
Config.SearchCommunityMacroAutomatically,
v => Config.SearchCommunityMacroAutomatically = v,
ref isDirty
);
}
ImGuiHelpers.ScaledDummy(5);
ImGui.Separator();
ImGuiHelpers.ScaledDummy(5);
var solverConfig = Config.RecipeNoteSolverConfig;
DrawSolverConfig(ref solverConfig, SolverConfig.RecipeNoteDefault, out var isSolverDirty);
if (isSolverDirty)
{
Config.SimulatorSolverConfig = solverConfig;
Config.RecipeNoteSolverConfig = solverConfig;
isDirty = true;
}
if (isDirty)
Config.Save();
}
private void DrawTabMacroEditor()
{
using var tab = TabItem("Macro Editor");
if (!tab)
return;
ImGuiHelpers.ScaledDummy(5);
var isDirty = false;
var solverConfig = Config.EditorSolverConfig;
DrawSolverConfig(ref solverConfig, SolverConfig.EditorDefault, out var isSolverDirty);
if (isSolverDirty)
{
Config.EditorSolverConfig = solverConfig;
isDirty = true;
}
@@ -842,7 +869,7 @@ public sealed class Settings : Window, IDisposable
var isDirty = false;
DrawOption(
"Pin Window",
"Pin Helper Window",
"Pins the synthesis helper to the right of your synthesis window. Disabling this will " +
"allow you to move it around.",
Config.PinSynthHelperToWindow,
+1 -1
View File
@@ -426,7 +426,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
"can vary wildly depending on the solver's settings.");
}
if (ImGui.Button("Open in Simulator", new(-1, 0)))
if (ImGui.Button("Open in Macro Editor", new(-1, 0)))
Service.Plugin.OpenMacroEditor(CharacterStats!, RecipeData!, new(Service.ClientState.LocalPlayer!.StatusList), Enumerable.Empty<ActionType>(), null);
}
+91 -31
View File
@@ -1,4 +1,5 @@
using Craftimizer.Simulator.Actions;
using System.Collections.Frozen;
using System.Runtime.InteropServices;
namespace Craftimizer.Solver;
@@ -37,7 +38,7 @@ public readonly record struct SolverConfig
public SolverConfig()
{
Iterations = 100000;
Iterations = 100_000;
ScoreStorageThreshold = 1f;
MaxScoreWeightingConstant = 0.1f;
ExplorationConstant = 4;
@@ -56,63 +57,122 @@ public readonly record struct SolverConfig
ScoreCP = .05f;
ScoreSteps = .05f;
ActionPool = DefaultActionPool;
ActionPool = DeterministicActionPool;
Algorithm = SolverAlgorithm.StepwiseFurcated;
}
public static ActionType[] OptimizeActionPool(IEnumerable<ActionType> actions) =>
actions.Order().ToArray();
public static readonly ActionType[] DefaultActionPool = OptimizeActionPool(new[]
public static readonly ActionType[] DeterministicActionPool = OptimizeActionPool(new[]
{
ActionType.MuscleMemory,
ActionType.Reflect,
ActionType.TrainedEye,
ActionType.BasicSynthesis,
ActionType.CarefulSynthesis,
ActionType.FocusedSynthesis,
ActionType.Groundwork,
ActionType.DelicateSynthesis,
ActionType.PrudentSynthesis,
ActionType.BasicTouch,
ActionType.StandardTouch,
ActionType.ByregotsBlessing,
ActionType.PrudentTouch,
ActionType.FocusedTouch,
ActionType.PreparatoryTouch,
ActionType.AdvancedTouch,
ActionType.TrainedFinesse,
ActionType.MastersMend,
ActionType.WasteNot,
ActionType.WasteNot2,
ActionType.Manipulation,
ActionType.Veneration,
ActionType.GreatStrides,
ActionType.Innovation,
ActionType.Observe,
ActionType.StandardTouchCombo,
ActionType.AdvancedTouchCombo,
ActionType.FocusedTouchCombo,
ActionType.FocusedSynthesisCombo,
ActionType.TrainedFinesse,
ActionType.PrudentSynthesis,
ActionType.Groundwork,
ActionType.AdvancedTouch,
ActionType.CarefulSynthesis,
ActionType.TrainedEye,
ActionType.DelicateSynthesis,
ActionType.PreparatoryTouch,
ActionType.Reflect,
ActionType.PrudentTouch,
ActionType.Manipulation,
ActionType.MuscleMemory,
ActionType.ByregotsBlessing,
ActionType.WasteNot2,
ActionType.BasicSynthesis,
ActionType.Innovation,
ActionType.GreatStrides,
ActionType.StandardTouch,
ActionType.Veneration,
ActionType.WasteNot,
ActionType.MastersMend,
ActionType.BasicTouch,
});
public static readonly IReadOnlySet<ActionType> InefficientActions = new HashSet<ActionType>(new[]
// Same as deterministic, but with condition-specific actions added
public static readonly ActionType[] RandomizedActionPool = OptimizeActionPool(new[]
{
ActionType.MuscleMemory,
ActionType.Reflect,
ActionType.TrainedEye,
ActionType.BasicSynthesis,
ActionType.CarefulSynthesis,
ActionType.FocusedSynthesis,
ActionType.Groundwork,
ActionType.DelicateSynthesis,
ActionType.IntensiveSynthesis,
ActionType.PrudentSynthesis,
ActionType.BasicTouch,
ActionType.StandardTouch,
ActionType.ByregotsBlessing,
ActionType.PreciseTouch,
ActionType.PrudentTouch,
ActionType.FocusedTouch,
ActionType.PreparatoryTouch,
ActionType.AdvancedTouch,
ActionType.TrainedFinesse,
ActionType.MastersMend,
ActionType.WasteNot,
ActionType.WasteNot2,
ActionType.Manipulation,
ActionType.Veneration,
ActionType.GreatStrides,
ActionType.Innovation,
ActionType.Observe,
ActionType.TricksOfTheTrade,
ActionType.StandardTouchCombo,
ActionType.AdvancedTouchCombo,
ActionType.FocusedTouchCombo,
ActionType.FocusedSynthesisCombo,
});
public static readonly FrozenSet<ActionType> InefficientActions =
new[]
{
ActionType.CarefulObservation,
ActionType.HeartAndSoul,
ActionType.FinalAppraisal
});
}.ToFrozenSet();
public static readonly IReadOnlySet<ActionType> RiskyActions = new HashSet<ActionType>(new[]
public static readonly FrozenSet<ActionType> RiskyActions =
new[]
{
ActionType.RapidSynthesis,
ActionType.HastyTouch,
});
}.ToFrozenSet();
public static readonly SolverConfig SimulatorDefault = new SolverConfig() with
public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with
{
};
public static readonly SolverConfig EditorDefault = new SolverConfig() with
{
Iterations = 500000
};
public static readonly SolverConfig SynthHelperDefault = new SolverConfig() with
{
// Add properties if necessary
ActionPool = RandomizedActionPool
};
}