diff --git a/Craftimizer/ImGuiUtils.cs b/Craftimizer/Plugin/ImGuiUtils.cs similarity index 96% rename from Craftimizer/ImGuiUtils.cs rename to Craftimizer/Plugin/ImGuiUtils.cs index c95f240..7cb176e 100644 --- a/Craftimizer/ImGuiUtils.cs +++ b/Craftimizer/Plugin/ImGuiUtils.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using System.Numerics; -namespace Craftimizer; +namespace Craftimizer.Plugin; internal class ImGuiUtils { @@ -58,7 +58,7 @@ internal class ImGuiUtils ImGui.SameLine(0, 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(); diff --git a/Craftimizer/Plugin/SimulatorWindow.cs b/Craftimizer/Plugin/SimulatorWindow.cs index a506895..8671be3 100644 --- a/Craftimizer/Plugin/SimulatorWindow.cs +++ b/Craftimizer/Plugin/SimulatorWindow.cs @@ -2,8 +2,6 @@ using Craftimizer.Simulator; using Craftimizer.Simulator.Actions; using Dalamud.Interface; using Dalamud.Interface.Windowing; -using Dalamud.Logging; -using Dalamud.Utility; using ImGuiNET; using System; using System.Linq; @@ -14,7 +12,6 @@ namespace Craftimizer.Plugin; public class SimulatorWindow : Window { public Simulation Simulation { get; } - public BaseAction[] AvailableActions { get; } 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)!); - AvailableActions = BaseAction.Actions.Select(a => (Activator.CreateInstance(a, Simulation)! as BaseAction)!).ToArray(); } public override void Draw() @@ -38,20 +34,21 @@ public class SimulatorWindow : Window ImGui.BeginChild("CraftimizerActions", Vector2.Zero, true, ImGuiWindowFlags.NoDecoration); ImGui.Checkbox("Show only guaranteed actions", ref showOnlyGuaranteedActions); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); - foreach(var category in AvailableActions.GroupBy(a => a.Category)) + foreach(var category in Enum.GetValues().GroupBy(a => a.Category())) { var i = 0; 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; - ImGui.BeginDisabled(!action.CanUse); + ImGui.BeginDisabled(!baseAction.CanUse); if (ImGui.ImageButton(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2))) Simulation.Execute(action); if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) - ImGui.SetTooltip(action.GetTooltip(true)); + ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(true)}"); ImGui.EndDisabled(); if (++i % 5 != 0) ImGui.SameLine(); @@ -95,9 +92,10 @@ public class SimulatorWindow : Window var i = 0; foreach (var action in Simulation.ActionHistory) { + var baseAction = action.With(Simulation); ImGui.Image(action.GetIcon(ClassJob.Carpenter).ImGuiHandle, new Vector2(ImGui.GetFontSize() * 2f)); if (ImGui.IsItemHovered()) - ImGui.SetTooltip(action.GetTooltip(false)); + ImGui.SetTooltip($"{action.GetName(ClassJob.Carpenter)}\n{baseAction.GetTooltip(false)}"); if (++i % 5 != 0) ImGui.SameLine(); } diff --git a/Craftimizer/Simulator/Actions/ActionType.cs b/Craftimizer/Simulator/Actions/ActionType.cs new file mode 100644 index 0000000..1af9492 --- /dev/null +++ b/Craftimizer/Simulator/Actions/ActionType.cs @@ -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() + .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); + } +} diff --git a/Craftimizer/Simulator/Actions/AdvancedTouch.cs b/Craftimizer/Simulator/Actions/AdvancedTouch.cs index e5dcf18..3dad79a 100644 --- a/Craftimizer/Simulator/Actions/AdvancedTouch.cs +++ b/Craftimizer/Simulator/Actions/AdvancedTouch.cs @@ -2,13 +2,11 @@ namespace Craftimizer.Simulator.Actions; internal class AdvancedTouch : BaseAction { - public AdvancedTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 84; - public override int ActionId => 100411; + public override uint ActionId => 100411; - public override int CPCost => Simulation.IsPreviousAction() && Simulation.IsPreviousAction(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 bool IncreasesQuality => true; } diff --git a/Craftimizer/Simulator/Actions/BaseAction.cs b/Craftimizer/Simulator/Actions/BaseAction.cs index b4086cf..9c73a78 100644 --- a/Craftimizer/Simulator/Actions/BaseAction.cs +++ b/Craftimizer/Simulator/Actions/BaseAction.cs @@ -1,31 +1,23 @@ -using Craftimizer.Plugin; -using Dalamud.Utility; -using ImGuiScene; -using Lumina.Excel.GeneratedSheets; using System; -using System.Linq; using System.Text; -using Action = Lumina.Excel.GeneratedSheets.Action; +using System.Threading; namespace Craftimizer.Simulator.Actions; -public abstract class BaseAction +internal abstract class BaseAction { - public static readonly Type[] Actions = typeof(BaseAction).Assembly.GetTypes() - .Where(type => type.IsAssignableTo(typeof(BaseAction)) && !type.IsAbstract).ToArray(); + internal static readonly ThreadLocal TLSSimulation = new(false); + protected static Simulation Simulation => TLSSimulation.Value ?? throw new NullReferenceException(); - protected Simulation Simulation { get; } - - public BaseAction(Simulation simulation) - { - Simulation = simulation; - } + public BaseAction() { } + // Non-instanced properties public abstract ActionCategory Category { get; } public abstract int Level { get; } // 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 virtual float Efficiency => 0f; public virtual bool IncreasesProgress => false; @@ -35,57 +27,6 @@ public abstract class BaseAction public virtual bool IncreasesStepCount => true; 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 => Simulation.Stats.Level >= Level && Simulation.CP >= CPCost; @@ -118,7 +59,6 @@ public abstract class BaseAction public virtual string GetTooltip(bool addUsability) { var builder = new StringBuilder(); - builder.AppendLine(GetName(ClassJob.Carpenter)); if (addUsability && !CanUse) builder.AppendLine($"Cannot Use"); builder.AppendLine($"Level {Level}"); diff --git a/Craftimizer/Simulator/Actions/BaseBuffAction.cs b/Craftimizer/Simulator/Actions/BaseBuffAction.cs index d295249..eccfa7c 100644 --- a/Craftimizer/Simulator/Actions/BaseBuffAction.cs +++ b/Craftimizer/Simulator/Actions/BaseBuffAction.cs @@ -3,10 +3,8 @@ using System.Text; 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 virtual EffectType[] ConflictingEffects => Array.Empty(); diff --git a/Craftimizer/Simulator/Actions/BasicSynthesis.cs b/Craftimizer/Simulator/Actions/BasicSynthesis.cs index 9de266e..e06485c 100644 --- a/Craftimizer/Simulator/Actions/BasicSynthesis.cs +++ b/Craftimizer/Simulator/Actions/BasicSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class BasicSynthesis : BaseAction { - public BasicSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 1; - public override int ActionId => 100001; + public override uint ActionId => 100001; public override int CPCost => 0; // Basic Synthesis Mastery Trait diff --git a/Craftimizer/Simulator/Actions/BasicTouch.cs b/Craftimizer/Simulator/Actions/BasicTouch.cs index 3fd7951..c37c2fb 100644 --- a/Craftimizer/Simulator/Actions/BasicTouch.cs +++ b/Craftimizer/Simulator/Actions/BasicTouch.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class BasicTouch : BaseAction { - public BasicTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 5; - public override int ActionId => 100002; + public override uint ActionId => 100002; public override int CPCost => 18; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/ByregotsBlessing.cs b/Craftimizer/Simulator/Actions/ByregotsBlessing.cs index 610e7d1..d82cc25 100644 --- a/Craftimizer/Simulator/Actions/ByregotsBlessing.cs +++ b/Craftimizer/Simulator/Actions/ByregotsBlessing.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class ByregotsBlessing : BaseAction { - public ByregotsBlessing(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 50; - public override int ActionId => 100339; + public override uint ActionId => 100339; public override int CPCost => 24; public override float Efficiency => 1.00f + (0.20f * (Simulation.GetEffect(EffectType.InnerQuiet)?.Strength ?? 0)); diff --git a/Craftimizer/Simulator/Actions/CarefulObservation.cs b/Craftimizer/Simulator/Actions/CarefulObservation.cs index fcd6528..536d2ad 100644 --- a/Craftimizer/Simulator/Actions/CarefulObservation.cs +++ b/Craftimizer/Simulator/Actions/CarefulObservation.cs @@ -2,17 +2,15 @@ namespace Craftimizer.Simulator.Actions; internal class CarefulObservation : BaseAction { - public CarefulObservation(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Other; public override int Level => 55; - public override int ActionId => 100395; + public override uint ActionId => 100395; public override int CPCost => 0; public override int DurabilityCost => 0; public override bool IncreasesStepCount => false; - public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction() < 3; + public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.CarefulObservation) < 3; public override void UseSuccess() => Simulation.StepCondition(); diff --git a/Craftimizer/Simulator/Actions/CarefulSynthesis.cs b/Craftimizer/Simulator/Actions/CarefulSynthesis.cs index 8320d2c..3e4873c 100644 --- a/Craftimizer/Simulator/Actions/CarefulSynthesis.cs +++ b/Craftimizer/Simulator/Actions/CarefulSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class CarefulSynthesis : BaseAction { - public CarefulSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 62; - public override int ActionId => 100203; + public override uint ActionId => 100203; public override int CPCost => 7; // Careful Synthesis Mastery Trait diff --git a/Craftimizer/Simulator/Actions/DelicateSynthesis.cs b/Craftimizer/Simulator/Actions/DelicateSynthesis.cs index c8b6ba1..724b86d 100644 --- a/Craftimizer/Simulator/Actions/DelicateSynthesis.cs +++ b/Craftimizer/Simulator/Actions/DelicateSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class DelicateSynthesis : BaseAction { - public DelicateSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 76; - public override int ActionId => 100323; + public override uint ActionId => 100323; public override int CPCost => 32; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/FinalAppraisal.cs b/Craftimizer/Simulator/Actions/FinalAppraisal.cs index 4b87d9b..3314357 100644 --- a/Craftimizer/Simulator/Actions/FinalAppraisal.cs +++ b/Craftimizer/Simulator/Actions/FinalAppraisal.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class FinalAppraisal : BaseBuffAction { - public FinalAppraisal(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 42; - public override int ActionId => 19012; + public override uint ActionId => 19012; public override int CPCost => 1; public override bool IncreasesStepCount => false; diff --git a/Craftimizer/Simulator/Actions/FocusedSynthesis.cs b/Craftimizer/Simulator/Actions/FocusedSynthesis.cs index fd98eed..6c8d95b 100644 --- a/Craftimizer/Simulator/Actions/FocusedSynthesis.cs +++ b/Craftimizer/Simulator/Actions/FocusedSynthesis.cs @@ -2,14 +2,12 @@ namespace Craftimizer.Simulator.Actions; internal class FocusedSynthesis : BaseAction { - public FocusedSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 67; - public override int 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 float SuccessRate => Simulation.IsPreviousAction() ? 1.00f : 0.50f; + public override float SuccessRate => Simulation.IsPreviousAction(ActionType.Observe) ? 1.00f : 0.50f; } diff --git a/Craftimizer/Simulator/Actions/FocusedTouch.cs b/Craftimizer/Simulator/Actions/FocusedTouch.cs index 222855c..dc83848 100644 --- a/Craftimizer/Simulator/Actions/FocusedTouch.cs +++ b/Craftimizer/Simulator/Actions/FocusedTouch.cs @@ -2,14 +2,12 @@ namespace Craftimizer.Simulator.Actions; internal class FocusedTouch : BaseAction { - public FocusedTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 68; - public override int 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 float SuccessRate => Simulation.IsPreviousAction() ? 1.00f : 0.50f; + public override float SuccessRate => Simulation.IsPreviousAction(ActionType.Observe) ? 1.00f : 0.50f; } diff --git a/Craftimizer/Simulator/Actions/GreatStrides.cs b/Craftimizer/Simulator/Actions/GreatStrides.cs index a9112b0..f2eb7f5 100644 --- a/Craftimizer/Simulator/Actions/GreatStrides.cs +++ b/Craftimizer/Simulator/Actions/GreatStrides.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class GreatStrides : BaseBuffAction { - public GreatStrides(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Buffs; public override int Level => 21; - public override int ActionId => 260; + public override uint ActionId => 260; public override int CPCost => 32; diff --git a/Craftimizer/Simulator/Actions/Groundwork.cs b/Craftimizer/Simulator/Actions/Groundwork.cs index b961605..69ca89a 100644 --- a/Craftimizer/Simulator/Actions/Groundwork.cs +++ b/Craftimizer/Simulator/Actions/Groundwork.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Groundwork : BaseAction { - public Groundwork(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 72; - public override int ActionId => 100403; + public override uint ActionId => 100403; public override int CPCost => 18; // Groundwork Mastery Trait diff --git a/Craftimizer/Simulator/Actions/HastyTouch.cs b/Craftimizer/Simulator/Actions/HastyTouch.cs index 2a920ba..745e0ee 100644 --- a/Craftimizer/Simulator/Actions/HastyTouch.cs +++ b/Craftimizer/Simulator/Actions/HastyTouch.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class HastyTouch : BaseAction { - public HastyTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 9; - public override int ActionId => 100355; + public override uint ActionId => 100355; public override int CPCost => 0; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/HeartAndSoul.cs b/Craftimizer/Simulator/Actions/HeartAndSoul.cs index e64fe65..d61ed57 100644 --- a/Craftimizer/Simulator/Actions/HeartAndSoul.cs +++ b/Craftimizer/Simulator/Actions/HeartAndSoul.cs @@ -2,16 +2,14 @@ namespace Craftimizer.Simulator.Actions; internal class HeartAndSoul : BaseBuffAction { - public HeartAndSoul(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Other; public override int Level => 86; - public override int ActionId => 100419; + public override uint ActionId => 100419; public override int CPCost => 0; public override bool IncreasesStepCount => false; public override Effect Effect => new() { Type = EffectType.HeartAndSoul }; - public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction() == 0; + public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.HeartAndSoul) == 0; } diff --git a/Craftimizer/Simulator/Actions/Innovation.cs b/Craftimizer/Simulator/Actions/Innovation.cs index 4dff593..5db1695 100644 --- a/Craftimizer/Simulator/Actions/Innovation.cs +++ b/Craftimizer/Simulator/Actions/Innovation.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Innovation : BaseBuffAction { - public Innovation(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Buffs; public override int Level => 26; - public override int ActionId => 19004; + public override uint ActionId => 19004; public override int CPCost => 18; diff --git a/Craftimizer/Simulator/Actions/IntensiveSynthesis.cs b/Craftimizer/Simulator/Actions/IntensiveSynthesis.cs index 9ad6ec2..270ed37 100644 --- a/Craftimizer/Simulator/Actions/IntensiveSynthesis.cs +++ b/Craftimizer/Simulator/Actions/IntensiveSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class IntensiveSynthesis : BaseAction { - public IntensiveSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 78; - public override int ActionId => 100315; + public override uint ActionId => 100315; public override int CPCost => 6; public override float Efficiency => 4.00f; diff --git a/Craftimizer/Simulator/Actions/Manipulation.cs b/Craftimizer/Simulator/Actions/Manipulation.cs index 82b2cfb..86b7ef6 100644 --- a/Craftimizer/Simulator/Actions/Manipulation.cs +++ b/Craftimizer/Simulator/Actions/Manipulation.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Manipulation : BaseBuffAction { - public Manipulation(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Durability; public override int Level => 65; - public override int ActionId => 4574; + public override uint ActionId => 4574; public override int CPCost => 96; diff --git a/Craftimizer/Simulator/Actions/MastersMend.cs b/Craftimizer/Simulator/Actions/MastersMend.cs index 7ce47c1..e54443e 100644 --- a/Craftimizer/Simulator/Actions/MastersMend.cs +++ b/Craftimizer/Simulator/Actions/MastersMend.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class MastersMend : BaseAction { - public MastersMend(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Durability; public override int Level => 7; - public override int ActionId => 100003; + public override uint ActionId => 100003; public override int CPCost => 88; public override int DurabilityCost => 0; diff --git a/Craftimizer/Simulator/Actions/MuscleMemory.cs b/Craftimizer/Simulator/Actions/MuscleMemory.cs index 30dac5e..0b71c16 100644 --- a/Craftimizer/Simulator/Actions/MuscleMemory.cs +++ b/Craftimizer/Simulator/Actions/MuscleMemory.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class MuscleMemory : BaseAction { - public MuscleMemory(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.FirstTurn; public override int Level => 54; - public override int ActionId => 100379; + public override uint ActionId => 100379; public override int CPCost => 6; public override float Efficiency => 3.00f; diff --git a/Craftimizer/Simulator/Actions/Observe.cs b/Craftimizer/Simulator/Actions/Observe.cs index a75d391..7068826 100644 --- a/Craftimizer/Simulator/Actions/Observe.cs +++ b/Craftimizer/Simulator/Actions/Observe.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Observe : BaseAction { - public Observe(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Other; public override int Level => 13; - public override int ActionId => 100010; + public override uint ActionId => 100010; public override int CPCost => 7; public override int DurabilityCost => 0; diff --git a/Craftimizer/Simulator/Actions/PreciseTouch.cs b/Craftimizer/Simulator/Actions/PreciseTouch.cs index c1ea445..d076971 100644 --- a/Craftimizer/Simulator/Actions/PreciseTouch.cs +++ b/Craftimizer/Simulator/Actions/PreciseTouch.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class PreciseTouch : BaseAction { - public PreciseTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 53; - public override int ActionId => 100128; + public override uint ActionId => 100128; public override int CPCost => 18; public override float Efficiency => 1.50f; diff --git a/Craftimizer/Simulator/Actions/PreparatoryTouch.cs b/Craftimizer/Simulator/Actions/PreparatoryTouch.cs index 14e0701..d246ed3 100644 --- a/Craftimizer/Simulator/Actions/PreparatoryTouch.cs +++ b/Craftimizer/Simulator/Actions/PreparatoryTouch.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class PreparatoryTouch : BaseAction { - public PreparatoryTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 71; - public override int ActionId => 100299; + public override uint ActionId => 100299; public override int CPCost => 40; public override float Efficiency => 2.00f; diff --git a/Craftimizer/Simulator/Actions/PrudentSynthesis.cs b/Craftimizer/Simulator/Actions/PrudentSynthesis.cs index d2564a7..5c20439 100644 --- a/Craftimizer/Simulator/Actions/PrudentSynthesis.cs +++ b/Craftimizer/Simulator/Actions/PrudentSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class PrudentSynthesis : BaseAction { - public PrudentSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 88; - public override int ActionId => 100427; + public override uint ActionId => 100427; public override int CPCost => 18; public override float Efficiency => 1.80f; diff --git a/Craftimizer/Simulator/Actions/PrudentTouch.cs b/Craftimizer/Simulator/Actions/PrudentTouch.cs index 04f0e05..7bd06dc 100644 --- a/Craftimizer/Simulator/Actions/PrudentTouch.cs +++ b/Craftimizer/Simulator/Actions/PrudentTouch.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class PrudentTouch : BaseAction { - public PrudentTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 66; - public override int ActionId => 100227; + public override uint ActionId => 100227; public override int CPCost => 25; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/RapidSynthesis.cs b/Craftimizer/Simulator/Actions/RapidSynthesis.cs index 0200858..26f4b3b 100644 --- a/Craftimizer/Simulator/Actions/RapidSynthesis.cs +++ b/Craftimizer/Simulator/Actions/RapidSynthesis.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class RapidSynthesis : BaseAction { - public RapidSynthesis(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Synthesis; public override int Level => 9; - public override int ActionId => 100363; + public override uint ActionId => 100363; public override int CPCost => 0; // Rapid Synthesis Mastery Trait diff --git a/Craftimizer/Simulator/Actions/Reflect.cs b/Craftimizer/Simulator/Actions/Reflect.cs index 13396d7..c09d75d 100644 --- a/Craftimizer/Simulator/Actions/Reflect.cs +++ b/Craftimizer/Simulator/Actions/Reflect.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Reflect : BaseAction { - public Reflect(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.FirstTurn; public override int Level => 69; - public override int ActionId => 100387; + public override uint ActionId => 100387; public override int CPCost => 6; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/StandardTouch.cs b/Craftimizer/Simulator/Actions/StandardTouch.cs index 1dffa65..f3525ce 100644 --- a/Craftimizer/Simulator/Actions/StandardTouch.cs +++ b/Craftimizer/Simulator/Actions/StandardTouch.cs @@ -2,13 +2,11 @@ namespace Craftimizer.Simulator.Actions; internal class StandardTouch : BaseAction { - public StandardTouch(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 18; - public override int ActionId => 100004; + public override uint ActionId => 100004; - public override int CPCost => Simulation.IsPreviousAction() ? 18 : 32; + public override int CPCost => Simulation.IsPreviousAction(ActionType.BasicTouch) ? 18 : 32; public override float Efficiency => 1.25f; public override bool IncreasesQuality => true; } diff --git a/Craftimizer/Simulator/Actions/TrainedEye.cs b/Craftimizer/Simulator/Actions/TrainedEye.cs index 8e2207e..47e7ca0 100644 --- a/Craftimizer/Simulator/Actions/TrainedEye.cs +++ b/Craftimizer/Simulator/Actions/TrainedEye.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class TrainedEye : BaseAction { - public TrainedEye(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.FirstTurn; public override int Level => 80; - public override int ActionId => 100283; + public override uint ActionId => 100283; public override int CPCost => 250; public override bool IncreasesQuality => true; diff --git a/Craftimizer/Simulator/Actions/TrainedFinesse.cs b/Craftimizer/Simulator/Actions/TrainedFinesse.cs index 5553d88..0535504 100644 --- a/Craftimizer/Simulator/Actions/TrainedFinesse.cs +++ b/Craftimizer/Simulator/Actions/TrainedFinesse.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class TrainedFinesse : BaseAction { - public TrainedFinesse(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Quality; public override int Level => 90; - public override int ActionId => 100435; + public override uint ActionId => 100435; public override int CPCost => 32; public override float Efficiency => 1.00f; diff --git a/Craftimizer/Simulator/Actions/TricksOfTheTrade.cs b/Craftimizer/Simulator/Actions/TricksOfTheTrade.cs index 36e81de..80b2dcc 100644 --- a/Craftimizer/Simulator/Actions/TricksOfTheTrade.cs +++ b/Craftimizer/Simulator/Actions/TricksOfTheTrade.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class TricksOfTheTrade : BaseAction { - public TricksOfTheTrade(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Other; public override int Level => 13; - public override int ActionId => 100371; + public override uint ActionId => 100371; public override int CPCost => 0; public override int DurabilityCost => 0; diff --git a/Craftimizer/Simulator/Actions/Veneration.cs b/Craftimizer/Simulator/Actions/Veneration.cs index 83ca912..ab0a45f 100644 --- a/Craftimizer/Simulator/Actions/Veneration.cs +++ b/Craftimizer/Simulator/Actions/Veneration.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class Veneration : BaseBuffAction { - public Veneration(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Buffs; public override int Level => 15; - public override int ActionId => 19297; + public override uint ActionId => 19297; public override int CPCost => 18; public override int DurabilityCost => 0; diff --git a/Craftimizer/Simulator/Actions/WasteNot.cs b/Craftimizer/Simulator/Actions/WasteNot.cs index 498c3a5..50f8211 100644 --- a/Craftimizer/Simulator/Actions/WasteNot.cs +++ b/Craftimizer/Simulator/Actions/WasteNot.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class WasteNot : BaseBuffAction { - public WasteNot(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Durability; public override int Level => 15; - public override int ActionId => 4631; + public override uint ActionId => 4631; public override int CPCost => 56; diff --git a/Craftimizer/Simulator/Actions/WasteNot2.cs b/Craftimizer/Simulator/Actions/WasteNot2.cs index 51f2a89..0296292 100644 --- a/Craftimizer/Simulator/Actions/WasteNot2.cs +++ b/Craftimizer/Simulator/Actions/WasteNot2.cs @@ -2,11 +2,9 @@ namespace Craftimizer.Simulator.Actions; internal class WasteNot2 : BaseBuffAction { - public WasteNot2(Simulation simulation) : base(simulation) { } - public override ActionCategory Category => ActionCategory.Durability; public override int Level => 47; - public override int ActionId => 4639; + public override uint ActionId => 4639; public override int CPCost => 98; diff --git a/Craftimizer/Simulator/Effect.cs b/Craftimizer/Simulator/Effect.cs index 0915428..7ff5a62 100644 --- a/Craftimizer/Simulator/Effect.cs +++ b/Craftimizer/Simulator/Effect.cs @@ -15,7 +15,7 @@ public record Effect public ushort IconId { get { var status = Type.Status(); - var iconId = status.Icon; + uint iconId = status.Icon; if (status.MaxStacks != 0 && Strength != null) iconId += (uint)Math.Clamp(Strength.Value, 1, status.MaxStacks) - 1; return (ushort)iconId; diff --git a/Craftimizer/Simulator/Simulation.cs b/Craftimizer/Simulator/Simulation.cs index b0887c8..d4d5475 100644 --- a/Craftimizer/Simulator/Simulation.cs +++ b/Craftimizer/Simulator/Simulation.cs @@ -27,7 +27,7 @@ public class Simulation public int CP { get; private set; } public Condition Condition { get; private set; } public List ActiveEffects { get; } = new(); - public List ActionHistory { get; } = new(); + public List ActionHistory { get; } = new(); // https://github.com/ffxiv-teamcraft/simulator/blob/0682dfa76043ff4ccb38832c184d046ceaff0733/src/model/tables.ts#L2 private static readonly int[] HQPercentTable = { @@ -56,21 +56,22 @@ public class Simulation AvailableConditions = ConditionUtils.GetPossibleConditions(RecipeTable.ConditionsFlag); } - public ActionResponse Execute(BaseAction action) + public ActionResponse Execute(ActionType action) { if (IsComplete) 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; - if (action.CPCost > CP) + if (baseAction.CPCost > CP) return ActionResponse.NotEnoughCP; return ActionResponse.CannotUseAction; } - action.Use(); + baseAction.Use(); ActionHistory.Add(action); for (var i = 0; i < ActiveEffects.Count; ++i) @@ -98,9 +99,6 @@ public class Simulation return ActionResponse.UsedAction; } - public ActionResponse Execute() where T : BaseAction => - Execute((T)Activator.CreateInstance(typeof(T), this)!); - public Effect? GetEffect(EffectType effect) => ActiveEffects.FirstOrDefault(e => e.Type == effect); @@ -143,11 +141,11 @@ public class Simulation public bool HasEffect(EffectType effect) => ActiveEffects.Any(e => e.Type == effect); - public bool IsPreviousAction(int stepsBack = 1) where T : BaseAction => - ActionHistory.Count >= stepsBack && ActionHistory[^stepsBack] is T; + public bool IsPreviousAction(ActionType action, int stepsBack = 1) => + ActionHistory.Count >= stepsBack && ActionHistory[^stepsBack] == action; - public int CountPreviousAction() where T : BaseAction => - ActionHistory.Count(x => x is T); + public int CountPreviousAction(ActionType action) => + ActionHistory.Count(a => a == action); public bool RollSuccessRaw(float successRate) => successRate >= Random.NextSingle();