Decompiled source of Blacksmiths tools v2.0.4

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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BlacksmithTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.4.0")]
[assembly: AssemblyInformationalVersion("2.0.4+b02285992a4242e125f184ea8c8fab0666cdbc24")]
[assembly: AssemblyProduct("BlacksmithTools")]
[assembly: AssemblyTitle("BlacksmithTools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.4.0")]
[module: UnverifiableCode]
namespace BlacksmithTools;

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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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 && GetBoneWeight(boneWeight, k) / 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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)
			{
				((Component)__instance).gameObject.AddComponent<BodyPartController>().Setup(__instance);
			}
		}
	}

	public static void BindConfigs()
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		string[] files = Directory.GetFiles(Paths.ConfigPath);
		foreach (string text in files)
		{
			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);
			string[] array = val.Bind<string>("Body Parts", "List", "", "List of body parts to hide, delimited by a semilocor. List of valid values on mod page").Value.Split(new char[1] { ';' });
			for (int j = 0; j < array.Length; j++)
			{
				bodypartSettingsAsBones[text2].AddRange(Util.BodyPartToBoneIndexes(array[j]));
			}
			string[] array2 = 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").Value.Split(new char[1] { ';' });
			for (int k = 0; k < array2.Length; k++)
			{
				if (int.TryParse(array2[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]
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"))
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)((instance != null) ? instance.GetItemPrefab(itemHash) : null) != (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)(object)item == (Object)null) && ((Object)item).name.StartsWith("attach_skin"))
			{
				SetSMRBones(__instance, item, itemHash);
			}
		}
	}

	public static void SetSMRBones(VisEquipment ve, GameObject instance, int hash)
	{
		Util.LogMessage("Reordering bones", (LogLevel)8);
		object obj;
		if (ve == null)
		{
			obj = null;
		}
		else
		{
			SkinnedMeshRenderer bodyModel = ve.m_bodyModel;
			obj = ((bodyModel != null) ? bodyModel.rootBone : null);
		}
		if ((Object)obj == (Object)null || (Object)(object)instance == (Object)null)
		{
			return;
		}
		try
		{
			SkinnedMeshRenderer[] componentsInChildren = instance.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.bones != null && val.bones.Length != 0)
				{
					SetBones(val, GetBoneNames(val), ve.m_bodyModel.rootBone);
				}
			}
		}
		catch (Exception ex)
		{
			Util.LogMessage(ex.ToString(), (LogLevel)2);
		}
	}

	public static string[] GetBoneNames(SkinnedMeshRenderer smr)
	{
		if (((smr != null) ? smr.bones : null) == null)
		{
			return Array.Empty<string>();
		}
		string[] array = new string[smr.bones.Length];
		for (int i = 0; i < smr.bones.Length; i++)
		{
			if ((Object)(object)smr.bones[i] == (Object)null)
			{
				return Array.Empty<string>();
			}
			array[i] = ((Object)smr.bones[i]).name;
		}
		return array;
	}

	public static void SetBones(SkinnedMeshRenderer smr, string[] boneNames, Transform skeletonRoot)
	{
		if ((Object)(object)smr == (Object)null || (Object)(object)skeletonRoot == (Object)null || boneNames == null || boneNames.Length == 0 || boneNames.Length != smr.bones.Length)
		{
			return;
		}
		Transform[] array = (Transform[])(object)new Transform[boneNames.Length];
		for (int i = 0; i < boneNames.Length; i++)
		{
			if (string.IsNullOrEmpty(boneNames[i]))
			{
				return;
			}
			array[i] = Util.FindInChildren(skeletonRoot, boneNames[i]);
			if ((Object)(object)array[i] == (Object)null)
			{
				return;
			}
		}
		smr.bones = array;
		smr.rootBone = skeletonRoot;
	}
}
[BepInPlugin("GoldenJude_BlacksmithTools", "BlacksmithTools", "2.0.4")]
public class Main : BaseUnityPlugin
{
	public const string MODNAME = "BlacksmithTools";

	public const string AUTHOR = "GoldenJude";

	public const string GUID = "GoldenJude_BlacksmithTools";

	public const string VERSION = "2.0.4";

	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_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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();
		}
	}
}
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] { ';' });
		for (int i = 0; i < array.Length; i++)
		{
			if (Enum.TryParse<BodypartSystem.bodyPart>(array[i], 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_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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 }, 
		};
	}
}