Convert actions to singletons resolved from ActionType enum

This commit is contained in:
Asriel Camora
2023-06-16 00:03:15 -07:00
parent faa73d238c
commit 5555966b5b
40 changed files with 197 additions and 202 deletions
@@ -3,7 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
namespace Craftimizer; namespace Craftimizer.Plugin;
internal class ImGuiUtils internal class ImGuiUtils
{ {
@@ -58,7 +58,7 @@ internal class ImGuiUtils
ImGui.SameLine(0, 0); ImGui.SameLine(0, 0);
ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0)); ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0));
ImGui.Dummy(new Vector2(0f, (frameHeight * 0.5f) - itemSpacing.Y)); ImGui.Dummy(new Vector2(0f, frameHeight * 0.5f - itemSpacing.Y));
ImGui.EndGroup(); ImGui.EndGroup();
+8 -10
View File
@@ -2,8 +2,6 @@ using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions; using Craftimizer.Simulator.Actions;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Windowing; using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using System; using System;
using System.Linq; using System.Linq;
@@ -14,7 +12,6 @@ namespace Craftimizer.Plugin;
public class SimulatorWindow : Window public class SimulatorWindow : Window
{ {
public Simulation Simulation { get; } public Simulation Simulation { get; }
public BaseAction[] AvailableActions { get; }
private bool showOnlyGuaranteedActions = true; private bool showOnlyGuaranteedActions = true;
@@ -27,7 +24,6 @@ public class SimulatorWindow : Window
}; };
Simulation = new(new CharacterStats { Craftsmanship = 4041, Control = 3905, CP = 609, Level = 90 }, LuminaSheets.RecipeSheet.GetRow(35499)!); Simulation = new(new CharacterStats { Craftsmanship = 4041, Control = 3905, CP = 609, Level = 90 }, LuminaSheets.RecipeSheet.GetRow(35499)!);
AvailableActions = BaseAction.Actions.Select(a => (Activator.CreateInstance(a, Simulation)! as BaseAction)!).ToArray();
} }
public override void Draw() public override void Draw()
@@ -38,20 +34,21 @@ public class SimulatorWindow : Window
ImGui.BeginChild("CraftimizerActions", Vector2.Zero, true, ImGuiWindowFlags.NoDecoration); ImGui.BeginChild("CraftimizerActions", Vector2.Zero, true, ImGuiWindowFlags.NoDecoration);
ImGui.Checkbox("Show only guaranteed actions", ref showOnlyGuaranteedActions); ImGui.Checkbox("Show only guaranteed actions", ref showOnlyGuaranteedActions);
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
foreach(var category in AvailableActions.GroupBy(a => a.Category)) foreach(var category in Enum.GetValues<ActionType>().GroupBy(a => a.Category()))
{ {
var i = 0; var i = 0;
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()))
{ {
if (showOnlyGuaranteedActions && !action.IsGuaranteedAction) var baseAction = action.With(Simulation);
if (showOnlyGuaranteedActions && !baseAction.IsGuaranteedAction)
continue; continue;
ImGui.BeginDisabled(!action.CanUse); ImGui.BeginDisabled(!baseAction.CanUse);
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)))
Simulation.Execute(action); Simulation.Execute(action);
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
ImGui.SetTooltip(action.GetTooltip(true)); ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(true)}");
ImGui.EndDisabled(); ImGui.EndDisabled();
if (++i % 5 != 0) if (++i % 5 != 0)
ImGui.SameLine(); ImGui.SameLine();
@@ -95,9 +92,10 @@ public class SimulatorWindow : Window
var i = 0; var i = 0;
foreach (var action in Simulation.ActionHistory) foreach (var action in Simulation.ActionHistory)
{ {
var baseAction = action.With(Simulation);
ImGui.Image(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2f)); ImGui.Image(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2f));
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
ImGui.SetTooltip(action.GetTooltip(false)); ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(false)}");
if (++i % 5 != 0) if (++i % 5 != 0)
ImGui.SameLine(); ImGui.SameLine();
} }
+127
View File
@@ -0,0 +1,127 @@
using Craftimizer.Plugin;
using Dalamud.Utility;
using ImGuiScene;
using Lumina.Excel.GeneratedSheets;
using System;
using System.Linq;
using Action = Lumina.Excel.GeneratedSheets.Action;
namespace Craftimizer.Simulator.Actions;
public enum ActionType
{
AdvancedTouch,
BasicSynthesis,
BasicTouch,
ByregotsBlessing,
CarefulObservation,
CarefulSynthesis,
DelicateSynthesis,
FinalAppraisal,
FocusedSynthesis,
FocusedTouch,
GreatStrides,
Groundwork,
HastyTouch,
HeartAndSoul,
Innovation,
IntensiveSynthesis,
Manipulation,
MastersMend,
MuscleMemory,
Observe,
PreciseTouch,
PreparatoryTouch,
PrudentSynthesis,
PrudentTouch,
RapidSynthesis,
Reflect,
StandardTouch,
TrainedEye,
TrainedFinesse,
TricksOfTheTrade,
Veneration,
WasteNot,
WasteNot2,
}
internal static class ActionUtils
{
private static readonly BaseAction[] Actions;
static ActionUtils()
{
var types = typeof(BaseAction).Assembly.GetTypes()
.Where(t => t.IsAssignableTo(typeof(BaseAction)) && !t.IsAbstract);
Actions = Enum.GetNames<ActionType>()
.Select(a => types.First(t => t.Name == a))
.Select(t => (Activator.CreateInstance(t) as BaseAction)!)
.ToArray();
}
private static BaseAction Action(this ActionType me) => Actions[(int)me];
public static BaseAction With(this ActionType me, Simulation simulation)
{
BaseAction.TLSSimulation.Value = simulation;
return Action(me);
}
public static int Level(this ActionType me) =>
Action(me).Level;
public static ActionCategory Category(this ActionType me) =>
Action(me).Category;
private static (CraftAction? CraftAction, Action? Action) GetActionRow(this ActionType me, ClassJob classJob)
{
var actionId = Action(me).ActionId;
if (LuminaSheets.CraftActionSheet.GetRow(actionId) is CraftAction baseCraftAction)
{
return (classJob switch
{
ClassJob.Carpenter => baseCraftAction.CRP.Value!,
ClassJob.Blacksmith => baseCraftAction.BSM.Value!,
ClassJob.Armorer => baseCraftAction.ARM.Value!,
ClassJob.Goldsmith => baseCraftAction.GSM.Value!,
ClassJob.Leatherworker => baseCraftAction.LTW.Value!,
ClassJob.Weaver => baseCraftAction.WVR.Value!,
ClassJob.Alchemist => baseCraftAction.ALC.Value!,
ClassJob.Culinarian => baseCraftAction.CUL.Value!,
_ => baseCraftAction
}, null);
}
else if (LuminaSheets.ActionSheet.GetRow(actionId) is Action baseAction)
{
return (null,
LuminaSheets.ActionSheet.First(r =>
r.Icon == baseAction.Icon &&
r.ActionCategory.Row == baseAction.ActionCategory.Row &&
r.Name.RawString == baseAction.Name.RawString &&
(r.ClassJobCategory.Value?.IsClassJob(classJob) ?? false)
));
}
return (null, null);
}
public static string GetName(this ActionType me, ClassJob classJob)
{
var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null)
return craftAction.Name.ToDalamudString().TextValue;
else if (action != null)
return action.Name.ToDalamudString().TextValue;
return "Unknown";
}
public static TextureWrap GetIcon(this ActionType me, ClassJob classJob)
{
var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null)
return Icons.GetIconFromId(craftAction.Icon);
else if (action != null)
return Icons.GetIconFromId(action.Icon);
// Old "Steady Hand" action icon
return Icons.GetIconFromId(1953);
}
}
@@ -2,13 +2,11 @@ namespace Craftimizer.Simulator.Actions;
internal class AdvancedTouch : BaseAction internal class AdvancedTouch : BaseAction
{ {
public AdvancedTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 84; public override int Level => 84;
public override int ActionId => 100411; public override uint ActionId => 100411;
public override int CPCost => Simulation.IsPreviousAction<StandardTouch>() && Simulation.IsPreviousAction<BasicTouch>(2) ? 18 : 46; public override int CPCost => Simulation.IsPreviousAction(ActionType.StandardTouch) && Simulation.IsPreviousAction(ActionType.BasicTouch, 2) ? 18 : 46;
public override float Efficiency => 1.50f; public override float Efficiency => 1.50f;
public override bool IncreasesQuality => true; public override bool IncreasesQuality => true;
} }
+8 -68
View File
@@ -1,31 +1,23 @@
using Craftimizer.Plugin;
using Dalamud.Utility;
using ImGuiScene;
using Lumina.Excel.GeneratedSheets;
using System; using System;
using System.Linq;
using System.Text; using System.Text;
using Action = Lumina.Excel.GeneratedSheets.Action; using System.Threading;
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
public abstract class BaseAction internal abstract class BaseAction
{ {
public static readonly Type[] Actions = typeof(BaseAction).Assembly.GetTypes() internal static readonly ThreadLocal<Simulation> TLSSimulation = new(false);
.Where(type => type.IsAssignableTo(typeof(BaseAction)) && !type.IsAbstract).ToArray(); protected static Simulation Simulation => TLSSimulation.Value ?? throw new NullReferenceException();
protected Simulation Simulation { get; } public BaseAction() { }
public BaseAction(Simulation simulation)
{
Simulation = simulation;
}
// Non-instanced properties
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 int ActionId { get; } public abstract uint ActionId { get; }
// Instanced properties
public abstract int CPCost { get; } public abstract int CPCost { get; }
public virtual float Efficiency => 0f; public virtual float Efficiency => 0f;
public virtual bool IncreasesProgress => false; public virtual bool IncreasesProgress => false;
@@ -35,57 +27,6 @@ public abstract class BaseAction
public virtual bool IncreasesStepCount => true; public virtual bool IncreasesStepCount => true;
public virtual bool IsGuaranteedAction => SuccessRate == 1f; public virtual bool IsGuaranteedAction => SuccessRate == 1f;
private (CraftAction? CraftAction, Action? Action) GetActionRow(ClassJob classJob)
{
if (LuminaSheets.CraftActionSheet.GetRow((uint)ActionId) is CraftAction baseCraftAction)
{
return (classJob switch
{
ClassJob.Carpenter => baseCraftAction.CRP.Value!,
ClassJob.Blacksmith => baseCraftAction.BSM.Value!,
ClassJob.Armorer => baseCraftAction.ARM.Value!,
ClassJob.Goldsmith => baseCraftAction.GSM.Value!,
ClassJob.Leatherworker => baseCraftAction.LTW.Value!,
ClassJob.Weaver => baseCraftAction.WVR.Value!,
ClassJob.Alchemist => baseCraftAction.ALC.Value!,
ClassJob.Culinarian => baseCraftAction.CUL.Value!,
_ => baseCraftAction
}, null);
}
else if (LuminaSheets.ActionSheet.GetRow((uint)ActionId) is Action baseAction)
{
return (null,
LuminaSheets.ActionSheet.First(r =>
r.Icon == baseAction.Icon &&
r.ActionCategory.Row == baseAction.ActionCategory.Row &&
r.Name.RawString == baseAction.Name.RawString &&
(r.ClassJobCategory.Value?.IsClassJob(classJob) ?? false)
));
}
return (null, null);
}
public string GetName(ClassJob classJob)
{
var (craftAction, action) = GetActionRow(classJob);
if (craftAction != null)
return craftAction.Name.ToDalamudString().TextValue;
else if (action != null)
return action.Name.ToDalamudString().TextValue;
return "Unknown";
}
public TextureWrap GetIcon(ClassJob classJob)
{
var (craftAction, action) = GetActionRow(classJob);
if (craftAction != null)
return Icons.GetIconFromId(craftAction.Icon);
else if (action != null)
return Icons.GetIconFromId(action.Icon);
// Old "Steady Hand" action icon
return Icons.GetIconFromId(1953);
}
public virtual bool CanUse => public virtual bool CanUse =>
Simulation.Stats.Level >= Level && Simulation.CP >= CPCost; Simulation.Stats.Level >= Level && Simulation.CP >= CPCost;
@@ -118,7 +59,6 @@ public abstract class BaseAction
public virtual string GetTooltip(bool addUsability) public virtual string GetTooltip(bool addUsability)
{ {
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.AppendLine(GetName(ClassJob.Carpenter));
if (addUsability && !CanUse) if (addUsability && !CanUse)
builder.AppendLine($"Cannot Use"); builder.AppendLine($"Cannot Use");
builder.AppendLine($"Level {Level}"); builder.AppendLine($"Level {Level}");
@@ -3,10 +3,8 @@ using System.Text;
namespace Craftimizer.Simulator.Actions; namespace Craftimizer.Simulator.Actions;
public abstract class BaseBuffAction : BaseAction internal abstract class BaseBuffAction : BaseAction
{ {
public BaseBuffAction(Simulation simulation) : base(simulation) { }
public abstract Effect Effect { get; } public abstract Effect Effect { get; }
public virtual EffectType[] ConflictingEffects => Array.Empty<EffectType>(); public virtual EffectType[] ConflictingEffects => Array.Empty<EffectType>();
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class BasicSynthesis : BaseAction internal class BasicSynthesis : BaseAction
{ {
public BasicSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 1; public override int Level => 1;
public override int ActionId => 100001; public override uint ActionId => 100001;
public override int CPCost => 0; public override int CPCost => 0;
// Basic Synthesis Mastery Trait // Basic Synthesis Mastery Trait
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class BasicTouch : BaseAction internal class BasicTouch : BaseAction
{ {
public BasicTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 5; public override int Level => 5;
public override int ActionId => 100002; public override uint ActionId => 100002;
public override int CPCost => 18; public override int CPCost => 18;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class ByregotsBlessing : BaseAction internal class ByregotsBlessing : BaseAction
{ {
public ByregotsBlessing(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 50; public override int Level => 50;
public override int ActionId => 100339; public override uint ActionId => 100339;
public override int CPCost => 24; public override int CPCost => 24;
public override float Efficiency => 1.00f + (0.20f * (Simulation.GetEffect(EffectType.InnerQuiet)?.Strength ?? 0)); public override float Efficiency => 1.00f + (0.20f * (Simulation.GetEffect(EffectType.InnerQuiet)?.Strength ?? 0));
@@ -2,17 +2,15 @@ namespace Craftimizer.Simulator.Actions;
internal class CarefulObservation : BaseAction internal class CarefulObservation : BaseAction
{ {
public CarefulObservation(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Other; public override ActionCategory Category => ActionCategory.Other;
public override int Level => 55; public override int Level => 55;
public override int ActionId => 100395; public override uint ActionId => 100395;
public override int CPCost => 0; 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.Stats.IsSpecialist && Simulation.CountPreviousAction<CarefulObservation>() < 3; public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.CarefulObservation) < 3;
public override void UseSuccess() => public override void UseSuccess() =>
Simulation.StepCondition(); Simulation.StepCondition();
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class CarefulSynthesis : BaseAction internal class CarefulSynthesis : BaseAction
{ {
public CarefulSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 62; public override int Level => 62;
public override int ActionId => 100203; public override uint ActionId => 100203;
public override int CPCost => 7; public override int CPCost => 7;
// Careful Synthesis Mastery Trait // Careful Synthesis Mastery Trait
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class DelicateSynthesis : BaseAction internal class DelicateSynthesis : BaseAction
{ {
public DelicateSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 76; public override int Level => 76;
public override int ActionId => 100323; public override uint ActionId => 100323;
public override int CPCost => 32; public override int CPCost => 32;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class FinalAppraisal : BaseBuffAction internal class FinalAppraisal : BaseBuffAction
{ {
public FinalAppraisal(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 42; public override int Level => 42;
public override int ActionId => 19012; public override uint ActionId => 19012;
public override int CPCost => 1; public override int CPCost => 1;
public override bool IncreasesStepCount => false; public override bool IncreasesStepCount => false;
@@ -2,14 +2,12 @@ namespace Craftimizer.Simulator.Actions;
internal class FocusedSynthesis : BaseAction internal class FocusedSynthesis : BaseAction
{ {
public FocusedSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 67; public override int Level => 67;
public override int ActionId => 100235; public override uint ActionId => 100235;
public override int CPCost => 5; public override int CPCost => 5;
public override float Efficiency => 2.00f; public override float Efficiency => 2.00f;
public override bool IncreasesProgress => true; public override bool IncreasesProgress => true;
public override float SuccessRate => Simulation.IsPreviousAction<Observe>() ? 1.00f : 0.50f; public override float SuccessRate => Simulation.IsPreviousAction(ActionType.Observe) ? 1.00f : 0.50f;
} }
@@ -2,14 +2,12 @@ namespace Craftimizer.Simulator.Actions;
internal class FocusedTouch : BaseAction internal class FocusedTouch : BaseAction
{ {
public FocusedTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 68; public override int Level => 68;
public override int ActionId => 100243; public override uint ActionId => 100243;
public override int CPCost => 18; public override int CPCost => 18;
public override float Efficiency => 1.50f; public override float Efficiency => 1.50f;
public override bool IncreasesQuality => true; public override bool IncreasesQuality => true;
public override float SuccessRate => Simulation.IsPreviousAction<Observe>() ? 1.00f : 0.50f; public override float SuccessRate => Simulation.IsPreviousAction(ActionType.Observe) ? 1.00f : 0.50f;
} }
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class GreatStrides : BaseBuffAction internal class GreatStrides : BaseBuffAction
{ {
public GreatStrides(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Buffs; public override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 21; public override int Level => 21;
public override int ActionId => 260; public override uint ActionId => 260;
public override int CPCost => 32; public override int CPCost => 32;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Groundwork : BaseAction internal class Groundwork : BaseAction
{ {
public Groundwork(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 72; public override int Level => 72;
public override int ActionId => 100403; public override uint ActionId => 100403;
public override int CPCost => 18; public override int CPCost => 18;
// Groundwork Mastery Trait // Groundwork Mastery Trait
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class HastyTouch : BaseAction internal class HastyTouch : BaseAction
{ {
public HastyTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 9; public override int Level => 9;
public override int ActionId => 100355; public override uint ActionId => 100355;
public override int CPCost => 0; public override int CPCost => 0;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,16 +2,14 @@ namespace Craftimizer.Simulator.Actions;
internal class HeartAndSoul : BaseBuffAction internal class HeartAndSoul : BaseBuffAction
{ {
public HeartAndSoul(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Other; public override ActionCategory Category => ActionCategory.Other;
public override int Level => 86; public override int Level => 86;
public override int ActionId => 100419; public override uint ActionId => 100419;
public override int CPCost => 0; public override int CPCost => 0;
public override bool IncreasesStepCount => false; public override bool IncreasesStepCount => false;
public override Effect Effect => new() { Type = EffectType.HeartAndSoul }; public override Effect Effect => new() { Type = EffectType.HeartAndSoul };
public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction<HeartAndSoul>() == 0; public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.HeartAndSoul) == 0;
} }
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Innovation : BaseBuffAction internal class Innovation : BaseBuffAction
{ {
public Innovation(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Buffs; public override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 26; public override int Level => 26;
public override int ActionId => 19004; public override uint ActionId => 19004;
public override int CPCost => 18; public override int CPCost => 18;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class IntensiveSynthesis : BaseAction internal class IntensiveSynthesis : BaseAction
{ {
public IntensiveSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 78; public override int Level => 78;
public override int ActionId => 100315; public override uint ActionId => 100315;
public override int CPCost => 6; public override int CPCost => 6;
public override float Efficiency => 4.00f; public override float Efficiency => 4.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Manipulation : BaseBuffAction internal class Manipulation : BaseBuffAction
{ {
public Manipulation(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Durability; public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 65; public override int Level => 65;
public override int ActionId => 4574; public override uint ActionId => 4574;
public override int CPCost => 96; public override int CPCost => 96;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class MastersMend : BaseAction internal class MastersMend : BaseAction
{ {
public MastersMend(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Durability; public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 7; public override int Level => 7;
public override int ActionId => 100003; public override uint ActionId => 100003;
public override int CPCost => 88; public override int CPCost => 88;
public override int DurabilityCost => 0; public override int DurabilityCost => 0;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class MuscleMemory : BaseAction internal class MuscleMemory : BaseAction
{ {
public MuscleMemory(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.FirstTurn; public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 54; public override int Level => 54;
public override int ActionId => 100379; public override uint ActionId => 100379;
public override int CPCost => 6; public override int CPCost => 6;
public override float Efficiency => 3.00f; public override float Efficiency => 3.00f;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Observe : BaseAction internal class Observe : BaseAction
{ {
public Observe(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Other; public override ActionCategory Category => ActionCategory.Other;
public override int Level => 13; public override int Level => 13;
public override int ActionId => 100010; public override uint ActionId => 100010;
public override int CPCost => 7; public override int CPCost => 7;
public override int DurabilityCost => 0; public override int DurabilityCost => 0;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class PreciseTouch : BaseAction internal class PreciseTouch : BaseAction
{ {
public PreciseTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 53; public override int Level => 53;
public override int ActionId => 100128; public override uint ActionId => 100128;
public override int CPCost => 18; public override int CPCost => 18;
public override float Efficiency => 1.50f; public override float Efficiency => 1.50f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class PreparatoryTouch : BaseAction internal class PreparatoryTouch : BaseAction
{ {
public PreparatoryTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 71; public override int Level => 71;
public override int ActionId => 100299; public override uint ActionId => 100299;
public override int CPCost => 40; public override int CPCost => 40;
public override float Efficiency => 2.00f; public override float Efficiency => 2.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class PrudentSynthesis : BaseAction internal class PrudentSynthesis : BaseAction
{ {
public PrudentSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 88; public override int Level => 88;
public override int ActionId => 100427; public override uint ActionId => 100427;
public override int CPCost => 18; public override int CPCost => 18;
public override float Efficiency => 1.80f; public override float Efficiency => 1.80f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class PrudentTouch : BaseAction internal class PrudentTouch : BaseAction
{ {
public PrudentTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 66; public override int Level => 66;
public override int ActionId => 100227; public override uint ActionId => 100227;
public override int CPCost => 25; public override int CPCost => 25;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class RapidSynthesis : BaseAction internal class RapidSynthesis : BaseAction
{ {
public RapidSynthesis(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Synthesis; public override ActionCategory Category => ActionCategory.Synthesis;
public override int Level => 9; public override int Level => 9;
public override int ActionId => 100363; public override uint ActionId => 100363;
public override int CPCost => 0; public override int CPCost => 0;
// Rapid Synthesis Mastery Trait // Rapid Synthesis Mastery Trait
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Reflect : BaseAction internal class Reflect : BaseAction
{ {
public Reflect(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.FirstTurn; public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 69; public override int Level => 69;
public override int ActionId => 100387; public override uint ActionId => 100387;
public override int CPCost => 6; public override int CPCost => 6;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,13 +2,11 @@ namespace Craftimizer.Simulator.Actions;
internal class StandardTouch : BaseAction internal class StandardTouch : BaseAction
{ {
public StandardTouch(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 18; public override int Level => 18;
public override int ActionId => 100004; public override uint ActionId => 100004;
public override int CPCost => Simulation.IsPreviousAction<BasicTouch>() ? 18 : 32; public override int CPCost => Simulation.IsPreviousAction(ActionType.BasicTouch) ? 18 : 32;
public override float Efficiency => 1.25f; public override float Efficiency => 1.25f;
public override bool IncreasesQuality => true; public override bool IncreasesQuality => true;
} }
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class TrainedEye : BaseAction internal class TrainedEye : BaseAction
{ {
public TrainedEye(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.FirstTurn; public override ActionCategory Category => ActionCategory.FirstTurn;
public override int Level => 80; public override int Level => 80;
public override int ActionId => 100283; public override uint ActionId => 100283;
public override int CPCost => 250; public override int CPCost => 250;
public override bool IncreasesQuality => true; public override bool IncreasesQuality => true;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class TrainedFinesse : BaseAction internal class TrainedFinesse : BaseAction
{ {
public TrainedFinesse(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Quality; public override ActionCategory Category => ActionCategory.Quality;
public override int Level => 90; public override int Level => 90;
public override int ActionId => 100435; public override uint ActionId => 100435;
public override int CPCost => 32; public override int CPCost => 32;
public override float Efficiency => 1.00f; public override float Efficiency => 1.00f;
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class TricksOfTheTrade : BaseAction internal class TricksOfTheTrade : BaseAction
{ {
public TricksOfTheTrade(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Other; public override ActionCategory Category => ActionCategory.Other;
public override int Level => 13; public override int Level => 13;
public override int ActionId => 100371; public override uint ActionId => 100371;
public override int CPCost => 0; public override int CPCost => 0;
public override int DurabilityCost => 0; public override int DurabilityCost => 0;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class Veneration : BaseBuffAction internal class Veneration : BaseBuffAction
{ {
public Veneration(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Buffs; public override ActionCategory Category => ActionCategory.Buffs;
public override int Level => 15; public override int Level => 15;
public override int ActionId => 19297; public override uint ActionId => 19297;
public override int CPCost => 18; public override int CPCost => 18;
public override int DurabilityCost => 0; public override int DurabilityCost => 0;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class WasteNot : BaseBuffAction internal class WasteNot : BaseBuffAction
{ {
public WasteNot(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Durability; public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 15; public override int Level => 15;
public override int ActionId => 4631; public override uint ActionId => 4631;
public override int CPCost => 56; public override int CPCost => 56;
+1 -3
View File
@@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions;
internal class WasteNot2 : BaseBuffAction internal class WasteNot2 : BaseBuffAction
{ {
public WasteNot2(Simulation simulation) : base(simulation) { }
public override ActionCategory Category => ActionCategory.Durability; public override ActionCategory Category => ActionCategory.Durability;
public override int Level => 47; public override int Level => 47;
public override int ActionId => 4639; public override uint ActionId => 4639;
public override int CPCost => 98; public override int CPCost => 98;
+1 -1
View File
@@ -15,7 +15,7 @@ public record Effect
public ushort IconId { get public ushort IconId { get
{ {
var status = Type.Status(); var status = Type.Status();
var iconId = status.Icon; uint iconId = status.Icon;
if (status.MaxStacks != 0 && Strength != null) if (status.MaxStacks != 0 && Strength != null)
iconId += (uint)Math.Clamp(Strength.Value, 1, status.MaxStacks) - 1; iconId += (uint)Math.Clamp(Strength.Value, 1, status.MaxStacks) - 1;
return (ushort)iconId; return (ushort)iconId;
+11 -13
View File
@@ -27,7 +27,7 @@ public class Simulation
public int CP { get; private set; } public int CP { get; private set; }
public Condition Condition { get; private set; } public Condition Condition { get; private set; }
public List<Effect> ActiveEffects { get; } = new(); public List<Effect> ActiveEffects { get; } = new();
public List<BaseAction> ActionHistory { get; } = new(); public List<ActionType> ActionHistory { get; } = new();
// https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2 // https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2
private static readonly int[] HQPercentTable = { private static readonly int[] HQPercentTable = {
@@ -56,21 +56,22 @@ public class Simulation
AvailableConditions = ConditionUtils.GetPossibleConditions(RecipeTable.ConditionsFlag); AvailableConditions = ConditionUtils.GetPossibleConditions(RecipeTable.ConditionsFlag);
} }
public ActionResponse Execute(BaseAction action) public ActionResponse Execute(ActionType action)
{ {
if (IsComplete) if (IsComplete)
return ActionResponse.SimulationComplete; return ActionResponse.SimulationComplete;
if (!action.CanUse) var baseAction = action.With(this);
if (!baseAction.CanUse)
{ {
if (action.Level > Stats.Level) if (baseAction.Level > Stats.Level)
return ActionResponse.ActionNotUnlocked; return ActionResponse.ActionNotUnlocked;
if (action.CPCost > CP) if (baseAction.CPCost > CP)
return ActionResponse.NotEnoughCP; return ActionResponse.NotEnoughCP;
return ActionResponse.CannotUseAction; return ActionResponse.CannotUseAction;
} }
action.Use(); baseAction.Use();
ActionHistory.Add(action); ActionHistory.Add(action);
for (var i = 0; i < ActiveEffects.Count; ++i) for (var i = 0; i < ActiveEffects.Count; ++i)
@@ -98,9 +99,6 @@ public class Simulation
return ActionResponse.UsedAction; return ActionResponse.UsedAction;
} }
public ActionResponse Execute<T>() where T : BaseAction =>
Execute((T)Activator.CreateInstance(typeof(T), this)!);
public Effect? GetEffect(EffectType effect) => public Effect? GetEffect(EffectType effect) =>
ActiveEffects.FirstOrDefault(e => e.Type == effect); ActiveEffects.FirstOrDefault(e => e.Type == effect);
@@ -143,11 +141,11 @@ public class Simulation
public bool HasEffect(EffectType effect) => public bool HasEffect(EffectType effect) =>
ActiveEffects.Any(e => e.Type == effect); ActiveEffects.Any(e => e.Type == effect);
public bool IsPreviousAction<T>(int stepsBack = 1) where T : BaseAction => public bool IsPreviousAction(ActionType action, int stepsBack = 1) =>
ActionHistory.Count >= stepsBack && ActionHistory[^stepsBack] is T; ActionHistory.Count >= stepsBack && ActionHistory[^stepsBack] == action;
public int CountPreviousAction<T>() where T : BaseAction => public int CountPreviousAction(ActionType action) =>
ActionHistory.Count(x => x is T); ActionHistory.Count(a => a == action);
public bool RollSuccessRaw(float successRate) => public bool RollSuccessRaw(float successRate) =>
successRate >= Random.NextSingle(); successRate >= Random.NextSingle();