diff --git a/Glamaholic/GameFunctions.cs b/Glamaholic/GameFunctions.cs index 079c8c1..fe1cb9e 100755 --- a/Glamaholic/GameFunctions.cs +++ b/Glamaholic/GameFunctions.cs @@ -328,8 +328,11 @@ namespace Glamaholic { } } - internal void TryOn(uint itemId, byte stainId) { - this._filterIds.Add(itemId); + internal void TryOn(uint itemId, byte stainId, bool suppress = true) { + if (suppress) { + this._filterIds.Add(itemId); + } + this._tryOn(0xFF, itemId % 1_000_000, stainId, 0, 0); } } diff --git a/Glamaholic/PluginUi.cs b/Glamaholic/PluginUi.cs index 96a6672..3c45e15 100755 --- a/Glamaholic/PluginUi.cs +++ b/Glamaholic/PluginUi.cs @@ -15,6 +15,7 @@ namespace Glamaholic { private MainInterface MainInterface { get; } private EditorHelper EditorHelper { get; } private ExamineHelper ExamineHelper { get; } + internal List AlternativeFinders { get; } = new(); internal PluginUi(Plugin plugin) { this.Plugin = plugin; @@ -62,6 +63,11 @@ namespace Glamaholic { this.MainInterface.Draw(); this.EditorHelper.Draw(); this.ExamineHelper.Draw(); + + this.AlternativeFinders.RemoveAll(finder => { + finder.Draw(); + return !finder.Visible; + }); } internal void SwitchPlate(int idx, bool scrollTo = false) { diff --git a/Glamaholic/Ui/AlternativeFinder.cs b/Glamaholic/Ui/AlternativeFinder.cs new file mode 100755 index 0000000..f937f21 --- /dev/null +++ b/Glamaholic/Ui/AlternativeFinder.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Numerics; +using Dalamud.Game.Text; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Logging; +using ImGuiNET; +using Lumina.Excel.GeneratedSheets; + +namespace Glamaholic.Ui { + internal class AlternativeFinder { + private Guid Id { get; } = Guid.NewGuid(); + internal bool Visible = true; + + private PluginUi Ui { get; } + private Item Item { get; } + private List Alternatives { get; } = new(); + + internal AlternativeFinder(PluginUi ui, Item item) { + this.Ui = ui; + this.Item = item; + + var info = ModelInfo(item.ModelMain); + PluginLog.Log($"info: {item.ModelMain} = {info}"); + + foreach (var row in this.Ui.Plugin.DataManager.GetExcelSheet()!) { + if (row.EquipSlotCategory.Row != this.Item.EquipSlotCategory.Row || info != ModelInfo(row.ModelMain)) { + continue; + } + + this.Alternatives.Add(row); + } + } + + internal void Draw() { + ImGui.SetNextWindowSize(new Vector2(250, 350), ImGuiCond.Appearing); + ImGui.SetNextWindowPos(ImGui.GetMousePos(), ImGuiCond.Appearing); + + const ImGuiWindowFlags flags = ImGuiWindowFlags.NoSavedSettings; + if (!ImGui.Begin($"Alternative Finder: {this.Item.Name}##{this.Id}", ref this.Visible, flags)) { + ImGui.End(); + return; + } + + this.DrawInner(); + + ImGui.End(); + } + + private void DrawInner() { + ImGui.Columns(2); + ImGui.SetColumnWidth(0, MainInterface.IconSize + ImGui.GetStyle().ItemSpacing.X * 2); + var icon = this.Ui.GetIcon(this.Item.Icon); + if (icon != null) { + ImGui.Image(icon.ImGuiHandle, new Vector2(48)); + } + + ImGui.NextColumn(); + + ImGui.TextUnformatted("Click: link to chat"); + ImGui.TextUnformatted("Right-click: try on"); + + ImGui.Columns(); + + ImGui.Separator(); + + this.DrawAlternatives(); + } + + private void DrawAlternatives() { + if (!ImGui.BeginChild($"{this.Id} alternatives")) { + return; + } + + foreach (var alt in this.Alternatives) { + if (ImGui.Selectable($"{alt.Name}##{alt.RowId}", alt.RowId == this.Item.RowId)) { + this.LinkItem(alt); + } + + if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { + this.Ui.Plugin.Functions.TryOn(alt.RowId, 0, false); + } + } + + ImGui.EndChild(); + } + + private static (ushort, ushort, ushort, ushort) ModelInfo(ulong raw) { + // return (ushort) (raw & 0xFFFF); + var primaryKey = (ushort) (raw & 0xFFFF); + var secondaryKey = (ushort) ((raw >> 16) & 0xFFFF); + var variant = (ushort) ((raw >> 32) & 0xFFFF); + var dye = (ushort) ((raw >> 48) & 0xFFFF); + + if (variant != 0) { + // weapon + return (primaryKey, secondaryKey, variant, dye); + } + + return (primaryKey, 0, 0, 0); + } + + private void LinkItem(Item item) { + var payloadList = new List { + new UIForegroundPayload((ushort) (0x223 + item.Rarity * 2)), + new UIGlowPayload((ushort) (0x224 + item.Rarity * 2)), + new ItemPayload(item.RowId, false), + new UIForegroundPayload(500), + new UIGlowPayload(501), + new TextPayload($"{(char) SeIconChar.LinkMarker}"), + new UIForegroundPayload(0), + new UIGlowPayload(0), + }; + payloadList.AddRange(SeString.Parse(item.Name.RawData).Payloads); + payloadList.AddRange(new[] { + new RawPayload(new byte[] { 0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03 }), + new RawPayload(new byte[] { 0x02, 0x13, 0x02, 0xEC, 0x03 }), + }); + + var payload = new SeString(payloadList); + + this.Ui.Plugin.ChatGui.PrintChat(new XivChatEntry { + Message = payload, + }); + } + } +} diff --git a/Glamaholic/Ui/MainInterface.cs b/Glamaholic/Ui/MainInterface.cs index 95d502e..c9bab82 100755 --- a/Glamaholic/Ui/MainInterface.cs +++ b/Glamaholic/Ui/MainInterface.cs @@ -11,6 +11,8 @@ using Newtonsoft.Json; namespace Glamaholic.Ui { internal class MainInterface { + internal const int IconSize = 48; + private static readonly PlateSlot[] LeftSide = { PlateSlot.MainHand, PlateSlot.Head, @@ -397,6 +399,10 @@ namespace Glamaholic.Ui { ImGui.CloseCurrentPopup(); } + + if (ImGui.IsItemClicked(ImGuiMouseButton.Middle)) { + this.Ui.AlternativeFinders.Add(new AlternativeFinder(this.Ui, item)); + } } } @@ -499,6 +505,13 @@ namespace Glamaholic.Ui { } } + if (mirage != null && mirage.ItemId != 0 && ImGui.IsItemClicked(ImGuiMouseButton.Middle)) { + var item = this.Ui.Plugin.DataManager.GetExcelSheet()!.GetRow(mirage.ItemId); + if (item != null) { + this.Ui.AlternativeFinders.Add(new AlternativeFinder(this.Ui, item)); + } + } + this.DrawItemPopup(itemPopup, plate, slot); if (mirage != null) { @@ -507,7 +520,6 @@ namespace Glamaholic.Ui { } private void DrawPlatePreview(bool editingPlate, SavedPlate plate) { - const int iconSize = 48; const int paddingSize = 12; if (!ImGui.BeginTable("plate item preview", 2, ImGuiTableFlags.SizingFixedFit)) { @@ -516,9 +528,9 @@ namespace Glamaholic.Ui { foreach (var (left, right) in LeftSide.Zip(RightSide)) { ImGui.TableNextColumn(); - this.DrawIcon(left, plate, editingPlate, iconSize, paddingSize); + this.DrawIcon(left, plate, editingPlate, IconSize, paddingSize); ImGui.TableNextColumn(); - this.DrawIcon(right, plate, editingPlate, iconSize, paddingSize); + this.DrawIcon(right, plate, editingPlate, IconSize, paddingSize); } ImGui.EndTable();