Big UI changes, drag and drop works
todo: - action history doesnt wrap - macro saving + suggestion/solving - show macros in craftinglog window (still untested)
This commit is contained in:
@@ -20,6 +20,7 @@ public class Configuration : IPluginConfiguration
|
||||
public int Version { get; set; } = 1;
|
||||
|
||||
public bool OverrideUncraftability { get; set; } = true;
|
||||
public bool HideUnlearnedActions { get; set; } = true;
|
||||
public List<Macro> Macros { get; set; } = new();
|
||||
public string SimulatorType { get; set; } = typeof(Simulator.Simulator).AssemblyQualifiedName!;
|
||||
|
||||
|
||||
@@ -10,7 +10,35 @@ internal static class ImGuiUtils
|
||||
private static readonly Stack<(Vector2 Min, Vector2 Max)> GroupPanelLabelStack = new();
|
||||
|
||||
// Adapted from https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353
|
||||
public static void BeginGroupPanel(string name, float width = -1)
|
||||
public static void BeginGroupPanel(float width = -1, bool addPadding = true)
|
||||
{
|
||||
ImGui.BeginGroup();
|
||||
|
||||
var itemSpacing = ImGui.GetStyle().ItemSpacing;
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||
|
||||
var frameHeight = ImGui.GetFrameHeight();
|
||||
|
||||
ImGui.BeginGroup();
|
||||
ImGui.Dummy(new Vector2(width < 0 ? ImGui.GetContentRegionAvail().X : width, 0));
|
||||
ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0));
|
||||
ImGui.SameLine(0, 0);
|
||||
|
||||
ImGui.BeginGroup();
|
||||
ImGui.Dummy(new Vector2(frameHeight * 0.5f, 0));
|
||||
GroupPanelLabelStack.Push((ImGui.GetItemRectMin(), ImGui.GetItemRectMax()));
|
||||
ImGui.SameLine(0, 0);
|
||||
ImGui.Dummy(new Vector2(0f, frameHeight * (addPadding ? 1 : .5f) + itemSpacing.Y));
|
||||
|
||||
ImGui.BeginGroup();
|
||||
|
||||
ImGui.PopStyleVar(2);
|
||||
|
||||
ImGui.PushItemWidth(MathF.Max(0, ImGui.CalcItemWidth() - frameHeight));
|
||||
}
|
||||
|
||||
public static void BeginGroupPanel(string name, float width = -1, bool addPadding = true)
|
||||
{
|
||||
ImGui.BeginGroup();
|
||||
|
||||
@@ -31,14 +59,13 @@ internal static class ImGuiUtils
|
||||
ImGui.TextUnformatted(name);
|
||||
GroupPanelLabelStack.Push((ImGui.GetItemRectMin(), ImGui.GetItemRectMax()));
|
||||
ImGui.SameLine(0, 0);
|
||||
ImGui.Dummy(new Vector2(0f, frameHeight + itemSpacing.Y));
|
||||
ImGui.Dummy(new Vector2(0f, frameHeight * (addPadding ? 1 : .5f) + itemSpacing.Y));
|
||||
|
||||
ImGui.BeginGroup();
|
||||
|
||||
ImGui.PopStyleVar(2);
|
||||
|
||||
ImGui.PushItemWidth(MathF.Max(0, ImGui.CalcItemWidth() - frameHeight));
|
||||
|
||||
}
|
||||
|
||||
public static void EndGroupPanel()
|
||||
|
||||
@@ -40,14 +40,14 @@ public sealed class Plugin : IDalamudPlugin
|
||||
Service.PluginInterface.UiBuilder.OpenConfigUi += () => SettingsWindow.IsOpen = true;
|
||||
}
|
||||
|
||||
public void OpenSimulatorWindow(Item item, SimulationInput input, ClassJob classJob, List<ActionType> actions)
|
||||
public void OpenSimulatorWindow(Item item, bool isExpert, SimulationInput input, ClassJob classJob, List<ActionType> actions)
|
||||
{
|
||||
if (SimulatorWindow != null)
|
||||
{
|
||||
SimulatorWindow.IsOpen = false;
|
||||
WindowSystem.RemoveWindow(SimulatorWindow);
|
||||
}
|
||||
SimulatorWindow = new(item, input, classJob, actions);
|
||||
SimulatorWindow = new(item, isExpert, input, classJob, actions);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -160,10 +160,10 @@ internal static class ConditionUtils
|
||||
private static Vector3 AddRGB(this Condition me) =>
|
||||
me switch
|
||||
{
|
||||
Condition.Poor => Vector3.Zero, // Unsure
|
||||
Condition.Poor => new(-50, -50, -50),
|
||||
Condition.Normal => new(32, 48, 64),
|
||||
Condition.Good => new(80, -80, 0),
|
||||
Condition.Excellent => Vector3.Zero, // Unsure
|
||||
Condition.Excellent => Vector3.Zero, // All the other conditions are just a single lerp, this one is different
|
||||
Condition.Centered => new(200, 200, 0),
|
||||
Condition.Sturdy => new(-100, 45, 155),
|
||||
Condition.Pliant => new(0, 250, 0),
|
||||
@@ -173,6 +173,65 @@ internal static class ConditionUtils
|
||||
_ => Vector3.Zero // Unknown
|
||||
};
|
||||
|
||||
private const float ConditionCyclePeriod = 19/30f;
|
||||
// The real period of all condition color cycles are 0.633... (19/30) seconds
|
||||
// Interp accepts 0-1
|
||||
public static Vector4 GetColor(this Condition me, float interp)
|
||||
{
|
||||
//var baseColor = new Vector3(0.85f, 0.85f, 0.85f); // Middle-ish pixels of synthesis2_hr1.tex's condition circle
|
||||
|
||||
Vector3 addRgb;
|
||||
// Excellent has 6 lerps and 1 ending constant
|
||||
if (me == Condition.Excellent)
|
||||
{
|
||||
addRgb = interp switch
|
||||
{
|
||||
< 0.155f => Vector3.Lerp(new(128,0,0), new(128,80,0), (interp - 0) / 0.155f),
|
||||
< 0.315f => Vector3.Lerp(new(128, 80, 0), new(128, 128, 0), (interp - 0.155f) / 0.16f),
|
||||
< 0.475f => Vector3.Lerp(new(128, 128, 0), new(0, 64, 0), (interp - 0.315f) / 0.16f),
|
||||
< 0.630f => Vector3.Lerp(new(0, 64, 0), new(0, 128, 128), (interp - 0.475f) / 0.155f),
|
||||
< 0.790f => Vector3.Lerp(new(0, 128, 128), new(0, 0, 128), (interp - 0.630f) / 0.16f),
|
||||
< 0.945f => Vector3.Lerp(new(0, 0, 128), new(64, 0, 64), (interp - 0.790f) / 0.155f),
|
||||
_ => new(64, 0, 64)
|
||||
};
|
||||
}
|
||||
// Period is twice as fast so we oscillate at twice that speed
|
||||
else if (me == Condition.Malleable)
|
||||
{
|
||||
if (interp > .5f)
|
||||
interp -= .5f;
|
||||
if (interp > .25f)
|
||||
interp = .25f - (interp - .25f);
|
||||
interp *= 4;
|
||||
addRgb = Vector3.Lerp(new(-80, -40, 180), new(-41, -1, 254), interp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (interp > .5f)
|
||||
interp = .5f - (interp - .5f);
|
||||
interp *= 2;
|
||||
addRgb = me switch
|
||||
{
|
||||
Condition.Poor => Vector3.Lerp(new(-50, -50, -50), new(-1, -1, -1), interp),
|
||||
Condition.Normal => Vector3.Lerp(new(32, 48, 64), new(63, 95, 127), interp),
|
||||
Condition.Good => Vector3.Lerp(new(80, -80, 0), new(159, -1, 0), interp),
|
||||
Condition.Centered => Vector3.Lerp(new(199, 199, 0), new(100, 100, 0), interp),
|
||||
Condition.Sturdy => Vector3.Lerp(new(-100, 45, 155), new(-51, 89, 254), interp),
|
||||
Condition.Pliant => Vector3.Lerp(new(0, 150, 0), new(0, 249, 0), interp),
|
||||
Condition.Primed => Vector3.Lerp(new(-30, -255, 50), new(29, -156, 199), interp),
|
||||
Condition.GoodOmen => Vector3.Lerp(new(100, 20, 0), new(100, 99, 99), interp),
|
||||
_ => default
|
||||
};
|
||||
}
|
||||
|
||||
return new(addRgb / 255, 1);
|
||||
}
|
||||
|
||||
public static Vector4 GetColor(this Condition me, TimeSpan time)
|
||||
{
|
||||
return me.GetColor((float)(time.TotalSeconds % ConditionCyclePeriod / ConditionCyclePeriod));
|
||||
}
|
||||
|
||||
public static string Name(this Condition me) =>
|
||||
LuminaSheets.AddonSheet.GetRow(me.AddonIds().Name)!.Text.ToDalamudString().TextValue;
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ public unsafe class CraftingLog : Window
|
||||
|
||||
if (ImGui.Button("Open Simulator", size))
|
||||
{
|
||||
Service.Plugin.OpenSimulatorWindow(Recipe.ItemResult.Value!, CharacterSimulationInput, RecipeClassJob, new());
|
||||
Service.Plugin.OpenSimulatorWindow(Recipe.ItemResult.Value!, Recipe.IsExpert, CharacterSimulationInput, RecipeClassJob, new());
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.Button("Generate a new macro", size);
|
||||
|
||||
@@ -3,32 +3,46 @@ using Craftimizer.Simulator.Actions;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Memory;
|
||||
using Dalamud.Utility;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using ActionCategory = Craftimizer.Simulator.ActionCategory;
|
||||
using ClassJob = Craftimizer.Simulator.ClassJob;
|
||||
using Condition = Craftimizer.Simulator.Condition;
|
||||
|
||||
namespace Craftimizer.Plugin.Windows;
|
||||
|
||||
public class SimulatorWindow : Window
|
||||
{
|
||||
private const ImGuiWindowFlags WindowFlags = ImGuiWindowFlags.AlwaysAutoResize;
|
||||
|
||||
private static readonly Vector2 ProgressBarSize = new(200, 20);
|
||||
private static readonly Vector2 DurabilityBarSize = new(100, 20);
|
||||
private static readonly Vector2 ConditionBarSize = new(20, 20);
|
||||
private static readonly Vector2 ProgressBarSizeOld = new(200, 20);
|
||||
private static readonly Vector2 TooltipProgressBarSize = new(100, 5);
|
||||
|
||||
private static readonly Vector4 ProgressColor = new(.2f, 1f, .2f, 1f);
|
||||
private static readonly Vector4 QualityColor = new(.2f, .2f, 1f, 1f);
|
||||
private static readonly Vector4 DurabilityColor = new(1f, 1f, .2f, 1f);
|
||||
private static readonly Vector4 CPColor = new(1f, .2f, 1f, 1f);
|
||||
private static readonly Vector4 ProgressColorOld = new(.2f, 1f, .2f, 1f);
|
||||
private static readonly Vector4 QualityColorOld = new(.2f, .2f, 1f, 1f);
|
||||
private static readonly Vector4 DurabilityColorOld = new(1f, 1f, .2f, 1f);
|
||||
private static readonly Vector4 CPColorOld = new(1f, .2f, 1f, 1f);
|
||||
|
||||
private static readonly Vector4 CPColorNew = new(0.38f, 0.77f, 1f, 1f);
|
||||
private static readonly Vector4 ProgressColor = new(0.44f, 0.65f, 0.18f, 1f);
|
||||
private static readonly Vector4 QualityColor = new(0.26f, 0.71f, 0.69f, 1f);
|
||||
private static readonly Vector4 DurabilityColor = new(0.13f, 0.52f, 0.93f, 1f);
|
||||
private static readonly Vector4 HQColor = new(0.592f, 0.863f, 0.376f, 1f);
|
||||
private static readonly Vector4 CPColor = new(0.63f, 0.37f, 0.75f, 1f);
|
||||
|
||||
private static readonly Vector4 BadActionImageTint = new(1f, .5f, .5f, 1f);
|
||||
private static readonly Vector4 BadActionImageColor = new(1f, .3f, .3f, 1f);
|
||||
@@ -41,6 +55,7 @@ public class SimulatorWindow : Window
|
||||
private Stopwatch Stopwatch { get; } = new();
|
||||
|
||||
private Item Item { get; }
|
||||
private bool IsExpert { get; }
|
||||
private SimulationInput Input { get; }
|
||||
private ClassJob ClassJob { get; }
|
||||
// State is the state of the simulation *after* its corresponding action is executed.
|
||||
@@ -49,18 +64,17 @@ public class SimulatorWindow : Window
|
||||
|
||||
private SimulationState LatestState => Actions.Count == 0 ? new(Input) : Actions[^1].State;
|
||||
|
||||
private ActionType? DraggedAction { get; set; }
|
||||
|
||||
static SimulatorWindow()
|
||||
{
|
||||
SortedActions = Enum.GetValues<ActionType>().GroupBy(a => a.Category()).Select(g => (g.Key, g.OrderBy(a => a.Level()).ToArray())).ToArray();
|
||||
}
|
||||
|
||||
public SimulatorWindow(Item item, SimulationInput input, ClassJob classJob, List<ActionType> actions) : base("Simulator")
|
||||
public SimulatorWindow(Item item, bool isExpert, SimulationInput input, ClassJob classJob, List<ActionType> actions) : base("Simulator", WindowFlags)
|
||||
{
|
||||
Service.WindowSystem.AddWindow(this);
|
||||
|
||||
Item = item;
|
||||
IsExpert = isExpert;
|
||||
Input = input;
|
||||
ClassJob = classJob;
|
||||
Actions = new();
|
||||
@@ -70,6 +84,8 @@ public class SimulatorWindow : Window
|
||||
AppendAction(action);
|
||||
|
||||
IsOpen = true;
|
||||
CollapsedCondition = ImGuiCond.Appearing;
|
||||
Collapsed = false;
|
||||
}
|
||||
|
||||
public override void PreDraw()
|
||||
@@ -84,77 +100,89 @@ public class SimulatorWindow : Window
|
||||
Stopwatch.Stop();
|
||||
FrameTime = Stopwatch.Elapsed;
|
||||
|
||||
/*
|
||||
unsafe {
|
||||
var unitBase = (AtkUnitBase*)Service.GameGui.GetAddonByName("Synthesis");
|
||||
if (unitBase != null)
|
||||
{
|
||||
var res = unitBase->GetNodeById(95)->GetAsAtkComponentNode()->Component;
|
||||
var cond = MemoryHelper.ReadStringNullTerminated((nint)res->GetTextNodeById(4)->GetAsAtkTextNode()->GetText());
|
||||
var img = res->GetImageNodeById(3);
|
||||
|
||||
var d = unchecked(((short)img->AddRed, (short)img->AddGreen, (short)img->AddBlue));
|
||||
PluginLog.LogDebug($"{cond} -> {d}");
|
||||
}
|
||||
}
|
||||
*/
|
||||
base.PostDraw();
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
ImGui.BeginTable("simulatorWindow", 2, ImGuiTableFlags.Resizable);
|
||||
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, 300);
|
||||
ImGui.BeginTable("simulatorWindow", 2, ImGuiTableFlags.BordersInnerV);
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, 260);
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthStretch);
|
||||
ImGui.TableNextColumn();
|
||||
DrawActions();
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
DrawSimulationInfo();
|
||||
|
||||
ImGui.EndTable();
|
||||
|
||||
ImGui.TextUnformatted($"{FrameTime.TotalMilliseconds:0.00}ms");
|
||||
return;
|
||||
}
|
||||
|
||||
private void DrawActions()
|
||||
{
|
||||
ImGui.BeginChild("CraftimizerActions", Vector2.Zero, true, ImGuiWindowFlags.NoDecoration);
|
||||
//ImGui.Checkbox("Show only guaranteed actions", ref showOnlyGuaranteedActions);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||
|
||||
var actionSize = new Vector2(ImGui.GetFontSize() * 2);
|
||||
var actionSize = new Vector2(ImGui.GetFontSize() * 2f);
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero);
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonActive, Vector4.Zero);
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Vector4.Zero);
|
||||
|
||||
//ImGui.Checkbox("Show only guaranteed actions", ref showOnlyGuaranteedActions);
|
||||
|
||||
foreach (var (category, actions) in SortedActions)
|
||||
{
|
||||
var i = 0;
|
||||
ImGuiUtils.BeginGroupPanel(category.GetDisplayName());
|
||||
ImGuiUtils.BeginGroupPanel(category.GetDisplayName(), 260);
|
||||
foreach (var action in actions)
|
||||
{
|
||||
var baseAction = action.Base();
|
||||
|
||||
var cannotUse = action.Level() > Input.Stats.Level || (action == ActionType.Manipulation && !Input.Stats.CanUseManipulation);
|
||||
if (cannotUse && Service.Configuration.HideUnlearnedActions)
|
||||
continue;
|
||||
|
||||
var shouldNotUse = !baseAction.CanUse(Simulator) || Simulator.IsComplete;
|
||||
|
||||
ImGui.BeginDisabled(cannotUse);
|
||||
|
||||
if (shouldNotUse)
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, BadActionImageColor);
|
||||
|
||||
if (ImGui.ImageButton(action.GetIcon(ClassJob).ImGuiHandle, actionSize, Vector2.Zero, Vector2.One, -1, default, shouldNotUse ? BadActionImageTint : Vector4.One))
|
||||
if (ImGui.ImageButton(action.GetIcon(ClassJob).ImGuiHandle, actionSize, Vector2.Zero, Vector2.One, 0, default, shouldNotUse ? BadActionImageTint : Vector4.One))
|
||||
AppendAction(action);
|
||||
|
||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
ImGui.SetTooltip($"{action.GetName(ClassJob)}\n{baseAction.GetTooltip(Simulator, true)}");
|
||||
|
||||
if (shouldNotUse)
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
ImGui.EndDisabled();
|
||||
|
||||
if (++i % 5 != 0)
|
||||
ImGui.SameLine();
|
||||
}
|
||||
if (i == 0)
|
||||
ImGui.Dummy(actionSize);
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
}
|
||||
ImGui.PopStyleVar();
|
||||
ImGui.EndChild();
|
||||
ImGui.PopStyleColor(3);
|
||||
}
|
||||
|
||||
private void DrawSimulationInfo()
|
||||
{
|
||||
ImGui.BeginChild("simulationInfo", Vector2.Zero, true, ImGuiWindowFlags.NoDecoration);
|
||||
DrawSimulationSynth();
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
DrawSimulationEffects();
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
DrawSimulationActions();
|
||||
ImGui.EndChild();
|
||||
}
|
||||
|
||||
private void DrawSimulationSynth()
|
||||
@@ -162,73 +190,147 @@ public class SimulatorWindow : Window
|
||||
var state = LatestState;
|
||||
var imageSize = new Vector2(ImGui.GetFontSize() * 2f);
|
||||
|
||||
ImGui.Image(Icons.GetIconFromId(Item.Icon).ImGuiHandle, imageSize);
|
||||
ImGui.SameLine();
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.SetCursorPosY(ImGui.GetFontSize()*.75f);
|
||||
ImGui.TextUnformatted(Item.Name.ToDalamudString().ToString());
|
||||
var availWidth = ImGui.GetContentRegionAvail().X;
|
||||
var text = $"Step {state.StepCount + 1}";
|
||||
var textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SameLine(availWidth - textWidth);
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.SetCursorPosY(ImGui.GetFontSize() * .75f);
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGui.Separator();
|
||||
{
|
||||
ImGui.Image(Icons.GetIconFromId(Item.Icon).ImGuiHandle, imageSize);
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetFontSize() * .5f);
|
||||
ImGui.TextUnformatted(Item.Name.ToDalamudString().ToString());
|
||||
if (Item.IsCollectable)
|
||||
{
|
||||
ImGui.SameLine(0, 5);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetFontSize() * .5f);
|
||||
ImGui.TextColored(new(0.98f, 0.98f, 0.61f, 1), "(Collectible)");
|
||||
}
|
||||
if (IsExpert)
|
||||
{
|
||||
ImGui.SameLine(0, 5);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetFontSize() * .5f);
|
||||
ImGui.TextColored(new(0.941f, 0.557f, 0.216f, 1), "(Expert)");
|
||||
}
|
||||
var availWidth = ImGui.GetContentRegionAvail().X;
|
||||
var text = $"Step {state.StepCount + 1}";
|
||||
var textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SameLine(availWidth - textWidth);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetFontSize() * .5f);
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
ImGui.BeginTable("simSynth", 2);
|
||||
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, 110);
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiUtils.BeginGroupPanel("Durability");
|
||||
ImGui.TextUnformatted($"{state.Durability} / {Input.Recipe.MaxDurability}");
|
||||
DrawProgressBar(state.Durability, Input.Recipe.MaxDurability, new(100, 20), CPColorNew);
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
var sidePadding = ImGui.GetFrameHeight() / 2;
|
||||
var separatorTextWidth = ImGui.CalcTextSize(" / ").X;
|
||||
var itemSpacing = ImGui.GetStyle().ItemSpacing.X * 2;
|
||||
|
||||
ImGuiUtils.BeginGroupPanel("Condition");
|
||||
ImGui.TextUnformatted(state.Condition.Name());
|
||||
var leftDigits = (int)MathF.Floor(MathF.Log10(Input.Recipe.MaxDurability) + 1);
|
||||
var leftTextWidth = ImGui.CalcTextSize(new string('0', leftDigits)).X;
|
||||
var leftWidth = DurabilityBarSize.X + sidePadding + itemSpacing + separatorTextWidth + leftTextWidth * 2;
|
||||
|
||||
|
||||
var rightDigits = (int)MathF.Floor(MathF.Log10(Math.Max(Math.Max(Input.Recipe.MaxProgress, Input.Recipe.MaxQuality), Input.Stats.CP)) + 1);
|
||||
var rightTextWidth = ImGui.CalcTextSize(new string('0', rightDigits)).X;
|
||||
var rightWidth = ProgressBarSize.X + sidePadding + itemSpacing + separatorTextWidth + rightTextWidth * 2;
|
||||
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, leftWidth);
|
||||
ImGui.TableSetupColumn("", ImGuiTableColumnFlags.WidthFixed, rightWidth);
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
DrawSynthBarCenteredProgress("Durability", state.Durability, Input.Recipe.MaxDurability, DurabilityBarSize, DurabilityColor, leftTextWidth);
|
||||
|
||||
DrawSynthBarCenteredCircle("Condition", state.Condition.Name(), ConditionBarSize, new Vector4(.35f, .35f, .35f, 0) + state.Condition.GetColor(DateTime.UtcNow.TimeOfDay), DurabilityBarSize, leftTextWidth);
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip(state.Condition.Description(state.Input.Stats.HasSplendorousBuff));
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
|
||||
if (Item.IsCollectable)
|
||||
{
|
||||
var collectibility = Math.Max(state.Quality / 10, 1);
|
||||
DrawSynthBarCentered("Collectability", collectibility, Input.Recipe.MaxQuality / 10, $"{collectibility}", DurabilityBarSize, HQColor, leftTextWidth);
|
||||
}
|
||||
else
|
||||
DrawSynthBarCentered("HQ %", state.HQPercent, 100, $"{state.HQPercent}%", DurabilityBarSize, HQColor, leftTextWidth);
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
|
||||
ImGuiUtils.BeginGroupPanel("Progress");
|
||||
DrawProgressBar(state.Progress, Input.Recipe.MaxProgress, new(200, 20), ProgressColor);
|
||||
availWidth = ImGui.GetContentRegionAvail().X;
|
||||
text = $"{state.Progress} / {Input.Recipe.MaxProgress}";
|
||||
textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SameLine(availWidth - textWidth - 10);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f));
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
|
||||
ImGuiUtils.BeginGroupPanel("Quality");
|
||||
DrawProgressBar(state.Quality, Input.Recipe.MaxQuality, new(200, 20), QualityColor);
|
||||
availWidth = ImGui.GetContentRegionAvail().X;
|
||||
text = $"{state.Quality} / {Input.Recipe.MaxQuality}";
|
||||
textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SameLine(availWidth - textWidth - 10);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f));
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
|
||||
ImGuiUtils.BeginGroupPanel("CP");
|
||||
DrawProgressBar(state.CP, Input.Stats.CP, new(200, 20), CPColor);
|
||||
availWidth = ImGui.GetContentRegionAvail().X;
|
||||
text = $"{state.CP} / {Input.Stats.CP}";
|
||||
textWidth = ImGui.CalcTextSize(text).X;
|
||||
ImGui.SameLine(availWidth - textWidth - 10);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f));
|
||||
ImGui.TextUnformatted(text);
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.TextUnformatted($"HQ {state.HQPercent}%");
|
||||
DrawSynthBarCenteredProgress("Progress", state.Progress, Input.Recipe.MaxProgress, ProgressBarSize, ProgressColor, rightTextWidth);
|
||||
DrawSynthBarCenteredProgress("Quality", state.Quality, Input.Recipe.MaxQuality, ProgressBarSize, QualityColor, rightTextWidth);
|
||||
DrawSynthBarCenteredProgress("CP", state.CP, Input.Stats.CP, ProgressBarSize, CPColor, rightTextWidth);
|
||||
|
||||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
private void DrawSynthBarCenteredProgress(string name, int current, int max, Vector2 size, Vector4 color, float textWidth)
|
||||
{
|
||||
ImGuiUtils.BeginGroupPanel(name);
|
||||
|
||||
DrawProgressBar(current, max, size, color);
|
||||
|
||||
var w = ImGui.GetStyle().ItemSpacing.X;
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, ImGui.GetStyle().ItemSpacing.Y));
|
||||
|
||||
ImGui.SameLine(0, textWidth - ImGui.CalcTextSize($"{current}").X + w);
|
||||
var adjustedHeight = ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f);
|
||||
ImGui.SetCursorPosY(adjustedHeight);
|
||||
ImGui.TextUnformatted($"{current}");
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetCursorPosY(adjustedHeight);
|
||||
ImGui.TextUnformatted(" / ");
|
||||
|
||||
ImGui.SameLine(0, textWidth - ImGui.CalcTextSize($"{max}").X);
|
||||
ImGui.SetCursorPosY(adjustedHeight);
|
||||
ImGui.TextUnformatted($"{max}");
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
}
|
||||
|
||||
private void DrawSynthBarCenteredCircle(string name, string text, Vector2 size, Vector4 color, Vector2 otherProgressSize, float textWidth)
|
||||
{
|
||||
ImGuiUtils.BeginGroupPanel(name);
|
||||
|
||||
var w = ImGui.GetStyle().ItemSpacing.X;
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, ImGui.GetStyle().ItemSpacing.Y));
|
||||
|
||||
var contentWidth = size.X + w + ImGui.CalcTextSize(text).X;
|
||||
var totalWidth = otherProgressSize.X + w + textWidth * 2 + ImGui.CalcTextSize(" / ").X;
|
||||
|
||||
ImGui.Dummy(default);
|
||||
ImGui.SameLine(0, (totalWidth - contentWidth) / 2);
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, Math.Max(size.X, size.Y));
|
||||
DrawProgressBar(1, 1, size, color);
|
||||
ImGui.PopStyleVar();
|
||||
ImGui.SameLine(0, w);
|
||||
var adjustedHeight = ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f);
|
||||
ImGui.SetCursorPosY(adjustedHeight);
|
||||
ImGui.TextUnformatted(text);
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
}
|
||||
|
||||
private void DrawSynthBarCentered(string name, int current, int max, string text, Vector2 size, Vector4 color, float textWidth)
|
||||
{
|
||||
ImGuiUtils.BeginGroupPanel(name);
|
||||
|
||||
DrawProgressBar(current, max, size, color);
|
||||
|
||||
var w = ImGui.GetStyle().ItemSpacing.X;
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, ImGui.GetStyle().ItemSpacing.Y));
|
||||
|
||||
var totalWidth = textWidth * 2 + ImGui.CalcTextSize(" / ").X;
|
||||
|
||||
ImGui.SameLine(0, totalWidth - ImGui.CalcTextSize(text).X + w);
|
||||
var adjustedHeight = ImGui.GetCursorPosY() - ((ImGui.GetFrameHeight() - ImGui.GetFontSize()) / 2f);
|
||||
ImGui.SetCursorPosY(adjustedHeight);
|
||||
ImGui.TextUnformatted(text);
|
||||
|
||||
ImGui.PopStyleVar();
|
||||
|
||||
ImGuiUtils.EndGroupPanel();
|
||||
}
|
||||
|
||||
private void DrawSimulationSynthOld()
|
||||
{
|
||||
var state = LatestState;
|
||||
@@ -238,10 +340,10 @@ public class SimulatorWindow : Window
|
||||
if (ImGui.IsItemHovered())
|
||||
ImGui.SetTooltip(state.Condition.Description(state.Input.Stats.HasSplendorousBuff));
|
||||
ImGui.Text($"{state.HQPercent}%% HQ");
|
||||
DrawProgressBarOld(state.Progress, Input.Recipe.MaxProgress, ProgressColor);
|
||||
DrawProgressBarOld(state.Quality, Input.Recipe.MaxQuality, QualityColor);
|
||||
DrawProgressBarOld(state.Durability, Input.Recipe.MaxDurability, DurabilityColor);
|
||||
DrawProgressBarOld(state.CP, Input.Stats.CP, CPColor);
|
||||
DrawProgressBarOld(state.Progress, Input.Recipe.MaxProgress, ProgressColorOld);
|
||||
DrawProgressBarOld(state.Quality, Input.Recipe.MaxQuality, QualityColorOld);
|
||||
DrawProgressBarOld(state.Durability, Input.Recipe.MaxDurability, DurabilityColorOld);
|
||||
DrawProgressBarOld(state.CP, Input.Stats.CP, CPColorOld);
|
||||
}
|
||||
|
||||
private void DrawSimulationEffects()
|
||||
@@ -279,28 +381,30 @@ public class SimulatorWindow : Window
|
||||
for (var i = 0; i < Actions.Count; ++i)
|
||||
{
|
||||
var (action, tooltip, response, state) = Actions[i];
|
||||
ImGui.PushID(i);
|
||||
if (ImGui.ImageButton(action.GetIcon(ClassJob).ImGuiHandle, actionSize, Vector2.Zero, Vector2.One, 0, default, response != ActionResponse.UsedAction ? BadActionImageTint : Vector4.One))
|
||||
RemoveAction(i);
|
||||
if (ImGui.BeginDragDropSource())
|
||||
{
|
||||
unsafe { ImGui.SetDragDropPayload("simulationAction", (nint)(void*)&i, sizeof(int)); }
|
||||
ImGui.ImageButton(action.GetIcon(ClassJob).ImGuiHandle, actionSize);
|
||||
unsafe { ImGui.SetDragDropPayload("simulationAction", (nint)(&i), sizeof(int)); }
|
||||
ImGui.ImageButton(Actions[i].Action.GetIcon(ClassJob).ImGuiHandle, actionSize);
|
||||
ImGui.EndDragDropSource();
|
||||
}
|
||||
if (ImGui.BeginDragDropTarget())
|
||||
{
|
||||
var payload = ImGui.AcceptDragDropPayload("simulationAction");
|
||||
unsafe
|
||||
bool isValidPayload;
|
||||
unsafe { isValidPayload = payload.NativePtr != null; }
|
||||
if (isValidPayload)
|
||||
{
|
||||
if (payload.NativePtr != null)
|
||||
{
|
||||
int droppedIdx;
|
||||
droppedIdx = *(int*)payload.Data;
|
||||
var droppedAction = Actions[droppedIdx].Action;
|
||||
RemoveAction(droppedIdx);
|
||||
InsertAction(i, droppedAction);
|
||||
}
|
||||
int draggedIdx;
|
||||
unsafe { draggedIdx = *(int*)payload.Data; }
|
||||
var draggedAction = Actions[draggedIdx].Action;
|
||||
RemoveAction(draggedIdx);
|
||||
InsertAction(i, draggedAction);
|
||||
}
|
||||
ImGui.EndDragDropTarget();
|
||||
}
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
@@ -321,9 +425,10 @@ public class SimulatorWindow : Window
|
||||
DrawProgressBarTooltip(state.Quality, Input.Recipe.MaxQuality, QualityColor);
|
||||
DrawProgressBarTooltip(state.Durability, Input.Recipe.MaxDurability, DurabilityColor);
|
||||
DrawProgressBarTooltip(state.CP, Input.Stats.CP, CPColor);
|
||||
ImGui.Text("Right Click to Remove\nDrag to Move");
|
||||
ImGui.Text("Click to Remove\nDrag to Move");
|
||||
ImGui.EndTooltip();
|
||||
}
|
||||
ImGui.PopID();
|
||||
ImGui.SameLine();
|
||||
}
|
||||
ImGui.PopStyleColor(3);
|
||||
@@ -380,7 +485,7 @@ public class SimulatorWindow : Window
|
||||
}
|
||||
|
||||
private static void DrawProgressBarOld(int progress, int maxProgress, Vector4 color) =>
|
||||
DrawProgressBar(progress, maxProgress, ProgressBarSize, color, $"{progress} / {maxProgress}");
|
||||
DrawProgressBar(progress, maxProgress, ProgressBarSizeOld, color, $"{progress} / {maxProgress}");
|
||||
|
||||
private static void DrawProgressBar(int progress, int maxProgress, Vector2 size, Vector4 color, string overlay = "")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user