diff --git a/Penumbra/Interop/CharacterUtility.cs b/Penumbra/Interop/CharacterUtility.cs index 11d54eb4..7923254b 100644 --- a/Penumbra/Interop/CharacterUtility.cs +++ b/Penumbra/Interop/CharacterUtility.cs @@ -3,6 +3,7 @@ using System.Linq; using Dalamud.Hooking; using Dalamud.Logging; using Dalamud.Utility.Signatures; +using ImGuiScene; namespace Penumbra.Interop; @@ -32,7 +33,7 @@ public unsafe class CharacterUtility : IDisposable .Append( Structs.CharacterUtility.GmpIdx ) #endif #if USE_EQDP - .Concat( Enumerable.Range( Structs.CharacterUtility.EqdpStartIdx, Structs.CharacterUtility.NumEqdpFiles ) ) + .Concat( Enumerable.Range( Structs.CharacterUtility.EqdpStartIdx, Structs.CharacterUtility.NumEqdpFiles ).Where( i => i != 17 ) ) // TODO: Female Hrothgar #endif #if USE_CMP .Append( Structs.CharacterUtility.HumanCmpIdx ) @@ -42,7 +43,7 @@ public unsafe class CharacterUtility : IDisposable #endif .ToArray(); - private static readonly int[] ReverseIndices + public static readonly int[] ReverseIndices = Enumerable.Range( 0, Structs.CharacterUtility.NumResources ) .Select( i => Array.IndexOf( RelevantIndices, i ) ).ToArray(); @@ -86,20 +87,22 @@ public unsafe class CharacterUtility : IDisposable } // Set the data of one of the stored resources to a given pointer and length. - public bool SetResource( int idx, IntPtr data, int length ) + public bool SetResource( int resourceIdx, IntPtr data, int length ) { - var resource = ( Structs.ResourceHandle* )Address->Resources[ idx ]; + var resource = Address->Resource( resourceIdx ); var ret = resource->SetData( data, length ); - PluginLog.Verbose( "Set resource {Idx} to 0x{NewData:X} ({NewLength} bytes).", idx, ( ulong )data, length ); + PluginLog.Verbose( "Set resource {Idx} to 0x{NewData:X} ({NewLength} bytes).", resourceIdx, ( ulong )data, length ); return ret; } // Reset the data of one of the stored resources to its default values. - public void ResetResource( int fileIdx ) + public void ResetResource( int resourceIdx ) { - var (data, size) = DefaultResources[ ReverseIndices[ fileIdx ] ]; - var resource = ( Structs.ResourceHandle* )Address->Resources[ fileIdx ]; - resource->SetData( data, size ); + var relevantIdx = ReverseIndices[ resourceIdx ]; + var (data, length) = DefaultResources[ relevantIdx ]; + var resource = Address->Resource( resourceIdx ); + PluginLog.Verbose( "Reset resource {Idx} to default at 0x{DefaultData:X} ({NewLength} bytes).", resourceIdx, ( ulong )data, length ); + resource->SetData( data, length ); } // Return all relevant resources to the default resource. diff --git a/Penumbra/Interop/Structs/CharacterUtility.cs b/Penumbra/Interop/Structs/CharacterUtility.cs index aaceee6b..fc4e4bee 100644 --- a/Penumbra/Interop/Structs/CharacterUtility.cs +++ b/Penumbra/Interop/Structs/CharacterUtility.cs @@ -8,8 +8,9 @@ namespace Penumbra.Interop.Structs; [StructLayout( LayoutKind.Explicit )] public unsafe struct CharacterUtility { + // TODO: female Hrothgar public static readonly int[] EqdpIndices - = Enumerable.Range( EqdpStartIdx, NumEqdpFiles ).ToArray(); + = Enumerable.Range( EqdpStartIdx, NumEqdpFiles ).Where( i => i != EqdpStartIdx + 15 ).ToArray(); public const int NumResources = 85; public const int EqpIdx = 0; @@ -41,7 +42,7 @@ public unsafe struct CharacterUtility 1301 => EqdpStartIdx + 12, 1401 => EqdpStartIdx + 13, 1501 => EqdpStartIdx + 14, - 1601 => EqdpStartIdx + 15, // Does not exist yet + 1601 => EqdpStartIdx + 15, // TODO: female Hrothgar 1701 => EqdpStartIdx + 16, 1801 => EqdpStartIdx + 17, 0104 => EqdpStartIdx + 18, diff --git a/Penumbra/Meta/Files/EqdpFile.cs b/Penumbra/Meta/Files/EqdpFile.cs index 6d4ebe8d..c0f2add2 100644 --- a/Penumbra/Meta/Files/EqdpFile.cs +++ b/Penumbra/Meta/Files/EqdpFile.cs @@ -120,8 +120,10 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile => GetDefault( Index, setIdx ); public static EqdpEntry GetDefault( int fileIdx, int setIdx ) + => GetDefault( ( byte* )Penumbra.CharacterUtility.DefaultResource( fileIdx ).Address, setIdx ); + + public static EqdpEntry GetDefault( byte* data, int setIdx ) { - var data = ( byte* )Penumbra.CharacterUtility.DefaultResource( fileIdx ).Address; var blockSize = *( ushort* )( data + IdentifierSize ); var totalBlockCount = *( ushort* )( data + IdentifierSize + 2 ); @@ -138,7 +140,6 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile } var blockData = ( ushort* )( data + IdentifierSize + PreambleSize + totalBlockCount * 2 + block * 2 ); - var x = new ReadOnlySpan< ushort >( blockData, blockSize ); return ( EqdpEntry )( *( blockData + setIdx % blockSize ) ); } diff --git a/Penumbra/Meta/Manager/MetaManager.Eqdp.cs b/Penumbra/Meta/Manager/MetaManager.Eqdp.cs index 8edf1150..1dba4520 100644 --- a/Penumbra/Meta/Manager/MetaManager.Eqdp.cs +++ b/Penumbra/Meta/Manager/MetaManager.Eqdp.cs @@ -6,6 +6,7 @@ using Penumbra.GameData.Enums; using Penumbra.Interop.Structs; using Penumbra.Meta.Files; using Penumbra.Meta.Manipulations; +using Penumbra.Util; namespace Penumbra.Meta.Manager; @@ -13,7 +14,7 @@ public partial class MetaManager { public struct MetaManagerEqdp : IDisposable { - public ExpandedEqdpFile?[] Files = new ExpandedEqdpFile?[CharacterUtility.NumEqdpFiles]; + public ExpandedEqdpFile?[] Files = new ExpandedEqdpFile?[CharacterUtility.NumEqdpFiles - 1]; // TODO: female Hrothgar public readonly Dictionary< EqdpManipulation, Mod.Mod > Manipulations = new(); @@ -23,9 +24,9 @@ public partial class MetaManager [Conditional( "USE_EQDP" )] public void SetFiles() { - foreach( var idx in CharacterUtility.EqdpIndices ) + for( var i = 0; i < CharacterUtility.EqdpIndices.Length; ++i ) { - SetFile( Files[ idx - CharacterUtility.EqdpStartIdx ], idx ); + SetFile( Files[ i ], CharacterUtility.EqdpIndices[ i ] ); } } @@ -57,7 +58,8 @@ public partial class MetaManager return false; } - var file = Files[ m.FileIndex() - 2 ] ??= new ExpandedEqdpFile( Names.CombinedRace( m.Gender, m.Race ), m.Slot.IsAccessory() ); + var file = Files[ Array.IndexOf( CharacterUtility.EqdpIndices, m.FileIndex() ) ] ??= + new ExpandedEqdpFile( Names.CombinedRace( m.Gender, m.Race ), m.Slot.IsAccessory() ); // TODO: female Hrothgar return m.Apply( file ); #else return false; @@ -65,7 +67,7 @@ public partial class MetaManager } public ExpandedEqdpFile? File( GenderRace race, bool accessory ) - => Files[ CharacterUtility.EqdpIdx( race, accessory ) - CharacterUtility.EqdpStartIdx ]; + => Files[ Array.IndexOf( CharacterUtility.EqdpIndices, CharacterUtility.EqdpIdx( race, accessory ) ) ]; // TODO: female Hrothgar public void Dispose() {