mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
108 lines
3 KiB
C#
108 lines
3 KiB
C#
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Converters;
|
|
using Penumbra.GameData.Enums;
|
|
using Penumbra.GameData.Structs;
|
|
using Penumbra.Interop.Structs;
|
|
using Penumbra.Meta.Files;
|
|
|
|
namespace Penumbra.Meta.Manipulations;
|
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public readonly struct EqdpManipulation : IMetaManipulation<EqdpManipulation>
|
|
{
|
|
public EqdpEntry Entry { get; private init; }
|
|
|
|
[JsonConverter(typeof(StringEnumConverter))]
|
|
public Gender Gender { get; private init; }
|
|
|
|
[JsonConverter(typeof(StringEnumConverter))]
|
|
public ModelRace Race { get; private init; }
|
|
|
|
public SetId SetId { get; private init; }
|
|
|
|
[JsonConverter(typeof(StringEnumConverter))]
|
|
public EquipSlot Slot { get; private init; }
|
|
|
|
[JsonConstructor]
|
|
public EqdpManipulation(EqdpEntry entry, EquipSlot slot, Gender gender, ModelRace race, SetId setId)
|
|
{
|
|
Gender = gender;
|
|
Race = race;
|
|
SetId = setId;
|
|
Slot = slot;
|
|
Entry = Eqdp.Mask(Slot) & entry;
|
|
}
|
|
|
|
public EqdpManipulation Copy(EqdpManipulation entry)
|
|
{
|
|
if (entry.Slot != Slot)
|
|
{
|
|
var (bit1, bit2) = entry.Entry.ToBits(entry.Slot);
|
|
return new EqdpManipulation(Eqdp.FromSlotAndBits(Slot, bit1, bit2), Slot, Gender, Race, SetId);
|
|
}
|
|
|
|
return new EqdpManipulation(entry.Entry, Slot, Gender, Race, SetId);
|
|
}
|
|
|
|
public EqdpManipulation Copy(EqdpEntry entry)
|
|
=> new(entry, Slot, Gender, Race, SetId);
|
|
|
|
public override string ToString()
|
|
=> $"Eqdp - {SetId} - {Slot} - {Race.ToName()} - {Gender.ToName()}";
|
|
|
|
public bool Equals(EqdpManipulation other)
|
|
=> Gender == other.Gender
|
|
&& Race == other.Race
|
|
&& SetId == other.SetId
|
|
&& Slot == other.Slot;
|
|
|
|
public override bool Equals(object? obj)
|
|
=> obj is EqdpManipulation other && Equals(other);
|
|
|
|
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.Id.CompareTo(other.SetId.Id);
|
|
return set != 0 ? set : Slot.CompareTo(other.Slot);
|
|
}
|
|
|
|
public MetaIndex FileIndex()
|
|
=> CharacterUtilityData.EqdpIdx(Names.CombinedRace(Gender, Race), Slot.IsAccessory());
|
|
|
|
public bool Apply(ExpandedEqdpFile file)
|
|
{
|
|
var entry = file[SetId];
|
|
var mask = Eqdp.Mask(Slot);
|
|
if ((entry & mask) == Entry)
|
|
return false;
|
|
|
|
file[SetId] = (entry & ~mask) | Entry;
|
|
return true;
|
|
}
|
|
|
|
public bool Validate()
|
|
{
|
|
var mask = Eqdp.Mask(Slot);
|
|
if (mask == 0)
|
|
return false;
|
|
|
|
if ((mask & Entry) != Entry)
|
|
return false;
|
|
|
|
if (FileIndex() == (MetaIndex)(-1))
|
|
return false;
|
|
|
|
// No check for set id.
|
|
return true;
|
|
}
|
|
}
|