mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
tmp2
This commit is contained in:
parent
de082439a4
commit
707570615c
10 changed files with 426 additions and 102 deletions
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Numerics;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Memory;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Util;
|
||||
|
|
@ -18,10 +19,16 @@ public readonly struct ImcEntry : IEquatable< ImcEntry >
|
|||
public readonly byte MaterialAnimationId;
|
||||
|
||||
public ushort AttributeMask
|
||||
=> ( ushort )( _attributeAndSound & 0x3FF );
|
||||
{
|
||||
get => ( ushort )( _attributeAndSound & 0x3FF );
|
||||
init => _attributeAndSound = ( ushort )( ( _attributeAndSound & ~0x3FF ) | ( value & 0x3FF ) );
|
||||
}
|
||||
|
||||
public byte SoundId
|
||||
=> ( byte )( _attributeAndSound >> 10 );
|
||||
{
|
||||
get => ( byte )( _attributeAndSound >> 10 );
|
||||
init => _attributeAndSound = ( ushort )( AttributeMask | ( value << 10 ) );
|
||||
}
|
||||
|
||||
public bool Equals( ImcEntry other )
|
||||
=> MaterialId == other.MaterialId
|
||||
|
|
@ -35,6 +42,18 @@ public readonly struct ImcEntry : IEquatable< ImcEntry >
|
|||
|
||||
public override int GetHashCode()
|
||||
=> HashCode.Combine( MaterialId, DecalId, _attributeAndSound, VfxId, MaterialAnimationId );
|
||||
|
||||
[JsonConstructor]
|
||||
public ImcEntry( byte materialId, byte decalId, ushort attributeMask, byte soundId, byte vfxId, byte materialAnimationId )
|
||||
{
|
||||
MaterialId = materialId;
|
||||
DecalId = decalId;
|
||||
_attributeAndSound = 0;
|
||||
VfxId = vfxId;
|
||||
MaterialAnimationId = materialAnimationId;
|
||||
AttributeMask = attributeMask;
|
||||
SoundId = soundId;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe class ImcFile : MetaBaseFile
|
||||
|
|
@ -118,7 +137,7 @@ public unsafe class ImcFile : MetaBaseFile
|
|||
}
|
||||
|
||||
PluginLog.Verbose( "Expanded imc from {Count} to {NewCount} variants.", Count, numVariants );
|
||||
*( ushort* )Count = ( ushort )numVariants;
|
||||
*( ushort* )Data = ( ushort )numVariants;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
|
@ -6,12 +9,16 @@ using Penumbra.Meta.Files;
|
|||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public readonly struct EqdpManipulation : IEquatable< EqdpManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct EqdpManipulation : IMetaManipulation< EqdpManipulation >
|
||||
{
|
||||
public readonly EqdpEntry Entry;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly Gender Gender;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly ModelRace Race;
|
||||
public readonly ushort SetId;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly EquipSlot Slot;
|
||||
|
||||
public EqdpManipulation( EqdpEntry entry, EquipSlot slot, Gender gender, ModelRace race, ushort setId )
|
||||
|
|
@ -38,6 +45,24 @@ public readonly struct EqdpManipulation : IEquatable< EqdpManipulation >
|
|||
public override int GetHashCode()
|
||||
=> HashCode.Combine( ( int )Gender, ( int )Race, SetId, ( int )Slot );
|
||||
|
||||
public int CompareTo( EqdpManipulation other )
|
||||
{
|
||||
var r = Race.CompareTo( other.Race );
|
||||
if( r != 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
var g = Gender.CompareTo( other.Gender );
|
||||
if( g != 0 )
|
||||
{
|
||||
return g;
|
||||
}
|
||||
|
||||
var set = SetId.CompareTo( other.SetId );
|
||||
return set != 0 ? set : Slot.CompareTo( other.Slot );
|
||||
}
|
||||
|
||||
public int FileIndex()
|
||||
=> CharacterUtility.EqdpIdx( Names.CombinedRace( Gender, Race ), Slot.IsAccessory() );
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
|
@ -6,10 +9,12 @@ using Penumbra.Meta.Files;
|
|||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public readonly struct EqpManipulation : IEquatable< EqpManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct EqpManipulation : IMetaManipulation< EqpManipulation >
|
||||
{
|
||||
public readonly EqpEntry Entry;
|
||||
public readonly ushort SetId;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly EquipSlot Slot;
|
||||
|
||||
public EqpManipulation( EqpEntry entry, EquipSlot slot, ushort setId )
|
||||
|
|
@ -32,6 +37,12 @@ public readonly struct EqpManipulation : IEquatable< EqpManipulation >
|
|||
public override int GetHashCode()
|
||||
=> HashCode.Combine( ( int )Slot, SetId );
|
||||
|
||||
public int CompareTo( EqpManipulation other )
|
||||
{
|
||||
var set = SetId.CompareTo( other.SetId );
|
||||
return set != 0 ? set : Slot.CompareTo( other.Slot );
|
||||
}
|
||||
|
||||
public int FileIndex()
|
||||
=> CharacterUtility.EqpIdx;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public readonly struct EstManipulation : IEquatable< EstManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct EstManipulation : IMetaManipulation< EstManipulation >
|
||||
{
|
||||
public enum EstType : byte
|
||||
{
|
||||
|
|
@ -16,10 +20,13 @@ public readonly struct EstManipulation : IEquatable< EstManipulation >
|
|||
}
|
||||
|
||||
public readonly ushort SkeletonIdx;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly Gender Gender;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly ModelRace Race;
|
||||
public readonly ushort SetId;
|
||||
public readonly EstType Type;
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly EstType Slot;
|
||||
|
||||
public EstManipulation( Gender gender, ModelRace race, EstType estType, ushort setId, ushort skeletonIdx )
|
||||
{
|
||||
|
|
@ -27,27 +34,45 @@ public readonly struct EstManipulation : IEquatable< EstManipulation >
|
|||
Gender = gender;
|
||||
Race = race;
|
||||
SetId = setId;
|
||||
Type = estType;
|
||||
Slot = estType;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
=> $"Est - {SetId} - {Type} - {Race.ToName()} {Gender.ToName()}";
|
||||
=> $"Est - {SetId} - {Slot} - {Race.ToName()} {Gender.ToName()}";
|
||||
|
||||
public bool Equals( EstManipulation other )
|
||||
=> Gender == other.Gender
|
||||
&& Race == other.Race
|
||||
&& SetId == other.SetId
|
||||
&& Type == other.Type;
|
||||
&& Slot == other.Slot;
|
||||
|
||||
public override bool Equals( object? obj )
|
||||
=> obj is EstManipulation other && Equals( other );
|
||||
|
||||
public override int GetHashCode()
|
||||
=> HashCode.Combine( ( int )Gender, ( int )Race, SetId, ( int )Type );
|
||||
=> HashCode.Combine( ( int )Gender, ( int )Race, SetId, ( int )Slot );
|
||||
|
||||
public int CompareTo( EstManipulation other )
|
||||
{
|
||||
var r = Race.CompareTo( other.Race );
|
||||
if( r != 0 )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
var g = Gender.CompareTo( other.Gender );
|
||||
if( g != 0 )
|
||||
{
|
||||
return g;
|
||||
}
|
||||
|
||||
var s = Slot.CompareTo( other.Slot );
|
||||
return s != 0 ? s : SetId.CompareTo( other.SetId );
|
||||
}
|
||||
|
||||
public int FileIndex()
|
||||
=> ( int )Type;
|
||||
=> ( int )Slot;
|
||||
|
||||
public bool Apply( EstFile file )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public readonly struct GmpManipulation : IEquatable< GmpManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct GmpManipulation : IMetaManipulation< GmpManipulation >
|
||||
{
|
||||
public readonly GmpEntry Entry;
|
||||
public readonly ushort SetId;
|
||||
|
|
@ -28,6 +30,9 @@ public readonly struct GmpManipulation : IEquatable< GmpManipulation >
|
|||
public override int GetHashCode()
|
||||
=> SetId.GetHashCode();
|
||||
|
||||
public int CompareTo( GmpManipulation other )
|
||||
=> SetId.CompareTo( other.SetId );
|
||||
|
||||
public int FileIndex()
|
||||
=> CharacterUtility.GmpIdx;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,29 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Meta.Files;
|
||||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public readonly struct ImcManipulation : IEquatable< ImcManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
||||
{
|
||||
public readonly ImcEntry Entry;
|
||||
public readonly ushort PrimaryId;
|
||||
public readonly ushort Variant;
|
||||
public readonly ushort SecondaryId;
|
||||
public readonly ImcEntry Entry;
|
||||
public readonly ushort PrimaryId;
|
||||
public readonly ushort Variant;
|
||||
public readonly ushort SecondaryId;
|
||||
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly ObjectType ObjectType;
|
||||
public readonly EquipSlot EquipSlot;
|
||||
public readonly BodySlot BodySlot;
|
||||
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly EquipSlot EquipSlot;
|
||||
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly BodySlot BodySlot;
|
||||
|
||||
public ImcManipulation( EquipSlot equipSlot, ushort variant, ushort primaryId, ImcEntry entry )
|
||||
{
|
||||
|
|
@ -40,6 +48,19 @@ public readonly struct ImcManipulation : IEquatable< ImcManipulation >
|
|||
EquipSlot = EquipSlot.Unknown;
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
internal ImcManipulation( ObjectType objectType, BodySlot bodySlot, ushort primaryId, ushort secondaryId, ushort variant,
|
||||
EquipSlot equipSlot, ImcEntry entry )
|
||||
{
|
||||
Entry = entry;
|
||||
ObjectType = objectType;
|
||||
BodySlot = bodySlot;
|
||||
PrimaryId = primaryId;
|
||||
SecondaryId = secondaryId;
|
||||
Variant = variant;
|
||||
EquipSlot = equipSlot;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
=> ObjectType is ObjectType.Equipment or ObjectType.Accessory
|
||||
? $"Imc - {PrimaryId} - {EquipSlot} - {Variant}"
|
||||
|
|
@ -59,6 +80,39 @@ public readonly struct ImcManipulation : IEquatable< ImcManipulation >
|
|||
public override int GetHashCode()
|
||||
=> HashCode.Combine( PrimaryId, Variant, SecondaryId, ( int )ObjectType, ( int )EquipSlot, ( int )BodySlot );
|
||||
|
||||
public int CompareTo( ImcManipulation other )
|
||||
{
|
||||
var o = ObjectType.CompareTo( other.ObjectType );
|
||||
if( o != 0 )
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
var i = PrimaryId.CompareTo( other.PrimaryId );
|
||||
if( i != 0 )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
if( ObjectType is ObjectType.Equipment or ObjectType.Accessory )
|
||||
{
|
||||
var e = EquipSlot.CompareTo( other.EquipSlot );
|
||||
return e != 0 ? e : Variant.CompareTo( other.Variant );
|
||||
}
|
||||
|
||||
var s = SecondaryId.CompareTo( other.SecondaryId );
|
||||
if( s != 0 )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
var b = BodySlot.CompareTo( other.BodySlot );
|
||||
return b != 0 ? b : Variant.CompareTo( other.Variant );
|
||||
}
|
||||
|
||||
public int FileIndex()
|
||||
=> -1;
|
||||
|
||||
public Utf8GamePath GamePath()
|
||||
{
|
||||
return ObjectType switch
|
||||
|
|
|
|||
|
|
@ -1,60 +1,225 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.Util;
|
||||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public interface IMetaManipulation
|
||||
{
|
||||
public int FileIndex();
|
||||
}
|
||||
|
||||
public interface IMetaManipulation< T > : IMetaManipulation, IComparable< T >, IEquatable< T > where T : struct
|
||||
{ }
|
||||
|
||||
public struct ManipulationSet< T > where T : struct, IMetaManipulation< T >
|
||||
{
|
||||
private List< T >? _data = null;
|
||||
|
||||
public IReadOnlyList< T > Data
|
||||
=> ( IReadOnlyList< T >? )_data ?? Array.Empty< T >();
|
||||
|
||||
public int Count
|
||||
=> _data?.Count ?? 0;
|
||||
|
||||
public ManipulationSet( int count = 0 )
|
||||
{
|
||||
if( count > 0 )
|
||||
{
|
||||
_data = new List< T >( count );
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryAdd( T manip )
|
||||
{
|
||||
if( _data == null )
|
||||
{
|
||||
_data = new List< T > { manip };
|
||||
return true;
|
||||
}
|
||||
|
||||
var idx = _data.BinarySearch( manip );
|
||||
if( idx >= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_data.Insert( ~idx, manip );
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Set( T manip )
|
||||
{
|
||||
if( _data == null )
|
||||
{
|
||||
_data = new List< T > { manip };
|
||||
return 0;
|
||||
}
|
||||
|
||||
var idx = _data.BinarySearch( manip );
|
||||
if( idx >= 0 )
|
||||
{
|
||||
_data[ idx ] = manip;
|
||||
return idx;
|
||||
}
|
||||
|
||||
idx = ~idx;
|
||||
_data.Insert( idx, manip );
|
||||
return idx;
|
||||
}
|
||||
|
||||
public bool TryGet( T manip, out T value )
|
||||
{
|
||||
var idx = _data?.BinarySearch( manip ) ?? -1;
|
||||
if( idx < 0 )
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = _data![ idx ];
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Remove( T manip )
|
||||
{
|
||||
var idx = _data?.BinarySearch( manip ) ?? -1;
|
||||
if( idx < 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_data!.RemoveAt( idx );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Explicit, Pack = 1, Size = 16 )]
|
||||
public readonly struct MetaManipulation : IEquatable< MetaManipulation >, IComparable<MetaManipulation>
|
||||
public readonly struct MetaManipulation : IEquatable< MetaManipulation >, IComparable< MetaManipulation >
|
||||
{
|
||||
public enum Type : byte
|
||||
{
|
||||
Eqp,
|
||||
Gmp,
|
||||
Eqdp,
|
||||
Est,
|
||||
Rsp,
|
||||
Imc,
|
||||
Unknown = 0,
|
||||
Imc = 1,
|
||||
Eqdp = 2,
|
||||
Eqp = 3,
|
||||
Est = 4,
|
||||
Gmp = 5,
|
||||
Rsp = 6,
|
||||
}
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly EqpManipulation Eqp = default;
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly GmpManipulation Gmp = default;
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly EqdpManipulation Eqdp = default;
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly EstManipulation Est = default;
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly RspManipulation Rsp = default;
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[JsonIgnore]
|
||||
public readonly ImcManipulation Imc = default;
|
||||
|
||||
[FieldOffset( 15 )]
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
[JsonProperty("Type")]
|
||||
public readonly Type ManipulationType;
|
||||
|
||||
public object? Manipulation
|
||||
{
|
||||
get => ManipulationType switch
|
||||
{
|
||||
Type.Unknown => null,
|
||||
Type.Imc => Imc,
|
||||
Type.Eqdp => Eqdp,
|
||||
Type.Eqp => Eqp,
|
||||
Type.Est => Est,
|
||||
Type.Gmp => Gmp,
|
||||
Type.Rsp => Rsp,
|
||||
_ => null,
|
||||
};
|
||||
init
|
||||
{
|
||||
switch( value )
|
||||
{
|
||||
case EqpManipulation m:
|
||||
Eqp = m;
|
||||
ManipulationType = Type.Eqp;
|
||||
return;
|
||||
case EqdpManipulation m:
|
||||
Eqdp = m;
|
||||
ManipulationType = Type.Eqdp;
|
||||
return;
|
||||
case GmpManipulation m:
|
||||
Gmp = m;
|
||||
ManipulationType = Type.Gmp;
|
||||
return;
|
||||
case EstManipulation m:
|
||||
Est = m;
|
||||
ManipulationType = Type.Est;
|
||||
return;
|
||||
case RspManipulation m:
|
||||
Rsp = m;
|
||||
ManipulationType = Type.Rsp;
|
||||
return;
|
||||
case ImcManipulation m:
|
||||
Imc = m;
|
||||
ManipulationType = Type.Imc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MetaManipulation( EqpManipulation eqp )
|
||||
=> ( ManipulationType, Eqp ) = ( Type.Eqp, eqp );
|
||||
{
|
||||
Eqp = eqp;
|
||||
ManipulationType = Type.Eqp;
|
||||
}
|
||||
|
||||
public MetaManipulation( GmpManipulation gmp )
|
||||
=> ( ManipulationType, Gmp ) = ( Type.Gmp, gmp );
|
||||
{
|
||||
Gmp = gmp;
|
||||
ManipulationType = Type.Gmp;
|
||||
}
|
||||
|
||||
public MetaManipulation( EqdpManipulation eqdp )
|
||||
=> ( ManipulationType, Eqdp ) = ( Type.Eqdp, eqdp );
|
||||
{
|
||||
Eqdp = eqdp;
|
||||
ManipulationType = Type.Eqdp;
|
||||
}
|
||||
|
||||
public MetaManipulation( EstManipulation est )
|
||||
=> ( ManipulationType, Est ) = ( Type.Est, est );
|
||||
{
|
||||
Est = est;
|
||||
ManipulationType = Type.Est;
|
||||
}
|
||||
|
||||
public MetaManipulation( RspManipulation rsp )
|
||||
=> ( ManipulationType, Rsp ) = ( Type.Rsp, rsp );
|
||||
{
|
||||
Rsp = rsp;
|
||||
ManipulationType = Type.Rsp;
|
||||
}
|
||||
|
||||
public MetaManipulation( ImcManipulation imc )
|
||||
=> ( ManipulationType, Imc ) = ( Type.Imc, imc );
|
||||
{
|
||||
Imc = imc;
|
||||
ManipulationType = Type.Imc;
|
||||
}
|
||||
|
||||
public static implicit operator MetaManipulation( EqpManipulation eqp )
|
||||
=> new(eqp);
|
||||
|
|
@ -110,7 +275,9 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
|||
|
||||
public unsafe int CompareTo( MetaManipulation other )
|
||||
{
|
||||
fixed(MetaManipulation* lhs = &this)
|
||||
return Functions.MemCmpUnchecked(lhs, &other, sizeof(MetaManipulation));
|
||||
fixed( MetaManipulation* lhs = &this )
|
||||
{
|
||||
return Functions.MemCmpUnchecked( lhs, &other, sizeof( MetaManipulation ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,22 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
|
||||
namespace Penumbra.Meta.Manipulations;
|
||||
|
||||
public readonly struct RspManipulation : IEquatable< RspManipulation >
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public readonly struct RspManipulation : IMetaManipulation< RspManipulation >
|
||||
{
|
||||
public readonly float Entry;
|
||||
public readonly SubRace SubRace;
|
||||
public readonly float Entry;
|
||||
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly SubRace SubRace;
|
||||
|
||||
[JsonConverter( typeof( StringEnumConverter ) )]
|
||||
public readonly RspAttribute Attribute;
|
||||
|
||||
public RspManipulation( SubRace subRace, RspAttribute attribute, float entry )
|
||||
|
|
@ -31,6 +39,12 @@ public readonly struct RspManipulation : IEquatable< RspManipulation >
|
|||
public override int GetHashCode()
|
||||
=> HashCode.Combine( ( int )SubRace, ( int )Attribute );
|
||||
|
||||
public int CompareTo( RspManipulation other )
|
||||
{
|
||||
var s = SubRace.CompareTo( other.SubRace );
|
||||
return s != 0 ? s : Attribute.CompareTo( other.Attribute );
|
||||
}
|
||||
|
||||
public int FileIndex()
|
||||
=> CharacterUtility.HumanCmpIdx;
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ public class MetaManager2 : IDisposable
|
|||
return false;
|
||||
}
|
||||
|
||||
var file = m.Type switch
|
||||
var file = m.Slot switch
|
||||
{
|
||||
EstManipulation.EstType.Hair => HairEstFile ??= new EstFile( EstManipulation.EstType.Hair ),
|
||||
EstManipulation.EstType.Face => FaceEstFile ??= new EstFile( EstManipulation.EstType.Face ),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Text;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
|
|
@ -484,39 +486,39 @@ namespace Penumbra.UI
|
|||
private bool DrawRspRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var ret = false;
|
||||
//var id = list[ manipIdx ].RspIdentifier;
|
||||
//var val = list[ manipIdx ].RspValue;
|
||||
//
|
||||
//if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
//{
|
||||
// using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
// 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 * ImGuiHelpers.GlobalScale );
|
||||
// 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.Text( id.Attribute.ToUngenderedString() );
|
||||
//ImGui.TableNextColumn();
|
||||
//ImGui.TableNextColumn();
|
||||
//ImGui.TableNextColumn();
|
||||
//ImGui.Text( id.SubRace.ToString() );
|
||||
//ImGui.TableNextColumn();
|
||||
//ImGui.Text( id.Attribute.ToGender().ToString() );
|
||||
var id = list[ manipIdx ].RspIdentifier;
|
||||
var val = list[ manipIdx ].RspValue;
|
||||
|
||||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
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 * ImGuiHelpers.GlobalScale );
|
||||
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.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;
|
||||
}
|
||||
|
||||
|
|
@ -543,35 +545,35 @@ namespace Penumbra.UI
|
|||
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:X}##{manipIdx}" ) )
|
||||
//{
|
||||
// ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
|
||||
//}
|
||||
//
|
||||
//ImGui.TableNextRow();
|
||||
switch( type )
|
||||
{
|
||||
case MetaManipulation.Type.Eqp:
|
||||
changes = DrawEqpRow( manipIdx, list );
|
||||
break;
|
||||
case MetaManipulation.Type.Gmp:
|
||||
changes = DrawGmpRow( manipIdx, list );
|
||||
break;
|
||||
case MetaManipulation.Type.Eqdp:
|
||||
changes = DrawEqdpRow( manipIdx, list );
|
||||
break;
|
||||
case MetaManipulation.Type.Est:
|
||||
changes = DrawEstRow( manipIdx, list );
|
||||
break;
|
||||
case MetaManipulation.Type.Imc:
|
||||
changes = DrawImcRow( manipIdx, list );
|
||||
break;
|
||||
case MetaManipulation.Type.Rsp:
|
||||
changes = DrawRspRow( manipIdx, list );
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui.TableSetColumnIndex( 9 );
|
||||
if( ImGui.Selectable( $"{manipIdx}##{manipIdx}" ) )
|
||||
{
|
||||
ImGui.OpenPopup( $"##MetaPopup{manipIdx}" );
|
||||
}
|
||||
|
||||
ImGui.TableNextRow();
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
|
@ -714,6 +716,8 @@ namespace Penumbra.UI
|
|||
{
|
||||
var numRows = _editMode ? 11 : 10;
|
||||
var changes = false;
|
||||
|
||||
|
||||
if( list.Count > 0
|
||||
&& ImGui.BeginTable( label, numRows,
|
||||
ImGuiTableFlags.BordersInner | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue