Stop using windows forms, add extensive meta manipulation editing, fix a concurrency crash and a dumb crash.

This commit is contained in:
Ottermandias 2022-05-18 17:40:41 +02:00
parent e5b739fc52
commit 0c3c7ea363
25 changed files with 1266 additions and 302 deletions

View file

@ -1,43 +1,42 @@
using System.Collections.Generic;
using System.ComponentModel;
namespace Penumbra.GameData.Enums
namespace Penumbra.GameData.Enums;
public enum BodySlot : byte
{
public enum BodySlot : byte
{
Unknown,
Hair,
Face,
Tail,
Body,
Zear,
}
Unknown,
Hair,
Face,
Tail,
Body,
Zear,
}
public static class BodySlotEnumExtension
public static class BodySlotEnumExtension
{
public static string ToSuffix( this BodySlot value )
{
public static string ToSuffix( this BodySlot value )
return value switch
{
return value switch
{
BodySlot.Zear => "zear",
BodySlot.Face => "face",
BodySlot.Hair => "hair",
BodySlot.Body => "body",
BodySlot.Tail => "tail",
_ => throw new InvalidEnumArgumentException(),
};
}
}
public static partial class Names
{
public static readonly Dictionary< string, BodySlot > StringToBodySlot = new()
{
{ BodySlot.Zear.ToSuffix(), BodySlot.Zear },
{ BodySlot.Face.ToSuffix(), BodySlot.Face },
{ BodySlot.Hair.ToSuffix(), BodySlot.Hair },
{ BodySlot.Body.ToSuffix(), BodySlot.Body },
{ BodySlot.Tail.ToSuffix(), BodySlot.Tail },
BodySlot.Zear => "zear",
BodySlot.Face => "face",
BodySlot.Hair => "hair",
BodySlot.Body => "body",
BodySlot.Tail => "tail",
_ => throw new InvalidEnumArgumentException(),
};
}
}
public static partial class Names
{
public static readonly Dictionary< string, BodySlot > StringToBodySlot = new()
{
{ BodySlot.Zear.ToSuffix(), BodySlot.Zear },
{ BodySlot.Face.ToSuffix(), BodySlot.Face },
{ BodySlot.Hair.ToSuffix(), BodySlot.Hair },
{ BodySlot.Body.ToSuffix(), BodySlot.Body },
{ BodySlot.Tail.ToSuffix(), BodySlot.Tail },
};
}

View file

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Penumbra.GameData.Enums
{
@ -30,7 +32,7 @@ namespace Penumbra.GameData.Enums
All = 22, // Not officially existing
}
public static class EquipSlotEnumExtension
public static class EquipSlotExtensions
{
public static string ToSuffix( this EquipSlot value )
{
@ -79,6 +81,36 @@ namespace Penumbra.GameData.Enums
};
}
public static string ToName( this EquipSlot value )
{
return value switch
{
EquipSlot.Head => "Head",
EquipSlot.Hands => "Hands",
EquipSlot.Legs => "Legs",
EquipSlot.Feet => "Feet",
EquipSlot.Body => "Body",
EquipSlot.Ears => "Earrings",
EquipSlot.Neck => "Necklace",
EquipSlot.RFinger => "Right Ring",
EquipSlot.LFinger => "Left Ring",
EquipSlot.Wrists => "Bracelets",
EquipSlot.MainHand => "Primary Weapon",
EquipSlot.OffHand => "Secondary Weapon",
EquipSlot.Belt => "Belt",
EquipSlot.BothHand => "Primary Weapon",
EquipSlot.HeadBody => "Head and Body",
EquipSlot.BodyHandsLegsFeet => "Costume",
EquipSlot.SoulCrystal => "Soul Crystal",
EquipSlot.LegsFeet => "Bottom",
EquipSlot.FullBody => "Costume",
EquipSlot.BodyHands => "Top",
EquipSlot.BodyLegsFeet => "Costume",
EquipSlot.All => "Costume",
_ => "Unknown",
};
}
public static bool IsEquipment( this EquipSlot value )
{
return value switch
@ -104,6 +136,10 @@ namespace Penumbra.GameData.Enums
_ => false,
};
}
public static readonly EquipSlot[] EquipmentSlots = Enum.GetValues< EquipSlot >().Where( e => e.IsEquipment() ).ToArray();
public static readonly EquipSlot[] AccessorySlots = Enum.GetValues< EquipSlot >().Where( e => e.IsAccessory() ).ToArray();
public static readonly EquipSlot[] EqdpSlots = EquipmentSlots.Concat( AccessorySlots ).ToArray();
}
public static partial class Names

View file

@ -1,21 +1,55 @@
namespace Penumbra.GameData.Enums
using System;
namespace Penumbra.GameData.Enums;
public enum ObjectType : byte
{
public enum ObjectType : byte
Unknown,
Vfx,
DemiHuman,
Accessory,
World,
Housing,
Monster,
Icon,
LoadingScreen,
Map,
Interface,
Equipment,
Character,
Weapon,
Font,
}
public static class ObjectTypeExtensions
{
public static string ToName( this ObjectType type )
=> type switch
{
ObjectType.Vfx => "Visual Effect",
ObjectType.DemiHuman => "Demi Human",
ObjectType.Accessory => "Accessory",
ObjectType.World => "Doodad",
ObjectType.Housing => "Housing Object",
ObjectType.Monster => "Monster",
ObjectType.Icon => "Icon",
ObjectType.LoadingScreen => "Loading Screen",
ObjectType.Map => "Map",
ObjectType.Interface => "UI Element",
ObjectType.Equipment => "Equipment",
ObjectType.Character => "Character",
ObjectType.Weapon => "Weapon",
ObjectType.Font => "Font",
_ => "Unknown",
};
public static readonly ObjectType[] ValidImcTypes =
{
Unknown,
Vfx,
DemiHuman,
Accessory,
World,
Housing,
Monster,
Icon,
LoadingScreen,
Map,
Interface,
Equipment,
Character,
Weapon,
Font,
}
ObjectType.Equipment,
ObjectType.Accessory,
ObjectType.DemiHuman,
ObjectType.Monster,
ObjectType.Weapon,
};
}

View file

@ -2,106 +2,119 @@ using System;
using System.ComponentModel;
using Penumbra.GameData.Enums;
namespace Penumbra.GameData.Structs
namespace Penumbra.GameData.Structs;
[Flags]
public enum EqdpEntry : ushort
{
[Flags]
public enum EqdpEntry : ushort
Invalid = 0,
Head1 = 0b0000000001,
Head2 = 0b0000000010,
HeadMask = 0b0000000011,
Body1 = 0b0000000100,
Body2 = 0b0000001000,
BodyMask = 0b0000001100,
Hands1 = 0b0000010000,
Hands2 = 0b0000100000,
HandsMask = 0b0000110000,
Legs1 = 0b0001000000,
Legs2 = 0b0010000000,
LegsMask = 0b0011000000,
Feet1 = 0b0100000000,
Feet2 = 0b1000000000,
FeetMask = 0b1100000000,
Ears1 = 0b0000000001,
Ears2 = 0b0000000010,
EarsMask = 0b0000000011,
Neck1 = 0b0000000100,
Neck2 = 0b0000001000,
NeckMask = 0b0000001100,
Wrists1 = 0b0000010000,
Wrists2 = 0b0000100000,
WristsMask = 0b0000110000,
RingR1 = 0b0001000000,
RingR2 = 0b0010000000,
RingRMask = 0b0011000000,
RingL1 = 0b0100000000,
RingL2 = 0b1000000000,
RingLMask = 0b1100000000,
}
public static class Eqdp
{
public static int Offset( EquipSlot slot )
=> slot switch
{
EquipSlot.Head => 0,
EquipSlot.Body => 2,
EquipSlot.Hands => 4,
EquipSlot.Legs => 6,
EquipSlot.Feet => 8,
EquipSlot.Ears => 0,
EquipSlot.Neck => 2,
EquipSlot.Wrists => 4,
EquipSlot.RFinger => 6,
EquipSlot.LFinger => 8,
_ => throw new InvalidEnumArgumentException(),
};
public static (bool, bool) ToBits( this EqdpEntry entry, EquipSlot slot )
=> slot switch
{
EquipSlot.Head => ( entry.HasFlag( EqdpEntry.Head1 ), entry.HasFlag( EqdpEntry.Head2 ) ),
EquipSlot.Body => ( entry.HasFlag( EqdpEntry.Body1 ), entry.HasFlag( EqdpEntry.Body2 ) ),
EquipSlot.Hands => ( entry.HasFlag( EqdpEntry.Hands1 ), entry.HasFlag( EqdpEntry.Hands2 ) ),
EquipSlot.Legs => ( entry.HasFlag( EqdpEntry.Legs1 ), entry.HasFlag( EqdpEntry.Legs2 ) ),
EquipSlot.Feet => ( entry.HasFlag( EqdpEntry.Feet1 ), entry.HasFlag( EqdpEntry.Feet2 ) ),
EquipSlot.Ears => ( entry.HasFlag( EqdpEntry.Ears1 ), entry.HasFlag( EqdpEntry.Ears2 ) ),
EquipSlot.Neck => ( entry.HasFlag( EqdpEntry.Neck1 ), entry.HasFlag( EqdpEntry.Neck2 ) ),
EquipSlot.Wrists => ( entry.HasFlag( EqdpEntry.Wrists1 ), entry.HasFlag( EqdpEntry.Wrists2 ) ),
EquipSlot.RFinger => ( entry.HasFlag( EqdpEntry.RingR1 ), entry.HasFlag( EqdpEntry.RingR2 ) ),
EquipSlot.LFinger => ( entry.HasFlag( EqdpEntry.RingL1 ), entry.HasFlag( EqdpEntry.RingL2 ) ),
_ => throw new InvalidEnumArgumentException(),
};
public static EqdpEntry FromSlotAndBits( EquipSlot slot, bool bit1, bool bit2 )
{
Invalid = 0,
Head1 = 0b0000000001,
Head2 = 0b0000000010,
HeadMask = 0b0000000011,
EqdpEntry ret = 0;
var offset = Offset( slot );
if( bit1 )
{
ret |= ( EqdpEntry )( 1 << offset );
}
Body1 = 0b0000000100,
Body2 = 0b0000001000,
BodyMask = 0b0000001100,
if( bit2 )
{
ret |= ( EqdpEntry )( 1 << ( offset + 1 ) );
}
Hands1 = 0b0000010000,
Hands2 = 0b0000100000,
HandsMask = 0b0000110000,
Legs1 = 0b0001000000,
Legs2 = 0b0010000000,
LegsMask = 0b0011000000,
Feet1 = 0b0100000000,
Feet2 = 0b1000000000,
FeetMask = 0b1100000000,
Ears1 = 0b0000000001,
Ears2 = 0b0000000010,
EarsMask = 0b0000000011,
Neck1 = 0b0000000100,
Neck2 = 0b0000001000,
NeckMask = 0b0000001100,
Wrists1 = 0b0000010000,
Wrists2 = 0b0000100000,
WristsMask = 0b0000110000,
RingR1 = 0b0001000000,
RingR2 = 0b0010000000,
RingRMask = 0b0011000000,
RingL1 = 0b0100000000,
RingL2 = 0b1000000000,
RingLMask = 0b1100000000,
return ret;
}
public static class Eqdp
public static EqdpEntry Mask( EquipSlot slot )
{
public static int Offset( EquipSlot slot )
return slot switch
{
return slot switch
{
EquipSlot.Head => 0,
EquipSlot.Body => 2,
EquipSlot.Hands => 4,
EquipSlot.Legs => 6,
EquipSlot.Feet => 8,
EquipSlot.Ears => 0,
EquipSlot.Neck => 2,
EquipSlot.Wrists => 4,
EquipSlot.RFinger => 6,
EquipSlot.LFinger => 8,
_ => throw new InvalidEnumArgumentException(),
};
}
public static EqdpEntry FromSlotAndBits( EquipSlot slot, bool bit1, bool bit2 )
{
EqdpEntry ret = 0;
var offset = Offset( slot );
if( bit1 )
{
ret |= ( EqdpEntry )( 1 << offset );
}
if( bit2 )
{
ret |= ( EqdpEntry )( 1 << ( offset + 1 ) );
}
return ret;
}
public static EqdpEntry Mask( EquipSlot slot )
{
return slot switch
{
EquipSlot.Head => EqdpEntry.HeadMask,
EquipSlot.Body => EqdpEntry.BodyMask,
EquipSlot.Hands => EqdpEntry.HandsMask,
EquipSlot.Legs => EqdpEntry.LegsMask,
EquipSlot.Feet => EqdpEntry.FeetMask,
EquipSlot.Ears => EqdpEntry.EarsMask,
EquipSlot.Neck => EqdpEntry.NeckMask,
EquipSlot.Wrists => EqdpEntry.WristsMask,
EquipSlot.RFinger => EqdpEntry.RingRMask,
EquipSlot.LFinger => EqdpEntry.RingLMask,
_ => 0,
};
}
EquipSlot.Head => EqdpEntry.HeadMask,
EquipSlot.Body => EqdpEntry.BodyMask,
EquipSlot.Hands => EqdpEntry.HandsMask,
EquipSlot.Legs => EqdpEntry.LegsMask,
EquipSlot.Feet => EqdpEntry.FeetMask,
EquipSlot.Ears => EqdpEntry.EarsMask,
EquipSlot.Neck => EqdpEntry.NeckMask,
EquipSlot.Wrists => EqdpEntry.WristsMask,
EquipSlot.RFinger => EqdpEntry.RingRMask,
EquipSlot.LFinger => EqdpEntry.RingLMask,
_ => 0,
};
}
}

View file

@ -198,12 +198,14 @@ public static class Eqp
EqpEntry._55 => EquipSlot.Head,
EqpEntry.HeadShowHrothgarHat => EquipSlot.Head,
EqpEntry.HeadShowVieraHat => EquipSlot.Head,
EqpEntry._58 => EquipSlot.Head,
EqpEntry._59 => EquipSlot.Head,
EqpEntry._60 => EquipSlot.Head,
EqpEntry._61 => EquipSlot.Head,
EqpEntry._62 => EquipSlot.Head,
EqpEntry._63 => EquipSlot.Head,
// Currently unused.
EqpEntry._58 => EquipSlot.Unknown,
EqpEntry._59 => EquipSlot.Unknown,
EqpEntry._60 => EquipSlot.Unknown,
EqpEntry._61 => EquipSlot.Unknown,
EqpEntry._62 => EquipSlot.Unknown,
EqpEntry._63 => EquipSlot.Unknown,
_ => EquipSlot.Unknown,
};
@ -299,7 +301,7 @@ public static class Eqp
public static readonly EqpEntry[] EqpAttributesFeet = GetEntriesForSlot( EquipSlot.Feet );
public static readonly EqpEntry[] EqpAttributesHead = GetEntriesForSlot( EquipSlot.Head );
public static IReadOnlyDictionary< EquipSlot, EqpEntry[] > EqpAttributes = new Dictionary< EquipSlot, EqpEntry[] >()
public static readonly IReadOnlyDictionary< EquipSlot, EqpEntry[] > EqpAttributes = new Dictionary< EquipSlot, EqpEntry[] >()
{
[ EquipSlot.Body ] = EqpAttributesBody,
[ EquipSlot.Legs ] = EqpAttributesLegs,