Remove threadlocal dependence
This commit is contained in:
@@ -18,7 +18,7 @@ internal static class ActionUtils
|
|||||||
{
|
{
|
||||||
private static (CraftAction? CraftAction, Action? Action) GetActionRow(this ActionType me, ClassJob classJob)
|
private static (CraftAction? CraftAction, Action? Action) GetActionRow(this ActionType me, ClassJob classJob)
|
||||||
{
|
{
|
||||||
var actionId = me.WithUnsafe().ActionId;
|
var actionId = me.Base().ActionId;
|
||||||
if (LuminaSheets.CraftActionSheet.GetRow(actionId) is CraftAction baseCraftAction)
|
if (LuminaSheets.CraftActionSheet.GetRow(actionId) is CraftAction baseCraftAction)
|
||||||
{
|
{
|
||||||
return (classJob switch
|
return (classJob switch
|
||||||
|
|||||||
@@ -71,15 +71,15 @@ public class SimulatorWindow : Window
|
|||||||
ImGuiUtils.BeginGroupPanel(category.Key.GetDisplayName());
|
ImGuiUtils.BeginGroupPanel(category.Key.GetDisplayName());
|
||||||
foreach (var action in category.OrderBy(a => a.Level()))
|
foreach (var action in category.OrderBy(a => a.Level()))
|
||||||
{
|
{
|
||||||
var baseAction = action.With(Simulation);
|
var baseAction = action.Base();
|
||||||
if (showOnlyGuaranteedActions && !baseAction.IsGuaranteedAction)
|
if (showOnlyGuaranteedActions && baseAction.SuccessRate(Simulation) != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ImGui.BeginDisabled(!baseAction.CanUse || Simulation.IsComplete);
|
ImGui.BeginDisabled(!baseAction.CanUse(Simulation) || Simulation.IsComplete);
|
||||||
if (ImGui.ImageButton(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2)))
|
if (ImGui.ImageButton(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2)))
|
||||||
(_, State) = Simulation.Execute(State, action);
|
(_, State) = Simulation.Execute(State, action);
|
||||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(true)}");
|
ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(Simulation, true)}");
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
if (++i % 5 != 0)
|
if (++i % 5 != 0)
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|||||||
@@ -51,32 +51,19 @@ public static class ActionUtils
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetSimulation(Simulator simulation) =>
|
public static BaseAction Base(this ActionType me) => Actions[(int)me];
|
||||||
BaseAction.TLSSimulation = simulation;
|
|
||||||
|
|
||||||
public static BaseAction WithUnsafe(this ActionType me) => Actions[(int)me];
|
public static IEnumerable<ActionType> AvailableActions(Simulator simulation) =>
|
||||||
|
simulation.IsComplete
|
||||||
public static BaseAction With(this ActionType me, Simulator simulation)
|
? Enumerable.Empty<ActionType>()
|
||||||
{
|
: Enum.GetValues<ActionType>()
|
||||||
SetSimulation(simulation);
|
.Where(a => a.Base().CanUse(simulation));
|
||||||
return WithUnsafe(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<ActionType> AvailableActions(Simulator simulation)
|
|
||||||
{
|
|
||||||
if (simulation.IsComplete)
|
|
||||||
return Enumerable.Empty<ActionType>();
|
|
||||||
|
|
||||||
SetSimulation(simulation);
|
|
||||||
return Enum.GetValues<ActionType>()
|
|
||||||
.Where(a => WithUnsafe(a).CanUse);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int Level(this ActionType me) =>
|
public static int Level(this ActionType me) =>
|
||||||
WithUnsafe(me).Level;
|
me.Base().Level;
|
||||||
|
|
||||||
public static ActionCategory Category(this ActionType me) =>
|
public static ActionCategory Category(this ActionType me) =>
|
||||||
WithUnsafe(me).Category;
|
me.Base().Category;
|
||||||
|
|
||||||
public static string IntName(this ActionType me) =>
|
public static string IntName(this ActionType me) =>
|
||||||
me switch
|
me switch
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ internal sealed class AdvancedTouch : BaseAction
|
|||||||
public override int Level => 84;
|
public override int Level => 84;
|
||||||
public override uint ActionId => 100411;
|
public override uint ActionId => 100411;
|
||||||
|
|
||||||
public override int CPCost => Simulation.ActionStates.TouchComboIdx == 2 ? 18 : 46;
|
|
||||||
public override float Efficiency => 1.50f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => s.ActionStates.TouchComboIdx == 2 ? 18 : 46;
|
||||||
|
public override float Efficiency(Simulator s) => 1.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,79 +4,78 @@ namespace Craftimizer.Simulator.Actions;
|
|||||||
|
|
||||||
public abstract class BaseAction
|
public abstract class BaseAction
|
||||||
{
|
{
|
||||||
[ThreadStatic]
|
|
||||||
internal static Simulator? TLSSimulation;
|
|
||||||
protected static Simulator Simulation => TLSSimulation!;
|
|
||||||
|
|
||||||
// Non-instanced properties
|
// Non-instanced properties
|
||||||
|
|
||||||
|
// Metadata
|
||||||
public abstract ActionCategory Category { get; }
|
public abstract ActionCategory Category { get; }
|
||||||
public abstract int Level { get; }
|
public abstract int Level { get; }
|
||||||
// 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 abstract uint ActionId { get; }
|
||||||
|
|
||||||
// Instanced properties
|
// Action properties
|
||||||
public abstract int CPCost { get; }
|
|
||||||
public virtual float Efficiency => 0f;
|
|
||||||
public virtual bool IncreasesProgress => false;
|
public virtual bool IncreasesProgress => false;
|
||||||
public virtual bool IncreasesQuality => false;
|
public virtual bool IncreasesQuality => false;
|
||||||
public virtual float SuccessRate => 1f;
|
|
||||||
public virtual int DurabilityCost => 10;
|
public virtual int DurabilityCost => 10;
|
||||||
public virtual bool IncreasesStepCount => true;
|
public virtual bool IncreasesStepCount => true;
|
||||||
public virtual bool IsGuaranteedAction => SuccessRate == 1f;
|
|
||||||
|
|
||||||
public virtual bool CanUse =>
|
// Instanced properties
|
||||||
Simulation.Input.Stats.Level >= Level && Simulation.CP >= CPCost;
|
public abstract int CPCost(Simulator s);
|
||||||
|
public virtual float Efficiency(Simulator s) => 0f;
|
||||||
|
public virtual float SuccessRate(Simulator s) => 1f;
|
||||||
|
|
||||||
public virtual void Use()
|
public virtual bool CanUse(Simulator s) =>
|
||||||
|
s.Input.Stats.Level >= Level && s.CP >= CPCost(s);
|
||||||
|
|
||||||
|
public virtual void Use(Simulator s)
|
||||||
{
|
{
|
||||||
if (Simulation.RollSuccess(SuccessRate))
|
if (s.RollSuccess(SuccessRate(s)))
|
||||||
UseSuccess();
|
UseSuccess(s);
|
||||||
|
|
||||||
Simulation.ReduceCP(CPCost);
|
s.ReduceCP(CPCost(s));
|
||||||
Simulation.ReduceDurability(DurabilityCost);
|
s.ReduceDurability(DurabilityCost);
|
||||||
|
|
||||||
if (Simulation.Durability > 0)
|
if (s.Durability > 0)
|
||||||
{
|
{
|
||||||
if (Simulation.HasEffect(EffectType.Manipulation))
|
if (s.HasEffect(EffectType.Manipulation))
|
||||||
Simulation.RestoreDurability(5);
|
s.RestoreDurability(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IncreasesStepCount)
|
if (IncreasesStepCount)
|
||||||
Simulation.IncreaseStepCount();
|
s.IncreaseStepCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UseSuccess()
|
public virtual void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
if (Efficiency != 0f)
|
if (Efficiency(s) != 0f)
|
||||||
{
|
{
|
||||||
if (IncreasesProgress)
|
if (IncreasesProgress)
|
||||||
Simulation.IncreaseProgress(Efficiency);
|
s.IncreaseProgress(Efficiency(s));
|
||||||
if (IncreasesQuality)
|
if (IncreasesQuality)
|
||||||
Simulation.IncreaseQuality(Efficiency);
|
s.IncreaseQuality(Efficiency(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetTooltip(bool addUsability)
|
public virtual string GetTooltip(Simulator s, bool addUsability)
|
||||||
{
|
{
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
if (addUsability && !CanUse)
|
if (addUsability && !CanUse(s))
|
||||||
builder.AppendLine($"Cannot Use");
|
builder.AppendLine($"Cannot Use");
|
||||||
builder.AppendLine($"Level {Level}");
|
builder.AppendLine($"Level {Level}");
|
||||||
if (CPCost != 0)
|
if (CPCost(s) != 0)
|
||||||
builder.AppendLine($"-{Simulation.CalculateCPCost(CPCost)} CP");
|
builder.AppendLine($"-{s.CalculateCPCost(CPCost(s))} CP");
|
||||||
if (DurabilityCost != 0)
|
if (DurabilityCost != 0)
|
||||||
builder.AppendLine($"-{Simulation.CalculateDurabilityCost(DurabilityCost)} Durability");
|
builder.AppendLine($"-{s.CalculateDurabilityCost(DurabilityCost)} Durability");
|
||||||
if (Efficiency != 0)
|
if (Efficiency(s) != 0)
|
||||||
{
|
{
|
||||||
if (IncreasesProgress)
|
if (IncreasesProgress)
|
||||||
builder.AppendLine($"+{Simulation.CalculateProgressGain(Efficiency)} Progress");
|
builder.AppendLine($"+{s.CalculateProgressGain(Efficiency(s))} Progress");
|
||||||
if (IncreasesQuality)
|
if (IncreasesQuality)
|
||||||
builder.AppendLine($"+{Simulation.CalculateQualityGain(Efficiency)} Quality");
|
builder.AppendLine($"+{s.CalculateQualityGain(Efficiency(s))} Quality");
|
||||||
}
|
}
|
||||||
if (!IncreasesStepCount)
|
if (!IncreasesStepCount)
|
||||||
builder.AppendLine($"Does Not Increase Step Count");
|
builder.AppendLine($"Does Not Increase Step Count");
|
||||||
if (SuccessRate != 1f)
|
if (SuccessRate(s) != 1f)
|
||||||
builder.AppendLine($"{Simulation.CalculateSuccessRate(SuccessRate) * 100}%% Success Rate");
|
builder.AppendLine($"{s.CalculateSuccessRate(SuccessRate(s)) * 100}%% Success Rate");
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,18 @@ namespace Craftimizer.Simulator.Actions;
|
|||||||
|
|
||||||
internal abstract class BaseBuffAction : BaseAction
|
internal abstract class BaseBuffAction : BaseAction
|
||||||
{
|
{
|
||||||
|
// Non-instanced properties
|
||||||
public abstract EffectType Effect { get; }
|
public abstract EffectType Effect { get; }
|
||||||
public virtual byte Duration => 1;
|
public virtual byte Duration => 1;
|
||||||
|
|
||||||
public override int DurabilityCost => 0;
|
public sealed override int DurabilityCost => 0;
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override void UseSuccess(Simulator s) =>
|
||||||
Simulation.AddEffect(Effect, Duration);
|
s.AddEffect(Effect, Duration);
|
||||||
|
|
||||||
public override string GetTooltip(bool addUsability)
|
public sealed override string GetTooltip(Simulator s, bool addUsability)
|
||||||
{
|
{
|
||||||
var builder = new StringBuilder(base.GetTooltip(addUsability));
|
var builder = new StringBuilder(base.GetTooltip(s, addUsability));
|
||||||
builder.AppendLine($"{Duration} Steps");
|
builder.AppendLine($"{Duration} Steps");
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class BasicSynthesis : BaseAction
|
|||||||
public override int Level => 1;
|
public override int Level => 1;
|
||||||
public override uint ActionId => 100001;
|
public override uint ActionId => 100001;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
// Basic Synthesis Mastery Trait
|
|
||||||
public override float Efficiency => Simulation.Input.Stats.Level >= 31 ? 1.20f : 1.00f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 0;
|
||||||
|
// Basic Synthesis Mastery Trait
|
||||||
|
public override float Efficiency(Simulator s) => s.Input.Stats.Level >= 31 ? 1.20f : 1.00f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ internal sealed class BasicTouch : BaseAction
|
|||||||
public override int Level => 5;
|
public override int Level => 5;
|
||||||
public override uint ActionId => 100002;
|
public override uint ActionId => 100002;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 18;
|
||||||
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ internal sealed class ByregotsBlessing : BaseAction
|
|||||||
public override int Level => 50;
|
public override int Level => 50;
|
||||||
public override uint ActionId => 100339;
|
public override uint ActionId => 100339;
|
||||||
|
|
||||||
public override int CPCost => 24;
|
|
||||||
public override float Efficiency => 1.00f + (0.20f * Simulation.GetEffectStrength(EffectType.InnerQuiet));
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.HasEffect(EffectType.InnerQuiet) && base.CanUse;
|
public override int CPCost(Simulator s) => 24;
|
||||||
|
public override float Efficiency(Simulator s) => 1.00f + (0.20f * s.GetEffectStrength(EffectType.InnerQuiet));
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) => s.HasEffect(EffectType.InnerQuiet) && base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.RemoveEffect(EffectType.InnerQuiet);
|
s.RemoveEffect(EffectType.InnerQuiet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ internal sealed class CarefulObservation : BaseAction
|
|||||||
public override int Level => 55;
|
public override int Level => 55;
|
||||||
public override uint ActionId => 100395;
|
public override uint ActionId => 100395;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
public override bool IncreasesStepCount => false;
|
public override bool IncreasesStepCount => false;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.Input.Stats.IsSpecialist && Simulation.ActionStates.CarefulObservationCount < 3;
|
public override int CPCost(Simulator s) => 0;
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override bool CanUse(Simulator s) => s.Input.Stats.IsSpecialist && s.ActionStates.CarefulObservationCount < 3;
|
||||||
Simulation.StepCondition();
|
|
||||||
|
public override void UseSuccess(Simulator s) => s.StepCondition();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class CarefulSynthesis : BaseAction
|
|||||||
public override int Level => 62;
|
public override int Level => 62;
|
||||||
public override uint ActionId => 100203;
|
public override uint ActionId => 100203;
|
||||||
|
|
||||||
public override int CPCost => 7;
|
|
||||||
// Careful Synthesis Mastery Trait
|
|
||||||
public override float Efficiency => Simulation.Input.Stats.Level >= 82 ? 1.80f : 1.50f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 7;
|
||||||
|
// Careful Synthesis Mastery Trait
|
||||||
|
public override float Efficiency(Simulator s) => s.Input.Stats.Level >= 82 ? 1.80f : 1.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class DelicateSynthesis : BaseAction
|
|||||||
public override int Level => 76;
|
public override int Level => 76;
|
||||||
public override uint ActionId => 100323;
|
public override uint ActionId => 100323;
|
||||||
|
|
||||||
public override int CPCost => 32;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 32;
|
||||||
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ internal sealed class FinalAppraisal : BaseBuffAction
|
|||||||
public override int Level => 42;
|
public override int Level => 42;
|
||||||
public override uint ActionId => 19012;
|
public override uint ActionId => 19012;
|
||||||
|
|
||||||
public override int CPCost => 1;
|
|
||||||
public override bool IncreasesStepCount => false;
|
public override bool IncreasesStepCount => false;
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.FinalAppraisal;
|
public override EffectType Effect => EffectType.FinalAppraisal;
|
||||||
public override byte Duration => 5;
|
public override byte Duration => 5;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class FocusedSynthesis : BaseAction
|
|||||||
public override int Level => 67;
|
public override int Level => 67;
|
||||||
public override uint ActionId => 100235;
|
public override uint ActionId => 100235;
|
||||||
|
|
||||||
public override int CPCost => 5;
|
|
||||||
public override float Efficiency => 2.00f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override float SuccessRate => Simulation.ActionStates.Observed ? 1.00f : 0.50f;
|
|
||||||
|
public override int CPCost(Simulator s) => 5;
|
||||||
|
public override float Efficiency(Simulator s) => 2.00f;
|
||||||
|
public override float SuccessRate(Simulator s) => s.ActionStates.Observed ? 1.00f : 0.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class FocusedTouch : BaseAction
|
|||||||
public override int Level => 68;
|
public override int Level => 68;
|
||||||
public override uint ActionId => 100243;
|
public override uint ActionId => 100243;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
public override float Efficiency => 1.50f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override float SuccessRate => Simulation.ActionStates.Observed ? 1.00f : 0.50f;
|
|
||||||
|
public override int CPCost(Simulator s) => 18;
|
||||||
|
public override float Efficiency(Simulator s) => 1.50f;
|
||||||
|
public override float SuccessRate(Simulator s) => s.ActionStates.Observed ? 1.00f : 0.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ internal sealed class GreatStrides : BaseBuffAction
|
|||||||
public override int Level => 21;
|
public override int Level => 21;
|
||||||
public override uint ActionId => 260;
|
public override uint ActionId => 260;
|
||||||
|
|
||||||
public override int CPCost => 32;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.GreatStrides;
|
public override EffectType Effect => EffectType.GreatStrides;
|
||||||
public override byte Duration => 3;
|
public override byte Duration => 3;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 32;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ internal sealed class Groundwork : BaseAction
|
|||||||
public override int Level => 72;
|
public override int Level => 72;
|
||||||
public override uint ActionId => 100403;
|
public override uint ActionId => 100403;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
// Groundwork Mastery Trait
|
|
||||||
public override float Efficiency
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var ret = Simulation.Input.Stats.Level >= 86 ? 3.60f : 3.00f;
|
|
||||||
return Simulation.Durability < Simulation.CalculateDurabilityCost(DurabilityCost) ? ret / 2 : ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override int DurabilityCost => 20;
|
public override int DurabilityCost => 20;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 18;
|
||||||
|
public override float Efficiency(Simulator s)
|
||||||
|
{
|
||||||
|
// Groundwork Mastery Trait
|
||||||
|
var ret = s.Input.Stats.Level >= 86 ? 3.60f : 3.00f;
|
||||||
|
return s.Durability < s.CalculateDurabilityCost(DurabilityCost) ? ret / 2 : ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ internal sealed class HastyTouch : BaseAction
|
|||||||
public override int Level => 9;
|
public override int Level => 9;
|
||||||
public override uint ActionId => 100355;
|
public override uint ActionId => 100355;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override float SuccessRate => 0.60f;
|
|
||||||
|
public override int CPCost(Simulator s) => 0;
|
||||||
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
|
public override float SuccessRate(Simulator s) => 0.60f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ internal sealed class HeartAndSoul : BaseBuffAction
|
|||||||
public override int Level => 86;
|
public override int Level => 86;
|
||||||
public override uint ActionId => 100419;
|
public override uint ActionId => 100419;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
public override bool IncreasesStepCount => false;
|
public override bool IncreasesStepCount => false;
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.HeartAndSoul;
|
public override EffectType Effect => EffectType.HeartAndSoul;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.Input.Stats.IsSpecialist && !Simulation.ActionStates.UsedHeartAndSoul;
|
public override int CPCost(Simulator s) => 0;
|
||||||
|
|
||||||
|
public override bool CanUse(Simulator s) => s.Input.Stats.IsSpecialist && !s.ActionStates.UsedHeartAndSoul;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ internal sealed class Innovation : BaseBuffAction
|
|||||||
public override int Level => 26;
|
public override int Level => 26;
|
||||||
public override uint ActionId => 19004;
|
public override uint ActionId => 19004;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.Innovation;
|
public override EffectType Effect => EffectType.Innovation;
|
||||||
public override byte Duration => 4;
|
public override byte Duration => 4;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 18;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,19 +6,19 @@ internal sealed class IntensiveSynthesis : BaseAction
|
|||||||
public override int Level => 78;
|
public override int Level => 78;
|
||||||
public override uint ActionId => 100315;
|
public override uint ActionId => 100315;
|
||||||
|
|
||||||
public override int CPCost => 6;
|
|
||||||
public override float Efficiency => 4.00f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override bool IsGuaranteedAction => false;
|
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 6;
|
||||||
(Simulation.Condition == Condition.Good || Simulation.Condition == Condition.Excellent || Simulation.HasEffect(EffectType.HeartAndSoul))
|
public override float Efficiency(Simulator s) => 4.00f;
|
||||||
&& base.CanUse;
|
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) =>
|
||||||
|
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
|
||||||
|
&& base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
if (Simulation.Condition != Condition.Good && Simulation.Condition != Condition.Excellent)
|
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
|
||||||
Simulation.RemoveEffect(EffectType.HeartAndSoul);
|
s.RemoveEffect(EffectType.HeartAndSoul);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ internal sealed class Manipulation : BaseBuffAction
|
|||||||
public override int Level => 65;
|
public override int Level => 65;
|
||||||
public override uint ActionId => 4574;
|
public override uint ActionId => 4574;
|
||||||
|
|
||||||
public override int CPCost => 96;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.Manipulation;
|
public override EffectType Effect => EffectType.Manipulation;
|
||||||
public override byte Duration => 8;
|
public override byte Duration => 8;
|
||||||
|
|
||||||
public override void Use()
|
public override int CPCost(Simulator s) => 96;
|
||||||
|
|
||||||
|
public override void Use(Simulator s)
|
||||||
{
|
{
|
||||||
if (Simulation.HasEffect(EffectType.Manipulation))
|
if (s.HasEffect(EffectType.Manipulation))
|
||||||
Simulation.RestoreDurability(5);
|
s.RestoreDurability(5);
|
||||||
|
|
||||||
Simulation.ReduceCP(CPCost);
|
s.ReduceCP(CPCost(s));
|
||||||
Simulation.ReduceDurability(DurabilityCost);
|
s.ReduceDurability(DurabilityCost);
|
||||||
|
|
||||||
UseSuccess();
|
UseSuccess(s);
|
||||||
|
|
||||||
Simulation.IncreaseStepCount();
|
s.IncreaseStepCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ internal sealed class MastersMend : BaseAction
|
|||||||
public override int Level => 7;
|
public override int Level => 7;
|
||||||
public override uint ActionId => 100003;
|
public override uint ActionId => 100003;
|
||||||
|
|
||||||
public override int CPCost => 88;
|
|
||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override int CPCost(Simulator s) => 88;
|
||||||
Simulation.RestoreDurability(30);
|
|
||||||
|
public override void UseSuccess(Simulator s) =>
|
||||||
|
s.RestoreDurability(30);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ internal sealed class MuscleMemory : BaseAction
|
|||||||
public override int Level => 54;
|
public override int Level => 54;
|
||||||
public override uint ActionId => 100379;
|
public override uint ActionId => 100379;
|
||||||
|
|
||||||
public override int CPCost => 6;
|
|
||||||
public override float Efficiency => 3.00f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.IsFirstStep && base.CanUse;
|
public override int CPCost(Simulator s) => 6;
|
||||||
|
public override float Efficiency(Simulator s) => 3.00f;
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) => s.IsFirstStep && base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.AddEffect(EffectType.MuscleMemory, 5);
|
s.AddEffect(EffectType.MuscleMemory, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ internal sealed class Observe : BaseAction
|
|||||||
public override int Level => 13;
|
public override int Level => 13;
|
||||||
public override uint ActionId => 100010;
|
public override uint ActionId => 100010;
|
||||||
|
|
||||||
public override int CPCost => 7;
|
|
||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 7;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ internal sealed class PreciseTouch : BaseAction
|
|||||||
public override int Level => 53;
|
public override int Level => 53;
|
||||||
public override uint ActionId => 100128;
|
public override uint ActionId => 100128;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
public override float Efficiency => 1.50f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override bool IsGuaranteedAction => false;
|
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 18;
|
||||||
(Simulation.Condition == Condition.Good || Simulation.Condition == Condition.Excellent || Simulation.HasEffect(EffectType.HeartAndSoul))
|
public override float Efficiency(Simulator s) => 1.50f;
|
||||||
&& base.CanUse;
|
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) =>
|
||||||
|
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
|
||||||
|
&& base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.StrengthenEffect(EffectType.InnerQuiet);
|
s.StrengthenEffect(EffectType.InnerQuiet);
|
||||||
if (Simulation.Condition != Condition.Good && Simulation.Condition != Condition.Excellent)
|
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
|
||||||
Simulation.RemoveEffect(EffectType.HeartAndSoul);
|
s.RemoveEffect(EffectType.HeartAndSoul);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,15 @@ internal sealed class PreparatoryTouch : BaseAction
|
|||||||
public override int Level => 71;
|
public override int Level => 71;
|
||||||
public override uint ActionId => 100299;
|
public override uint ActionId => 100299;
|
||||||
|
|
||||||
public override int CPCost => 40;
|
|
||||||
public override float Efficiency => 2.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override int DurabilityCost => 20;
|
public override int DurabilityCost => 20;
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override int CPCost(Simulator s) => 40;
|
||||||
|
public override float Efficiency(Simulator s) => 2.00f;
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.StrengthenEffect(EffectType.InnerQuiet);
|
s.StrengthenEffect(EffectType.InnerQuiet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ internal sealed class PrudentSynthesis : BaseAction
|
|||||||
public override int Level => 88;
|
public override int Level => 88;
|
||||||
public override uint ActionId => 100427;
|
public override uint ActionId => 100427;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
public override float Efficiency => 1.80f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override int DurabilityCost => base.DurabilityCost / 2;
|
public override int DurabilityCost => base.DurabilityCost / 2;
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 18;
|
||||||
!(Simulation.HasEffect(EffectType.WasteNot) || Simulation.HasEffect(EffectType.WasteNot2))
|
public override float Efficiency(Simulator s) => 1.80f;
|
||||||
&& base.CanUse;
|
|
||||||
|
public override bool CanUse(Simulator s) =>
|
||||||
|
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
|
||||||
|
&& base.CanUse(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ internal sealed class PrudentTouch : BaseAction
|
|||||||
public override int Level => 66;
|
public override int Level => 66;
|
||||||
public override uint ActionId => 100227;
|
public override uint ActionId => 100227;
|
||||||
|
|
||||||
public override int CPCost => 25;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override int DurabilityCost => base.DurabilityCost / 2;
|
public override int DurabilityCost => base.DurabilityCost / 2;
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 25;
|
||||||
!(Simulation.HasEffect(EffectType.WasteNot) || Simulation.HasEffect(EffectType.WasteNot2))
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
&& base.CanUse;
|
|
||||||
|
public override bool CanUse(Simulator s) =>
|
||||||
|
!(s.HasEffect(EffectType.WasteNot) || s.HasEffect(EffectType.WasteNot2))
|
||||||
|
&& base.CanUse(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ internal sealed class RapidSynthesis : BaseAction
|
|||||||
public override int Level => 9;
|
public override int Level => 9;
|
||||||
public override uint ActionId => 100363;
|
public override uint ActionId => 100363;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
// Rapid Synthesis Mastery Trait
|
|
||||||
public override float Efficiency => Simulation.Input.Stats.Level >= 63 ? 5.00f : 2.50f;
|
|
||||||
public override bool IncreasesProgress => true;
|
public override bool IncreasesProgress => true;
|
||||||
public override float SuccessRate => 0.50f;
|
|
||||||
|
public override int CPCost(Simulator s) => 0;
|
||||||
|
// Rapid Synthesis Mastery Trait
|
||||||
|
public override float Efficiency(Simulator s) => s.Input.Stats.Level >= 63 ? 5.00f : 2.50f;
|
||||||
|
public override float SuccessRate(Simulator s) => 0.50f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ internal sealed class Reflect : BaseAction
|
|||||||
public override int Level => 69;
|
public override int Level => 69;
|
||||||
public override uint ActionId => 100387;
|
public override uint ActionId => 100387;
|
||||||
|
|
||||||
public override int CPCost => 6;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
public override bool CanUse => Simulation.IsFirstStep && base.CanUse;
|
public override int CPCost(Simulator s) => 6;
|
||||||
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) => s.IsFirstStep && base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.StrengthenEffect(EffectType.InnerQuiet);
|
s.StrengthenEffect(EffectType.InnerQuiet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ internal sealed class StandardTouch : BaseAction
|
|||||||
public override int Level => 18;
|
public override int Level => 18;
|
||||||
public override uint ActionId => 100004;
|
public override uint ActionId => 100004;
|
||||||
|
|
||||||
public override int CPCost => Simulation.ActionStates.TouchComboIdx == 1 ? 18 : 32;
|
|
||||||
public override float Efficiency => 1.25f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => s.ActionStates.TouchComboIdx == 1 ? 18 : 32;
|
||||||
|
public override float Efficiency(Simulator s) => 1.25f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ internal sealed class TrainedEye : BaseAction
|
|||||||
public override int Level => 80;
|
public override int Level => 80;
|
||||||
public override uint ActionId => 100283;
|
public override uint ActionId => 100283;
|
||||||
|
|
||||||
public override int CPCost => 250;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 250;
|
||||||
Simulation.IsFirstStep &&
|
|
||||||
!Simulation.Input.Recipe.IsExpert &&
|
|
||||||
Simulation.Input.Stats.Level >= (Simulation.Input.Recipe.ClassJobLevel + 10) &&
|
|
||||||
base.CanUse;
|
|
||||||
|
|
||||||
public override void UseSuccess() =>
|
public override bool CanUse(Simulator s) =>
|
||||||
Simulation.IncreaseQualityRaw(Simulation.Input.Recipe.MaxQuality - Simulation.Quality);
|
s.IsFirstStep &&
|
||||||
|
!s.Input.Recipe.IsExpert &&
|
||||||
|
s.Input.Stats.Level >= (s.Input.Recipe.ClassJobLevel + 10) &&
|
||||||
|
base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s) =>
|
||||||
|
s.IncreaseQualityRaw(s.Input.Recipe.MaxQuality - s.Quality);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ internal sealed class TrainedFinesse : BaseAction
|
|||||||
public override int Level => 90;
|
public override int Level => 90;
|
||||||
public override uint ActionId => 100435;
|
public override uint ActionId => 100435;
|
||||||
|
|
||||||
public override int CPCost => 32;
|
|
||||||
public override float Efficiency => 1.00f;
|
|
||||||
public override bool IncreasesQuality => true;
|
public override bool IncreasesQuality => true;
|
||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 32;
|
||||||
Simulation.GetEffectStrength(EffectType.InnerQuiet) == 10
|
public override float Efficiency(Simulator s) => 1.00f;
|
||||||
&& base.CanUse;
|
|
||||||
|
public override bool CanUse(Simulator s) =>
|
||||||
|
s.GetEffectStrength(EffectType.InnerQuiet) == 10
|
||||||
|
&& base.CanUse(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ internal sealed class TricksOfTheTrade : BaseAction
|
|||||||
public override int Level => 13;
|
public override int Level => 13;
|
||||||
public override uint ActionId => 100371;
|
public override uint ActionId => 100371;
|
||||||
|
|
||||||
public override int CPCost => 0;
|
|
||||||
public override int DurabilityCost => 0;
|
public override int DurabilityCost => 0;
|
||||||
public override bool IsGuaranteedAction => false;
|
|
||||||
|
|
||||||
public override bool CanUse =>
|
public override int CPCost(Simulator s) => 0;
|
||||||
(Simulation.Condition == Condition.Good || Simulation.Condition == Condition.Excellent || Simulation.HasEffect(EffectType.HeartAndSoul))
|
|
||||||
&& base.CanUse;
|
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override bool CanUse(Simulator s) =>
|
||||||
|
(s.Condition == Condition.Good || s.Condition == Condition.Excellent || s.HasEffect(EffectType.HeartAndSoul))
|
||||||
|
&& base.CanUse(s);
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
Simulation.RestoreCP(20);
|
s.RestoreCP(20);
|
||||||
if (Simulation.Condition != Condition.Good && Simulation.Condition != Condition.Excellent)
|
if (s.Condition != Condition.Good && s.Condition != Condition.Excellent)
|
||||||
Simulation.RemoveEffect(EffectType.HeartAndSoul);
|
s.RemoveEffect(EffectType.HeartAndSoul);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ internal sealed class Veneration : BaseBuffAction
|
|||||||
public override int Level => 15;
|
public override int Level => 15;
|
||||||
public override uint ActionId => 19297;
|
public override uint ActionId => 19297;
|
||||||
|
|
||||||
public override int CPCost => 18;
|
|
||||||
public override int DurabilityCost => 0;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.Veneration;
|
public override EffectType Effect => EffectType.Veneration;
|
||||||
public override byte Duration => 4;
|
public override byte Duration => 4;
|
||||||
|
|
||||||
|
public override int CPCost(Simulator s) => 18;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ internal sealed class WasteNot : BaseBuffAction
|
|||||||
public override int Level => 15;
|
public override int Level => 15;
|
||||||
public override uint ActionId => 4631;
|
public override uint ActionId => 4631;
|
||||||
|
|
||||||
public override int CPCost => 56;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.WasteNot;
|
public override EffectType Effect => EffectType.WasteNot;
|
||||||
public override byte Duration => 4;
|
public override byte Duration => 4;
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override int CPCost(Simulator s) => 56;
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.RemoveEffect(EffectType.WasteNot2);
|
s.RemoveEffect(EffectType.WasteNot2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ internal sealed class WasteNot2 : BaseBuffAction
|
|||||||
public override int Level => 47;
|
public override int Level => 47;
|
||||||
public override uint ActionId => 4639;
|
public override uint ActionId => 4639;
|
||||||
|
|
||||||
public override int CPCost => 98;
|
|
||||||
|
|
||||||
public override EffectType Effect => EffectType.WasteNot2;
|
public override EffectType Effect => EffectType.WasteNot2;
|
||||||
public override byte Duration => 8;
|
public override byte Duration => 8;
|
||||||
|
|
||||||
public override void UseSuccess()
|
public override int CPCost(Simulator s) => 98;
|
||||||
|
|
||||||
|
public override void UseSuccess(Simulator s)
|
||||||
{
|
{
|
||||||
base.UseSuccess();
|
base.UseSuccess(s);
|
||||||
Simulation.RemoveEffect(EffectType.WasteNot);
|
s.RemoveEffect(EffectType.WasteNot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Diagnostics.Contracts;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Craftimizer.Simulator;
|
namespace Craftimizer.Simulator;
|
||||||
@@ -16,6 +18,7 @@ public struct Effects
|
|||||||
public byte Manipulation;
|
public byte Manipulation;
|
||||||
public bool HeartAndSoul;
|
public bool HeartAndSoul;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetDuration(EffectType effect, byte duration)
|
public void SetDuration(EffectType effect, byte duration)
|
||||||
{
|
{
|
||||||
switch (effect)
|
switch (effect)
|
||||||
@@ -54,12 +57,15 @@ public struct Effects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Strengthen(EffectType effect)
|
public void Strengthen(EffectType effect)
|
||||||
{
|
{
|
||||||
if (effect == EffectType.InnerQuiet && InnerQuiet < 10)
|
if (effect == EffectType.InnerQuiet && InnerQuiet < 10)
|
||||||
InnerQuiet++;
|
InnerQuiet++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly byte GetDuration(EffectType effect) =>
|
public readonly byte GetDuration(EffectType effect) =>
|
||||||
effect switch
|
effect switch
|
||||||
{
|
{
|
||||||
@@ -76,13 +82,18 @@ public struct Effects
|
|||||||
_ => 0
|
_ => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly byte GetStrength(EffectType effect) =>
|
public readonly byte GetStrength(EffectType effect) =>
|
||||||
effect == EffectType.InnerQuiet ? InnerQuiet :
|
effect == EffectType.InnerQuiet ? InnerQuiet :
|
||||||
(byte)(GetDuration(effect) != 0 ? 1 : 0);
|
(byte)(GetDuration(effect) != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly bool HasEffect(EffectType effect) =>
|
public readonly bool HasEffect(EffectType effect) =>
|
||||||
GetDuration(effect) != 0;
|
GetDuration(effect) != 0;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void DecrementDuration()
|
public void DecrementDuration()
|
||||||
{
|
{
|
||||||
if (WasteNot > 0)
|
if (WasteNot > 0)
|
||||||
|
|||||||
@@ -50,17 +50,17 @@ public class Simulator
|
|||||||
if (IsComplete)
|
if (IsComplete)
|
||||||
return ActionResponse.SimulationComplete;
|
return ActionResponse.SimulationComplete;
|
||||||
|
|
||||||
var baseAction = action.With(this);
|
var baseAction = action.Base();
|
||||||
if (!baseAction.CanUse)
|
if (!baseAction.CanUse(this))
|
||||||
{
|
{
|
||||||
if (baseAction.Level > Input.Stats.Level)
|
if (baseAction.Level > Input.Stats.Level)
|
||||||
return ActionResponse.ActionNotUnlocked;
|
return ActionResponse.ActionNotUnlocked;
|
||||||
if (baseAction.CPCost > CP)
|
if (baseAction.CPCost(this) > CP)
|
||||||
return ActionResponse.NotEnoughCP;
|
return ActionResponse.NotEnoughCP;
|
||||||
return ActionResponse.CannotUseAction;
|
return ActionResponse.CannotUseAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseAction.Use();
|
baseAction.Use(this);
|
||||||
ActionStates.MutateState(action);
|
ActionStates.MutateState(action);
|
||||||
ActionCount++;
|
ActionCount++;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Craftimizer.Simulator.Actions;
|
using Craftimizer.Simulator.Actions;
|
||||||
|
using System.Diagnostics.Contracts;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Intrinsics.X86;
|
using System.Runtime.Intrinsics.X86;
|
||||||
@@ -42,23 +43,29 @@ public struct ActionSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static int FromAction(ActionType action) => Array.IndexOf(Simulator.AcceptedActions, action);
|
private static int FromAction(ActionType action) => Simulator.AcceptedActionsLUT[(byte)action];
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private static ActionType ToAction(int index) => Simulator.AcceptedActions[index];
|
private static ActionType ToAction(int index) => Simulator.AcceptedActions[index];
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public readonly bool HasAction(ActionType action) => (bits & (1u << (FromAction(action) + 1))) != 0;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void AddAction(ActionType action) => bits |= 1u << (FromAction(action) + 1);
|
public void AddAction(ActionType action) => bits |= 1u << (FromAction(action) + 1);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveAction(ActionType action) => bits &= ~(1u << (FromAction(action) + 1));
|
public void RemoveAction(ActionType action) => bits &= ~(1u << (FromAction(action) + 1));
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public readonly bool HasAction(ActionType action) => (bits & (1u << (FromAction(action) + 1))) != 0;
|
||||||
|
[Pure]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly ActionType ElementAt(int index) => ToAction(NthBitSet(bits, index) - 1);
|
public readonly ActionType ElementAt(int index) => ToAction(NthBitSet(bits, index) - 1);
|
||||||
|
|
||||||
|
[Pure]
|
||||||
public readonly int Count => BitOperations.PopCount(bits);
|
public readonly int Count => BitOperations.PopCount(bits);
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly ActionType SelectRandom(Random random) => ElementAt(random.Next(Count));
|
public readonly ActionType SelectRandom(Random random) => ElementAt(random.Next(Count));
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly ActionType First() => ElementAt(0);
|
public readonly ActionType First() => ElementAt(0);
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-10
@@ -1,10 +1,12 @@
|
|||||||
using Craftimizer.Simulator;
|
using Craftimizer.Simulator;
|
||||||
using Craftimizer.Simulator.Actions;
|
using Craftimizer.Simulator.Actions;
|
||||||
|
using System.Diagnostics.Contracts;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using Sim = Craftimizer.Simulator.Simulator;
|
using Sim = Craftimizer.Simulator.Simulator;
|
||||||
|
|
||||||
namespace Craftimizer.Solver.Crafty;
|
namespace Craftimizer.Solver.Crafty;
|
||||||
|
|
||||||
public class Simulator : Sim
|
public sealed class Simulator : Sim
|
||||||
{
|
{
|
||||||
private readonly int maxStepCount;
|
private readonly int maxStepCount;
|
||||||
|
|
||||||
@@ -52,12 +54,26 @@ public class Simulator : Sim
|
|||||||
ActionType.BasicTouch,
|
ActionType.BasicTouch,
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L146
|
public static readonly int[] AcceptedActionsLUT;
|
||||||
private bool CanUseAction(ActionType action, bool strict)
|
|
||||||
{
|
|
||||||
var baseAction = action.WithUnsafe();
|
|
||||||
|
|
||||||
if (CalculateSuccessRate(baseAction.SuccessRate) != 1)
|
static Simulator()
|
||||||
|
{
|
||||||
|
AcceptedActionsLUT = new int[Enum.GetValues<ActionType>().Length];
|
||||||
|
for (var i = 0; i < AcceptedActions.Length; i++)
|
||||||
|
AcceptedActionsLUT[(byte)AcceptedActions[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L146
|
||||||
|
[Pure]
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// It's just a bunch of if statements, I would assume this is actually quite simple to follow
|
||||||
|
#pragma warning disable MA0051 // Method is too long
|
||||||
|
private bool CanUseAction(ActionType action, bool strict)
|
||||||
|
#pragma warning restore MA0051 // Method is too long
|
||||||
|
{
|
||||||
|
var baseAction = action.Base();
|
||||||
|
|
||||||
|
if (CalculateSuccessRate(baseAction.SuccessRate(this)) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// don't allow quality moves at max quality
|
// don't allow quality moves at max quality
|
||||||
@@ -72,7 +88,7 @@ public class Simulator : Sim
|
|||||||
{
|
{
|
||||||
// always used Trained Eye if it's available
|
// always used Trained Eye if it's available
|
||||||
if (action == ActionType.TrainedEye)
|
if (action == ActionType.TrainedEye)
|
||||||
return baseAction.CanUse;
|
return baseAction.CanUse(this);
|
||||||
|
|
||||||
// only allow Focused moves after Observe
|
// only allow Focused moves after Observe
|
||||||
if (ActionStates.Observed &&
|
if (ActionStates.Observed &&
|
||||||
@@ -94,7 +110,7 @@ public class Simulator : Sim
|
|||||||
|
|
||||||
if (baseAction.IncreasesProgress)
|
if (baseAction.IncreasesProgress)
|
||||||
{
|
{
|
||||||
var progressIncrease = CalculateProgressGain(baseAction.Efficiency);
|
var progressIncrease = CalculateProgressGain(baseAction.Efficiency(this));
|
||||||
var wouldFinish = Progress + progressIncrease >= Input.Recipe.MaxProgress;
|
var wouldFinish = Progress + progressIncrease >= Input.Recipe.MaxProgress;
|
||||||
|
|
||||||
if (wouldFinish)
|
if (wouldFinish)
|
||||||
@@ -142,7 +158,7 @@ public class Simulator : Sim
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseAction.CanUse;
|
return baseAction.CanUse(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L137
|
// https://github.com/alostsock/crafty/blob/cffbd0cad8bab3cef9f52a3e3d5da4f5e3781842/crafty/src/craft_state.rs#L137
|
||||||
@@ -151,7 +167,6 @@ public class Simulator : Sim
|
|||||||
if (IsComplete)
|
if (IsComplete)
|
||||||
return new();
|
return new();
|
||||||
|
|
||||||
ActionUtils.SetSimulation(this);
|
|
||||||
var ret = new ActionSet();
|
var ret = new ActionSet();
|
||||||
foreach (var action in AcceptedActions)
|
foreach (var action in AcceptedActions)
|
||||||
if (CanUseAction(action, strict))
|
if (CanUseAction(action, strict))
|
||||||
|
|||||||
+7
-11
@@ -1,5 +1,6 @@
|
|||||||
using Craftimizer.Simulator;
|
using Craftimizer.Simulator;
|
||||||
using Craftimizer.Simulator.Actions;
|
using Craftimizer.Simulator.Actions;
|
||||||
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@@ -32,20 +33,14 @@ public class Solver
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private (SimulationState NewState, CompletionState SimulatorCompletionState, ActionSet AvailableActions) ExecuteSimple(SimulationState state, ActionType action, bool strict)
|
|
||||||
{
|
|
||||||
(_, var newState) = Simulator.Execute(state, action);
|
|
||||||
return (newState, Simulator.CompletionState, Simulator.AvailableActionsHeuristic(strict));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SimulationNode Execute(SimulationState state, ActionType action, bool strict)
|
private SimulationNode Execute(SimulationState state, ActionType action, bool strict)
|
||||||
{
|
{
|
||||||
(var newState, var completionState, var newActions) = ExecuteSimple(state, action, strict);
|
(_, var newState) = Simulator.Execute(state, action);
|
||||||
return new(
|
return new(
|
||||||
newState,
|
newState,
|
||||||
action,
|
action,
|
||||||
completionState,
|
Simulator.CompletionState,
|
||||||
newActions
|
Simulator.AvailableActionsHeuristic(strict)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,11 +172,12 @@ public class Solver
|
|||||||
break;
|
break;
|
||||||
randomAction = currentActions.SelectRandom(Random);
|
randomAction = currentActions.SelectRandom(Random);
|
||||||
actions[actionCount++] = randomAction;
|
actions[actionCount++] = randomAction;
|
||||||
(currentState, currentCompletionState, currentActions) = ExecuteSimple(currentState, randomAction, true);
|
(_, currentState) = Simulator.Execute(currentState, randomAction);
|
||||||
|
currentCompletionState = Simulator.CompletionState;
|
||||||
|
currentActions = Simulator.AvailableActionsHeuristic(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the result if a max score was reached
|
// store the result if a max score was reached
|
||||||
currentCompletionState = SimulationNode.GetCompletionState(currentCompletionState, currentActions);
|
|
||||||
var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState, Config.MaxStepCount) ?? 0;
|
var score = SimulationNode.CalculateScoreForState(currentState, currentCompletionState, Config.MaxStepCount) ?? 0;
|
||||||
if (currentCompletionState == CompletionState.ProgressComplete)
|
if (currentCompletionState == CompletionState.ProgressComplete)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user