Optimizations (from @wolfcomp)

This commit is contained in:
Asriel Camora
2024-03-15 09:49:03 -07:00
parent ea963f9e1b
commit 3223bdcbfb
43 changed files with 691 additions and 354 deletions
+2 -1
View File
@@ -935,6 +935,7 @@ 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)
@@ -952,7 +953,7 @@ public sealed class MacroEditor : Window, IDisposable
if (i < itemCount)
{
var actionBase = actions[i].Base();
var canUse = actionBase.CanUse(sim);
var canUse = actionBase.CanUse(sim, ref cost);
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 &&
+21 -7
View File
@@ -2,12 +2,26 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class AdvancedTouch : BaseAction
{
public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 84;
public override uint ActionId => 100411;
public int CostDefault = 46;
public int CostOptimal = 18;
public int EfficiencyDefault = 150;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => s.ActionStates.TouchComboIdx == 2 ? 18 : 46;
public override int Efficiency(Simulator s) => 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;
}
}
-2
View File
@@ -4,6 +4,4 @@ internal sealed class AdvancedTouchCombo : BaseComboAction<StandardTouchCombo, A
{
public override ActionType ActionTypeA => ActionType.StandardTouchCombo;
public override ActionType ActionTypeB => ActionType.AdvancedTouch;
public override int CPCost(Simulator s) => 18 * 3;
}
+54 -33
View File
@@ -7,23 +7,34 @@ public abstract class BaseAction
// Non-instanced properties
// Metadata
public abstract ActionCategory Category { get; }
public abstract int Level { get; }
public ActionCategory Category;
public int Level;
// Doesn't matter from which class, we'll use the sheet to extrapolate the rest
public abstract uint ActionId { get; }
public uint ActionId;
// Seconds
public virtual int MacroWaitTime => 3;
public int MacroWaitTime = 3;
// Action properties
public virtual bool IncreasesProgress => false;
public virtual bool IncreasesQuality => false;
public virtual int DurabilityCost => 10;
public virtual bool IncreasesStepCount => true;
public bool IncreasesProgress;
public bool IncreasesQuality;
public int DurabilityCost = 10;
public bool IncreasesStepCount = true;
public int EfficiencyFactor;
public float SuccessRateFactor = 1;
// Instanced properties
public abstract int CPCost(Simulator s);
public virtual int Efficiency(Simulator s) => 0;
public virtual float SuccessRate(Simulator s) => 1f;
public abstract void CPCost(Simulator s, ref int cost);
public virtual void Efficiency(Simulator s, ref int eff)
{
eff = EfficiencyFactor;
}
public virtual void SuccessRate(Simulator s, ref float success)
{
success = SuccessRateFactor;
}
// 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
@@ -33,18 +44,23 @@ 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) =>
s.CP >= CPCost(s);
public bool CanUse(Simulator s) =>
IsPossible(s) && CouldUse(s);
public virtual void Use(Simulator s)
public virtual bool CouldUse(Simulator s, ref int cost)
{
if (s.RollSuccess(SuccessRate(s)))
UseSuccess(s);
CPCost(s, ref cost);
return s.CP >= cost;
}
s.ReduceCP(CPCost(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.ReduceDurability(DurabilityCost);
if (s.Durability > 0)
@@ -63,38 +79,43 @@ public abstract class BaseAction
s.ActiveEffects.DecrementDuration();
}
public virtual void UseSuccess(Simulator s)
public virtual void UseSuccess(Simulator s, ref int eff)
{
if (Efficiency(s) != 0f)
Efficiency(s, ref eff);
if (eff != 0)
{
if (IncreasesProgress)
s.IncreaseProgress(Efficiency(s));
s.IncreaseProgress(eff);
if (IncreasesQuality)
s.IncreaseQuality(Efficiency(s));
s.IncreaseQuality(eff);
}
}
public virtual string GetTooltip(Simulator s, bool addUsability)
{
var builder = new StringBuilder();
if (addUsability && !CanUse(s))
int cost = 0;
float success = 1f;
if (addUsability && !CanUse(s, ref cost))
builder.AppendLine($"Cannot Use");
builder.AppendLine($"Level {Level}");
if (CPCost(s) != 0)
builder.AppendLine($"-{s.CalculateCPCost(CPCost(s))} CP");
if (cost != 0)
builder.AppendLine($"-{s.CalculateCPCost(cost)} CP");
if (DurabilityCost != 0)
builder.AppendLine($"-{s.CalculateDurabilityCost(DurabilityCost)} Durability");
if (Efficiency(s) != 0)
Efficiency(s, ref cost);
if (cost != 0)
{
if (IncreasesProgress)
builder.AppendLine($"+{s.CalculateProgressGain(Efficiency(s))} Progress");
builder.AppendLine($"+{s.CalculateProgressGain(cost)} Progress");
if (IncreasesQuality)
builder.AppendLine($"+{s.CalculateQualityGain(Efficiency(s))} Quality");
builder.AppendLine($"+{s.CalculateQualityGain(cost)} Quality");
}
if (!IncreasesStepCount)
builder.AppendLine($"Does Not Increase Step Count");
if (SuccessRate(s) != 1f)
builder.AppendLine($"{s.CalculateSuccessRate(SuccessRate(s)) * 100:##}% Success Rate");
SuccessRate(s, ref success);
if (Math.Abs(success - 1f) > float.Epsilon)
builder.AppendLine($"{s.CalculateSuccessRate(success) * 100:##}% Success Rate");
return builder.ToString();
}
}
+9 -6
View File
@@ -4,14 +4,17 @@ namespace Craftimizer.Simulator.Actions;
internal abstract class BaseBuffAction : BaseAction
{
public BaseBuffAction()
{
MacroWaitTime = 2;
DurabilityCost = 0;
}
// Non-instanced properties
public abstract EffectType Effect { get; }
public virtual byte Duration => 1;
public override int MacroWaitTime => 2;
public EffectType Effect;
public int Duration = 1;
public sealed override int DurabilityCost => 0;
public override void UseSuccess(Simulator s) =>
public override void UseSuccess(Simulator s, ref int eff) =>
s.AddEffect(Effect, Duration);
public override string GetTooltip(Simulator s, bool addUsability)
+6 -3
View File
@@ -5,10 +5,13 @@ public abstract class BaseComboAction : BaseAction
public abstract ActionType ActionTypeA { get; }
public abstract ActionType ActionTypeB { get; }
public sealed override ActionCategory Category => ActionCategory.Combo;
public BaseComboAction()
{
Category = ActionCategory.Combo;
}
protected bool BaseCouldUse(Simulator s) =>
base.CouldUse(s);
protected bool BaseCouldUse(Simulator s, ref int cost) =>
base.CouldUse(s, ref cost);
private static bool VerifyDurability2(int durabilityA, int durability, in Effects effects)
{
+20 -11
View File
@@ -5,23 +5,32 @@ internal abstract class BaseComboAction<A, B> : BaseComboAction where A : BaseAc
protected static readonly A ActionA = new();
protected static readonly B ActionB = new();
public override int Level => ActionB.Level;
public override uint ActionId => ActionB.ActionId;
protected BaseComboAction()
{
Level = ActionB.Level;
ActionId = ActionB.ActionId;
IncreasesProgress = ActionA.IncreasesProgress || ActionB.IncreasesProgress;
IncreasesQuality = ActionA.IncreasesQuality || ActionB.IncreasesQuality;
}
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 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) =>
BaseCouldUse(s) && VerifyDurability2(s, ActionA.DurabilityCost);
public override bool CouldUse(Simulator s, ref int cost) =>
BaseCouldUse(s, ref cost) && VerifyDurability2(s, ActionA.DurabilityCost);
public override void Use(Simulator s)
public override void Use(Simulator s, ref int cost, ref float success, ref int eff)
{
ActionA.Use(s);
ActionB.Use(s);
ActionA.Use(s, ref cost, ref success, ref eff);
ActionB.Use(s, ref cost, ref success, ref eff);
}
public override string GetTooltip(Simulator s, bool addUsability) =>
+20 -8
View File
@@ -2,13 +2,25 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class BasicSynthesis : BaseAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 1;
public override uint ActionId => 100001;
public int CP;
public int EfficiencyNormal = 100;
public int EfficiencyGood = 120;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 0;
// Basic Synthesis Mastery Trait
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 31 ? 120 : 100;
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;
}
}
+19 -7
View File
@@ -2,12 +2,24 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class BasicTouch : BaseAction
{
public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 5;
public override uint ActionId => 100002;
public int CP = 18;
public int eff = 100;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s) => 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;
}
}
+23 -12
View File
@@ -2,20 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class ByregotsBlessing : BaseAction
{
public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 50;
public override uint ActionId => 100339;
public int CP = 24;
public override bool IncreasesQuality => true;
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 ByregotsBlessing()
{
base.UseSuccess(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);
s.RemoveEffect(EffectType.InnerQuiet);
}
}
+16 -9
View File
@@ -2,22 +2,29 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class CarefulObservation : BaseAction
{
public override ActionCategory Category => ActionCategory.Other;
public override int Level => 55;
public override uint ActionId => 100395;
public override int MacroWaitTime => 3;
public int CP = 0;
public override int DurabilityCost => 0;
public override bool IncreasesStepCount => false;
public CarefulObservation()
{
Category = ActionCategory.Other;
Level = 55;
ActionId = 100395;
MacroWaitTime = 3;
DurabilityCost = 0;
IncreasesStepCount = false;
}
public override int CPCost(Simulator s) => 0;
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) => s.ActionStates.CarefulObservationCount < 3;
public override bool CouldUse(Simulator s, ref int cost) => s.ActionStates.CarefulObservationCount < 3;
public override void UseSuccess(Simulator s) => s.StepCondition();
public override void UseSuccess(Simulator s, ref int eff) => s.StepCondition();
public override string GetTooltip(Simulator s, bool addUsability) =>
$"{base.GetTooltip(s, addUsability)}Specialist Only\n";
+21 -8
View File
@@ -2,13 +2,26 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class CarefulSynthesis : BaseAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 62;
public override uint ActionId => 100203;
public int CP = 7;
public int EfficiencyNormal = 150;
public int EfficiencyMastery = 180;
public override bool IncreasesProgress => true;
public override int CPCost(Simulator s) => 7;
// Careful Synthesis Mastery Trait
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 82 ? 180 : 150;
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;
}
}
+20 -8
View File
@@ -2,13 +2,25 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class DelicateSynthesis : BaseAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 76;
public override uint ActionId => 100323;
public int CP = 32;
public int Eff = 100;
public override bool IncreasesProgress => true;
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 32;
public override int Efficiency(Simulator s) => 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;
}
}
+15 -11
View File
@@ -2,16 +2,20 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class FinalAppraisal : BaseBuffAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 42;
public override uint ActionId => 19012;
public int CP = 1;
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;
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;
}
}
+26 -8
View File
@@ -2,13 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedSynthesis : BaseAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 67;
public override uint ActionId => 100235;
public int CP = 5;
public int Eff = 200;
public float SuccessNormal = 0.50f;
public float SuccessObserved = 1.00f;
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;
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;
}
}
+27 -8
View File
@@ -2,13 +2,32 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class FocusedTouch : BaseAction
{
public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 68;
public override uint ActionId => 100243;
public int CP = 18;
public int Eff = 150;
public float SuccessNormal = 0.50f;
public float SuccessObserved = 1.00f;
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;
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;
}
}
+14 -7
View File
@@ -2,12 +2,19 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class GreatStrides : BaseBuffAction
{
public override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 21;
public override uint ActionId => 260;
public int CP = 32;
public override EffectType Effect => EffectType.GreatStrides;
public override byte Duration => 3;
public override int CPCost(Simulator s) => 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;
}
}
+16 -9
View File
@@ -2,18 +2,25 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Groundwork : BaseAction
{
public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 72;
public override uint ActionId => 100403;
public Groundwork()
{
Category = ActionCategory.Synthesis;
Level = 72;
ActionId = 100403;
IncreasesProgress = true;
DurabilityCost = 20;
}
public override bool IncreasesProgress => true;
public override int DurabilityCost => 20;
public override void CPCost(Simulator s, ref int cost)
{
cost = 18;
}
public override int CPCost(Simulator s) => 18;
public override int Efficiency(Simulator s)
public override void Efficiency(Simulator s, ref int eff)
{
// Groundwork Mastery Trait
var ret = s.Input.Stats.Level >= 86 ? 360 : 300;
return s.Durability < s.CalculateDurabilityCost(DurabilityCost) ? ret / 2 : ret;
eff = s.Input.Stats.Level >= 86 ? 360 : 300;
if (s.Durability < s.CalculateDurabilityCost(DurabilityCost))
eff /= 2;
}
}
+22 -9
View File
@@ -2,13 +2,26 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class HastyTouch : BaseAction
{
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;
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;
}
}
+14 -10
View File
@@ -2,21 +2,25 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class HeartAndSoul : BaseBuffAction
{
public override ActionCategory Category => ActionCategory.Other;
public override int Level => 86;
public override uint ActionId => 100419;
public override int MacroWaitTime => 3;
public HeartAndSoul()
{
Level = 86;
Effect = EffectType.HeartAndSoul;
MacroWaitTime = 3;
ActionId = 100419;
Category = ActionCategory.Other;
IncreasesStepCount = false;
}
public override bool IncreasesStepCount => false;
public override EffectType Effect => EffectType.HeartAndSoul;
public override int CPCost(Simulator s) => 0;
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) => !s.ActionStates.UsedHeartAndSoul;
public override bool CouldUse(Simulator s, ref int cost) => !s.ActionStates.UsedHeartAndSoul;
public override string GetTooltip(Simulator s, bool addUsability) =>
$"{GetBaseTooltip(s, addUsability)}Specialist Only\n";
+14 -8
View File
@@ -2,12 +2,18 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Innovation : BaseBuffAction
{
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;
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;
}
}
+24 -15
View File
@@ -2,22 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class IntensiveSynthesis : BaseAction
{
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) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s);
public override void UseSuccess(Simulator s)
public IntensiveSynthesis()
{
base.UseSuccess(s);
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) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s, ref int eff)
{
base.UseSuccess(s, ref eff);
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
s.RemoveEffect(EffectType.HeartAndSoul);
}
+16 -10
View File
@@ -2,23 +2,29 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Manipulation : BaseBuffAction
{
public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 65;
public override uint ActionId => 4574;
public Manipulation()
{
Category = ActionCategory.Durability;
Level = 65;
ActionId = 4574;
Effect = EffectType.Manipulation;
Duration = 8;
}
public override EffectType Effect => EffectType.Manipulation;
public override byte Duration => 8;
public override int CPCost(Simulator s) => 96;
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)
public override void Use(Simulator s, ref int cost, ref float success, ref int eff)
{
UseSuccess(s);
UseSuccess(s, ref eff);
CPCost(s, ref cost);
s.ReduceCP(CPCost(s));
s.ReduceCP(cost);
s.IncreaseStepCount();
+12 -7
View File
@@ -2,14 +2,19 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class MastersMend : BaseAction
{
public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 7;
public override uint ActionId => 100003;
public MastersMend()
{
Category = ActionCategory.Durability;
Level = 7;
ActionId = 100003;
DurabilityCost = 0;
}
public override int DurabilityCost => 0;
public override void CPCost(Simulator s, ref int cost)
{
cost = 88;
}
public override int CPCost(Simulator s) => 88;
public override void UseSuccess(Simulator s) =>
public override void UseSuccess(Simulator s, ref int eff) =>
s.RestoreDurability(30);
}
+18 -9
View File
@@ -2,22 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class MuscleMemory : BaseAction
{
public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 54;
public override uint ActionId => 100379;
public MuscleMemory()
{
Category = ActionCategory.FirstTurn;
Level = 54;
ActionId = 100379;
IncreasesProgress = true;
}
public override bool IncreasesProgress => true;
public override void CPCost(Simulator s, ref int cost)
{
cost = 6;
}
public override int CPCost(Simulator s) => 6;
public override int Efficiency(Simulator s) => 300;
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) => s.IsFirstStep && base.CouldUse(s);
public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s)
public override void UseSuccess(Simulator s, ref int eff)
{
base.UseSuccess(s);
base.UseSuccess(s, ref eff);
s.AddEffect(EffectType.MuscleMemory, 5);
}
}
+12 -7
View File
@@ -2,11 +2,16 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Observe : BaseAction
{
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;
public Observe()
{
Category = ActionCategory.Other;
Level = 13;
ActionId = 100010;
DurabilityCost = 0;
}
public override void CPCost(Simulator s, ref int cost)
{
cost = 7;
}
}
+24 -15
View File
@@ -2,22 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class PreciseTouch : BaseAction
{
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) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s);
public override void UseSuccess(Simulator s)
public PreciseTouch()
{
base.UseSuccess(s);
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) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s, ref int eff)
{
base.UseSuccess(s, ref eff);
s.StrengthenEffect(EffectType.InnerQuiet);
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
s.RemoveEffect(EffectType.HeartAndSoul);
+21 -12
View File
@@ -2,19 +2,28 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class PreparatoryTouch : BaseAction
{
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 PreparatoryTouch()
{
base.UseSuccess(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);
s.StrengthenEffect(EffectType.InnerQuiet);
}
}
+22 -12
View File
@@ -2,17 +2,27 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class PrudentSynthesis : BaseAction
{
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) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s);
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) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s, ref cost);
}
+22 -13
View File
@@ -2,17 +2,26 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class PrudentTouch : BaseAction
{
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) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s);
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) =>
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
&& base.CouldUse(s, ref cost);
}
+23 -10
View File
@@ -2,14 +2,27 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class RapidSynthesis : BaseAction
{
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
public override int Efficiency(Simulator s) => s.Input.Stats.Level >= 63 ? 500 : 250;
public override float SuccessRate(Simulator s) => 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;
}
}
+18 -9
View File
@@ -2,22 +2,31 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Reflect : BaseAction
{
public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 69;
public override uint ActionId => 100387;
public Reflect()
{
Category = ActionCategory.FirstTurn;
Level = 69;
ActionId = 100387;
IncreasesQuality = true;
}
public override bool IncreasesQuality => true;
public override void CPCost(Simulator s, ref int cost)
{
cost = 6;
}
public override int CPCost(Simulator s) => 6;
public override int Efficiency(Simulator s) => 100;
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) => s.IsFirstStep && base.CouldUse(s);
public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s)
public override void UseSuccess(Simulator s, ref int eff)
{
base.UseSuccess(s);
base.UseSuccess(s, ref eff);
s.StrengthenEffect(EffectType.InnerQuiet);
}
}
+17 -8
View File
@@ -2,12 +2,21 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class StandardTouch : BaseAction
{
public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 18;
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;
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;
}
}
-2
View File
@@ -4,6 +4,4 @@ internal sealed class StandardTouchCombo : BaseComboAction<BasicTouch, StandardT
{
public override ActionType ActionTypeA => ActionType.BasicTouch;
public override ActionType ActionTypeB => ActionType.StandardTouch;
public override int CPCost(Simulator s) => 18 * 2;
}
+13 -8
View File
@@ -2,22 +2,27 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class TrainedEye : BaseAction
{
public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 80;
public override uint ActionId => 100283;
public TrainedEye()
{
Category = ActionCategory.FirstTurn;
Level = 80;
ActionId = 100283;
IncreasesQuality = true;
}
public override bool IncreasesQuality => true;
public override int CPCost(Simulator s) => 250;
public override void CPCost(Simulator s,ref int cost)
{
cost = 250;
}
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) => s.IsFirstStep && base.CouldUse(s);
public override bool CouldUse(Simulator s, ref int cost) => s.IsFirstStep && base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s) =>
public override void UseSuccess(Simulator s, ref int eff) =>
s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality);
public override string GetTooltip(Simulator s, bool addUsability) =>
+22 -13
View File
@@ -2,17 +2,26 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class TrainedFinesse : BaseAction
{
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) =>
s.GetEffectStrength(EffectType.InnerQuiet) == 10
&& base.CouldUse(s);
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) =>
s.GetEffectStrength(EffectType.InnerQuiet) == 10
&& base.CouldUse(s, ref cost);
}
+14 -9
View File
@@ -2,19 +2,24 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class TricksOfTheTrade : BaseAction
{
public override ActionCategory Category => ActionCategory.Other;
public override int Level => 13;
public override uint ActionId => 100371;
public TricksOfTheTrade()
{
Category = ActionCategory.Other;
Level = 13;
ActionId = 100371;
DurabilityCost = 0;
}
public override int DurabilityCost => 0;
public override void CPCost(Simulator s, ref int cost)
{
cost = 0;
}
public override int CPCost(Simulator s) => 0;
public override bool CouldUse(Simulator s) =>
public override bool CouldUse(Simulator s, ref int cost) =>
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
&& base.CouldUse(s);
&& base.CouldUse(s, ref cost);
public override void UseSuccess(Simulator s)
public override void UseSuccess(Simulator s, ref int eff)
{
s.RestoreCP(20);
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
+13 -8
View File
@@ -2,12 +2,17 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class Veneration : BaseBuffAction
{
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;
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;
}
}
+16 -11
View File
@@ -2,18 +2,23 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class WasteNot : BaseBuffAction
{
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 WasteNot()
{
base.UseSuccess(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);
s.RemoveEffect(EffectType.WasteNot2);
}
}
+16 -11
View File
@@ -2,18 +2,23 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class WasteNot2 : BaseBuffAction
{
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 WasteNot2()
{
base.UseSuccess(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);
s.RemoveEffect(EffectType.WasteNot);
}
}
+8 -4
View File
@@ -21,6 +21,10 @@ 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 {
@@ -50,7 +54,7 @@ public class Simulator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ExecuteUnchecked(ActionType action) =>
action.Base().Use(this);
action.Base().Use(this, ref cost, ref success, ref eff);
private ActionResponse Execute(ActionType action)
{
@@ -58,7 +62,7 @@ public class Simulator
return ActionResponse.SimulationComplete;
var baseAction = action.Base();
if (!baseAction.CanUse(this))
if (!baseAction.CanUse(this, ref cost))
{
if (baseAction.Level > Input.Stats.Level)
return ActionResponse.ActionNotUnlocked;
@@ -66,12 +70,12 @@ public class Simulator
return ActionResponse.ActionNotUnlocked;
if (action is ActionType.CarefulObservation or ActionType.HeartAndSoul && !Input.Stats.IsSpecialist)
return ActionResponse.ActionNotUnlocked;
if (baseAction.CPCost(this) > CP)
if (cost > CP)
return ActionResponse.NotEnoughCP;
return ActionResponse.CannotUseAction;
}
baseAction.Use(this);
baseAction.Use(this, ref cost, ref success, ref eff);
return ActionResponse.UsedAction;
}
+8 -4
View File
@@ -41,7 +41,10 @@ internal sealed class Simulator : SimulatorNoRandom
private bool CouldUseAction(ActionType action, BaseAction baseAction, bool strict)
#pragma warning restore MA0051 // Method is too long
{
if (CalculateSuccessRate(baseAction.SuccessRate(this)) != 1)
var success = 0f;
int cost = 0, eff = 0;
baseAction.SuccessRate(this, ref success);
if (Math.Abs(CalculateSuccessRate(success) - 1) > float.Epsilon)
return false;
// don't allow quality moves at max quality
@@ -52,7 +55,7 @@ internal sealed class Simulator : SimulatorNoRandom
{
// always use Trained Eye if it's available
if (action == ActionType.TrainedEye)
return baseAction.CouldUse(this);
return baseAction.CouldUse(this, ref cost);
// don't allow quality moves under Muscle Memory for difficult crafts
if (Input.Recipe.ClassJobLevel == 90 &&
@@ -85,7 +88,8 @@ internal sealed class Simulator : SimulatorNoRandom
if (baseAction.IncreasesProgress)
{
var progressIncrease = CalculateProgressGain(baseAction.Efficiency(this));
baseAction.Efficiency(this, ref eff);
var progressIncrease = CalculateProgressGain(eff);
var wouldFinish = Progress + progressIncrease >= Input.Recipe.MaxProgress;
if (wouldFinish)
@@ -129,7 +133,7 @@ internal sealed class Simulator : SimulatorNoRandom
return false;
}
return baseAction.CouldUse(this);
return baseAction.CouldUse(this, ref cost);
}
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L137
+2 -1
View File
@@ -170,7 +170,8 @@ public class SimulatorTests
},
0, 4064, 15, 332);
Assert.AreEqual(10, state.ActiveEffects.InnerQuiet);
Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state }));
var cost = 0;
Assert.IsTrue(ActionType.TrainedFinesse.Base().CanUse(new SimulatorNoRandom() { State = state }, ref cost));
}
[TestMethod]