Refactor ui code, add temp synth window

This commit is contained in:
Asriel Camora
2023-07-17 00:13:59 +04:00
parent 858d5d468c
commit c8231b5d2a
11 changed files with 288 additions and 132 deletions
+5 -5
View File
@@ -1,7 +1,5 @@
using Craftimizer.Plugin.Windows;
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
using Dalamud.IoC;
using Dalamud.Plugin;
@@ -15,9 +13,10 @@ public sealed class Plugin : IDalamudPlugin
public string Name => "Craftimizer";
public WindowSystem WindowSystem { get; }
public SettingsWindow SettingsWindow { get; }
public Settings SettingsWindow { get; }
public CraftingLog RecipeNoteWindow { get; }
public SimulatorWindow? SimulatorWindow { get; set; }
public Craft SynthesisWindow { get; }
public Windows.Simulator? SimulatorWindow { get; set; }
public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface)
{
@@ -27,8 +26,9 @@ public sealed class Plugin : IDalamudPlugin
WindowSystem = new(Name);
RecipeNoteWindow = new();
SettingsWindow = new();
RecipeNoteWindow = new();
SynthesisWindow = new();
Service.PluginInterface.UiBuilder.Draw += WindowSystem.Draw;
Service.PluginInterface.UiBuilder.OpenConfigUi += OpenSettingsWindow;
+20 -7
View File
@@ -1,6 +1,7 @@
using Craftimizer.Simulator;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using Lumina.Excel.GeneratedSheets;
using System;
@@ -83,21 +84,33 @@ internal static unsafe class Gearsets
public static GearsetStats CalculateGearsetStats(GearsetItem[] gearsetItems) =>
gearsetItems.Select(CalculateGearsetItemStats).Aggregate(BaseStats, (a, b) => new(a.CP + b.CP, a.Craftsmanship + b.Craftsmanship, a.Control + b.Control));
public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation)
public static GearsetStats CalculateGearsetCurrentStats()
{
var stats = CalculateGearsetStats(gearsetItems);
return new CharacterStats
var attributes = UIState.Instance()->PlayerState.Attributes;
return new()
{
CP = stats.CP,
Craftsmanship = stats.Craftsmanship,
Control = stats.Control,
CP = attributes[ParamCP],
Craftsmanship = attributes[ParamCraftsmanship],
Control = attributes[ParamControl],
};
}
public static CharacterStats CalculateCharacterStats(GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
CalculateCharacterStats(CalculateGearsetStats(gearsetItems), gearsetItems, characterLevel, canUseManipulation);
public static CharacterStats CalculateCharacterStats(GearsetStats gearsetStats, GearsetItem[] gearsetItems, int characterLevel, bool canUseManipulation) =>
new()
{
CP = gearsetStats.CP,
Craftsmanship = gearsetStats.Craftsmanship,
Control = gearsetStats.Control,
Level = characterLevel,
CanUseManipulation = canUseManipulation,
HasSplendorousBuff = gearsetItems.Any(IsSplendorousTool),
IsSpecialist = gearsetItems.Any(IsSpecialistSoulCrystal),
CLvl = CalculateCLvl(characterLevel),
};
}
public static bool IsItem(GearsetItem item, uint itemId) =>
item.itemId == itemId;
+112
View File
@@ -0,0 +1,112 @@
using Craftimizer.Plugin;
using Craftimizer.Simulator;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.UI;
using Lumina.Excel.GeneratedSheets;
using System.Linq;
using System;
using ClassJob = Craftimizer.Simulator.ClassJob;
using CSRecipeNote = FFXIVClientStructs.FFXIV.Client.Game.UI.RecipeNote;
using ActionType = Craftimizer.Simulator.Actions.ActionType;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
namespace Craftimizer.Utils;
public unsafe class RecipeNote
{
public AddonRecipeNote* AddonRecipe { get; private set; }
public AddonSynthesis* AddonSynthesis { get; private set; }
public CSRecipeNote* State { get; private set; }
public ushort RecipeId { get; private set; }
public Recipe Recipe { get; private set; } = null!;
public RecipeLevelTable Table { get; private set; } = null!;
public RecipeInfo Info { get; private set; } = null!;
public ClassJob ClassJob { get; private set; }
public short CharacterLevel { get; private set; }
public bool CanUseManipulation { get; private set; }
public int HQIngredientCount { get; private set; }
public int MaxStartingQuality { get; private set; }
public RecipeNote()
{
}
public bool Update(out bool isNewRecipe)
{
isNewRecipe = false;
if (Service.ClientState.LocalPlayer == null)
return false;
AddonRecipe = (AddonRecipeNote*)Service.GameGui.GetAddonByName("RecipeNote");
AddonSynthesis = (AddonSynthesis*)Service.GameGui.GetAddonByName("Synthesis");
if (AddonRecipe == null)
return false;
if (AddonSynthesis == null)
return false;
State = CSRecipeNote.Instance();
var list = State->RecipeList;
if (list == null)
return false;
var recipeEntry = list->SelectedRecipe;
if (recipeEntry == null)
return false;
isNewRecipe = RecipeId != recipeEntry->RecipeId;
RecipeId = recipeEntry->RecipeId;
var recipe = LuminaSheets.RecipeSheet.GetRow(RecipeId);
if (recipe == null)
return false;
Recipe = recipe;
if (isNewRecipe)
CalculateStats();
return true;
}
private void CalculateStats()
{
Table = Recipe.RecipeLevelTable.Value!;
Info = CreateInfo();
ClassJob = (ClassJob)Recipe.CraftType.Row;
CharacterLevel = PlayerState.Instance()->ClassJobLevelArray[ClassJob.GetClassJobIndex()];
CanUseManipulation = ActionManager.CanUseActionOnTarget(ActionType.Manipulation.GetId(ClassJob), (GameObject*)Service.ClientState.LocalPlayer!.Address);
HQIngredientCount = Recipe.UnkData5
.Where(i =>
i != null &&
i.ItemIngredient != 0 &&
(LuminaSheets.ItemSheet.GetRow((uint)i.ItemIngredient)?.CanBeHq ?? false)
).Sum(i => i.AmountIngredient);
MaxStartingQuality = (int)Math.Floor(Recipe.MaterialQualityFactor * Info.MaxQuality / 100f);
}
private RecipeInfo CreateInfo() =>
new()
{
IsExpert = Recipe.IsExpert,
ClassJobLevel = Table.ClassJobLevel,
RLvl = (int)Table.RowId,
ConditionsFlag = Table.ConditionsFlag,
MaxDurability = Table.Durability * Recipe.DurabilityFactor / 100,
MaxQuality = (int)Table.Quality * Recipe.QualityFactor / 100,
MaxProgress = Table.Difficulty * Recipe.DifficultyFactor / 100,
QualityModifier = Table.QualityModifier,
QualityDivider = Table.QualityDivider,
ProgressModifier = Table.ProgressModifier,
ProgressDivider = Table.ProgressDivider,
};
}
+87
View File
@@ -0,0 +1,87 @@
using Craftimizer.Plugin.Utils;
using Craftimizer.Simulator;
using Craftimizer.Utils;
using Dalamud.Interface.Windowing;
using FFXIVClientStructs.FFXIV.Client.Game;
using ImGuiNET;
using System.Numerics;
namespace Craftimizer.Plugin.Windows;
public unsafe class Craft : Window
{
private const ImGuiWindowFlags WindowFlags = ImGuiWindowFlags.NoDecoration
| ImGuiWindowFlags.AlwaysAutoResize
| ImGuiWindowFlags.NoSavedSettings
| ImGuiWindowFlags.NoFocusOnAppearing
| ImGuiWindowFlags.NoNavFocus;
private RecipeNote RecipeUtils { get; } = new();
private bool WasOpen { get; set; }
private CharacterStats CharacterStats { get; set; } = null!;
public Craft() : base("Craftimizer SynthesisHelper", WindowFlags, true)
{
Service.WindowSystem.AddWindow(this);
IsOpen = true;
}
public override void Draw()
{
ImGui.Text($"{CharacterStats.CP};{CharacterStats.Control};{CharacterStats.Craftsmanship}");
}
public override void PreDraw()
{
var addon = RecipeUtils.AddonSynthesis;
ref var unit = ref addon->AtkUnitBase;
var scale = unit.Scale;
var pos = new Vector2(unit.X, unit.Y);
var size = new Vector2(unit.WindowNode->AtkResNode.Width, unit.WindowNode->AtkResNode.Height) * scale;
var node = unit.GetNodeById(5);
Position = pos + new Vector2(size.X, node->Y * scale);
SizeConstraints = new WindowSizeConstraints
{
MinimumSize = new(-1),
MaximumSize = new(10000, 10000)
};
base.PreDraw();
}
private bool DrawConditionsInner()
{
if (!RecipeUtils.Update(out _))
return false;
// Check if Synthesis addon is visible
if (RecipeUtils.AddonSynthesis->AtkUnitBase.WindowNode == null)
return false;
return base.DrawConditions();
}
public override bool DrawConditions()
{
var ret = DrawConditionsInner();
if (ret && !WasOpen)
ResetSimulation();
WasOpen = ret;
return ret;
}
private void ResetSimulation()
{
var container = InventoryManager.Instance()->GetInventoryContainer(InventoryType.EquippedItems);
if (container == null)
return;
CharacterStats = Gearsets.CalculateCharacterStats(Gearsets.CalculateGearsetCurrentStats(), Gearsets.GetGearsetItems(container), RecipeUtils.CharacterLevel, RecipeUtils.CanUseManipulation);
}
}
+45 -101
View File
@@ -7,22 +7,18 @@ using Dalamud.Interface.Components;
using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using ActionType = Craftimizer.Simulator.Actions.ActionType;
using ClassJob = Craftimizer.Simulator.ClassJob;
using RecipeNote = Craftimizer.Utils.RecipeNote;
namespace Craftimizer.Plugin.Windows;
@@ -46,20 +42,7 @@ public unsafe class CraftingLog : Window
private static Food[] MedicineItems { get; }
private static Random Random { get; }
// Set in DrawConditions
private AddonRecipeNote* Addon { get; set; }
private RecipeNote* State { get; set; }
private ushort RecipeId { get; set; }
private Recipe Recipe { get; set; } = null!;
// Set in CalculateRecipeStats (in DrawConditions)
private RecipeLevelTable RecipeTable { get; set; } = null!;
private RecipeInfo RecipeInfo { get; set; } = null!;
private ClassJob RecipeClassJob { get; set; }
private short RecipeCharacterLevel { get; set; }
private bool RecipeCanUseManipulation { get; set; }
private int RecipeHQIngredientCount { get; set; }
private int RecipeMaxStartingQuality { get; set; }
private RecipeNote RecipeUtils { get; } = new();
// Set in CalculateCharacterStats (in PreDraw)
private Gearsets.GearsetItem[] CharacterEquipment { get; set; } = null!;
@@ -71,7 +54,10 @@ public unsafe class CraftingLog : Window
// Set in UI
private int QualityNotches { get; set; }
private int StartingQuality => RecipeHQIngredientCount == 0 ? 0 : (int)((float)QualityNotches * RecipeMaxStartingQuality / RecipeHQIngredientCount);
private int StartingQuality =>
RecipeUtils.HQIngredientCount == 0 ?
0 :
(int)((float)QualityNotches * RecipeUtils.MaxStartingQuality / RecipeUtils.HQIngredientCount);
private Food? SelectedFood { get; set; }
private bool SelectedFoodHQ { get; set; }
@@ -139,22 +125,6 @@ public unsafe class CraftingLog : Window
IsOpen = true;
}
private void CalculateRecipeStats()
{
RecipeTable = Recipe.RecipeLevelTable.Value!;
RecipeInfo = CreateRecipeInfo(Recipe);
RecipeClassJob = (ClassJob)Recipe.CraftType.Row;
RecipeCharacterLevel = PlayerState.Instance()->ClassJobLevelArray[RecipeClassJob.GetClassJobIndex()];
RecipeCanUseManipulation = ActionManager.CanUseActionOnTarget(ActionType.Manipulation.GetId(RecipeClassJob), (GameObject*)Service.ClientState.LocalPlayer!.Address);
RecipeHQIngredientCount = Recipe.UnkData5
.Where(i =>
i != null &&
i.ItemIngredient != 0 &&
(LuminaSheets.ItemSheet.GetRow((uint)i.ItemIngredient)?.CanBeHq ?? false)
).Sum(i => i.AmountIngredient);
RecipeMaxStartingQuality = (int)Math.Floor(Recipe.MaterialQualityFactor * RecipeInfo.MaxQuality / 100f);
}
private void CalculateCharacterStats()
{
var container = InventoryManager.Instance()->GetInventoryContainer(InventoryType.EquippedItems);
@@ -162,7 +132,7 @@ public unsafe class CraftingLog : Window
return;
CharacterEquipment = Gearsets.GetGearsetItems(container);
CharacterStatsNoConsumable = Gearsets.CalculateCharacterStats(CharacterEquipment, RecipeCharacterLevel, RecipeCanUseManipulation);
CharacterStatsNoConsumable = Gearsets.CalculateCharacterStats(CharacterEquipment, RecipeUtils.CharacterLevel, RecipeUtils.CanUseManipulation);
CharacterConsumableBonus = CalculateConsumableBonus(CharacterStatsNoConsumable);
CharacterStatsConsumable = CharacterStatsNoConsumable with
{
@@ -173,7 +143,7 @@ public unsafe class CraftingLog : Window
CharacterCannotCraftReason = Service.Configuration.OverrideUncraftability ? CannotCraftReason.OK : CanCraftRecipe(CharacterEquipment, CharacterStatsConsumable);
if (CharacterCannotCraftReason == CannotCraftReason.OK)
CharacterSimulationInput = new(CharacterStatsConsumable, RecipeInfo, StartingQuality, Random);
CharacterSimulationInput = new(CharacterStatsConsumable, RecipeUtils.Info, StartingQuality, Random);
}
public override void Draw()
@@ -210,11 +180,11 @@ public unsafe class CraftingLog : Window
private void DrawRecipeInfo()
{
var s = new StringBuilder();
s.AppendLine($"{RecipeClassJob.GetName()} {new string('★', RecipeTable.Stars)}");
s.AppendLine($"Level {RecipeTable.ClassJobLevel} (RLvl {RecipeInfo.RLvl})");
s.AppendLine($"Durability: {RecipeInfo.MaxDurability}");
s.AppendLine($"Progress: {RecipeInfo.MaxProgress}");
s.AppendLine($"Quality: {RecipeInfo.MaxQuality}");
s.AppendLine($"{RecipeUtils.ClassJob.GetName()} {new string('★', RecipeUtils.Table.Stars)}");
s.AppendLine($"Level {RecipeUtils.Table.ClassJobLevel} (RLvl {RecipeUtils.Info.RLvl})");
s.AppendLine($"Durability: {RecipeUtils.Info.MaxDurability}");
s.AppendLine($"Progress: {RecipeUtils.Info.MaxProgress}");
s.AppendLine($"Quality: {RecipeUtils.Info.MaxQuality}");
ImGui.Text(s.ToString());
}
@@ -231,10 +201,10 @@ public unsafe class CraftingLog : Window
private void DrawCraftParameters()
{
ImGui.BeginDisabled(RecipeHQIngredientCount == 0);
ImGui.BeginDisabled(RecipeUtils.HQIngredientCount == 0);
var qualityNotches = QualityNotches;
ImGui.SetNextItemWidth(LeftSideWidth - 115);
if (ImGui.SliderInt("Starting Quality", ref qualityNotches, 0, RecipeHQIngredientCount, StartingQuality.ToString(), ImGuiSliderFlags.NoInput | ImGuiSliderFlags.AlwaysClamp))
if (ImGui.SliderInt("Starting Quality", ref qualityNotches, 0, RecipeUtils.HQIngredientCount, StartingQuality.ToString(), ImGuiSliderFlags.NoInput | ImGuiSliderFlags.AlwaysClamp))
QualityNotches = qualityNotches;
ImGui.EndDisabled();
@@ -286,7 +256,7 @@ public unsafe class CraftingLog : Window
var height = fontSize + (padding.Y * 2);
var width = ImGui.GetContentRegionAvail().X;
var size = new Vector2(width, height);
var infoColWidth = SimulatorWindow.TooltipProgressBarSize.X;
var infoColWidth = Simulator.TooltipProgressBarSize.X;
var infoButtonCount = 3;
var infoButtonWidth = (infoColWidth - ImGui.GetStyle().ItemSpacing.X * (infoButtonCount - 1)) / infoButtonCount;
var infoButtonSize = new Vector2(infoButtonWidth, height);
@@ -319,7 +289,7 @@ public unsafe class CraftingLog : Window
ImGui.TableNextColumn();
ImGui.TextWrapped(macro.Name);
if (state.HasValue)
SimulatorWindow.DrawAllProgressTooltips(state!.Value);
Simulator.DrawAllProgressTooltips(state!.Value);
if (ImGuiUtils.IconButtonSized(FontAwesomeIcon.Copy, infoButtonSize))
CopyMacroToClipboard(macro);
@@ -340,7 +310,7 @@ public unsafe class CraftingLog : Window
var j = 0;
foreach (var action in macro.Actions)
{
ImGui.Image(action.GetIcon(RecipeClassJob).ImGuiHandle, actionSize);
ImGui.Image(action.GetIcon(RecipeUtils.ClassJob).ImGuiHandle, actionSize);
if (j++ % actionCount != actionCount - 1)
ImGui.SameLine();
if (j == actionCount * 2)
@@ -354,7 +324,7 @@ public unsafe class CraftingLog : Window
private void OpenSimulatorWindow(Macro? macro)
{
Service.Plugin.OpenSimulatorWindow(Recipe.ItemResult.Value!, Recipe.IsExpert, CharacterSimulationInput, RecipeClassJob, macro);
Service.Plugin.OpenSimulatorWindow(RecipeUtils.Recipe.ItemResult.Value!, RecipeUtils.Recipe.IsExpert, CharacterSimulationInput, RecipeUtils.ClassJob, macro);
}
private string GetMacroCommand(ActionType action, bool addWaitTimes)
@@ -363,9 +333,9 @@ public unsafe class CraftingLog : Window
if (actionBase is BaseComboAction comboActionBase)
return $"{GetMacroCommand(comboActionBase.ActionTypeA, addWaitTimes)}\n{GetMacroCommand(comboActionBase.ActionTypeB, addWaitTimes)}";
if (addWaitTimes)
return $"/ac \"{action.GetName(RecipeClassJob)}\" <wait.{actionBase.MacroWaitTime}>";
return $"/ac \"{action.GetName(RecipeUtils.ClassJob)}\" <wait.{actionBase.MacroWaitTime}>";
else
return $"/ac \"{action.GetName(RecipeClassJob)}\"";
return $"/ac \"{action.GetName(RecipeUtils.ClassJob)}\"";
}
private void CopyMacroToClipboard(Macro macro)
@@ -401,11 +371,11 @@ public unsafe class CraftingLog : Window
if (!gearset->Flags.HasFlag(RaptureGearsetModule.GearsetFlag.Exists))
continue;
if (!ClassJobUtils.IsClassJob(gearset->ClassJob, RecipeClassJob))
if (!ClassJobUtils.IsClassJob(gearset->ClassJob, RecipeUtils.ClassJob))
continue;
var items = Gearsets.GetGearsetItems(gearset);
var stats = Gearsets.CalculateCharacterStats(items, RecipeCharacterLevel, RecipeCanUseManipulation);
var stats = Gearsets.CalculateCharacterStats(items, RecipeUtils.CharacterLevel, RecipeUtils.CanUseManipulation);
var gearsetId = gearset->ID + 1;
ImGuiUtils.BeginGroupPanel($"{SafeMemory.ReadString((nint)gearset->Name, 47)} ({gearsetId})");
@@ -421,61 +391,33 @@ public unsafe class CraftingLog : Window
public override bool DrawConditions()
{
if (Service.ClientState.LocalPlayer == null)
if (!RecipeUtils.Update(out var isNew))
return false;
Addon = (AddonRecipeNote*)Service.GameGui.GetAddonByName("RecipeNote");
if (Addon == null)
// Check if RecipeNote addon is visible
if (RecipeUtils.AddonRecipe->AtkUnitBase.WindowNode == null)
return false;
if (Addon->AtkUnitBase.WindowNode == null)
// Check if RecipeNote has a visible selected recipe
if (!RecipeUtils.AddonRecipe->Unk258->IsVisible)
return false;
State = RecipeNote.Instance();
var list = State->RecipeList;
if (list == null)
return false;
var recipeEntry = list->SelectedRecipe;
if (recipeEntry == null)
return false;
var isNewRecipe = RecipeId != recipeEntry->RecipeId;
RecipeId = recipeEntry->RecipeId;
var recipe = LuminaSheets.RecipeSheet.GetRow(RecipeId);
if (recipe == null)
return false;
Recipe = recipe;
if (!Addon->Unk258->IsVisible)
return false;
if (isNewRecipe)
{
if (isNew)
QualityNotches = 0;
CalculateRecipeStats();
}
return base.DrawConditions();
}
public override unsafe void PreDraw()
{
ref var unit = ref Addon->AtkUnitBase;
var addon = RecipeUtils.AddonRecipe;
ref var unit = ref addon->AtkUnitBase;
var scale = unit.Scale;
var pos = new Vector2(unit.X, unit.Y);
var size = new Vector2(unit.WindowNode->AtkResNode.Width, unit.WindowNode->AtkResNode.Height) * scale;
var node = (AtkResNode*)Addon->Unk458; // unit.GetNodeById(59);
var nodeParent = Addon->Unk258; // unit.GetNodeById(57);
var node = (AtkResNode*)addon->Unk458; // unit.GetNodeById(59);
var nodeParent = addon->Unk258; // unit.GetNodeById(57);
Position = pos + new Vector2(size.X, (nodeParent->Y + node->Y) * scale);
SizeConstraints = new WindowSizeConstraints
@@ -537,36 +479,38 @@ public unsafe class CraftingLog : Window
private CannotCraftReason CanCraftRecipe(Gearsets.GearsetItem[] items, CharacterStats stats)
{
if (!ClassJobUtils.IsClassJob((byte)Service.ClientState.LocalPlayer!.ClassJob.Id, RecipeClassJob))
if (!ClassJobUtils.IsClassJob((byte)Service.ClientState.LocalPlayer!.ClassJob.Id, RecipeUtils.ClassJob))
return CannotCraftReason.WrongClassJob;
if (Recipe.IsSpecializationRequired && !stats.IsSpecialist)
var recipe = RecipeUtils.Recipe;
if (recipe.IsSpecializationRequired && !stats.IsSpecialist)
return CannotCraftReason.SpecialistRequired;
if (Recipe.ItemRequired.Row != 0)
if (recipe.ItemRequired.Row != 0)
{
if (Recipe.ItemRequired.Value != null)
if (recipe.ItemRequired.Value != null)
{
if (!items.Any(i => Gearsets.IsItem(i, Recipe.ItemRequired.Row)))
if (!items.Any(i => Gearsets.IsItem(i, recipe.ItemRequired.Row)))
{
return CannotCraftReason.RequiredItem;
}
}
}
if (Recipe.StatusRequired.Row != 0)
if (recipe.StatusRequired.Row != 0)
{
if (Recipe.StatusRequired.Value != null)
if (recipe.StatusRequired.Value != null)
{
if (!Service.ClientState.LocalPlayer.StatusList.Any(s => s.StatusId == Recipe.StatusRequired.Row))
if (!Service.ClientState.LocalPlayer.StatusList.Any(s => s.StatusId == recipe.StatusRequired.Row))
return CannotCraftReason.RequiredStatus;
}
}
if (Recipe.RequiredCraftsmanship > stats.Craftsmanship)
if (recipe.RequiredCraftsmanship > stats.Craftsmanship)
return CannotCraftReason.CraftsmanshipTooLow;
if (Recipe.RequiredControl > stats.Control)
if (recipe.RequiredControl > stats.Control)
return CannotCraftReason.ControlTooLow;
return CannotCraftReason.OK;
@@ -6,11 +6,11 @@ using System;
namespace Craftimizer.Plugin.Windows;
public class SettingsWindow : Window
public class Settings : Window
{
private static Configuration Config => Service.Configuration;
public SettingsWindow() : base("Craftimizer Settings")
public Settings() : base("Craftimizer Settings")
{
Service.WindowSystem.AddWindow(this);
@@ -9,7 +9,7 @@ using ClassJob = Craftimizer.Simulator.ClassJob;
namespace Craftimizer.Plugin.Windows;
public sealed partial class SimulatorWindow : Window, IDisposable
public sealed partial class Simulator : Window, IDisposable
{
private const ImGuiWindowFlags WindowFlags = ImGuiWindowFlags.AlwaysAutoResize;
@@ -23,13 +23,13 @@ public sealed partial class SimulatorWindow : Window, IDisposable
private string MacroName { get; set; }
// State is the state of the simulation *after* its corresponding action is executed.
private List<(ActionType Action, string Tooltip, ActionResponse Response, SimulationState State)> Actions { get; }
private Simulator.Simulator Simulator { get; set; }
private Craftimizer.Simulator.Simulator Sim { get; set; }
private SimulationState LatestState => Actions.Count == 0 ? new(Input) : Actions[^1].State;
// Simulator is set by ResetSimulator()
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public SimulatorWindow(Item item, bool isExpert, SimulationInput input, ClassJob classJob, Macro? macro) : base("Craftimizer Simulator", WindowFlags)
public Simulator(Item item, bool isExpert, SimulationInput input, ClassJob classJob, Macro? macro) : base("Craftimizer Simulator", WindowFlags)
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
{
Service.WindowSystem.AddWindow(this);
@@ -58,7 +58,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
private void ResetSimulator()
{
Simulator = Configuration.CreateSimulator(LatestState);
Sim = Configuration.CreateSimulator(LatestState);
ReexecuteAllActions();
}
}
@@ -5,7 +5,7 @@ using System;
namespace Craftimizer.Plugin.Windows;
public sealed partial class SimulatorWindow : Window, IDisposable
public sealed partial class Simulator : Window, IDisposable
{
private void AppendAction(ActionType action)
{
@@ -24,8 +24,8 @@ public sealed partial class SimulatorWindow : Window, IDisposable
}
else
{
var tooltip = actionBase.GetTooltip(Simulator, false);
var (response, state) = Simulator.Execute(LatestState, action);
var tooltip = actionBase.GetTooltip(Sim, false);
var (response, state) = Sim.Execute(LatestState, action);
Actions.Add((action, tooltip, response, state));
}
}
@@ -13,7 +13,7 @@ using Dalamud.Game.Text;
namespace Craftimizer.Plugin.Windows;
public sealed partial class SimulatorWindow : Window, IDisposable
public sealed partial class Simulator : Window, IDisposable
{
private const int ActionColumnSize = 260;
@@ -36,7 +36,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
private static readonly (ActionCategory Category, ActionType[] Actions)[] SortedActions;
static SimulatorWindow()
static Simulator()
{
SortedActions = Enum.GetValues<ActionType>()
.Where(a => a.Category() != ActionCategory.Combo)
@@ -69,7 +69,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
Configuration.Save();
}
Simulator.SetState(LatestState);
Sim.SetState(LatestState);
var actionSize = new Vector2((ActionColumnSize / 5) - ImGui.GetStyle().ItemSpacing.X * (6f / 5));
ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero);
@@ -89,7 +89,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
if (cannotUse && Configuration.HideUnlearnedActions)
continue;
var shouldNotUse = !baseAction.CanUse(Simulator) || Simulator.IsComplete;
var shouldNotUse = !baseAction.CanUse(Sim) || Sim.IsComplete;
ImGui.BeginDisabled(cannotUse);
@@ -97,7 +97,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
AppendAction(action);
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
ImGui.SetTooltip($"{action.GetName(ClassJob)}\n{baseAction.GetTooltip(Simulator, true)}");
ImGui.SetTooltip($"{action.GetName(ClassJob)}\n{baseAction.GetTooltip(Sim, true)}");
ImGui.EndDisabled();
@@ -210,11 +210,11 @@ public sealed partial class SimulatorWindow : Window, IDisposable
ImGui.SameLine(0, 0);
foreach (var effect in Enum.GetValues<EffectType>())
{
var duration = Simulator.GetEffectDuration(effect);
var duration = Sim.GetEffectDuration(effect);
if (duration == 0)
continue;
var strength = Simulator.GetEffectStrength(effect);
var strength = Sim.GetEffectStrength(effect);
var icon = effect.GetIcon(strength);
var iconSize = GetEffectSize(icon);
@@ -6,7 +6,7 @@ using System.Numerics;
namespace Craftimizer.Plugin.Windows;
public sealed partial class SimulatorWindow : Window, IDisposable
public sealed partial class Simulator : Window, IDisposable
{
private readonly record struct SynthDrawParams
{
@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace Craftimizer.Plugin.Windows;
public sealed partial class SimulatorWindow : Window, IDisposable
public sealed partial class Simulator : Window, IDisposable
{
private Task SolverTask { get; set; } = Task.CompletedTask;
private CancellationTokenSource SolverTaskToken { get; set; } = new();
@@ -27,7 +27,7 @@ public sealed partial class SimulatorWindow : Window, IDisposable
private SimulationState? GenerateSolverState()
{
if (Simulator is SimulatorNoRandom)
if (Sim is SimulatorNoRandom)
{
if (!Actions.Exists(a => a.Response != ActionResponse.UsedAction))
return LatestState;