From 992cdff58d3a82c64dc166147de7de4a10be87f6 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Thu, 23 May 2024 22:31:39 +0200 Subject: [PATCH] Improve some IMC things. --- OtterGui | 2 +- Penumbra/Meta/Manipulations/Imc.cs | 14 +- .../UI/AdvancedWindow/ModEditWindow.Meta.cs | 92 +++----- Penumbra/UI/ModsTab/Groups/AddGroupDrawer.cs | 18 +- Penumbra/UI/ModsTab/ImcManipulationDrawer.cs | 221 ++++++++++++++++++ Penumbra/UI/ModsTab/MetaManipulationDrawer.cs | 105 --------- 6 files changed, 267 insertions(+), 185 deletions(-) create mode 100644 Penumbra/UI/ModsTab/ImcManipulationDrawer.cs delete mode 100644 Penumbra/UI/ModsTab/MetaManipulationDrawer.cs diff --git a/OtterGui b/OtterGui index 462acb87..1d936516 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 462acb87099650019996e4306d18cc70f76ca576 +Subproject commit 1d9365164655a7cb38172e1311e15e19b1def6db diff --git a/Penumbra/Meta/Manipulations/Imc.cs b/Penumbra/Meta/Manipulations/Imc.cs index f0101be2..9b123df1 100644 --- a/Penumbra/Meta/Manipulations/Imc.cs +++ b/Penumbra/Meta/Manipulations/Imc.cs @@ -1,3 +1,4 @@ +using Newtonsoft.Json.Linq; using Penumbra.GameData.Data; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; @@ -134,7 +135,7 @@ public readonly record struct ImcIdentifier( var b = BodySlot.CompareTo(other.BodySlot); return b != 0 ? b : Variant.Id.CompareTo(other.Variant.Id); - } + } public static ImcIdentifier? FromJson(JObject jObj) { @@ -177,11 +178,12 @@ public readonly record struct ImcIdentifier( public JObject AddToJson(JObject jObj) { - var (gender, race) = GenderRace.Split(); - jObj["Gender"] = gender.ToString(); - jObj["Race"] = race.ToString(); - jObj["SetId"] = SetId.Id.ToString(); - jObj["Slot"] = Slot.ToString(); + jObj["ObjectType"] = ObjectType.ToString(); + jObj["PrimaryId"] = PrimaryId.Id; + jObj["PrimaryId"] = SecondaryId.Id; + jObj["Variant"] = Variant.Id; + jObj["EquipSlot"] = EquipSlot.ToString(); + jObj["BodySlot"] = BodySlot.ToString(); return jObj; } } diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Meta.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Meta.cs index 55125375..99889360 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Meta.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Meta.cs @@ -352,26 +352,26 @@ public partial class ModEditWindow // Identifier ImGui.TableNextColumn(); - var change = MetaManipulationDrawer.DrawObjectType(ref _new); + var change = ImcManipulationDrawer.DrawObjectType(ref _new); ImGui.TableNextColumn(); - change |= MetaManipulationDrawer.DrawPrimaryId(ref _new); + change |= ImcManipulationDrawer.DrawPrimaryId(ref _new); using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y)); ImGui.TableNextColumn(); // Equipment and accessories are slightly different imcs than other types. if (_new.ObjectType is ObjectType.Equipment or ObjectType.Accessory) - change |= MetaManipulationDrawer.DrawSlot(ref _new); + change |= ImcManipulationDrawer.DrawSlot(ref _new); else - change |= MetaManipulationDrawer.DrawSecondaryId(ref _new); + change |= ImcManipulationDrawer.DrawSecondaryId(ref _new); ImGui.TableNextColumn(); - change |= MetaManipulationDrawer.DrawVariant(ref _new); + change |= ImcManipulationDrawer.DrawVariant(ref _new); ImGui.TableNextColumn(); if (_new.ObjectType is ObjectType.DemiHuman) - change |= MetaManipulationDrawer.DrawSlot(ref _new, 70); + change |= ImcManipulationDrawer.DrawSlot(ref _new, 70); else ImGui.Dummy(new Vector2(70 * UiHelpers.Scale, 0)); @@ -379,32 +379,20 @@ public partial class ModEditWindow _new = _new.Copy(GetDefault(metaFileManager, _new) ?? new ImcEntry()); // Values using var disabled = ImRaii.Disabled(); - ImGui.TableNextColumn(); - IntDragInput("##imcMaterialId", "Material ID", SmallIdWidth, defaultEntry.Value.MaterialId, defaultEntry.Value.MaterialId, out _, - 1, byte.MaxValue, 0f); - ImGui.SameLine(); - IntDragInput("##imcMaterialAnimId", "Material Animation ID", SmallIdWidth, defaultEntry.Value.MaterialAnimationId, - defaultEntry.Value.MaterialAnimationId, out _, 0, byte.MaxValue, 0.01f); - ImGui.TableNextColumn(); - IntDragInput("##imcDecalId", "Decal ID", SmallIdWidth, defaultEntry.Value.DecalId, defaultEntry.Value.DecalId, out _, 0, - byte.MaxValue, 0f); - ImGui.SameLine(); - IntDragInput("##imcVfxId", "VFX ID", SmallIdWidth, defaultEntry.Value.VfxId, defaultEntry.Value.VfxId, out _, 0, byte.MaxValue, - 0f); - ImGui.SameLine(); - IntDragInput("##imcSoundId", "Sound ID", SmallIdWidth, defaultEntry.Value.SoundId, defaultEntry.Value.SoundId, out _, 0, 0b111111, - 0f); - ImGui.TableNextColumn(); - for (var i = 0; i < 10; ++i) - { - using var id = ImRaii.PushId(i); - var flag = 1 << i; - Checkmark("##attribute", $"{(char)('A' + i)}", (defaultEntry.Value.AttributeMask & flag) != 0, - (defaultEntry.Value.AttributeMask & flag) != 0, out _); - ImGui.SameLine(); - } - ImGui.NewLine(); + var entry = defaultEntry.Value; + ImGui.TableNextColumn(); + ImcManipulationDrawer.DrawMaterialId(entry, ref entry, false); + ImGui.SameLine(); + ImcManipulationDrawer.DrawMaterialAnimationId(entry, ref entry, false); + ImGui.TableNextColumn(); + ImcManipulationDrawer.DrawDecalId(entry, ref entry, false); + ImGui.SameLine(); + ImcManipulationDrawer.DrawVfxId(entry, ref entry, false); + ImGui.SameLine(); + ImcManipulationDrawer.DrawSoundId(entry, ref entry, false); + ImGui.TableNextColumn(); + ImcManipulationDrawer.DrawAttributes(entry, ref entry); } public static void Draw(MetaFileManager metaFileManager, ImcManipulation meta, ModEditor editor, Vector2 iconSize) @@ -452,46 +440,22 @@ public partial class ModEditWindow new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y)); ImGui.TableNextColumn(); var defaultEntry = GetDefault(metaFileManager, meta) ?? new ImcEntry(); - if (IntDragInput("##imcMaterialId", $"Material ID\nDefault Value: {defaultEntry.MaterialId}", SmallIdWidth, meta.Entry.MaterialId, - defaultEntry.MaterialId, out var materialId, 1, byte.MaxValue, 0.01f)) - editor.MetaEditor.Change(meta.Copy(meta.Entry with { MaterialId = (byte)materialId })); + var newEntry = meta.Entry; + var changes = ImcManipulationDrawer.DrawMaterialId(defaultEntry, ref newEntry, true); ImGui.SameLine(); - if (IntDragInput("##imcMaterialAnimId", $"Material Animation ID\nDefault Value: {defaultEntry.MaterialAnimationId}", SmallIdWidth, - meta.Entry.MaterialAnimationId, defaultEntry.MaterialAnimationId, out var materialAnimId, 0, byte.MaxValue, 0.01f)) - editor.MetaEditor.Change(meta.Copy(meta.Entry with { MaterialAnimationId = (byte)materialAnimId })); - + changes |= ImcManipulationDrawer.DrawMaterialAnimationId(defaultEntry, ref newEntry, true); ImGui.TableNextColumn(); - if (IntDragInput("##imcDecalId", $"Decal ID\nDefault Value: {defaultEntry.DecalId}", SmallIdWidth, meta.Entry.DecalId, - defaultEntry.DecalId, out var decalId, 0, byte.MaxValue, 0.01f)) - editor.MetaEditor.Change(meta.Copy(meta.Entry with { DecalId = (byte)decalId })); - + changes |= ImcManipulationDrawer.DrawDecalId(defaultEntry, ref newEntry, true); ImGui.SameLine(); - if (IntDragInput("##imcVfxId", $"VFX ID\nDefault Value: {defaultEntry.VfxId}", SmallIdWidth, meta.Entry.VfxId, defaultEntry.VfxId, - out var vfxId, 0, byte.MaxValue, 0.01f)) - editor.MetaEditor.Change(meta.Copy(meta.Entry with { VfxId = (byte)vfxId })); - + changes |= ImcManipulationDrawer.DrawVfxId(defaultEntry, ref newEntry, true); ImGui.SameLine(); - if (IntDragInput("##imcSoundId", $"Sound ID\nDefault Value: {defaultEntry.SoundId}", SmallIdWidth, meta.Entry.SoundId, - defaultEntry.SoundId, out var soundId, 0, 0b111111, 0.01f)) - editor.MetaEditor.Change(meta.Copy(meta.Entry with { SoundId = (byte)soundId })); - + changes |= ImcManipulationDrawer.DrawSoundId(defaultEntry, ref newEntry, true); ImGui.TableNextColumn(); - for (var i = 0; i < 10; ++i) - { - using var id = ImRaii.PushId(i); - var flag = 1 << i; - if (Checkmark("##attribute", $"{(char)('A' + i)}", (meta.Entry.AttributeMask & flag) != 0, - (defaultEntry.AttributeMask & flag) != 0, out var val)) - { - var attributes = val ? meta.Entry.AttributeMask | flag : meta.Entry.AttributeMask & ~flag; - editor.MetaEditor.Change(meta.Copy(meta.Entry with { AttributeMask = (ushort)attributes })); - } + changes |= ImcManipulationDrawer.DrawAttributes(defaultEntry, ref newEntry); - ImGui.SameLine(); - } - - ImGui.NewLine(); + if (changes) + editor.MetaEditor.Change(meta.Copy(newEntry)); } } diff --git a/Penumbra/UI/ModsTab/Groups/AddGroupDrawer.cs b/Penumbra/UI/ModsTab/Groups/AddGroupDrawer.cs index 06cb4154..2d80d3df 100644 --- a/Penumbra/UI/ModsTab/Groups/AddGroupDrawer.cs +++ b/Penumbra/UI/ModsTab/Groups/AddGroupDrawer.cs @@ -80,29 +80,29 @@ public class AddGroupDrawer : IUiService private void DrawImcInput(float width) { - var change = MetaManipulationDrawer.DrawObjectType(ref _imcManip, width); + var change = ImcManipulationDrawer.DrawObjectType(ref _imcManip, width); ImUtf8.SameLineInner(); - change |= MetaManipulationDrawer.DrawPrimaryId(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawPrimaryId(ref _imcManip, width); if (_imcManip.ObjectType is ObjectType.Weapon or ObjectType.Monster) { - change |= MetaManipulationDrawer.DrawSecondaryId(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawSecondaryId(ref _imcManip, width); ImUtf8.SameLineInner(); - change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, width); } else if (_imcManip.ObjectType is ObjectType.DemiHuman) { var quarterWidth = (width - ImUtf8.ItemInnerSpacing.X / ImUtf8.GlobalScale) / 2; - change |= MetaManipulationDrawer.DrawSecondaryId(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawSecondaryId(ref _imcManip, width); ImUtf8.SameLineInner(); - change |= MetaManipulationDrawer.DrawSlot(ref _imcManip, quarterWidth); + change |= ImcManipulationDrawer.DrawSlot(ref _imcManip, quarterWidth); ImUtf8.SameLineInner(); - change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, quarterWidth); + change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, quarterWidth); } else { - change |= MetaManipulationDrawer.DrawSlot(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawSlot(ref _imcManip, width); ImUtf8.SameLineInner(); - change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, width); + change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, width); } if (change) diff --git a/Penumbra/UI/ModsTab/ImcManipulationDrawer.cs b/Penumbra/UI/ModsTab/ImcManipulationDrawer.cs new file mode 100644 index 00000000..5873119e --- /dev/null +++ b/Penumbra/UI/ModsTab/ImcManipulationDrawer.cs @@ -0,0 +1,221 @@ +using ImGuiNET; +using OtterGui; +using OtterGui.Raii; +using OtterGui.Text; +using OtterGui.Text.HelperObjects; +using Penumbra.GameData.Enums; +using Penumbra.GameData.Structs; +using Penumbra.Meta.Manipulations; +using Penumbra.UI.Classes; + +namespace Penumbra.UI.ModsTab; + +public static class ImcManipulationDrawer +{ + public static bool DrawObjectType(ref ImcManipulation manip, float width = 110) + { + var ret = Combos.ImcType("##imcType", manip.ObjectType, out var type, width); + ImUtf8.HoverTooltip("Object Type"u8); + + if (ret) + { + var equipSlot = type switch + { + ObjectType.Equipment => manip.EquipSlot.IsEquipment() ? manip.EquipSlot : EquipSlot.Head, + ObjectType.DemiHuman => manip.EquipSlot.IsEquipment() ? manip.EquipSlot : EquipSlot.Head, + ObjectType.Accessory => manip.EquipSlot.IsAccessory() ? manip.EquipSlot : EquipSlot.Ears, + _ => EquipSlot.Unknown, + }; + manip = new ImcManipulation(type, manip.BodySlot, manip.PrimaryId, manip.SecondaryId == 0 ? 1 : manip.SecondaryId, + manip.Variant.Id, equipSlot, manip.Entry); + } + + return ret; + } + + public static bool DrawPrimaryId(ref ImcManipulation manip, float unscaledWidth = 80) + { + var ret = IdInput("##imcPrimaryId"u8, unscaledWidth, manip.PrimaryId.Id, out var newId, 0, ushort.MaxValue, + manip.PrimaryId.Id <= 1); + ImUtf8.HoverTooltip("Primary ID - You can usually find this as the 'x####' part of an item path.\n"u8 + + "This should generally not be left <= 1 unless you explicitly want that."u8); + if (ret) + manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, newId, manip.SecondaryId, manip.Variant.Id, manip.EquipSlot, + manip.Entry); + return ret; + } + + public static bool DrawSecondaryId(ref ImcManipulation manip, float unscaledWidth = 100) + { + var ret = IdInput("##imcSecondaryId"u8, unscaledWidth, manip.SecondaryId.Id, out var newId, 0, ushort.MaxValue, false); + ImUtf8.HoverTooltip("Secondary ID"u8); + if (ret) + manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, newId, manip.Variant.Id, manip.EquipSlot, + manip.Entry); + return ret; + } + + public static bool DrawVariant(ref ImcManipulation manip, float unscaledWidth = 45) + { + var ret = IdInput("##imcVariant"u8, unscaledWidth, manip.Variant.Id, out var newId, 0, byte.MaxValue, false); + ImUtf8.HoverTooltip("Variant ID"u8); + if (ret) + manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, (byte)newId, manip.EquipSlot, + manip.Entry); + return ret; + } + + public static bool DrawSlot(ref ImcManipulation manip, float unscaledWidth = 100) + { + bool ret; + EquipSlot slot; + switch (manip.ObjectType) + { + case ObjectType.Equipment: + case ObjectType.DemiHuman: + ret = Combos.EqpEquipSlot("##slot", manip.EquipSlot, out slot, unscaledWidth); + break; + case ObjectType.Accessory: + ret = Combos.AccessorySlot("##slot", manip.EquipSlot, out slot, unscaledWidth); + break; + default: return false; + } + + ImUtf8.HoverTooltip("Equip Slot"u8); + if (ret) + manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, manip.Variant.Id, slot, + manip.Entry); + return ret; + } + + public static bool DrawMaterialId(ImcEntry defaultEntry, ref ImcEntry entry, bool addDefault, float unscaledWidth = 45) + { + if (!DragInput("##materialId"u8, "Material ID"u8, unscaledWidth * ImUtf8.GlobalScale, entry.MaterialId, defaultEntry.MaterialId, + out var newValue, (byte)1, byte.MaxValue, 0.01f, addDefault)) + return false; + + entry = entry with { MaterialId = newValue }; + return true; + } + + public static bool DrawMaterialAnimationId(ImcEntry defaultEntry, ref ImcEntry entry, bool addDefault, float unscaledWidth = 45) + { + if (!DragInput("##mAnimId"u8, "Material Animation ID"u8, unscaledWidth * ImUtf8.GlobalScale, entry.MaterialAnimationId, + defaultEntry.MaterialAnimationId, out var newValue, (byte)0, byte.MaxValue, 0.01f, addDefault)) + return false; + + entry = entry with { MaterialAnimationId = newValue }; + return true; + } + + public static bool DrawDecalId(ImcEntry defaultEntry, ref ImcEntry entry, bool addDefault, float unscaledWidth = 45) + { + if (!DragInput("##decalId"u8, "Decal ID"u8, unscaledWidth * ImUtf8.GlobalScale, entry.DecalId, defaultEntry.DecalId, out var newValue, + (byte)0, byte.MaxValue, 0.01f, addDefault)) + return false; + + entry = entry with { DecalId = newValue }; + return true; + } + + public static bool DrawVfxId(ImcEntry defaultEntry, ref ImcEntry entry, bool addDefault, float unscaledWidth = 45) + { + if (!DragInput("##vfxId"u8, "VFX ID"u8, unscaledWidth * ImUtf8.GlobalScale, entry.VfxId, defaultEntry.VfxId, out var newValue, (byte)0, + byte.MaxValue, 0.01f, addDefault)) + return false; + + entry = entry with { VfxId = newValue }; + return true; + } + + public static bool DrawSoundId(ImcEntry defaultEntry, ref ImcEntry entry, bool addDefault, float unscaledWidth = 45) + { + if (!DragInput("##soundId"u8, "Sound ID"u8, unscaledWidth * ImUtf8.GlobalScale, entry.SoundId, defaultEntry.SoundId, out var newValue, + (byte)0, byte.MaxValue, 0.01f, addDefault)) + return false; + + entry = entry with { SoundId = newValue }; + return true; + } + + public static bool DrawAttributes(ImcEntry defaultEntry, ref ImcEntry entry) + { + var changes = false; + for (var i = 0; i < ImcEntry.NumAttributes; ++i) + { + using var id = ImRaii.PushId(i); + var flag = 1 << i; + var value = (entry.AttributeMask & flag) != 0; + var def = (defaultEntry.AttributeMask & flag) != 0; + if (Checkmark("##attribute"u8, "ABCDEFGHIJ"u8.Slice(i, 1), value, def, out var newValue)) + { + var newMask = (ushort)(newValue ? entry.AttributeMask | flag : entry.AttributeMask & ~flag); + entry = entry with { AttributeMask = newMask }; + changes = true; + } + + if (i < ImcEntry.NumAttributes - 1) + ImGui.SameLine(); + } + + return changes; + } + + + /// + /// A number input for ids with an optional max id of given width. + /// Returns true if newId changed against currentId. + /// + private static bool IdInput(ReadOnlySpan label, float unscaledWidth, ushort currentId, out ushort newId, int minId, int maxId, + bool border) + { + int tmp = currentId; + ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale); + using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, UiHelpers.Scale, border); + using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, border); + if (ImUtf8.InputScalar(label, ref tmp)) + tmp = Math.Clamp(tmp, minId, maxId); + + newId = (ushort)tmp; + return newId != currentId; + } + + /// + /// A dragging int input of given width that compares against a default value, shows a tooltip and clamps against min and max. + /// Returns true if newValue changed against currentValue. + /// + private static bool DragInput(ReadOnlySpan label, ReadOnlySpan tooltip, float width, T currentValue, T defaultValue, + out T newValue, T minValue, T maxValue, float speed, bool addDefault) where T : unmanaged, INumber + { + newValue = currentValue; + using var color = ImRaii.PushColor(ImGuiCol.FrameBg, + defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(), + defaultValue != currentValue); + ImGui.SetNextItemWidth(width); + if (ImUtf8.DragScalar(label, ref newValue, minValue, maxValue, speed)) + newValue = newValue <= minValue ? minValue : newValue >= maxValue ? maxValue : newValue; + + if (addDefault) + ImUtf8.HoverTooltip($"{tooltip}\nDefault Value: {defaultValue}"); + else + ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip); + + return newValue != currentValue; + } + + /// + /// A checkmark that compares against a default value and shows a tooltip. + /// Returns true if newValue is changed against currentValue. + /// + private static bool Checkmark(ReadOnlySpan label, ReadOnlySpan tooltip, bool currentValue, bool defaultValue, + out bool newValue) + { + using var color = ImRaii.PushColor(ImGuiCol.FrameBg, + defaultValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(), + defaultValue != currentValue); + newValue = currentValue; + ImUtf8.Checkbox(label, ref newValue); + ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, tooltip); + return newValue != currentValue; + } +} diff --git a/Penumbra/UI/ModsTab/MetaManipulationDrawer.cs b/Penumbra/UI/ModsTab/MetaManipulationDrawer.cs deleted file mode 100644 index 1f2273b5..00000000 --- a/Penumbra/UI/ModsTab/MetaManipulationDrawer.cs +++ /dev/null @@ -1,105 +0,0 @@ -using ImGuiNET; -using OtterGui.Raii; -using OtterGui.Text; -using Penumbra.GameData.Enums; -using Penumbra.Meta.Manipulations; -using Penumbra.UI.Classes; - -namespace Penumbra.UI.ModsTab; - -public static class MetaManipulationDrawer -{ - public static bool DrawObjectType(ref ImcManipulation manip, float width = 110) - { - var ret = Combos.ImcType("##imcType", manip.ObjectType, out var type, width); - ImUtf8.HoverTooltip("Object Type"u8); - - if (ret) - { - var equipSlot = type switch - { - ObjectType.Equipment => manip.EquipSlot.IsEquipment() ? manip.EquipSlot : EquipSlot.Head, - ObjectType.DemiHuman => manip.EquipSlot.IsEquipment() ? manip.EquipSlot : EquipSlot.Head, - ObjectType.Accessory => manip.EquipSlot.IsAccessory() ? manip.EquipSlot : EquipSlot.Ears, - _ => EquipSlot.Unknown, - }; - manip = new ImcManipulation(type, manip.BodySlot, manip.PrimaryId, manip.SecondaryId == 0 ? 1 : manip.SecondaryId, - manip.Variant.Id, equipSlot, manip.Entry); - } - - return ret; - } - - public static bool DrawPrimaryId(ref ImcManipulation manip, float unscaledWidth = 80) - { - var ret = IdInput("##imcPrimaryId"u8, unscaledWidth, manip.PrimaryId.Id, out var newId, 0, ushort.MaxValue, - manip.PrimaryId.Id <= 1); - ImUtf8.HoverTooltip("Primary ID - You can usually find this as the 'x####' part of an item path.\n"u8 - + "This should generally not be left <= 1 unless you explicitly want that."u8); - if (ret) - manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, newId, manip.SecondaryId, manip.Variant.Id, manip.EquipSlot, - manip.Entry); - return ret; - } - - public static bool DrawSecondaryId(ref ImcManipulation manip, float unscaledWidth = 100) - { - var ret = IdInput("##imcSecondaryId"u8, unscaledWidth, manip.SecondaryId.Id, out var newId, 0, ushort.MaxValue, false); - ImUtf8.HoverTooltip("Secondary ID"u8); - if (ret) - manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, newId, manip.Variant.Id, manip.EquipSlot, - manip.Entry); - return ret; - } - - public static bool DrawVariant(ref ImcManipulation manip, float unscaledWidth = 45) - { - var ret = IdInput("##imcVariant"u8, unscaledWidth, manip.Variant.Id, out var newId, 0, byte.MaxValue, false); - ImUtf8.HoverTooltip("Variant ID"u8); - if (ret) - manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, (byte)newId, manip.EquipSlot, - manip.Entry); - return ret; - } - - public static bool DrawSlot(ref ImcManipulation manip, float unscaledWidth = 100) - { - bool ret; - EquipSlot slot; - switch (manip.ObjectType) - { - case ObjectType.Equipment: - case ObjectType.DemiHuman: - ret = Combos.EqpEquipSlot("##slot", manip.EquipSlot, out slot, unscaledWidth); - break; - case ObjectType.Accessory: - ret = Combos.AccessorySlot("##slot", manip.EquipSlot, out slot, unscaledWidth); - break; - default: return false; - } - - ImUtf8.HoverTooltip("Equip Slot"u8); - if (ret) - manip = new ImcManipulation(manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, manip.Variant.Id, slot, - manip.Entry); - return ret; - } - - /// - /// A number input for ids with an optional max id of given width. - /// Returns true if newId changed against currentId. - /// - private static bool IdInput(ReadOnlySpan label, float unscaledWidth, ushort currentId, out ushort newId, int minId, int maxId, - bool border) - { - int tmp = currentId; - ImGui.SetNextItemWidth(unscaledWidth * ImUtf8.GlobalScale); - using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, UiHelpers.Scale, border); - using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, border); - if (ImUtf8.InputScalar(label, ref tmp)) - tmp = Math.Clamp(tmp, minId, maxId); - - newId = (ushort)tmp; - return newId != currentId; - } -}