Decompiled source of Blacksmiths tools v3.0.0

plugins/BlacksmithTools.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BlacksmithTools")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: AssemblyInformationalVersion("3.0.0+b02285992a4242e125f184ea8c8fab0666cdbc24")]
[assembly: AssemblyProduct("BlacksmithTools")]
[assembly: AssemblyTitle("BlacksmithTools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
namespace BlacksmithTools;

[BepInPlugin("GoldenJude_BlacksmithTools", "BlacksmithTools", "3.0.0")]
public class Main : BaseUnityPlugin
{
	public const string MODNAME = "BlacksmithTools";

	public const string AUTHOR = "GoldenJude";

	public const string GUID = "GoldenJude_BlacksmithTools";

	public const string VERSION = "3.0.0";

	public static ManualLogSource log;

	public static Harmony harmony;

	public static Assembly assembly;

	public static string modFolder;

	public static ConfigFile configFile;

	public static ConfigEntry<bool> reorderEnabled;

	public static ConfigEntry<bool> bodyHidingEnabled;

	public static ConfigEntry<bool> loggingEnabled;

	public Main()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		log = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("GoldenJude_BlacksmithTools");
		assembly = Assembly.GetExecutingAssembly();
		modFolder = Path.GetDirectoryName(assembly.Location);
	}

	public void Start()
	{
		harmony.PatchAll(assembly);
	}

	public void Awake()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		configFile = ((BaseUnityPlugin)this).Config;
		reorderEnabled = configFile.Bind<bool>("bone reorder", "enabled", true, new ConfigDescription("", (AcceptableValueBase)null, Array.Empty<object>()));
		bodyHidingEnabled = configFile.Bind<bool>("bodypart hiding", "enabled", true, new ConfigDescription("", (AcceptableValueBase)null, Array.Empty<object>()));
		loggingEnabled = configFile.Bind<bool>("logging", "enabled", false, new ConfigDescription("", (AcceptableValueBase)null, Array.Empty<object>()));
		if (bodyHidingEnabled.Value)
		{
			BodypartSystem.BindConfigs();
		}
	}
}
internal class BodyPartController : MonoBehaviour
{
	public List<PlayerModel> originalModels = new List<PlayerModel>();

	public VisEquipment viseq;

	public void FullUpdate()
	{
		UpdateBodyModel();
	}

	public void UpdateBodyModel()
	{
		if (BodypartSystem.bodypartSettingsAsBones.Keys.Count != BodypartSystem.bodypartSettings.Keys.Count)
		{
			BodypartSystem.PartCfgToBoneindexes();
			BodypartSystem.CleanupCfgs();
		}
		List<int> list = new List<int>();
		int[] equippedHashes = Util.GetEquippedHashes(viseq);
		foreach (int num in equippedHashes)
		{
			foreach (string key in BodypartSystem.bodypartSettingsAsBones.Keys)
			{
				if (StringExtensionMethods.GetStableHashCode(key) == num || StringExtensionMethods.GetStableHashCode(Util.CorrectRRRArmorPrefabName(key)) == num)
				{
					list.AddRange(BodypartSystem.bodypartSettingsAsBones[key].ToArray());
				}
			}
		}
		Util.LogMessage("Hiding " + list.Count + " bones", (LogLevel)8);
		if (list.Count == 0)
		{
			viseq.m_models[viseq.GetModelIndex()].m_mesh = originalModels[viseq.GetModelIndex()].m_mesh;
			return;
		}
		Mesh mesh = originalModels[viseq.GetModelIndex()].m_mesh;
		Mesh val = Amputate(Object.Instantiate<Mesh>(mesh), list.ToArray());
		((Object)val).name = ((Object)mesh).name;
		viseq.m_models[viseq.GetModelIndex()].m_mesh = val;
	}

	private Mesh Amputate(Mesh body, int[] bonesToHide)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		BoneWeight[] boneWeights = body.boneWeights;
		for (int i = 0; i < body.subMeshCount; i++)
		{
			List<int> list = new List<int>(body.GetTriangles(i));
			int num = 0;
			while (num < list.Count)
			{
				bool flag = false;
				int num2 = 0;
				for (int j = 0; j < 2; j++)
				{
					if (flag)
					{
						break;
					}
					BoneWeight boneWeight = boneWeights[list[num + j]];
					float num3 = Mathf.Max(new float[4]
					{
						((BoneWeight)(ref boneWeight)).weight0,
						((BoneWeight)(ref boneWeight)).weight1,
						((BoneWeight)(ref boneWeight)).weight2,
						((BoneWeight)(ref boneWeight)).weight3
					});
					for (int k = 0; k < 4; k++)
					{
						int boneIndex = GetBoneIndex(boneWeight, k);
						foreach (int num4 in bonesToHide)
						{
							if (flag)
							{
								break;
							}
							if (boneIndex == num4)
							{
								float boneWeight2 = GetBoneWeight(boneWeight, k);
								if (boneWeight2 / num3 > 0.9f && ++num2 == 1)
								{
									flag = true;
									break;
								}
							}
						}
					}
				}
				if (flag)
				{
					list.RemoveAt(num);
					list.RemoveAt(num);
					list.RemoveAt(num);
				}
				else
				{
					num += 3;
				}
			}
			body.SetTriangles(list.ToArray(), i);
		}
		return body;
	}

	private int GetBoneIndex(BoneWeight boneWeight, int bone)
	{
		return bone switch
		{
			0 => ((BoneWeight)(ref boneWeight)).boneIndex0, 
			1 => ((BoneWeight)(ref boneWeight)).boneIndex1, 
			2 => ((BoneWeight)(ref boneWeight)).boneIndex2, 
			3 => ((BoneWeight)(ref boneWeight)).boneIndex3, 
			_ => -1, 
		};
	}

	private float GetBoneWeight(BoneWeight boneWeight, int bone)
	{
		return bone switch
		{
			0 => ((BoneWeight)(ref boneWeight)).weight0, 
			1 => ((BoneWeight)(ref boneWeight)).weight1, 
			2 => ((BoneWeight)(ref boneWeight)).weight2, 
			3 => ((BoneWeight)(ref boneWeight)).weight3, 
			_ => 0f, 
		};
	}

	public void Setup(VisEquipment _viseq)
	{
		viseq = _viseq;
		SaveOriginalModels();
		UpdateBodyModel();
		Util.LogMessage("bodypart controller attached to " + ((Object)viseq).name, (LogLevel)8);
	}

	private void SaveOriginalModels()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		for (int i = 0; i < viseq.m_models.Length; i++)
		{
			PlayerModel val = viseq.m_models[i];
			if ((Object)(object)val.m_baseMaterial == (Object)null)
			{
				Util.LogMessage("mat null", (LogLevel)8);
			}
			Material val2 = new Material(val.m_baseMaterial);
			((Object)val2).name = ((Object)val.m_baseMaterial).name;
			if ((Object)(object)val.m_mesh == (Object)null)
			{
				Util.LogMessage("mesh null", (LogLevel)8);
			}
			Mesh val3 = Object.Instantiate<Mesh>(val.m_mesh);
			((Object)val3).name = ((Object)val.m_mesh).name;
			originalModels.Add(new PlayerModel
			{
				m_baseMaterial = val2,
				m_mesh = val3
			});
		}
	}
}
[HarmonyPatch]
public static class BodypartSystem
{
	public enum bodyPart
	{
		Head,
		Torso,
		ArmUpperLeft,
		ArmLowerLeft,
		HandLeft,
		ArmUpperRight,
		ArmLowerRight,
		HandRight,
		LegUpperLeft,
		LegLowerLeft,
		FootLeft,
		LegUpperRight,
		LegLowerRight,
		FootRight,
		All,
		Beard,
		Hair
	}

	public static Dictionary<string, List<bodyPart>> bodypartSettings = new Dictionary<string, List<bodyPart>>();

	public static Dictionary<string, List<int>> bodypartSettingsAsBones = new Dictionary<string, List<int>>();

	[HarmonyPatch(typeof(VisEquipment), "Awake")]
	[HarmonyPostfix]
	private static void VisEqAwakePatch(VisEquipment __instance)
	{
		if (Main.bodyHidingEnabled.Value && __instance.m_isPlayer)
		{
			SkinnedMeshRenderer bodyModel = __instance.m_bodyModel;
			if (!((Object)(object)((bodyModel != null) ? bodyModel.sharedMesh : null) == (Object)null) && __instance.m_bodyModel.sharedMesh.isReadable)
			{
				BodyPartController bodyPartController = ((Component)__instance).gameObject.AddComponent<BodyPartController>();
				bodyPartController.Setup(__instance);
			}
		}
	}

	public static void BindConfigs()
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		string[] files = Directory.GetFiles(Paths.ConfigPath);
		string[] array = files;
		foreach (string text in array)
		{
			string fileName = Path.GetFileName(text);
			if (!fileName.StartsWith("bsmith."))
			{
				continue;
			}
			string text2 = fileName.Remove(0, 7);
			text2 = text2.Remove(text2.Length - 4, 4);
			Util.LogMessage("Loaded configuration file for " + text2, (LogLevel)8);
			if (bodypartSettingsAsBones.ContainsKey(text2))
			{
				return;
			}
			bodypartSettingsAsBones.Add(text2, new List<int>());
			ConfigFile val = new ConfigFile(text, true);
			ConfigEntry<string> val2 = val.Bind<string>("Body Parts", "List", "", "List of body parts to hide, delimited by a semilocor. List of valid values on mod page");
			string[] array2 = val2.Value.Split(new char[1] { ';' });
			for (int j = 0; j < array2.Length; j++)
			{
				bodypartSettingsAsBones[text2].AddRange(Util.BodyPartToBoneIndexes(array2[j]));
			}
			ConfigEntry<string> val3 = val.Bind<string>("Body Parts", "Bone List", "", "List of bone indexes, body model geometry weighted to these bones will be hidden, delimited by a semilocor. List of valid values on mod page");
			string[] array3 = val3.Value.Split(new char[1] { ';' });
			for (int k = 0; k < array3.Length; k++)
			{
				if (int.TryParse(array3[k], out var result))
				{
					bodypartSettingsAsBones[text2].Add(result);
				}
			}
			Util.LogMessage(bodypartSettingsAsBones[text2].Count + " bones for " + text2, (LogLevel)8);
		}
		PartCfgToBoneindexes();
		CleanupCfgs();
	}

	public static void PartCfgToBoneindexes()
	{
		foreach (string key in bodypartSettings.Keys)
		{
			if (!bodypartSettingsAsBones.ContainsKey(key))
			{
				bodypartSettingsAsBones.Add(key, new List<int>());
			}
			bodypartSettingsAsBones[key].AddRange(Util.BodyPartToBoneIndexes(bodypartSettings[key].ToArray()));
		}
	}

	public static void CleanupCfgs()
	{
		foreach (KeyValuePair<string, List<bodyPart>> bodypartSetting in bodypartSettings)
		{
			bodypartSettingsAsBones[bodypartSetting.Key] = new List<int>(bodypartSettingsAsBones[bodypartSetting.Key].Distinct().ToArray());
		}
	}

	private static void EquipmentChanged(VisEquipment viseq)
	{
		if (Main.bodyHidingEnabled.Value)
		{
			((Component)viseq).GetComponent<BodyPartController>()?.FullUpdate();
			Util.LogMessage("Equipment changed ", (LogLevel)8);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")]
	[HarmonyPostfix]
	private static void SetRightHandPatch(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetLeftHandEquipped")]
	[HarmonyPostfix]
	private static void SetLeftHandPatch(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")]
	[HarmonyPostfix]
	private static void SetChestPatch(VisEquipment __instance, bool __result, int hash)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")]
	[HarmonyPostfix]
	private static void SetLegPatch(VisEquipment __instance, bool __result, int hash)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetHelmetEquipped")]
	[HarmonyPostfix]
	private static void SetHelmetPatch(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped")]
	[HarmonyPostfix]
	private static void SetShoulderPtach(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetUtilityEquipped")]
	[HarmonyPostfix]
	private static void SetUtilityPatch(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetTrinketEquipped")]
	[HarmonyPostfix]
	private static void SetTrinketPatch(VisEquipment __instance, bool __result)
	{
		if (__result)
		{
			EquipmentChanged(__instance);
		}
	}
}
[HarmonyPatch]
public static class BoneReorder
{
	[HarmonyPatch(typeof(VisEquipment), "AttachItem")]
	[HarmonyPostfix]
	private static void AttachItemPatch(VisEquipment __instance, GameObject __result, int itemHash)
	{
		if (Main.reorderEnabled.Value && !((Object)(object)__result == (Object)null) && ((Object)__result).name.StartsWith("attach_skin") && (Object)(object)ObjectDB.instance.GetItemPrefab(itemHash) != (Object)null)
		{
			SetSMRBones(__instance, __result, itemHash);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "AttachArmor")]
	[HarmonyPostfix]
	private static void AttachArmorPatch(VisEquipment __instance, List<GameObject> __result, int itemHash)
	{
		if (!Main.reorderEnabled.Value || __result == null)
		{
			return;
		}
		foreach (GameObject item in __result)
		{
			if (((Object)item).name.StartsWith("attach_skin"))
			{
				SetSMRBones(__instance, item, itemHash);
			}
		}
	}

	public static void SetSMRBones(VisEquipment ve, GameObject instance, int hash)
	{
		Util.LogMessage("Trying to reorder bones...", (LogLevel)8);
		if ((Object)(object)ve == (Object)null || (Object)(object)ve.m_bodyModel == (Object)null || (Object)(object)ve.m_bodyModel.rootBone == (Object)null)
		{
			return;
		}
		try
		{
			SkinnedMeshRenderer componentInChildren = instance.GetComponentInChildren<SkinnedMeshRenderer>();
			SkinnedMeshRenderer[] componentsInChildren = instance.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			SkinnedMeshRenderer[] array = componentsInChildren;
			foreach (SkinnedMeshRenderer val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					SetBones(val, GetBoneNames(componentInChildren), ve.m_bodyModel.rootBone);
				}
			}
			Util.LogMessage("Success!", (LogLevel)8);
		}
		catch (Exception ex)
		{
			Util.LogMessage(ex.Message, (LogLevel)2);
		}
	}

	public static string[] GetBoneNames(SkinnedMeshRenderer smr)
	{
		List<string> list = new List<string>();
		Transform[] bones = smr.bones;
		foreach (Transform val in bones)
		{
			list.Add(((Object)val).name);
		}
		return list.ToArray();
	}

	public static void SetBones(SkinnedMeshRenderer smr, string[] boneNames, Transform skeletonRoot)
	{
		if (smr.bones.Length != boneNames.Length)
		{
			return;
		}
		Transform[] array = (Transform[])(object)new Transform[smr.bones.Length];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = Util.FindInChildren(skeletonRoot, boneNames[i]);
			if ((Object)(object)array[i] == (Object)null)
			{
				return;
			}
		}
		smr.bones = array;
		smr.rootBone = skeletonRoot;
	}
}
public static class Util
{
	public static Transform FindInChildrenWc(Transform trans, string name)
	{
		if (((Object)trans).name.ToLower().Contains(name.ToLower()))
		{
			return trans;
		}
		for (int i = 0; i < trans.childCount; i++)
		{
			Transform val = FindInChildrenWc(trans.GetChild(i), name);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return null;
	}

	public static Transform FindInChildren(Transform trans, string name)
	{
		if (((Object)trans).name == name)
		{
			return trans;
		}
		for (int i = 0; i < trans.childCount; i++)
		{
			Transform val = FindInChildren(trans.GetChild(i), name);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return null;
	}

	public static List<BodypartSystem.bodyPart> StringToParts(string partstring)
	{
		List<BodypartSystem.bodyPart> list = new List<BodypartSystem.bodyPart>();
		string[] array = partstring.Split(new char[1] { ';' });
		foreach (string value in array)
		{
			if (Enum.TryParse<BodypartSystem.bodyPart>(value, out var result) && !list.Contains(result))
			{
				list.Add(result);
			}
		}
		return list;
	}

	public static string CorrectRRRArmorPrefabName(string name)
	{
		string[] array = name.Split(new char[1] { '@' });
		if (array.Length > 1)
		{
			return array[1];
		}
		return name;
	}

	public static string[] GetEquippedItemNames(VisEquipment ve, ObjectDB db)
	{
		if ((Object)(object)ve == (Object)null || (Object)(object)db == (Object)null)
		{
			return new string[0];
		}
		List<string> list = new List<string>();
		int[] equippedHashes = GetEquippedHashes(ve);
		foreach (int num in equippedHashes)
		{
			GameObject itemPrefab = db.GetItemPrefab(num);
			if (!((Object)(object)itemPrefab == (Object)null))
			{
				list.Add(((Object)itemPrefab).name);
			}
		}
		return list.ToArray();
	}

	public static int[] GetEquippedHashes(VisEquipment ve)
	{
		if ((Object)(object)ve == (Object)null)
		{
			return new int[0];
		}
		List<int> list = new List<int>();
		if (ve.m_currentLeftItemHash != 0)
		{
			list.Add(ve.m_currentLeftItemHash);
		}
		if (ve.m_currentRightItemHash != 0)
		{
			list.Add(ve.m_currentRightItemHash);
		}
		if (ve.m_currentChestItemHash != 0)
		{
			list.Add(ve.m_currentChestItemHash);
		}
		if (ve.m_currentLegItemHash != 0)
		{
			list.Add(ve.m_currentLegItemHash);
		}
		if (ve.m_currentHelmetItemHash != 0)
		{
			list.Add(ve.m_currentHelmetItemHash);
		}
		if (ve.m_currentShoulderItemHash != 0)
		{
			list.Add(ve.m_currentShoulderItemHash);
		}
		if (ve.m_currentBeardItemHash != 0)
		{
			list.Add(ve.m_currentBeardItemHash);
		}
		if (ve.m_currentHairItemHash != 0)
		{
			list.Add(ve.m_currentHairItemHash);
		}
		if (ve.m_currentUtilityItemHash != 0)
		{
			list.Add(ve.m_currentUtilityItemHash);
		}
		if (ve.m_currentLeftBackItemHash != 0)
		{
			list.Add(ve.m_currentLeftBackItemHash);
		}
		if (ve.m_currentRightBackItemHash != 0)
		{
			list.Add(ve.m_currentRightBackItemHash);
		}
		return list.ToArray();
	}

	public static void LogMessage(string message, LogLevel level = (LogLevel)8)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Invalid comparison between Unknown and I4
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Invalid comparison between Unknown and I4
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Invalid comparison between Unknown and I4
		if (Main.loggingEnabled.Value)
		{
			if ((int)level == 8)
			{
				Main.log.LogMessage((object)message);
			}
			if ((int)level == 4)
			{
				Main.log.LogWarning((object)message);
			}
			if ((int)level == 2)
			{
				Main.log.LogError((object)message);
			}
		}
	}

	public static int[] BodyPartToBoneIndexes(string part)
	{
		if (Enum.TryParse<BodypartSystem.bodyPart>(part, out var result))
		{
			return BodyPartToBoneIndexes(result);
		}
		return new int[1] { -100 };
	}

	public static int[] BodyPartToBoneIndexes(BodypartSystem.bodyPart[] part)
	{
		List<int> list = new List<int>();
		for (int i = 0; i < part.Length; i++)
		{
			list.AddRange(BodyPartToBoneIndexes(part[i]));
		}
		return list.ToArray();
	}

	public static int[] BodyPartToBoneIndexes(BodypartSystem.bodyPart part)
	{
		return part switch
		{
			BodypartSystem.bodyPart.All => new int[1] { -1 }, 
			BodypartSystem.bodyPart.Head => new int[3] { 4, 5, 6 }, 
			BodypartSystem.bodyPart.Torso => new int[6] { 0, 1, 2, 3, 7, 26 }, 
			BodypartSystem.bodyPart.ArmUpperLeft => new int[1] { 8 }, 
			BodypartSystem.bodyPart.ArmLowerLeft => new int[1] { 9 }, 
			BodypartSystem.bodyPart.HandLeft => new int[17]
			{
				10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
				20, 21, 22, 23, 24, 25, 26
			}, 
			BodypartSystem.bodyPart.ArmUpperRight => new int[1] { 27 }, 
			BodypartSystem.bodyPart.ArmLowerRight => new int[1] { 28 }, 
			BodypartSystem.bodyPart.HandRight => new int[16]
			{
				29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
				39, 40, 41, 42, 43, 44
			}, 
			BodypartSystem.bodyPart.LegUpperLeft => new int[1] { 45 }, 
			BodypartSystem.bodyPart.LegLowerLeft => new int[1] { 46 }, 
			BodypartSystem.bodyPart.FootLeft => new int[2] { 47, 48 }, 
			BodypartSystem.bodyPart.LegUpperRight => new int[1] { 49 }, 
			BodypartSystem.bodyPart.LegLowerRight => new int[1] { 50 }, 
			BodypartSystem.bodyPart.FootRight => new int[2] { 51, 52 }, 
			_ => new int[1] { -100 }, 
		};
	}
}