Merge branch 'action-pool'

This commit is contained in:
Asriel Camora
2024-03-16 13:31:10 -07:00
43 changed files with 335 additions and 384 deletions
+19 -3
View File
@@ -1,4 +1,5 @@
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Diagnostics.dotTrace; using BenchmarkDotNet.Diagnostics.dotTrace;
using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Jobs;
using Craftimizer.Simulator; using Craftimizer.Simulator;
@@ -9,7 +10,9 @@ namespace Craftimizer.Benchmark;
[SimpleJob(RuntimeMoniker.Net80, baseline: true)] [SimpleJob(RuntimeMoniker.Net80, baseline: true)]
[SimpleJob(RuntimeMoniker.Net90)] [SimpleJob(RuntimeMoniker.Net90)]
[MinColumn, Q1Column, Q3Column, MaxColumn] [MinColumn, Q1Column, Q3Column, MaxColumn]
[DotTraceDiagnoser] //[DotTraceDiagnoser]
[MemoryDiagnoser]
[DisassemblyDiagnoser(maxDepth: 500, exportGithubMarkdown: false, exportHtml: true)]
public class Bench public class Bench
{ {
public record struct HashWrapper<T>(T Data) where T : notnull public record struct HashWrapper<T>(T Data) where T : notnull
@@ -96,12 +99,25 @@ public class Bench
[ParamsSource(nameof(Configs))] [ParamsSource(nameof(Configs))]
public HashWrapper<SolverConfig> Config { get; set; } public HashWrapper<SolverConfig> Config { get; set; }
[Benchmark] // [Benchmark]
public async Task<float> Solve() public async Task<float> SolveAsync()
{ {
var solver = new Solver.Solver(Config, State); var solver = new Solver.Solver(Config, State);
solver.Start(); solver.Start();
var (_, s) = await solver.GetTask().ConfigureAwait(false); var (_, s) = await solver.GetTask().ConfigureAwait(false);
return (float)s.Quality / s.Input.Recipe.MaxQuality; 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);
}
} }
+6 -9
View File
@@ -1,13 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality; public override int CPCost(Simulator s) =>
public override int Level => 84; s.ActionStates.TouchComboIdx == 2 ? 18 : 46;
public override uint ActionId => 100411;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => s.ActionStates.TouchComboIdx == 2 ? 18 : 46;
public override int Efficiency(Simulator s) => 150;
} }
+3 -4
View File
@@ -1,9 +1,8 @@
namespace Craftimizer.Simulator.Actions; 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;
public override int CPCost(Simulator s) => 18 * 3;
} }
+45 -22
View File
@@ -2,28 +2,46 @@ using System.Text;
namespace Craftimizer.Simulator.Actions; 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 // Non-instanced properties
// Metadata // Metadata
public abstract ActionCategory Category { get; } public readonly ActionCategory Category = category;
public abstract int Level { get; }
public readonly int Level = level;
// Doesn't matter from which class, we'll use the sheet to extrapolate the rest // Doesn't matter from which class, we'll use the sheet to extrapolate the rest
public abstract uint ActionId { get; } public readonly uint ActionId = actionId;
// Seconds // Seconds
public virtual int MacroWaitTime => 3; public readonly int MacroWaitTime = macroWaitTime;
// Action properties // Action properties
public virtual bool IncreasesProgress => false; public readonly bool IncreasesProgress = increasesProgress;
public virtual bool IncreasesQuality => false; public readonly bool IncreasesQuality = increasesQuality;
public virtual int DurabilityCost => 10; public readonly int DurabilityCost = durabilityCost;
public virtual bool IncreasesStepCount => true; public readonly bool IncreasesStepCount = increasesStepCount;
// Instanced properties // Instanced properties
public abstract int CPCost(Simulator s); public readonly int DefaultCPCost = defaultCPCost;
public virtual int Efficiency(Simulator s) => 0; public readonly int DefaultEfficiency = defaultEfficiency;
public virtual float SuccessRate(Simulator s) => 1f; public readonly float DefaultSuccessRate = defaultSuccessRate;
// Instanced properties
public virtual int CPCost(Simulator s) =>
DefaultCPCost;
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 // 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 // e.g. if Heart and Soul is already used, it is impossible to use it again
@@ -65,36 +83,41 @@ public abstract class BaseAction
public virtual void UseSuccess(Simulator s) public virtual void UseSuccess(Simulator s)
{ {
if (Efficiency(s) != 0f) var eff = Efficiency(s);
if (eff != 0)
{ {
if (IncreasesProgress) if (IncreasesProgress)
s.IncreaseProgress(Efficiency(s)); s.IncreaseProgress(eff);
if (IncreasesQuality) if (IncreasesQuality)
s.IncreaseQuality(Efficiency(s)); s.IncreaseQuality(eff);
} }
} }
public virtual string GetTooltip(Simulator s, bool addUsability) public virtual string GetTooltip(Simulator s, bool addUsability)
{ {
var cost = CPCost(s);
var eff = Efficiency(s);
var success = SuccessRate(s);
var builder = new StringBuilder(); var builder = new StringBuilder();
if (addUsability && !CanUse(s)) if (addUsability && !CanUse(s))
builder.AppendLine($"Cannot Use"); builder.AppendLine($"Cannot Use");
builder.AppendLine($"Level {Level}"); builder.AppendLine($"Level {Level}");
if (CPCost(s) != 0) if (cost != 0)
builder.AppendLine($"-{s.CalculateCPCost(CPCost(s))} CP"); builder.AppendLine($"-{s.CalculateCPCost(cost)} CP");
if (DurabilityCost != 0) if (DurabilityCost != 0)
builder.AppendLine($"-{s.CalculateDurabilityCost(DurabilityCost)} Durability"); builder.AppendLine($"-{s.CalculateDurabilityCost(DurabilityCost)} Durability");
if (Efficiency(s) != 0) if (eff != 0)
{ {
if (IncreasesProgress) if (IncreasesProgress)
builder.AppendLine($"+{s.CalculateProgressGain(Efficiency(s))} Progress"); builder.AppendLine($"+{s.CalculateProgressGain(eff)} Progress");
if (IncreasesQuality) if (IncreasesQuality)
builder.AppendLine($"+{s.CalculateQualityGain(Efficiency(s))} Quality"); builder.AppendLine($"+{s.CalculateQualityGain(eff)} Quality");
} }
if (!IncreasesStepCount) if (!IncreasesStepCount)
builder.AppendLine($"Does Not Increase Step Count"); builder.AppendLine($"Does Not Increase Step Count");
if (SuccessRate(s) != 1f) if (success != 1)
builder.AppendLine($"{s.CalculateSuccessRate(SuccessRate(s)) * 100:##}% Success Rate"); builder.AppendLine($"{s.CalculateSuccessRate(success) * 100:##}% Success Rate");
return builder.ToString(); return builder.ToString();
} }
} }
+17 -6
View File
@@ -2,14 +2,25 @@ using System.Text;
namespace Craftimizer.Simulator.Actions; 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)
{ {
// Non-instanced properties // Non-instanced properties
public abstract EffectType Effect { get; } public readonly EffectType Effect = effect;
public virtual byte Duration => 1; public readonly int Duration = duration;
public override int MacroWaitTime => 2;
public sealed override int DurabilityCost => 0;
public override void UseSuccess(Simulator s) => public override void UseSuccess(Simulator s) =>
s.AddEffect(Effect, Duration); s.AddEffect(Effect, Duration);
+11 -5
View File
@@ -1,11 +1,17 @@
namespace Craftimizer.Simulator.Actions; 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 readonly ActionType ActionTypeA = actionTypeA;
public abstract ActionType ActionTypeB { get; } public readonly ActionType ActionTypeB = actionTypeB;
public sealed override ActionCategory Category => ActionCategory.Combo;
protected bool BaseCouldUse(Simulator s) => protected bool BaseCouldUse(Simulator s) =>
base.CouldUse(s); base.CouldUse(s);
+8 -9
View File
@@ -1,18 +1,17 @@
namespace Craftimizer.Simulator.Actions; 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 A ActionA = new();
protected static readonly B ActionB = new(); protected static readonly B ActionB = new();
public override int Level => ActionB.Level;
public override uint ActionId => ActionB.ActionId;
public override bool IncreasesProgress => ActionA.IncreasesProgress || ActionB.IncreasesProgress;
public override bool IncreasesQuality => ActionA.IncreasesQuality || ActionB.IncreasesQuality;
public override int CPCost(Simulator s) => ActionA.CPCost(s) + ActionB.CPCost(s);
public override bool IsPossible(Simulator s) => ActionA.IsPossible(s) && ActionB.IsPossible(s); public override bool IsPossible(Simulator s) => ActionA.IsPossible(s) && ActionB.IsPossible(s);
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
+8 -9
View File
@@ -1,14 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 1;
public override uint ActionId => 100001;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 0;
// Basic Synthesis Mastery Trait // Basic Synthesis Mastery Trait
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 31 ? 120 : 100; public override int Efficiency(Simulator s) =>
s.Input.Stats.Level >= 31 ? 120 : 100;
} }
+5 -8
View File
@@ -1,13 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 5;
public override uint ActionId => 100002;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) => 100;
} }
+9 -10
View File
@@ -1,17 +1,16 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality; public override int Efficiency(Simulator s) =>
public override int Level => 50; 100 + (20 * s.GetEffectStrength(EffectType.InnerQuiet));
public override uint ActionId => 100339;
public override bool IncreasesQuality => true; public override bool CouldUse(Simulator s) =>
s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s);
public override int CPCost(Simulator s) => 24;
public override int Efficiency(Simulator s) => 100 + (20 * s.GetEffectStrength(EffectType.InnerQuiet));
public override bool CouldUse(Simulator s) => s.HasEffect(EffectType.InnerQuiet) && base.CouldUse(s);
public override void UseSuccess(Simulator s) public override void UseSuccess(Simulator s)
{ {
+9 -13
View File
@@ -1,23 +1,19 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Other;
public override int Level => 55;
public override uint ActionId => 100395;
public override int MacroWaitTime => 3;
public override int DurabilityCost => 0;
public override bool IncreasesStepCount => false;
public override int CPCost(Simulator s) => 0;
public override bool IsPossible(Simulator s) => public override bool IsPossible(Simulator s) =>
base.IsPossible(s) && s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3; base.IsPossible(s) && s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3;
public override bool CouldUse(Simulator s) => s.ActionStates.CarefulObservationCount < 3; public override bool CouldUse(Simulator s) =>
s.ActionStates.CarefulObservationCount < 3;
public override void UseSuccess(Simulator s) => s.StepCondition(); public override void UseSuccess(Simulator s) =>
s.StepCondition();
public override string GetTooltip(Simulator s, bool addUsability) => public override string GetTooltip(Simulator s, bool addUsability) =>
$"{base.GetTooltip(s, addUsability)}Specialist Only\n"; $"{base.GetTooltip(s, addUsability)}Specialist Only\n";
+8 -9
View File
@@ -1,14 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 62;
public override uint ActionId => 100203;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 7;
// Careful Synthesis Mastery Trait // Careful Synthesis Mastery Trait
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 82 ? 180 : 150; public override int Efficiency(Simulator s) =>
s.Input.Stats.Level >= 82 ? 180 : 150;
} }
+6 -9
View File
@@ -1,14 +1,11 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 76;
public override uint ActionId => 100323;
public override bool IncreasesProgress => true;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 32;
public override int Efficiency(Simulator s) => 100;
} }
+5 -12
View File
@@ -1,17 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 42;
public override uint ActionId => 19012;
public override bool IncreasesStepCount => false;
public override EffectType Effect => EffectType.FinalAppraisal;
// This is set to 4 since IncreaseStepCount is false.
// Usually it adds 1 extra duration and then it would tick it down, but IncreaseStepCount prevents that.
public override byte Duration => 4;
public override int CPCost(Simulator s) => 1;
} }
+9 -10
View File
@@ -1,14 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis; public override float SuccessRate(Simulator s) =>
public override int Level => 67; s.ActionStates.Observed ? 1.00f : 0.50f;
public override uint ActionId => 100235;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 5;
public override int Efficiency(Simulator s) => 200;
public override float SuccessRate(Simulator s) => s.ActionStates.Observed ? 1.00f : 0.50f;
} }
+4 -3
View File
@@ -1,7 +1,8 @@
namespace Craftimizer.Simulator.Actions; 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;
} }
+9 -10
View File
@@ -1,14 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality; public override float SuccessRate(Simulator s) =>
public override int Level => 68; s.ActionStates.Observed ? 1.00f : 0.50f;
public override uint ActionId => 100243;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) => 150;
public override float SuccessRate(Simulator s) => s.ActionStates.Observed ? 1.00f : 0.50f;
} }
+4 -3
View File
@@ -1,7 +1,8 @@
namespace Craftimizer.Simulator.Actions; 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;
} }
+5 -8
View File
@@ -1,13 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 21;
public override uint ActionId => 260;
public override EffectType Effect => EffectType.GreatStrides;
public override byte Duration => 3;
public override int CPCost(Simulator s) => 32;
} }
+11 -11
View File
@@ -1,19 +1,19 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 72;
public override uint ActionId => 100403;
public override bool IncreasesProgress => true;
public override int DurabilityCost => 20;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) public override int Efficiency(Simulator s)
{ {
// Groundwork Mastery Trait // Groundwork Mastery Trait
var ret = s.Input.Stats.Level >= 86 ? 360 : 300; var eff = s.Input.Stats.Level >= 86 ? 360 : 300;
return s.Durability < s.CalculateDurabilityCost(DurabilityCost) ? ret / 2 : ret; if (s.Durability < s.CalculateDurabilityCost(DurabilityCost))
eff /= 2;
return eff;
} }
} }
+7 -9
View File
@@ -1,14 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 9;
public override uint ActionId => 100355;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 0;
public override int Efficiency(Simulator s) => 100;
public override float SuccessRate(Simulator s) => 0.60f;
} }
+8 -13
View File
@@ -1,22 +1,17 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Other;
public override int Level => 86;
public override uint ActionId => 100419;
public override int MacroWaitTime => 3;
public override bool IncreasesStepCount => false;
public override EffectType Effect => EffectType.HeartAndSoul;
public override int CPCost(Simulator s) => 0;
public override bool IsPossible(Simulator s) => public override bool IsPossible(Simulator s) =>
base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul; base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul;
public override bool CouldUse(Simulator s) => !s.ActionStates.UsedHeartAndSoul; public override bool CouldUse(Simulator s) =>
!s.ActionStates.UsedHeartAndSoul;
public override string GetTooltip(Simulator s, bool addUsability) => public override string GetTooltip(Simulator s, bool addUsability) =>
$"{GetBaseTooltip(s, addUsability)}Specialist Only\n"; $"{GetBaseTooltip(s, addUsability)}Specialist Only\n";
+4 -8
View File
@@ -1,13 +1,9 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 26;
public override uint ActionId => 19004;
public override EffectType Effect => EffectType.Innovation;
public override byte Duration => 4;
public override int CPCost(Simulator s) => 18;
} }
+6 -10
View File
@@ -1,16 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 78;
public override uint ActionId => 100315;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 6;
public override int Efficiency(Simulator s) => 400;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s); && base.CouldUse(s);
+4 -10
View File
@@ -1,16 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Durability;
public override int Level => 65;
public override uint ActionId => 4574;
public override EffectType Effect => EffectType.Manipulation;
public override byte Duration => 8;
public override int CPCost(Simulator s) => 96;
public override bool IsPossible(Simulator s) => public override bool IsPossible(Simulator s) =>
s.Input.Stats.CanUseManipulation && base.IsPossible(s); s.Input.Stats.CanUseManipulation && base.IsPossible(s);
+5 -9
View File
@@ -1,15 +1,11 @@
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
internal sealed class MastersMend : BaseAction internal sealed class MastersMend() : BaseAction(
ActionCategory.Durability, 7, 100003,
durabilityCost: 0,
defaultCPCost: 88
)
{ {
public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 7;
public override uint ActionId => 100003;
public override int DurabilityCost => 0;
public override int CPCost(Simulator s) => 88;
public override void UseSuccess(Simulator s) => public override void UseSuccess(Simulator s) =>
s.RestoreDurability(30); s.RestoreDurability(30);
} }
+6 -10
View File
@@ -1,16 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 54;
public override uint ActionId => 100379;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 6;
public override int Efficiency(Simulator s) => 300;
public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s);
public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s);
+5 -7
View File
@@ -1,12 +1,10 @@
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
internal sealed class Observe : BaseAction internal sealed class Observe() : BaseAction(
ActionCategory.Other, 13, 100010,
durabilityCost: 0,
defaultCPCost: 7
)
{ {
public override ActionCategory Category => ActionCategory.Other;
public override int Level => 13;
public override uint ActionId => 100010;
public override int DurabilityCost => 0;
public override int CPCost(Simulator s) => 7;
} }
+6 -10
View File
@@ -1,16 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 53;
public override uint ActionId => 100128;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) => 150;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s); && base.CouldUse(s);
+6 -11
View File
@@ -1,17 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 71;
public override uint ActionId => 100299;
public override bool IncreasesQuality => true;
public override int DurabilityCost => 20;
public override int CPCost(Simulator s) => 40;
public override int Efficiency(Simulator s) => 200;
public override void UseSuccess(Simulator s) public override void UseSuccess(Simulator s)
{ {
base.UseSuccess(s); base.UseSuccess(s);
+7 -11
View File
@@ -1,17 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 88;
public override uint ActionId => 100427;
public override bool IncreasesProgress => true;
public override int DurabilityCost => base.DurabilityCost / 2;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) => 180;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s); && base.CouldUse(s);
+7 -11
View File
@@ -1,17 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 66;
public override uint ActionId => 100227;
public override bool IncreasesQuality => true;
public override int DurabilityCost => base.DurabilityCost / 2;
public override int CPCost(Simulator s) => 25;
public override int Efficiency(Simulator s) => 100;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2)) !(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s); && base.CouldUse(s);
+9 -10
View File
@@ -1,15 +1,14 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 9;
public override uint ActionId => 100363;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 0;
// Rapid Synthesis Mastery Trait // Rapid Synthesis Mastery Trait
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 63 ? 500 : 250; public override int Efficiency(Simulator s) =>
public override float SuccessRate(Simulator s) => 0.50f; s.Input.Stats.Level >= 63 ? 500 : 250;
} }
+6 -10
View File
@@ -1,16 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 69;
public override uint ActionId => 100387;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 6;
public override int Efficiency(Simulator s) => 100;
public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s); public override bool IsPossible(Simulator s) => s.IsFirstStep && base.IsPossible(s);
public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s);
+8 -9
View File
@@ -1,13 +1,12 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality; public override int CPCost(Simulator s) =>
public override int Level => 18; s.ActionStates.TouchComboIdx == 1 ? 18 : 32;
public override uint ActionId => 100004;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => s.ActionStates.TouchComboIdx == 1 ? 18 : 32;
public override int Efficiency(Simulator s) => 125;
} }
+3 -4
View File
@@ -1,9 +1,8 @@
namespace Craftimizer.Simulator.Actions; 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;
public override int CPCost(Simulator s) => 18 * 2;
} }
+9 -11
View File
@@ -1,21 +1,19 @@
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
internal sealed class TrainedEye : BaseAction internal sealed class TrainedEye() : BaseAction(
ActionCategory.FirstTurn, 80, 100283,
increasesQuality: true,
defaultCPCost: 250
)
{ {
public override ActionCategory Category => ActionCategory.FirstTurn; public override bool IsPossible(Simulator s) =>
public override int Level => 80; s.IsFirstStep &&
public override uint ActionId => 100283;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 250;
public override bool IsPossible(Simulator s) => s.IsFirstStep &&
!s.Input.Recipe.IsExpert && !s.Input.Recipe.IsExpert &&
s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) && s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) &&
base.IsPossible(s); base.IsPossible(s);
public override bool CouldUse(Simulator s) => s.IsFirstStep && base.CouldUse(s); public override bool CouldUse(Simulator s) =>
s.IsFirstStep && base.CouldUse(s);
public override void UseSuccess(Simulator s) => public override void UseSuccess(Simulator s) =>
s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality); s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality);
+7 -11
View File
@@ -1,17 +1,13 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Quality;
public override int Level => 90;
public override uint ActionId => 100435;
public override bool IncreasesQuality => true;
public override int DurabilityCost => 0;
public override int CPCost(Simulator s) => 32;
public override int Efficiency(Simulator s) => 100;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
s.GetEffectStrength(EffectType.InnerQuiet) == 10 s.GetEffectStrength(EffectType.InnerQuiet) == 10
&& base.CouldUse(s); && base.CouldUse(s);
+5 -9
View File
@@ -1,15 +1,11 @@
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
internal sealed class TricksOfTheTrade : BaseAction internal sealed class TricksOfTheTrade() : BaseAction(
ActionCategory.Other, 13, 100371,
durabilityCost: 0,
defaultCPCost: 0
)
{ {
public override ActionCategory Category => ActionCategory.Other;
public override int Level => 13;
public override uint ActionId => 100371;
public override int DurabilityCost => 0;
public override int CPCost(Simulator s) => 0;
public override bool CouldUse(Simulator s) => public override bool CouldUse(Simulator s) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul)) (s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s); && base.CouldUse(s);
+5 -8
View File
@@ -1,13 +1,10 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 15;
public override uint ActionId => 19297;
public override EffectType Effect => EffectType.Veneration;
public override byte Duration => 4;
public override int CPCost(Simulator s) => 18;
} }
+5 -10
View File
@@ -1,16 +1,11 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Durability;
public override int Level => 15;
public override uint ActionId => 4631;
public override EffectType Effect => EffectType.WasteNot;
public override byte Duration => 4;
public override int CPCost(Simulator s) => 56;
public override void UseSuccess(Simulator s) public override void UseSuccess(Simulator s)
{ {
base.UseSuccess(s); base.UseSuccess(s);
+5 -10
View File
@@ -1,16 +1,11 @@
namespace Craftimizer.Simulator.Actions; 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 override ActionCategory Category => ActionCategory.Durability;
public override int Level => 47;
public override uint ActionId => 4639;
public override EffectType Effect => EffectType.WasteNot2;
public override byte Duration => 8;
public override int CPCost(Simulator s) => 98;
public override void UseSuccess(Simulator s) public override void UseSuccess(Simulator s)
{ {
base.UseSuccess(s); base.UseSuccess(s);
+1
View File
@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Configurations>Debug;Release</Configurations> <Configurations>Debug;Release</Configurations>