diff --git a/PCK-Studio/Forms/Editor/ANIMEditor.cs b/PCK-Studio/Forms/Editor/ANIMEditor.cs index 3718dcd8..bd27d242 100644 --- a/PCK-Studio/Forms/Editor/ANIMEditor.cs +++ b/PCK-Studio/Forms/Editor/ANIMEditor.cs @@ -328,18 +328,18 @@ namespace PckStudio.Forms.Editor setDisplayAnim((SkinANIM)initialANIM.Clone()); } - static readonly Dictionary Templates = new Dictionary() + static readonly Dictionary Templates = new Dictionary() { - { "Steve (64x32)", SkinAnimFlag.NONE }, - { "Steve (64x64)", SkinAnimFlag.RESOLUTION_64x64 }, - { "Alex (64x64)", SkinAnimFlag.SLIM_MODEL }, - { "Zombie Skins", SkinAnimFlag.ZOMBIE_ARMS }, - { "Cetacean Skins", SkinAnimFlag.SYNCED_ARMS | SkinAnimFlag.SYNCED_LEGS }, - { "Ski Skins", SkinAnimFlag.SYNCED_ARMS | SkinAnimFlag.STATIC_LEGS }, - { "Ghost Skins", SkinAnimFlag.STATIC_LEGS | SkinAnimFlag.ZOMBIE_ARMS }, - { "Medusa (Greek Myth.)", SkinAnimFlag.SYNCED_LEGS }, - { "Librarian (Halo)", SkinAnimFlag.STATIC_LEGS }, - { "Grim Reaper (Halloween)", SkinAnimFlag.STATIC_LEGS | SkinAnimFlag.STATIC_ARMS } + { "Steve (64x32)", SkinAnimMask.NONE }, + { "Steve (64x64)", SkinAnimMask.RESOLUTION_64x64 }, + { "Alex (64x64)", SkinAnimMask.SLIM_MODEL }, + { "Zombie Skins", SkinAnimMask.ZOMBIE_ARMS }, + { "Cetacean Skins", SkinAnimMask.SYNCED_ARMS | SkinAnimMask.SYNCED_LEGS }, + { "Ski Skins", SkinAnimMask.SYNCED_ARMS | SkinAnimMask.STATIC_LEGS }, + { "Ghost Skins", SkinAnimMask.STATIC_LEGS | SkinAnimMask.ZOMBIE_ARMS }, + { "Medusa (Greek Myth.)", SkinAnimMask.SYNCED_LEGS }, + { "Librarian (Halo)", SkinAnimMask.STATIC_LEGS }, + { "Grim Reaper (Halloween)", SkinAnimMask.STATIC_LEGS | SkinAnimMask.STATIC_ARMS } }; private void templateButton_Click(object sender, EventArgs e) diff --git a/PCK-Studio/Internal/SkinANIM.cs b/PCK-Studio/Internal/SkinANIM.cs index 784ff3f1..c152efa8 100644 --- a/PCK-Studio/Internal/SkinANIM.cs +++ b/PCK-Studio/Internal/SkinANIM.cs @@ -16,118 +16,72 @@ * 3. This notice may not be removed or altered from any source distribution. **/ using System; +using System.Collections.Specialized; using System.Text.RegularExpressions; namespace PckStudio.Internal { - /// - /// For usage see - /// - [Flags] - public enum SkinAnimFlag : int - { - NONE = 0, // 0x00 - STATIC_ARMS = 1 << 0, // 0x01 - ZOMBIE_ARMS = 1 << 1, // 0x02 - STATIC_LEGS = 1 << 2, // 0x04 - BAD_SANTA = 1 << 3, // 0x08 - // - __BIT_4 = 1 << 4, // 0x10 - Unused?? - SYNCED_LEGS = 1 << 5, // 0x20 - SYNCED_ARMS = 1 << 6, // 0x40 - STATUE_OF_LIBERTY = 1 << 7, // 0x80 - - ALL_ARMOR_DISABLED = 1 << 8, // 0x100 - HEAD_BOBBING_DISABLED = 1 << 9, // 0x200 - HEAD_DISABLED = 1 << 10, // 0x400 - RIGHT_ARM_DISABLED = 1 << 11, // 0x800 - - LEFT_ARM_DISABLED = 1 << 12, // 0x1000 - BODY_DISABLED = 1 << 13, // 0x2000 - RIGHT_LEG_DISABLED = 1 << 14, // 0x4000 - LEFT_LEG_DISABLED = 1 << 15, // 0x8000 - - HEAD_OVERLAY_DISABLED = 1 << 16, // 0x10000 - DO_BACKWARDS_CROUCH = 1 << 17, // 0x20000 - RESOLUTION_64x64 = 1 << 18, // 0x40000 - SLIM_MODEL = 1 << 19, // 0x80000 - - LEFT_ARM_OVERLAY_DISABLED = 1 << 20, // 0x100000 - RIGHT_ARM_OVERLAY_DISABLED = 1 << 21, // 0x200000 - LEFT_LEG_OVERLAY_DISABLED = 1 << 22, // 0x400000 - RIGHT_LEG_OVERLAY_DISABLED = 1 << 23, // 0x800000 - - BODY_OVERLAY_DISABLED = 1 << 24, // 0x1000000 - FORCE_HEAD_ARMOR = 1 << 25, // 0x2000000 - FORCE_RIGHT_ARM_ARMOR = 1 << 26, // 0x4000000 - FORCE_LEFT_ARM_ARMOR = 1 << 27, // 0x8000000 - - FORCE_BODY_ARMOR = 1 << 28, // 0x10000000 - FORCE_RIGHT_LEG_ARMOR = 1 << 29, // 0x20000000 - FORCE_LEFT_LEG_ARMOR = 1 << 30, // 0x40000000 - DINNERBONE = 1 << 31, // 0x80000000 - } - /// /// Represents a Skin Anim value where flags can be set /// - public class SkinANIM : ICloneable, IEquatable, IEquatable + public class SkinANIM : ICloneable, IEquatable, IEquatable { public static readonly SkinANIM Empty = new SkinANIM(); - private SkinAnimFlag _flags; + private BitVector32 _flags; private static readonly Regex _validator = new Regex(@"^0x[0-9a-f]{1,8}\b", RegexOptions.IgnoreCase); public SkinANIM() - : this(SkinAnimFlag.NONE) + : this(SkinAnimMask.NONE) { } - public SkinANIM(SkinAnimFlag mask) + public SkinANIM(SkinAnimMask mask) + : this((int)mask) { - _flags = mask; } - public override string ToString() => "0x" + ((int)_flags).ToString("x8"); + private SkinANIM(int mask) + { + _flags = new BitVector32(mask); + } + + public override string ToString() => "0x" + _flags.Data.ToString("x8"); public static bool IsValidANIM(string anim) { - if (anim is not null) - return _validator.IsMatch(anim); - return false; + return !string.IsNullOrWhiteSpace(anim) && _validator.IsMatch(anim); } public static SkinANIM FromString(string value) => IsValidANIM(value) - ? new SkinANIM((SkinAnimFlag)Convert.ToInt32(value.TrimEnd(' ', '\n', '\r'), 16)) + ? new SkinANIM(Convert.ToInt32(value.TrimEnd(' ', '\n', '\r'), 16)) : new SkinANIM(); - public void SetMask(SkinAnimFlag mask) => _flags = mask; - - public static SkinANIM operator |(SkinANIM _this, SkinANIM other) => new SkinANIM(_this._flags | other._flags); + public static SkinANIM operator |(SkinANIM _this, SkinANIM other) => new SkinANIM(_this._flags.Data | other._flags.Data); - public static SkinANIM operator |(SkinANIM _this, SkinAnimFlag mask) => new SkinANIM(_this._flags | mask); + public static SkinANIM operator |(SkinANIM _this, SkinAnimMask mask) => new SkinANIM(_this._flags.Data | (int)mask); - public static implicit operator SkinANIM(SkinAnimFlag mask) => new SkinANIM(mask); + public static implicit operator SkinANIM(SkinAnimMask mask) => new SkinANIM(mask); - public static bool operator ==(SkinANIM _this, SkinAnimFlag mask) => _this.Equals(mask); - public static bool operator !=(SkinANIM _this, SkinAnimFlag mask) => !_this.Equals(mask); + public static bool operator ==(SkinANIM _this, SkinAnimMask mask) => _this.Equals(mask); + public static bool operator !=(SkinANIM _this, SkinAnimMask mask) => !_this.Equals(mask); public static bool operator ==(SkinANIM _this, SkinANIM other) => _this.Equals(other); public static bool operator !=(SkinANIM _this, SkinANIM other) => !_this.Equals(other); public bool Equals(SkinANIM other) { - return _flags == other._flags; + return _flags.Data == other._flags.Data; } - public bool Equals(SkinAnimFlag other) + public bool Equals(SkinAnimMask other) { - return _flags == other; + return _flags.Data == (int)other; } public override bool Equals(object obj) => obj is SkinANIM a && Equals(a); - public override int GetHashCode() => (int)_flags; + public override int GetHashCode() => _flags.Data; /// /// Sets the desired flag in the bitfield @@ -136,18 +90,21 @@ namespace PckStudio.Internal /// State of the flag public void SetFlag(SkinAnimFlag flag, bool state) { - if (state) _flags |= flag; - else _flags &= ~flag; + if (!Enum.IsDefined(typeof(SkinAnimFlag), flag)) + throw new ArgumentOutOfRangeException(nameof(flag)); + _flags[1 << (int)flag] = state; } /// - /// Gets a desired flags state + /// Gets flag state /// /// Flag to check /// True if flag is set, otherwise false public bool GetFlag(SkinAnimFlag flag) { - return (_flags & flag) != 0; + if (!Enum.IsDefined(typeof(SkinAnimFlag), flag)) + throw new ArgumentOutOfRangeException(nameof(flag)); + return _flags[1 << (int)flag]; } public object Clone() diff --git a/PCK-Studio/Internal/SkinAnimFlag.cs b/PCK-Studio/Internal/SkinAnimFlag.cs new file mode 100644 index 00000000..456c4c91 --- /dev/null +++ b/PCK-Studio/Internal/SkinAnimFlag.cs @@ -0,0 +1,67 @@ +/* Copyright (c) 2022-present miku-666, MattNL + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +**/ +using System; + +namespace PckStudio.Internal +{ + /// + /// For usage see + /// + public enum SkinAnimFlag : int + { + STATIC_ARMS = 0, // 0x01 + ZOMBIE_ARMS = 1, // 0x02 + STATIC_LEGS = 2, // 0x04 + BAD_SANTA = 3, // 0x08 + // + __BIT_4 = 4, // 0x10 - Unused?? + SYNCED_LEGS = 5, // 0x20 + SYNCED_ARMS = 6, // 0x40 + STATUE_OF_LIBERTY = 7, // 0x80 + + ALL_ARMOR_DISABLED = 8, // 0x100 + HEAD_BOBBING_DISABLED = 9, // 0x200 + HEAD_DISABLED = 10, // 0x400 + RIGHT_ARM_DISABLED = 11, // 0x800 + + LEFT_ARM_DISABLED = 12, // 0x1000 + BODY_DISABLED = 13, // 0x2000 + RIGHT_LEG_DISABLED = 14, // 0x4000 + LEFT_LEG_DISABLED = 15, // 0x8000 + + HEAD_OVERLAY_DISABLED = 16, // 0x10000 + DO_BACKWARDS_CROUCH = 17, // 0x20000 + RESOLUTION_64x64 = 18, // 0x40000 + SLIM_MODEL = 19, // 0x80000 + + LEFT_ARM_OVERLAY_DISABLED = 20, // 0x100000 + RIGHT_ARM_OVERLAY_DISABLED = 21, // 0x200000 + LEFT_LEG_OVERLAY_DISABLED = 22, // 0x400000 + RIGHT_LEG_OVERLAY_DISABLED = 23, // 0x800000 + + BODY_OVERLAY_DISABLED = 24, // 0x1000000 + FORCE_HEAD_ARMOR = 25, // 0x2000000 + FORCE_RIGHT_ARM_ARMOR = 26, // 0x4000000 + FORCE_LEFT_ARM_ARMOR = 27, // 0x8000000 + + FORCE_BODY_ARMOR = 28, // 0x10000000 + FORCE_RIGHT_LEG_ARMOR = 29, // 0x20000000 + FORCE_LEFT_LEG_ARMOR = 30, // 0x40000000 + DINNERBONE = 31, // 0x80000000 + } +} diff --git a/PCK-Studio/Internal/SkinAnimMask.cs b/PCK-Studio/Internal/SkinAnimMask.cs new file mode 100644 index 00000000..05a3b097 --- /dev/null +++ b/PCK-Studio/Internal/SkinAnimMask.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Internal +{ + [Flags] + public enum SkinAnimMask : int + { + NONE = 0, // 0x00 + STATIC_ARMS = 1 << 0, // 0x01 + ZOMBIE_ARMS = 1 << 1, // 0x02 + STATIC_LEGS = 1 << 2, // 0x04 + BAD_SANTA = 1 << 3, // 0x08 + + __BIT_4 = 1 << 4, // 0x10 - Unused?? + SYNCED_LEGS = 1 << 5, // 0x20 + SYNCED_ARMS = 1 << 6, // 0x40 + STATUE_OF_LIBERTY = 1 << 7, // 0x80 + + ALL_ARMOR_DISABLED = 1 << 8, // 0x100 + HEAD_BOBBING_DISABLED = 1 << 9, // 0x200 + HEAD_DISABLED = 1 << 10, // 0x400 + RIGHT_ARM_DISABLED = 1 << 11, // 0x800 + + LEFT_ARM_DISABLED = 1 << 12, // 0x1000 + BODY_DISABLED = 1 << 13, // 0x2000 + RIGHT_LEG_DISABLED = 1 << 14, // 0x4000 + LEFT_LEG_DISABLED = 1 << 15, // 0x8000 + + HEAD_OVERLAY_DISABLED = 1 << 16, // 0x10000 + DO_BACKWARDS_CROUCH = 1 << 17, // 0x20000 + RESOLUTION_64x64 = 1 << 18, // 0x40000 + SLIM_MODEL = 1 << 19, // 0x80000 + + LEFT_ARM_OVERLAY_DISABLED = 1 << 20, // 0x100000 + RIGHT_ARM_OVERLAY_DISABLED = 1 << 21, // 0x200000 + LEFT_LEG_OVERLAY_DISABLED = 1 << 22, // 0x400000 + RIGHT_LEG_OVERLAY_DISABLED = 1 << 23, // 0x800000 + + BODY_OVERLAY_DISABLED = 1 << 24, // 0x1000000 + FORCE_HEAD_ARMOR = 1 << 25, // 0x2000000 + FORCE_RIGHT_ARM_ARMOR = 1 << 26, // 0x4000000 + FORCE_LEFT_ARM_ARMOR = 1 << 27, // 0x8000000 + + FORCE_BODY_ARMOR = 1 << 28, // 0x10000000 + FORCE_RIGHT_LEG_ARMOR = 1 << 29, // 0x20000000 + FORCE_LEFT_LEG_ARMOR = 1 << 30, // 0x40000000 + DINNERBONE = 1 << 31, // 0x80000000 + } +} diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 7c09e1ce..cd955fc4 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -476,7 +476,7 @@ namespace PckStudio buttonEdit.Visible = true; } else if (file.Properties.HasProperty("ANIM") && - file.Properties.GetPropertyValue("ANIM", s => SkinANIM.FromString(s) == (SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL))) + file.Properties.GetPropertyValue("ANIM", s => SkinANIM.FromString(s) == (SkinAnimMask.RESOLUTION_64x64 | SkinAnimMask.SLIM_MODEL))) { buttonEdit.Text = "View Skin"; buttonEdit.Visible = true; diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index 1b1f7b15..f78b84a2 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -135,6 +135,8 @@ + + Component