Implement collectability bars
This commit is contained in:
+11
-11
@@ -75,17 +75,17 @@ public class SharlayanCraftWorksSupply : ExcelRow
|
|||||||
for (var i = 0; i < 4; i++)
|
for (var i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
Items[i] = new ItemData();
|
Items[i] = new ItemData();
|
||||||
Items[i].Level = parser.ReadColumn<byte>(0 + (i * 11 + 0));
|
Items[i].Level = parser.ReadColumn<byte>(0 * 4 + i);
|
||||||
Items[i].Item = new LazyRow<Item>(gameData, parser.ReadColumn<uint>(0 + (i * 11 + 1)), language);
|
Items[i].Item = new LazyRow<Item>(gameData, parser.ReadColumn<uint>(1 * 4 + i), language);
|
||||||
Items[i].CollectabilityMid = parser.ReadColumn<ushort>(0 + (i * 11 + 2));
|
Items[i].CollectabilityMid = parser.ReadColumn<ushort>(2 * 4 + i);
|
||||||
Items[i].CollectabilityHigh = parser.ReadColumn<ushort>(0 + (i * 11 + 3));
|
Items[i].CollectabilityHigh = parser.ReadColumn<ushort>(3 * 4 + i);
|
||||||
Items[i].XPReward = parser.ReadColumn<uint>(0 + (i * 11 + 4));
|
Items[i].XPReward = parser.ReadColumn<uint>(4 * 4 + i);
|
||||||
Items[i].HighXPMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 5));
|
Items[i].HighXPMultiplier = parser.ReadColumn<byte>(5 * 4 + i);
|
||||||
Items[i].GilReward = parser.ReadColumn<ushort>(0 + (i * 11 + 6));
|
Items[i].GilReward = parser.ReadColumn<ushort>(6 * 4 + i);
|
||||||
Items[i].HighGilMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 7));
|
Items[i].HighGilMultiplier = parser.ReadColumn<byte>(7 * 4 + i);
|
||||||
Items[i].Unknown8 = parser.ReadColumn<byte>(0 + (i * 11 + 8));
|
Items[i].Unknown8 = parser.ReadColumn<byte>(8 * 4 + i);
|
||||||
Items[i].ScripReward = parser.ReadColumn<byte>(0 + (i * 11 + 9));
|
Items[i].ScripReward = parser.ReadColumn<byte>(9 * 4 + i);
|
||||||
Items[i].HighScripMultiplier = parser.ReadColumn<byte>(0 + (i * 11 + 10));
|
Items[i].HighScripMultiplier = parser.ReadColumn<byte>(10 * 4 + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public static class Colors
|
|||||||
public static readonly Vector4 Quality = new(0.26f, 0.71f, 0.69f, 1f);
|
public static readonly Vector4 Quality = new(0.26f, 0.71f, 0.69f, 1f);
|
||||||
public static readonly Vector4 Durability = new(0.13f, 0.52f, 0.93f, 1f);
|
public static readonly Vector4 Durability = new(0.13f, 0.52f, 0.93f, 1f);
|
||||||
public static readonly Vector4 HQ = new(0.592f, 0.863f, 0.376f, 1f);
|
public static readonly Vector4 HQ = new(0.592f, 0.863f, 0.376f, 1f);
|
||||||
|
public static readonly Vector4 Collectability = new(0.99f, 0.56f, 0.57f, 1f);
|
||||||
public static readonly Vector4 CP = new(0.63f, 0.37f, 0.75f, 1f);
|
public static readonly Vector4 CP = new(0.63f, 0.37f, 0.75f, 1f);
|
||||||
|
|
||||||
private static Vector4 SolverProgressBg => ImGui.ColorConvertU32ToFloat4(ImGui.GetColorU32(ImGuiCol.TableBorderLight));
|
private static Vector4 SolverProgressBg => ImGui.ColorConvertU32ToFloat4(ImGui.GetColorU32(ImGuiCol.TableBorderLight));
|
||||||
@@ -25,6 +26,13 @@ public static class Colors
|
|||||||
new(0.70f, 0.49f, 0.88f, 1f),
|
new(0.70f, 0.49f, 0.88f, 1f),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static readonly Vector4[] CollectabilityThreshold = new Vector4[]
|
||||||
|
{
|
||||||
|
new(0.47f, 0.78f, 0.93f, 1f), // Blue
|
||||||
|
new(0.99f, 0.79f, 0f, 1f), // Yellow
|
||||||
|
new(0.75f, 1f, 0.75f, 1f), // Green
|
||||||
|
};
|
||||||
|
|
||||||
public static (Vector4 Background, Vector4 Foreground) GetSolverProgressColors(int? stageValue) =>
|
public static (Vector4 Background, Vector4 Foreground) GetSolverProgressColors(int? stageValue) =>
|
||||||
stageValue is not { } stage ?
|
stageValue is not { } stage ?
|
||||||
(SolverProgressBg, SolverProgressFgBland) :
|
(SolverProgressBg, SolverProgressFgBland) :
|
||||||
|
|||||||
@@ -5,19 +5,20 @@ using System.Collections.Generic;
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Utility.Numerics;
|
||||||
|
|
||||||
namespace Craftimizer.Utils;
|
namespace Craftimizer.Utils;
|
||||||
|
|
||||||
internal static class DynamicBars
|
internal static class DynamicBars
|
||||||
{
|
{
|
||||||
public readonly record struct BarData(string Name, Vector4 Color, SimulatedMacro.Reliablity.Param? Reliability, float Value, float Max, string? Caption = null, Action<DrawerParams>? CustomDrawer = null)
|
public readonly record struct BarData(string Name, Vector4 Color, SimulatedMacro.Reliablity.Param? Reliability, float Value, float Max, IReadOnlyList<int?>? Collectability = null, string? Caption = null, string? DefaultCaptionSizeText = null, Action<DrawerParams>? CustomDrawer = null)
|
||||||
{
|
{
|
||||||
public BarData(string name, Action<DrawerParams> customDrawer) : this(name, default, null, 0, 0, null, customDrawer)
|
public BarData(string name, Action<DrawerParams> customDrawer) : this(name, default, null, 0, 0, null, null, null, customDrawer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BarData(string name, Vector4 color, float value, float max) : this(name, color, null, value, max, null, null)
|
public BarData(string name, Vector4 color, float value, float max) : this(name, color, null, value, max, null, null, null)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -30,12 +31,17 @@ internal static class DynamicBars
|
|||||||
{
|
{
|
||||||
if (b.CustomDrawer is { })
|
if (b.CustomDrawer is { })
|
||||||
return 0;
|
return 0;
|
||||||
|
var defaultSize = 0f;
|
||||||
|
if (b.DefaultCaptionSizeText is { } defaultCaptionSizeText)
|
||||||
|
defaultSize = ImGui.CalcTextSize(defaultCaptionSizeText).X;
|
||||||
if (b.Caption is { } caption)
|
if (b.Caption is { } caption)
|
||||||
return ImGui.CalcTextSize(caption).X;
|
return Math.Max(ImGui.CalcTextSize(caption).X, defaultSize);
|
||||||
// max (sp/2) "/" (sp/2) max
|
// max (sp/2) "/" (sp/2) max
|
||||||
return Math.Max(ImGui.CalcTextSize($"{b.Value:0}").X, ImGui.CalcTextSize($"{b.Max:0}").X) * 2
|
return Math.Max(
|
||||||
|
Math.Max(ImGui.CalcTextSize($"{b.Value:0}").X, ImGui.CalcTextSize($"{b.Max:0}").X) * 2
|
||||||
+ ImGui.GetStyle().ItemSpacing.X
|
+ ImGui.GetStyle().ItemSpacing.X
|
||||||
+ ImGui.CalcTextSize("/").X;
|
+ ImGui.CalcTextSize("/").X,
|
||||||
|
defaultSize);
|
||||||
});
|
});
|
||||||
|
|
||||||
public static void Draw(IEnumerable<BarData> bars, float? textSize = null)
|
public static void Draw(IEnumerable<BarData> bars, float? textSize = null)
|
||||||
@@ -54,8 +60,40 @@ internal static class DynamicBars
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var pos = ImGui.GetCursorPos();
|
var pos = ImGui.GetCursorPos();
|
||||||
|
var screenPos = ImGui.GetCursorScreenPos();
|
||||||
using (var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color))
|
using (var color = ImRaii.PushColor(ImGuiCol.PlotHistogram, bar.Color))
|
||||||
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
ImGui.ProgressBar(Math.Clamp(bar.Value / bar.Max, 0, 1), new(barSize, ImGui.GetFrameHeight()), string.Empty);
|
||||||
|
var passedCollectabilityColor = 0;
|
||||||
|
if (bar.Collectability is { } collectability)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
var rounding = ImGui.GetStyle().FrameRounding;
|
||||||
|
var height = ImGui.GetFrameHeight();
|
||||||
|
foreach (var (c, color) in collectability.Zip(Colors.CollectabilityThreshold))
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if (c is not { } threshold)
|
||||||
|
continue;
|
||||||
|
var offset = barSize * threshold / bar.Max;
|
||||||
|
var isLast = i == collectability.Count;
|
||||||
|
var offsetNext = isLast ? barSize : barSize * collectability[i]!.Value / bar.Max;
|
||||||
|
var passedThreshold = bar.Value >= threshold;
|
||||||
|
if (passedThreshold)
|
||||||
|
passedCollectabilityColor = i;
|
||||||
|
ImGui.GetWindowDrawList().AddRectFilled(
|
||||||
|
screenPos + new Vector2(offset, 0),
|
||||||
|
screenPos + new Vector2(offsetNext, height),
|
||||||
|
ImGui.GetColorU32(color.WithW(passedThreshold ? 0.6f : 0.2f)),
|
||||||
|
isLast ? rounding : 0
|
||||||
|
);
|
||||||
|
ImGui.GetWindowDrawList().AddLine(
|
||||||
|
screenPos + new Vector2(offset, 0),
|
||||||
|
screenPos + new Vector2(offset, height),
|
||||||
|
ImGui.GetColorU32(color),
|
||||||
|
Math.Max(passedThreshold ? 3 : 1.5f, rounding / 2f)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenOverlapped))
|
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenOverlapped))
|
||||||
{
|
{
|
||||||
if (bar.Reliability is { } reliability)
|
if (bar.Reliability is { } reliability)
|
||||||
@@ -75,6 +113,7 @@ internal static class DynamicBars
|
|||||||
}
|
}
|
||||||
ImGui.SameLine(0, spacing);
|
ImGui.SameLine(0, spacing);
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
|
using var _color = ImRaii.PushColor(ImGuiCol.Text, passedCollectabilityColor != 0 ? Colors.CollectabilityThreshold[passedCollectabilityColor - 1] : default, passedCollectabilityColor != 0);
|
||||||
if (bar.Caption is { } caption)
|
if (bar.Caption is { } caption)
|
||||||
ImGuiUtils.TextRight(caption, textSize.Value);
|
ImGuiUtils.TextRight(caption, textSize.Value);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public sealed record RecipeData
|
|||||||
case 4:
|
case 4:
|
||||||
var data4 = LuminaSheets.SharlayanCraftWorksSupplySheet.GetRow(Recipe.Unknown46);
|
var data4 = LuminaSheets.SharlayanCraftWorksSupplySheet.GetRow(Recipe.Unknown46);
|
||||||
if (data4 == null)
|
if (data4 == null)
|
||||||
goto default;
|
break;
|
||||||
foreach (var item in data4.Items)
|
foreach (var item in data4.Items)
|
||||||
{
|
{
|
||||||
if (item.Item.Row == Recipe.ItemResult.Row)
|
if (item.Item.Row == Recipe.ItemResult.Row)
|
||||||
|
|||||||
@@ -189,8 +189,6 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
if (modifiedInput)
|
if (modifiedInput)
|
||||||
RecalculateState();
|
RecalculateState();
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
using (var table = ImRaii.Table("macroInfo", 2, ImGuiTableFlags.BordersInnerV | ImGuiTableFlags.SizingStretchSame))
|
using (var table = ImRaii.Table("macroInfo", 2, ImGuiTableFlags.BordersInnerV | ImGuiTableFlags.SizingStretchSame))
|
||||||
{
|
{
|
||||||
if (table)
|
if (table)
|
||||||
@@ -1052,14 +1050,14 @@ public sealed class MacroEditor : Window, IDisposable
|
|||||||
new("Condition", DrawCondition)
|
new("Condition", DrawCondition)
|
||||||
};
|
};
|
||||||
if (RecipeData.Recipe.ItemResult.Value!.IsCollectable)
|
if (RecipeData.Recipe.ItemResult.Value!.IsCollectable)
|
||||||
datas.Add(new("Collectability", Colors.HQ, Reliability.ParamScore, State.Collectability, State.MaxCollectability, $"{State.Collectability}"));
|
datas.Add(new("Collectability", Colors.Collectability, Reliability.ParamScore, State.Collectability, State.MaxCollectability, RecipeData.CollectableThresholds, $"{State.Collectability}", $"{State.MaxCollectability:0}"));
|
||||||
else if (RecipeData.Recipe.RequiredQuality > 0)
|
else if (RecipeData.Recipe.RequiredQuality > 0)
|
||||||
{
|
{
|
||||||
var qualityPercent = (float)State.Quality / RecipeData.Recipe.RequiredQuality * 100;
|
var qualityPercent = (float)State.Quality / RecipeData.Recipe.RequiredQuality * 100;
|
||||||
datas.Add(new("Quality %", Colors.HQ, Reliability.ParamScore, qualityPercent, 100, $"{qualityPercent:0}%"));
|
datas.Add(new("Quality %", Colors.HQ, Reliability.ParamScore, qualityPercent, 100, null, $"{qualityPercent:0}%"));
|
||||||
}
|
}
|
||||||
else if (RecipeData.RecipeInfo.MaxQuality > 0)
|
else if (RecipeData.RecipeInfo.MaxQuality > 0)
|
||||||
datas.Add(new("HQ %", Colors.HQ, Reliability.ParamScore, State.HQPercent, 100, $"{State.HQPercent}%"));
|
datas.Add(new("HQ %", Colors.HQ, Reliability.ParamScore, State.HQPercent, 100, null, $"{State.HQPercent}%"));
|
||||||
DynamicBars.Draw(datas);
|
DynamicBars.Draw(datas);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|||||||
@@ -349,14 +349,14 @@ public sealed unsafe class SynthHelper : Window, IDisposable
|
|||||||
new("Durability", Colors.Durability, state.Durability, RecipeData.RecipeInfo.MaxDurability),
|
new("Durability", Colors.Durability, state.Durability, RecipeData.RecipeInfo.MaxDurability),
|
||||||
};
|
};
|
||||||
if (RecipeData.Recipe.ItemResult.Value!.IsCollectable)
|
if (RecipeData.Recipe.ItemResult.Value!.IsCollectable)
|
||||||
halfBars.Add(new("Collectability", Colors.HQ, reliability.ParamScore, state.Collectability, state.MaxCollectability, $"{state.Collectability}", null));
|
halfBars.Add(new("Collectability", Colors.Collectability, reliability.ParamScore, state.Collectability, state.MaxCollectability, RecipeData.CollectableThresholds, $"{state.Collectability}", $"{state.MaxCollectability:0}"));
|
||||||
else if (RecipeData.Recipe.RequiredQuality > 0)
|
else if (RecipeData.Recipe.RequiredQuality > 0)
|
||||||
{
|
{
|
||||||
var qualityPercent = (float)state.Quality / RecipeData.Recipe.RequiredQuality * 100;
|
var qualityPercent = (float)state.Quality / RecipeData.Recipe.RequiredQuality * 100;
|
||||||
halfBars.Add(new("Quality %", Colors.HQ, reliability.ParamScore, qualityPercent, 100, $"{qualityPercent:0}%", null));
|
halfBars.Add(new("Quality %", Colors.HQ, reliability.ParamScore, qualityPercent, 100, null, $"{qualityPercent:0}%", null));
|
||||||
}
|
}
|
||||||
else if (RecipeData.RecipeInfo.MaxQuality > 0)
|
else if (RecipeData.RecipeInfo.MaxQuality > 0)
|
||||||
halfBars.Add(new("HQ %", Colors.HQ, reliability.ParamScore, state.HQPercent, 100, $"{state.HQPercent}%", null));
|
halfBars.Add(new("HQ %", Colors.HQ, reliability.ParamScore, state.HQPercent, 100, null, $"{state.HQPercent}%", null));
|
||||||
|
|
||||||
if (halfBars.Count > 1)
|
if (halfBars.Count > 1)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user