API10 updates
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
using Dalamud;
|
||||
using Dalamud.Game;
|
||||
using ExdSheets;
|
||||
using Lumina.Excel;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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,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;
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user