Fix specialist bug when having no delineations

This commit is contained in:
Asriel Camora
2024-08-06 12:51:44 -07:00
parent fa45ac072e
commit d488b9e797
6 changed files with 40 additions and 12 deletions
+4 -5
View File
@@ -1,5 +1,4 @@
using Craftimizer.Simulator; using Craftimizer.Simulator;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI; using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Misc; using FFXIVClientStructs.FFXIV.Client.UI.Misc;
@@ -98,10 +97,10 @@ public static unsafe class Gearsets
}; };
} }
public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation, bool checkDelineations) => public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation, checkDelineations); CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation);
public static CharacterStats CalculateCharacterStats(GearsetStats gearsetStats, GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation, bool checkDelineations) => public static CharacterStats CalculateCharacterStats(GearsetStats gearsetStats, GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
new() new()
{ {
CP = gearsetStats.CP, CP = gearsetStats.CP,
@@ -110,7 +109,7 @@ 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) && (!checkDelineations || HasDelineations()), IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal),
}; };
public static bool HasDelineations() => public static bool HasDelineations() =>
+5 -2
View File
@@ -1535,13 +1535,16 @@ public sealed class MacroEditor : Window, IDisposable
SolverStartStepCount = Macro.Count; SolverStartStepCount = Macro.Count;
var state = State; var state = State;
SolverTask = new(token => CalculateBestMacroTask(state, token)); SolverTask = new(token => CalculateBestMacroTask(state, token, Gearsets.HasDelineations()));
SolverTask.Start(); SolverTask.Start();
} }
private int CalculateBestMacroTask(SimulationState state, CancellationToken token) private int CalculateBestMacroTask(SimulationState state, CancellationToken token, bool hasDelineations)
{ {
var config = Service.Configuration.EditorSolverConfig; var config = Service.Configuration.EditorSolverConfig;
var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations;
if (!canUseDelineations)
config = config.FilterSpecialistActions();
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
+13 -1
View File
@@ -224,7 +224,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(), Service.Configuration.CheckDelineations); var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation());
if (characterStats != CharacterStats) if (characterStats != CharacterStats)
{ {
CharacterStats = characterStats; CharacterStats = characterStats;
@@ -1140,11 +1140,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable
private void CalculateSavedMacro() private void CalculateSavedMacro()
{ {
SavedMacroTask?.Cancel(); SavedMacroTask?.Cancel();
var hasDelineations = Gearsets.HasDelineations();
SavedMacroTask = new(token => SavedMacroTask = new(token =>
{ {
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality);
var state = new SimulationState(input); var state = new SimulationState(input);
var config = Service.Configuration.RecipeNoteSolverConfig; var config = Service.Configuration.RecipeNoteSolverConfig;
var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations;
if (!canUseDelineations)
config = config.FilterSpecialistActions();
var mctsConfig = new MCTSConfig(config); var mctsConfig = new MCTSConfig(config);
var simulator = new SimulatorNoRandom(); var simulator = new SimulatorNoRandom();
List<Macro> macros = new(Service.Configuration.Macros); List<Macro> macros = new(Service.Configuration.Macros);
@@ -1171,11 +1175,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable
private void CalculateSuggestedMacro() private void CalculateSuggestedMacro()
{ {
SuggestedMacroTask?.Cancel(); SuggestedMacroTask?.Cancel();
var hasDelineations = Gearsets.HasDelineations();
SuggestedMacroTask = new(token => SuggestedMacroTask = new(token =>
{ {
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality);
var state = new SimulationState(input); var state = new SimulationState(input);
var config = Service.Configuration.RecipeNoteSolverConfig; var config = Service.Configuration.RecipeNoteSolverConfig;
var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations;
if (!canUseDelineations)
config = config.FilterSpecialistActions();
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
@@ -1195,11 +1203,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable
public void CalculateCommunityMacro() public void CalculateCommunityMacro()
{ {
CommunityMacroTask?.Cancel(); CommunityMacroTask?.Cancel();
var hasDelineations = Gearsets.HasDelineations();
CommunityMacroTask = new(token => CommunityMacroTask = new(token =>
{ {
var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality);
var state = new SimulationState(input); var state = new SimulationState(input);
var config = Service.Configuration.RecipeNoteSolverConfig; var config = Service.Configuration.RecipeNoteSolverConfig;
var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations;
if (!canUseDelineations)
config = config.FilterSpecialistActions();
var mctsConfig = new MCTSConfig(config); var mctsConfig = new MCTSConfig(config);
var simulator = new SimulatorNoRandom(); var simulator = new SimulatorNoRandom();
var macros = Service.CommunityMacros.RetrieveRotations((int)RecipeData.Table.RowId, token).GetAwaiter().GetResult(); var macros = Service.CommunityMacros.RetrieveRotations((int)RecipeData.Table.RowId, token).GetAwaiter().GetResult();
+1 -1
View File
@@ -253,7 +253,7 @@ public sealed class Settings : Window, IDisposable
DrawOption( DrawOption(
"Check For Delineations", "Check For Delineations",
"Your inventory will be checked to ensure that you have delineations available " + "Your inventory will be checked to ensure that you have delineations available " +
"before suggesting any specialist acitons.", "before suggesting any specialist actions.",
Config.CheckDelineations, Config.CheckDelineations,
v => Config.CheckDelineations = v, v => Config.CheckDelineations = v,
ref isDirty ref isDirty
+6 -3
View File
@@ -493,7 +493,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(), Service.Configuration.CheckDelineations); var characterStats = Gearsets.CalculateCharacterStats(gearStats, gearItems, RecipeData.ClassJob.GetPlayerLevel(), RecipeData.ClassJob.CanPlayerUseManipulation());
if (characterStats != CharacterStats) if (characterStats != CharacterStats)
{ {
CharacterStats = characterStats; CharacterStats = characterStats;
@@ -596,13 +596,16 @@ public sealed unsafe class SynthHelper : Window, IDisposable
} }
var state = CurrentState; var state = CurrentState;
SolverTask = new(token => CalculateBestMacroTask(state, token)); SolverTask = new(token => CalculateBestMacroTask(state, token, Gearsets.HasDelineations()));
SolverTask.Start(); SolverTask.Start();
} }
private int CalculateBestMacroTask(SimulationState state, CancellationToken token) private int CalculateBestMacroTask(SimulationState state, CancellationToken token, bool hasDelineations)
{ {
var config = Service.Configuration.SynthHelperSolverConfig; var config = Service.Configuration.SynthHelperSolverConfig;
var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations;
if (!canUseDelineations)
config = config.FilterSpecialistActions();
token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested();
+11
View File
@@ -64,6 +64,9 @@ public readonly record struct SolverConfig
public static ActionType[] OptimizeActionPool(IEnumerable<ActionType> actions) => public static ActionType[] OptimizeActionPool(IEnumerable<ActionType> actions) =>
[.. actions.Order()]; [.. actions.Order()];
public SolverConfig FilterSpecialistActions() =>
this with { ActionPool = ActionPool.Where(action => !SpecialistActions.Contains(action)).ToArray() };
public static readonly ActionType[] DeterministicActionPool = OptimizeActionPool(new[] public static readonly ActionType[] DeterministicActionPool = OptimizeActionPool(new[]
{ {
ActionType.MuscleMemory, ActionType.MuscleMemory,
@@ -167,6 +170,14 @@ public readonly record struct SolverConfig
ActionType.DaringTouch, ActionType.DaringTouch,
}.ToFrozenSet(); }.ToFrozenSet();
public static readonly FrozenSet<ActionType> SpecialistActions =
new[]
{
ActionType.CarefulObservation,
ActionType.HeartAndSoul,
ActionType.QuickInnovation,
}.ToFrozenSet();
public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with
{ {