Convert actions to singletons resolved from ActionType enum
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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<ActionType>().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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
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<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 bool IncreasesQuality => true;
|
||||
}
|
||||
|
||||
@@ -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<Simulation> 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}");
|
||||
|
||||
@@ -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<EffectType>();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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<CarefulObservation>() < 3;
|
||||
public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.CarefulObservation) < 3;
|
||||
|
||||
public override void UseSuccess() =>
|
||||
Simulation.StepCondition();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<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
|
||||
{
|
||||
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<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
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<HeartAndSoul>() == 0;
|
||||
public override bool CanUse => Simulation.Stats.IsSpecialist && Simulation.CountPreviousAction(ActionType.HeartAndSoul) == 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<BasicTouch>() ? 18 : 32;
|
||||
public override int CPCost => Simulation.IsPreviousAction(ActionType.BasicTouch) ? 18 : 32;
|
||||
public override float Efficiency => 1.25f;
|
||||
public override bool IncreasesQuality => true;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class Simulation
|
||||
public int CP { get; private set; }
|
||||
public Condition Condition { get; private set; }
|
||||
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
|
||||
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<T>() 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<T>(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<T>() 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();
|
||||
|
||||
Reference in New Issue
Block a user