mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +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 );
|
||||
foreach( var manip in manipArray )
|
||||
foreach( var manip in manipArray.Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||
{
|
||||
if( !manips.Add( manip ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -138,7 +138,11 @@ public partial class TexToolsMeta
|
|||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ public partial class MetaManager
|
|||
|
||||
public bool ApplyMod( ImcManipulation manip )
|
||||
{
|
||||
if( !manip.Valid )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_imcManipulations.AddOrReplace( manip );
|
||||
var path = manip.GamePath();
|
||||
try
|
||||
|
|
@ -91,7 +96,7 @@ public partial class MetaManager
|
|||
|
||||
public bool RevertMod( ImcManipulation m )
|
||||
{
|
||||
if( !_imcManipulations.Remove( m ) )
|
||||
if( !m.Valid || !_imcManipulations.Remove( m ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,13 +32,17 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
|||
{
|
||||
Entry = entry;
|
||||
PrimaryId = primaryId;
|
||||
Variant = ( byte )variant;
|
||||
Variant = ( byte )Math.Clamp( variant, ( ushort )0, byte.MaxValue );
|
||||
SecondaryId = 0;
|
||||
ObjectType = equipSlot.IsAccessory() ? ObjectType.Accessory : ObjectType.Equipment;
|
||||
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]
|
||||
internal ImcManipulation( ObjectType objectType, BodySlot bodySlot, ushort primaryId, ushort secondaryId, ushort variant,
|
||||
EquipSlot equipSlot, ImcEntry entry )
|
||||
|
|
@ -46,16 +50,17 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
|||
Entry = entry;
|
||||
ObjectType = objectType;
|
||||
PrimaryId = primaryId;
|
||||
Variant = ( byte )variant;
|
||||
Variant = ( byte )Math.Clamp( variant, ( ushort )0, byte.MaxValue );
|
||||
|
||||
if( objectType is ObjectType.Accessory or ObjectType.Equipment )
|
||||
{
|
||||
BodySlot = BodySlot.Unknown;
|
||||
BodySlot = variant > byte.MaxValue ? BodySlot.Body : BodySlot.Unknown;
|
||||
SecondaryId = 0;
|
||||
EquipSlot = equipSlot;
|
||||
}
|
||||
else if( objectType is ObjectType.DemiHuman )
|
||||
{
|
||||
BodySlot = BodySlot.Unknown;
|
||||
BodySlot = variant > byte.MaxValue ? BodySlot.Body : BodySlot.Unknown;
|
||||
SecondaryId = secondaryId;
|
||||
EquipSlot = equipSlot == EquipSlot.Unknown ? EquipSlot.Head : equipSlot;
|
||||
}
|
||||
|
|
@ -63,10 +68,19 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
|
|||
{
|
||||
BodySlot = bodySlot;
|
||||
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 )
|
||||
=> new(ObjectType, BodySlot, PrimaryId, SecondaryId, Variant, EquipSlot, entry);
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
|||
return;
|
||||
case ImcManipulation m:
|
||||
Imc = m;
|
||||
ManipulationType = Type.Imc;
|
||||
ManipulationType = m.Valid ? Type.Imc : Type.Unknown;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
|||
Type.Est => Est.Equals( other.Est ),
|
||||
Type.Rsp => Rsp.Equals( other.Rsp ),
|
||||
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.Rsp => Rsp.GetHashCode(),
|
||||
Type.Imc => Imc.GetHashCode(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
public unsafe int CompareTo( MetaManipulation other )
|
||||
|
|
@ -249,7 +249,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
|
|||
Type.Est => Est.ToString(),
|
||||
Type.Rsp => Rsp.ToString(),
|
||||
Type.Imc => Imc.ToString(),
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
_ => "Invalid",
|
||||
};
|
||||
|
||||
public string EntryToString()
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public partial class Mod
|
|||
var manips = json[ nameof( Manipulations ) ];
|
||||
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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -930,7 +930,7 @@ public partial class ModEditWindow
|
|||
var version = Functions.FromCompressedBase64< MetaManipulation[] >( clipboard, out var manips );
|
||||
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 );
|
||||
}
|
||||
|
|
@ -950,7 +950,7 @@ public partial class ModEditWindow
|
|||
if( version == MetaManipulation.CurrentVersion && manips != null )
|
||||
{
|
||||
_editor!.Meta.Clear();
|
||||
foreach( var manip in manips )
|
||||
foreach( var manip in manips.Where( m => m.ManipulationType != MetaManipulation.Type.Unknown ) )
|
||||
{
|
||||
_editor!.Meta.Set( manip );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue