Decompiled source of EliteEquipment v0.1.0

plugins\EliteEquipment.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BundlePrefabs;
using Charter;
using ConfigReload;
using EliteCraftingLink;
using EliteEquipment.Boots;
using EliteEquipment.Core;
using EliteEquipment.Fitted;
using HarmonyLib;
using ItemCopies;
using MagicaCloth2;
using Microsoft.CodeAnalysis;
using PatchGuard;
using PlateColumn;
using SyncedConfig;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.UI;
using YamlConfig;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("EliteEquipment")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("EliteEquipment: more from the game's own equipment, starting with boots split from the leggings")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+0cf3be3418919774cf3d3c90f9043bcbb4d8d38a")]
[assembly: AssemblyProduct("EliteEquipment")]
[assembly: AssemblyTitle("EliteEquipment")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EliteEquipment
{
	[BepInPlugin("milkyteam.eliteequipment", "EliteEquipment", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "milkyteam.eliteequipment";

		public const string PluginName = "EliteEquipment";

		public const string PluginVersion = "0.1.0";

		public static ManualLogSource Log { get; private set; }

		public static SyncedConfiguration Synced { get; private set; }

		public static ConfigEntry<bool> LockConfiguration { get; private set; }

		private void Awake()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Synced = new SyncedConfiguration((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger, "EliteEquipment", "0.1.0");
			LockConfiguration = Synced.BindLocking("General", "Lock Configuration", defaultValue: true, "[Server Only] Clients cannot change synced settings while connected to a server that has this on.");
			BootsModule.Initialize(Synced);
			Harmony harmony = new Harmony("milkyteam.eliteequipment");
			int num = PatchEverything(harmony);
			Synced.Finish(harmony);
			Log.LogInfo((object)("Loading [EliteEquipment 0.1.0]" + ((num > 0) ? $" with {num} failed patches, see above" : "")));
			Guard.Install(harmony, ((BaseUnityPlugin)this).Logger, Assembly.GetExecutingAssembly());
		}

		private static int PatchEverything(Harmony harmony)
		{
			int num = 0;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly());
			foreach (Type type in typesFromAssembly)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0)
				{
					try
					{
						harmony.CreateClassProcessor(type).Patch();
					}
					catch (Exception ex)
					{
						num++;
						Log.LogError((object)("Patch " + type.FullName + " failed to apply: " + ex.Message));
					}
				}
			}
			return num;
		}
	}
}
namespace EliteEquipment.Fitted
{
	internal sealed class BodyEnvelope
	{
		public const float Low = 0.3f;

		public const float High = 1.2f;

		private const float Step = 0.02f;

		private const int Sectors = 36;

		private readonly float[,] radius;

		public Vector2 Axis { get; }

		public BodyEnvelope(BodySurface body)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Axis = HipAxis(body);
			radius = new float[Mathf.CeilToInt(45.000004f) + 1, 36];
			for (int i = 0; i < body.Rest.Length; i++)
			{
				Vector3 val = body.Rest[i];
				if (!body.Upper[i] && !(val.y < 0.3f) && !(val.y > 1.2f))
				{
					int num = Band(val.y);
					int num2 = Sector(Angle(val));
					radius[num, num2] = Mathf.Max(radius[num, num2], Distance(val));
				}
			}
			for (int j = 0; j < radius.GetLength(0); j++)
			{
				FillBand(j);
			}
		}

		public float At(Vector3 rest)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return radius[Band(Mathf.Clamp(rest.y, 0.3f, 1.2f)), Sector(Angle(rest))];
		}

		public float Distance(Vector3 rest)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(rest.x - Axis.x, rest.z - Axis.y);
			return ((Vector2)(ref val)).magnitude;
		}

		public Vector3 Outward(Vector3 rest)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = new Vector3(rest.x - Axis.x, 0f, rest.z - Axis.y);
			return ((Vector3)(ref val)).normalized;
		}

		private float Angle(Vector3 rest)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Atan2(rest.z - Axis.y, rest.x - Axis.x);
		}

		private static int Band(float height)
		{
			return Mathf.RoundToInt((height - 0.3f) / 0.02f);
		}

		private static int Sector(float angle)
		{
			return ((int)Mathf.Floor((angle + (float)Math.PI) / ((float)Math.PI * 2f) * 36f) % 36 + 36) % 36;
		}

		private static Vector2 HipAxis(BodySurface body)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = Vector2.zero;
			int num = 0;
			for (int i = 0; i < body.Rest.Length; i++)
			{
				Vector3 val2 = body.Rest[i];
				if (!body.Upper[i] && val2.y >= 0.84f && val2.y <= 1.12f)
				{
					val += new Vector2(val2.x, val2.z);
					num++;
				}
			}
			if (num <= 0)
			{
				return Vector2.zero;
			}
			return val / (float)num;
		}

		private void FillBand(int band)
		{
			float[] array = new float[36];
			for (int i = 0; i < 36; i++)
			{
				array[i] = radius[band, i];
				int num = 1;
				while (array[i] <= 0f && num <= 18)
				{
					array[i] = Mathf.Max(radius[band, (i + num) % 36], radius[band, (i - num + 36) % 36]);
					num++;
				}
			}
			for (int j = 0; j < 36; j++)
			{
				radius[band, j] = array[j];
			}
		}
	}
	internal sealed class BodySurface
	{
		public const float Scale = 95f;

		private static readonly string[] UpperBones = new string[11]
		{
			"Arm", "Hand", "Shoulder", "Neck", "Head", "Jaw", "Thumb", "Index", "Middle", "Ring",
			"Pinky"
		};

		public Mesh Mesh { get; }

		public Vector3[] Vertices { get; }

		public BoneWeight[] Weights { get; }

		public Vector2[] Uvs { get; }

		public int[] Triangles { get; }

		public Vector3[] Rest { get; }

		public Vector3[] Outward { get; }

		public bool[] Upper { get; }

		private BodySurface(Mesh mesh, string[] bones)
		{
			Mesh = mesh;
			Vertices = mesh.vertices;
			Weights = mesh.boneWeights;
			Uvs = mesh.uv;
			Triangles = mesh.GetTriangles(0);
			Rest = Array.ConvertAll(Vertices, ToRest);
			Outward = Welded(mesh.normals);
			Upper = UpperOf(Weights, bones);
		}

		public static BodySurface Of(Mesh mesh, string[] bones)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mesh == (Object)null || !mesh.isReadable || mesh.vertexCount == 0 || mesh.boneWeights.Length != mesh.vertexCount)
			{
				return null;
			}
			Bounds bounds = mesh.bounds;
			float num = ((Bounds)(ref bounds)).size.z * 95f;
			if (!(num > 1.4f) || !(num < 2.4f))
			{
				return null;
			}
			return new BodySurface(mesh, bones);
		}

		public static Vector3 ToRest(Vector3 p)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(95f * p.x, 95f * p.z, -95f * p.y);
		}

		public static Vector3 FromRest(Vector3 r)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.x / 95f, (0f - r.z) / 95f, r.y / 95f);
		}

		public Vector3 Out(int vertex, float metres)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return Vertices[vertex] + Outward[vertex] * (metres / 95f);
		}

		public Vector3Int Place(int vertex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3Int.RoundToInt(Rest[vertex] * 2000f);
		}

		private Vector3[] Welded(Vector3[] normals)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Vector3Int, Vector3> dictionary = new Dictionary<Vector3Int, Vector3>();
			for (int i = 0; i < normals.Length; i++)
			{
				dictionary[Place(i)] = (dictionary.TryGetValue(Place(i), out var value) ? value : Vector3.zero) + normals[i];
			}
			Vector3[] array = (Vector3[])(object)new Vector3[normals.Length];
			for (int j = 0; j < normals.Length; j++)
			{
				int num = j;
				Vector3 val = dictionary[Place(j)];
				array[num] = ((Vector3)(ref val)).normalized;
			}
			return array;
		}

		public static bool[] UpperOf(BoneWeight[] weights, string[] bones)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			bool[] upperBone = Array.ConvertAll(bones, (string name) => Array.Exists(UpperBones, (string part) => name != null && name.Contains(part)));
			bool[] array = new bool[weights.Length];
			for (int num = 0; num < array.Length; num++)
			{
				BoneWeight val = weights[num];
				array[num] = On(upperBone, ((BoneWeight)(ref val)).boneIndex0, ((BoneWeight)(ref val)).weight0) + On(upperBone, ((BoneWeight)(ref val)).boneIndex1, ((BoneWeight)(ref val)).weight1) + On(upperBone, ((BoneWeight)(ref val)).boneIndex2, ((BoneWeight)(ref val)).weight2) + On(upperBone, ((BoneWeight)(ref val)).boneIndex3, ((BoneWeight)(ref val)).weight3) >= 0.02f;
			}
			return array;
		}

		private static float On(bool[] upperBone, int bone, float weight)
		{
			if (bone < 0 || bone >= upperBone.Length || !upperBone[bone])
			{
				return 0f;
			}
			return weight;
		}
	}
	internal static class BoneBlend
	{
		public static BoneWeight Mix(BoneWeight a, BoneWeight b, float t)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			Add(dictionary, a, 1f - t);
			Add(dictionary, b, t);
			List<KeyValuePair<int, float>> list = new List<KeyValuePair<int, float>>(dictionary);
			list.Sort((KeyValuePair<int, float> x, KeyValuePair<int, float> y) => y.Value.CompareTo(x.Value));
			float num = 0f;
			for (int num2 = 0; num2 < list.Count && num2 < 4; num2++)
			{
				num += list[num2].Value;
			}
			BoneWeight w = default(BoneWeight);
			for (int num3 = 0; num3 < list.Count && num3 < 4; num3++)
			{
				Set(ref w, num3, list[num3].Key, (num > 0f) ? (list[num3].Value / num) : 0f);
			}
			return w;
		}

		private static void Add(Dictionary<int, float> sums, BoneWeight w, float share)
		{
			Put(sums, ((BoneWeight)(ref w)).boneIndex0, ((BoneWeight)(ref w)).weight0 * share);
			Put(sums, ((BoneWeight)(ref w)).boneIndex1, ((BoneWeight)(ref w)).weight1 * share);
			Put(sums, ((BoneWeight)(ref w)).boneIndex2, ((BoneWeight)(ref w)).weight2 * share);
			Put(sums, ((BoneWeight)(ref w)).boneIndex3, ((BoneWeight)(ref w)).weight3 * share);
		}

		private static void Put(Dictionary<int, float> sums, int bone, float weight)
		{
			if (weight > 0f)
			{
				sums[bone] = (sums.TryGetValue(bone, out var value) ? value : 0f) + weight;
			}
		}

		private static void Set(ref BoneWeight w, int slot, int bone, float weight)
		{
			switch (slot)
			{
			case 0:
				((BoneWeight)(ref w)).boneIndex0 = bone;
				((BoneWeight)(ref w)).weight0 = weight;
				break;
			case 1:
				((BoneWeight)(ref w)).boneIndex1 = bone;
				((BoneWeight)(ref w)).weight1 = weight;
				break;
			case 2:
				((BoneWeight)(ref w)).boneIndex2 = bone;
				((BoneWeight)(ref w)).weight2 = weight;
				break;
			default:
				((BoneWeight)(ref w)).boneIndex3 = bone;
				((BoneWeight)(ref w)).weight3 = weight;
				break;
			}
		}
	}
	internal static class BootTop
	{
		private static readonly Dictionary<(Mesh, BootSet), float> known = new Dictionary<(Mesh, BootSet), float>();

		public static float Of(BodySurface body, BootSet boots)
		{
			if (boots == null)
			{
				return 0f;
			}
			if (!known.TryGetValue((body.Mesh, boots), out var value))
			{
				value = (known[(body.Mesh, boots)] = Mathf.Max(MeshTop(boots), PaintTop(body, boots)));
			}
			return value;
		}

		private static float MeshTop(BootSet boots)
		{
			Transform val = (((Object)(object)boots.Item != (Object)null) ? boots.Item.transform.Find("attach_skin") : null);
			float num = 0f;
			if ((Object)(object)val == (Object)null)
			{
				return num;
			}
			SkinnedMeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				num = Mathf.Max(num, Highest(val2.sharedMesh));
			}
			return num;
		}

		private static float Highest(Mesh mesh)
		{
			if ((Object)(object)mesh == (Object)null || !mesh.isReadable)
			{
				return 0f;
			}
			Vector3[] vertices = mesh.vertices;
			float num = 0f;
			int[] triangles = mesh.triangles;
			foreach (int num2 in triangles)
			{
				num = Mathf.Max(num, vertices[num2].z * 95f);
			}
			return num;
		}

		private static float PaintTop(BodySurface body, BootSet boots)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Paint paint = PaintCut.Boots(boots);
			float num = 0f;
			int num2 = 0;
			while (paint != null && num2 < body.Uvs.Length)
			{
				if (!body.Upper[num2] && Painted(paint, body.Uvs[num2]))
				{
					num = Mathf.Max(num, body.Rest[num2].y);
				}
				num2++;
			}
			return num;
		}

		private static bool Painted(Paint paint, Vector2 uv)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			int x = Mathf.Clamp((int)(uv.x * (float)paint.Width), 0, paint.Width - 1);
			int y = Mathf.Clamp((int)((1f - uv.y) * (float)paint.Height), 0, paint.Height - 1);
			return paint.Pixels[paint.Index(x, y)].a > 8;
		}
	}
	internal static class ChestCloth
	{
		private const float Top = 1.2f;

		private const float BeltRow = 0.05f;

		private const float Fixed = 0.03f;

		private const float Room = 0.015f;

		private const float Near = 0.05f;

		public static void Hang(ChestVertices v, float bottom)
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			List<int> list = Front(v);
			List<int> list2 = list.FindAll((int i) => v.Rest[i].y > 1.01f);
			if (list.Count == 0 || list2.Count == 0)
			{
				return;
			}
			float num = float.MaxValue;
			foreach (int item in list)
			{
				num = Mathf.Min(num, v.Rest[item].y);
			}
			float num2 = ((num < bottom) ? ((1.06f - bottom) / (1.06f - num)) : 1f);
			Vector3 val = default(Vector3);
			foreach (int item2 in list)
			{
				int num3 = Nearest(v, list2, v.Rest[item2].x);
				((Vector3)(ref val))..ctor(v.Rest[item2].x, 1.06f - (1.06f - v.Rest[item2].y) * num2, v.Rest[num3].z);
				v.Rest[item2] = new Vector3(val.x, val.y, Mathf.Max(val.z, Clear(v, val)));
				v.Weights[item2] = v.Weights[num3];
			}
		}

		private static float Clear(ChestVertices v, Vector3 at)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			float num = v.Envelope.Axis.y + v.Envelope.At(at) + v.Thickness + 0.015f;
			for (int i = 0; i < v.Rest.Length; i++)
			{
				Vector3 val = v.Rest[i];
				if (v.Kind[i] == ChestPart.Plate && !(Mathf.Abs(val.x - at.x) > 0.05f) && !(Mathf.Abs(val.y - at.y) > 0.05f))
				{
					num = Mathf.Max(num, val.z + 0.015f);
				}
			}
			return num;
		}

		public static Mesh Split(Mesh chest, ChestVertices v, ChestShape shape)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			int[] triangles = chest.GetTriangles(0);
			List<int> list = new List<int>(triangles.Length);
			List<int> list2 = new List<int>();
			for (int i = 0; i < triangles.Length; i += 3)
			{
				int num = triangles[i];
				int num2 = triangles[i + 1];
				int num3 = triangles[i + 2];
				if (!IsCloth(v, shape, num) || !IsCloth(v, shape, num2) || !IsCloth(v, shape, num3))
				{
					list.AddRange(new int[3] { num, num2, num3 });
				}
				else if (v.Rest[num].z + v.Rest[num2].z + v.Rest[num3].z > 3f * v.Envelope.Axis.y)
				{
					list2.AddRange(new int[3] { num, num2, num3 });
				}
			}
			if (list2.Count == 0)
			{
				return null;
			}
			Mesh result = Compact(chest, v, list2);
			chest.SetTriangles(list, 0);
			return result;
		}

		private static bool IsCloth(ChestVertices v, ChestShape shape, int i)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (v.Rest[i].y < 1.2f && v.Kind[i] != ChestPart.Arm)
			{
				return shape.IsCloth(v.Uv[i]);
			}
			return false;
		}

		private static Mesh Compact(Mesh chest, ChestVertices v, List<int> triangles)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_0099: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			List<int> list = new List<int>();
			List<int> list2 = new List<int>(triangles.Count);
			foreach (int triangle in triangles)
			{
				if (!dictionary.TryGetValue(triangle, out var value))
				{
					value = (dictionary[triangle] = list.Count);
					list.Add(triangle);
				}
				list2.Add(value);
			}
			Mesh val = new Mesh
			{
				name = ((Object)chest).name.Replace("_ee_fitted", "_ee_cloth")
			};
			Fill(val, chest, v, list);
			val.SetTriangles(list2, 0);
			val.bindposes = chest.bindposes;
			val.bounds = chest.bounds;
			return val;
		}

		private static void Fill(Mesh mesh, Mesh chest, ChestVertices v, List<int> used)
		{
			Vector3[] vertices = chest.vertices;
			Vector3[] normals = chest.normals;
			Vector4[] tangents = chest.tangents;
			Vector2[] uv = chest.uv;
			BoneWeight[] weights = chest.boneWeights;
			mesh.SetVertices(used.ConvertAll((int i) => vertices[i]));
			mesh.SetNormals(used.ConvertAll((int i) => normals[i]));
			if (tangents.Length == vertices.Length)
			{
				mesh.SetTangents(used.ConvertAll((int i) => tangents[i]));
			}
			mesh.SetUVs(0, used.ConvertAll((int i) => uv[i]));
			mesh.SetUVs(1, used.ConvertAll((Converter<int, Vector2>)((int i) => new Vector2((v.Rest[i].y >= 1.03f) ? 0.25f : 0.75f, 0.5f))));
			mesh.boneWeights = used.ConvertAll((int i) => weights[i]).ToArray();
		}

		private static List<int> Front(ChestVertices v)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			List<int> list = new List<int>();
			for (int i = 0; i < v.Rest.Length; i++)
			{
				if (v.Kind[i] == ChestPart.Cloth && v.Rest[i].z > v.Envelope.Axis.y)
				{
					list.Add(i);
				}
			}
			return list;
		}

		private static int Nearest(ChestVertices v, List<int> among, float x)
		{
			int num = among[0];
			foreach (int item in among)
			{
				if (Mathf.Abs(v.Rest[item].x - x) < Mathf.Abs(v.Rest[num].x - x))
				{
					num = item;
				}
			}
			return num;
		}
	}
	internal static class ChestClothSim
	{
		private const string Template = "CapeLinen";

		private const float ThighRadius = 0.09f;

		private const float ThighReach = 0.04f;

		private const float Wind = 0.05f;

		private static readonly string[][] Legs = new string[2][]
		{
			new string[2] { "LeftUpLeg", "LeftLeg" },
			new string[2] { "RightUpLeg", "RightLeg" }
		};

		private static Texture2D paint;

		public static GameObject Attach(VisEquipment vis, SkinnedMeshRenderer chest, Mesh cloth)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EE_ChestCloth")
			{
				layer = ((Component)chest).gameObject.layer
			};
			Transform transform = ((Component)vis.m_bodyModel).transform;
			val.transform.SetParent(transform.parent, false);
			val.transform.localPosition = transform.localPosition;
			val.transform.localRotation = transform.localRotation;
			val.transform.localScale = transform.localScale;
			SkinnedMeshRenderer val2 = val.AddComponent<SkinnedMeshRenderer>();
			val2.sharedMesh = cloth;
			val2.bones = chest.bones;
			val2.rootBone = chest.rootBone;
			((Renderer)val2).localBounds = ((Renderer)chest).localBounds;
			((Renderer)val2).sharedMaterial = ((Renderer)chest).sharedMaterial;
			((Renderer)val2).shadowCastingMode = ((Renderer)chest).shadowCastingMode;
			Simulate(vis, val, val2);
			return val;
		}

		private static void Simulate(VisEquipment vis, GameObject holder, SkinnedMeshRenderer renderer)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("EE_ChestCloth_Cloth");
				val.SetActive(false);
				val.transform.SetParent(holder.transform, false);
				MagicaCloth obj = val.AddComponent<MagicaCloth>();
				Configure(obj, renderer, Thighs(renderer, holder.AddComponent<ClothColliders>()));
				val.SetActive(true);
				obj.Initialize();
				obj.DisableAutoBuild();
				if (!obj.BuildAndRun())
				{
					Plugin.Log.LogWarning((object)"EliteEquipment: the chest's cloth simulation did not build; it hangs without moving");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("EliteEquipment: the chest's cloth will hang without moving: " + ex.Message));
			}
		}

		private static void Configure(MagicaCloth cloth, SkinnedMeshRenderer renderer, List<ColliderComponent> colliders)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			MagicaCloth val = Cape();
			if ((Object)(object)val != (Object)null)
			{
				cloth.SerializeData.Import(val, true);
			}
			ClothSerializeData serializeData = cloth.SerializeData;
			serializeData.clothType = (ClothType)0;
			serializeData.sourceRenderers = new List<Renderer> { (Renderer)(object)renderer };
			serializeData.rootBones = new List<Transform>();
			serializeData.paintMode = (PaintMode)1;
			serializeData.paintMaps = new List<Texture2D> { Paint() };
			serializeData.paintMapUvChannel = 1;
			serializeData.wind.influence = 0.05f;
			serializeData.colliderCollisionConstraint.colliderList = new List<ColliderComponent>(colliders ?? new List<ColliderComponent>());
		}

		private static List<ColliderComponent> Thighs(SkinnedMeshRenderer renderer, ClothColliders made)
		{
			List<ColliderComponent> list = new List<ColliderComponent>();
			string[][] legs = Legs;
			foreach (string[] array in legs)
			{
				int num = Bone(renderer, array[0]);
				int num2 = Bone(renderer, array[1]);
				if (num >= 0 && num2 >= 0)
				{
					list.Add(Thigh(renderer, made, num, num2));
				}
			}
			return list;
		}

		private static ColliderComponent Thigh(SkinnedMeshRenderer renderer, ClothColliders made, int hip, int knee)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004d: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4[] bindposes = renderer.sharedMesh.bindposes;
			Matrix4x4 inverse = ((Matrix4x4)(ref bindposes[hip])).inverse;
			Vector3 val = ((Matrix4x4)(ref inverse)).MultiplyPoint3x4(Vector3.zero);
			inverse = ((Matrix4x4)(ref bindposes[knee])).inverse;
			Vector3 val2 = ((Matrix4x4)(ref inverse)).MultiplyPoint3x4(Vector3.zero);
			GameObject val3 = new GameObject("EE_ChestClothThigh");
			val3.transform.SetParent(renderer.bones[hip], false);
			val3.transform.localPosition = ((Matrix4x4)(ref bindposes[hip])).MultiplyPoint3x4((val + val2) / 2f);
			Transform transform = val3.transform;
			Vector3 up = Vector3.up;
			Vector3 val4 = ((Matrix4x4)(ref bindposes[hip])).MultiplyVector(val2 - val);
			transform.localRotation = Quaternion.FromToRotation(up, ((Vector3)(ref val4)).normalized);
			val3.transform.localScale = Vector3.one;
			MagicaCapsuleCollider obj = val3.AddComponent<MagicaCapsuleCollider>();
			obj.direction = (Direction)1;
			float x = val3.transform.lossyScale.x;
			val4 = BodySurface.ToRest(val2 - val);
			float num = ((Vector3)(ref val4)).magnitude + 0.08f;
			obj.SetSize(0.09f / x, 0.09f / x, num / x);
			((ColliderComponent)obj).UpdateParameters();
			made.Made.Add(val3);
			return (ColliderComponent)(object)obj;
		}

		private static int Bone(SkinnedMeshRenderer renderer, string name)
		{
			int num = Array.FindIndex(renderer.bones, (Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == name);
			if (num >= renderer.sharedMesh.bindposes.Length)
			{
				return -1;
			}
			return num;
		}

		private static MagicaCloth Cape()
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("CapeLinen") : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponentInChildren<MagicaCloth>(true);
		}

		private static Texture2D Paint()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)paint != (Object)null)
			{
				return paint;
			}
			paint = new Texture2D(2, 1, (TextureFormat)4, false)
			{
				name = "EE_ChestClothPaint",
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			paint.SetPixels32((Color32[])(object)new Color32[2]
			{
				new Color32(byte.MaxValue, (byte)0, (byte)0, byte.MaxValue),
				new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue)
			});
			paint.Apply(false, false);
			return paint;
		}

		public static void Detach(GameObject holder)
		{
			if ((Object)(object)holder != (Object)null)
			{
				Object.Destroy((Object)(object)holder);
			}
		}
	}
	public static class ChestFit
	{
		[HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")]
		private static class ChestPatch
		{
			[HarmonyPostfix]
			private static void Postfix(VisEquipment __instance, bool __result)
			{
				if (__result)
				{
					FittedLook.ChestChanged(__instance);
				}
			}
		}

		private sealed class Swap
		{
			public SkinnedMeshRenderer Renderer { get; }

			public Mesh Own { get; }

			public Mesh DrawnIn { get; }

			public GameObject Cloth { get; set; }

			public Swap(SkinnedMeshRenderer renderer, Mesh own, Mesh drawnIn)
			{
				Renderer = renderer;
				Own = own;
				DrawnIn = drawnIn;
			}
		}

		private static readonly Dictionary<(Mesh, Mesh, int), ChestParts> made = new Dictionary<(Mesh, Mesh, int), ChestParts>();

		private static readonly Dictionary<Mesh, BodyEnvelope> envelopes = new Dictionary<Mesh, BodyEnvelope>();

		private static readonly ConditionalWeakTable<VisEquipment, List<Swap>> worn = new ConditionalWeakTable<VisEquipment, List<Swap>>();

		internal static void Fit(VisEquipment vis, BodySurface body, float thickness)
		{
			Unfit(vis);
			ChestShape chestShape = ChestShape.Of(vis.m_currentChestItemHash);
			if (body == null || chestShape == null || vis.m_chestItemInstances == null)
			{
				return;
			}
			List<Swap> list = new List<Swap>();
			foreach (GameObject chestItemInstance in vis.m_chestItemInstances)
			{
				if ((Object)(object)chestItemInstance == (Object)null)
				{
					continue;
				}
				SkinnedMeshRenderer[] componentsInChildren = chestItemInstance.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer renderer in componentsInChildren)
				{
					ChestParts chestParts = Get(renderer, body, thickness, chestShape);
					if (chestParts != null)
					{
						list.Add(Wear(vis, renderer, chestParts));
					}
				}
			}
			worn.Add(vis, list);
		}

		internal static void Unfit(VisEquipment vis)
		{
			if (!worn.TryGetValue(vis, out var value))
			{
				return;
			}
			worn.Remove(vis);
			foreach (Swap item in value)
			{
				if ((Object)(object)item.Renderer != (Object)null && (Object)(object)item.Renderer.sharedMesh == (Object)(object)item.DrawnIn)
				{
					item.Renderer.sharedMesh = item.Own;
				}
				ChestClothSim.Detach(item.Cloth);
			}
		}

		private static Swap Wear(VisEquipment vis, SkinnedMeshRenderer renderer, ChestParts parts)
		{
			Swap swap = new Swap(renderer, renderer.sharedMesh, parts.Chest);
			renderer.sharedMesh = parts.Chest;
			if ((Object)(object)parts.Cloth != (Object)null)
			{
				swap.Cloth = ChestClothSim.Attach(vis, renderer, parts.Cloth);
			}
			return swap;
		}

		private static ChestParts Get(SkinnedMeshRenderer renderer, BodySurface body, float thickness, ChestShape shape)
		{
			Mesh sharedMesh = renderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null || sharedMesh.subMeshCount != 1 || renderer.bones == null)
			{
				return null;
			}
			(Mesh, Mesh, int) key = (sharedMesh, body.Mesh, Mathf.RoundToInt(thickness * 1000f));
			if (!made.TryGetValue(key, out var value))
			{
				value = (made[key] = Guarded(sharedMesh, Array.ConvertAll(renderer.bones, (Transform bone) => (!((Object)(object)bone != (Object)null)) ? null : ((Object)bone).name), body, thickness, shape));
			}
			return value;
		}

		private static ChestParts Guarded(Mesh own, string[] bones, BodySurface body, float thickness, ChestShape shape)
		{
			try
			{
				if (!envelopes.TryGetValue(body.Mesh, out var value))
				{
					value = (envelopes[body.Mesh] = new BodyEnvelope(body));
				}
				return ChestPull.Make(own, bones, body, value, thickness, shape);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("EliteEquipment: the chest " + ((Object)own).name + " could not be drawn in over fitted leggings: " + ex.Message));
				return null;
			}
		}
	}
	internal static class ChestPull
	{
		private const float Settled = 0.03f;

		private const float Tenth = 0.1f;

		private const float FollowDepth = 0.35f;

		private const float FollowMost = 0.75f;

		private const float FollowBehind = 0.2f;

		public static ChestParts Make(Mesh source, string[] bones, BodySurface body, BodyEnvelope envelope, float thickness, ChestShape shape)
		{
			Mesh[] array = MeshCut.Cut(source, new bool[source.GetIndexCount(0) / 3], null);
			Object.Destroy((Object)(object)array[1]);
			Mesh val = array[0];
			((Object)val).name = ((Object)source).name + "_ee_fitted";
			ChestVertices chestVertices = new ChestVertices(Array.ConvertAll(val.vertices, BodySurface.ToRest), val.uv, val.boneWeights, BodySurface.UpperOf(val.boneWeights, bones), envelope);
			chestVertices.Measure(thickness, shape);
			float num = LeanPlates(chestVertices);
			Reweight(chestVertices);
			Follow(chestVertices, body);
			ChestCloth.Hang(chestVertices, shape.ClothBottom);
			val.vertices = Array.ConvertAll(chestVertices.Rest, BodySurface.FromRest);
			val.boneWeights = chestVertices.Weights;
			Mesh val2 = ChestCloth.Split(val, chestVertices, shape);
			val.UploadMeshData(true);
			Plugin.Log.LogInfo((object)string.Format("EliteEquipment: {0} drawn in over fitted leggings: plates lean in by up to {1:0.0} cm; front cloth {2}", ((Object)source).name, num * 100f, ((Object)(object)val2 != (Object)null) ? ("on its own, ending at " + shape.ClothBottom.ToString("0.00") + " m") : "not found"));
			return new ChestParts(val, val2);
		}

		private static float LeanPlates(ChestVertices v)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			float[] array = Smooth(Rates(v), 3, 3);
			float num = 0f;
			for (int i = 0; i < v.Rest.Length; i++)
			{
				if (v.Kind[i] == ChestPart.Plate)
				{
					float num2 = array[v.Sector(i)] * v.Depth(i);
					num = Mathf.Max(num, num2);
					ref Vector3 reference = ref v.Rest[i];
					reference -= v.Envelope.Outward(v.Rest[i]) * num2;
				}
			}
			return num;
		}

		private static float[] Rates(ChestVertices v)
		{
			List<float>[] array = new List<float>[36];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new List<float>();
			}
			for (int j = 0; j < v.Rest.Length; j++)
			{
				if (v.Kind[j] == ChestPart.Plate && v.Depth(j) > 0.03f)
				{
					array[v.Sector(j)].Add(Mathf.Max(0f, v.Excess[j]) / v.Depth(j));
				}
			}
			float[] array2 = new float[array.Length];
			float num = 0f;
			int num2 = 0;
			for (int k = 0; k < array.Length; k++)
			{
				array[k].Sort();
				array2[k] = ((array[k].Count > 0) ? array[k][(int)((float)array[k].Count * 0.1f)] : (-1f));
				num += ((array2[k] >= 0f) ? array2[k] : 0f);
				num2 += ((array2[k] >= 0f) ? 1 : 0);
			}
			for (int l = 0; l < array2.Length; l++)
			{
				array2[l] = ((array2[l] >= 0f) ? array2[l] : ((num2 > 0) ? (num / (float)num2) : 0f));
			}
			return array2;
		}

		private static float[] Smooth(float[] rate, int width, int passes)
		{
			for (int i = 0; i < passes; i++)
			{
				float[] array = new float[rate.Length];
				for (int j = 0; j < rate.Length; j++)
				{
					for (int k = -width; k <= width; k++)
					{
						array[j] += rate[(j + k + rate.Length) % rate.Length];
					}
					array[j] /= 2 * width + 1;
				}
				rate = array;
			}
			return rate;
		}

		private static void Follow(ChestVertices v, BodySurface body)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < v.Rest.Length; i++)
			{
				if (v.Kind[i] == ChestPart.Plate)
				{
					float num = Mathf.Max(0f, 0f - v.Envelope.Outward(v.Rest[i]).z);
					float num2 = Mathf.Clamp01(v.Depth(i) / 0.35f) * Mathf.Lerp(0.75f, 0.2f, num);
					int num3 = NearestLeg(body, v.Rest[i]);
					if (num3 >= 0 && num2 > 0f)
					{
						v.Weights[i] = BoneBlend.Mix(v.Weights[i], body.Weights[num3], num2);
					}
				}
			}
		}

		private static int NearestLeg(BodySurface body, Vector3 rest)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			int result = -1;
			float num = float.MaxValue;
			for (int i = 0; i < body.Rest.Length; i++)
			{
				if (!body.Upper[i] && !(body.Rest[i].y > 1.12f) && !(body.Rest[i].y < 0.3f))
				{
					Vector3 val = body.Rest[i] - rest;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = i;
					}
				}
			}
			return result;
		}

		private static void Reweight(ChestVertices v)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			List<int> list = new List<int>();
			for (int i = 0; i < v.Rest.Length; i++)
			{
				if (v.Kind[i] == ChestPart.Plate && !v.Upper[i])
				{
					list.Add(i);
				}
			}
			for (int j = 0; j < v.Rest.Length; j++)
			{
				if (list.Count <= 0)
				{
					break;
				}
				if (v.Kind[j] != ChestPart.Plate || !v.Upper[j])
				{
					continue;
				}
				int num = list[0];
				foreach (int item in list)
				{
					Vector3 val = v.Rest[item] - v.Rest[j];
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					val = v.Rest[num] - v.Rest[j];
					if (sqrMagnitude < ((Vector3)(ref val)).sqrMagnitude)
					{
						num = item;
					}
				}
				v.Weights[j] = v.Weights[num];
			}
		}
	}
	internal sealed class ChestParts
	{
		public Mesh Chest { get; }

		public Mesh Cloth { get; }

		public ChestParts(Mesh chest, Mesh cloth)
		{
			Chest = chest;
			Cloth = cloth;
		}
	}
	internal sealed class ChestShape
	{
		private static readonly Dictionary<int, ChestShape> byChest;

		public int Hash { get; }

		public int Base { get; }

		public float ClothBottom { get; }

		public RectInt[] Cloth { get; }

		static ChestShape()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			byChest = new Dictionary<int, ChestShape>();
			Add(new ChestShape("ArmorDeepNorthHeavyChest", 256, 0.62f, new RectInt(222, 95, 34, 115), new RectInt(40, 205, 88, 51)));
		}

		private ChestShape(string chest, int atlas, float clothBottom, params RectInt[] cloth)
		{
			Hash = StringExtensionMethods.GetStableHashCode(chest);
			Base = atlas;
			ClothBottom = clothBottom;
			Cloth = cloth;
		}

		public static ChestShape Of(int chestHash)
		{
			if (!byChest.TryGetValue(chestHash, out var value))
			{
				return null;
			}
			return value;
		}

		public bool IsCloth(Vector2 uv)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(uv.x * (float)Base, (1f - uv.y) * (float)Base);
			RectInt[] cloth = Cloth;
			for (int i = 0; i < cloth.Length; i++)
			{
				RectInt val2 = cloth[i];
				if (val.x >= (float)((RectInt)(ref val2)).xMin && val.x <= (float)((RectInt)(ref val2)).xMax && val.y >= (float)((RectInt)(ref val2)).yMin && val.y <= (float)((RectInt)(ref val2)).yMax)
				{
					return true;
				}
			}
			return false;
		}

		private static void Add(ChestShape shape)
		{
			byChest[shape.Hash] = shape;
		}
	}
	internal enum ChestPart
	{
		Other,
		Arm,
		Plate,
		Cloth
	}
	internal sealed class ChestVertices
	{
		public const float From = 1.06f;

		public const int Sectors = 36;

		private const float FrontGap = 0.025f;

		private const float SideGap = 0.04f;

		private const float BackGap = 0.11f;

		private const float ArmReach = 0.36f;

		private const float ArmLow = 0.8f;

		public Vector3[] Rest { get; }

		public Vector2[] Uv { get; }

		public BoneWeight[] Weights { get; }

		public bool[] Upper { get; }

		public BodyEnvelope Envelope { get; }

		public ChestPart[] Kind { get; }

		public float[] Excess { get; }

		public float Thickness { get; private set; }

		public ChestVertices(Vector3[] rest, Vector2[] uv, BoneWeight[] weights, bool[] upper, BodyEnvelope envelope)
		{
			Rest = rest;
			Uv = uv;
			Weights = weights;
			Upper = upper;
			Envelope = envelope;
			Kind = new ChestPart[rest.Length];
			Excess = new float[rest.Length];
		}

		public void Measure(float thickness, ChestShape shape)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Thickness = thickness;
			for (int i = 0; i < Rest.Length; i++)
			{
				Vector3 val = Rest[i];
				if (!(val.y >= 1.06f))
				{
					bool flag = Upper[i] && Envelope.Distance(val) > 0.36f && val.y > 0.8f;
					Kind[i] = (flag ? ChestPart.Arm : (shape.IsCloth(Uv[i]) ? ChestPart.Cloth : ((val.y > 0.3f) ? ChestPart.Plate : ChestPart.Other)));
					Excess[i] = Envelope.Distance(val) - Envelope.At(val) - thickness - Gap(val);
				}
			}
		}

		public float Depth(int i)
		{
			return Mathf.Max(0f, 1.06f - Rest[i].y);
		}

		public int Sector(int i)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			return ((int)Mathf.Floor((Mathf.Atan2(Rest[i].z - Envelope.Axis.y, Rest[i].x - Envelope.Axis.x) + (float)Math.PI) / ((float)Math.PI * 2f) * 36f) % 36 + 36) % 36;
		}

		private float Gap(Vector3 r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			float z = Envelope.Outward(r).z;
			return 0.04f + 0.07f * Mathf.Max(0f, 0f - z) + -0.014999999f * Mathf.Max(0f, z);
		}
	}
	public sealed class ClothColliders : MonoBehaviour
	{
		public List<GameObject> Made { get; } = new List<GameObject>();

		private void OnDestroy()
		{
			foreach (GameObject item in Made)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)item);
				}
			}
		}
	}
	internal static class FittedAtlas
	{
		private readonly struct Source
		{
			public Color32[] Pixels { get; }

			private int Width { get; }

			private int Height { get; }

			private Source(Color32[] pixels, int width, int height)
			{
				Pixels = pixels;
				Width = width;
				Height = height;
			}

			public static Source Of(Texture texture, bool data)
			{
				int width;
				int height;
				Color32[] array = (data ? TexturePixels.ReadLinear(texture, out width, out height) : TexturePixels.Read(texture, out width, out height));
				return new Source((Color32[])(((object)array) ?? ((object)new Color32[1])), (array == null) ? 1 : width, (array == null) ? 1 : height);
			}

			public Color32 At(int x, int y, int layout)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				int num = Mathf.Clamp(x * Width / layout, 0, Width - 1);
				int num2 = Mathf.Clamp(y * Height / layout, 0, Height - 1);
				return Pixels[(Height - 1 - num2) * Width + num];
			}
		}

		public const int Size = 256;

		private static readonly Color32[] Blank = (Color32[])(object)new Color32[3]
		{
			new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue),
			new Color32((byte)128, (byte)128, byte.MaxValue, byte.MaxValue),
			new Color32((byte)0, (byte)0, (byte)0, (byte)0)
		};

		public static Texture2D Build(LegStyle style, Texture[] sources, int channel)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[65536];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Blank[channel];
			}
			Source[] array2 = new Source[sources.Length];
			foreach (AtlasCopy item in style.Recipe)
			{
				Texture val = sources[(int)item.Source];
				if (!((Object)(object)val == (Object)null))
				{
					if (array2[(int)item.Source].Pixels == null)
					{
						array2[(int)item.Source] = Source.Of(val, channel > 0);
					}
					Fill(array2[(int)item.Source], item, array);
				}
			}
			if (channel == 0)
			{
				Opaque(array);
			}
			return ToTexture(array, "EE_Fitted" + style.Key + "_" + channel, channel > 0);
		}

		private static void Opaque(Color32[] atlas)
		{
			for (int i = 0; i < atlas.Length; i++)
			{
				atlas[i].a = byte.MaxValue;
			}
		}

		public static Vector2 Field(LegStyle style, float radius, float angle, float height)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return Px(style.FieldOrigin.x + angle * radius * style.Density, style.FieldOrigin.y + (1.12f - height) * style.Density);
		}

		public static Vector2 Region(RectInt region, float along, float across, bool rotated)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			along = Mathf.Clamp(along, 0f, 1.1f) / 1.1f;
			if (!rotated)
			{
				return Px((float)((RectInt)(ref region)).x + 2f + along * ((float)((RectInt)(ref region)).width - 4f), (float)((RectInt)(ref region)).y + across * (float)((RectInt)(ref region)).height);
			}
			return Px((float)((RectInt)(ref region)).x + across * (float)((RectInt)(ref region)).width, (float)((RectInt)(ref region)).y + along * (float)((RectInt)(ref region)).height);
		}

		public static Vector2 Px(float x, float y)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(x / 256f, 1f - y / 256f);
		}

		private static void Fill(Source from, AtlasCopy step, Color32[] atlas)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			RectInt val = step.From;
			RectInt to = step.To;
			for (int i = 0; i < ((RectInt)(ref to)).height; i++)
			{
				for (int j = 0; j < ((RectInt)(ref to)).width; j++)
				{
					int num = Repeat(j, ((RectInt)(ref val)).width, step.Fill);
					int num2 = Repeat(i, ((RectInt)(ref val)).height, step.Fill);
					Put(atlas, ((RectInt)(ref to)).x + j, ((RectInt)(ref to)).y + i, from.At(((RectInt)(ref val)).x + num, ((RectInt)(ref val)).y + num2, step.Base));
				}
			}
		}

		private static int Repeat(int i, int size, AtlasFill fill)
		{
			if (fill == AtlasFill.Copy)
			{
				return Mathf.Min(i, size - 1);
			}
			int num = i % size;
			if (fill != AtlasFill.Mirror || i / size % 2 != 1)
			{
				return num;
			}
			return size - 1 - num;
		}

		private static void Put(Color32[] atlas, int x, int y, Color32 colour)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (x >= 0 && x < 256 && y >= 0 && y < 256)
			{
				atlas[(255 - y) * 256 + x] = colour;
			}
		}

		private static Texture2D ToTexture(Color32[] atlas, string name, bool data)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			Texture2D val = new Texture2D(256, 256, (TextureFormat)4, true, data)
			{
				name = name,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			val.SetPixels32(atlas);
			val.Apply(true, true);
			return val;
		}
	}
	internal static class FittedBands
	{
		public static void Add(LegStyle style, BodySurface body, bool[] covered, Unwrap unwrap, FittedMesh mesh, float bottom, bool booted)
		{
			foreach (BandSpec band in style.Bands)
			{
				if (band.Ankle && booted)
				{
					continue;
				}
				float offset = (band.Ankle ? bottom : 0f);
				for (int i = 0; i < covered.Length; i++)
				{
					if (covered[i])
					{
						Piece(body, unwrap, mesh, band, offset, style.Thickness + band.Lift, i);
					}
				}
			}
			int num = Front(body);
			if (num >= 0)
			{
				Disc(body, mesh, style.Buckle, style.Thickness, num);
			}
		}

		private static void Piece(BodySurface body, Unwrap unwrap, FittedMesh mesh, BandSpec band, float offset, float lift, int t)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			List<FittedCorner> list = new List<FittedCorner>(3);
			for (int i = 0; i < 3; i++)
			{
				list.Add(Corner(body, body.Triangles[3 * t + i], lift));
			}
			int num = Unwrap.Part((list[0].Rest + list[1].Rest + list[2].Rest) / 3f);
			if (band.Hips != (num == 0))
			{
				return;
			}
			float num2 = band.From + offset;
			float num3 = band.To + offset;
			list = FittedCorner.Clip(FittedCorner.Clip(list, band.Normal, num2), -band.Normal, 0f - num3);
			if (list.Count >= 3)
			{
				float[] array = unwrap.Angles(num, list.ConvertAll((FittedCorner c) => c.Rest).ToArray());
				int num4 = -1;
				for (int num5 = 0; num5 < list.Count; num5++)
				{
					float across = (num3 - Vector3.Dot(list[num5].Rest, band.Normal)) / (num3 - num2);
					Vector2 uv = FittedAtlas.Region(band.Region, array[num5] / ((float)Math.PI * 2f), across, band.Rotated);
					int num6 = mesh.Add(list[num5].Position, list[num5].Normal, uv, list[num5].Weight);
					num4 = ((num4 < 0) ? num6 : num4);
				}
				mesh.Fan(num4, list.Count);
			}
		}

		private static FittedCorner Corner(BodySurface body, int v, float lift)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			return new FittedCorner
			{
				Position = body.Out(v, lift),
				Normal = body.Outward[v],
				Rest = body.Rest[v],
				Weight = body.Weights[v]
			};
		}

		private static void Disc(BodySurface body, FittedMesh mesh, DiscSpec disc, float thickness, int vertex)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = body.Outward[vertex];
			Vector3 val2 = body.Out(vertex, thickness + 0.01f);
			Vector3 val3 = Vector3.Cross(val, Vector3.right);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			val3 = Vector3.Cross(normalized, val);
			Vector3 normalized2 = ((Vector3)(ref val3)).normalized;
			float num = disc.Radius / 95f;
			BoneWeight weight = body.Weights[vertex];
			Vector2 uv = FittedAtlas.Px(disc.Centre.x, disc.Centre.y);
			int num2 = mesh.Add(val2 + val * 4.2105265E-05f, val, uv, weight);
			for (int i = 0; i < 10; i++)
			{
				float num3 = (float)i * ((float)Math.PI * 2f) / 10f;
				float num4 = Mathf.Cos(num3);
				float num5 = Mathf.Sin(num3);
				Vector2 uv2 = FittedAtlas.Px(disc.Centre.x + num4 * disc.Texels, disc.Centre.y - num5 * disc.Texels);
				mesh.Add(val2 + (normalized2 * num4 + normalized * num5) * num, val, uv2, weight);
			}
			for (int j = 0; j < 10; j++)
			{
				mesh.Both(num2, num2 + 1 + j, num2 + 1 + (j + 1) % 10);
			}
		}

		private static int Front(BodySurface body)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			int result = -1;
			float num = float.MinValue;
			float num2 = 1.0675f;
			for (int i = 0; i < body.Rest.Length; i++)
			{
				Vector3 val = body.Rest[i];
				if (Mathf.Abs(val.x) <= 0.04f && Mathf.Abs(val.y - num2) <= 0.04f && val.z > num && !body.Upper[i])
				{
					num = val.z;
					result = i;
				}
			}
			return result;
		}
	}
	internal static class FittedBuild
	{
		private static readonly Dictionary<Mesh, BodySurface> surfaces = new Dictionary<Mesh, BodySurface>();

		private static readonly Dictionary<(LegStyle, Mesh, int, int), FittedParts> made = new Dictionary<(LegStyle, Mesh, int, int), FittedParts>();

		public static FittedParts For(LegStyle style, Mesh bodyMesh, string[] bones, BootSet boots)
		{
			BodySurface bodySurface = Surface(bodyMesh, bones);
			if (bodySurface == null)
			{
				return null;
			}
			float num = BootTop.Of(bodySurface, boots);
			float num2 = LegRegion.Bottom(bodySurface, style.UnderBoots ? 0f : num);
			(LegStyle, Mesh, int, int) key = (style, bodyMesh, Mathf.RoundToInt(num2 * 1000f), Mathf.RoundToInt(num * 1000f));
			if (!made.TryGetValue(key, out var value))
			{
				value = (made[key] = Guarded(style, bodySurface, num2, num));
			}
			return value;
		}

		internal static BodySurface Surface(Mesh bodyMesh, string[] bones)
		{
			if ((Object)(object)bodyMesh == (Object)null)
			{
				return null;
			}
			if (!surfaces.TryGetValue(bodyMesh, out var value))
			{
				value = (surfaces[bodyMesh] = BodySurface.Of(bodyMesh, bones));
				if (value == null)
				{
					Plugin.Log.LogWarning((object)("EliteEquipment: the body " + ((Object)bodyMesh).name + " cannot be read; it wears the game's leggings"));
				}
			}
			return value;
		}

		private static FittedParts Guarded(LegStyle style, BodySurface body, float bottom, float bootTop)
		{
			try
			{
				return Make(style, body, bottom, bootTop);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("EliteEquipment: the " + style.Key + " leggings could not be fitted to " + ((Object)body.Mesh).name + ": " + ex.Message));
				return null;
			}
		}

		private static FittedParts Make(LegStyle style, BodySurface body, float bottom, float bootTop)
		{
			bool[] covered = LegRegion.Covered(body, bottom);
			Unwrap unwrap = new Unwrap(body, LegRegion.Covered(body, 0.094f));
			FittedMesh fittedMesh = new FittedMesh();
			FittedShell.Build(style, body, covered, unwrap, fittedMesh, bootTop);
			FittedShell.Hems(style, body, covered, fittedMesh, bootTop);
			FittedBands.Add(style, body, covered, unwrap, fittedMesh, bottom, bootTop > 0.094f);
			return new FittedParts(fittedMesh.ToMesh("EE_Fitted" + style.Key + "_" + ((Object)body.Mesh).name, body.Mesh.bindposes), Trimmed(body, covered));
		}

		private static Mesh Trimmed(BodySurface body, bool[] covered)
		{
			Mesh val = Object.Instantiate<Mesh>(body.Mesh);
			((Object)val).name = ((Object)body.Mesh).name + "_ee_fitted";
			List<int> list = new List<int>(body.Triangles.Length);
			for (int i = 0; i < covered.Length; i++)
			{
				if (!covered[i])
				{
					list.AddRange(new int[3]
					{
						body.Triangles[3 * i],
						body.Triangles[3 * i + 1],
						body.Triangles[3 * i + 2]
					});
				}
			}
			val.SetTriangles(list, 0);
			return val;
		}
	}
	internal sealed class FittedParts
	{
		public Mesh Leggings { get; }

		public Mesh Body { get; }

		public FittedParts(Mesh leggings, Mesh body)
		{
			Leggings = leggings;
			Body = body;
		}
	}
	internal struct FittedCorner
	{
		public Vector3 Position;

		public Vector3 Normal;

		public Vector3 Rest;

		public BoneWeight Weight;

		public static FittedCorner Lerp(FittedCorner a, FittedCorner b, float t)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FittedCorner result = new FittedCorner
			{
				Position = Vector3.Lerp(a.Position, b.Position, t)
			};
			Vector3 val = Vector3.Lerp(a.Normal, b.Normal, t);
			result.Normal = ((Vector3)(ref val)).normalized;
			result.Rest = Vector3.Lerp(a.Rest, b.Rest, t);
			result.Weight = Mix(a.Weight, b.Weight, t);
			return result;
		}

		public static List<FittedCorner> Clip(List<FittedCorner> polygon, Vector3 normal, float distance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			List<FittedCorner> list = new List<FittedCorner>();
			for (int i = 0; i < polygon.Count; i++)
			{
				FittedCorner fittedCorner = polygon[i];
				FittedCorner b = polygon[(i + 1) % polygon.Count];
				float num = Vector3.Dot(fittedCorner.Rest, normal) - distance;
				float num2 = Vector3.Dot(b.Rest, normal) - distance;
				if (num >= 0f)
				{
					list.Add(fittedCorner);
				}
				if (num >= 0f != num2 >= 0f)
				{
					list.Add(Lerp(fittedCorner, b, num / (num - num2)));
				}
			}
			return list;
		}

		private static BoneWeight Mix(BoneWeight a, BoneWeight b, float t)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			Add(dictionary, a, 1f - t);
			Add(dictionary, b, t);
			KeyValuePair<int, float>[] array = dictionary.OrderByDescending((KeyValuePair<int, float> kv) => kv.Value).Take(4).ToArray();
			float num = array.Sum((KeyValuePair<int, float> kv) => kv.Value);
			BoneWeight result = default(BoneWeight);
			if (array.Length != 0)
			{
				((BoneWeight)(ref result)).boneIndex0 = array[0].Key;
				((BoneWeight)(ref result)).weight0 = array[0].Value / num;
			}
			if (array.Length > 1)
			{
				((BoneWeight)(ref result)).boneIndex1 = array[1].Key;
				((BoneWeight)(ref result)).weight1 = array[1].Value / num;
			}
			if (array.Length > 2)
			{
				((BoneWeight)(ref result)).boneIndex2 = array[2].Key;
				((BoneWeight)(ref result)).weight2 = array[2].Value / num;
			}
			if (array.Length > 3)
			{
				((BoneWeight)(ref result)).boneIndex3 = array[3].Key;
				((BoneWeight)(ref result)).weight3 = array[3].Value / num;
			}
			return result;
		}

		private static void Add(Dictionary<int, float> sums, BoneWeight w, float share)
		{
			One(sums, ((BoneWeight)(ref w)).boneIndex0, ((BoneWeight)(ref w)).weight0 * share);
			One(sums, ((BoneWeight)(ref w)).boneIndex1, ((BoneWeight)(ref w)).weight1 * share);
			One(sums, ((BoneWeight)(ref w)).boneIndex2, ((BoneWeight)(ref w)).weight2 * share);
			One(sums, ((BoneWeight)(ref w)).boneIndex3, ((BoneWeight)(ref w)).weight3 * share);
		}

		private static void One(Dictionary<int, float> sums, int bone, float weight)
		{
			if (weight > 0f)
			{
				sums[bone] = (sums.TryGetValue(bone, out var value) ? value : 0f) + weight;
			}
		}
	}
	public static class FittedLook
	{
		[HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")]
		private static class LegsPatch
		{
			[HarmonyPostfix]
			private static void Postfix(VisEquipment __instance, bool __result)
			{
				if (__result)
				{
					Refresh(__instance, BootsShow.Attached(__instance));
				}
			}
		}

		private sealed class Worn
		{
			public LegStyle Style { get; }

			public int Index { get; }

			public int Boots { get; }

			public Mesh Body { get; }

			public Mesh Trimmed { get; }

			public GameObject Leggings { get; }

			public List<Renderer> Hidden { get; } = new List<Renderer>();

			public Worn(LegStyle style, int index, int boots, Mesh body, Mesh trimmed, GameObject leggings)
			{
				Style = style;
				Index = index;
				Boots = boots;
				Body = body;
				Trimmed = trimmed;
				Leggings = leggings;
			}
		}

		private static readonly bool headless = (int)SystemInfo.graphicsDeviceType == 4;

		private static readonly ConditionalWeakTable<VisEquipment, Worn> worn = new ConditionalWeakTable<VisEquipment, Worn>();

		public static void Check(VisEquipment vis, int bootsHash)
		{
			if (worn.TryGetValue(vis, out var value) && (value.Boots != bootsHash || value.Index != vis.m_currentModelIndex))
			{
				Refresh(vis, bootsHash);
				vis.UpdateLodgroup();
			}
		}

		private static void Refresh(VisEquipment vis, int bootsHash)
		{
			Remove(vis);
			LegStyle legStyle = (Wanted(vis) ? LegStyles.ByLegsHash(vis.m_currentLegItemHash) : null);
			if (legStyle != null)
			{
				int currentModelIndex = vis.m_currentModelIndex;
				string[] bones = Array.ConvertAll(vis.m_bodyModel.bones, (Transform bone) => (!((Object)(object)bone != (Object)null)) ? null : ((Object)bone).name);
				FittedParts fittedParts = FittedBuild.For(legStyle, vis.m_models[currentModelIndex].m_mesh, bones, BootSets.ByHash(bootsHash));
				Material val = ((fittedParts != null) ? FittedMaterial.Get(legStyle) : null);
				if ((Object)(object)val != (Object)null)
				{
					Wear(vis, legStyle, fittedParts, val, bootsHash);
				}
			}
		}

		internal static void ChestChanged(VisEquipment vis)
		{
			if (worn.TryGetValue(vis, out var value))
			{
				ChestFit.Fit(vis, Surface(vis, value.Body), value.Style.Thickness);
			}
		}

		private static BodySurface Surface(VisEquipment vis, Mesh body)
		{
			return FittedBuild.Surface(body, Array.ConvertAll(vis.m_bodyModel.bones, (Transform bone) => (!((Object)(object)bone != (Object)null)) ? null : ((Object)bone).name));
		}

		private static bool Wanted(VisEquipment vis)
		{
			if (!headless && BootsSettings.On && vis.m_isPlayer && !vis.m_isArmorStand && (Object)(object)vis.m_bodyModel != (Object)null && vis.m_models != null && vis.m_currentModelIndex >= 0)
			{
				return vis.m_currentModelIndex < vis.m_models.Length;
			}
			return false;
		}

		private static void Wear(VisEquipment vis, LegStyle style, FittedParts parts, Material material, int bootsHash)
		{
			int currentModelIndex = vis.m_currentModelIndex;
			Worn worn = new Worn(style, currentModelIndex, bootsHash, vis.m_models[currentModelIndex].m_mesh, parts.Body, Draw(vis.m_bodyModel, parts.Leggings, material));
			Hide(vis.m_legItemInstances, worn.Hidden);
			ChestFit.Fit(vis, Surface(vis, worn.Body), style.Thickness);
			vis.m_models[currentModelIndex].m_mesh = parts.Body;
			vis.m_bodyModel.sharedMesh = parts.Body;
			FittedLook.worn.Add(vis, worn);
		}

		private static void Hide(List<GameObject> pieces, List<Renderer> hidden)
		{
			if (pieces == null)
			{
				return;
			}
			foreach (GameObject piece in pieces)
			{
				if ((Object)(object)piece == (Object)null)
				{
					continue;
				}
				SkinnedMeshRenderer[] componentsInChildren = piece.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val in componentsInChildren)
				{
					if (((Renderer)val).enabled)
					{
						((Renderer)val).enabled = false;
						hidden.Add((Renderer)(object)val);
					}
				}
			}
		}

		private static GameObject Draw(SkinnedMeshRenderer body, Mesh mesh, Material material)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			GameObject val = new GameObject("EE_FittedLegs")
			{
				layer = ((Component)body).gameObject.layer
			};
			val.transform.SetParent(((Component)body).transform.parent, false);
			val.transform.localPosition = ((Component)body).transform.localPosition;
			val.transform.localRotation = ((Component)body).transform.localRotation;
			val.transform.localScale = ((Component)body).transform.localScale;
			SkinnedMeshRenderer obj = val.AddComponent<SkinnedMeshRenderer>();
			obj.sharedMesh = mesh;
			obj.bones = body.bones;
			obj.rootBone = body.rootBone;
			((Renderer)obj).localBounds = ((Renderer)body).localBounds;
			((Renderer)obj).sharedMaterial = material;
			((Renderer)obj).shadowCastingMode = ((Renderer)body).shadowCastingMode;
			return val;
		}

		private static void Remove(VisEquipment vis)
		{
			if (!worn.TryGetValue(vis, out var value))
			{
				return;
			}
			worn.Remove(vis);
			ChestFit.Unfit(vis);
			if (vis.m_models != null && value.Index < vis.m_models.Length && (Object)(object)vis.m_models[value.Index].m_mesh == (Object)(object)value.Trimmed)
			{
				vis.m_models[value.Index].m_mesh = value.Body;
			}
			if ((Object)(object)vis.m_bodyModel != (Object)null && (Object)(object)vis.m_bodyModel.sharedMesh == (Object)(object)value.Trimmed)
			{
				vis.m_bodyModel.sharedMesh = value.Body;
			}
			foreach (Renderer item in value.Hidden)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.enabled = true;
				}
			}
			if ((Object)(object)value.Leggings != (Object)null)
			{
				Object.Destroy((Object)(object)value.Leggings);
			}
		}
	}
	internal static class FittedMaterial
	{
		private static readonly string[][] Properties = new string[2][]
		{
			new string[3] { "_MainTex", "_BumpMap", "_MetallicGlossMap" },
			new string[3] { "_ChestTex", "_ChestBumpMap", "_ChestMetal" }
		};

		private static readonly Dictionary<LegStyle, Material> made = new Dictionary<LegStyle, Material>();

		public static Material Get(LegStyle style)
		{
			if (made.TryGetValue(style, out var value))
			{
				return value;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(style.Chest) : null);
			Material val2 = Worn(val);
			Material paint = ((!((Object)(object)val != (Object)null)) ? null : val.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_armorMaterial);
			value = (made[style] = (((Object)(object)val2 != (Object)null && val2.HasProperty("_MainTex") && (Object)(object)val2.GetTexture("_MainTex") != (Object)null) ? Make(style, val2, paint) : null));
			if ((Object)(object)value == (Object)null)
			{
				Plugin.Log.LogWarning((object)("EliteEquipment: the game's " + style.Chest + " material was not found; the " + style.Key + " leggings keep the game's look"));
			}
			return value;
		}

		private static Material Make(LegStyle style, Material worn, Material paint)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			Material val = new Material(worn)
			{
				name = "EE_Fitted" + style.Key
			};
			for (int i = 0; i < 3; i++)
			{
				if (i <= 0 || val.HasProperty(Properties[0][i]))
				{
					Texture[] sources = (Texture[])(object)new Texture[2]
					{
						Texture(worn, Properties[0][i]),
						Texture(paint, Properties[1][i])
					};
					val.SetTexture(Properties[0][i], (Texture)(object)FittedAtlas.Build(style, sources, i));
				}
			}
			if (val.HasProperty("_EmissionMap"))
			{
				val.SetTexture("_EmissionMap", (Texture)(object)Texture2D.blackTexture);
			}
			return val;
		}

		private static Texture Texture(Material material, string property)
		{
			if (!((Object)(object)material != (Object)null) || !material.HasProperty(property))
			{
				return null;
			}
			return material.GetTexture(property);
		}

		private static Material Worn(GameObject chest)
		{
			Transform val = (((Object)(object)chest != (Object)null) ? chest.transform.Find("attach_skin") : null);
			SkinnedMeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<SkinnedMeshRenderer>(true) : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return ((Renderer)val2).sharedMaterial;
		}
	}
	internal sealed class FittedMesh
	{
		private readonly List<Vector3> positions = new List<Vector3>();

		private readonly List<Vector3> normals = new List<Vector3>();

		private readonly List<Vector2> uvs = new List<Vector2>();

		private readonly List<BoneWeight> weights = new List<BoneWeight>();

		private readonly List<int> triangles = new List<int>();

		public int TriangleCount => triangles.Count / 3;

		public int Add(Vector3 position, Vector3 normal, Vector2 uv, BoneWeight weight)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			positions.Add(position);
			normals.Add(normal);
			uvs.Add(uv);
			weights.Add(weight);
			return positions.Count - 1;
		}

		public void Triangle(int a, int b, int c)
		{
			triangles.Add(a);
			triangles.Add(b);
			triangles.Add(c);
		}

		public void Both(int a, int b, int c)
		{
			Triangle(a, b, c);
			Triangle(a, c, b);
		}

		public void Fan(int first, int count)
		{
			for (int i = 1; i + 1 < count; i++)
			{
				Triangle(first, first + i, first + i + 1);
			}
		}

		public Mesh ToMesh(string name, Matrix4x4[] bindposes)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name
			};
			if (positions.Count > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.SetVertices(positions);
			val.SetNormals(normals);
			val.SetUVs(0, uvs);
			val.boneWeights = weights.ToArray();
			val.bindposes = bindposes;
			val.SetTriangles(triangles, 0);
			val.RecalculateTangents();
			val.RecalculateBounds();
			val.UploadMeshData(true);
			return val;
		}
	}
	internal static class FittedShell
	{
		private readonly struct Context
		{
			public LegStyle Style { get; }

			public BodySurface Body { get; }

			public Unwrap Unwrap { get; }

			public FittedMesh Mesh { get; }

			public float BootTop { get; }

			public Dictionary<long, int> Made { get; }

			public Context(LegStyle style, BodySurface body, Unwrap unwrap, FittedMesh mesh, float bootTop, Dictionary<long, int> made)
			{
				Style = style;
				Body = body;
				Unwrap = unwrap;
				Mesh = mesh;
				BootTop = bootTop;
				Made = made;
			}
		}

		private const float LeatherFrom = 1.025f;

		private const float Sunk = 0.002f;

		private const float SinkAbove = 0.01f;

		private const float SinkDepth = 0.05f;

		public static void Build(LegStyle style, BodySurface body, bool[] covered, Unwrap unwrap, FittedMesh mesh, float bootTop)
		{
			Context c = new Context(style, body, unwrap, mesh, bootTop, new Dictionary<long, int>());
			for (int i = 0; i < covered.Length; i++)
			{
				if (covered[i])
				{
					Triangle(c, i);
				}
			}
		}

		public static float Off(LegStyle style, float bootTop, float height)
		{
			if (!style.UnderBoots || bootTop <= 0.094f)
			{
				return style.Thickness;
			}
			return Mathf.Lerp(style.Thickness, 0.002f, Mathf.Clamp01((bootTop + 0.01f - height) / 0.05f));
		}

		public static void Hems(LegStyle style, BodySurface body, bool[] covered, FittedMesh mesh, float bootTop)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			RectInt leather = style.Leather;
			RectInt leather2 = style.Leather;
			Vector2 uv = FittedAtlas.Region(leather, 0.5f, 36f / (float)((RectInt)(ref leather2)).height, rotated: false);
			foreach (var item3 in OpenEdges(body, covered))
			{
				int item = item3.Item1;
				int item2 = item3.Item2;
				int a = mesh.Add(body.Out(item, Off(style, bootTop, body.Rest[item].y)), body.Outward[item], uv, body.Weights[item]);
				int b = mesh.Add(body.Out(item2, Off(style, bootTop, body.Rest[item2].y)), body.Outward[item2], uv, body.Weights[item2]);
				int c = mesh.Add(body.Vertices[item], body.Outward[item], uv, body.Weights[item]);
				int num = mesh.Add(body.Vertices[item2], body.Outward[item2], uv, body.Weights[item2]);
				mesh.Both(a, b, num);
				mesh.Both(a, num, c);
			}
		}

		private static void Triangle(Context c, int t)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			BodySurface body = c.Body;
			int[] array = new int[3]
			{
				body.Triangles[3 * t],
				body.Triangles[3 * t + 1],
				body.Triangles[3 * t + 2]
			};
			Vector3[] array2 = (Vector3[])(object)new Vector3[3]
			{
				body.Rest[array[0]],
				body.Rest[array[1]],
				body.Rest[array[2]]
			};
			Vector3 val = (array2[0] + array2[1] + array2[2]) / 3f;
			int part = Unwrap.Part(val);
			float[] array3 = c.Unwrap.Angles(part, array2);
			bool leather = val.y > 1.025f;
			int[] array4 = new int[3];
			for (int i = 0; i < 3; i++)
			{
				array4[i] = Corner(c, array[i], part, array3[i], leather);
			}
			c.Mesh.Triangle(array4[0], array4[1], array4[2]);
		}

		private static int Corner(Context c, int v, int part, float angle, bool leather)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			long key = ((long)v << 8) | ((long)part << 4) | ((angle >= (float)Math.PI * 2f) ? 4 : 0) | (leather ? 1 : 0);
			if (c.Made.TryGetValue(key, out var value))
			{
				return value;
			}
			BodySurface body = c.Body;
			float num = Mathf.Clamp01((1.12f - body.Rest[v].y) / 0.13500002f);
			Vector2 val;
			if (!leather)
			{
				val = FittedAtlas.Field(c.Style, c.Unwrap.Radius(part), angle, body.Rest[v].y);
			}
			else
			{
				RectInt leather2 = c.Style.Leather;
				float along = angle / ((float)Math.PI * 2f);
				float num2 = 4f + num * 14f;
				RectInt leather3 = c.Style.Leather;
				val = FittedAtlas.Region(leather2, along, num2 / (float)((RectInt)(ref leather3)).height, rotated: false);
			}
			Vector2 uv = val;
			value = c.Mesh.Add(body.Out(v, Off(c.Style, c.BootTop, body.Rest[v].y)), body.Outward[v], uv, body.Weights[v]);
			c.Made[key] = value;
			return value;
		}

		private static List<(int, int)> OpenEdges(BodySurface body, bool[] covered)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<(Vector3Int, Vector3Int), int> dictionary = new Dictionary<(Vector3Int, Vector3Int), int>();
			Dictionary<(Vector3Int, Vector3Int), (int, int)> dictionary2 = new Dictionary<(Vector3Int, Vector3Int), (int, int)>();
			for (int i = 0; i < covered.Length; i++)
			{
				int num = 0;
				while (covered[i] && num < 3)
				{
					int num2 = body.Triangles[3 * i + num];
					int num3 = body.Triangles[3 * i + (num + 1) % 3];
					(Vector3Int, Vector3Int) key = Edge(body.Place(num2), body.Place(num3));
					dictionary[key] = ((!dictionary.TryGetValue(key, out var value)) ? 1 : (value + 1));
					dictionary2[key] = (num2, num3);
					num++;
				}
			}
			List<(int, int)> list = new List<(int, int)>();
			foreach (KeyValuePair<(Vector3Int, Vector3Int), int> item in dictionary)
			{
				if (item.Value == 1)
				{
					list.Add(dictionary2[item.Key]);
				}
			}
			return list;
		}

		private static (Vector3Int, Vector3Int) Edge(Vector3Int p, Vector3Int q)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due