diff --git a/Craftimizer/Utils/Gearsets.cs b/Craftimizer/Utils/Gearsets.cs index 6bed176..a868862 100644 --- a/Craftimizer/Utils/Gearsets.cs +++ b/Craftimizer/Utils/Gearsets.cs @@ -1,5 +1,4 @@ using Craftimizer.Simulator; -using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game; using FFXIVClientStructs.FFXIV.Client.Game.UI; 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) => - CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation, checkDelineations); + public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) => + 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() { CP = gearsetStats.CP, @@ -110,7 +109,7 @@ public static unsafe class Gearsets Level = characterLevel, CanUseManipulation = canUseManipulation, HasSplendorousBuff = gearsetItems.Any(IsSplendorousTool), - IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal) && (!checkDelineations || HasDelineations()), + IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal), }; public static bool HasDelineations() => diff --git a/Craftimizer/Windows/MacroEditor.cs b/Craftimizer/Windows/MacroEditor.cs index ffc2927..b1aaf6d 100644 --- a/Craftimizer/Windows/MacroEditor.cs +++ b/Craftimizer/Windows/MacroEditor.cs @@ -1535,13 +1535,16 @@ public sealed class MacroEditor : Window, IDisposable SolverStartStepCount = Macro.Count; var state = State; - SolverTask = new(token => CalculateBestMacroTask(state, token)); + SolverTask = new(token => CalculateBestMacroTask(state, token, Gearsets.HasDelineations())); SolverTask.Start(); } - private int CalculateBestMacroTask(SimulationState state, CancellationToken token) + private int CalculateBestMacroTask(SimulationState state, CancellationToken token, bool hasDelineations) { var config = Service.Configuration.EditorSolverConfig; + var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations; + if (!canUseDelineations) + config = config.FilterSpecialistActions(); token.ThrowIfCancellationRequested(); diff --git a/Craftimizer/Windows/RecipeNote.cs b/Craftimizer/Windows/RecipeNote.cs index 5872d75..f57a16d 100644 --- a/Craftimizer/Windows/RecipeNote.cs +++ b/Craftimizer/Windows/RecipeNote.cs @@ -224,7 +224,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable 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) { CharacterStats = characterStats; @@ -1140,11 +1140,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable private void CalculateSavedMacro() { SavedMacroTask?.Cancel(); + var hasDelineations = Gearsets.HasDelineations(); SavedMacroTask = new(token => { var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var state = new SimulationState(input); var config = Service.Configuration.RecipeNoteSolverConfig; + var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations; + if (!canUseDelineations) + config = config.FilterSpecialistActions(); var mctsConfig = new MCTSConfig(config); var simulator = new SimulatorNoRandom(); List macros = new(Service.Configuration.Macros); @@ -1171,11 +1175,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable private void CalculateSuggestedMacro() { SuggestedMacroTask?.Cancel(); + var hasDelineations = Gearsets.HasDelineations(); SuggestedMacroTask = new(token => { var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var state = new SimulationState(input); var config = Service.Configuration.RecipeNoteSolverConfig; + var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations; + if (!canUseDelineations) + config = config.FilterSpecialistActions(); token.ThrowIfCancellationRequested(); @@ -1195,11 +1203,15 @@ public sealed unsafe class RecipeNote : Window, IDisposable public void CalculateCommunityMacro() { CommunityMacroTask?.Cancel(); + var hasDelineations = Gearsets.HasDelineations(); CommunityMacroTask = new(token => { var input = new SimulationInput(CharacterStats!, RecipeData!.RecipeInfo, StartingQuality); var state = new SimulationState(input); var config = Service.Configuration.RecipeNoteSolverConfig; + var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations; + if (!canUseDelineations) + config = config.FilterSpecialistActions(); var mctsConfig = new MCTSConfig(config); var simulator = new SimulatorNoRandom(); var macros = Service.CommunityMacros.RetrieveRotations((int)RecipeData.Table.RowId, token).GetAwaiter().GetResult(); diff --git a/Craftimizer/Windows/Settings.cs b/Craftimizer/Windows/Settings.cs index ad6b94e..00db707 100644 --- a/Craftimizer/Windows/Settings.cs +++ b/Craftimizer/Windows/Settings.cs @@ -253,7 +253,7 @@ public sealed class Settings : Window, IDisposable DrawOption( "Check For Delineations", "Your inventory will be checked to ensure that you have delineations available " + - "before suggesting any specialist acitons.", + "before suggesting any specialist actions.", Config.CheckDelineations, v => Config.CheckDelineations = v, ref isDirty diff --git a/Craftimizer/Windows/SynthHelper.cs b/Craftimizer/Windows/SynthHelper.cs index 43338f6..433aae4 100644 --- a/Craftimizer/Windows/SynthHelper.cs +++ b/Craftimizer/Windows/SynthHelper.cs @@ -493,7 +493,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable 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) { CharacterStats = characterStats; @@ -596,13 +596,16 @@ public sealed unsafe class SynthHelper : Window, IDisposable } var state = CurrentState; - SolverTask = new(token => CalculateBestMacroTask(state, token)); + SolverTask = new(token => CalculateBestMacroTask(state, token, Gearsets.HasDelineations())); SolverTask.Start(); } - private int CalculateBestMacroTask(SimulationState state, CancellationToken token) + private int CalculateBestMacroTask(SimulationState state, CancellationToken token, bool hasDelineations) { var config = Service.Configuration.SynthHelperSolverConfig; + var canUseDelineations = !Service.Configuration.CheckDelineations || hasDelineations; + if (!canUseDelineations) + config = config.FilterSpecialistActions(); token.ThrowIfCancellationRequested(); diff --git a/Solver/SolverConfig.cs b/Solver/SolverConfig.cs index d43b49f..f125ca8 100644 --- a/Solver/SolverConfig.cs +++ b/Solver/SolverConfig.cs @@ -64,6 +64,9 @@ public readonly record struct SolverConfig public static ActionType[] OptimizeActionPool(IEnumerable actions) => [.. actions.Order()]; + public SolverConfig FilterSpecialistActions() => + this with { ActionPool = ActionPool.Where(action => !SpecialistActions.Contains(action)).ToArray() }; + public static readonly ActionType[] DeterministicActionPool = OptimizeActionPool(new[] { ActionType.MuscleMemory, @@ -167,6 +170,14 @@ public readonly record struct SolverConfig ActionType.DaringTouch, }.ToFrozenSet(); + public static readonly FrozenSet SpecialistActions = + new[] + { + ActionType.CarefulObservation, + ActionType.HeartAndSoul, + ActionType.QuickInnovation, + }.ToFrozenSet(); + public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with {