mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add some checks for valid variants in IMC Meta Edits.
This commit is contained in:
parent
a01f73cde4
commit
33b4905ae2
7 changed files with 39 additions and 16 deletions
|
|
@ -963,7 +963,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
}
|
}
|
||||||
|
|
||||||
manips = new HashSet< MetaManipulation >( manipArray!.Length );
|
manips = new HashSet< MetaManipulation >( manipArray!.Length );
|
||||||
foreach( var manip in manipArray )
|
foreach( var manip in manipArray.Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||||
{
|
{
|
||||||
if( !manips.Add( manip ) )
|
if( !manips.Add( manip ) )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,11 @@ public partial class TexToolsMeta
|
||||||
{
|
{
|
||||||
if( _keepDefault || !value.Equals( def.GetEntry( partIdx, i ) ) )
|
if( _keepDefault || !value.Equals( def.GetEntry( partIdx, i ) ) )
|
||||||
{
|
{
|
||||||
MetaManipulations.Add( new ImcManipulation( manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, i, manip.EquipSlot, value ) );
|
var imc = new ImcManipulation( manip.ObjectType, manip.BodySlot, manip.PrimaryId, manip.SecondaryId, i, manip.EquipSlot, value );
|
||||||
|
if( imc.Valid )
|
||||||
|
{
|
||||||
|
MetaManipulations.Add( imc );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ public partial class MetaManager
|
||||||
|
|
||||||
public bool ApplyMod( ImcManipulation manip )
|
public bool ApplyMod( ImcManipulation manip )
|
||||||
{
|
{
|
||||||
|
if( !manip.Valid )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_imcManipulations.AddOrReplace( manip );
|
_imcManipulations.AddOrReplace( manip );
|
||||||
var path = manip.GamePath();
|
var path = manip.GamePath();
|
||||||
try
|
try
|
||||||
|
|
@ -91,7 +96,7 @@ public partial class MetaManager
|
||||||
|
|
||||||
public bool RevertMod( ImcManipulation m )
|
public bool RevertMod( ImcManipulation m )
|
||||||
{
|
{
|
||||||
if( !_imcManipulations.Remove( m ) )
|
if( !m.Valid || !_imcManipulations.Remove( m ) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,17 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
||||||
{
|
{
|
||||||
Entry = entry;
|
Entry = entry;
|
||||||
PrimaryId = primaryId;
|
PrimaryId = primaryId;
|
||||||
Variant = ( byte )variant;
|
Variant = ( byte )Math.Clamp( variant, ( ushort )0, byte.MaxValue );
|
||||||
SecondaryId = 0;
|
SecondaryId = 0;
|
||||||
ObjectType = equipSlot.IsAccessory() ? ObjectType.Accessory : ObjectType.Equipment;
|
ObjectType = equipSlot.IsAccessory() ? ObjectType.Accessory : ObjectType.Equipment;
|
||||||
EquipSlot = equipSlot;
|
EquipSlot = equipSlot;
|
||||||
BodySlot = BodySlot.Unknown;
|
BodySlot = variant > byte.MaxValue ? BodySlot.Body : BodySlot.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Variants were initially ushorts but got shortened to bytes.
|
||||||
|
// There are still some manipulations around that have values > 255 for variant,
|
||||||
|
// so we change the unused value to something nonsensical in that case, just so they do not compare equal,
|
||||||
|
// and clamp the variant to 255.
|
||||||
[JsonConstructor]
|
[JsonConstructor]
|
||||||
internal ImcManipulation( ObjectType objectType, BodySlot bodySlot, ushort primaryId, ushort secondaryId, ushort variant,
|
internal ImcManipulation( ObjectType objectType, BodySlot bodySlot, ushort primaryId, ushort secondaryId, ushort variant,
|
||||||
EquipSlot equipSlot, ImcEntry entry )
|
EquipSlot equipSlot, ImcEntry entry )
|
||||||
|
|
@ -46,16 +50,17 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
||||||
Entry = entry;
|
Entry = entry;
|
||||||
ObjectType = objectType;
|
ObjectType = objectType;
|
||||||
PrimaryId = primaryId;
|
PrimaryId = primaryId;
|
||||||
Variant = ( byte )variant;
|
Variant = ( byte )Math.Clamp( variant, ( ushort )0, byte.MaxValue );
|
||||||
|
|
||||||
if( objectType is ObjectType.Accessory or ObjectType.Equipment )
|
if( objectType is ObjectType.Accessory or ObjectType.Equipment )
|
||||||
{
|
{
|
||||||
BodySlot = BodySlot.Unknown;
|
BodySlot = variant > byte.MaxValue ? BodySlot.Body : BodySlot.Unknown;
|
||||||
SecondaryId = 0;
|
SecondaryId = 0;
|
||||||
EquipSlot = equipSlot;
|
EquipSlot = equipSlot;
|
||||||
}
|
}
|
||||||
else if( objectType is ObjectType.DemiHuman )
|
else if( objectType is ObjectType.DemiHuman )
|
||||||
{
|
{
|
||||||
BodySlot = BodySlot.Unknown;
|
BodySlot = variant > byte.MaxValue ? BodySlot.Body : BodySlot.Unknown;
|
||||||
SecondaryId = secondaryId;
|
SecondaryId = secondaryId;
|
||||||
EquipSlot = equipSlot == EquipSlot.Unknown ? EquipSlot.Head : equipSlot;
|
EquipSlot = equipSlot == EquipSlot.Unknown ? EquipSlot.Head : equipSlot;
|
||||||
}
|
}
|
||||||
|
|
@ -63,10 +68,19 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
||||||
{
|
{
|
||||||
BodySlot = bodySlot;
|
BodySlot = bodySlot;
|
||||||
SecondaryId = secondaryId;
|
SecondaryId = secondaryId;
|
||||||
EquipSlot = EquipSlot.Unknown;
|
EquipSlot = variant > byte.MaxValue ? EquipSlot.All : EquipSlot.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Valid
|
||||||
|
=> ObjectType switch
|
||||||
|
{
|
||||||
|
ObjectType.Accessory => BodySlot == BodySlot.Unknown,
|
||||||
|
ObjectType.Equipment => BodySlot == BodySlot.Unknown,
|
||||||
|
ObjectType.DemiHuman => BodySlot == BodySlot.Unknown,
|
||||||
|
_ => EquipSlot == EquipSlot.Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
public ImcManipulation Copy( ImcEntry entry )
|
public ImcManipulation Copy( ImcEntry entry )
|
||||||
=> new(ObjectType, BodySlot, PrimaryId, SecondaryId, Variant, EquipSlot, entry);
|
=> new(ObjectType, BodySlot, PrimaryId, SecondaryId, Variant, EquipSlot, entry);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
||||||
return;
|
return;
|
||||||
case ImcManipulation m:
|
case ImcManipulation m:
|
||||||
Imc = m;
|
Imc = m;
|
||||||
ManipulationType = Type.Imc;
|
ManipulationType = m.Valid ? Type.Imc : Type.Unknown;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +194,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
||||||
Type.Est => Est.Equals( other.Est ),
|
Type.Est => Est.Equals( other.Est ),
|
||||||
Type.Rsp => Rsp.Equals( other.Rsp ),
|
Type.Rsp => Rsp.Equals( other.Rsp ),
|
||||||
Type.Imc => Imc.Equals( other.Imc ),
|
Type.Imc => Imc.Equals( other.Imc ),
|
||||||
_ => throw new ArgumentOutOfRangeException(),
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +229,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
||||||
Type.Est => Est.GetHashCode(),
|
Type.Est => Est.GetHashCode(),
|
||||||
Type.Rsp => Rsp.GetHashCode(),
|
Type.Rsp => Rsp.GetHashCode(),
|
||||||
Type.Imc => Imc.GetHashCode(),
|
Type.Imc => Imc.GetHashCode(),
|
||||||
_ => throw new ArgumentOutOfRangeException(),
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
public unsafe int CompareTo( MetaManipulation other )
|
public unsafe int CompareTo( MetaManipulation other )
|
||||||
|
|
@ -249,7 +249,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
||||||
Type.Est => Est.ToString(),
|
Type.Est => Est.ToString(),
|
||||||
Type.Rsp => Rsp.ToString(),
|
Type.Rsp => Rsp.ToString(),
|
||||||
Type.Imc => Imc.ToString(),
|
Type.Imc => Imc.ToString(),
|
||||||
_ => throw new ArgumentOutOfRangeException(),
|
_ => "Invalid",
|
||||||
};
|
};
|
||||||
|
|
||||||
public string EntryToString()
|
public string EntryToString()
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ public partial class Mod
|
||||||
var manips = json[ nameof( Manipulations ) ];
|
var manips = json[ nameof( Manipulations ) ];
|
||||||
if( manips != null )
|
if( manips != null )
|
||||||
{
|
{
|
||||||
foreach( var s in manips.Children().Select( c => c.ToObject< MetaManipulation >() ) )
|
foreach( var s in manips.Children().Select( c => c.ToObject< MetaManipulation >() ).Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||||
{
|
{
|
||||||
ManipulationData.Add( s );
|
ManipulationData.Add( s );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -930,7 +930,7 @@ public partial class ModEditWindow
|
||||||
var version = Functions.FromCompressedBase64< MetaManipulation[] >( clipboard, out var manips );
|
var version = Functions.FromCompressedBase64< MetaManipulation[] >( clipboard, out var manips );
|
||||||
if( version == MetaManipulation.CurrentVersion && manips != null )
|
if( version == MetaManipulation.CurrentVersion && manips != null )
|
||||||
{
|
{
|
||||||
foreach( var manip in manips )
|
foreach( var manip in manips.Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||||
{
|
{
|
||||||
_editor!.Meta.Set( manip );
|
_editor!.Meta.Set( manip );
|
||||||
}
|
}
|
||||||
|
|
@ -950,7 +950,7 @@ public partial class ModEditWindow
|
||||||
if( version == MetaManipulation.CurrentVersion && manips != null )
|
if( version == MetaManipulation.CurrentVersion && manips != null )
|
||||||
{
|
{
|
||||||
_editor!.Meta.Clear();
|
_editor!.Meta.Clear();
|
||||||
foreach( var manip in manips )
|
foreach( var manip in manips.Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||||
{
|
{
|
||||||
_editor!.Meta.Set( manip );
|
_editor!.Meta.Set( manip );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue