API10 updates

This commit is contained in:
Asriel Camora
2024-06-30 18:33:57 -07:00
parent 7236d5a382
commit 2c0978f76b
25 changed files with 202 additions and 242 deletions
+8 -2
View File
@@ -223,7 +223,13 @@ public partial class Configuration
[JsonSourceGenerationOptions(Converters = [typeof(StoredActionTypeConverter)])]
[JsonSerializable(typeof(Configuration))]
internal sealed partial class JsonContext : JsonSerializerContext { }
internal sealed partial class JsonContext : JsonSerializerContext
{
public static JsonSerializerOptions DeserializeOptions { get; } = new()
{
Converters = { new StoredActionTypeConverter() }
};
}
public void Save()
{
@@ -240,7 +246,7 @@ public partial class Configuration
using var stream = f.OpenRead();
// System.InvalidOperationException: Setting init-only properties is not supported in source generation mode.
return JsonSerializer.Deserialize<Configuration>(stream, JsonContext.Default.Options) ?? new();
return JsonSerializer.Deserialize<Configuration>(stream, JsonContext.DeserializeOptions) ?? new();
}
return new();
}
+4 -3
View File
@@ -38,10 +38,11 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.12" />
<PackageReference Include="ExdSheets" Version="1.0.0" />
<PackageReference Include="DalamudPackager" Version="2.1.13" />
<PackageReference Include="ExdSheets" Version="1.1.0" />
<PackageReference Include="Lumina" Version="3.15.2" ExcludeAssets="all" />
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.157">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.159">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
+1 -1
View File
@@ -1,4 +1,4 @@
using Dalamud;
using Dalamud.Game;
using ExdSheets;
using Lumina.Excel;
using System.Collections.Concurrent;
+5 -9
View File
@@ -5,7 +5,8 @@ using Craftimizer.Simulator.Actions;
using Craftimizer.Utils;
using Craftimizer.Windows;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using System;
@@ -19,7 +20,7 @@ public sealed class Plugin : IDalamudPlugin
public string Version { get; }
public string Author { get; }
public string BuildConfiguration { get; }
public IDalamudTextureWrap Icon { get; }
public ISharedImmediateTexture Icon { get; }
public WindowSystem WindowSystem { get; }
public Settings SettingsWindow { get; }
@@ -32,11 +33,10 @@ public sealed class Plugin : IDalamudPlugin
public Configuration Configuration { get; }
public Hooks Hooks { get; }
public Chat Chat { get; }
public IconManager IconManager { get; }
public CommunityMacros CommunityMacros { get; }
public AttributeCommandManager AttributeCommandManager { get; }
public Plugin(DalamudPluginInterface pluginInterface)
public Plugin(IDalamudPluginInterface pluginInterface)
{
Service.Initialize(this, pluginInterface);
@@ -44,7 +44,6 @@ public sealed class Plugin : IDalamudPlugin
Configuration = Configuration.Load();
Hooks = new();
Chat = new();
IconManager = new();
CommunityMacros = new();
AttributeCommandManager = new();
@@ -156,10 +155,8 @@ public sealed class Plugin : IDalamudPlugin
public IActiveNotification DisplayNotification(Notification notification)
{
notification.InitialDuration = TimeSpan.FromSeconds(5);
var ret = Service.NotificationManager.AddNotification(notification);
if (notification.Icon != null)
ret.SetIconTexture(Icon);
// ret.SetIconTexture(Icon.RentAsync().ContinueWith(t => (IDalamudTextureWrap?)t));
return ret;
}
@@ -173,6 +170,5 @@ public sealed class Plugin : IDalamudPlugin
EditorWindow?.Dispose();
ClipboardWindow?.Dispose();
Hooks.Dispose();
IconManager.Dispose();
}
}
+2 -3
View File
@@ -11,7 +11,7 @@ namespace Craftimizer.Plugin;
public sealed class Service
{
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
[PluginService] public static DalamudPluginInterface PluginInterface { get; private set; }
[PluginService] public static IDalamudPluginInterface PluginInterface { get; private set; }
[PluginService] public static ICommandManager CommandManager { get; private set; }
[PluginService] public static IObjectTable Objects { get; private set; }
[PluginService] public static ISigScanner SigScanner { get; private set; }
@@ -30,11 +30,10 @@ public sealed class Service
public static Configuration Configuration => Plugin.Configuration;
public static WindowSystem WindowSystem => Plugin.WindowSystem;
public static Chat Chat => Plugin.Chat;
public static IconManager IconManager => Plugin.IconManager;
public static CommunityMacros CommunityMacros => Plugin.CommunityMacros;
#pragma warning restore CS8618
internal static void Initialize(Plugin plugin, DalamudPluginInterface iface)
internal static void Initialize(Plugin plugin, IDalamudPluginInterface iface)
{
Plugin = plugin;
iface.Create<Service>();
+9 -8
View File
@@ -1,7 +1,6 @@
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface.Internal;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using ExdSheets;
@@ -15,6 +14,8 @@ using ActionType = Craftimizer.Simulator.Actions.ActionType;
using ClassJob = Craftimizer.Simulator.ClassJob;
using Condition = Craftimizer.Simulator.Condition;
using Status = ExdSheets.Status;
using Dalamud.Interface.Textures;
using Craftimizer.Utils;
namespace Craftimizer.Plugin;
@@ -86,15 +87,15 @@ internal static class ActionUtils
return "Unknown";
}
public static IDalamudTextureWrap GetIcon(this ActionType me, ClassJob classJob)
public static ISharedImmediateTexture GetIcon(this ActionType me, ClassJob classJob)
{
var (craftAction, action) = GetActionRow(me, classJob);
if (craftAction != null)
return Service.IconManager.GetIcon(craftAction.Icon);
return IconManager.GetIcon(craftAction.Icon);
if (action != null)
return Service.IconManager.GetIcon(action.Icon);
return IconManager.GetIcon(action.Icon);
// Old "Steady Hand" action icon
return Service.IconManager.GetIcon(1953);
return IconManager.GetIcon(1953);
}
public static ActionType? GetActionTypeFromId(uint actionId, ClassJob classJob, bool isCraftAction)
@@ -151,7 +152,7 @@ internal static class ClassJobUtils
LuminaSheets.ClassJobSheet.GetRow(me.GetClassJobIndex())!.ExpArrayIndex;
public static unsafe short GetPlayerLevel(this ClassJob me) =>
PlayerState.Instance()->ClassJobLevelArray[me.GetExpArrayIdx()];
PlayerState.Instance()->ClassJobLevels[me.GetExpArrayIdx()];
public static unsafe bool CanPlayerUseManipulation(this ClassJob me) =>
UIState.Instance()->IsUnlockLinkUnlockedOrQuestCompleted(ActionType.Manipulation.GetActionRow(me).Action!.UnlockLink.Row);
@@ -330,8 +331,8 @@ internal static class EffectUtils
return (ushort)iconId;
}
public static IDalamudTextureWrap GetIcon(this EffectType me, int strength) =>
Service.IconManager.GetIcon(me.GetIconId(strength));
public static ISharedImmediateTexture GetIcon(this EffectType me, int strength) =>
IconManager.GetIcon(me.GetIconId(strength));
public static string GetTooltip(this EffectType me, int strength, int duration)
{
+2 -2
View File
@@ -29,9 +29,9 @@ public sealed class AttributeCommandManager : IDisposable
var takesParams = method.GetParameters().Length != 0;
CommandInfo.HandlerDelegate handler;
IReadOnlyCommandInfo.HandlerDelegate handler;
if (takesParams)
handler = method.CreateDelegate<CommandInfo.HandlerDelegate>(target);
handler = method.CreateDelegate<IReadOnlyCommandInfo.HandlerDelegate>(target);
else
{
var invoker = method.CreateDelegate<Action>(target);
+4 -10
View File
@@ -1,6 +1,5 @@
using Craftimizer.Plugin;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI;
using System;
@@ -10,15 +9,11 @@ namespace Craftimizer.Utils;
// https://github.com/Caraxi/SimpleTweaksPlugin/blob/0973b93931cdf8a1b01153984d62f76d998747ff/Utility/ChatHelper.cs#L17
public sealed unsafe class Chat
{
private delegate void SendChatDelegate(UIModule* uiModule, Utf8String* message, Utf8String* historyMessage, bool pushToHistory);
private delegate void SanitizeStringDelegate(Utf8String* data, int flags, Utf8String* buffer);
private delegate void SendChatDelegate(UIModule* @this, Utf8String* message, Utf8String* historyMessage, bool pushToHistory);
[Signature("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9")]
private readonly SendChatDelegate sendChat = null!;
[Signature("E8 ?? ?? ?? ?? EB 0A 48 8D 4C 24 ?? E8 ?? ?? ?? ?? 48 8D 8D")]
private readonly SanitizeStringDelegate sanitizeString = null!;
public Chat()
{
Service.GameInteropProvider.InitializeFromAttributes(this);
@@ -26,12 +21,11 @@ public sealed unsafe class Chat
public void SendMessage(string message)
{
if (string.IsNullOrWhiteSpace(message))
throw new ArgumentException("Message is empty", nameof(message));
ArgumentException.ThrowIfNullOrWhiteSpace(message);
var str = Utf8String.FromString(message);
sanitizeString(str, 0x27F, null);
sendChat(Framework.Instance()->GetUiModule(), str, null, false);
str->SanitizeString(0x27F, null);
sendChat(UIModule.Instance(), str, null, false);
str->Dtor(true);
}
}
+16 -16
View File
@@ -12,13 +12,13 @@ public static unsafe class Gearsets
{
public record struct GearsetStats(int CP, int Craftsmanship, int Control);
public record struct GearsetMateria(ushort Type, ushort Grade);
public record struct GearsetItem(uint itemId, bool isHq, GearsetMateria[] materia);
public record struct GearsetItem(uint ItemId, bool IsHq, GearsetMateria[] Materia);
private static readonly GearsetStats BaseStats = new(180, 0, 0);
public const uint ParamCP = 11;
public const uint ParamCraftsmanship = 70;
public const uint ParamControl = 71;
public const int ParamCP = 11;
public const int ParamCraftsmanship = 70;
public const int ParamControl = 71;
private static readonly int[] LevelToCLvlLUT;
@@ -44,26 +44,26 @@ public static unsafe class Gearsets
for (var i = 0; i < container->Size; ++i)
{
var item = container->Items[i];
items[i] = new(item.ItemID, item.Flags.HasFlag(InventoryItem.ItemFlags.HQ), GetMaterias(item.Materia, item.MateriaGrade));
items[i] = new(item.ItemId, item.Flags.HasFlag(InventoryItem.ItemFlags.HighQuality), GetMaterias(item.Materia, item.MateriaGrades));
}
return items;
}
public static GearsetItem[] GetGearsetItems(RaptureGearsetModule.GearsetEntry* entry)
{
var gearsetItems = entry->ItemsSpan;
var gearsetItems = entry->Items;
var items = new GearsetItem[14];
for (var i = 0; i < 14; ++i)
{
var item = gearsetItems[i];
items[i] = new(item.ItemID % 1000000, item.ItemID > 1000000, GetMaterias(item.Materia, item.MateriaGrade));
items[i] = new(item.ItemId % 1000000, item.ItemId > 1000000, GetMaterias(item.Materia, item.MateriaGrades));
}
return items;
}
public static GearsetStats CalculateGearsetItemStats(GearsetItem gearsetItem)
{
var item = LuminaSheets.ItemSheet.GetRow(gearsetItem.itemId)!;
var item = LuminaSheets.ItemSheet.GetRow(gearsetItem.ItemId)!;
int cp = 0, craftsmanship = 0, control = 0;
@@ -79,11 +79,11 @@ public static unsafe class Gearsets
foreach (var statIncrease in item.BaseParam.Zip(item.BaseParamValue))
IncreaseStat(statIncrease.First.Row, statIncrease.Second);
if (gearsetItem.isHq)
if (gearsetItem.IsHq)
foreach (var statIncrease in item.BaseParamSpecial.Zip(item.BaseParamValueSpecial))
IncreaseStat(statIncrease.First.Row, statIncrease.Second);
foreach (var gearsetMateria in gearsetItem.materia)
foreach (var gearsetMateria in gearsetItem.Materia)
{
if (gearsetMateria.Type == 0)
continue;
@@ -131,23 +131,23 @@ public static unsafe class Gearsets
};
public static bool IsItem(GearsetItem item, uint itemId) =>
item.itemId == itemId;
item.ItemId == itemId;
public static bool IsSpecialistSoulCrystal(GearsetItem item)
{
if (item.itemId == 0)
if (item.ItemId == 0)
return false;
var luminaItem = LuminaSheets.ItemSheet.GetRow(item.itemId)!;
var luminaItem = LuminaSheets.ItemSheet.GetRow(item.ItemId)!;
// Soul Crystal ItemUICategory DoH Category
return luminaItem.ItemUICategory.Row == 62 && luminaItem.ClassJobUse.Value!.ClassJobCategory.Row == 33;
}
public static bool IsSplendorousTool(GearsetItem item) =>
LuminaSheets.ItemSheetEnglish.GetRow(item.itemId)!.Description.ToDalamudString().TextValue.Contains("Increases to quality are 1.75 times higher than normal when material condition is Good.", StringComparison.Ordinal);
LuminaSheets.ItemSheetEnglish.GetRow(item.ItemId)!.Description.ToDalamudString().TextValue.Contains("Increases to quality are 1.75 times higher than normal when material condition is Good.", StringComparison.Ordinal);
public static int CalculateCLvl(int level) =>
(level > 0 && level <= 90) ?
(level > 0 && level <= 100) ?
LevelToCLvlLUT[level - 1] :
throw new ArgumentOutOfRangeException(nameof(level), level, "Level is out of range.");
@@ -197,7 +197,7 @@ public static unsafe class Gearsets
return cap == 0 ? int.MaxValue : cap;
}
private static GearsetMateria[] GetMaterias(ushort* types, byte* grades)
private static GearsetMateria[] GetMaterias(ReadOnlySpan<ushort> types, ReadOnlySpan<byte> grades)
{
var materia = new GearsetMateria[5];
for (var i = 0; i < 5; ++i)
+10 -64
View File
@@ -1,81 +1,27 @@
using Craftimizer.Plugin;
using Dalamud.Interface.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Interface.Textures;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Craftimizer.Utils;
public sealed class IconManager : IDisposable
public static class IconManager
{
private readonly Dictionary<uint, IDalamudTextureWrap> iconCache = [];
private readonly Dictionary<uint, IDalamudTextureWrap> hqIconCache = [];
private readonly Dictionary<string, IDalamudTextureWrap> textureCache = [];
private readonly Dictionary<string, IDalamudTextureWrap> assemblyCache = [];
public IDalamudTextureWrap GetIcon(uint id)
public static ISharedImmediateTexture GetIcon(uint id, bool isHq = false)
{
if (!iconCache.TryGetValue(id, out var ret))
iconCache.Add(id, ret = Service.TextureProvider.GetIcon(id) ??
throw new ArgumentException($"Invalid icon id {id}", nameof(id)));
return ret;
return Service.TextureProvider.GetFromGameIcon(new GameIconLookup(id, itemHq: isHq));
}
public IDalamudTextureWrap GetHqIcon(uint id, bool isHq = true)
public static ISharedImmediateTexture GetTexture(string path)
{
if (!isHq)
return GetIcon(id);
if (!hqIconCache.TryGetValue(id, out var ret))
hqIconCache.Add(id, ret = Service.TextureProvider.GetIcon(id, ITextureProvider.IconFlags.HiRes | ITextureProvider.IconFlags.ItemHighQuality) ??
throw new ArgumentException($"Invalid hq icon id {id}", nameof(id)));
return ret;
return Service.TextureProvider.GetFromGame(path);
}
public IDalamudTextureWrap GetTexture(string path)
public static ISharedImmediateTexture GetAssemblyTexture(string filename)
{
if (!textureCache.TryGetValue(path, out var ret))
textureCache.Add(path, ret = Service.TextureProvider.GetTextureFromGame(path) ??
throw new ArgumentException($"Invalid texture {path}", nameof(path)));
return ret;
return Service.TextureProvider.GetFromManifestResource(Assembly.GetExecutingAssembly(), $"Craftimizer.{filename}");
}
public IDalamudTextureWrap GetAssemblyTexture(string filename)
{
if (!assemblyCache.TryGetValue(filename, out var ret))
assemblyCache.Add(filename, ret = GetAssemblyTextureInternal(filename));
return ret;
}
private static IDalamudTextureWrap GetAssemblyTextureInternal(string filename)
{
var assembly = Assembly.GetExecutingAssembly();
byte[] iconData;
using (var stream = assembly.GetManifestResourceStream($"Craftimizer.{filename}") ?? throw new InvalidDataException($"Could not load resource {filename}"))
{
iconData = new byte[stream.Length];
_ = stream.Read(iconData);
}
return Service.PluginInterface.UiBuilder.LoadImage(iconData);
}
public void Dispose()
{
foreach (var image in iconCache.Values)
image.Dispose();
iconCache.Clear();
foreach (var image in hqIconCache.Values)
image.Dispose();
hqIconCache.Clear();
foreach (var image in textureCache.Values)
image.Dispose();
textureCache.Clear();
foreach (var image in assemblyCache.Values)
image.Dispose();
assemblyCache.Clear();
}
public static nint GetHandle(this ISharedImmediateTexture me) =>
me.GetWrapOrEmpty().ImGuiHandle;
}
+1 -1
View File
@@ -1,7 +1,7 @@
using Craftimizer.Plugin;
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using FFXIVClientStructs.FFXIV.Client.System.Memory;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
+1 -1
View File
@@ -1,6 +1,5 @@
using Craftimizer.Plugin;
using Dalamud.Interface;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
using ImGuiNET;
@@ -8,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Numerics;
using System.Linq;
using Dalamud.Interface.ImGuiNotification;
namespace Craftimizer.Windows;
+56 -49
View File
@@ -8,9 +8,11 @@ using Dalamud.Game.Text;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
using Dalamud.Utility;
@@ -42,7 +44,7 @@ public sealed class MacroEditor : Window, IDisposable
Craftsmanship = Math.Clamp(value.Craftsmanship, 0, 9000),
Control = Math.Clamp(value.Control, 0, 9000),
CP = Math.Clamp(value.CP, 180, 1000),
Level = Math.Clamp(value.Level, 1, 90),
Level = Math.Clamp(value.Level, 1, 100),
CLvl = Gearsets.CalculateCLvl(value.Level),
};
}
@@ -91,16 +93,16 @@ public sealed class MacroEditor : Window, IDisposable
private Solver.Solver? SolverObject { get; set; }
private bool SolverRunning => SolverTokenSource != null;
private IDalamudTextureWrap ExpertBadge { get; }
private IDalamudTextureWrap CollectibleBadge { get; }
private IDalamudTextureWrap SplendorousBadge { get; }
private IDalamudTextureWrap SpecialistBadge { get; }
private IDalamudTextureWrap NoManipulationBadge { get; }
private IDalamudTextureWrap ManipulationBadge { get; }
private IDalamudTextureWrap WellFedBadge { get; }
private IDalamudTextureWrap MedicatedBadge { get; }
private IDalamudTextureWrap InControlBadge { get; }
private IDalamudTextureWrap EatFromTheHandBadge { get; }
private ISharedImmediateTexture ExpertBadge { get; }
private ISharedImmediateTexture CollectibleBadge { get; }
private ISharedImmediateTexture SplendorousBadge { get; }
private ISharedImmediateTexture SpecialistBadge { get; }
private ISharedImmediateTexture NoManipulationBadge { get; }
private ISharedImmediateTexture ManipulationBadge { get; }
private ISharedImmediateTexture WellFedBadge { get; }
private ISharedImmediateTexture MedicatedBadge { get; }
private ISharedImmediateTexture InControlBadge { get; }
private ISharedImmediateTexture EatFromTheHandBadge { get; }
private IFontHandle AxisFont { get; }
private string popupSaveAsMacroName = string.Empty;
@@ -125,16 +127,16 @@ public sealed class MacroEditor : Window, IDisposable
foreach (var action in DefaultActions)
AddStep(action);
ExpertBadge = Service.IconManager.GetAssemblyTexture("Graphics.expert_badge.png");
CollectibleBadge = Service.IconManager.GetAssemblyTexture("Graphics.collectible_badge.png");
SplendorousBadge = Service.IconManager.GetAssemblyTexture("Graphics.splendorous.png");
SpecialistBadge = Service.IconManager.GetAssemblyTexture("Graphics.specialist.png");
NoManipulationBadge = Service.IconManager.GetAssemblyTexture("Graphics.no_manip.png");
ExpertBadge = IconManager.GetAssemblyTexture("Graphics.expert_badge.png");
CollectibleBadge = IconManager.GetAssemblyTexture("Graphics.collectible_badge.png");
SplendorousBadge = IconManager.GetAssemblyTexture("Graphics.splendorous.png");
SpecialistBadge = IconManager.GetAssemblyTexture("Graphics.specialist.png");
NoManipulationBadge = IconManager.GetAssemblyTexture("Graphics.no_manip.png");
ManipulationBadge = ActionType.Manipulation.GetIcon(RecipeData.ClassJob);
WellFedBadge = Service.IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(48)!.Icon);
MedicatedBadge = Service.IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(49)!.Icon);
InControlBadge = Service.IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(356)!.Icon);
EatFromTheHandBadge = Service.IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(357)!.Icon);
WellFedBadge = IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(48)!.Icon);
MedicatedBadge = IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(49)!.Icon);
InControlBadge = IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(356)!.Icon);
EatFromTheHandBadge = IconManager.GetIcon(LuminaSheets.StatusSheet.GetRow(357)!.Icon);
AxisFont = Service.PluginInterface.UiBuilder.FontAtlas.NewGameFontHandle(new(GameFontFamilyAndSize.Axis14));
IsOpen = true;
@@ -223,7 +225,7 @@ public sealed class MacroEditor : Window, IDisposable
uv0 /= new Vector2(56);
uv1 /= new Vector2(56);
ImGui.Image(Service.IconManager.GetIcon(RecipeData.ClassJob.GetIconId()).ImGuiHandle, new Vector2(imageSize), uv0, uv1);
ImGui.Image(IconManager.GetIcon(RecipeData.ClassJob.GetIconId()).GetHandle(), new Vector2(imageSize), uv0, uv1);
ImGui.SameLine(0, 5);
AxisFont.Text(textClassName);
@@ -274,7 +276,7 @@ public sealed class MacroEditor : Window, IDisposable
ImGui.TableSetupColumn("col3", ImGuiTableColumnFlags.WidthStretch, 2);
ImGui.TableNextColumn();
var levelTextWidth = ImGui.CalcTextSize(SqText.ToLevelString(99)).X + ImGui.GetStyle().FramePadding.X * 2 + 5;
var levelTextWidth = ImGui.CalcTextSize(SqText.ToLevelString(100)).X + ImGui.GetStyle().FramePadding.X * 2 + 5;
ImGuiUtils.AlignCentered(
ImGui.CalcTextSize(SqText.LevelPrefix.ToIconString()).X + 5 +
levelTextWidth);
@@ -287,14 +289,14 @@ public sealed class MacroEditor : Window, IDisposable
bool textChanged;
unsafe
{
textChanged = ImGui.InputText("##levelText", ref levelText, 8, ImGuiInputTextFlags.CallbackCharFilter | ImGuiInputTextFlags.AutoSelectAll, LevelInputCallback);
textChanged = ImGui.InputText("##levelText", ref levelText, 12, ImGuiInputTextFlags.CallbackCharFilter | ImGuiInputTextFlags.AutoSelectAll, LevelInputCallback);
}
if (textChanged)
CharacterStats = CharacterStats with
{
Level =
SqText.TryParseLevelString(levelText, out var newLevel)
? Math.Clamp(newLevel, 1, 90)
? Math.Clamp(newLevel, 1, 100)
: 1
};
if (ImGui.IsItemHovered())
@@ -312,7 +314,7 @@ public sealed class MacroEditor : Window, IDisposable
{
var v = CharacterStats.HasSplendorousBuff;
var tint = v ? Vector4.One : disabledTint;
if (ImGui.ImageButton(SplendorousBadge.ImGuiHandle, new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
if (ImGui.ImageButton(SplendorousBadge.GetHandle(), new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
CharacterStats = CharacterStats with { HasSplendorousBuff = !v };
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
@@ -330,7 +332,7 @@ public sealed class MacroEditor : Window, IDisposable
using (var d = ImRaii.Disabled(specialistLevel > CharacterStats.Level))
{
var tint = new Vector4(0.99f, 0.97f, 0.62f, 1f) * (v ? Vector4.One : disabledTint);
if (ImGui.ImageButton(SpecialistBadge.ImGuiHandle, new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
if (ImGui.ImageButton(SpecialistBadge.GetHandle(), new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
{
v = !v;
newIsSpecialist = v;
@@ -346,7 +348,7 @@ public sealed class MacroEditor : Window, IDisposable
{
var v = CharacterStats.CanUseManipulation && manipLevel <= CharacterStats.Level;
var tint = (v || manipLevel > CharacterStats.Level) ? disabledTint : Vector4.One;
if (ImGui.ImageButton(v ? ManipulationBadge.ImGuiHandle : NoManipulationBadge.ImGuiHandle, new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
if (ImGui.ImageButton(v ? ManipulationBadge.GetHandle() : NoManipulationBadge.GetHandle(), new Vector2(imageButtonSize), default, Vector2.One, imageButtonPadding, default, tint))
CharacterStats = CharacterStats with { CanUseManipulation = !v };
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
@@ -356,8 +358,9 @@ public sealed class MacroEditor : Window, IDisposable
ImGui.TableNextColumn();
(uint ItemId, bool HQ)? newFoodBuff = null;
var buffImageSize = new Vector2(imageSize * WellFedBadge.Width / WellFedBadge.Height, imageSize);
ImGui.Image(WellFedBadge.ImGuiHandle, buffImageSize);
var buffBadge = WellFedBadge.GetWrapOrEmpty();
var buffImageSize = new Vector2(imageSize * buffBadge.Width / buffBadge.Height, imageSize);
ImGui.Image(buffBadge.ImGuiHandle, buffImageSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip("Food");
ImGui.SameLine(0, 5);
@@ -392,8 +395,9 @@ public sealed class MacroEditor : Window, IDisposable
}
(uint ItemId, bool HQ)? newMedicineBuff = null;
buffImageSize = new Vector2(imageSize * MedicatedBadge.Width / MedicatedBadge.Height, imageSize);
ImGui.Image(MedicatedBadge.ImGuiHandle, buffImageSize);
buffBadge = MedicatedBadge.GetWrapOrEmpty();
buffImageSize = new Vector2(imageSize * buffBadge.Width / buffBadge.Height, imageSize);
ImGui.Image(buffBadge.ImGuiHandle, buffImageSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip("Medicine");
ImGui.SameLine(0, 5);
@@ -430,8 +434,9 @@ public sealed class MacroEditor : Window, IDisposable
ImGui.TableNextColumn();
int? newFCCraftsmanshipBuff = null;
buffImageSize = new Vector2(imageSize * MedicatedBadge.Width / MedicatedBadge.Height, imageSize);
ImGui.Image(EatFromTheHandBadge.ImGuiHandle, buffImageSize);
buffBadge = EatFromTheHandBadge.GetWrapOrEmpty();
buffImageSize = new Vector2(imageSize * buffBadge.Width / buffBadge.Height, imageSize);
ImGui.Image(buffBadge.ImGuiHandle, buffImageSize);
var fcBuffName = "Eat from the Hand";
var fcStatName = "Craftsmanship";
if (ImGui.IsItemHovered())
@@ -458,8 +463,9 @@ public sealed class MacroEditor : Window, IDisposable
}
int? newFCControlBuff = null;
buffImageSize = new Vector2(imageSize * MedicatedBadge.Width / MedicatedBadge.Height, imageSize);
ImGui.Image(InControlBadge.ImGuiHandle, buffImageSize);
buffBadge = InControlBadge.GetWrapOrEmpty();
buffImageSize = new Vector2(imageSize * buffBadge.Width / buffBadge.Height, imageSize);
ImGui.Image(buffBadge.ImGuiHandle, buffImageSize);
fcBuffName = "In Control";
fcStatName = "Control";
if (ImGui.IsItemHovered())
@@ -709,7 +715,8 @@ public sealed class MacroEditor : Window, IDisposable
var isCollectable = RecipeData.Recipe.ItemResult.Value!.IsCollectable;
var imageSize = ImGui.GetFrameHeight();
var textSize = ImGui.GetFontSize();
var badgeSize = new Vector2(textSize * ExpertBadge.Width / ExpertBadge.Height, textSize);
var badge = ExpertBadge.GetWrapOrEmpty();
var badgeSize = new Vector2(textSize * badge.Width / badge.Height, textSize);
var badgeOffset = (imageSize - badgeSize.Y) / 2;
var rightSideWidth =
@@ -719,7 +726,7 @@ public sealed class MacroEditor : Window, IDisposable
(isExpert ? badgeSize.X + 3 : 0);
ImGui.AlignTextToFramePadding();
ImGui.Image(Service.IconManager.GetIcon(RecipeData.Recipe.ItemResult.Value!.Icon).ImGuiHandle, new Vector2(imageSize));
ImGui.Image(IconManager.GetIcon(RecipeData.Recipe.ItemResult.Value!.Icon).GetHandle(), new Vector2(imageSize));
ImGui.SameLine(0, 5);
@@ -757,7 +764,7 @@ public sealed class MacroEditor : Window, IDisposable
uv1 /= new Vector2(56);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetStyle().FramePadding.Y / 2);
ImGui.Image(Service.IconManager.GetIcon(classJob.GetIconId()).ImGuiHandle, new Vector2(imageSize), uv0, uv1);
ImGui.Image(IconManager.GetIcon(classJob.GetIconId()).GetHandle(), new Vector2(imageSize), uv0, uv1);
ImGui.SameLine(0, 5);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + (fontHandle.FontSize - textLevelSize.Y) / 2);
ImGui.TextUnformatted(textLevel);
@@ -785,7 +792,7 @@ public sealed class MacroEditor : Window, IDisposable
{
ImGui.SameLine(0, 3);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + badgeOffset);
ImGui.Image(CollectibleBadge.ImGuiHandle, badgeSize);
ImGui.Image(CollectibleBadge.GetHandle(), badgeSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Collectible");
}
@@ -794,7 +801,7 @@ public sealed class MacroEditor : Window, IDisposable
{
ImGui.SameLine(0, 3);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + badgeOffset);
ImGui.Image(ExpertBadge.ImGuiHandle, badgeSize);
ImGui.Image(ExpertBadge.GetHandle(), badgeSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Expert Recipe");
}
@@ -881,11 +888,11 @@ public sealed class MacroEditor : Window, IDisposable
var hqCount = HQIngredientCounts[idx];
var canHq = ingredient.Item.CanBeHq;
var icon = Service.IconManager.GetHqIcon(ingredient.Item.Icon, canHq);
var icon = IconManager.GetIcon(ingredient.Item.Icon, canHq);
var imageSize = ImGui.GetFrameHeight();
using (var d = ImRaii.Disabled(!canHq))
ImGui.Image(icon.ImGuiHandle, new Vector2(imageSize));
ImGui.Image(icon.GetHandle(), new Vector2(imageSize));
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
if (canHq)
@@ -953,12 +960,12 @@ public sealed class MacroEditor : Window, IDisposable
{
var actionBase = actions[i].Base();
var canUse = actionBase.CanUse(sim);
if (ImGui.ImageButton(actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize), default, Vector2.One, 0, default, !canUse ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One) && !SolverRunning)
if (ImGui.ImageButton(actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(imageSize), default, Vector2.One, 0, default, !canUse ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One) && !SolverRunning)
AddStep(actions[i]);
if (!canUse &&
(CharacterStats.Level < actionBase.Level ||
(actions[i] == ActionType.Manipulation && !CharacterStats.CanUseManipulation) ||
(actions[i] is ActionType.HeartAndSoul or ActionType.CarefulObservation && !CharacterStats.IsSpecialist)
(actions[i] is ActionType.HeartAndSoul or ActionType.CarefulObservation or ActionType.QuickInnovation && !CharacterStats.IsSpecialist)
)
)
{
@@ -977,7 +984,7 @@ public sealed class MacroEditor : Window, IDisposable
if (_source)
{
ImGuiExtras.SetDragDropPayload("macroActionInsert", actions[i]);
ImGui.ImageButton(actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize));
ImGui.ImageButton(actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(imageSize));
}
}
}
@@ -1091,7 +1098,7 @@ public sealed class MacroEditor : Window, IDisposable
using (var group = ImRaii.Group())
{
var icon = effect.GetIcon(effects.GetStrength(effect));
var icon = effect.GetIcon(effects.GetStrength(effect)).GetWrapOrEmpty();
var size = new Vector2(iconHeight * icon.Width / icon.Height, iconHeight);
ImGui.Image(icon.ImGuiHandle, size);
@@ -1140,7 +1147,7 @@ public sealed class MacroEditor : Window, IDisposable
var actionBase = action.Base();
var failedAction = response != ActionResponse.UsedAction;
using var id = ImRaii.PushId(i);
if (ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize), default, Vector2.One, 0, default, failedAction ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One))
if (ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).GetHandle(), new(imageSize), default, Vector2.One, 0, default, failedAction ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One))
RemoveStep(i);
if (response is ActionResponse.ActionNotUnlocked ||
(
@@ -1169,7 +1176,7 @@ public sealed class MacroEditor : Window, IDisposable
if (_source)
{
ImGuiExtras.SetDragDropPayload("macroAction", i);
ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize));
ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).GetHandle(), new(imageSize));
}
}
using (var _target = ImRaii.DragDropTarget())
+2 -2
View File
@@ -274,7 +274,7 @@ public sealed class MacroList : Window, IDisposable
var shouldShowMore = i + 1 == itemsPerRow * 2 && i + 1 < itemCount;
if (!shouldShowMore)
{
ImGui.Image(macro.Actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(miniRowHeight));
ImGui.Image(macro.Actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(miniRowHeight));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip(macro.Actions[i].GetName(RecipeData!.ClassJob));
}
@@ -282,7 +282,7 @@ public sealed class MacroList : Window, IDisposable
{
var amtMore = itemCount - itemsPerRow * 2;
var pos = ImGui.GetCursorPos();
ImGui.Image(macro.Actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(miniRowHeight), default, Vector2.One, new(1, 1, 1, .5f));
ImGui.Image(macro.Actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(miniRowHeight), default, Vector2.One, new(1, 1, 1, .5f));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"{macro.Actions[i].GetName(RecipeData!.ClassJob)}\nand {amtMore} more");
ImGui.SetCursorPos(pos);
+33 -30
View File
@@ -10,8 +10,8 @@ using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface.GameFonts;
using Dalamud.Interface.Internal;
using Dalamud.Interface.ManagedFontAtlas;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
@@ -20,7 +20,6 @@ using FFXIVClientStructs.FFXIV.Client.Game;
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 System;
using System.Collections.Generic;
@@ -108,20 +107,20 @@ public sealed unsafe class RecipeNote : Window, IDisposable
private Solver.Solver? BestMacroSolver { get; set; }
public bool HasSavedMacro { get; private set; }
private IDalamudTextureWrap ExpertBadge { get; }
private IDalamudTextureWrap CollectibleBadge { get; }
private IDalamudTextureWrap SplendorousBadge { get; }
private IDalamudTextureWrap SpecialistBadge { get; }
private IDalamudTextureWrap NoManipulationBadge { get; }
private ISharedImmediateTexture ExpertBadge { get; }
private ISharedImmediateTexture CollectibleBadge { get; }
private ISharedImmediateTexture SplendorousBadge { get; }
private ISharedImmediateTexture SpecialistBadge { get; }
private ISharedImmediateTexture NoManipulationBadge { get; }
private IFontHandle AxisFont { get; }
public RecipeNote() : base(WindowNamePinned)
{
ExpertBadge = Service.IconManager.GetAssemblyTexture("Graphics.expert_badge.png");
CollectibleBadge = Service.IconManager.GetAssemblyTexture("Graphics.collectible_badge.png");
SplendorousBadge = Service.IconManager.GetAssemblyTexture("Graphics.splendorous.png");
SpecialistBadge = Service.IconManager.GetAssemblyTexture("Graphics.specialist.png");
NoManipulationBadge = Service.IconManager.GetAssemblyTexture("Graphics.no_manip.png");
ExpertBadge = IconManager.GetAssemblyTexture("Graphics.expert_badge.png");
CollectibleBadge = IconManager.GetAssemblyTexture("Graphics.collectible_badge.png");
SplendorousBadge = IconManager.GetAssemblyTexture("Graphics.splendorous.png");
SpecialistBadge = IconManager.GetAssemblyTexture("Graphics.specialist.png");
NoManipulationBadge = IconManager.GetAssemblyTexture("Graphics.no_manip.png");
AxisFont = Service.PluginInterface.UiBuilder.FontAtlas.NewGameFontHandle(new(GameFontFamilyAndSize.Axis14));
RespectCloseHotkey = false;
@@ -230,7 +229,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
return false;
// Check if RecipeNote has a visible selected recipe
if (!Addon->Unk258->IsVisible)
if (!Addon->GetNodeById(57)->IsVisible())
return false;
}
@@ -324,8 +323,8 @@ public sealed unsafe class RecipeNote : Window, IDisposable
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 = Addon->GetNodeById(59);
var nodeParent = Addon->GetNodeById(57);
var newAlpha = unit.WindowNode->AtkResNode.Alpha_2;
StyleAlpha = LastAlpha ?? newAlpha;
@@ -482,7 +481,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
uv0 /= new Vector2(56);
uv1 /= new Vector2(56);
ImGui.Image(Service.IconManager.GetIcon(RecipeData.ClassJob.GetIconId()).ImGuiHandle, new Vector2(imageSize), uv0, uv1);
ImGui.Image(IconManager.GetIcon(RecipeData.ClassJob.GetIconId()).GetHandle(), new Vector2(imageSize), uv0, uv1);
ImGui.SameLine(0, 5);
if (level != 0)
@@ -498,7 +497,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
if (hasSplendorous)
{
ImGui.SameLine(0, 3);
ImGui.Image(SplendorousBadge.ImGuiHandle, new Vector2(imageSize));
ImGui.Image(SplendorousBadge.GetHandle(), new Vector2(imageSize));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Splendorous Tool");
}
@@ -506,7 +505,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
if (hasSpecialist)
{
ImGui.SameLine(0, 3);
ImGui.Image(SpecialistBadge.ImGuiHandle, new Vector2(imageSize), Vector2.Zero, Vector2.One, new(0.99f, 0.97f, 0.62f, 1f));
ImGui.Image(SpecialistBadge.GetHandle(), new Vector2(imageSize), Vector2.Zero, Vector2.One, new(0.99f, 0.97f, 0.62f, 1f));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Specialist");
}
@@ -514,7 +513,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
if (shouldHaveManip)
{
ImGui.SameLine(0, 3);
ImGui.Image(NoManipulationBadge.ImGuiHandle, new Vector2(imageSize));
ImGui.Image(NoManipulationBadge.GetHandle(), new Vector2(imageSize));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"No Manipulation (Missing Job Quest)");
}
@@ -588,7 +587,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
ImGuiUtils.TextCentered($"You are missing the required equipment.");
ImGuiUtils.AlignCentered(imageSize + 5 + ImGui.CalcTextSize(itemName).X);
ImGui.AlignTextToFramePadding();
ImGui.Image(Service.IconManager.GetIcon(item.Icon).ImGuiHandle, new(imageSize));
ImGui.Image(IconManager.GetIcon(item.Icon).GetHandle(), new(imageSize));
ImGui.SameLine(0, 5);
ImGui.TextUnformatted(itemName);
}
@@ -597,7 +596,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
var status = RecipeData.Recipe.StatusRequired.Value!;
var statusName = status.Name.ToDalamudString().ToString();
var statusIcon = Service.IconManager.GetIcon(status.Icon);
var statusIcon = IconManager.GetIcon(status.Icon).GetWrapOrEmpty();
var imageSize = new Vector2(ImGui.GetFrameHeight() * statusIcon.Width / statusIcon.Height, ImGui.GetFrameHeight());
ImGuiUtils.TextCentered($"You are missing the required status effect.");
@@ -668,7 +667,8 @@ public sealed unsafe class RecipeNote : Window, IDisposable
var isCollectable = RecipeData.Recipe.ItemResult.Value!.IsCollectable;
var imageSize = ImGui.GetFrameHeight();
var textSize = ImGui.GetFontSize();
var badgeSize = new Vector2(textSize * ExpertBadge.Width / ExpertBadge.Height, textSize);
var badge = ExpertBadge.GetWrapOrEmpty();
var badgeSize = new Vector2(textSize * badge.Width / badge.Height, textSize);
var badgeOffset = (imageSize - badgeSize.Y) / 2;
ImGuiUtils.AlignCentered(
@@ -680,7 +680,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
);
ImGui.AlignTextToFramePadding();
ImGui.Image(Service.IconManager.GetIcon(RecipeData.Recipe.ItemResult.Value!.Icon).ImGuiHandle, new Vector2(imageSize));
ImGui.Image(IconManager.GetIcon(RecipeData.Recipe.ItemResult.Value!.Icon).GetHandle(), new Vector2(imageSize));
ImGui.SameLine(0, 5);
ImGui.TextUnformatted(textLevel);
@@ -700,7 +700,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
ImGui.SameLine(0, 3);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + badgeOffset);
ImGui.Image(CollectibleBadge.ImGuiHandle, badgeSize);
ImGui.Image(CollectibleBadge.GetHandle(), badgeSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Collectible");
}
@@ -709,7 +709,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
ImGui.SameLine(0, 3);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + badgeOffset);
ImGui.Image(ExpertBadge.ImGuiHandle, badgeSize);
ImGui.Image(ExpertBadge.GetHandle(), badgeSize);
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"Expert Recipe");
}
@@ -1010,7 +1010,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
var shouldShowMore = i + 1 == itemsPerRow * 2 && i + 1 < itemCount;
if (!shouldShowMore)
{
ImGui.Image(actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(miniRowHeight));
ImGui.Image(actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(miniRowHeight));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip(actions[i].GetName(RecipeData!.ClassJob));
}
@@ -1018,7 +1018,7 @@ public sealed unsafe class RecipeNote : Window, IDisposable
{
var amtMore = itemCount - itemsPerRow * 2;
var pos = ImGui.GetCursorPos();
ImGui.Image(actions[i].GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(miniRowHeight), default, Vector2.One, new(1, 1, 1, .5f));
ImGui.Image(actions[i].GetIcon(RecipeData!.ClassJob).GetHandle(), new(miniRowHeight), default, Vector2.One, new(1, 1, 1, .5f));
if (ImGui.IsItemHovered())
ImGuiUtils.Tooltip($"{actions[i].GetName(RecipeData!.ClassJob)}\nand {amtMore} more");
ImGui.SetCursorPos(pos);
@@ -1120,15 +1120,18 @@ public sealed unsafe class RecipeNote : Window, IDisposable
private static int? GetGearsetForJob(ClassJob job)
{
var gearsetModule = RaptureGearsetModule.Instance();
for (var i = 0; i < 100; i++)
var i = -1;
foreach (ref var gearset in gearsetModule->Entries)
{
var gearset = gearsetModule->EntriesSpan[i];
i++;
if (!gearset.Flags.HasFlag(RaptureGearsetModule.GearsetFlag.Exists))
continue;
if (gearset.ID != i)
if (gearset.Id != i)
continue;
if (gearset.ClassJob != job.GetClassJobIndex())
continue;
return i;
}
return null;
+3 -2
View File
@@ -1,6 +1,7 @@
using Craftimizer.Simulator;
using Craftimizer.Simulator.Actions;
using Craftimizer.Solver;
using Craftimizer.Utils;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.ManagedFontAtlas;
@@ -694,7 +695,7 @@ public sealed class Settings : Window, IDisposable
iconTint = new(1, 1f, .5f, 1);
else if (isRisky)
iconTint = new(1, .5f, .5f, 1);
if (ImGui.ImageButton(actions[i].GetIcon(recipeData.ClassJob).ImGuiHandle, new(imageSize), default, Vector2.One, 0, default, iconTint))
if (ImGui.ImageButton(actions[i].GetIcon(recipeData.ClassJob).GetHandle(), new(imageSize), default, Vector2.One, 0, default, iconTint))
{
isDirty = true;
if (isEnabled)
@@ -932,7 +933,7 @@ public sealed class Settings : Window, IDisposable
ImGuiHelpers.ScaledDummy(5);
var plugin = Service.Plugin;
var icon = plugin.Icon;
var icon = plugin.Icon.GetWrapOrEmpty();
using (var table = ImRaii.Table("settingsAboutTable", 2))
{
+8 -8
View File
@@ -310,7 +310,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
isPressed = ImGuiExtras.ButtonBehavior(bb, id, out isHovered, out isHeld, ImGuiButtonFlags.None);
}
ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).ImGuiHandle, new(imageSize), default, Vector2.One, 0, default, failedAction ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One);
ImGui.ImageButton(action.GetIcon(RecipeData!.ClassJob).GetHandle(), new(imageSize), default, Vector2.One, 0, default, failedAction ? new(1, 1, 1, ImGui.GetStyle().DisabledAlpha) : Vector4.One);
if (isPressed || IsSuggestedActionExecutionQueued)
{
if (canExecute && i == 0)
@@ -359,7 +359,7 @@ public sealed unsafe class SynthHelper : Window, IDisposable
using (var group = ImRaii.Group())
{
var icon = effect.GetIcon(effects.GetStrength(effect));
var icon = effect.GetIcon(effects.GetStrength(effect)).GetWrapOrEmpty();
var size = new Vector2(iconHeight * icon.Width / icon.Height, iconHeight);
ImGui.Image(icon.ImGuiHandle, size);
@@ -535,15 +535,15 @@ public sealed unsafe class SynthHelper : Window, IDisposable
byte GetEffectStack(ushort id)
{
foreach (var status in statusManager->StatusSpan)
if (status.StatusID == id)
foreach (var status in statusManager->Status)
if (status.StatusId == id)
return status.StackCount;
return 0;
}
bool HasEffect(ushort id)
{
foreach (var status in statusManager->StatusSpan)
if (status.StatusID == id)
foreach (var status in statusManager->Status)
if (status.StatusId == id)
return true;
return false;
}
@@ -568,8 +568,8 @@ public sealed unsafe class SynthHelper : Window, IDisposable
WasteNot2 = GetEffectStack((ushort)EffectType.WasteNot2.StatusId()),
MuscleMemory = GetEffectStack((ushort)EffectType.MuscleMemory.StatusId()),
Manipulation = GetEffectStack((ushort)EffectType.Manipulation.StatusId()),
Expedience = HasEffect((ushort)EffectType.Expedience.StatusId()),
TrainedPerfection = HasEffect((ushort)EffectType.TrainedPerfection.StatusId()),
Expedience = GetEffectStack((ushort)EffectType.Expedience.StatusId()),
TrainedPerfection = GetEffectStack((ushort)EffectType.TrainedPerfection.StatusId()),
HeartAndSoul = HasEffect((ushort)EffectType.HeartAndSoul.StatusId()),
},
ActionStates = CurrentActionStates
+15 -14
View File
@@ -4,19 +4,25 @@
"net8.0-windows7.0": {
"DalamudPackager": {
"type": "Direct",
"requested": "[2.1.12, )",
"resolved": "2.1.12",
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
"requested": "[2.1.13, )",
"resolved": "2.1.13",
"contentHash": "rMN1omGe8536f4xLMvx9NwfvpAc9YFFfeXJ1t4P4PE6Gu8WCIoFliR1sh07hM+bfODmesk/dvMbji7vNI+B/pQ=="
},
"ExdSheets": {
"type": "Direct",
"requested": "[1.0.0, )",
"resolved": "1.0.0",
"contentHash": "Zf1btj6qUkrzEm+MVCd2vRWguXizb+Ucy49xWHhFJ5HQj6gtLOxAX2gJqebAtg/uDBbEb9BHx/5Kz7Kuha5+cw==",
"requested": "[1.1.0, )",
"resolved": "1.1.0",
"contentHash": "Je/kV/jpZoIEmJVi1ICRnl1/ENB+nyFHX1KZUu3rkxMO8H9uJJ6CA1MdRiOD6OE6If1eGXAL1bLwEupC2Ikraw==",
"dependencies": {
"Lumina": "3.15.2"
}
},
"Lumina": {
"type": "Direct",
"requested": "[3.15.2, )",
"resolved": "3.15.2",
"contentHash": "EnoxYEYMepcvAoXdZhaFJiv2aiDBIPjgkgzxR/+ArOxlrALzCgheTsb5yD39a9sxNIi2tNECT93ulZvYjx8fZg=="
},
"MathNet.Numerics": {
"type": "Direct",
"requested": "[5.0.0, )",
@@ -25,14 +31,9 @@
},
"Meziantou.Analyzer": {
"type": "Direct",
"requested": "[2.0.157, )",
"resolved": "2.0.157",
"contentHash": "gQ9xAHvpYeqwOqcyRs5f8kFrTt7Kg2atzjsETGhRjuyGXqKYrN84n52Je6NcGEkZWRwhrQTBJl1wlcsh2se7Fw=="
},
"Lumina": {
"type": "Transitive",
"resolved": "3.15.2",
"contentHash": "EnoxYEYMepcvAoXdZhaFJiv2aiDBIPjgkgzxR/+ArOxlrALzCgheTsb5yD39a9sxNIi2tNECT93ulZvYjx8fZg=="
"requested": "[2.0.159, )",
"resolved": "2.0.159",
"contentHash": "+Lu4NktCK98/PkPCluTA+uRHS7uvMXa/Z2WLPE8TDsS/ybYtaOhfq8Wi745fO26wI8rNGaJlKsfFskcKWC5eDQ=="
},
"craftimizer.simulator": {
"type": "Project"
+2 -1
View File
@@ -21,9 +21,10 @@ internal abstract class BaseBuffAction(
// Non-instanced properties
public readonly EffectType Effect = effect;
public readonly int Duration = duration;
private readonly int trueDuration = increasesStepCount ? duration + 1 : duration;
public override void UseSuccess(Simulator s) =>
s.AddEffect(Effect, Duration);
s.AddEffect(Effect, trueDuration);
public override string GetTooltip(Simulator s, bool addUsability)
{
+1 -1
View File
@@ -2,7 +2,7 @@ namespace Craftimizer.Simulator.Actions;
internal sealed class FinalAppraisal() : BaseBuffAction(
ActionCategory.Other, 42, 19012,
EffectType.FinalAppraisal, duration: 4,
EffectType.FinalAppraisal, duration: 5,
increasesStepCount: false,
defaultCPCost: 1)
{
+6
View File
@@ -8,5 +8,11 @@ internal sealed class HastyTouch() : BaseAction(
defaultSuccessRate: 60
)
{
public override void UseSuccess(Simulator s)
{
base.UseSuccess(s);
if (s.Input.Stats.Level >= 96)
s.AddEffect(EffectType.Expedience, 1 + 1);
}
}
+1 -1
View File
@@ -14,6 +14,6 @@ internal sealed class MuscleMemory() : BaseAction(
public override void UseSuccess(Simulator s)
{
base.UseSuccess(s);
s.AddEffect(EffectType.MuscleMemory, 5);
s.AddEffect(EffectType.MuscleMemory, 5 + 1);
}
}
+2 -2
View File
@@ -11,8 +11,8 @@ internal sealed class QuickInnovation() : BaseBuffAction(
base.IsPossible(s) && s.Input.Stats.IsSpecialist && !s.ActionStates.UsedQuickInnovation;
public override bool CouldUse(Simulator s) =>
!s.ActionStates.UsedQuickInnovation;
!s.ActionStates.UsedQuickInnovation && !s.HasEffect(EffectType.Innovation);
public override string GetTooltip(Simulator s, bool addUsability) =>
$"{GetBaseTooltip(s, addUsability)}Specialist Only\n";
$"{base.GetTooltip(s, addUsability)}Specialist Only\n";
}
+10 -9
View File
@@ -16,8 +16,8 @@ public record struct Effects
public byte WasteNot2;
public byte MuscleMemory;
public byte Manipulation;
public bool Expedience;
public bool TrainedPerfection;
public byte Expedience;
public byte TrainedPerfection;
public bool HeartAndSoul;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -54,10 +54,10 @@ public record struct Effects
Manipulation = duration;
break;
case EffectType.Expedience:
Expedience = duration != 0;
Expedience = duration;
break;
case EffectType.TrainedPerfection:
TrainedPerfection = duration != 0;
TrainedPerfection = duration;
break;
case EffectType.HeartAndSoul:
HeartAndSoul = duration != 0;
@@ -86,8 +86,8 @@ public record struct Effects
EffectType.WasteNot2 => WasteNot2,
EffectType.MuscleMemory => MuscleMemory,
EffectType.Manipulation => Manipulation,
EffectType.Expedience => (byte)(Expedience ? 1 : 0),
EffectType.TrainedPerfection => (byte)(TrainedPerfection ? 1 : 0),
EffectType.Expedience => Expedience,
EffectType.TrainedPerfection => TrainedPerfection,
EffectType.HeartAndSoul => (byte)(HeartAndSoul ? 1 : 0),
_ => 0
};
@@ -127,8 +127,9 @@ public record struct Effects
MuscleMemory--;
if (Manipulation > 0)
Manipulation--;
Expedience = false;
TrainedPerfection = false;
if (Expedience > 0)
Expedience--;
if (TrainedPerfection > 0)
TrainedPerfection--;
}
}
-3
View File
@@ -105,9 +105,6 @@ public class Simulator
if (Condition == Condition.Primed)
duration += 2;
// Duration will be decreased in the next step, so we need to add 1
duration++;
ActiveEffects.SetDuration(effect, (byte)duration);
}