Remove ref passing, but keep devirtualizations
This commit is contained in:
+21
-5
@@ -1,4 +1,5 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Diagnostics.dotTrace;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using Craftimizer.Simulator;
|
||||
@@ -6,10 +7,12 @@ using Craftimizer.Solver;
|
||||
|
||||
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>(T Data) where T : notnull
|
||||
@@ -95,12 +98,25 @@ public class Bench
|
||||
[ParamsSource(nameof(Configs))]
|
||||
public HashWrapper<SolverConfig> Config { get; set; }
|
||||
|
||||
[Benchmark]
|
||||
public async Task<float> Solve()
|
||||
// [Benchmark]
|
||||
public async Task<float> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +935,6 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
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<ActionCategory>())
|
||||
{
|
||||
if (category == ActionCategory.Combo)
|
||||
@@ -953,7 +952,7 @@ public sealed class MacroEditor : Window, IDisposable
|
||||
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 &&
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Craftimizer.Simulator.Actions;
|
||||
|
||||
internal sealed class AdvancedTouchCombo : BaseComboAction<StandardTouchCombo, AdvancedTouch>
|
||||
internal sealed class AdvancedTouchCombo() : BaseComboAction<StandardTouchCombo, AdvancedTouch>(
|
||||
ActionType.StandardTouchCombo, ActionType.AdvancedTouch, 18 * 3
|
||||
)
|
||||
{
|
||||
public override ActionType ActionTypeA => ActionType.StandardTouchCombo;
|
||||
public override ActionType ActionTypeB => ActionType.AdvancedTouch;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,39 +2,46 @@ using System.Text;
|
||||
|
||||
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 abstract class BaseAction
|
||||
|
||||
// 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)
|
||||
public virtual bool CouldUse(Simulator s) =>
|
||||
s.CP >= CPCost(s);
|
||||
|
||||
public bool CanUse(Simulator s) =>
|
||||
IsPossible(s) && CouldUse(s);
|
||||
|
||||
public virtual void Use(Simulator s)
|
||||
{
|
||||
CPCost(s, ref cost);
|
||||
return s.CP >= cost;
|
||||
}
|
||||
if (s.RollSuccess(SuccessRate(s)))
|
||||
UseSuccess(s);
|
||||
|
||||
public bool CanUse(Simulator s, ref int cost) =>
|
||||
IsPossible(s) && CouldUse(s, ref cost);
|
||||
|
||||
public virtual void Use(Simulator s, ref int cost, ref float success, ref int eff)
|
||||
{
|
||||
SuccessRate(s, ref success);
|
||||
if (s.RollSuccess(success))
|
||||
UseSuccess(s, ref eff);
|
||||
CPCost(s, ref cost);
|
||||
|
||||
s.ReduceCP(cost);
|
||||
s.ReduceCP(CPCost(s));
|
||||
s.ReduceDurability(DurabilityCost);
|
||||
|
||||
if (s.Durability > 0)
|
||||
@@ -79,9 +81,9 @@ public abstract class BaseAction
|
||||
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 abstract class BaseAction
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -2,19 +2,27 @@ using System.Text;
|
||||
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -1,36 +1,26 @@
|
||||
namespace Craftimizer.Simulator.Actions;
|
||||
|
||||
internal abstract class BaseComboAction<A, B> : BaseComboAction where A : BaseAction, new() where B : BaseAction, new()
|
||||
internal abstract class BaseComboAction<A, B>(
|
||||
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) =>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
public override bool CouldUse(Simulator s) =>
|
||||
s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s);
|
||||
|
||||
public override void UseSuccess(Simulator s)
|
||||
{
|
||||
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 void UseSuccess(Simulator s, ref int eff)
|
||||
{
|
||||
base.UseSuccess(s, ref eff);
|
||||
base.UseSuccess(s);
|
||||
s.RemoveEffect(EffectType.InnerQuiet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Craftimizer.Simulator.Actions;
|
||||
|
||||
internal sealed class FocusedSynthesisCombo : BaseComboAction<Observe, FocusedSynthesis>
|
||||
internal sealed class FocusedSynthesisCombo() : BaseComboAction<Observe, FocusedSynthesis>(
|
||||
ActionType.Observe, ActionType.FocusedSynthesis
|
||||
)
|
||||
{
|
||||
public override ActionType ActionTypeA => ActionType.Observe;
|
||||
public override ActionType ActionTypeB => ActionType.FocusedSynthesis;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Craftimizer.Simulator.Actions;
|
||||
|
||||
internal sealed class FocusedTouchCombo : BaseComboAction<Observe, FocusedTouch>
|
||||
internal sealed class FocusedTouchCombo() : BaseComboAction<Observe, FocusedTouch>(
|
||||
ActionType.Observe, ActionType.FocusedTouch
|
||||
)
|
||||
{
|
||||
public override ActionType ActionTypeA => ActionType.Observe;
|
||||
public override ActionType ActionTypeB => ActionType.FocusedTouch;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace Craftimizer.Simulator.Actions;
|
||||
|
||||
internal sealed class StandardTouchCombo : BaseComboAction<BasicTouch, StandardTouch>
|
||||
internal sealed class StandardTouchCombo() : BaseComboAction<BasicTouch, StandardTouch>(
|
||||
ActionType.BasicTouch, ActionType.StandardTouch, 18 * 2
|
||||
)
|
||||
{
|
||||
public override ActionType ActionTypeA => ActionType.BasicTouch;
|
||||
public override ActionType ActionTypeB => ActionType.StandardTouch;
|
||||
|
||||
}
|
||||
|
||||
@@ -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 void CPCost(Simulator s,ref int cost)
|
||||
{
|
||||
cost = 250;
|
||||
}
|
||||
|
||||
public override bool IsPossible(Simulator s) => s.IsFirstStep &&
|
||||
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 bool CouldUse(Simulator s) =>
|
||||
s.IsFirstStep && base.CouldUse(s);
|
||||
|
||||
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) =>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
|
||||
@@ -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 class Simulator
|
||||
|
||||
[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 @@ public class Simulator
|
||||
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 @@ public class Simulator
|
||||
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;
|
||||
}
|
||||
|
||||
+12
-2
@@ -34,13 +34,22 @@ internal static class Intrinsics
|
||||
return m;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static Vector256<float> ClearLastN(Vector256<float> data, int len)
|
||||
{
|
||||
var threshold = Vector256.Create<int>(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<float> v, int len)
|
||||
{
|
||||
// Remove NaNs
|
||||
var vfilt = Avx.Blend(v.AsVector256(), Vector256<float>.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 @@ internal static class Intrinsics
|
||||
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 @@ internal static class Intrinsics
|
||||
|
||||
[Pure]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[SkipLocalsInit]
|
||||
public static Vector<float> ReciprocalSqrt(Vector<float> data)
|
||||
{
|
||||
if (Avx.IsSupported && Vector<float>.Count >= Vector256<float>.Count)
|
||||
|
||||
+4
-8
@@ -41,10 +41,7 @@ internal sealed class Simulator : SimulatorNoRandom
|
||||
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 @@ internal sealed class Simulator : SimulatorNoRandom
|
||||
{
|
||||
// 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 @@ internal sealed class Simulator : SimulatorNoRandom
|
||||
|
||||
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 @@ internal sealed class Simulator : SimulatorNoRandom
|
||||
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
|
||||
|
||||
@@ -170,8 +170,7 @@ public class SimulatorTests
|
||||
},
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user