diff --git a/Benchmark/Bench.cs b/Benchmark/Bench.cs index 95f7659..c3a14e6 100644 --- a/Benchmark/Bench.cs +++ b/Benchmark/Bench.cs @@ -1,4 +1,5 @@ using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Diagnostics.dotTrace; using BenchmarkDotNet.Jobs; using Craftimizer.Simulator; @@ -6,10 +7,12 @@ namespace Craftimizer.Benchmark; -[SimpleJob(RuntimeMoniker.Net70, baseline: true)] -[SimpleJob(RuntimeMoniker.Net80)] +[SimpleJob(RuntimeMoniker.Net70)] +[SimpleJob(RuntimeMoniker.Net80, baseline: true)] [MinColumn, Q1Column, Q3Column, MaxColumn] -[DotTraceDiagnoser] +//[DotTraceDiagnoser] +[MemoryDiagnoser] +[DisassemblyDiagnoser(maxDepth: 500, exportGithubMarkdown: false, exportHtml: true)] public class Bench { public record struct HashWrapper(T Data) where T : notnull @@ -95,12 +98,25 @@ public override readonly string ToString() => [ParamsSource(nameof(Configs))] public HashWrapper Config { get; set; } - [Benchmark] - public async Task Solve() + // [Benchmark] + public async Task SolveAsync() { var solver = new Solver.Solver(Config, State); solver.Start(); var (_, s) = await solver.GetTask().ConfigureAwait(false); return (float)s.Quality / s.Input.Recipe.MaxQuality; } + + [Benchmark] + public (float MaxScore, SolverSolution Solution) Solve() + { + var config = new MCTSConfig(Config.Data); + + var solver = new MCTS(config, State); + var progress = 0; + solver.Search(Config.Data.Iterations, ref progress, CancellationToken.None); + var solution = solver.Solution(); + + return (solver.MaxScore, solution); + } } diff --git a/Craftimizer/Windows/MacroEditor.cs b/Craftimizer/Windows/MacroEditor.cs index 65066d6..35ebc80 100644 --- a/Craftimizer/Windows/MacroEditor.cs +++ b/Craftimizer/Windows/MacroEditor.cs @@ -935,7 +935,6 @@ private void DrawActionHotbars() using var _color3 = ImRaii.PushColor(ImGuiCol.ButtonHovered, Vector4.Zero); using var _color2 = ImRaii.PushColor(ImGuiCol.ButtonActive, Vector4.Zero); using var _alpha = ImRaii.PushStyle(ImGuiStyleVar.DisabledAlpha, ImGui.GetStyle().DisabledAlpha * .5f); - var cost = 0; foreach (var category in Enum.GetValues()) { if (category == ActionCategory.Combo) @@ -953,7 +952,7 @@ private void DrawActionHotbars() if (i < itemCount) { var actionBase = actions[i].Base(); - var canUse = actionBase.CanUse(sim, ref cost); + var canUse = actionBase.CanUse(sim); if (ImGui.ImageButton(actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize), default, Vector2.One, 0, default, !canUse ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One)) AddStep(actions[i]); if (!canUse && diff --git a/Simulator/Actions/AdvancedTouch.cs b/Simulator/Actions/AdvancedTouch.cs index 5ac7fa2..69a7ede 100644 --- a/Simulator/Actions/AdvancedTouch.cs +++ b/Simulator/Actions/AdvancedTouch.cs @@ -1,27 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class AdvancedTouch : BaseAction +internal sealed class AdvancedTouch() : BaseAction( + ActionCategory.Quality, level: 84, actionId: 100411, + increasesQuality: true, + defaultCPCost: 46, defaultEfficiency: 150) { - public int CostDefault = 46; - public int CostOptimal = 18; - public int EfficiencyDefault = 150; - - public AdvancedTouch() - { - Category = ActionCategory.Quality; - Level = 84; - ActionId = 100411; - IncreasesQuality = true; - } - - - public override void CPCost(Simulator s, ref int cost) - { - cost = s.ActionStates.TouchComboIdx == 2 ? CostOptimal : CostDefault; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = EfficiencyDefault; - } + public override int CPCost(Simulator s) => + s.ActionStates.TouchComboIdx == 2 ? 18 : 46; } diff --git a/Simulator/Actions/AdvancedTouchCombo.cs b/Simulator/Actions/AdvancedTouchCombo.cs index 6a147a0..aa80a4b 100644 --- a/Simulator/Actions/AdvancedTouchCombo.cs +++ b/Simulator/Actions/AdvancedTouchCombo.cs @@ -1,7 +1,8 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class AdvancedTouchCombo : BaseComboAction +internal sealed class AdvancedTouchCombo() : BaseComboAction( + ActionType.StandardTouchCombo, ActionType.AdvancedTouch, 18 * 3 + ) { - public override ActionType ActionTypeA => ActionType.StandardTouchCombo; - public override ActionType ActionTypeB => ActionType.AdvancedTouch; + } diff --git a/Simulator/Actions/BaseAction.cs b/Simulator/Actions/BaseAction.cs index 0127e97..70c40c5 100644 --- a/Simulator/Actions/BaseAction.cs +++ b/Simulator/Actions/BaseAction.cs @@ -2,39 +2,46 @@ namespace Craftimizer.Simulator.Actions; -public abstract class BaseAction +public abstract class BaseAction( + ActionCategory category, int level, uint actionId, + int macroWaitTime = 3, + bool increasesProgress = false, bool increasesQuality = false, + int durabilityCost = 10, bool increasesStepCount = true, + int defaultCPCost = 0, + int defaultEfficiency = 0, + float defaultSuccessRate = 1) { // Non-instanced properties // Metadata - public ActionCategory Category; + public readonly ActionCategory Category = category; - public int Level; + public readonly int Level = level; // Doesn't matter from which class, we'll use the sheet to extrapolate the rest - public uint ActionId; + public readonly uint ActionId = actionId; // Seconds - public int MacroWaitTime = 3; + public readonly int MacroWaitTime = macroWaitTime; // Action properties - public bool IncreasesProgress; - public bool IncreasesQuality; - public int DurabilityCost = 10; - public bool IncreasesStepCount = true; - public int EfficiencyFactor; - public float SuccessRateFactor = 1; + public readonly bool IncreasesProgress = increasesProgress; + public readonly bool IncreasesQuality = increasesQuality; + public readonly int DurabilityCost = durabilityCost; + public readonly bool IncreasesStepCount = increasesStepCount; // Instanced properties - public abstract void CPCost(Simulator s, ref int cost); + public readonly int DefaultCPCost = defaultCPCost; + public readonly int DefaultEfficiency = defaultEfficiency; + public readonly float DefaultSuccessRate = defaultSuccessRate; - public virtual void Efficiency(Simulator s, ref int eff) - { - eff = EfficiencyFactor; - } + // Instanced properties + public virtual int CPCost(Simulator s) => + DefaultCPCost; - public virtual void SuccessRate(Simulator s, ref float success) - { - success = SuccessRateFactor; - } + public virtual int Efficiency(Simulator s) => + DefaultEfficiency; + + public virtual float SuccessRate(Simulator s) => + DefaultSuccessRate; // Return true if it can be in the action pool now or in the future // e.g. if Heart and Soul is already used, it is impossible to use it again @@ -44,23 +51,18 @@ public virtual bool IsPossible(Simulator s) => // Return true if it can be used now // This already assumes that IsPossible returns true *at some point before* - public virtual bool CouldUse(Simulator s, ref int cost) - { - CPCost(s, ref cost); - return s.CP >= cost; - } + public virtual bool CouldUse(Simulator s) => + s.CP >= CPCost(s); - public bool CanUse(Simulator s, ref int cost) => - IsPossible(s) && CouldUse(s, ref cost); + public bool CanUse(Simulator s) => + IsPossible(s) && CouldUse(s); - public virtual void Use(Simulator s, ref int cost, ref float success, ref int eff) + public virtual void Use(Simulator s) { - SuccessRate(s, ref success); - if (s.RollSuccess(success)) - UseSuccess(s, ref eff); - CPCost(s, ref cost); + if (s.RollSuccess(SuccessRate(s))) + UseSuccess(s); - s.ReduceCP(cost); + s.ReduceCP(CPCost(s)); s.ReduceDurability(DurabilityCost); if (s.Durability > 0) @@ -79,9 +81,9 @@ public virtual void Use(Simulator s, ref int cost, ref float success, ref int ef s.ActiveEffects.DecrementDuration(); } - public virtual void UseSuccess(Simulator s, ref int eff) + public virtual void UseSuccess(Simulator s) { - Efficiency(s, ref eff); + var eff = Efficiency(s); if (eff != 0) { if (IncreasesProgress) @@ -93,28 +95,28 @@ public virtual void UseSuccess(Simulator s, ref int eff) public virtual string GetTooltip(Simulator s, bool addUsability) { + var cost = CPCost(s); + var eff = Efficiency(s); + var success = SuccessRate(s); + var builder = new StringBuilder(); - int cost = 0; - float success = 1f; - if (addUsability && !CanUse(s, ref cost)) + if (addUsability && !CanUse(s)) builder.AppendLine($"Cannot Use"); builder.AppendLine($"Level {Level}"); if (cost != 0) builder.AppendLine($"-{s.CalculateCPCost(cost)} CP"); if (DurabilityCost != 0) builder.AppendLine($"-{s.CalculateDurabilityCost(DurabilityCost)} Durability"); - Efficiency(s, ref cost); - if (cost != 0) + if (eff != 0) { if (IncreasesProgress) - builder.AppendLine($"+{s.CalculateProgressGain(cost)} Progress"); + builder.AppendLine($"+{s.CalculateProgressGain(eff)} Progress"); if (IncreasesQuality) - builder.AppendLine($"+{s.CalculateQualityGain(cost)} Quality"); + builder.AppendLine($"+{s.CalculateQualityGain(eff)} Quality"); } if (!IncreasesStepCount) builder.AppendLine($"Does Not Increase Step Count"); - SuccessRate(s, ref success); - if (Math.Abs(success - 1f) > float.Epsilon) + if (success != 1) builder.AppendLine($"{s.CalculateSuccessRate(success) * 100:##}% Success Rate"); return builder.ToString(); } diff --git a/Simulator/Actions/BaseBuffAction.cs b/Simulator/Actions/BaseBuffAction.cs index debb1c3..64be9fb 100644 --- a/Simulator/Actions/BaseBuffAction.cs +++ b/Simulator/Actions/BaseBuffAction.cs @@ -2,19 +2,27 @@ namespace Craftimizer.Simulator.Actions; -internal abstract class BaseBuffAction : BaseAction +internal abstract class BaseBuffAction( + ActionCategory category, int level, uint actionId, + EffectType effect, int duration, + int macroWaitTime = 2, + bool increasesProgress = false, bool increasesQuality = false, + int durabilityCost = 0, bool increasesStepCount = true, + int defaultCPCost = 0, + int defaultEfficiency = 0, + float defaultSuccessRate = 1) : + BaseAction( + category, level, actionId, + macroWaitTime, + increasesProgress, increasesQuality, + durabilityCost, increasesStepCount, + defaultCPCost, defaultEfficiency, defaultSuccessRate) { - public BaseBuffAction() - { - MacroWaitTime = 2; - DurabilityCost = 0; - } - // Non-instanced properties - public EffectType Effect; - public int Duration = 1; + public readonly EffectType Effect = effect; + public readonly int Duration = duration; - public override void UseSuccess(Simulator s, ref int eff) => + public override void UseSuccess(Simulator s) => s.AddEffect(Effect, Duration); public override string GetTooltip(Simulator s, bool addUsability) diff --git a/Simulator/Actions/BaseComboAction.cs b/Simulator/Actions/BaseComboAction.cs index c17c9e9..cfe1a24 100644 --- a/Simulator/Actions/BaseComboAction.cs +++ b/Simulator/Actions/BaseComboAction.cs @@ -1,17 +1,20 @@ namespace Craftimizer.Simulator.Actions; -public abstract class BaseComboAction : BaseAction +public abstract class BaseComboAction( + ActionType actionTypeA, ActionType actionTypeB, + BaseAction actionA, BaseAction actionB, + int? defaultCPCost = null) : + BaseAction( + ActionCategory.Combo, Math.Max(actionA.Level, actionA.Level), actionB.ActionId, + increasesProgress: actionA.IncreasesProgress || actionB.IncreasesProgress, + increasesQuality: actionA.IncreasesQuality || actionB.IncreasesQuality, + defaultCPCost: defaultCPCost ?? (actionA.DefaultCPCost + actionB.DefaultCPCost)) { - public abstract ActionType ActionTypeA { get; } - public abstract ActionType ActionTypeB { get; } + public readonly ActionType ActionTypeA = actionTypeA; + public readonly ActionType ActionTypeB = actionTypeB; - public BaseComboAction() - { - Category = ActionCategory.Combo; - } - - protected bool BaseCouldUse(Simulator s, ref int cost) => - base.CouldUse(s, ref cost); + protected bool BaseCouldUse(Simulator s) => + base.CouldUse(s); private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects) { diff --git a/Simulator/Actions/BaseComboActionImpl.cs b/Simulator/Actions/BaseComboActionImpl.cs index 9866a76..c071d76 100644 --- a/Simulator/Actions/BaseComboActionImpl.cs +++ b/Simulator/Actions/BaseComboActionImpl.cs @@ -1,36 +1,26 @@ namespace Craftimizer.Simulator.Actions; -internal abstract class BaseComboAction : BaseComboAction where A : BaseAction, new() where B : BaseAction, new() +internal abstract class BaseComboAction( + ActionType actionTypeA, ActionType actionTypeB, + int? baseCPCost = null) : + BaseComboAction( + actionTypeA, actionTypeB, + ActionA, ActionB, + baseCPCost + ) where A : BaseAction, new() where B : BaseAction, new() { protected static readonly A ActionA = new(); protected static readonly B ActionB = new(); - protected BaseComboAction() - { - Level = ActionB.Level; - ActionId = ActionB.ActionId; - IncreasesProgress = ActionA.IncreasesProgress || ActionB.IncreasesProgress; - IncreasesQuality = ActionA.IncreasesQuality || ActionB.IncreasesQuality; - } - - public override void CPCost(Simulator s, ref int cost) - { - var costTmp = 0; - ActionA.CPCost(s, ref costTmp); - cost += costTmp; - ActionB.CPCost(s, ref costTmp); - cost += costTmp; - } - public override bool IsPossible(Simulator s) => ActionA.IsPossible(s) && ActionB.IsPossible(s); - public override bool CouldUse(Simulator s, ref int cost) => - BaseCouldUse(s, ref cost) && VerifyDurability2(s, ActionA.DurabilityCost); + public override bool CouldUse(Simulator s) => + BaseCouldUse(s) && VerifyDurability2(s, ActionA.DurabilityCost); - public override void Use(Simulator s, ref int cost, ref float success, ref int eff) + public override void Use(Simulator s) { - ActionA.Use(s, ref cost, ref success, ref eff); - ActionB.Use(s, ref cost, ref success, ref eff); + ActionA.Use(s); + ActionB.Use(s); } public override string GetTooltip(Simulator s, bool addUsability) => diff --git a/Simulator/Actions/BasicSynthesis.cs b/Simulator/Actions/BasicSynthesis.cs index 307c8cf..b76a38c 100644 --- a/Simulator/Actions/BasicSynthesis.cs +++ b/Simulator/Actions/BasicSynthesis.cs @@ -1,26 +1,13 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class BasicSynthesis : BaseAction +internal sealed class BasicSynthesis() : BaseAction( + ActionCategory.Synthesis, 1, 100001, + increasesProgress: true, + defaultCPCost: 0, + defaultEfficiency: 100 + ) { - public int CP; - public int EfficiencyNormal = 100; - public int EfficiencyGood = 120; - - public BasicSynthesis() - { - Category = ActionCategory.Synthesis; - IncreasesProgress = true; - ActionId = 100001; - Level = 1; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } // Basic Synthesis Mastery Trait - public override void Efficiency(Simulator s, ref int eff) - { - eff = s.Input.Stats.Level >= 31 ? EfficiencyGood : EfficiencyNormal; - } + public override int Efficiency(Simulator s) => + s.Input.Stats.Level >= 31 ? 120 : 100; } diff --git a/Simulator/Actions/BasicTouch.cs b/Simulator/Actions/BasicTouch.cs index 3fa0500..39b392a 100644 --- a/Simulator/Actions/BasicTouch.cs +++ b/Simulator/Actions/BasicTouch.cs @@ -1,25 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class BasicTouch : BaseAction +internal sealed class BasicTouch() : BaseAction( + ActionCategory.Quality, 5, 100002, + increasesQuality: true, + defaultCPCost: 18, + defaultEfficiency: 100) { - public int CP = 18; - public int eff = 100; - public BasicTouch() - { - Category = ActionCategory.Quality; - Level = 5; - ActionId = 100002; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = this.eff; - } } diff --git a/Simulator/Actions/ByregotsBlessing.cs b/Simulator/Actions/ByregotsBlessing.cs index a90edad..fb8164b 100644 --- a/Simulator/Actions/ByregotsBlessing.cs +++ b/Simulator/Actions/ByregotsBlessing.cs @@ -1,32 +1,20 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class ByregotsBlessing : BaseAction +internal sealed class ByregotsBlessing() : BaseAction( + ActionCategory.Quality, 50, 100339, + increasesQuality: true, + defaultCPCost: 24, + defaultEfficiency: 100) { - public int CP = 24; + public override int Efficiency(Simulator s) => + 100 + (20 * s.GetEffectStrength(EffectType.InnerQuiet)); - public ByregotsBlessing() - { - Category = ActionCategory.Quality; - Level = 50; - ActionId = 100339; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 100 + (20 * s.GetEffectStrength(EffectType.InnerQuiet)); - } - - public override bool CouldUse(Simulator s, ref int cost) => s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s, ref cost); + public override bool CouldUse(Simulator s) => + s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.RemoveEffect(EffectType.InnerQuiet); } } diff --git a/Simulator/Actions/CarefulObservation.cs b/Simulator/Actions/CarefulObservation.cs index d5db0ea..78d8b51 100644 --- a/Simulator/Actions/CarefulObservation.cs +++ b/Simulator/Actions/CarefulObservation.cs @@ -1,30 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class CarefulObservation : BaseAction +internal sealed class CarefulObservation() : BaseAction( + ActionCategory.Other, 55, 100395, + durabilityCost: 0, increasesStepCount: false, + defaultCPCost: 0 + ) { - public int CP = 0; - - public CarefulObservation() - { - Category = ActionCategory.Other; - Level = 55; - ActionId = 100395; - MacroWaitTime = 3; - DurabilityCost = 0; - IncreasesStepCount = false; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - public override bool IsPossible(Simulator s) => base.IsPossible(s) && s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3; - public override bool CouldUse(Simulator s, ref int cost) => s.ActionStates.CarefulObservationCount < 3; + public override bool CouldUse(Simulator s) => + s.ActionStates.CarefulObservationCount < 3; - public override void UseSuccess(Simulator s, ref int eff) => s.StepCondition(); + public override void UseSuccess(Simulator s) => + s.StepCondition(); public override string GetTooltip(Simulator s, bool addUsability) => $"{base.GetTooltip(s, addUsability)}Specialist Only\n"; diff --git a/Simulator/Actions/CarefulSynthesis.cs b/Simulator/Actions/CarefulSynthesis.cs index 3b61c46..eeb4e15 100644 --- a/Simulator/Actions/CarefulSynthesis.cs +++ b/Simulator/Actions/CarefulSynthesis.cs @@ -1,27 +1,13 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class CarefulSynthesis : BaseAction +internal sealed class CarefulSynthesis() : BaseAction( + ActionCategory.Synthesis, 62, 100203, + increasesProgress: true, + defaultCPCost: 7, + defaultEfficiency: 150 + ) { - public int CP = 7; - public int EfficiencyNormal = 150; - public int EfficiencyMastery = 180; - - public CarefulSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 62; - ActionId = 100203; - IncreasesProgress = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - // Careful Synthesis Mastery Trait - public override void Efficiency(Simulator s, ref int eff) - { - eff = s.Input.Stats.Level >= 82 ? EfficiencyMastery : EfficiencyNormal; - } + public override int Efficiency(Simulator s) => + s.Input.Stats.Level >= 82 ? 180 : 150; } diff --git a/Simulator/Actions/DelicateSynthesis.cs b/Simulator/Actions/DelicateSynthesis.cs index 618cf50..5f0fc3a 100644 --- a/Simulator/Actions/DelicateSynthesis.cs +++ b/Simulator/Actions/DelicateSynthesis.cs @@ -1,26 +1,11 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class DelicateSynthesis : BaseAction +internal sealed class DelicateSynthesis() : BaseAction( + ActionCategory.Synthesis, 76, 100323, + increasesProgress: true, increasesQuality: true, + defaultCPCost: 32, + defaultEfficiency: 100 + ) { - public int CP = 32; - public int Eff = 100; - public DelicateSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 76; - ActionId = 100323; - IncreasesProgress = true; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = Eff; - } } diff --git a/Simulator/Actions/FinalAppraisal.cs b/Simulator/Actions/FinalAppraisal.cs index 0da441c..6ca7772 100644 --- a/Simulator/Actions/FinalAppraisal.cs +++ b/Simulator/Actions/FinalAppraisal.cs @@ -1,21 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class FinalAppraisal : BaseBuffAction +internal sealed class FinalAppraisal() : BaseBuffAction( + ActionCategory.Synthesis, 42, 19012, + EffectType.FinalAppraisal, duration: 4, + increasesStepCount: false, + defaultCPCost: 1) { - public int CP = 1; - public FinalAppraisal() - { - Category = ActionCategory.Synthesis; - Level = 42; - ActionId = 19012; - Effect = EffectType.FinalAppraisal; - Duration = 4; - IncreasesStepCount = false; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } } diff --git a/Simulator/Actions/FocusedSynthesis.cs b/Simulator/Actions/FocusedSynthesis.cs index 0f46196..9ddde41 100644 --- a/Simulator/Actions/FocusedSynthesis.cs +++ b/Simulator/Actions/FocusedSynthesis.cs @@ -1,32 +1,13 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class FocusedSynthesis : BaseAction +internal sealed class FocusedSynthesis() : BaseAction( + ActionCategory.Synthesis, 67, 100235, + increasesProgress: true, + defaultCPCost: 5, + defaultEfficiency: 200, + defaultSuccessRate: 0.50f + ) { - public int CP = 5; - public int Eff = 200; - public float SuccessNormal = 0.50f; - public float SuccessObserved = 1.00f; - - public FocusedSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 67; - ActionId = 100235; - IncreasesProgress = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = Eff; - } - - public override void SuccessRate(Simulator s, ref float success) - { - success = s.ActionStates.Observed ? SuccessObserved : SuccessNormal; - } + public override float SuccessRate(Simulator s) => + s.ActionStates.Observed ? 1.00f : 0.50f; } diff --git a/Simulator/Actions/FocusedSynthesisCombo.cs b/Simulator/Actions/FocusedSynthesisCombo.cs index 819b586..f3951fb 100644 --- a/Simulator/Actions/FocusedSynthesisCombo.cs +++ b/Simulator/Actions/FocusedSynthesisCombo.cs @@ -1,7 +1,8 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class FocusedSynthesisCombo : BaseComboAction +internal sealed class FocusedSynthesisCombo() : BaseComboAction( + ActionType.Observe, ActionType.FocusedSynthesis + ) { - public override ActionType ActionTypeA => ActionType.Observe; - public override ActionType ActionTypeB => ActionType.FocusedSynthesis; + } diff --git a/Simulator/Actions/FocusedTouch.cs b/Simulator/Actions/FocusedTouch.cs index 2a6afa1..5798590 100644 --- a/Simulator/Actions/FocusedTouch.cs +++ b/Simulator/Actions/FocusedTouch.cs @@ -1,33 +1,13 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class FocusedTouch : BaseAction +internal sealed class FocusedTouch() : BaseAction( + ActionCategory.Quality, 68, 100243, + increasesQuality: true, + defaultCPCost: 18, + defaultEfficiency: 150, + defaultSuccessRate: 0.50f + ) { - public int CP = 18; - public int Eff = 150; - public float SuccessNormal = 0.50f; - public float SuccessObserved = 1.00f; - - public FocusedTouch() - { - Category = ActionCategory.Quality; - Level = 68; - ActionId = 100243; - IncreasesQuality = true; - } - - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = Eff; - } - - public override void SuccessRate(Simulator s, ref float success) - { - success = s.ActionStates.Observed ? SuccessObserved : SuccessNormal; - } + public override float SuccessRate(Simulator s) => + s.ActionStates.Observed ? 1.00f : 0.50f; } diff --git a/Simulator/Actions/FocusedTouchCombo.cs b/Simulator/Actions/FocusedTouchCombo.cs index 98f7a15..f1c16c8 100644 --- a/Simulator/Actions/FocusedTouchCombo.cs +++ b/Simulator/Actions/FocusedTouchCombo.cs @@ -1,7 +1,8 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class FocusedTouchCombo : BaseComboAction +internal sealed class FocusedTouchCombo() : BaseComboAction( + ActionType.Observe, ActionType.FocusedTouch + ) { - public override ActionType ActionTypeA => ActionType.Observe; - public override ActionType ActionTypeB => ActionType.FocusedTouch; + } diff --git a/Simulator/Actions/GreatStrides.cs b/Simulator/Actions/GreatStrides.cs index 8567b94..507a714 100644 --- a/Simulator/Actions/GreatStrides.cs +++ b/Simulator/Actions/GreatStrides.cs @@ -1,20 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class GreatStrides : BaseBuffAction +internal sealed class GreatStrides() : BaseBuffAction( + ActionCategory.Buffs, 21, 260, + EffectType.GreatStrides, duration: 3, + increasesStepCount: false, + defaultCPCost: 32) { - public int CP = 32; - public GreatStrides() - { - Category = ActionCategory.Buffs; - Level = 21; - ActionId = 260; - Effect = EffectType.GreatStrides; - Duration = 3; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = CP; - } } diff --git a/Simulator/Actions/Groundwork.cs b/Simulator/Actions/Groundwork.cs index 1b23e50..dbd1824 100644 --- a/Simulator/Actions/Groundwork.cs +++ b/Simulator/Actions/Groundwork.cs @@ -1,26 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Groundwork : BaseAction +internal sealed class Groundwork() : BaseAction( + ActionCategory.Synthesis, 72, 100403, + increasesProgress: true, + durabilityCost: 20, + defaultCPCost: 18, + defaultEfficiency: 300 + ) { - public Groundwork() - { - Category = ActionCategory.Synthesis; - Level = 72; - ActionId = 100403; - IncreasesProgress = true; - DurabilityCost = 20; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 18; - } - - public override void Efficiency(Simulator s, ref int eff) + public override int Efficiency(Simulator s) { // Groundwork Mastery Trait - eff = s.Input.Stats.Level >= 86 ? 360 : 300; + var eff = s.Input.Stats.Level >= 86 ? 360 : 300; if (s.Durability < s.CalculateDurabilityCost(DurabilityCost)) eff /= 2; + return eff; } } diff --git a/Simulator/Actions/HastyTouch.cs b/Simulator/Actions/HastyTouch.cs index 3914972..66b7897 100644 --- a/Simulator/Actions/HastyTouch.cs +++ b/Simulator/Actions/HastyTouch.cs @@ -1,27 +1,12 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class HastyTouch : BaseAction +internal sealed class HastyTouch() : BaseAction( + ActionCategory.Quality, 9, 100355, + increasesQuality: true, + defaultCPCost: 0, + defaultEfficiency: 100, + defaultSuccessRate: 0.60f + ) { - public HastyTouch() - { - Category = ActionCategory.Quality; - Level = 9; - ActionId = 100355; - IncreasesQuality = true; - } - public override void CPCost(Simulator s, ref int cost) - { - cost = 0; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 100; - } - - public override void SuccessRate(Simulator s, ref float success) - { - success = 0.60f; - } } diff --git a/Simulator/Actions/HeartAndSoul.cs b/Simulator/Actions/HeartAndSoul.cs index 544adf8..bca6a63 100644 --- a/Simulator/Actions/HeartAndSoul.cs +++ b/Simulator/Actions/HeartAndSoul.cs @@ -1,26 +1,17 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class HeartAndSoul : BaseBuffAction +internal sealed class HeartAndSoul() : BaseBuffAction( + ActionCategory.Other, 86, 100419, + EffectType.HeartAndSoul, duration: 1, + macroWaitTime: 3, + increasesStepCount: false + ) { - public HeartAndSoul() - { - Level = 86; - Effect = EffectType.HeartAndSoul; - MacroWaitTime = 3; - ActionId = 100419; - Category = ActionCategory.Other; - IncreasesStepCount = false; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 0; - } - public override bool IsPossible(Simulator s) => base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul; - public override bool CouldUse(Simulator s, ref int cost) => !s.ActionStates.UsedHeartAndSoul; + public override bool CouldUse(Simulator s) => + !s.ActionStates.UsedHeartAndSoul; public override string GetTooltip(Simulator s, bool addUsability) => $"{GetBaseTooltip(s, addUsability)}Specialist Only\n"; diff --git a/Simulator/Actions/Innovation.cs b/Simulator/Actions/Innovation.cs index beba15c..7e06706 100644 --- a/Simulator/Actions/Innovation.cs +++ b/Simulator/Actions/Innovation.cs @@ -1,19 +1,9 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Innovation : BaseBuffAction +internal sealed class Innovation() : BaseBuffAction( + ActionCategory.Buffs, 26, 19004, + EffectType.Innovation, duration: 4, + defaultCPCost: 18) { - public Innovation() - { - Level = 26; - Effect = EffectType.Innovation; - MacroWaitTime = 3; - ActionId = 19004; - Category = ActionCategory.Buffs; - Duration = 4; - } - public override void CPCost(Simulator s, ref int cost) - { - cost = 18; - } } diff --git a/Simulator/Actions/IntensiveSynthesis.cs b/Simulator/Actions/IntensiveSynthesis.cs index f34616d..bb66c95 100644 --- a/Simulator/Actions/IntensiveSynthesis.cs +++ b/Simulator/Actions/IntensiveSynthesis.cs @@ -1,32 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class IntensiveSynthesis : BaseAction +internal sealed class IntensiveSynthesis() : BaseAction( + ActionCategory.Synthesis, 78, 100315, + increasesProgress: true, + defaultCPCost: 6, + defaultEfficiency: 400 + ) { - public IntensiveSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 78; - ActionId = 100315; - IncreasesProgress = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 6; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 400; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CouldUse(s, ref cost); + && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); if (s.Condition != Condition.Good && s.Condition != Condition.Excellent) s.RemoveEffect(EffectType.HeartAndSoul); } diff --git a/Simulator/Actions/Manipulation.cs b/Simulator/Actions/Manipulation.cs index bed327d..571d296 100644 --- a/Simulator/Actions/Manipulation.cs +++ b/Simulator/Actions/Manipulation.cs @@ -1,30 +1,18 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Manipulation : BaseBuffAction +internal sealed class Manipulation() : BaseBuffAction( + ActionCategory.Durability, 65, 4574, + EffectType.Manipulation, duration: 8, + defaultCPCost: 96) { - public Manipulation() - { - Category = ActionCategory.Durability; - Level = 65; - ActionId = 4574; - Effect = EffectType.Manipulation; - Duration = 8; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 96; - } - public override bool IsPossible(Simulator s) => s.Input.Stats.CanUseManipulation && base.IsPossible(s); - public override void Use(Simulator s, ref int cost, ref float success, ref int eff) + public override void Use(Simulator s) { - UseSuccess(s, ref eff); - CPCost(s, ref cost); + UseSuccess(s); - s.ReduceCP(cost); + s.ReduceCP(CPCost(s)); s.IncreaseStepCount(); diff --git a/Simulator/Actions/MastersMend.cs b/Simulator/Actions/MastersMend.cs index 9fd1e02..7416a20 100644 --- a/Simulator/Actions/MastersMend.cs +++ b/Simulator/Actions/MastersMend.cs @@ -1,20 +1,11 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class MastersMend : BaseAction +internal sealed class MastersMend() : BaseAction( + ActionCategory.Durability, 7, 100003, + durabilityCost: 0, + defaultCPCost: 88 + ) { - public MastersMend() - { - Category = ActionCategory.Durability; - Level = 7; - ActionId = 100003; - DurabilityCost = 0; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 88; - } - - public override void UseSuccess(Simulator s, ref int eff) => + public override void UseSuccess(Simulator s) => s.RestoreDurability(30); } diff --git a/Simulator/Actions/MuscleMemory.cs b/Simulator/Actions/MuscleMemory.cs index 9acec69..fa72d54 100644 --- a/Simulator/Actions/MuscleMemory.cs +++ b/Simulator/Actions/MuscleMemory.cs @@ -1,32 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class MuscleMemory : BaseAction +internal sealed class MuscleMemory() : BaseAction( + ActionCategory.FirstTurn, 54, 100379, + increasesProgress: true, + defaultCPCost: 6, + defaultEfficiency: 300 + ) { - public MuscleMemory() - { - Category = ActionCategory.FirstTurn; - Level = 54; - ActionId = 100379; - IncreasesProgress = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 6; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 300; - } - public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); - public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost); + public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.AddEffect(EffectType.MuscleMemory, 5); } } diff --git a/Simulator/Actions/Observe.cs b/Simulator/Actions/Observe.cs index 6ebb0a0..5ff3cbf 100644 --- a/Simulator/Actions/Observe.cs +++ b/Simulator/Actions/Observe.cs @@ -1,17 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Observe : BaseAction +internal sealed class Observe() : BaseAction( + ActionCategory.Other, 13, 100010, + durabilityCost: 0, + defaultCPCost: 7 + ) { - public Observe() - { - Category = ActionCategory.Other; - Level = 13; - ActionId = 100010; - DurabilityCost = 0; - } - public override void CPCost(Simulator s, ref int cost) - { - cost = 7; - } } diff --git a/Simulator/Actions/PreciseTouch.cs b/Simulator/Actions/PreciseTouch.cs index 7c77501..95c1ead 100644 --- a/Simulator/Actions/PreciseTouch.cs +++ b/Simulator/Actions/PreciseTouch.cs @@ -1,32 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class PreciseTouch : BaseAction +internal sealed class PreciseTouch() : BaseAction( + ActionCategory.Quality, 53, 100128, + increasesQuality: true, + defaultCPCost: 18, + defaultEfficiency: 150 + ) { - public PreciseTouch() - { - Category = ActionCategory.Quality; - Level = 53; - ActionId = 100128; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 18; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 150; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CouldUse(s, ref cost); + && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.StrengthenEffect(EffectType.InnerQuiet); if (s.Condition != Condition.Good && s.Condition != Condition.Excellent) s.RemoveEffect(EffectType.HeartAndSoul); diff --git a/Simulator/Actions/PreparatoryTouch.cs b/Simulator/Actions/PreparatoryTouch.cs index 005b394..f571f1e 100644 --- a/Simulator/Actions/PreparatoryTouch.cs +++ b/Simulator/Actions/PreparatoryTouch.cs @@ -1,29 +1,15 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class PreparatoryTouch : BaseAction +internal sealed class PreparatoryTouch() : BaseAction( + ActionCategory.Quality, 71, 100299, + increasesQuality: true, + durabilityCost: 20, + defaultCPCost: 40, + defaultEfficiency: 200) { - public PreparatoryTouch() + public override void UseSuccess(Simulator s) { - Category = ActionCategory.Quality; - Level = 71; - ActionId = 100299; - IncreasesQuality = true; - DurabilityCost = 20; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 40; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 200; - } - - public override void UseSuccess(Simulator s, ref int eff) - { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.StrengthenEffect(EffectType.InnerQuiet); } } diff --git a/Simulator/Actions/PrudentSynthesis.cs b/Simulator/Actions/PrudentSynthesis.cs index b53000e..90d7bf2 100644 --- a/Simulator/Actions/PrudentSynthesis.cs +++ b/Simulator/Actions/PrudentSynthesis.cs @@ -1,28 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class PrudentSynthesis : BaseAction +internal sealed class PrudentSynthesis() : BaseAction( + ActionCategory.Synthesis, 88, 100427, + increasesProgress: true, + durabilityCost: 5, + defaultCPCost: 18, + defaultEfficiency: 180 + ) { - - public PrudentSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 88; - ActionId = 100427; - IncreasesProgress = true; - DurabilityCost /= 2; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 18; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 180; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) - && base.CouldUse(s, ref cost); + && base.CouldUse(s); } diff --git a/Simulator/Actions/PrudentTouch.cs b/Simulator/Actions/PrudentTouch.cs index 36879fa..076c484 100644 --- a/Simulator/Actions/PrudentTouch.cs +++ b/Simulator/Actions/PrudentTouch.cs @@ -1,27 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class PrudentTouch : BaseAction +internal sealed class PrudentTouch() : BaseAction( + ActionCategory.Quality, 66, 100227, + increasesQuality: true, + durabilityCost: 5, + defaultCPCost: 25, + defaultEfficiency: 100 + ) { - public PrudentTouch() - { - Category = ActionCategory.Quality; - Level = 66; - ActionId = 100227; - IncreasesQuality = true; - DurabilityCost /= 2; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 25; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 100; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) - && base.CouldUse(s, ref cost); + && base.CouldUse(s); } diff --git a/Simulator/Actions/RapidSynthesis.cs b/Simulator/Actions/RapidSynthesis.cs index 517744e..703df9d 100644 --- a/Simulator/Actions/RapidSynthesis.cs +++ b/Simulator/Actions/RapidSynthesis.cs @@ -1,28 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class RapidSynthesis : BaseAction +internal sealed class RapidSynthesis() : BaseAction( + ActionCategory.Synthesis, 9, 100363, + increasesProgress: true, + defaultCPCost: 0, + defaultEfficiency: 250, + defaultSuccessRate: 0.50f + ) { - public RapidSynthesis() - { - Category = ActionCategory.Synthesis; - Level = 9; - ActionId = 100363; - IncreasesProgress = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 0; - } - // Rapid Synthesis Mastery Trait - public override void Efficiency(Simulator s, ref int eff) - { - eff = s.Input.Stats.Level >= 63 ? 500 : 250; - } - - public override void SuccessRate(Simulator s, ref float success) - { - success = 0.50f; - } + public override int Efficiency(Simulator s) => + s.Input.Stats.Level >= 63 ? 500 : 250; } diff --git a/Simulator/Actions/Reflect.cs b/Simulator/Actions/Reflect.cs index f2b5612..bc459ed 100644 --- a/Simulator/Actions/Reflect.cs +++ b/Simulator/Actions/Reflect.cs @@ -1,32 +1,19 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Reflect : BaseAction +internal sealed class Reflect() : BaseAction( + ActionCategory.FirstTurn, 69, 100387, + increasesQuality: true, + defaultCPCost: 6, + defaultEfficiency: 100 + ) { - public Reflect() - { - Category = ActionCategory.FirstTurn; - Level = 69; - ActionId = 100387; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 6; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 100; - } - public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); - public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost); + public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.StrengthenEffect(EffectType.InnerQuiet); } } diff --git a/Simulator/Actions/StandardTouch.cs b/Simulator/Actions/StandardTouch.cs index 4a8701d..ca62358 100644 --- a/Simulator/Actions/StandardTouch.cs +++ b/Simulator/Actions/StandardTouch.cs @@ -1,22 +1,12 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class StandardTouch : BaseAction +internal sealed class StandardTouch() : BaseAction( + ActionCategory.Quality, 18, 100004, + increasesQuality: true, + defaultCPCost: 32, + defaultEfficiency: 125 + ) { - public StandardTouch() - { - Category = ActionCategory.Quality; - Level = 18; - ActionId = 100004; - IncreasesQuality = true; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = s.ActionStates.TouchComboIdx == 1 ? 18 : 32; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 125; - } + public override int CPCost(Simulator s) => + s.ActionStates.TouchComboIdx == 1 ? 18 : 32; } diff --git a/Simulator/Actions/StandardTouchCombo.cs b/Simulator/Actions/StandardTouchCombo.cs index 5fcea98..745d0e5 100644 --- a/Simulator/Actions/StandardTouchCombo.cs +++ b/Simulator/Actions/StandardTouchCombo.cs @@ -1,7 +1,8 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class StandardTouchCombo : BaseComboAction +internal sealed class StandardTouchCombo() : BaseComboAction( + ActionType.BasicTouch, ActionType.StandardTouch, 18 * 2 + ) { - public override ActionType ActionTypeA => ActionType.BasicTouch; - public override ActionType ActionTypeB => ActionType.StandardTouch; + } diff --git a/Simulator/Actions/TrainedEye.cs b/Simulator/Actions/TrainedEye.cs index 302022c..fa3f467 100644 --- a/Simulator/Actions/TrainedEye.cs +++ b/Simulator/Actions/TrainedEye.cs @@ -1,28 +1,21 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class TrainedEye : BaseAction +internal sealed class TrainedEye() : BaseAction( + ActionCategory.FirstTurn, 80, 100283, + increasesQuality: true, + defaultCPCost: 250 + ) { - public TrainedEye() - { - Category = ActionCategory.FirstTurn; - Level = 80; - ActionId = 100283; - IncreasesQuality = true; - } + public override bool IsPossible(Simulator s) => + s.IsFirstStep && + !s.Input.Recipe.IsExpert && + s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) && + base.IsPossible(s); - public override void CPCost(Simulator s,ref int cost) - { - cost = 250; - } + public override bool CouldUse(Simulator s) => + s.IsFirstStep && base.CouldUse(s); - public override bool IsPossible(Simulator s) => s.IsFirstStep && - !s.Input.Recipe.IsExpert && - s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) && - base.IsPossible(s); - - public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost); - - public override void UseSuccess(Simulator s, ref int eff) => + public override void UseSuccess(Simulator s) => s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality); public override string GetTooltip(Simulator s, bool addUsability) => diff --git a/Simulator/Actions/TrainedFinesse.cs b/Simulator/Actions/TrainedFinesse.cs index be013ba..79888f7 100644 --- a/Simulator/Actions/TrainedFinesse.cs +++ b/Simulator/Actions/TrainedFinesse.cs @@ -1,27 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class TrainedFinesse : BaseAction +internal sealed class TrainedFinesse() : BaseAction( + ActionCategory.Quality, 90, 100435, + increasesQuality: true, + durabilityCost: 0, + defaultCPCost: 32, + defaultEfficiency: 100 + ) { - public TrainedFinesse() - { - Category = ActionCategory.Quality; - Level = 90; - ActionId = 100435; - IncreasesQuality = true; - DurabilityCost = 0; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 32; - } - - public override void Efficiency(Simulator s, ref int eff) - { - eff = 100; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => s.GetEffectStrength(EffectType.InnerQuiet) == 10 - && base.CouldUse(s, ref cost); + && base.CouldUse(s); } diff --git a/Simulator/Actions/TricksOfTheTrade.cs b/Simulator/Actions/TricksOfTheTrade.cs index 826f498..bc7d6c6 100644 --- a/Simulator/Actions/TricksOfTheTrade.cs +++ b/Simulator/Actions/TricksOfTheTrade.cs @@ -1,25 +1,16 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class TricksOfTheTrade : BaseAction +internal sealed class TricksOfTheTrade() : BaseAction( + ActionCategory.Other, 13, 100371, + durabilityCost: 0, + defaultCPCost: 0 + ) { - public TricksOfTheTrade() - { - Category = ActionCategory.Other; - Level = 13; - ActionId = 100371; - DurabilityCost = 0; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 0; - } - - public override bool CouldUse(Simulator s, ref int cost) => + public override bool CouldUse(Simulator s) => (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) - && base.CouldUse(s, ref cost); + && base.CouldUse(s); - public override void UseSuccess(Simulator s, ref int eff) + public override void UseSuccess(Simulator s) { s.RestoreCP(20); if (s.Condition != Condition.Good && s.Condition != Condition.Excellent) diff --git a/Simulator/Actions/Veneration.cs b/Simulator/Actions/Veneration.cs index e99aa3b..d6b1686 100644 --- a/Simulator/Actions/Veneration.cs +++ b/Simulator/Actions/Veneration.cs @@ -1,18 +1,10 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class Veneration : BaseBuffAction +internal sealed class Veneration() : BaseBuffAction( + ActionCategory.Buffs, 15, 19297, + EffectType.Veneration, duration: 4, + defaultCPCost: 18 + ) { - public Veneration() - { - Category = ActionCategory.Buffs; - Level = 15; - ActionId = 19297; - Effect = EffectType.Veneration; - Duration = 4; - } - public override void CPCost(Simulator s, ref int cost) - { - cost = 18; - } } diff --git a/Simulator/Actions/WasteNot.cs b/Simulator/Actions/WasteNot.cs index 1fcf8e5..0c9f5c6 100644 --- a/Simulator/Actions/WasteNot.cs +++ b/Simulator/Actions/WasteNot.cs @@ -1,24 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class WasteNot : BaseBuffAction +internal sealed class WasteNot() : BaseBuffAction( + ActionCategory.Durability, 15, 4631, + EffectType.WasteNot, duration: 4, + defaultCPCost: 56 + ) { - public WasteNot() + public override void UseSuccess(Simulator s) { - Category = ActionCategory.Durability; - Level = 15; - ActionId = 4631; - Effect = EffectType.WasteNot; - Duration = 4; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 56; - } - - public override void UseSuccess(Simulator s, ref int eff) - { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.RemoveEffect(EffectType.WasteNot2); } } diff --git a/Simulator/Actions/WasteNot2.cs b/Simulator/Actions/WasteNot2.cs index 082e748..e09fd1e 100644 --- a/Simulator/Actions/WasteNot2.cs +++ b/Simulator/Actions/WasteNot2.cs @@ -1,24 +1,14 @@ namespace Craftimizer.Simulator.Actions; -internal sealed class WasteNot2 : BaseBuffAction +internal sealed class WasteNot2() : BaseBuffAction( + ActionCategory.Durability, 47, 4639, + EffectType.WasteNot2, duration: 8, + defaultCPCost: 98 + ) { - public WasteNot2() + public override void UseSuccess(Simulator s) { - Category = ActionCategory.Durability; - Level = 47; - ActionId = 4639; - Effect = EffectType.WasteNot2; - Duration = 8; - } - - public override void CPCost(Simulator s, ref int cost) - { - cost = 98; - } - - public override void UseSuccess(Simulator s, ref int eff) - { - base.UseSuccess(s, ref eff); + base.UseSuccess(s); s.RemoveEffect(EffectType.WasteNot); } } diff --git a/Simulator/Craftimizer.Simulator.csproj b/Simulator/Craftimizer.Simulator.csproj index 1f2f063..b5de580 100644 --- a/Simulator/Craftimizer.Simulator.csproj +++ b/Simulator/Craftimizer.Simulator.csproj @@ -3,6 +3,7 @@ net7.0 enable + 12.0 enable x64 Debug;Release diff --git a/Simulator/Simulator.cs b/Simulator/Simulator.cs index 5c84b4d..b984d9b 100644 --- a/Simulator/Simulator.cs +++ b/Simulator/Simulator.cs @@ -21,10 +21,6 @@ public class Simulator public ref Effects ActiveEffects => ref state.ActiveEffects; public ref ActionStates ActionStates => ref state.ActionStates; - private int cost; - private int eff; - private float success; - public bool IsFirstStep => state.StepCount == 0; public virtual CompletionState CompletionState { @@ -54,7 +50,7 @@ public SimulationState ExecuteUnchecked(in SimulationState state, ActionType act [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ExecuteUnchecked(ActionType action) => - action.Base().Use(this, ref cost, ref success, ref eff); + action.Base().Use(this); private ActionResponse Execute(ActionType action) { @@ -62,7 +58,7 @@ private ActionResponse Execute(ActionType action) return ActionResponse.SimulationComplete; var baseAction = action.Base(); - if (!baseAction.CanUse(this, ref cost)) + if (!baseAction.CanUse(this)) { if (baseAction.Level > Input.Stats.Level) return ActionResponse.ActionNotUnlocked; @@ -70,12 +66,12 @@ private ActionResponse Execute(ActionType action) return ActionResponse.ActionNotUnlocked; if (action is ActionType.CarefulObservation or ActionType.HeartAndSoul && !Input.Stats.IsSpecialist) return ActionResponse.ActionNotUnlocked; - if (cost > CP) + if (baseAction.CPCost(this) > CP) return ActionResponse.NotEnoughCP; return ActionResponse.CannotUseAction; } - baseAction.Use(this, ref cost, ref success, ref eff); + baseAction.Use(this); return ActionResponse.UsedAction; } diff --git a/Solver/Intrinsics.cs b/Solver/Intrinsics.cs index d901f7f..6eca3b9 100644 --- a/Solver/Intrinsics.cs +++ b/Solver/Intrinsics.cs @@ -34,13 +34,22 @@ private static int HMaxIndexScalar(Vector v, int len) return m; } + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Vector256 ClearLastN(Vector256 data, int len) + { + var threshold = Vector256.Create(len); + var index = Vector256.Create(0, 1, 2, 3, 4, 5, 6, 7); + return Avx.And(Avx2.CompareGreaterThan(threshold, index).AsSingle(), data); + } + [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] // https://stackoverflow.com/a/23592221 private static int HMaxIndexAVX2(Vector v, int len) { // Remove NaNs - var vfilt = Avx.Blend(v.AsVector256(), Vector256.Zero, (byte)~((1 << len) - 1)); + var vfilt = ClearLastN(v.AsVector256(), len); // Find max value and broadcast to all lanes var vmax128 = HMax(vfilt); @@ -50,7 +59,7 @@ private static int HMaxIndexAVX2(Vector v, int len) var vcmp = Avx.CompareEqual(vfilt, vmax); var mask = unchecked((uint)Avx2.MoveMask(vcmp.AsByte())); - var inverseIdx = BitOperations.LeadingZeroCount(mask << (8 - len << 2)) >> 2; + var inverseIdx = BitOperations.LeadingZeroCount(mask << ((8 - len) << 2)) >> 2; return len - 1 - inverseIdx; } @@ -158,6 +167,7 @@ public static int NthBitSet(ulong value, int n) [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SkipLocalsInit] public static Vector ReciprocalSqrt(Vector data) { if (Avx.IsSupported && Vector.Count >= Vector256.Count) diff --git a/Solver/Simulator.cs b/Solver/Simulator.cs index 7d91b97..843e86c 100644 --- a/Solver/Simulator.cs +++ b/Solver/Simulator.cs @@ -41,10 +41,7 @@ public Simulator(ActionType[] actionPool, int maxStepCount, SimulationState? fil private bool CouldUseAction(ActionType action, BaseAction baseAction, bool strict) #pragma warning restore MA0051 // Method is too long { - var success = 0f; - int cost = 0, eff = 0; - baseAction.SuccessRate(this, ref success); - if (Math.Abs(CalculateSuccessRate(success) - 1) > float.Epsilon) + if (CalculateSuccessRate(baseAction.SuccessRate(this)) != 1) return false; // don't allow quality moves at max quality @@ -55,7 +52,7 @@ private bool CouldUseAction(ActionType action, BaseAction baseAction, bool stric { // always use Trained Eye if it's available if (action == ActionType.TrainedEye) - return baseAction.CouldUse(this, ref cost); + return baseAction.CouldUse(this); // don't allow quality moves under Muscle Memory for difficult crafts if (Input.Recipe.ClassJobLevel == 90 && @@ -88,8 +85,7 @@ private bool CouldUseAction(ActionType action, BaseAction baseAction, bool stric if (baseAction.IncreasesProgress) { - baseAction.Efficiency(this, ref eff); - var progressIncrease = CalculateProgressGain(eff); + var progressIncrease = CalculateProgressGain(baseAction.Efficiency(this)); var wouldFinish = Progress + progressIncrease >= Input.Recipe.MaxProgress; if (wouldFinish) @@ -133,7 +129,7 @@ private bool CouldUseAction(ActionType action, BaseAction baseAction, bool stric return false; } - return baseAction.CouldUse(this, ref cost); + return baseAction.CouldUse(this); } // https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L137 diff --git a/Test/Simulator/Simulator.cs b/Test/Simulator/Simulator.cs index c6b60f5..9356348 100644 --- a/Test/Simulator/Simulator.cs +++ b/Test/Simulator/Simulator.cs @@ -170,8 +170,7 @@ public void TrainedFinesseProcs() }, 0, 4064, 15, 332); Assert.AreEqual(10, state.ActiveEffects.InnerQuiet); - var cost = 0; - Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state }, ref cost)); + Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state })); } [TestMethod]