diff --git a/Glamaholic/GameFunctions.cs b/Glamaholic/GameFunctions.cs index 46cd691..079c8c1 100755 --- a/Glamaholic/GameFunctions.cs +++ b/Glamaholic/GameFunctions.cs @@ -18,17 +18,20 @@ namespace Glamaholic { private static class Signatures { internal const string SetGlamourPlateSlot = "E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B 46 10"; internal const string ModifyGlamourPlateSlot = "48 89 74 24 ?? 57 48 83 EC 20 80 79 30 00"; + internal const string ClearGlamourPlateSlot = "80 79 30 00 4C 8B C1"; internal const string IsInArmoire = "E8 ?? ?? ?? ?? 84 C0 74 16 8B CB"; internal const string ArmoirePointer = "48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 16 8B CB E8"; internal const string TryOn = "E8 ?? ?? ?? ?? EB 35 BA"; internal const string ExamineNamePointer = "48 8D 05 ?? ?? ?? ?? 48 89 85 ?? ?? ?? ?? 74 56 49 8B 4F"; } - internal delegate void SetGlamourPlateSlotDelegate(IntPtr agent, MirageSource mirageSource, int glamId, uint itemId, byte stainId); + private delegate void SetGlamourPlateSlotDelegate(IntPtr agent, MirageSource mirageSource, int glamId, uint itemId, byte stainId); - internal delegate void ModifyGlamourPlateSlotDelegate(IntPtr agent, PlateSlot slot, byte stainId, IntPtr numbers, int stainItemId); + private delegate void ModifyGlamourPlateSlotDelegate(IntPtr agent, PlateSlot slot, byte stainId, IntPtr numbers, int stainItemId); - internal delegate byte IsInArmoireDelegate(IntPtr armoire, int index); + private delegate void ClearGlamourPlateSlotDelegate(IntPtr agent, PlateSlot slot); + + private delegate byte IsInArmoireDelegate(IntPtr armoire, int index); private delegate byte TryOnDelegate(uint unknownCanEquip, uint itemBaseId, ulong stainColor, uint itemGlamourId, byte unknownByte); @@ -36,6 +39,7 @@ namespace Glamaholic { private readonly SetGlamourPlateSlotDelegate _setGlamourPlateSlot; private readonly ModifyGlamourPlateSlotDelegate _modifyGlamourPlateSlot; + private readonly ClearGlamourPlateSlotDelegate _clearGlamourPlateSlot; private readonly IsInArmoireDelegate _isInArmoire; private readonly IntPtr _armoirePtr; private readonly TryOnDelegate _tryOn; @@ -48,6 +52,7 @@ namespace Glamaholic { this._setGlamourPlateSlot = Marshal.GetDelegateForFunctionPointer(this.Plugin.SigScanner.ScanText(Signatures.SetGlamourPlateSlot)); this._modifyGlamourPlateSlot = Marshal.GetDelegateForFunctionPointer(this.Plugin.SigScanner.ScanText(Signatures.ModifyGlamourPlateSlot)); + this._clearGlamourPlateSlot = Marshal.GetDelegateForFunctionPointer(this.Plugin.SigScanner.ScanText(Signatures.ClearGlamourPlateSlot)); this._isInArmoire = Marshal.GetDelegateForFunctionPointer(this.Plugin.SigScanner.ScanText(Signatures.IsInArmoire)); this._armoirePtr = this.Plugin.SigScanner.GetStaticAddressFromSig(Signatures.ArmoirePointer); this._tryOn = Marshal.GetDelegateForFunctionPointer(this.Plugin.SigScanner.ScanText(Signatures.TryOn)); @@ -188,6 +193,12 @@ namespace Glamaholic { continue; } } + + *slotPtr = slot; + if (item.ItemId == 0) { + this._clearGlamourPlateSlot((IntPtr) agent, slot); + continue; + } var source = MirageSource.GlamourDresser; var info = (0, 0u, (byte) 0); @@ -214,7 +225,6 @@ namespace Glamaholic { continue; } - *slotPtr = slot; this._setGlamourPlateSlot( (IntPtr) agent, source, diff --git a/Glamaholic/PluginUi.cs b/Glamaholic/PluginUi.cs index 35d5464..96a6672 100755 --- a/Glamaholic/PluginUi.cs +++ b/Glamaholic/PluginUi.cs @@ -78,6 +78,10 @@ namespace Glamaholic { SetTryOnSave(false); foreach (var mirage in items) { + if (mirage.ItemId == 0) { + continue; + } + this.Plugin.Functions.TryOn(mirage.ItemId, mirage.StainId); SetTryOnSave(true); } diff --git a/Glamaholic/Ui/MainInterface.cs b/Glamaholic/Ui/MainInterface.cs index 477fc69..31d5cf1 100755 --- a/Glamaholic/Ui/MainInterface.cs +++ b/Glamaholic/Ui/MainInterface.cs @@ -340,16 +340,23 @@ namespace Glamaholic.Ui { } if (ImGui.BeginChild("item search", new Vector2(250, 450), false, ImGuiWindowFlags.HorizontalScrollbar)) { - var id = 0u; + uint? id; if (plate.Items.TryGetValue(slot, out var slotMirage)) { id = slotMirage.ItemId; + } else { + id = null; } - if (ImGui.Selectable("None", id == 0)) { + if (ImGui.Selectable("None (keep existing)", id == null)) { plate.Items.Remove(slot); ImGui.CloseCurrentPopup(); } + if (ImGui.Selectable("None (remove existing)", id == 0)) { + plate.Items[slot] = new SavedGlamourItem(); + ImGui.CloseCurrentPopup(); + } + var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper()); clipper.Begin(this.FilteredItems.Count); @@ -388,7 +395,7 @@ namespace Glamaholic.Ui { var borderColour = *ImGui.GetStyleColorVec4(ImGuiCol.Border); // check for item - if (mirage != null && editingPlate) { + if (mirage != null && mirage.ItemId != 0 && editingPlate) { var has = GameFunctions.DresserContents.Any(saved => saved.ItemId % 1_000_000 == mirage.ItemId) || this.Ui.Plugin.Functions.IsInArmoire(mirage.ItemId); if (!has) { borderColour = ImGuiColors.DalamudYellow; @@ -401,7 +408,7 @@ namespace Glamaholic.Ui { ImGui.InvisibleButton($"preview {slot}", new Vector2(iconSize + paddingSize)); var cursorAfter = ImGui.GetCursorPos(); - if (mirage != null) { + if (mirage != null && mirage.ItemId != 0) { var item = this.Ui.Plugin.DataManager.GetExcelSheet()!.GetRow(mirage.ItemId); if (item != null) { var icon = this.Ui.GetIcon(item.Icon); @@ -431,6 +438,19 @@ namespace Glamaholic.Ui { tooltip += $"\n{item.Name}{stainName}"; } } + } else if (mirage != null) { + // remove + ImGui.GetWindowDrawList().AddLine( + drawCursor + new Vector2(paddingSize / 2f), + drawCursor + new Vector2(paddingSize / 2f) + new Vector2(iconSize), + ImGui.ColorConvertFloat4ToU32(ImGui.GetStyle().Colors[(int) ImGuiCol.Text]) + ); + + ImGui.GetWindowDrawList().AddLine( + drawCursor + new Vector2(paddingSize / 2f) + new Vector2(iconSize, 0), + drawCursor + new Vector2(paddingSize / 2f) + new Vector2(0, iconSize), + ImGui.ColorConvertFloat4ToU32(ImGui.GetStyle().Colors[(int) ImGuiCol.Text]) + ); } ImGui.EndGroup();