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