diff --git a/Craftimizer/SimulatorUtils.cs b/Craftimizer/SimulatorUtils.cs index 172e24e..7208bbf 100644 --- a/Craftimizer/SimulatorUtils.cs +++ b/Craftimizer/SimulatorUtils.cs @@ -310,6 +310,8 @@ public static uint StatusId(this EffectType me) => EffectType.MuscleMemory => 2191, EffectType.Manipulation => 1164, EffectType.HeartAndSoul => 2665, + EffectType.Expedience => 3812, + EffectType.TrainedPerfection => 3813, _ => throw new ArgumentOutOfRangeException(nameof(me)), }; diff --git a/Craftimizer/Utils/CommunityMacros.cs b/Craftimizer/Utils/CommunityMacros.cs index d85bab2..df26458 100644 --- a/Craftimizer/Utils/CommunityMacros.cs +++ b/Craftimizer/Utils/CommunityMacros.cs @@ -256,30 +256,33 @@ public CommunityMacro(TeamcraftMacro macro) "PrudentSynthesis" => ActionType.PrudentSynthesis, "RapidSynthesis" => ActionType.RapidSynthesis, "Groundwork" => ActionType.Groundwork, - "FocusedSynthesis" => ActionType.FocusedSynthesis, "MuscleMemory" => ActionType.MuscleMemory, "IntensiveSynthesis" => ActionType.IntensiveSynthesis, "BasicTouch" => ActionType.BasicTouch, "StandardTouch" => ActionType.StandardTouch, "AdvancedTouch" => ActionType.AdvancedTouch, "HastyTouch" => ActionType.HastyTouch, + "DaringTouch" => ActionType.DaringTouch, "ByregotsBlessing" => ActionType.ByregotsBlessing, "PreciseTouch" => ActionType.PreciseTouch, - "FocusedTouch" => ActionType.FocusedTouch, "PrudentTouch" => ActionType.PrudentTouch, "TrainedEye" => ActionType.TrainedEye, "PreparatoryTouch" => ActionType.PreparatoryTouch, "Reflect" => ActionType.Reflect, "TrainedFinesse" => ActionType.TrainedFinesse, + "RefinedTouch" => ActionType.RefinedTouch, + "TrainedPerfection" => ActionType.TrainedPerfection, "TricksOfTheTrade" => ActionType.TricksOfTheTrade, "MastersMend" => ActionType.MastersMend, "Manipulation" => ActionType.Manipulation, + "ImmaculateMend" => ActionType.ImmaculateMend, "WasteNot" => ActionType.WasteNot, "WasteNotII" => ActionType.WasteNot2, "GreatStrides" => ActionType.GreatStrides, "Innovation" => ActionType.Innovation, "Veneration" => ActionType.Veneration, "FinalAppraisal" => ActionType.FinalAppraisal, + "QuickInnovation" => ActionType.QuickInnovation, "Observe" => ActionType.Observe, "HeartAndSoul" => ActionType.HeartAndSoul, "CarefulObservation" => ActionType.CarefulObservation, @@ -311,42 +314,46 @@ public CommunityMacro(CraftingwayMacro macro) if (macro.Actions is not { } rotation) throw new Exception($"Internal error; No actions were returned"); - // https://github.com/ffxiv-teamcraft/ffxiv-teamcraft/blob/67f453041c6b2b31d32fcf6e1fd53aa38ed7a12b/apps/client/src/app/model/other/crafting-rotation.ts#L49 - Name = macro.Slug ?? "New Craftinway Rotation"; + Name = macro.Slug ?? "New Craftingway Rotation"; var actions = new List(); foreach (var action in rotation.Split(',')) { ActionType? actionType = action switch { - "BasicSynthesis" => ActionType.BasicSynthesis, - "BasicTouch" => ActionType.BasicTouch, - "MastersMend" => ActionType.MastersMend, - "Observe" => ActionType.Observe, - "WasteNot" => ActionType.WasteNot, + "MuscleMemory" => ActionType.MuscleMemory, + "Reflect" => ActionType.Reflect, + "TrainedEye" => ActionType.TrainedEye, "Veneration" => ActionType.Veneration, - "StandardTouch" => ActionType.StandardTouch, "GreatStrides" => ActionType.GreatStrides, "Innovation" => ActionType.Innovation, + "QuickInnovation" => ActionType.QuickInnovation, + "BasicSynthesis" => ActionType.BasicSynthesis, "BasicSynthesisTraited" => ActionType.BasicSynthesis, - "WasteNotII" => ActionType.WasteNot2, - "ByregotsBlessing" => ActionType.ByregotsBlessing, - "MuscleMemory" => ActionType.MuscleMemory, "CarefulSynthesis" => ActionType.CarefulSynthesis, - "Manipulation" => ActionType.Manipulation, - "PrudentTouch" => ActionType.PrudentTouch, - "FocusedSynthesis" => ActionType.FocusedSynthesis, - "FocusedTouch" => ActionType.FocusedTouch, - "Reflect" => ActionType.Reflect, - "PreparatoryTouch" => ActionType.PreparatoryTouch, - "Groundwork" => ActionType.Groundwork, - "DelicateSynthesis" => ActionType.DelicateSynthesis, - "TrainedEye" => ActionType.TrainedEye, "CarefulSynthesisTraited" => ActionType.CarefulSynthesis, - "AdvancedTouch" => ActionType.AdvancedTouch, - "GroundworkTraited" => ActionType.Groundwork, "PrudentSynthesis" => ActionType.PrudentSynthesis, + "Groundwork" => ActionType.Groundwork, + "GroundworkTraited" => ActionType.Groundwork, + "BasicTouch" => ActionType.BasicTouch, + "StandardTouch" => ActionType.StandardTouch, + "AdvancedTouch" => ActionType.AdvancedTouch, + "ByregotsBlessing" => ActionType.ByregotsBlessing, + "PrudentTouch" => ActionType.PrudentTouch, + "PreparatoryTouch" => ActionType.PreparatoryTouch, "TrainedFinesse" => ActionType.TrainedFinesse, - { } actionValue => throw new Exception($"Unknown action {actionValue}"), + "RefinedTouch" => ActionType.RefinedTouch, + "MastersMend" => ActionType.MastersMend, + "ImmaculateMend" => ActionType.ImmaculateMend, + "WasteNot" => ActionType.WasteNot, + "WasteNotII" => ActionType.WasteNot2, + "Manipulation" => ActionType.Manipulation, + "TrainedPerfection" => ActionType.TrainedPerfection, + "Observe" => ActionType.Observe, + "DelicateSynthesis" => ActionType.DelicateSynthesis, + "DelicateSynthesisTraited" => ActionType.DelicateSynthesis, + + // Old actions? + _ => null }; if (actionType.HasValue) actions.Add(actionType.Value); diff --git a/Craftimizer/Utils/Gearsets.cs b/Craftimizer/Utils/Gearsets.cs index e1bad67..d0a8377 100644 --- a/Craftimizer/Utils/Gearsets.cs +++ b/Craftimizer/Utils/Gearsets.cs @@ -24,12 +24,12 @@ public record struct GearsetItem(uint itemId, bool isHq, GearsetMateria[] materi static Gearsets() { - LevelToCLvlLUT = new int[90]; + LevelToCLvlLUT = new int[100]; for (uint i = 0; i < 80; ++i) { var level = i + 1; LevelToCLvlLUT[i] = LuminaSheets.ParamGrowSheet.GetRow(level)!.CraftingLevel; } - for (var i = 80; i < 90; ++i) + for (var i = 80; i < 100; ++i) { var level = i + 1; LevelToCLvlLUT[i] = (int)LuminaSheets.RecipeLevelTableSheet.First(r => r.ClassJobLevel == level).RowId; diff --git a/Craftimizer/Windows/SynthHelper.cs b/Craftimizer/Windows/SynthHelper.cs index e3c4dcf..a0236bd 100644 --- a/Craftimizer/Windows/SynthHelper.cs +++ b/Craftimizer/Windows/SynthHelper.cs @@ -568,6 +568,8 @@ bool HasEffect(ushort id) WasteNot2 = GetEffectStack((ushort)EffectType.WasteNot2.StatusId()), MuscleMemory = GetEffectStack((ushort)EffectType.MuscleMemory.StatusId()), Manipulation = GetEffectStack((ushort)EffectType.Manipulation.StatusId()), + Expedience = HasEffect((ushort)EffectType.Expedience.StatusId()), + TrainedPerfection = HasEffect((ushort)EffectType.TrainedPerfection.StatusId()), HeartAndSoul = HasEffect((ushort)EffectType.HeartAndSoul.StatusId()), }, ActionStates = CurrentActionStates diff --git a/Simulator/ActionStates.cs b/Simulator/ActionStates.cs index 53a02c6..c59f448 100644 --- a/Simulator/ActionStates.cs +++ b/Simulator/ActionStates.cs @@ -10,7 +10,9 @@ public record struct ActionStates public byte TouchComboIdx; public byte CarefulObservationCount; public bool UsedHeartAndSoul; - public bool Observed; + public bool UsedQuickInnovation; + public bool UsedTrainedPerfection; + public bool ObserveCombo; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void MutateState(BaseAction baseAction) @@ -28,6 +30,12 @@ public void MutateState(BaseAction baseAction) if (baseAction is HeartAndSoul) UsedHeartAndSoul = true; - Observed = baseAction is Observe; + if (baseAction is QuickInnovation) + UsedQuickInnovation = true; + + if (baseAction is TrainedPerfection) + UsedTrainedPerfection = true; + + ObserveCombo = baseAction is Observe; } } diff --git a/Simulator/Actions/ActionType.cs b/Simulator/Actions/ActionType.cs index d7dd285..5afb7c0 100644 --- a/Simulator/Actions/ActionType.cs +++ b/Simulator/Actions/ActionType.cs @@ -11,14 +11,14 @@ public enum ActionType : byte ByregotsBlessing, CarefulObservation, CarefulSynthesis, + DaringTouch, DelicateSynthesis, FinalAppraisal, - FocusedSynthesis, - FocusedTouch, GreatStrides, Groundwork, HastyTouch, HeartAndSoul, + ImmaculateMend, Innovation, IntensiveSynthesis, Manipulation, @@ -29,11 +29,14 @@ public enum ActionType : byte PreparatoryTouch, PrudentSynthesis, PrudentTouch, + QuickInnovation, RapidSynthesis, + RefinedTouch, Reflect, StandardTouch, TrainedEye, TrainedFinesse, + TrainedPerfection, TricksOfTheTrade, Veneration, WasteNot, @@ -41,8 +44,8 @@ public enum ActionType : byte StandardTouchCombo, AdvancedTouchCombo, - FocusedSynthesisCombo, - FocusedTouchCombo, + ObservedAdvancedTouchCombo, + RefinedTouchCombo, } public static class ActionUtils @@ -68,47 +71,4 @@ public static int Level(this ActionType me) => public static ActionCategory Category(this ActionType me) => me.Base().Category; - - public static string IntName(this ActionType me) => - me switch - { - ActionType.AdvancedTouch => "Advanced Touch", - ActionType.BasicSynthesis => "Basic Synthesis", - ActionType.BasicTouch => "Basic Touch", - ActionType.ByregotsBlessing => "Byregot's Blessing", - ActionType.CarefulObservation => "Careful Observation", - ActionType.CarefulSynthesis => "Careful Synthesis", - ActionType.DelicateSynthesis => "Delicate Synthesis", - ActionType.FinalAppraisal => "Final Appraisal", - ActionType.FocusedSynthesis => "Focused Synthesis", - ActionType.FocusedTouch => "Focused Touch", - ActionType.GreatStrides => "Great Strides", - ActionType.Groundwork => "Groundwork", - ActionType.HastyTouch => "Hasty Touch", - ActionType.HeartAndSoul => "Heart And Soul", - ActionType.Innovation => "Innovation", - ActionType.IntensiveSynthesis => "Intensive Synthesis", - ActionType.Manipulation => "Manipulation", - ActionType.MastersMend => "Master's Mend", - ActionType.MuscleMemory => "Muscle Memory", - ActionType.Observe => "Observe", - ActionType.PreciseTouch => "Precise Touch", - ActionType.PreparatoryTouch => "Preparatory Touch", - ActionType.PrudentSynthesis => "Prudent Synthesis", - ActionType.PrudentTouch => "Prudent Touch", - ActionType.RapidSynthesis => "Rapid Synthesis", - ActionType.Reflect => "Reflect", - ActionType.StandardTouch => "Standard Touch", - ActionType.TrainedEye => "Trained Eye", - ActionType.TrainedFinesse => "Trained Finesse", - ActionType.TricksOfTheTrade => "Tricks Of The Trade", - ActionType.Veneration => "Veneration", - ActionType.WasteNot => "Waste Not", - ActionType.WasteNot2 => "Waste Not II", - ActionType.StandardTouchCombo => "Standard Touch Combo", - ActionType.AdvancedTouchCombo => "Advanced Touch Combo", - ActionType.FocusedSynthesisCombo => "Focused Synthesis Combo", - ActionType.FocusedTouchCombo => "Focused Touch Combo", - _ => me.ToString(), - }; } diff --git a/Simulator/Actions/AdvancedTouch.cs b/Simulator/Actions/AdvancedTouch.cs index 69a7ede..273ca5f 100644 --- a/Simulator/Actions/AdvancedTouch.cs +++ b/Simulator/Actions/AdvancedTouch.cs @@ -1,10 +1,10 @@ namespace Craftimizer.Simulator.Actions; internal sealed class AdvancedTouch() : BaseAction( - ActionCategory.Quality, level: 84, actionId: 100411, + ActionCategory.Quality, level: 68, actionId: 100411, increasesQuality: true, defaultCPCost: 46, defaultEfficiency: 150) { public override int CPCost(Simulator s) => - s.ActionStates.TouchComboIdx == 2 ? 18 : 46; + (s.ActionStates.TouchComboIdx == 2 || s.ActionStates.ObserveCombo) ? 18 : 46; } diff --git a/Simulator/Actions/BaseAction.cs b/Simulator/Actions/BaseAction.cs index 90435ce..ce63a80 100644 --- a/Simulator/Actions/BaseAction.cs +++ b/Simulator/Actions/BaseAction.cs @@ -67,7 +67,8 @@ public virtual void Use(Simulator s) UseSuccess(s); s.ReduceCP(CPCost(s)); - s.ReduceDurability(DurabilityCost); + if (!s.HasEffect(EffectType.TrainedPerfection)) + s.ReduceDurability(DurabilityCost); if (IncreasesStepCount) { diff --git a/Simulator/Actions/BaseComboAction.cs b/Simulator/Actions/BaseComboAction.cs index cfe1a24..b7e53eb 100644 --- a/Simulator/Actions/BaseComboAction.cs +++ b/Simulator/Actions/BaseComboAction.cs @@ -18,11 +18,14 @@ protected bool BaseCouldUse(Simulator s) => private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects) { - var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); - // -A - durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); - if (durability <= 0) - return false; + if (!effects.HasEffect(EffectType.TrainedPerfection)) + { + var wasteNots = effects.HasEffect(EffectType.WasteNot) || effects.HasEffect(EffectType.WasteNot2); + // -A + durability -= (int)MathF.Ceiling(durabilityA * (wasteNots ? .5f : 1f)); + if (durability <= 0) + return false; + } // If we can do the first action and still have durability left to survive to the next // step (even before the Manipulation modifier), we can certainly do the next action. @@ -36,10 +39,14 @@ public static bool VerifyDurability3(int durabilityA, int durabilityB, int durab { var wasteNots = Math.Max(effects.GetDuration(EffectType.WasteNot), effects.GetDuration(EffectType.WasteNot2)); var manips = effects.HasEffect(EffectType.Manipulation); + var perfection = effects.HasEffect(EffectType.TrainedPerfection); - durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); - if (durability <= 0) - return false; + if (!perfection) + { + durability -= (int)MathF.Ceiling(durabilityA * wasteNots > 0 ? .5f : 1f); + if (durability <= 0) + return false; + } if (manips) durability += 5; diff --git a/Simulator/Actions/DaringTouch.cs b/Simulator/Actions/DaringTouch.cs new file mode 100644 index 0000000..ba7bc8f --- /dev/null +++ b/Simulator/Actions/DaringTouch.cs @@ -0,0 +1,13 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class DaringTouch() : BaseAction( + ActionCategory.Quality, 96, 100451, + increasesQuality: true, + defaultCPCost: 0, + defaultEfficiency: 150, + defaultSuccessRate: 60 + ) +{ + public override bool CouldUse(Simulator s) => + s.HasEffect(EffectType.Expedience) && base.CouldUse(s); +} diff --git a/Simulator/Actions/DelicateSynthesis.cs b/Simulator/Actions/DelicateSynthesis.cs index 5f0fc3a..3310687 100644 --- a/Simulator/Actions/DelicateSynthesis.cs +++ b/Simulator/Actions/DelicateSynthesis.cs @@ -7,5 +7,11 @@ internal sealed class DelicateSynthesis() : BaseAction( defaultEfficiency: 100 ) { - + public override void UseSuccess(Simulator s) + { + // Delicate Synthesis Mastery Trait + var hasTrait = s.Input.Stats.Level >= 94; + s.IncreaseProgress(hasTrait ? 150 : 100); + s.IncreaseQuality(100); + } } diff --git a/Simulator/Actions/FocusedSynthesis.cs b/Simulator/Actions/FocusedSynthesis.cs deleted file mode 100644 index 06510c7..0000000 --- a/Simulator/Actions/FocusedSynthesis.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Craftimizer.Simulator.Actions; - -internal sealed class FocusedSynthesis() : BaseAction( - ActionCategory.Synthesis, 67, 100235, - increasesProgress: true, - defaultCPCost: 5, - defaultEfficiency: 200, - defaultSuccessRate: 50 - ) -{ - public override int SuccessRate(Simulator s) => - s.ActionStates.Observed ? 100 : 50; -} diff --git a/Simulator/Actions/FocusedSynthesisCombo.cs b/Simulator/Actions/FocusedSynthesisCombo.cs deleted file mode 100644 index f3951fb..0000000 --- a/Simulator/Actions/FocusedSynthesisCombo.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Craftimizer.Simulator.Actions; - -internal sealed class FocusedSynthesisCombo() : BaseComboAction( - ActionType.Observe, ActionType.FocusedSynthesis - ) -{ - -} diff --git a/Simulator/Actions/FocusedTouch.cs b/Simulator/Actions/FocusedTouch.cs deleted file mode 100644 index 3946b79..0000000 --- a/Simulator/Actions/FocusedTouch.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Craftimizer.Simulator.Actions; - -internal sealed class FocusedTouch() : BaseAction( - ActionCategory.Quality, 68, 100243, - increasesQuality: true, - defaultCPCost: 18, - defaultEfficiency: 150, - defaultSuccessRate: 50 - ) -{ - public override int SuccessRate(Simulator s) => - s.ActionStates.Observed ? 100 : 50; -} diff --git a/Simulator/Actions/FocusedTouchCombo.cs b/Simulator/Actions/FocusedTouchCombo.cs deleted file mode 100644 index f1c16c8..0000000 --- a/Simulator/Actions/FocusedTouchCombo.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Craftimizer.Simulator.Actions; - -internal sealed class FocusedTouchCombo() : BaseComboAction( - ActionType.Observe, ActionType.FocusedTouch - ) -{ - -} diff --git a/Simulator/Actions/ImmaculateMend.cs b/Simulator/Actions/ImmaculateMend.cs new file mode 100644 index 0000000..fe41b9e --- /dev/null +++ b/Simulator/Actions/ImmaculateMend.cs @@ -0,0 +1,12 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class ImmaculateMend() : BaseAction( + ActionCategory.Durability, 98, 100467, + macroWaitTime: 2, + durabilityCost: 0, + defaultCPCost: 112 + ) +{ + public override void UseSuccess(Simulator s) => + s.RestoreAllDurability(); +} diff --git a/Simulator/Actions/MastersMend.cs b/Simulator/Actions/MastersMend.cs index 7416a20..7287371 100644 --- a/Simulator/Actions/MastersMend.cs +++ b/Simulator/Actions/MastersMend.cs @@ -2,6 +2,7 @@ namespace Craftimizer.Simulator.Actions; internal sealed class MastersMend() : BaseAction( ActionCategory.Durability, 7, 100003, + macroWaitTime: 2, durabilityCost: 0, defaultCPCost: 88 ) diff --git a/Simulator/Actions/ObservedAdvancedTouchCombo.cs b/Simulator/Actions/ObservedAdvancedTouchCombo.cs new file mode 100644 index 0000000..5e25f0d --- /dev/null +++ b/Simulator/Actions/ObservedAdvancedTouchCombo.cs @@ -0,0 +1,8 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class ObservedAdvancedTouchCombo() : BaseComboAction( + ActionType.StandardTouchCombo, ActionType.AdvancedTouch, 7 + 18 + ) +{ + +} diff --git a/Simulator/Actions/QuickInnovation.cs b/Simulator/Actions/QuickInnovation.cs new file mode 100644 index 0000000..c809487 --- /dev/null +++ b/Simulator/Actions/QuickInnovation.cs @@ -0,0 +1,18 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class QuickInnovation() : BaseBuffAction( + ActionCategory.Other, 96, 100459, + EffectType.Innovation, duration: 1, + macroWaitTime: 3, + increasesStepCount: false + ) +{ + public override bool IsPossible(Simulator s) => + base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedQuickInnovation; + + public override bool CouldUse(Simulator s) => + !s.ActionStates.UsedQuickInnovation; + + public override string GetTooltip(Simulator s, bool addUsability) => + $"{GetBaseTooltip(s, addUsability)}Specialist Only\n"; +} diff --git a/Simulator/Actions/RefinedTouch.cs b/Simulator/Actions/RefinedTouch.cs new file mode 100644 index 0000000..f68c5ac --- /dev/null +++ b/Simulator/Actions/RefinedTouch.cs @@ -0,0 +1,16 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class RefinedTouch() : BaseAction( + ActionCategory.Quality, 92, 100443, + increasesQuality: true, + defaultCPCost: 24, + defaultEfficiency: 100 + ) +{ + public override void UseSuccess(Simulator s) + { + base.UseSuccess(s); + if (s.ActionStates.TouchComboIdx == 1) + s.StrengthenEffect(EffectType.InnerQuiet); + } +} diff --git a/Simulator/Actions/RefinedTouchCombo.cs b/Simulator/Actions/RefinedTouchCombo.cs new file mode 100644 index 0000000..17d43c1 --- /dev/null +++ b/Simulator/Actions/RefinedTouchCombo.cs @@ -0,0 +1,8 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class RefinedTouchCombo() : BaseComboAction( + ActionType.BasicTouch, ActionType.RefinedTouch + ) +{ + +} diff --git a/Simulator/Actions/Reflect.cs b/Simulator/Actions/Reflect.cs index bc459ed..4c933e6 100644 --- a/Simulator/Actions/Reflect.cs +++ b/Simulator/Actions/Reflect.cs @@ -4,7 +4,7 @@ internal sealed class Reflect() : BaseAction( ActionCategory.FirstTurn, 69, 100387, increasesQuality: true, defaultCPCost: 6, - defaultEfficiency: 100 + defaultEfficiency: 300 ) { public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); diff --git a/Simulator/Actions/TrainedPerfection.cs b/Simulator/Actions/TrainedPerfection.cs new file mode 100644 index 0000000..f340eea --- /dev/null +++ b/Simulator/Actions/TrainedPerfection.cs @@ -0,0 +1,13 @@ +namespace Craftimizer.Simulator.Actions; + +internal sealed class TrainedPerfection() : BaseBuffAction( + ActionCategory.Durability, 100, 100475, + EffectType.TrainedPerfection, duration: 1 + ) +{ + public override bool IsPossible(Simulator s) => + base.IsPossible(s) && !s.ActionStates.UsedTrainedPerfection; + + public override bool CouldUse(Simulator s) => + !s.ActionStates.UsedTrainedPerfection; +} diff --git a/Simulator/EffectType.cs b/Simulator/EffectType.cs index cf4ff72..50bb4b0 100644 --- a/Simulator/EffectType.cs +++ b/Simulator/EffectType.cs @@ -12,4 +12,6 @@ public enum EffectType MuscleMemory, Manipulation, HeartAndSoul, + Expedience, + TrainedPerfection } diff --git a/Simulator/Effects.cs b/Simulator/Effects.cs index 6740e16..0bea88c 100644 --- a/Simulator/Effects.cs +++ b/Simulator/Effects.cs @@ -16,6 +16,8 @@ public record struct Effects public byte WasteNot2; public byte MuscleMemory; public byte Manipulation; + public bool Expedience; + public bool TrainedPerfection; public bool HeartAndSoul; [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -51,6 +53,12 @@ public void SetDuration(EffectType effect, byte duration) case EffectType.Manipulation: Manipulation = duration; break; + case EffectType.Expedience: + Expedience = duration != 0; + break; + case EffectType.TrainedPerfection: + TrainedPerfection = duration != 0; + break; case EffectType.HeartAndSoul: HeartAndSoul = duration != 0; break; @@ -78,6 +86,8 @@ public readonly byte GetDuration(EffectType effect) => EffectType.WasteNot2 => WasteNot2, EffectType.MuscleMemory => MuscleMemory, EffectType.Manipulation => Manipulation, + EffectType.Expedience => (byte)(Expedience ? 1 : 0), + EffectType.TrainedPerfection => (byte)(TrainedPerfection ? 1 : 0), EffectType.HeartAndSoul => (byte)(HeartAndSoul ? 1 : 0), _ => 0 }; @@ -117,5 +127,8 @@ public void DecrementDuration() MuscleMemory--; if (Manipulation > 0) Manipulation--; + + Expedience = false; + TrainedPerfection = false; } } diff --git a/Simulator/Simulator.cs b/Simulator/Simulator.cs index 9d1b8da..74c4a36 100644 --- a/Simulator/Simulator.cs +++ b/Simulator/Simulator.cs @@ -181,6 +181,12 @@ public void RestoreDurability(int amount) Durability = Input.Recipe.MaxDurability; } + public void RestoreAllDurability() + { + Durability = Input.Recipe.MaxDurability; + } + + public void RestoreCP(int amount) { CP += amount; diff --git a/Solver/SolverConfig.cs b/Solver/SolverConfig.cs index e2f300a..90b4b71 100644 --- a/Solver/SolverConfig.cs +++ b/Solver/SolverConfig.cs @@ -72,7 +72,6 @@ public static ActionType[] OptimizeActionPool(IEnumerable actions) = ActionType.BasicSynthesis, ActionType.CarefulSynthesis, - ActionType.FocusedSynthesis, ActionType.Groundwork, ActionType.DelicateSynthesis, ActionType.PrudentSynthesis, @@ -81,26 +80,30 @@ public static ActionType[] OptimizeActionPool(IEnumerable actions) = ActionType.StandardTouch, ActionType.ByregotsBlessing, ActionType.PrudentTouch, - ActionType.FocusedTouch, - ActionType.PreparatoryTouch, ActionType.AdvancedTouch, + ActionType.PreparatoryTouch, ActionType.TrainedFinesse, + ActionType.RefinedTouch, ActionType.MastersMend, ActionType.WasteNot, ActionType.WasteNot2, ActionType.Manipulation, + ActionType.ImmaculateMend, + ActionType.TrainedPerfection, ActionType.Veneration, ActionType.GreatStrides, ActionType.Innovation, + ActionType.QuickInnovation, ActionType.Observe, + ActionType.HeartAndSoul, ActionType.StandardTouchCombo, ActionType.AdvancedTouchCombo, - ActionType.FocusedTouchCombo, - ActionType.FocusedSynthesisCombo, + ActionType.ObservedAdvancedTouchCombo, + ActionType.RefinedTouchCombo, }); // Same as deterministic, but with condition-specific actions added @@ -112,7 +115,6 @@ public static ActionType[] OptimizeActionPool(IEnumerable actions) = ActionType.BasicSynthesis, ActionType.CarefulSynthesis, - ActionType.FocusedSynthesis, ActionType.Groundwork, ActionType.DelicateSynthesis, ActionType.IntensiveSynthesis, @@ -123,34 +125,37 @@ public static ActionType[] OptimizeActionPool(IEnumerable actions) = ActionType.ByregotsBlessing, ActionType.PreciseTouch, ActionType.PrudentTouch, - ActionType.FocusedTouch, - ActionType.PreparatoryTouch, ActionType.AdvancedTouch, + ActionType.PreparatoryTouch, ActionType.TrainedFinesse, + ActionType.RefinedTouch, ActionType.MastersMend, ActionType.WasteNot, ActionType.WasteNot2, ActionType.Manipulation, + ActionType.ImmaculateMend, + ActionType.TrainedPerfection, ActionType.Veneration, ActionType.GreatStrides, ActionType.Innovation, + ActionType.QuickInnovation, ActionType.Observe, + ActionType.HeartAndSoul, ActionType.TricksOfTheTrade, ActionType.StandardTouchCombo, ActionType.AdvancedTouchCombo, - ActionType.FocusedTouchCombo, - ActionType.FocusedSynthesisCombo, + ActionType.ObservedAdvancedTouchCombo, + ActionType.RefinedTouchCombo, }); public static readonly FrozenSet InefficientActions = new[] { ActionType.CarefulObservation, - ActionType.HeartAndSoul, ActionType.FinalAppraisal }.ToFrozenSet(); @@ -159,6 +164,7 @@ public static ActionType[] OptimizeActionPool(IEnumerable actions) = { ActionType.RapidSynthesis, ActionType.HastyTouch, + ActionType.DaringTouch, }.ToFrozenSet(); public static readonly SolverConfig RecipeNoteDefault = new SolverConfig() with diff --git a/Test/Simulator/Simulator.cs b/Test/Simulator/Simulator.cs index 83939f0..f48f597 100644 --- a/Test/Simulator/Simulator.cs +++ b/Test/Simulator/Simulator.cs @@ -114,7 +114,7 @@ public void WithBuffs1() ActionType.PreparatoryTouch, ActionType.WasteNot2 }, - 0, 890, 60, 335); + 0, 1414, 60, 335); } [TestMethod] @@ -165,7 +165,7 @@ public void TrainedFinesseProcs() ActionType.PrudentTouch, ActionType.PreparatoryTouch }, - 0, 4064, 15, 332); + 0, 4588, 15, 332); Assert.AreEqual(10, state.ActiveEffects.InnerQuiet); Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state })); } @@ -191,7 +191,7 @@ public void TestCompletedCraft1() ActionType.Groundwork, ActionType.Groundwork, }, - 3726, 8224, 5, 69); + 3726, 8748, 5, 69); } [TestMethod]