mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
917 lines
45 KiB
C#
917 lines
45 KiB
C#
using Dalamud.Interface;
|
|
using ImGuiNET;
|
|
using OtterGui;
|
|
using OtterGui.Raii;
|
|
using Penumbra.GameData.Enums;
|
|
using Penumbra.GameData.Structs;
|
|
using Penumbra.Interop.Structs;
|
|
using Penumbra.Meta;
|
|
using Penumbra.Meta.Files;
|
|
using Penumbra.Meta.Manipulations;
|
|
using Penumbra.Mods.Editor;
|
|
using Penumbra.UI.Classes;
|
|
|
|
namespace Penumbra.UI.AdvancedWindow;
|
|
|
|
public partial class ModEditWindow
|
|
{
|
|
private const string ModelSetIdTooltip =
|
|
"Model Set ID - You can usually find this as the 'e####' part of an item path.\nThis should generally not be left <= 1 unless you explicitly want that.";
|
|
|
|
private const string PrimaryIdTooltip =
|
|
"Primary ID - You can usually find this as the 'x####' part of an item path.\nThis should generally not be left <= 1 unless you explicitly want that.";
|
|
|
|
private const string ModelSetIdTooltipShort = "Model Set ID";
|
|
private const string EquipSlotTooltip = "Equip Slot";
|
|
private const string ModelRaceTooltip = "Model Race";
|
|
private const string GenderTooltip = "Gender";
|
|
private const string ObjectTypeTooltip = "Object Type";
|
|
private const string SecondaryIdTooltip = "Secondary ID";
|
|
private const string PrimaryIdTooltipShort = "Primary ID";
|
|
private const string VariantIdTooltip = "Variant ID";
|
|
private const string EstTypeTooltip = "EST Type";
|
|
private const string RacialTribeTooltip = "Racial Tribe";
|
|
private const string ScalingTypeTooltip = "Scaling Type";
|
|
|
|
private void DrawMetaTab()
|
|
{
|
|
using var tab = ImRaii.TabItem("Meta Manipulations");
|
|
if (!tab)
|
|
return;
|
|
|
|
DrawOptionSelectHeader();
|
|
|
|
var setsEqual = !_editor.MetaEditor.Changes;
|
|
var tt = setsEqual ? "No changes staged." : "Apply the currently staged changes to the option.";
|
|
ImGui.NewLine();
|
|
if (ImGuiUtil.DrawDisabledButton("Apply Changes", Vector2.Zero, tt, setsEqual))
|
|
_editor.MetaEditor.Apply(_editor.Option!);
|
|
|
|
ImGui.SameLine();
|
|
tt = setsEqual ? "No changes staged." : "Revert all currently staged changes.";
|
|
if (ImGuiUtil.DrawDisabledButton("Revert Changes", Vector2.Zero, tt, setsEqual))
|
|
_editor.MetaEditor.Load(_editor.Mod!, _editor.Option!);
|
|
|
|
ImGui.SameLine();
|
|
AddFromClipboardButton();
|
|
ImGui.SameLine();
|
|
SetFromClipboardButton();
|
|
ImGui.SameLine();
|
|
CopyToClipboardButton("Copy all current manipulations to clipboard.", _iconSize, _editor.MetaEditor.Recombine());
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Write as TexTools Files"))
|
|
_metaFileManager.WriteAllTexToolsMeta(Mod!);
|
|
|
|
using var child = ImRaii.Child("##meta", -Vector2.One, true);
|
|
if (!child)
|
|
return;
|
|
|
|
DrawEditHeader(_editor.MetaEditor.Eqp, "Equipment Parameter Edits (EQP)###EQP", 5, EqpRow.Draw, EqpRow.DrawNew,
|
|
_editor.MetaEditor.OtherEqpCount);
|
|
DrawEditHeader(_editor.MetaEditor.Eqdp, "Racial Model Edits (EQDP)###EQDP", 7, EqdpRow.Draw, EqdpRow.DrawNew,
|
|
_editor.MetaEditor.OtherEqdpCount);
|
|
DrawEditHeader(_editor.MetaEditor.Imc, "Variant Edits (IMC)###IMC", 10, ImcRow.Draw, ImcRow.DrawNew, _editor.MetaEditor.OtherImcCount);
|
|
DrawEditHeader(_editor.MetaEditor.Est, "Extra Skeleton Parameters (EST)###EST", 7, EstRow.Draw, EstRow.DrawNew,
|
|
_editor.MetaEditor.OtherEstCount);
|
|
DrawEditHeader(_editor.MetaEditor.Gmp, "Visor/Gimmick Edits (GMP)###GMP", 7, GmpRow.Draw, GmpRow.DrawNew,
|
|
_editor.MetaEditor.OtherGmpCount);
|
|
DrawEditHeader(_editor.MetaEditor.Rsp, "Racial Scaling Edits (RSP)###RSP", 5, RspRow.Draw, RspRow.DrawNew,
|
|
_editor.MetaEditor.OtherRspCount);
|
|
}
|
|
|
|
|
|
/// <summary> The headers for the different meta changes all have basically the same structure for different types.</summary>
|
|
private void DrawEditHeader<T>(IReadOnlyCollection<T> items, string label, int numColumns,
|
|
Action<MetaFileManager, T, ModEditor, Vector2> draw,
|
|
Action<MetaFileManager, ModEditor, Vector2> drawNew, int otherCount)
|
|
{
|
|
const ImGuiTableFlags flags = ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.BordersInnerV;
|
|
|
|
var oldPos = ImGui.GetCursorPosY();
|
|
var header = ImGui.CollapsingHeader($"{items.Count} {label}");
|
|
var newPos = ImGui.GetCursorPos();
|
|
if (otherCount > 0)
|
|
{
|
|
var text = $"{otherCount} Edits in other Options";
|
|
var size = ImGui.CalcTextSize(text).X;
|
|
ImGui.SetCursorPos(new Vector2(ImGui.GetContentRegionAvail().X - size, oldPos + ImGui.GetStyle().FramePadding.Y));
|
|
ImGuiUtil.TextColored(ColorId.RedundantAssignment.Value() | 0xFF000000, text);
|
|
ImGui.SetCursorPos(newPos);
|
|
}
|
|
|
|
if (!header)
|
|
return;
|
|
|
|
using (var table = ImRaii.Table(label, numColumns, flags))
|
|
{
|
|
if (table)
|
|
{
|
|
drawNew(_metaFileManager, _editor, _iconSize);
|
|
foreach (var (item, index) in items.ToArray().WithIndex())
|
|
{
|
|
using var id = ImRaii.PushId(index);
|
|
draw(_metaFileManager, item, _editor, _iconSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui.NewLine();
|
|
}
|
|
|
|
private static class EqpRow
|
|
{
|
|
private static EqpManipulation _new = new(Eqp.DefaultEntry, EquipSlot.Head, 1);
|
|
|
|
private static float IdWidth
|
|
=> 100 * UiHelpers.Scale;
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current EQP manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Eqp.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var canAdd = editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." : "This entry is already edited.";
|
|
var defaultEntry = ExpandedEqpFile.GetDefault(metaFileManager, _new.SetId);
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##eqpId", IdWidth, _new.SetId.Id, out var setId, 1, ExpandedEqpGmpBase.Count - 1, _new.SetId <= 1))
|
|
_new = new EqpManipulation(ExpandedEqpFile.GetDefault(metaFileManager, setId), _new.Slot, setId);
|
|
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.EqpEquipSlot("##eqpSlot", 100, _new.Slot, out var slot))
|
|
_new = new EqpManipulation(ExpandedEqpFile.GetDefault(metaFileManager, setId), slot, _new.SetId);
|
|
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
|
|
// Values
|
|
using var disabled = ImRaii.Disabled();
|
|
ImGui.TableNextColumn();
|
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
|
new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y));
|
|
foreach (var flag in Eqp.EqpAttributes[_new.Slot])
|
|
{
|
|
var value = defaultEntry.HasFlag(flag);
|
|
Checkmark("##eqp", flag.ToLocalName(), value, value, out _);
|
|
ImGui.SameLine();
|
|
}
|
|
|
|
ImGui.NewLine();
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, EqpManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.SetId.ToString());
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltipShort);
|
|
var defaultEntry = ExpandedEqpFile.GetDefault(metaFileManager, meta.SetId);
|
|
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Slot.ToName());
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
|
|
// Values
|
|
ImGui.TableNextColumn();
|
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
|
new Vector2(3 * UiHelpers.Scale, ImGui.GetStyle().ItemSpacing.Y));
|
|
var idx = 0;
|
|
foreach (var flag in Eqp.EqpAttributes[meta.Slot])
|
|
{
|
|
using var id = ImRaii.PushId(idx++);
|
|
var defaultValue = defaultEntry.HasFlag(flag);
|
|
var currentValue = meta.Entry.HasFlag(flag);
|
|
if (Checkmark("##eqp", flag.ToLocalName(), currentValue, defaultValue, out var value))
|
|
editor.MetaEditor.Change(meta.Copy(value ? meta.Entry | flag : meta.Entry & ~flag));
|
|
|
|
ImGui.SameLine();
|
|
}
|
|
|
|
ImGui.NewLine();
|
|
}
|
|
}
|
|
|
|
|
|
private static class EqdpRow
|
|
{
|
|
private static EqdpManipulation _new = new(EqdpEntry.Invalid, EquipSlot.Head, Gender.Male, ModelRace.Midlander, 1);
|
|
|
|
private static float IdWidth
|
|
=> 100 * UiHelpers.Scale;
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current EQDP manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Eqdp.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var raceCode = Names.CombinedRace(_new.Gender, _new.Race);
|
|
var validRaceCode = CharacterUtilityData.EqdpIdx(raceCode, false) >= 0;
|
|
var canAdd = validRaceCode && editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." :
|
|
validRaceCode ? "This entry is already edited." : "This combination of race and gender can not be used.";
|
|
var defaultEntry = validRaceCode
|
|
? ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(_new.Gender, _new.Race), _new.Slot.IsAccessory(), _new.SetId)
|
|
: 0;
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##eqdpId", IdWidth, _new.SetId.Id, out var setId, 0, ExpandedEqpGmpBase.Count - 1, _new.SetId <= 1))
|
|
{
|
|
var newDefaultEntry = ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(_new.Gender, _new.Race),
|
|
_new.Slot.IsAccessory(), setId);
|
|
_new = new EqdpManipulation(newDefaultEntry, _new.Slot, _new.Gender, _new.Race, setId);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.Race("##eqdpRace", _new.Race, out var race))
|
|
{
|
|
var newDefaultEntry = ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(_new.Gender, race),
|
|
_new.Slot.IsAccessory(), _new.SetId);
|
|
_new = new EqdpManipulation(newDefaultEntry, _new.Slot, _new.Gender, race, _new.SetId);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(ModelRaceTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.Gender("##eqdpGender", _new.Gender, out var gender))
|
|
{
|
|
var newDefaultEntry = ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(gender, _new.Race),
|
|
_new.Slot.IsAccessory(), _new.SetId);
|
|
_new = new EqdpManipulation(newDefaultEntry, _new.Slot, gender, _new.Race, _new.SetId);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(GenderTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.EqdpEquipSlot("##eqdpSlot", _new.Slot, out var slot))
|
|
{
|
|
var newDefaultEntry = ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(_new.Gender, _new.Race),
|
|
slot.IsAccessory(), _new.SetId);
|
|
_new = new EqdpManipulation(newDefaultEntry, slot, _new.Gender, _new.Race, _new.SetId);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
|
|
// Values
|
|
using var disabled = ImRaii.Disabled();
|
|
ImGui.TableNextColumn();
|
|
var (bit1, bit2) = defaultEntry.ToBits(_new.Slot);
|
|
Checkmark("Material##eqdpCheck1", string.Empty, bit1, bit1, out _);
|
|
ImGui.SameLine();
|
|
Checkmark("Model##eqdpCheck2", string.Empty, bit2, bit2, out _);
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, EqdpManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.SetId.ToString());
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltipShort);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Race.ToName());
|
|
ImGuiUtil.HoverTooltip(ModelRaceTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Gender.ToName());
|
|
ImGuiUtil.HoverTooltip(GenderTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Slot.ToName());
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
|
|
// Values
|
|
var defaultEntry = ExpandedEqdpFile.GetDefault(metaFileManager, Names.CombinedRace(meta.Gender, meta.Race), meta.Slot.IsAccessory(),
|
|
meta.SetId);
|
|
var (defaultBit1, defaultBit2) = defaultEntry.ToBits(meta.Slot);
|
|
var (bit1, bit2) = meta.Entry.ToBits(meta.Slot);
|
|
ImGui.TableNextColumn();
|
|
if (Checkmark("Material##eqdpCheck1", string.Empty, bit1, defaultBit1, out var newBit1))
|
|
editor.MetaEditor.Change(meta.Copy(Eqdp.FromSlotAndBits(meta.Slot, newBit1, bit2)));
|
|
|
|
ImGui.SameLine();
|
|
if (Checkmark("Model##eqdpCheck2", string.Empty, bit2, defaultBit2, out var newBit2))
|
|
editor.MetaEditor.Change(meta.Copy(Eqdp.FromSlotAndBits(meta.Slot, bit1, newBit2)));
|
|
}
|
|
}
|
|
|
|
private static class ImcRow
|
|
{
|
|
private static ImcManipulation _new = new(EquipSlot.Head, 1, 1, new ImcEntry());
|
|
|
|
private static float IdWidth
|
|
=> 80 * UiHelpers.Scale;
|
|
|
|
private static float SmallIdWidth
|
|
=> 45 * UiHelpers.Scale;
|
|
|
|
/// <summary> Convert throwing to null-return if the file does not exist. </summary>
|
|
private static ImcEntry? GetDefault(MetaFileManager metaFileManager, ImcManipulation imc)
|
|
{
|
|
try
|
|
{
|
|
return ImcFile.GetDefault(metaFileManager, imc.GamePath(), imc.EquipSlot, imc.Variant, out _);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current IMC manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Imc.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var defaultEntry = GetDefault(metaFileManager, _new);
|
|
var canAdd = defaultEntry != null && editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." : defaultEntry == null ? "This IMC file does not exist." : "This entry is already edited.";
|
|
defaultEntry ??= new ImcEntry();
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry.Value));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (Combos.ImcType("##imcType", _new.ObjectType, out var type))
|
|
{
|
|
var equipSlot = type switch
|
|
{
|
|
ObjectType.Equipment => _new.EquipSlot.IsEquipment() ? _new.EquipSlot : EquipSlot.Head,
|
|
ObjectType.DemiHuman => _new.EquipSlot.IsEquipment() ? _new.EquipSlot : EquipSlot.Head,
|
|
ObjectType.Accessory => _new.EquipSlot.IsAccessory() ? _new.EquipSlot : EquipSlot.Ears,
|
|
_ => EquipSlot.Unknown,
|
|
};
|
|
_new = new ImcManipulation(type, _new.BodySlot, _new.PrimaryId, _new.SecondaryId == 0 ? (ushort)1 : _new.SecondaryId,
|
|
_new.Variant.Id, equipSlot, _new.Entry);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(ObjectTypeTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##imcId", IdWidth, _new.PrimaryId.Id, out var setId, 0, ushort.MaxValue, _new.PrimaryId <= 1))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, setId, _new.SecondaryId, _new.Variant.Id, _new.EquipSlot, _new.Entry)
|
|
.Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(PrimaryIdTooltip);
|
|
|
|
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)
|
|
{
|
|
if (Combos.EqpEquipSlot("##imcSlot", 100, _new.EquipSlot, out var slot))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, _new.PrimaryId, _new.SecondaryId, _new.Variant.Id, slot,
|
|
_new.Entry)
|
|
.Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
}
|
|
else if (_new.ObjectType is ObjectType.Accessory)
|
|
{
|
|
if (Combos.AccessorySlot("##imcSlot", _new.EquipSlot, out var slot))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, _new.PrimaryId, _new.SecondaryId, _new.Variant.Id, slot,
|
|
_new.Entry)
|
|
.Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
}
|
|
else
|
|
{
|
|
if (IdInput("##imcId2", 100 * UiHelpers.Scale, _new.SecondaryId.Id, out var setId2, 0, ushort.MaxValue, false))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, _new.PrimaryId, setId2, _new.Variant.Id, _new.EquipSlot,
|
|
_new.Entry)
|
|
.Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(SecondaryIdTooltip);
|
|
}
|
|
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##imcVariant", SmallIdWidth, _new.Variant.Id, out var variant, 0, byte.MaxValue, false))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, _new.PrimaryId, _new.SecondaryId, variant, _new.EquipSlot,
|
|
_new.Entry).Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(VariantIdTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (_new.ObjectType is ObjectType.DemiHuman)
|
|
{
|
|
if (Combos.EqpEquipSlot("##imcSlot", 70, _new.EquipSlot, out var slot))
|
|
_new = new ImcManipulation(_new.ObjectType, _new.BodySlot, _new.PrimaryId, _new.SecondaryId, _new.Variant.Id, slot,
|
|
_new.Entry)
|
|
.Copy(GetDefault(metaFileManager, _new)
|
|
?? new ImcEntry());
|
|
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
}
|
|
else
|
|
{
|
|
ImGui.Dummy(new Vector2(70 * UiHelpers.Scale, 0));
|
|
}
|
|
|
|
|
|
// 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();
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, ImcManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.ObjectType.ToName());
|
|
ImGuiUtil.HoverTooltip(ObjectTypeTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.PrimaryId.ToString());
|
|
ImGuiUtil.HoverTooltip(PrimaryIdTooltipShort);
|
|
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
if (meta.ObjectType is ObjectType.Equipment or ObjectType.Accessory)
|
|
{
|
|
ImGui.TextUnformatted(meta.EquipSlot.ToName());
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextUnformatted(meta.SecondaryId.ToString());
|
|
ImGuiUtil.HoverTooltip(SecondaryIdTooltip);
|
|
}
|
|
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Variant.ToString());
|
|
ImGuiUtil.HoverTooltip(VariantIdTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
if (meta.ObjectType is ObjectType.DemiHuman)
|
|
{
|
|
ImGui.TextUnformatted(meta.EquipSlot.ToName());
|
|
ImGuiUtil.HoverTooltip(EquipSlotTooltip);
|
|
}
|
|
|
|
// Values
|
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing,
|
|
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 }));
|
|
|
|
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 }));
|
|
|
|
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 }));
|
|
|
|
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 }));
|
|
|
|
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 }));
|
|
|
|
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 }));
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
}
|
|
|
|
ImGui.NewLine();
|
|
}
|
|
}
|
|
|
|
private static class EstRow
|
|
{
|
|
private static EstManipulation _new = new(Gender.Male, ModelRace.Midlander, EstManipulation.EstType.Body, 1, 0);
|
|
|
|
private static float IdWidth
|
|
=> 100 * UiHelpers.Scale;
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current EST manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Est.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var canAdd = editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." : "This entry is already edited.";
|
|
var defaultEntry = EstFile.GetDefault(metaFileManager, _new.Slot, Names.CombinedRace(_new.Gender, _new.Race), _new.SetId);
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##estId", IdWidth, _new.SetId.Id, out var setId, 0, ExpandedEqpGmpBase.Count - 1, _new.SetId <= 1))
|
|
{
|
|
var newDefaultEntry = EstFile.GetDefault(metaFileManager, _new.Slot, Names.CombinedRace(_new.Gender, _new.Race), setId);
|
|
_new = new EstManipulation(_new.Gender, _new.Race, _new.Slot, setId, newDefaultEntry);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.Race("##estRace", _new.Race, out var race))
|
|
{
|
|
var newDefaultEntry = EstFile.GetDefault(metaFileManager, _new.Slot, Names.CombinedRace(_new.Gender, race), _new.SetId);
|
|
_new = new EstManipulation(_new.Gender, race, _new.Slot, _new.SetId, newDefaultEntry);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(ModelRaceTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.Gender("##estGender", _new.Gender, out var gender))
|
|
{
|
|
var newDefaultEntry = EstFile.GetDefault(metaFileManager, _new.Slot, Names.CombinedRace(gender, _new.Race), _new.SetId);
|
|
_new = new EstManipulation(gender, _new.Race, _new.Slot, _new.SetId, newDefaultEntry);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(GenderTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.EstSlot("##estSlot", _new.Slot, out var slot))
|
|
{
|
|
var newDefaultEntry = EstFile.GetDefault(metaFileManager, slot, Names.CombinedRace(_new.Gender, _new.Race), _new.SetId);
|
|
_new = new EstManipulation(_new.Gender, _new.Race, slot, _new.SetId, newDefaultEntry);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(EstTypeTooltip);
|
|
|
|
// Values
|
|
using var disabled = ImRaii.Disabled();
|
|
ImGui.TableNextColumn();
|
|
IntDragInput("##estSkeleton", "Skeleton Index", IdWidth, _new.Entry, defaultEntry, out _, 0, ushort.MaxValue, 0.05f);
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, EstManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.SetId.ToString());
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltipShort);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Race.ToName());
|
|
ImGuiUtil.HoverTooltip(ModelRaceTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Gender.ToName());
|
|
ImGuiUtil.HoverTooltip(GenderTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Slot.ToString());
|
|
ImGuiUtil.HoverTooltip(EstTypeTooltip);
|
|
|
|
// Values
|
|
var defaultEntry = EstFile.GetDefault(metaFileManager, meta.Slot, Names.CombinedRace(meta.Gender, meta.Race), meta.SetId);
|
|
ImGui.TableNextColumn();
|
|
if (IntDragInput("##estSkeleton", $"Skeleton Index\nDefault Value: {defaultEntry}", IdWidth, meta.Entry, defaultEntry,
|
|
out var entry, 0, ushort.MaxValue, 0.05f))
|
|
editor.MetaEditor.Change(meta.Copy((ushort)entry));
|
|
}
|
|
}
|
|
|
|
private static class GmpRow
|
|
{
|
|
private static GmpManipulation _new = new(GmpEntry.Default, 1);
|
|
|
|
private static float RotationWidth
|
|
=> 75 * UiHelpers.Scale;
|
|
|
|
private static float UnkWidth
|
|
=> 50 * UiHelpers.Scale;
|
|
|
|
private static float IdWidth
|
|
=> 100 * UiHelpers.Scale;
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current GMP manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Gmp.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var canAdd = editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." : "This entry is already edited.";
|
|
var defaultEntry = ExpandedGmpFile.GetDefault(metaFileManager, _new.SetId);
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (IdInput("##gmpId", IdWidth, _new.SetId.Id, out var setId, 1, ExpandedEqpGmpBase.Count - 1, _new.SetId <= 1))
|
|
_new = new GmpManipulation(ExpandedGmpFile.GetDefault(metaFileManager, setId), setId);
|
|
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltip);
|
|
|
|
// Values
|
|
using var disabled = ImRaii.Disabled();
|
|
ImGui.TableNextColumn();
|
|
Checkmark("##gmpEnabled", "Gimmick Enabled", defaultEntry.Enabled, defaultEntry.Enabled, out _);
|
|
ImGui.TableNextColumn();
|
|
Checkmark("##gmpAnimated", "Gimmick Animated", defaultEntry.Animated, defaultEntry.Animated, out _);
|
|
ImGui.TableNextColumn();
|
|
IntDragInput("##gmpRotationA", "Rotation A in Degrees", RotationWidth, defaultEntry.RotationA, defaultEntry.RotationA, out _, 0,
|
|
360, 0f);
|
|
ImGui.SameLine();
|
|
IntDragInput("##gmpRotationB", "Rotation B in Degrees", RotationWidth, defaultEntry.RotationB, defaultEntry.RotationB, out _, 0,
|
|
360, 0f);
|
|
ImGui.SameLine();
|
|
IntDragInput("##gmpRotationC", "Rotation C in Degrees", RotationWidth, defaultEntry.RotationC, defaultEntry.RotationC, out _, 0,
|
|
360, 0f);
|
|
ImGui.TableNextColumn();
|
|
IntDragInput("##gmpUnkA", "Animation Type A?", UnkWidth, defaultEntry.UnknownA, defaultEntry.UnknownA, out _, 0, 15, 0f);
|
|
ImGui.SameLine();
|
|
IntDragInput("##gmpUnkB", "Animation Type B?", UnkWidth, defaultEntry.UnknownB, defaultEntry.UnknownB, out _, 0, 15, 0f);
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, GmpManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.SetId.ToString());
|
|
ImGuiUtil.HoverTooltip(ModelSetIdTooltipShort);
|
|
|
|
// Values
|
|
var defaultEntry = ExpandedGmpFile.GetDefault(metaFileManager, meta.SetId);
|
|
ImGui.TableNextColumn();
|
|
if (Checkmark("##gmpEnabled", "Gimmick Enabled", meta.Entry.Enabled, defaultEntry.Enabled, out var enabled))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { Enabled = enabled }));
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Checkmark("##gmpAnimated", "Gimmick Animated", meta.Entry.Animated, defaultEntry.Animated, out var animated))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { Animated = animated }));
|
|
|
|
ImGui.TableNextColumn();
|
|
if (IntDragInput("##gmpRotationA", $"Rotation A in Degrees\nDefault Value: {defaultEntry.RotationA}", RotationWidth,
|
|
meta.Entry.RotationA, defaultEntry.RotationA, out var rotationA, 0, 360, 0.05f))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { RotationA = (ushort)rotationA }));
|
|
|
|
ImGui.SameLine();
|
|
if (IntDragInput("##gmpRotationB", $"Rotation B in Degrees\nDefault Value: {defaultEntry.RotationB}", RotationWidth,
|
|
meta.Entry.RotationB, defaultEntry.RotationB, out var rotationB, 0, 360, 0.05f))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { RotationB = (ushort)rotationB }));
|
|
|
|
ImGui.SameLine();
|
|
if (IntDragInput("##gmpRotationC", $"Rotation C in Degrees\nDefault Value: {defaultEntry.RotationC}", RotationWidth,
|
|
meta.Entry.RotationC, defaultEntry.RotationC, out var rotationC, 0, 360, 0.05f))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { RotationC = (ushort)rotationC }));
|
|
|
|
ImGui.TableNextColumn();
|
|
if (IntDragInput("##gmpUnkA", $"Animation Type A?\nDefault Value: {defaultEntry.UnknownA}", UnkWidth, meta.Entry.UnknownA,
|
|
defaultEntry.UnknownA, out var unkA, 0, 15, 0.01f))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { UnknownA = (byte)unkA }));
|
|
|
|
ImGui.SameLine();
|
|
if (IntDragInput("##gmpUnkB", $"Animation Type B?\nDefault Value: {defaultEntry.UnknownB}", UnkWidth, meta.Entry.UnknownB,
|
|
defaultEntry.UnknownB, out var unkB, 0, 15, 0.01f))
|
|
editor.MetaEditor.Change(meta.Copy(meta.Entry with { UnknownA = (byte)unkB }));
|
|
}
|
|
}
|
|
|
|
private static class RspRow
|
|
{
|
|
private static RspManipulation _new = new(SubRace.Midlander, RspAttribute.MaleMinSize, 1f);
|
|
|
|
private static float FloatWidth
|
|
=> 150 * UiHelpers.Scale;
|
|
|
|
public static void DrawNew(MetaFileManager metaFileManager, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy all current RSP manipulations to clipboard.", iconSize,
|
|
editor.MetaEditor.Rsp.Select(m => (MetaManipulation)m));
|
|
ImGui.TableNextColumn();
|
|
var canAdd = editor.MetaEditor.CanAdd(_new);
|
|
var tt = canAdd ? "Stage this edit." : "This entry is already edited.";
|
|
var defaultEntry = CmpFile.GetDefault(metaFileManager, _new.SubRace, _new.Attribute);
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), iconSize, tt, !canAdd, true))
|
|
editor.MetaEditor.Add(_new.Copy(defaultEntry));
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
if (Combos.SubRace("##rspSubRace", _new.SubRace, out var subRace))
|
|
_new = new RspManipulation(subRace, _new.Attribute, CmpFile.GetDefault(metaFileManager, subRace, _new.Attribute));
|
|
|
|
ImGuiUtil.HoverTooltip(RacialTribeTooltip);
|
|
|
|
ImGui.TableNextColumn();
|
|
if (Combos.RspAttribute("##rspAttribute", _new.Attribute, out var attribute))
|
|
_new = new RspManipulation(_new.SubRace, attribute, CmpFile.GetDefault(metaFileManager, subRace, attribute));
|
|
|
|
ImGuiUtil.HoverTooltip(ScalingTypeTooltip);
|
|
|
|
// Values
|
|
using var disabled = ImRaii.Disabled();
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetNextItemWidth(FloatWidth);
|
|
ImGui.DragFloat("##rspValue", ref defaultEntry, 0f);
|
|
}
|
|
|
|
public static void Draw(MetaFileManager metaFileManager, RspManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
DrawMetaButtons(meta, editor, iconSize);
|
|
|
|
// Identifier
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.SubRace.ToName());
|
|
ImGuiUtil.HoverTooltip(RacialTribeTooltip);
|
|
ImGui.TableNextColumn();
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetStyle().FramePadding.X);
|
|
ImGui.TextUnformatted(meta.Attribute.ToFullString());
|
|
ImGuiUtil.HoverTooltip(ScalingTypeTooltip);
|
|
ImGui.TableNextColumn();
|
|
|
|
// Values
|
|
var def = CmpFile.GetDefault(metaFileManager, meta.SubRace, meta.Attribute);
|
|
var value = meta.Entry;
|
|
ImGui.SetNextItemWidth(FloatWidth);
|
|
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
|
def < value ? ColorId.IncreasedMetaValue.Value() : ColorId.DecreasedMetaValue.Value(),
|
|
def != value);
|
|
if (ImGui.DragFloat("##rspValue", ref value, 0.001f, RspManipulation.MinValue, RspManipulation.MaxValue)
|
|
&& value is >= RspManipulation.MinValue and <= RspManipulation.MaxValue)
|
|
editor.MetaEditor.Change(meta.Copy(value));
|
|
|
|
ImGuiUtil.HoverTooltip($"Default Value: {def:0.###}");
|
|
}
|
|
}
|
|
|
|
// A number input for ids with a optional max id of given width.
|
|
// Returns true if newId changed against currentId.
|
|
private static bool IdInput(string label, float width, ushort currentId, out ushort newId, int minId, int maxId, bool border)
|
|
{
|
|
int tmp = currentId;
|
|
ImGui.SetNextItemWidth(width);
|
|
using var style = ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, UiHelpers.Scale, border);
|
|
using var color = ImRaii.PushColor(ImGuiCol.Border, Colors.RegexWarningBorder, border);
|
|
if (ImGui.InputInt(label, ref tmp, 0))
|
|
tmp = Math.Clamp(tmp, minId, maxId);
|
|
|
|
newId = (ushort)tmp;
|
|
return newId != currentId;
|
|
}
|
|
|
|
// A checkmark that compares against a default value and shows a tooltip.
|
|
// Returns true if newValue is changed against currentValue.
|
|
private static bool Checkmark(string label, string 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;
|
|
ImGui.Checkbox(label, ref newValue);
|
|
ImGuiUtil.HoverTooltip(tooltip, ImGuiHoveredFlags.AllowWhenDisabled);
|
|
return newValue != currentValue;
|
|
}
|
|
|
|
// 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 IntDragInput(string label, string tooltip, float width, int currentValue, int defaultValue, out int newValue,
|
|
int minValue, int maxValue, float speed)
|
|
{
|
|
newValue = currentValue;
|
|
using var color = ImRaii.PushColor(ImGuiCol.FrameBg,
|
|
defaultValue > currentValue ? ColorId.DecreasedMetaValue.Value() : ColorId.IncreasedMetaValue.Value(),
|
|
defaultValue != currentValue);
|
|
ImGui.SetNextItemWidth(width);
|
|
if (ImGui.DragInt(label, ref newValue, speed, minValue, maxValue))
|
|
newValue = Math.Clamp(newValue, minValue, maxValue);
|
|
|
|
ImGuiUtil.HoverTooltip(tooltip, ImGuiHoveredFlags.AllowWhenDisabled);
|
|
|
|
return newValue != currentValue;
|
|
}
|
|
|
|
private static void CopyToClipboardButton(string tooltip, Vector2 iconSize, IEnumerable<MetaManipulation> manipulations)
|
|
{
|
|
if (!ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), iconSize, tooltip, false, true))
|
|
return;
|
|
|
|
var text = Functions.ToCompressedBase64(manipulations, MetaManipulation.CurrentVersion);
|
|
if (text.Length > 0)
|
|
ImGui.SetClipboardText(text);
|
|
}
|
|
|
|
private void AddFromClipboardButton()
|
|
{
|
|
if (ImGui.Button("Add from Clipboard"))
|
|
{
|
|
var clipboard = ImGuiUtil.GetClipboardText();
|
|
|
|
var version = Functions.FromCompressedBase64<MetaManipulation[]>(clipboard, out var manips);
|
|
if (version == MetaManipulation.CurrentVersion && manips != null)
|
|
foreach (var manip in manips.Where(m => m.ManipulationType != MetaManipulation.Type.Unknown))
|
|
_editor.MetaEditor.Set(manip);
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(
|
|
"Try to add meta manipulations currently stored in the clipboard to the current manipulations.\nOverwrites already existing manipulations.");
|
|
}
|
|
|
|
private void SetFromClipboardButton()
|
|
{
|
|
if (ImGui.Button("Set from Clipboard"))
|
|
{
|
|
var clipboard = ImGuiUtil.GetClipboardText();
|
|
var version = Functions.FromCompressedBase64<MetaManipulation[]>(clipboard, out var manips);
|
|
if (version == MetaManipulation.CurrentVersion && manips != null)
|
|
{
|
|
_editor.MetaEditor.Clear();
|
|
foreach (var manip in manips.Where(m => m.ManipulationType != MetaManipulation.Type.Unknown))
|
|
_editor.MetaEditor.Set(manip);
|
|
}
|
|
}
|
|
|
|
ImGuiUtil.HoverTooltip(
|
|
"Try to set the current meta manipulations to the set currently stored in the clipboard.\nRemoves all other manipulations.");
|
|
}
|
|
|
|
private static void DrawMetaButtons(MetaManipulation meta, ModEditor editor, Vector2 iconSize)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
CopyToClipboardButton("Copy this manipulation to clipboard.", iconSize, Array.Empty<MetaManipulation>().Append(meta));
|
|
|
|
ImGui.TableNextColumn();
|
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), iconSize, "Delete this meta manipulation.", false, true))
|
|
editor.MetaEditor.Delete(meta);
|
|
}
|
|
}
|