mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-21 22:46:47 +00:00
Added SkinArmorFlags classes
This commit is contained in:
@@ -83,10 +83,10 @@ namespace PckStudio.Controls
|
||||
SizeZUpDown.Value = (decimal)box.Size.Z;
|
||||
uvXUpDown.Value = (decimal)box.UV.X;
|
||||
uvYUpDown.Value = (decimal)box.UV.Y;
|
||||
helmetCheckBox.Checked = (box.ArmorMaskFlags & 1) != 0;
|
||||
chestplateCheckBox.Checked = (box.ArmorMaskFlags & 2) != 0;
|
||||
leggingsCheckBox.Checked = (box.ArmorMaskFlags & 4) != 0;
|
||||
bootsCheckBox.Checked = (box.ArmorMaskFlags & 8) != 0;
|
||||
helmetCheckBox.Checked = box.ArmorMaskFlags.GetFlag(SkinArmorFlagsFlag.HELMET);
|
||||
chestplateCheckBox.Checked = box.ArmorMaskFlags.GetFlag(SkinArmorFlagsFlag.CHESTPLATE);
|
||||
leggingsCheckBox.Checked = box.ArmorMaskFlags.GetFlag(SkinArmorFlagsFlag.LEGGINGS);
|
||||
bootsCheckBox.Checked = box.ArmorMaskFlags.GetFlag(SkinArmorFlagsFlag.BOOTS);
|
||||
mirrorCheckBox.Checked = box.Mirror;
|
||||
// if the XMLVersion doesn't support scaling, set this value to 0 because it's not supported and fixes a rendering issue - May
|
||||
inflationUpDown.Value = boxVersion == 3 ? (decimal)box.Scale : 0;
|
||||
|
||||
@@ -131,7 +131,10 @@
|
||||
<Compile Include="Serializer\AtlasSerializer.cs" />
|
||||
<Compile Include="Serializer\ImageSerializer.cs" />
|
||||
<Compile Include="Skin\Skin.cs" />
|
||||
<Compile Include="Skin\SkinArmorFlagsFlag.cs" />
|
||||
<Compile Include="Skin\SkinArmorFlags.cs" />
|
||||
<Compile Include="Skin\SkinGameFlagsFlag.cs" />
|
||||
<Compile Include="Skin\SkinArmorFlagsMask.cs" />
|
||||
<Compile Include="Skin\SkinGameFlagsMask.cs" />
|
||||
<Compile Include="Skin\SkinGameFlags.cs" />
|
||||
<Compile Include="Skin\SkinANIM.cs" />
|
||||
|
||||
120
PckStudio.Core/Skin/SkinArmorFlags.cs
Normal file
120
PckStudio.Core/Skin/SkinArmorFlags.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
/* Copyright (c) 2026-present miku-666, MayNL
|
||||
* 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;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace PckStudio.Core.Skin
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a SkinBOX ArmorFlags value where flags can be set
|
||||
/// </summary>
|
||||
public class SkinArmorFlags : ICloneable, IEquatable<SkinArmorFlags>, IEquatable<SkinArmorFlagsMask>
|
||||
{
|
||||
public static readonly SkinArmorFlags Empty = new SkinArmorFlags(0);
|
||||
public static readonly SkinArmorFlags HeadArmor = new SkinArmorFlags(1);
|
||||
public static readonly SkinArmorFlags ChestplateAndArmArmor = new SkinArmorFlags(2);
|
||||
public static readonly SkinArmorFlags Leggings = new SkinArmorFlags(4);
|
||||
public static readonly SkinArmorFlags Belt = new SkinArmorFlags(6);
|
||||
public static readonly SkinArmorFlags Boots = new SkinArmorFlags(8);
|
||||
public static readonly SkinArmorFlags Socks = new SkinArmorFlags(12);
|
||||
|
||||
private BitVector32 _flags;
|
||||
private static readonly Regex _validator = new Regex(@"^(0|[1-9]|1[0-6])$", RegexOptions.CultureInvariant);
|
||||
|
||||
public SkinArmorFlags(SkinArmorFlagsMask mask)
|
||||
: this((int)mask)
|
||||
{
|
||||
}
|
||||
|
||||
public SkinArmorFlags(int mask)
|
||||
{
|
||||
_flags = new BitVector32(mask);
|
||||
}
|
||||
|
||||
public override string ToString() => _flags.Data.ToString(); // decimal instead of hexadecimal like the other bitfields in the game
|
||||
|
||||
public static bool IsValidArmorFlags(string gameFlags)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(gameFlags) && _validator.IsMatch(gameFlags);
|
||||
}
|
||||
|
||||
public static SkinArmorFlags FromString(string value)
|
||||
=> IsValidArmorFlags(value)
|
||||
? new SkinArmorFlags(Convert.ToInt32(value))
|
||||
: Empty;
|
||||
|
||||
public static SkinArmorFlags operator |(SkinArmorFlags @this, SkinArmorFlags other) => new SkinArmorFlags(@this._flags.Data | other._flags.Data);
|
||||
|
||||
public static SkinArmorFlags operator |(SkinArmorFlags @this, SkinArmorFlagsMask mask) => new SkinArmorFlags(@this._flags.Data | (int)mask);
|
||||
public static SkinArmorFlags operator &(SkinArmorFlags @this, SkinArmorFlagsMask mask) => new SkinArmorFlags(@this._flags.Data & (int)mask);
|
||||
public static SkinArmorFlags FromValue(int value) => new SkinArmorFlags(value);
|
||||
|
||||
public int ToValue() => _flags.Data;
|
||||
|
||||
public static implicit operator SkinArmorFlags(SkinArmorFlagsMask mask) => new SkinArmorFlags(mask);
|
||||
|
||||
public static bool operator ==(SkinArmorFlags @this, SkinArmorFlagsMask mask) => @this.Equals(mask);
|
||||
public static bool operator !=(SkinArmorFlags @this, SkinArmorFlagsMask mask) => !@this.Equals(mask);
|
||||
public static bool operator ==(SkinArmorFlags @this, SkinArmorFlags other) => @this.Equals(other);
|
||||
public static bool operator !=(SkinArmorFlags @this, SkinArmorFlags other) => !@this.Equals(other);
|
||||
|
||||
public bool Equals(SkinArmorFlags other)
|
||||
{
|
||||
return _flags.Data == other._flags.Data;
|
||||
}
|
||||
|
||||
public bool Equals(SkinArmorFlagsMask other)
|
||||
{
|
||||
return _flags.Data == (int)other;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => obj is SkinArmorFlags a && Equals(a);
|
||||
|
||||
public override int GetHashCode() => _flags.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the desired flag in the bitfield
|
||||
/// </summary>
|
||||
/// <param name="flag">SkinArmor Flag to set</param>
|
||||
/// <param name="state">State of the flag</param>
|
||||
public SkinArmorFlags SetFlag(SkinArmorFlagsFlag flag, bool state)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(SkinArmorFlagsFlag), flag))
|
||||
throw new ArgumentOutOfRangeException(nameof(flag));
|
||||
return new SkinArmorFlags(state ? _flags.Data | 1 << (int)flag : _flags.Data & ~(1 << (int)flag));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets flag state
|
||||
/// </summary>
|
||||
/// <param name="flag">Flag to check</param>
|
||||
/// <returns>True if flag is set, otherwise false</returns>
|
||||
public bool GetFlag(SkinArmorFlagsFlag flag)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(SkinArmorFlagsFlag), flag))
|
||||
throw new ArgumentOutOfRangeException(nameof(flag));
|
||||
return _flags[1 << (int)flag];
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
PckStudio.Core/Skin/SkinArmorFlagsFlag.cs
Normal file
13
PckStudio.Core/Skin/SkinArmorFlagsFlag.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace PckStudio.Core.Skin
|
||||
{
|
||||
/// <summary>
|
||||
/// For usage see <see cref="SkinArmorFlags"/>
|
||||
/// </summary>
|
||||
public enum SkinArmorFlagsFlag : int
|
||||
{
|
||||
HELMET = 0, // 0x01
|
||||
CHESTPLATE = 1, // 0x02
|
||||
LEGGINGS = 2, // 0x04
|
||||
BOOTS = 3, // 0x08
|
||||
}
|
||||
}
|
||||
18
PckStudio.Core/Skin/SkinArmorFlagsMask.cs
Normal file
18
PckStudio.Core/Skin/SkinArmorFlagsMask.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PckStudio.Core.Skin
|
||||
{
|
||||
[Flags]
|
||||
public enum SkinArmorFlagsMask : int
|
||||
{
|
||||
NONE = 0, // 0x00
|
||||
HELMET = 1 << 0, // 0x01, Makes the SkinBOX invisible when wearing a helmet or other head armor
|
||||
CHESTPLATE = 1 << 1, // 0x02, Makes the SkinBOX invisible when wearing a chestplate; automatically applied with BODYARMOR, ARMARMOR0, ARMARMOR1, and BELT box types
|
||||
LEGGINGS = 1 << 2, // 0x04, Makes the SkinBOX invisible when wearing leggings; automatically applied with BELT, LEGGING0, LEGGING1, SOCK0, and SOCK1 box types
|
||||
BOOTS = 1 << 3, // 0x08, Makes the SkinBOX invisible when wearing boots; automatically applied with BOOT0, and BOOT1 box types
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ namespace PckStudio.Core.Skin
|
||||
public Vector3 Pos { get; }
|
||||
public Vector3 Size { get; }
|
||||
public Vector2 UV { get; }
|
||||
public int ArmorMaskFlags { get; }
|
||||
public SkinArmorFlags ArmorMaskFlags { get; }
|
||||
public bool Mirror { get; }
|
||||
public float Scale { get; }
|
||||
// Simplified display info for the CustomSkinEditor
|
||||
@@ -106,7 +106,7 @@ namespace PckStudio.Core.Skin
|
||||
Pos = pos;
|
||||
Size = size;
|
||||
UV = uv;
|
||||
ArmorMaskFlags = armorMaskFlags;
|
||||
ArmorMaskFlags = new SkinArmorFlags(armorMaskFlags);
|
||||
Mirror = mirror;
|
||||
Scale = scale;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace PckStudio.ModelSupport
|
||||
SkinBOX ApplyOffset(SkinBOX box)
|
||||
{
|
||||
SkinPartOffset offset = skinModel.PartOffsets.FirstOrDefault(offset => offset.Type == (box.IsOverlayPart() ? box.GetBaseType() : box.Type));
|
||||
return string.IsNullOrEmpty(offset.Type) ? box : new SkinBOX(box.Type, box.Pos - (Vector3.UnitY * offset.Value), box.Size, box.UV, box.ArmorMaskFlags, box.Mirror, box.Scale);
|
||||
return string.IsNullOrEmpty(offset.Type) ? box : new SkinBOX(box.Type, box.Pos - (Vector3.UnitY * offset.Value), box.Size, box.UV, box.ArmorMaskFlags.ToValue(), box.Mirror, box.Scale);
|
||||
}
|
||||
|
||||
IEnumerable<SkinBOX> convertedBoxes = boxes.Select(ApplyOffset);
|
||||
|
||||
@@ -13,6 +13,36 @@ namespace PckStudio.Rendering.Extension
|
||||
public static Cube ToCube(this SkinBOX skinBOX) => skinBOX.ToCube(0f);
|
||||
|
||||
public static Cube ToCube(this SkinBOX skinBOX, float inflate, bool flipZMapping = false)
|
||||
=> new Cube(skinBOX.Pos.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.UV.ToOpenTKVector(), skinBOX.Scale + inflate, skinBOX.Mirror, flipZMapping, skinBOX.ArmorMaskFlags);
|
||||
{
|
||||
SkinArmorFlags ArmorFlags = skinBOX.ArmorMaskFlags;
|
||||
|
||||
// this is to ensure armor types include the flags on top of custom defined flags for armor masking
|
||||
|
||||
switch(skinBOX.Type)
|
||||
{
|
||||
case "BODYARMOR":
|
||||
case "ARMARMOR0":
|
||||
case "ARMARMOR1":
|
||||
ArmorFlags |= SkinArmorFlags.ChestplateAndArmArmor;
|
||||
break;
|
||||
case "LEGGING0":
|
||||
case "LEGGING1":
|
||||
ArmorFlags |= SkinArmorFlags.Leggings;
|
||||
break;
|
||||
case "BOOT0":
|
||||
case "BOOT1":
|
||||
ArmorFlags |= SkinArmorFlags.Boots;
|
||||
break;
|
||||
case "BELT":
|
||||
ArmorFlags |= SkinArmorFlags.Belt;
|
||||
break;
|
||||
case "SOCK0":
|
||||
case "SOCK1":
|
||||
ArmorFlags |= SkinArmorFlags.Socks;
|
||||
break;
|
||||
}
|
||||
|
||||
return new Cube(skinBOX.Pos.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.UV.ToOpenTKVector(), skinBOX.Scale + inflate, skinBOX.Mirror, flipZMapping, ArmorFlags.ToValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user