mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-16 21:54:19 +01:00
Improve some IMC things.
This commit is contained in:
parent
fca1bf9d94
commit
992cdff58d
6 changed files with 267 additions and 185 deletions
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
||||||
Subproject commit 462acb87099650019996e4306d18cc70f76ca576
|
Subproject commit 1d9365164655a7cb38172e1311e15e19b1def6db
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
@ -134,7 +135,7 @@ public readonly record struct ImcIdentifier(
|
||||||
|
|
||||||
var b = BodySlot.CompareTo(other.BodySlot);
|
var b = BodySlot.CompareTo(other.BodySlot);
|
||||||
return b != 0 ? b : Variant.Id.CompareTo(other.Variant.Id);
|
return b != 0 ? b : Variant.Id.CompareTo(other.Variant.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImcIdentifier? FromJson(JObject jObj)
|
public static ImcIdentifier? FromJson(JObject jObj)
|
||||||
{
|
{
|
||||||
|
|
@ -177,11 +178,12 @@ public readonly record struct ImcIdentifier(
|
||||||
|
|
||||||
public JObject AddToJson(JObject jObj)
|
public JObject AddToJson(JObject jObj)
|
||||||
{
|
{
|
||||||
var (gender, race) = GenderRace.Split();
|
jObj["ObjectType"] = ObjectType.ToString();
|
||||||
jObj["Gender"] = gender.ToString();
|
jObj["PrimaryId"] = PrimaryId.Id;
|
||||||
jObj["Race"] = race.ToString();
|
jObj["PrimaryId"] = SecondaryId.Id;
|
||||||
jObj["SetId"] = SetId.Id.ToString();
|
jObj["Variant"] = Variant.Id;
|
||||||
jObj["Slot"] = Slot.ToString();
|
jObj["EquipSlot"] = EquipSlot.ToString();
|
||||||
|
jObj["BodySlot"] = BodySlot.ToString();
|
||||||
return jObj;
|
return jObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -352,26 +352,26 @@ public partial class ModEditWindow
|
||||||
|
|
||||||
// Identifier
|
// Identifier
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var change = MetaManipulationDrawer.DrawObjectType(ref _new);
|
var change = ImcManipulationDrawer.DrawObjectType(ref _new);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
change |= MetaManipulationDrawer.DrawPrimaryId(ref _new);
|
change |= ImcManipulationDrawer.DrawPrimaryId(ref _new);
|
||||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
||||||
new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y));
|
new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y));
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
// Equipment and accessories are slightly different imcs than other types.
|
// Equipment and accessories are slightly different imcs than other types.
|
||||||
if (_new.ObjectType is ObjectType.Equipment or ObjectType.Accessory)
|
if (_new.ObjectType is ObjectType.Equipment or ObjectType.Accessory)
|
||||||
change |= MetaManipulationDrawer.DrawSlot(ref _new);
|
change |= ImcManipulationDrawer.DrawSlot(ref _new);
|
||||||
else
|
else
|
||||||
change |= MetaManipulationDrawer.DrawSecondaryId(ref _new);
|
change |= ImcManipulationDrawer.DrawSecondaryId(ref _new);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
change |= MetaManipulationDrawer.DrawVariant(ref _new);
|
change |= ImcManipulationDrawer.DrawVariant(ref _new);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (_new.ObjectType is ObjectType.DemiHuman)
|
if (_new.ObjectType is ObjectType.DemiHuman)
|
||||||
change |= MetaManipulationDrawer.DrawSlot(ref _new, 70);
|
change |= ImcManipulationDrawer.DrawSlot(ref _new, 70);
|
||||||
else
|
else
|
||||||
ImGui.Dummy(new Vector2(70 * UiHelpers.Scale, 0));
|
ImGui.Dummy(new Vector2(70 * UiHelpers.Scale, 0));
|
||||||
|
|
||||||
|
|
@ -379,32 +379,20 @@ public partial class ModEditWindow
|
||||||
_new = _new.Copy(GetDefault(metaFileManager, _new) ?? new ImcEntry());
|
_new = _new.Copy(GetDefault(metaFileManager, _new) ?? new ImcEntry());
|
||||||
// Values
|
// Values
|
||||||
using var disabled = ImRaii.Disabled();
|
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)
|
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));
|
new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y));
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
var defaultEntry = GetDefault(metaFileManager, meta) ?? new ImcEntry();
|
var defaultEntry = GetDefault(metaFileManager, meta) ?? new ImcEntry();
|
||||||
if (IntDragInput("##imcMaterialId", $"Material ID\nDefault Value: {defaultEntry.MaterialId}", SmallIdWidth, meta.Entry.MaterialId,
|
var newEntry = meta.Entry;
|
||||||
defaultEntry.MaterialId, out var materialId, 1, byte.MaxValue, 0.01f))
|
|
||||||
editor.MetaEditor.Change(meta.Copy(meta.Entry with { MaterialId = (byte)materialId }));
|
|
||||||
|
|
||||||
|
var changes = ImcManipulationDrawer.DrawMaterialId(defaultEntry, ref newEntry, true);
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (IntDragInput("##imcMaterialAnimId", $"Material Animation ID\nDefault Value: {defaultEntry.MaterialAnimationId}", SmallIdWidth,
|
changes |= ImcManipulationDrawer.DrawMaterialAnimationId(defaultEntry, ref newEntry, true);
|
||||||
meta.Entry.MaterialAnimationId, defaultEntry.MaterialAnimationId, out var materialAnimId, 0, byte.MaxValue, 0.01f))
|
|
||||||
editor.MetaEditor.Change(meta.Copy(meta.Entry with { MaterialAnimationId = (byte)materialAnimId }));
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (IntDragInput("##imcDecalId", $"Decal ID\nDefault Value: {defaultEntry.DecalId}", SmallIdWidth, meta.Entry.DecalId,
|
changes |= ImcManipulationDrawer.DrawDecalId(defaultEntry, ref newEntry, true);
|
||||||
defaultEntry.DecalId, out var decalId, 0, byte.MaxValue, 0.01f))
|
|
||||||
editor.MetaEditor.Change(meta.Copy(meta.Entry with { DecalId = (byte)decalId }));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (IntDragInput("##imcVfxId", $"VFX ID\nDefault Value: {defaultEntry.VfxId}", SmallIdWidth, meta.Entry.VfxId, defaultEntry.VfxId,
|
changes |= ImcManipulationDrawer.DrawVfxId(defaultEntry, ref newEntry, true);
|
||||||
out var vfxId, 0, byte.MaxValue, 0.01f))
|
|
||||||
editor.MetaEditor.Change(meta.Copy(meta.Entry with { VfxId = (byte)vfxId }));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (IntDragInput("##imcSoundId", $"Sound ID\nDefault Value: {defaultEntry.SoundId}", SmallIdWidth, meta.Entry.SoundId,
|
changes |= ImcManipulationDrawer.DrawSoundId(defaultEntry, ref newEntry, true);
|
||||||
defaultEntry.SoundId, out var soundId, 0, 0b111111, 0.01f))
|
|
||||||
editor.MetaEditor.Change(meta.Copy(meta.Entry with { SoundId = (byte)soundId }));
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
for (var i = 0; i < 10; ++i)
|
changes |= ImcManipulationDrawer.DrawAttributes(defaultEntry, ref newEntry);
|
||||||
{
|
|
||||||
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 }));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
if (changes)
|
||||||
}
|
editor.MetaEditor.Change(meta.Copy(newEntry));
|
||||||
|
|
||||||
ImGui.NewLine();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,29 +80,29 @@ public class AddGroupDrawer : IUiService
|
||||||
|
|
||||||
private void DrawImcInput(float width)
|
private void DrawImcInput(float width)
|
||||||
{
|
{
|
||||||
var change = MetaManipulationDrawer.DrawObjectType(ref _imcManip, width);
|
var change = ImcManipulationDrawer.DrawObjectType(ref _imcManip, width);
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
change |= MetaManipulationDrawer.DrawPrimaryId(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawPrimaryId(ref _imcManip, width);
|
||||||
if (_imcManip.ObjectType is ObjectType.Weapon or ObjectType.Monster)
|
if (_imcManip.ObjectType is ObjectType.Weapon or ObjectType.Monster)
|
||||||
{
|
{
|
||||||
change |= MetaManipulationDrawer.DrawSecondaryId(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawSecondaryId(ref _imcManip, width);
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, width);
|
||||||
}
|
}
|
||||||
else if (_imcManip.ObjectType is ObjectType.DemiHuman)
|
else if (_imcManip.ObjectType is ObjectType.DemiHuman)
|
||||||
{
|
{
|
||||||
var quarterWidth = (width - ImUtf8.ItemInnerSpacing.X / ImUtf8.GlobalScale) / 2;
|
var quarterWidth = (width - ImUtf8.ItemInnerSpacing.X / ImUtf8.GlobalScale) / 2;
|
||||||
change |= MetaManipulationDrawer.DrawSecondaryId(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawSecondaryId(ref _imcManip, width);
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
change |= MetaManipulationDrawer.DrawSlot(ref _imcManip, quarterWidth);
|
change |= ImcManipulationDrawer.DrawSlot(ref _imcManip, quarterWidth);
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, quarterWidth);
|
change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, quarterWidth);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
change |= MetaManipulationDrawer.DrawSlot(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawSlot(ref _imcManip, width);
|
||||||
ImUtf8.SameLineInner();
|
ImUtf8.SameLineInner();
|
||||||
change |= MetaManipulationDrawer.DrawVariant(ref _imcManip, width);
|
change |= ImcManipulationDrawer.DrawVariant(ref _imcManip, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change)
|
if (change)
|
||||||
|
|
|
||||||
221
Penumbra/UI/ModsTab/ImcManipulationDrawer.cs
Normal file
221
Penumbra/UI/ModsTab/ImcManipulationDrawer.cs
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A number input for ids with an optional max id of given width.
|
||||||
|
/// Returns true if newId changed against currentId.
|
||||||
|
/// </summary>
|
||||||
|
private static bool IdInput(ReadOnlySpan<byte> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
private static bool DragInput<T>(ReadOnlySpan<byte> label, ReadOnlySpan<byte> tooltip, float width, T currentValue, T defaultValue,
|
||||||
|
out T newValue, T minValue, T maxValue, float speed, bool addDefault) where T : unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A checkmark that compares against a default value and shows a tooltip.
|
||||||
|
/// Returns true if newValue is changed against currentValue.
|
||||||
|
/// </summary>
|
||||||
|
private static bool Checkmark(ReadOnlySpan<byte> label, ReadOnlySpan<byte> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A number input for ids with an optional max id of given width.
|
|
||||||
/// Returns true if newId changed against currentId.
|
|
||||||
/// </summary>
|
|
||||||
private static bool IdInput(ReadOnlySpan<byte> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue