mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Added more detailed information about metadata changes on click on value, as well as option to edit them or add new ones.
This commit is contained in:
parent
068b1e074b
commit
83cad76b62
9 changed files with 950 additions and 166 deletions
|
|
@ -32,7 +32,7 @@ namespace Penumbra.Game
|
||||||
LegsHideBootsM = 0x08ul << 16,
|
LegsHideBootsM = 0x08ul << 16,
|
||||||
_20 = 0x10ul << 16,
|
_20 = 0x10ul << 16,
|
||||||
LegsShowFoot = 0x20ul << 16,
|
LegsShowFoot = 0x20ul << 16,
|
||||||
_22 = 0x40ul << 16,
|
LegsShowTail = 0x40ul << 16,
|
||||||
_23 = 0x80ul << 16,
|
_23 = 0x80ul << 16,
|
||||||
LegsMask = 0xFFul << 16,
|
LegsMask = 0xFFul << 16,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,35 @@ namespace Penumbra.Meta.Files
|
||||||
public static ulong ToInteger( this ImcFile.ImageChangeData imc )
|
public static ulong ToInteger( this ImcFile.ImageChangeData imc )
|
||||||
{
|
{
|
||||||
ulong ret = imc.MaterialId;
|
ulong ret = imc.MaterialId;
|
||||||
ret |= ( ulong )imc.DecalId << 8;
|
ret |= ( ulong )imc.DecalId << 8;
|
||||||
ret |= ( ulong )imc.AttributeMask << 16;
|
ret |= ( ulong )imc.AttributeMask << 16;
|
||||||
ret |= ( ulong )imc.SoundId << 16;
|
ret |= ( ulong )imc.SoundId << 16;
|
||||||
ret |= ( ulong )imc.VfxId << 32;
|
ret |= ( ulong )imc.VfxId << 32;
|
||||||
|
ret |= ( ulong )imc.ActualMaterialAnimationId() << 40;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte ActualMaterialAnimationId( this ImcFile.ImageChangeData imc )
|
||||||
|
{
|
||||||
var tmp = imc.GetType().GetField( "_MaterialAnimationIdMask",
|
var tmp = imc.GetType().GetField( "_MaterialAnimationIdMask",
|
||||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance );
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance );
|
||||||
ret |= ( ulong )( byte )tmp!.GetValue( imc ) << 40;
|
return ( byte )( tmp?.GetValue( imc ) ?? 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImcFile.ImageChangeData FromValues( byte materialId, byte decalId, ushort attributeMask, byte soundId, byte vfxId,
|
||||||
|
byte materialAnimationId )
|
||||||
|
{
|
||||||
|
var ret = new ImcFile.ImageChangeData()
|
||||||
|
{
|
||||||
|
DecalId = decalId,
|
||||||
|
MaterialId = materialId,
|
||||||
|
VfxId = vfxId,
|
||||||
|
};
|
||||||
|
ret.GetType().GetField( "_AttributeAndSound",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance )!
|
||||||
|
.SetValue( ret, ( ushort )( ( attributeMask & 0x3FF ) | ( soundId << 10 ) ) );
|
||||||
|
ret.GetType().GetField( "_AttributeAndSound",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance )!.SetValue( ret, materialAnimationId );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +67,7 @@ namespace Penumbra.Meta.Files
|
||||||
bw.Write( variant.DecalId );
|
bw.Write( variant.DecalId );
|
||||||
bw.Write( ( ushort )( variant.AttributeMask | variant.SoundId ) );
|
bw.Write( ( ushort )( variant.AttributeMask | variant.SoundId ) );
|
||||||
bw.Write( variant.VfxId );
|
bw.Write( variant.VfxId );
|
||||||
bw.Write( variant.MaterialAnimationId );
|
bw.Write( variant.ActualMaterialAnimationId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] WriteBytes( this ImcFile file )
|
public static byte[] WriteBytes( this ImcFile file )
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,24 @@ namespace Penumbra.Meta.Files
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object? GetDefaultValue( MetaManipulation m )
|
||||||
|
{
|
||||||
|
return m.Type switch
|
||||||
|
{
|
||||||
|
MetaType.Imc => GetDefaultImcFile( m.ImcIdentifier.ObjectType, m.ImcIdentifier.PrimaryId, m.ImcIdentifier.SecondaryId )
|
||||||
|
?.GetValue( m ),
|
||||||
|
MetaType.Gmp => GetDefaultGmpFile()?.GetEntry( m.GmpIdentifier.SetId ),
|
||||||
|
MetaType.Eqp => GetDefaultEqpFile()?.GetEntry( m.EqpIdentifier.SetId )
|
||||||
|
.Reduce( m.EqpIdentifier.Slot ),
|
||||||
|
MetaType.Eqdp => GetDefaultEqdpFile( m.EqdpIdentifier.Slot, m.EqdpIdentifier.GenderRace )?.GetEntry( m.EqdpIdentifier.SetId )
|
||||||
|
.Reduce( m.EqdpIdentifier.Slot ),
|
||||||
|
MetaType.Est => GetDefaultEstFile( m.EstIdentifier.ObjectType, m.EstIdentifier.EquipSlot, m.EstIdentifier.BodySlot )
|
||||||
|
?.GetEntry( m.EstIdentifier.GenderRace, m.EstIdentifier.PrimaryId ),
|
||||||
|
MetaType.Rsp => GetDefaultCmpFile()?[ m.RspIdentifier.SubRace ][ m.RspIdentifier.Attribute ],
|
||||||
|
_ => throw new NotImplementedException(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Create a deep copy of a default file as a new file.
|
// Create a deep copy of a default file as a new file.
|
||||||
public object? CreateNewFile( MetaManipulation m )
|
public object? CreateNewFile( MetaManipulation m )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateCollections( ModData mod, bool metaChanges, ResourceChange fileChanges, bool nameChange, bool recomputeMeta )
|
internal void UpdateCollections( ModData mod, bool metaChanges, ResourceChange fileChanges, bool nameChange, bool reloadMeta )
|
||||||
{
|
{
|
||||||
foreach( var collection in Collections.Values )
|
foreach( var collection in Collections.Values )
|
||||||
{
|
{
|
||||||
|
|
@ -70,13 +70,13 @@ namespace Penumbra.Mods
|
||||||
collection.Cache?.CalculateEffectiveFileList();
|
collection.Cache?.CalculateEffectiveFileList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( recomputeMeta )
|
if( reloadMeta )
|
||||||
{
|
{
|
||||||
collection.Cache?.UpdateMetaManipulations();
|
collection.Cache?.UpdateMetaManipulations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( recomputeMeta )
|
if( reloadMeta && ActiveCollection.Settings.TryGetValue( mod.BasePath.Name, out var config ) && config.Enabled )
|
||||||
{
|
{
|
||||||
Service< GameResourceManagement >.Get().ReloadPlayerResources();
|
Service< GameResourceManagement >.Get().ReloadPlayerResources();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ namespace Penumbra.Mods
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool UpdateMod( ModData mod, bool recomputeMeta = false )
|
public bool UpdateMod( ModData mod, bool reloadMeta = false, bool recomputeMeta = false )
|
||||||
{
|
{
|
||||||
var oldName = mod.Meta.Name;
|
var oldName = mod.Meta.Name;
|
||||||
var metaChanges = mod.Meta.RefreshFromFile( mod.MetaFile );
|
var metaChanges = mod.Meta.RefreshFromFile( mod.MetaFile );
|
||||||
|
|
@ -177,7 +177,7 @@ namespace Penumbra.Mods
|
||||||
mod.Resources.MetaManipulations.SaveToFile( MetaCollection.FileName( mod.BasePath ) );
|
mod.Resources.MetaManipulations.SaveToFile( MetaCollection.FileName( mod.BasePath ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.UpdateCollections( mod, metaChanges, fileChanges, nameChange, recomputeMeta );
|
Collections.UpdateCollections( mod, metaChanges, fileChanges, nameChange, reloadMeta );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,13 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
private const float OptionSelectionWidth = 140f;
|
private const float OptionSelectionWidth = 140f;
|
||||||
private const float CheckMarkSize = 50f;
|
private const float CheckMarkSize = 50f;
|
||||||
|
private const uint ColorDarkGreen = 0xFF00A000;
|
||||||
private const uint ColorGreen = 0xFF00C800;
|
private const uint ColorGreen = 0xFF00C800;
|
||||||
private const uint ColorYellow = 0xFF00C8C8;
|
private const uint ColorYellow = 0xFF00C8C8;
|
||||||
|
private const uint ColorDarkRed = 0xFF0000A0;
|
||||||
private const uint ColorRed = 0xFF0000C8;
|
private const uint ColorRed = 0xFF0000C8;
|
||||||
|
|
||||||
|
|
||||||
private bool _editMode;
|
private bool _editMode;
|
||||||
private int _selectedGroupIndex;
|
private int _selectedGroupIndex;
|
||||||
private OptionGroup? _selectedGroup;
|
private OptionGroup? _selectedGroup;
|
||||||
|
|
@ -649,149 +652,6 @@ namespace Penumbra.UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawManipulationRow( MetaManipulation manip )
|
|
||||||
{
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.Type.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
|
|
||||||
switch( manip.Type )
|
|
||||||
{
|
|
||||||
case MetaType.Eqp:
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.EqpIdentifier.Slot.IsAccessory()
|
|
||||||
? ObjectType.Accessory.ToString()
|
|
||||||
: ObjectType.Equipment.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EqpIdentifier.SetId.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EqpIdentifier.Slot.ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MetaType.Gmp:
|
|
||||||
{
|
|
||||||
ImGui.Text( ObjectType.Equipment.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.GmpIdentifier.SetId.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( EquipSlot.Head.ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MetaType.Eqdp:
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.EqpIdentifier.Slot.IsAccessory()
|
|
||||||
? ObjectType.Accessory.ToString()
|
|
||||||
: ObjectType.Equipment.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EqdpIdentifier.SetId.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EqpIdentifier.Slot.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
var (gender, race) = manip.EqdpIdentifier.GenderRace.Split();
|
|
||||||
ImGui.Text( race.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( gender.ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MetaType.Est:
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.EstIdentifier.ObjectType.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EstIdentifier.PrimaryId.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.EstIdentifier.ObjectType == ObjectType.Equipment
|
|
||||||
? manip.EstIdentifier.EquipSlot.ToString()
|
|
||||||
: manip.EstIdentifier.BodySlot.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
var (gender, race) = manip.EstIdentifier.GenderRace.Split();
|
|
||||||
ImGui.Text( race.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( gender.ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MetaType.Imc:
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.ImcIdentifier.ObjectType.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.ImcIdentifier.PrimaryId.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if( manip.ImcIdentifier.ObjectType == ObjectType.Accessory
|
|
||||||
|| manip.ImcIdentifier.ObjectType == ObjectType.Equipment )
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.ImcIdentifier.ObjectType == ObjectType.Equipment
|
|
||||||
|| manip.ImcIdentifier.ObjectType == ObjectType.Accessory
|
|
||||||
? manip.ImcIdentifier.EquipSlot.ToString()
|
|
||||||
: manip.ImcIdentifier.BodySlot.ToString() );
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if( manip.ImcIdentifier.ObjectType != ObjectType.Equipment
|
|
||||||
&& manip.ImcIdentifier.ObjectType != ObjectType.Accessory )
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.ImcIdentifier.SecondaryId.ToString() );
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.ImcIdentifier.Variant.ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MetaType.Rsp:
|
|
||||||
{
|
|
||||||
ImGui.Text( manip.RspIdentifier.Attribute.ToUngenderedString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.RspIdentifier.SubRace.ToString() );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( manip.RspIdentifier.Attribute.ToGender().ToString() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableSetColumnIndex( 9 );
|
|
||||||
ImGui.Text( manip.Type == MetaType.Rsp ? manip.RspValue.ToString( CultureInfo.InvariantCulture ) : manip.Value.ToString() );
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DrawMetaManipulationsTable( string label, List< MetaManipulation > list )
|
|
||||||
{
|
|
||||||
if( list.Count == 0
|
|
||||||
|| !ImGui.BeginTable( label, 10,
|
|
||||||
ImGuiTableFlags.BordersInner | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Type##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Object Type##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Set##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Slot##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Race##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Gender##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Secondary ID##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Variant##{label}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableHeader( $"Value##{label}" );
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
foreach( var manip in list )
|
|
||||||
{
|
|
||||||
DrawManipulationRow( manip );
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawMetaManipulationsTab()
|
private void DrawMetaManipulationsTab()
|
||||||
{
|
{
|
||||||
if( Mod.Data.Resources.MetaManipulations.Count == 0 )
|
if( Mod.Data.Resources.MetaManipulations.Count == 0 )
|
||||||
|
|
@ -806,26 +666,33 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
if( ImGui.BeginListBox( "##MetaManipulations", AutoFillSize ) )
|
if( ImGui.BeginListBox( "##MetaManipulations", AutoFillSize ) )
|
||||||
{
|
{
|
||||||
var manips = Mod.Data.Resources.MetaManipulations;
|
var manips = Mod.Data.Resources.MetaManipulations;
|
||||||
if( manips.DefaultData.Count > 0 )
|
var changes = false;
|
||||||
|
if( _editMode || manips.DefaultData.Count > 0 )
|
||||||
{
|
{
|
||||||
if( ImGui.CollapsingHeader( "Default" ) )
|
if( ImGui.CollapsingHeader( "Default" ) )
|
||||||
{
|
{
|
||||||
DrawMetaManipulationsTable( "##DefaultManips", manips.DefaultData );
|
changes = DrawMetaManipulationsTable( "##DefaultManips", manips.DefaultData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( var group in manips.GroupData )
|
foreach( var group in manips.GroupData )
|
||||||
{
|
{
|
||||||
foreach( var option in @group.Value )
|
foreach( var option in group.Value )
|
||||||
{
|
{
|
||||||
if( ImGui.CollapsingHeader( $"{@group.Key} - {option.Key}" ) )
|
if( ImGui.CollapsingHeader( $"{group.Key} - {option.Key}" ) )
|
||||||
{
|
{
|
||||||
DrawMetaManipulationsTable( $"##{@group.Key}{option.Key}manips", option.Value );
|
changes |= DrawMetaManipulationsTable( $"##{group.Key}{option.Key}manips", option.Value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( changes )
|
||||||
|
{
|
||||||
|
Mod.Data.Resources.MetaManipulations.SaveToFile( MetaCollection.FileName( Mod.Data.BasePath ) );
|
||||||
|
_selector.ReloadCurrentMod( true, false );
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.EndListBox();
|
ImGui.EndListBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,877 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Lumina.Data.Files;
|
||||||
|
using Penumbra.Game;
|
||||||
|
using Penumbra.Game.Enums;
|
||||||
|
using Penumbra.Meta;
|
||||||
|
using Penumbra.Meta.Files;
|
||||||
|
using Penumbra.Util;
|
||||||
|
using ObjectType = Penumbra.Game.Enums.ObjectType;
|
||||||
|
|
||||||
|
namespace Penumbra.UI
|
||||||
|
{
|
||||||
|
public partial class SettingsInterface
|
||||||
|
{
|
||||||
|
private partial class PluginDetails
|
||||||
|
{
|
||||||
|
private int _newManipTypeIdx = 0;
|
||||||
|
private ushort _newManipSetId = 0;
|
||||||
|
private ushort _newManipSecondaryId = 0;
|
||||||
|
private int _newManipSubrace = 0;
|
||||||
|
private int _newManipRace = 0;
|
||||||
|
private int _newManipAttribute = 0;
|
||||||
|
private int _newManipEquipSlot = 0;
|
||||||
|
private int _newManipObjectType = 0;
|
||||||
|
private int _newManipGender = 0;
|
||||||
|
private int _newManipBodySlot = 0;
|
||||||
|
private ushort _newManipVariant = 0;
|
||||||
|
|
||||||
|
private static readonly (string, EqpEntry)[] EqpAttributesBody =
|
||||||
|
{
|
||||||
|
( "Enabled", EqpEntry.BodyEnabled ),
|
||||||
|
( "Hide Waist", EqpEntry.BodyHideWaist ),
|
||||||
|
( "Hide Small Gloves", EqpEntry.BodyHideGlovesS ),
|
||||||
|
( "Hide Medium Gloves", EqpEntry.BodyHideGlovesM ),
|
||||||
|
( "Hide Large Gloves", EqpEntry.BodyHideGlovesL ),
|
||||||
|
( "Hide Gorget", EqpEntry.BodyHideGorget ),
|
||||||
|
( "Show Legs", EqpEntry.BodyShowLeg ),
|
||||||
|
( "Show Hands", EqpEntry.BodyShowHand ),
|
||||||
|
( "Show Head", EqpEntry.BodyShowHead ),
|
||||||
|
( "Show Necklace", EqpEntry.BodyShowNecklace ),
|
||||||
|
( "Show Bracelet", EqpEntry.BodyShowBracelet ),
|
||||||
|
( "Show Tail", EqpEntry.BodyShowTail ),
|
||||||
|
( "Unknown 2", EqpEntry._2 ),
|
||||||
|
( "Unknown 4", EqpEntry._4 ),
|
||||||
|
( "Unknown 14", EqpEntry._14 ),
|
||||||
|
( "Unknown 15", EqpEntry._15 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EqpEntry)[] EqpAttributesLegs =
|
||||||
|
{
|
||||||
|
( "Enabled", EqpEntry.LegsEnabled ),
|
||||||
|
( "Hide Kneepads", EqpEntry.LegsHideKneePads ),
|
||||||
|
( "Hide Small Boots", EqpEntry.LegsHideBootsS ),
|
||||||
|
( "Hide Medium Boots", EqpEntry.LegsHideBootsM ),
|
||||||
|
( "Hide Show Foot", EqpEntry.LegsShowFoot ),
|
||||||
|
( "Hide Show Tail", EqpEntry.LegsShowTail ),
|
||||||
|
( "Unknown 20", EqpEntry._20 ),
|
||||||
|
( "Unknown 23", EqpEntry._23 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EqpEntry)[] EqpAttributesHands =
|
||||||
|
{
|
||||||
|
( "Enabled", EqpEntry.HandsEnabled ),
|
||||||
|
( "Hide Elbow", EqpEntry.HandsHideElbow ),
|
||||||
|
( "Hide Forearm", EqpEntry.HandsHideForearm ),
|
||||||
|
( "Show Bracelet", EqpEntry.HandShowBracelet ),
|
||||||
|
( "Show Left Ring", EqpEntry.HandShowRingL ),
|
||||||
|
( "Show Right Ring", EqpEntry.HandShowRingR ),
|
||||||
|
( "Unknown 27", EqpEntry._27 ),
|
||||||
|
( "Unknown 31", EqpEntry._31 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EqpEntry)[] EqpAttributesFeet =
|
||||||
|
{
|
||||||
|
( "Enabled", EqpEntry.FeetEnabled ),
|
||||||
|
( "Hide Knees", EqpEntry.FeetHideKnee ),
|
||||||
|
( "Hide Calfs", EqpEntry.FeetHideCalf ),
|
||||||
|
( "Hide Ankles", EqpEntry.FeetHideAnkle ),
|
||||||
|
( "Unknown 36", EqpEntry._36 ),
|
||||||
|
( "Unknown 37", EqpEntry._37 ),
|
||||||
|
( "Unknown 38", EqpEntry._38 ),
|
||||||
|
( "Unknown 39", EqpEntry._39 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EqpEntry)[] EqpAttributesHead =
|
||||||
|
{
|
||||||
|
( "Enabled", EqpEntry.HeadEnabled ),
|
||||||
|
( "Hide Scalp", EqpEntry.HeadHideScalp ),
|
||||||
|
( "Hide Hair", EqpEntry.HeadHideHair ),
|
||||||
|
( "Show Hair Override", EqpEntry.HeadShowHairOverride ),
|
||||||
|
( "Hide Neck", EqpEntry.HeadHideNeck ),
|
||||||
|
( "Show Necklace", EqpEntry.HeadShowNecklace ),
|
||||||
|
( "Show Earrings", EqpEntry.HeadShowEarrings ),
|
||||||
|
( "Show Earrings (Human)", EqpEntry.HeadShowEarringsHuman ),
|
||||||
|
( "Show Earrings (Au Ra)", EqpEntry.HeadShowEarringsAura ),
|
||||||
|
( "Show Ears (Human)", EqpEntry.HeadShowEarHuman ),
|
||||||
|
( "Show Ears (Miqo'te)", EqpEntry.HeadShowEarMiqote ),
|
||||||
|
( "Show Ears (Au Ra)", EqpEntry.HeadShowEarAuRa ),
|
||||||
|
( "Show Ears (Viera)", EqpEntry.HeadShowEarViera ),
|
||||||
|
( "Show on Hrothgar", EqpEntry.HeadShowHrothgarHat ),
|
||||||
|
( "Show on Viera", EqpEntry.HeadShowVieraHat ),
|
||||||
|
( "Unknown 46", EqpEntry._46 ),
|
||||||
|
( "Unknown 54", EqpEntry._54 ),
|
||||||
|
( "Unknown 55", EqpEntry._55 ),
|
||||||
|
( "Unknown 58", EqpEntry._58 ),
|
||||||
|
( "Unknown 59", EqpEntry._59 ),
|
||||||
|
( "Unknown 60", EqpEntry._60 ),
|
||||||
|
( "Unknown 61", EqpEntry._61 ),
|
||||||
|
( "Unknown 62", EqpEntry._62 ),
|
||||||
|
( "Unknown 63", EqpEntry._63 ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EquipSlot)[] EqpEquipSlots = new[]
|
||||||
|
{
|
||||||
|
( "Head", EquipSlot.Head ),
|
||||||
|
( "Body", EquipSlot.Body ),
|
||||||
|
( "Hands", EquipSlot.Hands ),
|
||||||
|
( "Legs", EquipSlot.Legs ),
|
||||||
|
( "Feet", EquipSlot.Feet ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EquipSlot)[] EqdpEquipSlots = new[]
|
||||||
|
{
|
||||||
|
EqpEquipSlots[ 0 ],
|
||||||
|
EqpEquipSlots[ 1 ],
|
||||||
|
EqpEquipSlots[ 2 ],
|
||||||
|
EqpEquipSlots[ 3 ],
|
||||||
|
EqpEquipSlots[ 4 ],
|
||||||
|
( "Ears", EquipSlot.Ears ),
|
||||||
|
( "Neck", EquipSlot.Neck ),
|
||||||
|
( "Wrist", EquipSlot.Wrists ),
|
||||||
|
( "Left Finger", EquipSlot.RingL ),
|
||||||
|
( "Right Finger", EquipSlot.RingR ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, Race)[] Races = new[]
|
||||||
|
{
|
||||||
|
( "Midlander", Race.Midlander ),
|
||||||
|
( "Highlander", Race.Highlander ),
|
||||||
|
( "Elezen", Race.Elezen ),
|
||||||
|
( "Miqo'te", Race.Miqote ),
|
||||||
|
( "Roegadyn", Race.Roegadyn ),
|
||||||
|
( "Lalafell", Race.Lalafell ),
|
||||||
|
( "Au Ra", Race.AuRa ),
|
||||||
|
( "Viera", Race.Viera ),
|
||||||
|
( "Hrothgar", Race.Hrothgar ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, Gender)[] Genders = new[]
|
||||||
|
{
|
||||||
|
( "Male", Gender.Male ),
|
||||||
|
( "Female", Gender.Female ),
|
||||||
|
( "Male (NPC)", Gender.MaleNpc ),
|
||||||
|
( "Female (NPC)", Gender.FemaleNpc ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, ObjectType)[] ObjectTypes = new[]
|
||||||
|
{
|
||||||
|
( "Equipment", ObjectType.Equipment ),
|
||||||
|
( "Customization", ObjectType.Character ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, EquipSlot)[] EstEquipSlots = new[]
|
||||||
|
{
|
||||||
|
EqpEquipSlots[ 0 ],
|
||||||
|
EqpEquipSlots[ 1 ],
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, BodySlot)[] EstBodySlots = new[]
|
||||||
|
{
|
||||||
|
( "Hair", BodySlot.Hair ),
|
||||||
|
( "Face", BodySlot.Face ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, SubRace)[] Subraces = new[]
|
||||||
|
{
|
||||||
|
( "Midlander", SubRace.Midlander ),
|
||||||
|
( "Highlander", SubRace.Highlander ),
|
||||||
|
( "Wildwood", SubRace.Wildwood ),
|
||||||
|
( "Duskwright", SubRace.Duskwright ),
|
||||||
|
( "Seeker Of The Sun", SubRace.SeekerOfTheSun ),
|
||||||
|
( "Keeper Of The Moon", SubRace.KeeperOfTheMoon ),
|
||||||
|
( "Seawolf", SubRace.Seawolf ),
|
||||||
|
( "Hellsguard", SubRace.Hellsguard ),
|
||||||
|
( "Plainsfolk", SubRace.Plainsfolk ),
|
||||||
|
( "Dunesfolk", SubRace.Dunesfolk ),
|
||||||
|
( "Raen", SubRace.Raen ),
|
||||||
|
( "Xaela", SubRace.Xaela ),
|
||||||
|
( "Rava", SubRace.Rava ),
|
||||||
|
( "Veena", SubRace.Veena ),
|
||||||
|
( "Hellion", SubRace.Hellion ),
|
||||||
|
( "Lost", SubRace.Lost ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, RspAttribute)[] RspAttributes = new[]
|
||||||
|
{
|
||||||
|
( "Male Minimum Size", RspAttribute.MaleMinSize ),
|
||||||
|
( "Male Maximum Size", RspAttribute.MaleMaxSize ),
|
||||||
|
( "Female Minimum Size", RspAttribute.FemaleMinSize ),
|
||||||
|
( "Female Maximum Size", RspAttribute.FemaleMaxSize ),
|
||||||
|
( "Bust Minimum X-Axis", RspAttribute.BustMinX ),
|
||||||
|
( "Bust Maximum X-Axis", RspAttribute.BustMaxX ),
|
||||||
|
( "Bust Minimum Y-Axis", RspAttribute.BustMinY ),
|
||||||
|
( "Bust Maximum Y-Axis", RspAttribute.BustMaxY ),
|
||||||
|
( "Bust Minimum Z-Axis", RspAttribute.BustMinZ ),
|
||||||
|
( "Bust Maximum Z-Axis", RspAttribute.BustMaxZ ),
|
||||||
|
( "Male Minimum Tail Length", RspAttribute.MaleMinTail ),
|
||||||
|
( "Male Maximum Tail Length", RspAttribute.MaleMaxTail ),
|
||||||
|
( "Female Minimum Tail Length", RspAttribute.FemaleMinTail ),
|
||||||
|
( "Female Maximum Tail Length", RspAttribute.FemaleMaxTail ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, ObjectType)[] ImcObjectType = new[]
|
||||||
|
{
|
||||||
|
ObjectTypes[ 0 ],
|
||||||
|
( "Weapon", ObjectType.Weapon ),
|
||||||
|
( "Demihuman", ObjectType.DemiHuman ),
|
||||||
|
( "Monster", ObjectType.Monster ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly (string, BodySlot)[] ImcBodySlots = new[]
|
||||||
|
{
|
||||||
|
EstBodySlots[ 0 ],
|
||||||
|
EstBodySlots[ 1 ],
|
||||||
|
( "Body", BodySlot.Body ),
|
||||||
|
( "Tail", BodySlot.Tail ),
|
||||||
|
( "Ears", BodySlot.Zear ),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static bool PrintCheckBox( string name, ref bool value, bool def )
|
||||||
|
{
|
||||||
|
var color = value == def ? 0 : value ? ColorDarkGreen : ColorDarkRed;
|
||||||
|
if( color == 0 )
|
||||||
|
{
|
||||||
|
return ImGui.Checkbox( name, ref value );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PushStyleColor( ImGuiCol.Text, color );
|
||||||
|
var ret = ImGui.Checkbox( name, ref value );
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool RestrictedInputInt( string name, ref ushort value, ushort min, ushort max )
|
||||||
|
{
|
||||||
|
int tmp = value;
|
||||||
|
if( ImGui.InputInt( name, ref tmp, 0, 0, _editMode ? ImGuiInputTextFlags.EnterReturnsTrue : ImGuiInputTextFlags.ReadOnly )
|
||||||
|
&& tmp != value
|
||||||
|
&& tmp >= min
|
||||||
|
&& tmp <= max )
|
||||||
|
{
|
||||||
|
value = ( ushort )tmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool DefaultButton< T >( string name, ref T value, T defaultValue ) where T : IComparable< T >
|
||||||
|
{
|
||||||
|
var compare = defaultValue.CompareTo( value );
|
||||||
|
var color = compare < 0 ? ColorDarkGreen :
|
||||||
|
compare > 0 ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] );
|
||||||
|
|
||||||
|
ImGui.PushStyleColor( ImGuiCol.Button, color );
|
||||||
|
var ret = ImGui.Button( name, Vector2.UnitX * 120 ) && compare != 0;
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawInputWithDefault( string name, ref ushort value, ushort defaultValue, ushort max )
|
||||||
|
=> DefaultButton( $"{( _editMode ? "Set to " : "" )}Default: {defaultValue}##imc{name}", ref value, defaultValue )
|
||||||
|
|| RestrictedInputInt( name, ref value, 0, max );
|
||||||
|
|
||||||
|
private static bool CustomCombo< T >( string label, IList< (string, T) > namesAndValues, out T value, ref int idx )
|
||||||
|
{
|
||||||
|
value = idx < namesAndValues.Count ? namesAndValues[ idx ].Item2 : default!;
|
||||||
|
|
||||||
|
if( !ImGui.BeginCombo( label, idx < namesAndValues.Count ? namesAndValues[ idx ].Item1 : string.Empty ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( var i = 0; i < namesAndValues.Count; ++i )
|
||||||
|
{
|
||||||
|
if( ImGui.Selectable( $"{namesAndValues[ i ].Item1}##{label}{i}", idx == i ) && idx != i )
|
||||||
|
{
|
||||||
|
idx = i;
|
||||||
|
value = namesAndValues[ i ].Item2;
|
||||||
|
ImGui.EndCombo();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawEqpRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].EqpIdentifier;
|
||||||
|
var val = list[ manipIdx ].EqpValue;
|
||||||
|
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var attributes = id.Slot switch
|
||||||
|
{
|
||||||
|
EquipSlot.Head => EqpAttributesHead,
|
||||||
|
EquipSlot.Body => EqpAttributesBody,
|
||||||
|
EquipSlot.Hands => EqpAttributesHands,
|
||||||
|
EquipSlot.Legs => EqpAttributesLegs,
|
||||||
|
EquipSlot.Feet => EqpAttributesFeet,
|
||||||
|
_ => Array.Empty< (string, EqpEntry) >(),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach( var (name, flag) in attributes )
|
||||||
|
{
|
||||||
|
var tmp = val.HasFlag( flag );
|
||||||
|
if( PrintCheckBox( $"{name}##manip", ref tmp, defaults.HasFlag( flag ) ) && _editMode && tmp != val.HasFlag( flag ) )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = MetaManipulation.Eqp( id.Slot, id.SetId, tmp ? val | flag : val & ~flag );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( ObjectType.Equipment.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.SetId.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.Slot.ToString() );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawGmpRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var defaults = ( GmpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].GmpIdentifier;
|
||||||
|
var val = list[ manipIdx ].GmpValue;
|
||||||
|
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
var enabled = val.Enabled;
|
||||||
|
var animated = val.Animated;
|
||||||
|
var rotationA = val.RotationA;
|
||||||
|
var rotationB = val.RotationB;
|
||||||
|
var rotationC = val.RotationC;
|
||||||
|
ushort unk = val.UnknownTotal;
|
||||||
|
|
||||||
|
ret |= PrintCheckBox( "Visor Enabled##manip", ref enabled, defaults.Enabled ) && enabled != val.Enabled;
|
||||||
|
ret |= PrintCheckBox( "Visor Animated##manip", ref animated, defaults.Animated );
|
||||||
|
ret |= DrawInputWithDefault( "Rotation A##manip", ref rotationA, defaults.RotationA, 0x3FF );
|
||||||
|
ret |= DrawInputWithDefault( "Rotation B##manip", ref rotationB, defaults.RotationB, 0x3FF );
|
||||||
|
ret |= DrawInputWithDefault( "Rotation C##manip", ref rotationC, defaults.RotationC, 0x3FF );
|
||||||
|
ret |= DrawInputWithDefault( "Unknown Byte##manip", ref unk, defaults.UnknownTotal, 0xFF );
|
||||||
|
|
||||||
|
if( ret && _editMode )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = MetaManipulation.Gmp( id.SetId,
|
||||||
|
new GmpEntry
|
||||||
|
{
|
||||||
|
Animated = animated, Enabled = enabled, UnknownTotal = ( byte )unk,
|
||||||
|
RotationA = rotationA, RotationB = rotationB, RotationC = rotationC,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( ObjectType.Equipment.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.SetId.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( EquipSlot.Head.ToString() );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (bool, bool) GetEqdpBits( EquipSlot slot, EqdpEntry entry )
|
||||||
|
{
|
||||||
|
return slot switch
|
||||||
|
{
|
||||||
|
EquipSlot.Head => ( entry.HasFlag( EqdpEntry.Head1 ), entry.HasFlag( EqdpEntry.Head2 ) ),
|
||||||
|
EquipSlot.Body => ( entry.HasFlag( EqdpEntry.Body1 ), entry.HasFlag( EqdpEntry.Body2 ) ),
|
||||||
|
EquipSlot.Hands => ( entry.HasFlag( EqdpEntry.Hands1 ), entry.HasFlag( EqdpEntry.Hands2 ) ),
|
||||||
|
EquipSlot.Legs => ( entry.HasFlag( EqdpEntry.Legs1 ), entry.HasFlag( EqdpEntry.Legs2 ) ),
|
||||||
|
EquipSlot.Feet => ( entry.HasFlag( EqdpEntry.Feet1 ), entry.HasFlag( EqdpEntry.Feet2 ) ),
|
||||||
|
EquipSlot.Neck => ( entry.HasFlag( EqdpEntry.Neck1 ), entry.HasFlag( EqdpEntry.Neck2 ) ),
|
||||||
|
EquipSlot.Ears => ( entry.HasFlag( EqdpEntry.Ears1 ), entry.HasFlag( EqdpEntry.Ears2 ) ),
|
||||||
|
EquipSlot.Wrists => ( entry.HasFlag( EqdpEntry.Wrists1 ), entry.HasFlag( EqdpEntry.Wrists2 ) ),
|
||||||
|
EquipSlot.RingR => ( entry.HasFlag( EqdpEntry.RingR1 ), entry.HasFlag( EqdpEntry.RingR2 ) ),
|
||||||
|
EquipSlot.RingL => ( entry.HasFlag( EqdpEntry.RingL1 ), entry.HasFlag( EqdpEntry.RingL2 ) ),
|
||||||
|
_ => ( false, false ),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EqdpEntry SetEqdpBits( EquipSlot slot, EqdpEntry value, bool bit1, bool bit2 )
|
||||||
|
{
|
||||||
|
switch( slot )
|
||||||
|
{
|
||||||
|
case EquipSlot.Head:
|
||||||
|
value = bit1 ? value | EqdpEntry.Head1 : value & ~EqdpEntry.Head1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Head2 : value & ~EqdpEntry.Head2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Body:
|
||||||
|
value = bit1 ? value | EqdpEntry.Body1 : value & ~EqdpEntry.Body1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Body2 : value & ~EqdpEntry.Body2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Hands:
|
||||||
|
value = bit1 ? value | EqdpEntry.Hands1 : value & ~EqdpEntry.Hands1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Hands2 : value & ~EqdpEntry.Hands2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Legs:
|
||||||
|
value = bit1 ? value | EqdpEntry.Legs1 : value & ~EqdpEntry.Legs1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Legs2 : value & ~EqdpEntry.Legs2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Feet:
|
||||||
|
value = bit1 ? value | EqdpEntry.Feet1 : value & ~EqdpEntry.Feet1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Feet2 : value & ~EqdpEntry.Feet2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Neck:
|
||||||
|
value = bit1 ? value | EqdpEntry.Neck1 : value & ~EqdpEntry.Neck1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Neck2 : value & ~EqdpEntry.Neck2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Ears:
|
||||||
|
value = bit1 ? value | EqdpEntry.Ears1 : value & ~EqdpEntry.Ears1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Ears2 : value & ~EqdpEntry.Ears2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.Wrists:
|
||||||
|
value = bit1 ? value | EqdpEntry.Wrists1 : value & ~EqdpEntry.Wrists1;
|
||||||
|
value = bit2 ? value | EqdpEntry.Wrists2 : value & ~EqdpEntry.Wrists2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.RingR:
|
||||||
|
value = bit1 ? value | EqdpEntry.RingR1 : value & ~EqdpEntry.RingR1;
|
||||||
|
value = bit2 ? value | EqdpEntry.RingR2 : value & ~EqdpEntry.RingR2;
|
||||||
|
return value;
|
||||||
|
case EquipSlot.RingL:
|
||||||
|
value = bit1 ? value | EqdpEntry.RingL1 : value & ~EqdpEntry.RingL1;
|
||||||
|
value = bit2 ? value | EqdpEntry.RingL2 : value & ~EqdpEntry.RingL2;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawEqdpRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var defaults = ( EqdpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].EqdpIdentifier;
|
||||||
|
var val = list[ manipIdx ].EqdpValue;
|
||||||
|
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
var (bit1, bit2) = GetEqdpBits( id.Slot, val );
|
||||||
|
var (defBit1, defBit2) = GetEqdpBits( id.Slot, defaults );
|
||||||
|
|
||||||
|
ret |= PrintCheckBox( "Bit 1##manip", ref bit1, defBit1 );
|
||||||
|
ret |= PrintCheckBox( "Bit 2##manip", ref bit2, defBit2 );
|
||||||
|
|
||||||
|
if( ret && _editMode )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = MetaManipulation.Eqdp( id.Slot, id.GenderRace, id.SetId, SetEqdpBits( id.Slot, val, bit1, bit2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( id.Slot.IsAccessory()
|
||||||
|
? ObjectType.Accessory.ToString()
|
||||||
|
: ObjectType.Equipment.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.SetId.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.Slot.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var (gender, race) = id.GenderRace.Split();
|
||||||
|
ImGui.Text( race.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( gender.ToString() );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawEstRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var defaults = ( ushort )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].EstIdentifier;
|
||||||
|
var val = list[ manipIdx ].EstValue;
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
if( DrawInputWithDefault( "No Idea what this does!##manip", ref val, defaults, ushort.MaxValue ) && _editMode )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = new MetaManipulation( id.Value, val );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( id.ObjectType.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.PrimaryId.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.ObjectType == ObjectType.Equipment
|
||||||
|
? id.EquipSlot.ToString()
|
||||||
|
: id.BodySlot.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var (gender, race) = id.GenderRace.Split();
|
||||||
|
ImGui.Text( race.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( gender.ToString() );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawImcRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var defaults = ( ImcFile.ImageChangeData )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].ImcIdentifier;
|
||||||
|
var val = list[ manipIdx ].ImcValue;
|
||||||
|
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
ushort materialId = val.MaterialId;
|
||||||
|
ushort vfxId = val.VfxId;
|
||||||
|
ushort decalId = val.DecalId;
|
||||||
|
var soundId = ( ushort )( val.SoundId >> 10 );
|
||||||
|
var attributeMask = val.AttributeMask;
|
||||||
|
var materialAnimationId = ( ushort )( val.MaterialAnimationId >> 12 );
|
||||||
|
ret |= DrawInputWithDefault( "Material Id", ref materialId, defaults.MaterialId, byte.MaxValue );
|
||||||
|
ret |= DrawInputWithDefault( "Vfx Id", ref vfxId, defaults.VfxId, byte.MaxValue );
|
||||||
|
ret |= DrawInputWithDefault( "Decal Id", ref decalId, defaults.DecalId, byte.MaxValue );
|
||||||
|
ret |= DrawInputWithDefault( "Sound Id", ref soundId, defaults.SoundId, 0x3F );
|
||||||
|
ret |= DrawInputWithDefault( "Attribute Mask", ref attributeMask, defaults.AttributeMask, 0x3FF );
|
||||||
|
ret |= DrawInputWithDefault( "Material Animation Id", ref materialAnimationId, defaults.MaterialAnimationId,
|
||||||
|
byte.MaxValue );
|
||||||
|
|
||||||
|
if( ret && _editMode )
|
||||||
|
{
|
||||||
|
var value = ImcExtensions.FromValues( ( byte )materialId, ( byte )decalId, attributeMask, ( byte )soundId,
|
||||||
|
( byte )vfxId, ( byte )materialAnimationId );
|
||||||
|
list[ manipIdx ] = new MetaManipulation( id.Value, value.ToInteger() );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( id.ObjectType.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.PrimaryId.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if( id.ObjectType == ObjectType.Accessory
|
||||||
|
|| id.ObjectType == ObjectType.Equipment )
|
||||||
|
{
|
||||||
|
ImGui.Text( id.ObjectType == ObjectType.Equipment
|
||||||
|
|| id.ObjectType == ObjectType.Accessory
|
||||||
|
? id.EquipSlot.ToString()
|
||||||
|
: id.BodySlot.ToString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if( id.ObjectType != ObjectType.Equipment
|
||||||
|
&& id.ObjectType != ObjectType.Accessory )
|
||||||
|
{
|
||||||
|
ImGui.Text( id.SecondaryId.ToString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.Variant.ToString() );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawRspRow( int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var defaults = ( float )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||||
|
var ret = false;
|
||||||
|
var id = list[ manipIdx ].RspIdentifier;
|
||||||
|
var val = list[ manipIdx ].RspValue;
|
||||||
|
|
||||||
|
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
var color = defaults < val ? ColorDarkGreen :
|
||||||
|
defaults > val ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] );
|
||||||
|
|
||||||
|
if( DefaultButton(
|
||||||
|
$"{( _editMode ? "Set to " : "" )}Default: {defaults:F3}##scaleManip", ref val, defaults )
|
||||||
|
&& _editMode )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = MetaManipulation.Rsp( id.SubRace, id.Attribute, defaults );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SetNextItemWidth( 50 );
|
||||||
|
if( ImGui.InputFloat( "Scale###manip", ref val, 0, 0, "%.3f",
|
||||||
|
_editMode ? ImGuiInputTextFlags.EnterReturnsTrue : ImGuiInputTextFlags.ReadOnly )
|
||||||
|
&& val >= 0
|
||||||
|
&& val <= 5
|
||||||
|
&& _editMode )
|
||||||
|
{
|
||||||
|
list[ manipIdx ] = MetaManipulation.Rsp( id.SubRace, id.Attribute, val );
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text( id.Attribute.ToUngenderedString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.SubRace.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( id.Attribute.ToGender().ToString() );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawManipulationRow( ref int manipIdx, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var type = list[ manipIdx ].Type;
|
||||||
|
|
||||||
|
if( _editMode )
|
||||||
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.PushFont( UiBuilder.IconFont );
|
||||||
|
if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##manipDelete{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
list.RemoveAt( manipIdx );
|
||||||
|
ImGui.PopFont();
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
--manipIdx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( type.ToString() );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
var changes = false;
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case MetaType.Eqp:
|
||||||
|
changes = DrawEqpRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
case MetaType.Gmp:
|
||||||
|
changes = DrawGmpRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
case MetaType.Eqdp:
|
||||||
|
changes = DrawEqdpRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
case MetaType.Est:
|
||||||
|
changes = DrawEstRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
case MetaType.Imc:
|
||||||
|
changes = DrawImcRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
case MetaType.Rsp:
|
||||||
|
changes = DrawRspRow( manipIdx, list );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableSetColumnIndex( 9 );
|
||||||
|
if( ImGui.Selectable( $"{list[ manipIdx ].Value}##{manipIdx}" ) )
|
||||||
|
{
|
||||||
|
ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private MetaType DrawNewTypeSelection()
|
||||||
|
{
|
||||||
|
ImGui.RadioButton( "IMC##newManipType", ref _newManipTypeIdx, 1 );
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton( "EQDP##newManipType", ref _newManipTypeIdx, 2 );
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton( "EQP##newManipType", ref _newManipTypeIdx, 3 );
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton( "EST##newManipType", ref _newManipTypeIdx, 4 );
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton( "GMP##newManipType", ref _newManipTypeIdx, 5 );
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.RadioButton( "RSP##newManipType", ref _newManipTypeIdx, 6 );
|
||||||
|
return ( MetaType )_newManipTypeIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawNewManipulationPopup( string popupName, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var change = false;
|
||||||
|
if( ImGui.BeginPopup( popupName ) )
|
||||||
|
{
|
||||||
|
var manipType = DrawNewTypeSelection();
|
||||||
|
MetaManipulation? newManip = null;
|
||||||
|
switch( manipType )
|
||||||
|
{
|
||||||
|
case MetaType.Imc:
|
||||||
|
{
|
||||||
|
RestrictedInputInt( "Set Id##newManipImc", ref _newManipSetId, 0, ushort.MaxValue );
|
||||||
|
RestrictedInputInt( "Variant##newManipImc", ref _newManipVariant, 0, byte.MaxValue );
|
||||||
|
CustomCombo( "Object Type", ImcObjectType, out var objectType, ref _newManipObjectType );
|
||||||
|
EquipSlot equipSlot = default;
|
||||||
|
switch( objectType )
|
||||||
|
{
|
||||||
|
case ObjectType.Equipment:
|
||||||
|
CustomCombo( "Equipment Slot", EqdpEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||||
|
newManip = MetaManipulation.Imc( equipSlot, _newManipSetId, _newManipVariant,
|
||||||
|
new ImcFile.ImageChangeData() );
|
||||||
|
break;
|
||||||
|
case ObjectType.DemiHuman:
|
||||||
|
case ObjectType.Weapon:
|
||||||
|
case ObjectType.Monster:
|
||||||
|
RestrictedInputInt( "Secondary Id##newManipImc", ref _newManipSecondaryId, 0, ushort.MaxValue );
|
||||||
|
CustomCombo( "Body Slot", ImcBodySlots, out var bodySlot, ref _newManipBodySlot );
|
||||||
|
newManip = MetaManipulation.Imc( objectType, bodySlot, _newManipSetId, _newManipSecondaryId,
|
||||||
|
_newManipVariant, new ImcFile.ImageChangeData() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MetaType.Eqdp:
|
||||||
|
{
|
||||||
|
RestrictedInputInt( "Set Id##newManipEqdp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||||
|
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||||
|
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||||
|
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||||
|
newManip = MetaManipulation.Eqdp( equipSlot, GameData.CombinedRace( gender, race ), ( ushort )_newManipSetId,
|
||||||
|
new EqdpEntry() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MetaType.Eqp:
|
||||||
|
{
|
||||||
|
RestrictedInputInt( "Set Id##newManipEqp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||||
|
CustomCombo( "Equipment Slot", EqpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
|
||||||
|
newManip = MetaManipulation.Eqp( equipSlot, ( ushort )_newManipSetId, 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MetaType.Est:
|
||||||
|
{
|
||||||
|
RestrictedInputInt( "Set Id##newManipEst", ref _newManipSetId, 0, ushort.MaxValue );
|
||||||
|
CustomCombo( "Object Type", ObjectTypes, out var objectType, ref _newManipObjectType );
|
||||||
|
EquipSlot equipSlot = default;
|
||||||
|
BodySlot bodySlot = default;
|
||||||
|
switch( ( ObjectType )_newManipObjectType )
|
||||||
|
{
|
||||||
|
case ObjectType.Equipment:
|
||||||
|
CustomCombo( "Equipment Slot", EstEquipSlots, out equipSlot, ref _newManipEquipSlot );
|
||||||
|
break;
|
||||||
|
case ObjectType.Character:
|
||||||
|
CustomCombo( "Body Slot", EstBodySlots, out bodySlot, ref _newManipBodySlot );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomCombo( "Race", Races, out var race, ref _newManipRace );
|
||||||
|
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender );
|
||||||
|
newManip = MetaManipulation.Est( objectType, equipSlot, GameData.CombinedRace( gender, race ), bodySlot,
|
||||||
|
( ushort )_newManipSetId, 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MetaType.Gmp:
|
||||||
|
RestrictedInputInt( "Set Id##newManipGmp", ref _newManipSetId, 0, ushort.MaxValue );
|
||||||
|
newManip = MetaManipulation.Gmp( ( ushort )_newManipSetId, new GmpEntry() );
|
||||||
|
break;
|
||||||
|
case MetaType.Rsp:
|
||||||
|
CustomCombo( "Subrace", Subraces, out var subRace, ref _newManipSubrace );
|
||||||
|
CustomCombo( "Attribute", RspAttributes, out var rspAttribute, ref _newManipAttribute );
|
||||||
|
newManip = MetaManipulation.Rsp( subRace, rspAttribute, 1f );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ImGui.Button( "Create Manipulation##newManip", Vector2.UnitX * -1 )
|
||||||
|
&& newManip != null
|
||||||
|
&& list.All( m => m.Identifier != newManip.Value.Identifier ) )
|
||||||
|
{
|
||||||
|
var def = Service< MetaDefaults >.Get().GetDefaultValue( newManip.Value );
|
||||||
|
if( def != null )
|
||||||
|
{
|
||||||
|
var manip = newManip.Value.Type switch
|
||||||
|
{
|
||||||
|
MetaType.Est => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||||
|
MetaType.Eqp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||||
|
MetaType.Eqdp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||||
|
MetaType.Gmp => new MetaManipulation( newManip.Value.Identifier, ( ulong )def ),
|
||||||
|
MetaType.Imc => new MetaManipulation( newManip.Value.Identifier,
|
||||||
|
( ( ImcFile.ImageChangeData )def ).ToInteger() ),
|
||||||
|
MetaType.Rsp => MetaManipulation.Rsp( newManip.Value.RspIdentifier.SubRace,
|
||||||
|
newManip.Value.RspIdentifier.Attribute, ( float )def ),
|
||||||
|
_ => throw new InvalidEnumArgumentException(),
|
||||||
|
};
|
||||||
|
list.Add( manip );
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DrawMetaManipulationsTable( string label, IList< MetaManipulation > list )
|
||||||
|
{
|
||||||
|
var numRows = _editMode ? 11 : 10;
|
||||||
|
var changes = false;
|
||||||
|
if( list.Count > 0
|
||||||
|
&& ImGui.BeginTable( label, numRows,
|
||||||
|
ImGuiTableFlags.BordersInner | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||||
|
{
|
||||||
|
if( _editMode )
|
||||||
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Type##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Object Type##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Set##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Slot##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Race##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Gender##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Secondary ID##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Variant##{label}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableHeader( $"Value##{label}" );
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
|
for( var i = 0; i < list.Count; ++i )
|
||||||
|
{
|
||||||
|
changes |= DrawManipulationRow( ref i, list );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
var popupName = $"##newManip{label}";
|
||||||
|
if( _editMode )
|
||||||
|
{
|
||||||
|
changes |= DrawNewManipulationPopup( $"##newManip{label}", list );
|
||||||
|
if( ImGui.Button( $"Add New Manipulation##{label}", Vector2.UnitX * -1 ) )
|
||||||
|
{
|
||||||
|
ImGui.OpenPopup( popupName );
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -430,7 +430,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
if( ImGui.Button( ButtonReloadJson ) )
|
if( ImGui.Button( ButtonReloadJson ) )
|
||||||
{
|
{
|
||||||
_selector.ReloadCurrentMod();
|
_selector.ReloadCurrentMod( true, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.IsItemHovered() )
|
if( ImGui.IsItemHovered() )
|
||||||
|
|
@ -443,13 +443,13 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
if( ImGui.Button( "Recompute Metadata" ) )
|
if( ImGui.Button( "Recompute Metadata" ) )
|
||||||
{
|
{
|
||||||
_selector.ReloadCurrentMod( true );
|
_selector.ReloadCurrentMod( true, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.IsItemHovered() )
|
if( ImGui.IsItemHovered() )
|
||||||
{
|
{
|
||||||
ImGui.SetTooltip(
|
ImGui.SetTooltip(
|
||||||
"Force a recomputation of the metadata_manipulations.json file from all .meta files in the folder.\nAlso reloads the mod." );
|
"Force a recomputation of the metadata_manipulations.json file from all .meta files in the folder.\nAlso reloads the mod.\nBe aware that this removes all manually added metadata changes." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -544,14 +544,14 @@ namespace Penumbra.UI
|
||||||
SetSelection( idx );
|
SetSelection( idx );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadCurrentMod( bool recomputeMeta = false )
|
public void ReloadCurrentMod( bool reloadMeta = false, bool recomputeMeta = false )
|
||||||
{
|
{
|
||||||
if( Mod == null )
|
if( Mod == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _index >= 0 && _modManager.UpdateMod( Mod.Data, recomputeMeta ) )
|
if( _index >= 0 && _modManager.UpdateMod( Mod.Data, reloadMeta, recomputeMeta ) )
|
||||||
{
|
{
|
||||||
ResetModNamesLower();
|
ResetModNamesLower();
|
||||||
SelectModByDir( Mod.Data.BasePath.Name );
|
SelectModByDir( Mod.Data.BasePath.Name );
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue