Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EliteEquipment v0.1.0
plugins\EliteEquipment.dll
Decompiled 16 hours ago
The result has been truncated due to the large size, download it to view full contents!
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