Decompiled source of DoubleDragonBed v1.0.3

plugins/DoubleBed.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DoubleBed
{
	internal sealed class BedSide : MonoBehaviour
	{
		public GameObject Piece => ((Component)((Component)this).transform.parent).gameObject;
	}
	internal static class BedSides
	{
		public const string Prefab = "piece_bed02";

		public const string SideName = "DoubleBed_side2";

		public const float Offset = 0.55f;

		public const string SideRpc = "DoubleBed_SetOwner";

		public static readonly int SideOwner = StringExtensionMethods.GetStableHashCode("DoubleBed_owner");

		public static readonly int SideOwnerName = StringExtensionMethods.GetStableHashCode("DoubleBed_ownerName");

		public const string MiddleName = "spawnpoint_both";

		public const string UnclaimText = "Unclaim";

		public const string UnclaimedText = "Bed unclaimed";

		public static int OwnerKey(Bed bed)
		{
			if (!IsSecond(bed))
			{
				return ZDOVars.s_owner;
			}
			return SideOwner;
		}

		public static int OwnerNameKey(Bed bed)
		{
			if (!IsSecond(bed))
			{
				return ZDOVars.s_ownerName;
			}
			return SideOwnerName;
		}

		public static string RpcName(Bed bed)
		{
			if (!IsSecond(bed))
			{
				return "SetOwner";
			}
			return "DoubleBed_SetOwner";
		}

		public static ZNetView NetViewOf(Component bed)
		{
			BedSide bedSide = default(BedSide);
			if (!bed.TryGetComponent<BedSide>(ref bedSide))
			{
				return bed.GetComponent<ZNetView>();
			}
			return bedSide.Piece.GetComponent<ZNetView>();
		}

		public static GameObject ColliderRoot(Component bed)
		{
			BedSide bedSide = default(BedSide);
			if (!bed.TryGetComponent<BedSide>(ref bedSide))
			{
				return bed.gameObject;
			}
			return bedSide.Piece;
		}

		public static bool IsSecond(Bed bed)
		{
			BedSide bedSide = default(BedSide);
			return ((Component)bed).TryGetComponent<BedSide>(ref bedSide);
		}

		public static Bed OtherSide(Bed bed)
		{
			BedSide bedSide = default(BedSide);
			if (((Component)bed).TryGetComponent<BedSide>(ref bedSide))
			{
				return bedSide.Piece.GetComponent<Bed>();
			}
			return SecondSide(((Component)bed).gameObject);
		}

		public static bool IsDragonBedSide(Bed bed)
		{
			if (!IsSecond(bed))
			{
				return (Object)(object)SecondSide(((Component)bed).gameObject) != (Object)null;
			}
			return true;
		}

		public static bool IsMyDragonSide(Bed bed)
		{
			if (Valid(bed) && bed.IsMine())
			{
				return IsDragonBedSide(bed);
			}
			return false;
		}

		public static Bed FirstSide(Bed bed)
		{
			if (!IsSecond(bed))
			{
				return bed;
			}
			return OtherSide(bed);
		}

		public static bool BothMine(Bed bed)
		{
			Bed val = OtherSide(bed);
			if ((Object)(object)val != (Object)null && Valid(bed) && Valid(val) && bed.IsMine())
			{
				return val.IsMine();
			}
			return false;
		}

		private static bool Valid(Bed bed)
		{
			if ((Object)(object)bed.m_nview != (Object)null)
			{
				return bed.m_nview.GetZDO() != null;
			}
			return false;
		}

		public static Transform AttachPoint(Bed bed)
		{
			if (!BothMine(bed))
			{
				return bed.m_spawnPoint;
			}
			Transform val = ((Component)FirstSide(bed)).transform.Find("DoubleBed_side2/spawnpoint_both");
			if (!((Object)(object)val != (Object)null))
			{
				return bed.m_spawnPoint;
			}
			return val;
		}

		public static Vector3 SpawnPoint(Bed bed, Vector3 own)
		{
			//IL_0016: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bed.m_spawnPoint == (Object)null || !BothMine(bed))
			{
				return own;
			}
			Transform val = ((Component)FirstSide(bed)).transform.Find("DoubleBed_side2/spawnpoint_both");
			if (!((Object)(object)val != (Object)null))
			{
				return own;
			}
			return val.position;
		}

		public static Bed SecondSide(GameObject piece)
		{
			Transform val = piece.transform.Find("DoubleBed_side2");
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).GetComponent<Bed>();
		}

		public static void Wake(Bed bed)
		{
			if (!IsSecond(bed) && !(Utils.GetPrefabName(((Component)bed).gameObject) != "piece_bed02"))
			{
				Apply(bed);
			}
		}

		public static void Install()
		{
			Bed[] array = Object.FindObjectsByType<Bed>((FindObjectsSortMode)0);
			foreach (Bed val in array)
			{
				if ((Object)(object)val != (Object)null && !IsSecond(val) && Utils.GetPrefabName(((Component)val).gameObject) == "piece_bed02")
				{
					Apply(val);
				}
			}
		}

		public static void Uninstall()
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("piece_bed02") : null);
			BedSide[] array = Object.FindObjectsByType<BedSide>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (BedSide obj in array)
			{
				GameObject piece = obj.Piece;
				ZNetView component = piece.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.GetZDO() != null)
				{
					component.Unregister("DoubleBed_SetOwner");
				}
				Object.DestroyImmediate((Object)(object)((Component)obj).gameObject);
				if ((Object)(object)val != (Object)null)
				{
					Restore(piece, val);
				}
			}
		}

		private static void Apply(Bed first)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)first).gameObject;
			if ((Object)(object)gameObject.transform.Find("DoubleBed_side2") != (Object)null || (Object)(object)first.m_spawnPoint == (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("DoubleBed_side2");
			val.SetActive(false);
			val.layer = gameObject.layer;
			val.tag = gameObject.tag;
			val.transform.SetParent(gameObject.transform, false);
			BoxCollider[] componentsInChildren = gameObject.GetComponentsInChildren<BoxCollider>(true);
			foreach (BoxCollider val2 in componentsInChildren)
			{
				if (!((Collider)val2).isTrigger && Aligned(((Component)val2).transform, gameObject.transform))
				{
					Vector3 val3 = gameObject.transform.InverseTransformPoint(((Component)val2).transform.TransformPoint(val2.center));
					float num = val3.x - val2.size.x * 0.5f;
					float num2 = val3.x + val2.size.x * 0.5f;
					if (!(num >= 0f) && !(num2 <= 0f))
					{
						GameObject val4 = new GameObject(((Object)(object)((Component)val2).gameObject == (Object)(object)gameObject) ? "collider_side2" : ((Object)((Component)val2).gameObject).name)
						{
							layer = ((Component)val2).gameObject.layer,
							tag = ((Component)val2).gameObject.tag
						};
						val4.transform.SetParent(val.transform, false);
						BoxCollider obj = val4.AddComponent<BoxCollider>();
						obj.center = new Vector3(num2 * 0.5f, val3.y, val3.z);
						obj.size = new Vector3(num2, val2.size.y, val2.size.z);
						((Collider)obj).sharedMaterial = ((Collider)val2).sharedMaterial;
						val2.center += new Vector3(num * 0.5f - val3.x, 0f, 0f);
						val2.size = new Vector3(0f - num, val2.size.y, val2.size.z);
					}
				}
			}
			Transform spawnPoint = first.m_spawnPoint;
			Vector3 position = spawnPoint.position;
			Vector3 val5 = gameObject.transform.right * 0.55f;
			Transform transform = new GameObject("spawnpoint").transform;
			transform.SetParent(val.transform, false);
			transform.SetPositionAndRotation(position + val5, spawnPoint.rotation);
			Transform transform2 = new GameObject("spawnpoint_both").transform;
			transform2.SetParent(val.transform, false);
			transform2.SetPositionAndRotation(position, spawnPoint.rotation);
			spawnPoint.position = position - val5;
			Bed obj2 = val.AddComponent<Bed>();
			obj2.m_spawnPoint = transform;
			obj2.m_monsterCheckRadius = first.m_monsterCheckRadius;
			obj2.m_hoverOffset = first.m_hoverOffset;
			val.AddComponent<BedSide>();
			ForgetColliders(gameObject);
			val.SetActive(true);
		}

		private static void Restore(GameObject piece, GameObject prefab)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider[] componentsInChildren = piece.GetComponentsInChildren<BoxCollider>(true);
			BoxCollider[] componentsInChildren2 = prefab.GetComponentsInChildren<BoxCollider>(true);
			for (int i = 0; i < componentsInChildren.Length && i < componentsInChildren2.Length; i++)
			{
				componentsInChildren[i].center = componentsInChildren2[i].center;
				componentsInChildren[i].size = componentsInChildren2[i].size;
			}
			Bed component = piece.GetComponent<Bed>();
			Bed component2 = prefab.GetComponent<Bed>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && (Object)(object)component.m_spawnPoint != (Object)null && (Object)(object)component2.m_spawnPoint != (Object)null)
			{
				component.m_spawnPoint.SetLocalPositionAndRotation(component2.m_spawnPoint.localPosition, component2.m_spawnPoint.localRotation);
			}
			ForgetColliders(piece);
		}

		private static void ForgetColliders(GameObject piece)
		{
			WearNTear val = default(WearNTear);
			if (piece.TryGetComponent<WearNTear>(ref val))
			{
				val.m_colliders = null;
			}
		}

		private static bool Aligned(Transform t, Transform root)
		{
			//IL_000e: 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_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_0031: 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)
			while ((Object)(object)t != (Object)(object)root)
			{
				if ((Object)(object)t == (Object)null)
				{
					return false;
				}
				if (Quaternion.Angle(t.localRotation, Quaternion.identity) > 0.1f)
				{
					return false;
				}
				Vector3 val = t.localScale - Vector3.one;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
				{
					return false;
				}
				t = t.parent;
			}
			return true;
		}
	}
	internal sealed class Part
	{
		public readonly List<int> Triangles = new List<int>();

		public Vector3 Min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

		public Vector3 Max = new Vector3(float.MinValue, float.MinValue, float.MinValue);

		public Vector3 Size => Max - Min;

		public Vector3 Centre => (Min + Max) * 0.5f;
	}
	internal sealed class BedParts
	{
		public readonly List<Part> Parts;

		public readonly int Fur1;

		public readonly int Fur2;

		private BedParts(List<Part> parts, int fur1, int fur2)
		{
			Parts = parts;
			Fur1 = fur1;
			Fur2 = fur2;
		}

		public static BedParts Read(Vector3[] vertices, int[] triangles, out string why)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			List<Part> list = Split(vertices, triangles);
			int fur = -1;
			int fur2 = -1;
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (IsFur(list[i]))
				{
					if (list[i].Centre.x < 0f)
					{
						fur = i;
						num++;
					}
					else
					{
						fur2 = i;
						num2++;
					}
				}
			}
			if (num != 1 || num2 != 1)
			{
				why = $"{list.Count} pieces, {num} fur(s) on side 1 and {num2} on side 2 (one each expected)";
				return null;
			}
			why = null;
			return new BedParts(list, fur, fur2);
		}

		private static bool IsFur(Part p)
		{
			//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_0008: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Vector3 size = p.Size;
			float num = Mathf.Abs(p.Centre.x);
			if (p.Min.y < 0.15f && p.Max.y > 0.35f && p.Max.y < 0.75f && num > 0.5f && num < 1f && size.x > 0.6f && size.x < 1.3f)
			{
				return size.z > 0.8f;
			}
			return false;
		}

		public bool IsGround(int part)
		{
			if (part != Fur1 && part != Fur2)
			{
				return Parts[part].Max.y < 0.6f;
			}
			return false;
		}

		public int[] TrianglesWithout(int[] triangles, bool fur1, bool fur2)
		{
			HashSet<int> hashSet = new HashSet<int>();
			if (fur1)
			{
				hashSet.UnionWith(Parts[Fur1].Triangles);
			}
			if (fur2)
			{
				hashSet.UnionWith(Parts[Fur2].Triangles);
			}
			List<int> list = new List<int>(triangles.Length);
			for (int i = 0; i < triangles.Length / 3; i++)
			{
				if (!hashSet.Contains(i))
				{
					list.Add(triangles[i * 3]);
					list.Add(triangles[i * 3 + 1]);
					list.Add(triangles[i * 3 + 2]);
				}
			}
			return list.ToArray();
		}

		public void Ground(Vector3[] vertices, int[] triangles, Field into)
		{
			//IL_0035: 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)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Parts.Count; i++)
			{
				if (!IsGround(i))
				{
					continue;
				}
				foreach (int triangle in Parts[i].Triangles)
				{
					into.Triangle(vertices[triangles[triangle * 3]], vertices[triangles[triangle * 3 + 1]], vertices[triangles[triangle * 3 + 2]]);
				}
			}
		}

		private static List<Part> Split(Vector3[] v, int[] tris)
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			int[] parent = new int[v.Length];
			for (int i = 0; i < parent.Length; i++)
			{
				parent[i] = i;
			}
			Dictionary<(int, int, int), int> dictionary = new Dictionary<(int, int, int), int>();
			for (int j = 0; j < v.Length; j++)
			{
				(int, int, int) key = (Mathf.RoundToInt(v[j].x * 10000f), Mathf.RoundToInt(v[j].y * 10000f), Mathf.RoundToInt(v[j].z * 10000f));
				if (dictionary.TryGetValue(key, out var value))
				{
					Join(j, value);
				}
				else
				{
					dictionary[key] = j;
				}
			}
			for (int k = 0; k + 2 < tris.Length; k += 3)
			{
				Join(tris[k], tris[k + 1]);
				Join(tris[k + 1], tris[k + 2]);
			}
			Dictionary<int, Part> dictionary2 = new Dictionary<int, Part>();
			List<Part> list = new List<Part>();
			for (int l = 0; l < tris.Length / 3; l++)
			{
				int key2 = Find(tris[l * 3]);
				if (!dictionary2.TryGetValue(key2, out var value2))
				{
					value2 = (dictionary2[key2] = new Part());
					list.Add(value2);
				}
				value2.Triangles.Add(l);
				for (int m = 0; m < 3; m++)
				{
					Vector3 val = v[tris[l * 3 + m]];
					value2.Min = Vector3.Min(value2.Min, val);
					value2.Max = Vector3.Max(value2.Max, val);
				}
			}
			return list;
			int Find(int a)
			{
				while (parent[a] != a)
				{
					a = (parent[a] = parent[parent[a]]);
				}
				return a;
			}
			void Join(int a, int b)
			{
				parent[Find(a)] = Find(b);
			}
		}
	}
	internal sealed class Sheet
	{
		public Vector3[] Rest;

		public Vector2[] Uv;

		public Vector2[] Flat;

		public int[] Triangles;

		public float MinX;

		public float MaxX;

		public float MinZ;

		public float MaxZ;

		public float FitError;

		public int FacingDown;

		public static Sheet From(Vector3[] vertices, Vector2[] uvs, int[] triangles, Part fur, int finer)
		{
			//IL_00a8: 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_0061: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<int> list3 = new List<int>();
			foreach (int triangle in fur.Triangles)
			{
				for (int i = 0; i < 3; i++)
				{
					int num = triangles[triangle * 3 + i];
					if (!dictionary.TryGetValue(num, out var value))
					{
						value = (dictionary[num] = list.Count);
						list.Add(vertices[num]);
						list2.Add(uvs[num]);
					}
					list3.Add(value);
				}
			}
			Vector2 scale = UvScale(list, list2, list3);
			for (int j = 0; j < finer; j++)
			{
				Subdivide(list, list2, list3);
			}
			Sheet sheet = new Sheet();
			sheet.Rest = list.ToArray();
			sheet.Uv = list2.ToArray();
			sheet.Triangles = list3.ToArray();
			sheet.Flatten(scale);
			return sheet;
		}

		private static Vector2 UvScale(List<Vector3> pos, List<Vector2> uv, List<int> tri)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			double num = 0.0;
			double num2 = 0.0;
			double num3 = 0.0;
			double num4 = 0.0;
			double num5 = 0.0;
			double num6 = 0.0;
			double num7 = 0.0;
			for (int i = 0; i < tri.Count; i += 3)
			{
				for (int j = 0; j < 3; j++)
				{
					int index = tri[i + j];
					int index2 = tri[i + (j + 1) % 3];
					double num8 = uv[index2].x - uv[index].x;
					double num9 = uv[index2].y - uv[index].y;
					Vector3 val = pos[index2] - pos[index];
					double num10 = ((Vector3)(ref val)).sqrMagnitude;
					double num11 = num8 * num8;
					double num12 = num9 * num9;
					num += num11 * num11;
					num2 += num11 * num12;
					num3 += num12 * num12;
					num4 += num10 * num11;
					num5 += num10 * num12;
					num6 += Math.Sqrt(num11 + num12) * Math.Sqrt(num10);
					num7 += num11 + num12;
				}
			}
			double num13 = num * num3 - num2 * num2;
			if (Math.Abs(num13) > 1E-18)
			{
				double num14 = (num4 * num3 - num2 * num5) / num13;
				double num15 = (num * num5 - num2 * num4) / num13;
				if (num14 > 0.0 && num15 > 0.0)
				{
					return new Vector2((float)Math.Sqrt(num14), (float)Math.Sqrt(num15));
				}
			}
			float num16 = ((num7 > 0.0) ? ((float)(num6 / num7)) : 1f);
			return new Vector2(num16, num16);
		}

		private static void Subdivide(List<Vector3> pos, List<Vector2> uv, List<int> tri)
		{
			Dictionary<(int, int), int> mid = new Dictionary<(int, int), int>();
			List<int> list = new List<int>(tri.Count * 4);
			for (int i = 0; i < tri.Count; i += 3)
			{
				int num = tri[i];
				int num2 = tri[i + 1];
				int num3 = tri[i + 2];
				int num4 = Mid(num, num2);
				int num5 = Mid(num2, num3);
				int num6 = Mid(num3, num);
				list.AddRange(new int[12]
				{
					num, num4, num6, num4, num2, num5, num6, num5, num3, num4,
					num5, num6
				});
			}
			tri.Clear();
			tri.AddRange(list);
			int Mid(int num7, int j)
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: 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_0068: 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_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_009a: Unknown result type (might be due to invalid IL or missing references)
				(int, int) key = ((num7 < j) ? (num7, j) : (j, num7));
				if (mid.TryGetValue(key, out var value))
				{
					return value;
				}
				value = (mid[key] = pos.Count);
				pos.Add((pos[num7] + pos[j]) * 0.5f);
				uv.Add((uv[num7] + uv[j]) * 0.5f);
				return value;
			}
		}

		private void Flatten(Vector2 scale)
		{
			//IL_002a: 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_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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			int num = Rest.Length;
			Vector2[] array = (Vector2[])(object)new Vector2[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = new Vector2(Uv[i].x * scale.x, Uv[i].y * scale.y);
			}
			List<int> list = new List<int>();
			for (int j = 0; j < num; j++)
			{
				if (Rest[j].y > 0.35f)
				{
					list.Add(j);
				}
			}
			if (list.Count < 3)
			{
				for (int k = 0; k < num; k++)
				{
					list.Add(k);
				}
			}
			Fit(array, list, mirror: false, out var angle, out var move, out var error);
			Fit(array, list, mirror: true, out var angle2, out var move2, out var error2);
			bool flag = error2 < error;
			float angle3 = (flag ? angle2 : angle);
			Vector2 val = (flag ? move2 : move);
			FitError = (flag ? error2 : error);
			Flat = (Vector2[])(object)new Vector2[num];
			MinX = (MinZ = float.MaxValue);
			MaxX = (MaxZ = float.MinValue);
			for (int l = 0; l < num; l++)
			{
				Vector2 val2 = Turn(Mirror(array[l], flag), angle3) + val;
				Flat[l] = val2;
				MinX = Mathf.Min(MinX, val2.x);
				MaxX = Mathf.Max(MaxX, val2.x);
				MinZ = Mathf.Min(MinZ, val2.y);
				MaxZ = Mathf.Max(MaxZ, val2.y);
			}
			int num2 = 0;
			for (int m = 0; m < Triangles.Length; m += 3)
			{
				if (FlatUp(m) < 0f)
				{
					num2++;
				}
			}
			if (num2 * 2 > Triangles.Length / 3)
			{
				for (int n = 0; n < Triangles.Length; n += 3)
				{
					ref int reference = ref Triangles[n + 1];
					ref int reference2 = ref Triangles[n + 2];
					int num3 = Triangles[n + 2];
					int num4 = Triangles[n + 1];
					reference = num3;
					reference2 = num4;
				}
			}
			FacingDown = 0;
			for (int num5 = 0; num5 < Triangles.Length; num5 += 3)
			{
				if (FlatUp(num5) < 0f)
				{
					FacingDown++;
				}
			}
		}

		private float FlatUp(int t)
		{
			//IL_000e: 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_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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0052: 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_005f: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = Flat[Triangles[t]];
			Vector2 val2 = Flat[Triangles[t + 1]];
			Vector2 val3 = Flat[Triangles[t + 2]];
			return Vector3.Cross(new Vector3(val2.x - val.x, 0f, val2.y - val.y), new Vector3(val3.x - val.x, 0f, val3.y - val.y)).y;
		}

		private static Vector2 Mirror(Vector2 p, bool mirror)
		{
			//IL_0005: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if (!mirror)
			{
				return p;
			}
			return new Vector2(0f - p.x, p.y);
		}

		private static Vector2 Turn(Vector2 p, float angle)
		{
			//IL_000f: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			float num = Mathf.Cos(angle);
			float num2 = Mathf.Sin(angle);
			return new Vector2(num * p.x - num2 * p.y, num2 * p.x + num * p.y);
		}

		private void Fit(Vector2[] flat, List<int> use, bool mirror, out float angle, out Vector2 move, out float error)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0023: 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_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_0059: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_0093: 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_00c6: 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_00d1: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = Vector2.zero;
			Vector2 val2 = Vector2.zero;
			foreach (int item in use)
			{
				val += Mirror(flat[item], mirror);
				val2 += new Vector2(Rest[item].x, Rest[item].z);
			}
			val /= (float)use.Count;
			val2 /= (float)use.Count;
			double num = 0.0;
			double num2 = 0.0;
			foreach (int item2 in use)
			{
				Vector2 val3 = Mirror(flat[item2], mirror) - val;
				Vector2 val4 = new Vector2(Rest[item2].x, Rest[item2].z) - val2;
				num += (double)(val3.x * val4.y - val3.y * val4.x);
				num2 += (double)(val3.x * val4.x + val3.y * val4.y);
			}
			angle = (float)Math.Atan2(num, num2);
			move = val2 - Turn(val, angle);
			double num3 = 0.0;
			foreach (int item3 in use)
			{
				double num4 = num3;
				Vector2 val5 = Turn(Mirror(flat[item3], mirror), angle) + move - new Vector2(Rest[item3].x, Rest[item3].z);
				num3 = num4 + (double)((Vector2)(ref val5)).sqrMagnitude;
			}
			error = (float)Math.Sqrt(num3 / (double)use.Count);
		}
	}
	internal sealed class Field
	{
		public readonly float X0;

		public readonly float Z0;

		public readonly float Cell;

		public readonly int Nx;

		public readonly int Nz;

		public readonly float[] H;

		public Field(float x0, float z0, float x1, float z1, float cell)
		{
			X0 = x0;
			Z0 = z0;
			Cell = cell;
			Nx = Mathf.CeilToInt((x1 - x0) / cell);
			Nz = Mathf.CeilToInt((z1 - z0) / cell);
			H = new float[Nx * Nz];
		}

		public Field(Field like)
			: this(like.X0, like.Z0, like.X0 + (float)like.Nx * like.Cell, like.Z0 + (float)like.Nz * like.Cell, like.Cell)
		{
		}

		public float X(int i)
		{
			return X0 + ((float)i + 0.5f) * Cell;
		}

		public float Z(int j)
		{
			return Z0 + ((float)j + 0.5f) * Cell;
		}

		public void Fill(float value)
		{
			for (int i = 0; i < H.Length; i++)
			{
				H[i] = value;
			}
		}

		public void CopyFrom(Field other)
		{
			Array.Copy(other.H, H, H.Length);
		}

		public void Triangle(Vector3 a, Vector3 b, Vector3 c)
		{
			//IL_0000: 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_000d: 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_001b: 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_0028: 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_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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00ba: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			float num = (b.x - a.x) * (c.z - a.z) - (c.x - a.x) * (b.z - a.z);
			if (Mathf.Abs(num) < 1E-09f)
			{
				return;
			}
			int num2 = Mathf.Max(0, Mathf.FloorToInt((Mathf.Min(a.x, Mathf.Min(b.x, c.x)) - X0) / Cell));
			int num3 = Mathf.Min(Nx - 1, Mathf.FloorToInt((Mathf.Max(a.x, Mathf.Max(b.x, c.x)) - X0) / Cell));
			int num4 = Mathf.Max(0, Mathf.FloorToInt((Mathf.Min(a.z, Mathf.Min(b.z, c.z)) - Z0) / Cell));
			int num5 = Mathf.Min(Nz - 1, Mathf.FloorToInt((Mathf.Max(a.z, Mathf.Max(b.z, c.z)) - Z0) / Cell));
			for (int i = num4; i <= num5; i++)
			{
				float num6 = Z(i);
				for (int j = num2; j <= num3; j++)
				{
					float num7 = X(j);
					float num8 = ((num7 - a.x) * (c.z - a.z) - (c.x - a.x) * (num6 - a.z)) / num;
					float num9 = ((b.x - a.x) * (num6 - a.z) - (num7 - a.x) * (b.z - a.z)) / num;
					float num10 = 1f - num8 - num9;
					if (!(num10 < -0.0001f) && !(num8 < -0.0001f) && !(num9 < -0.0001f))
					{
						Raise(j, i, num10 * a.y + num8 * b.y + num9 * c.y);
					}
				}
			}
		}

		public void Point(Vector3 p, int cells)
		{
			//IL_0000: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.FloorToInt((p.x - X0) / Cell);
			int num2 = Mathf.FloorToInt((p.z - Z0) / Cell);
			for (int i = Mathf.Max(0, num2 - cells); i <= Mathf.Min(Nz - 1, num2 + cells); i++)
			{
				for (int j = Mathf.Max(0, num - cells); j <= Mathf.Min(Nx - 1, num + cells); j++)
				{
					Raise(j, i, p.y);
				}
			}
		}

		public void Sphere(Vector3 c, float radius)
		{
			//IL_0001: 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_004c: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			int num = Mathf.Max(0, Mathf.FloorToInt((c.x - radius - X0) / Cell));
			int num2 = Mathf.Min(Nx - 1, Mathf.FloorToInt((c.x + radius - X0) / Cell));
			int num3 = Mathf.Max(0, Mathf.FloorToInt((c.z - radius - Z0) / Cell));
			int num4 = Mathf.Min(Nz - 1, Mathf.FloorToInt((c.z + radius - Z0) / Cell));
			for (int i = num3; i <= num4; i++)
			{
				for (int j = num; j <= num2; j++)
				{
					float num5 = X(j) - c.x;
					float num6 = Z(i) - c.z;
					float num7 = radius * radius - num5 * num5 - num6 * num6;
					if (num7 >= 0f)
					{
						Raise(j, i, c.y + Mathf.Sqrt(num7));
					}
				}
			}
		}

		public void Capsule(Vector3 a, Vector3 b, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0020: 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)
			int num = Mathf.Max(1, Mathf.CeilToInt(Vector3.Distance(a, b) / Cell));
			for (int i = 0; i <= num; i++)
			{
				Sphere(Vector3.Lerp(a, b, (float)i / (float)num), radius);
			}
		}

		public void Box(Vector3 min, Vector3 max)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(0, Mathf.FloorToInt((min.x - X0) / Cell));
			int num2 = Mathf.Min(Nx - 1, Mathf.FloorToInt((max.x - X0) / Cell));
			int num3 = Mathf.Max(0, Mathf.FloorToInt((min.z - Z0) / Cell));
			int num4 = Mathf.Min(Nz - 1, Mathf.FloorToInt((max.z - Z0) / Cell));
			for (int i = num3; i <= num4; i++)
			{
				for (int j = num; j <= num2; j++)
				{
					Raise(j, i, max.y);
				}
			}
		}

		private void Raise(int i, int j, float y)
		{
			int num = j * Nx + i;
			if (y > H[num])
			{
				H[num] = y;
			}
		}

		public void Close(int cells, float[] scratch)
		{
			Window(H, scratch, cells, max: true, alongX: true);
			Window(scratch, H, cells, max: true, alongX: false);
			Window(H, scratch, cells, max: false, alongX: true);
			Window(scratch, H, cells, max: false, alongX: false);
		}

		public void Slope(float rise)
		{
			float num = rise * Cell;
			for (int i = 0; i < Nz; i++)
			{
				for (int j = 1; j < Nx; j++)
				{
					H[i * Nx + j] = Mathf.Max(H[i * Nx + j], H[i * Nx + j - 1] - num);
				}
				for (int num2 = Nx - 2; num2 >= 0; num2--)
				{
					H[i * Nx + num2] = Mathf.Max(H[i * Nx + num2], H[i * Nx + num2 + 1] - num);
				}
			}
			for (int k = 0; k < Nx; k++)
			{
				for (int l = 1; l < Nz; l++)
				{
					H[l * Nx + k] = Mathf.Max(H[l * Nx + k], H[(l - 1) * Nx + k] - num);
				}
				for (int num3 = Nz - 2; num3 >= 0; num3--)
				{
					H[num3 * Nx + k] = Mathf.Max(H[num3 * Nx + k], H[(num3 + 1) * Nx + k] - num);
				}
			}
		}

		public void Dilate(int cells, float[] scratch)
		{
			Window(H, scratch, cells, max: true, alongX: true);
			Window(scratch, H, cells, max: true, alongX: false);
		}

		public void Blur(int cells, int passes, float[] scratch)
		{
			for (int i = 0; i < passes; i++)
			{
				Mean(H, scratch, cells, alongX: true);
				Mean(scratch, H, cells, alongX: false);
			}
		}

		private void Window(float[] from, float[] to, int r, bool max, bool alongX)
		{
			int num = (alongX ? Nx : Nz);
			int num2 = (alongX ? Nz : Nx);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num3 = (max ? float.MinValue : float.MaxValue);
					for (int k = Mathf.Max(0, j - r); k <= Mathf.Min(num - 1, j + r); k++)
					{
						float num4 = from[alongX ? (i * Nx + k) : (k * Nx + i)];
						num3 = (max ? Mathf.Max(num3, num4) : Mathf.Min(num3, num4));
					}
					to[alongX ? (i * Nx + j) : (j * Nx + i)] = num3;
				}
			}
		}

		private void Mean(float[] from, float[] to, int r, bool alongX)
		{
			int num = (alongX ? Nx : Nz);
			int num2 = (alongX ? Nz : Nx);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num3 = 0f;
					int num4 = 0;
					for (int k = Mathf.Max(0, j - r); k <= Mathf.Min(num - 1, j + r); k++)
					{
						num3 += from[alongX ? (i * Nx + k) : (k * Nx + i)];
						num4++;
					}
					to[alongX ? (i * Nx + j) : (j * Nx + i)] = num3 / (float)num4;
				}
			}
		}

		public float Sample(float x, float z)
		{
			float num = Mathf.Clamp((x - X0) / Cell - 0.5f, 0f, (float)Nx - 1.001f);
			float num2 = Mathf.Clamp((z - Z0) / Cell - 0.5f, 0f, (float)Nz - 1.001f);
			int num3 = (int)num;
			int num4 = (int)num2;
			float num5 = num - (float)num3;
			float num6 = num2 - (float)num4;
			float num7 = Mathf.Lerp(H[num4 * Nx + num3], H[num4 * Nx + num3 + 1], num5);
			float num8 = Mathf.Lerp(H[(num4 + 1) * Nx + num3], H[(num4 + 1) * Nx + num3 + 1], num5);
			return Mathf.Lerp(num7, num8, num6);
		}
	}
	internal struct Cover
	{
		public float CentreX;

		public float TopZ;

		public float FootZ;

		public int TuckSide;

		public float TuckX;

		public float Lift;
	}
	internal static class Drape
	{
		private sealed class Row
		{
			private readonly float[] _upLength;

			private readonly float[] _upHeight;

			private readonly float[] _downLength;

			private readonly float[] _downHeight;

			private readonly float _centre;

			private readonly float _cell;

			public Row(Field f, int j, float centre)
			{
				_centre = centre;
				_cell = f.Cell;
				float z = f.Z(j);
				Measure(f, z, 1, f.X0 + (float)f.Nx * f.Cell, out _upLength, out _upHeight);
				Measure(f, z, -1, f.X0, out _downLength, out _downHeight);
			}

			private void Measure(Field f, float z, int dir, float end, out float[] length, out float[] height)
			{
				int num = Mathf.Max(2, Mathf.FloorToInt(Mathf.Abs(end - _centre) / _cell));
				length = new float[num];
				height = new float[num];
				for (int i = 0; i < num; i++)
				{
					height[i] = f.Sample(_centre + (float)(dir * i) * _cell, z);
					length[i] = ((i == 0) ? 0f : (length[i - 1] + Mathf.Sqrt(_cell * _cell + (height[i] - height[i - 1]) * (height[i] - height[i - 1]))));
				}
			}

			public Vector2 At(float along)
			{
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				int num = ((along >= 0f) ? 1 : (-1));
				float[] array = ((num > 0) ? _upLength : _downLength);
				float[] array2 = ((num > 0) ? _upHeight : _downHeight);
				float num2 = Mathf.Abs(along);
				int num3 = array.Length;
				if (num2 >= array[num3 - 1])
				{
					float num4 = num2 - array[num3 - 1];
					float num5 = Mathf.Min(num4, Mathf.Max(0f, array2[num3 - 1] - 0.02f));
					return new Vector2(_centre + (float)num * ((float)(num3 - 1) * _cell + num4 - num5), array2[num3 - 1] - num5);
				}
				int num6 = 0;
				int num7 = num3 - 1;
				while (num7 - num6 > 1)
				{
					int num8 = (num6 + num7) / 2;
					if (array[num8] <= num2)
					{
						num6 = num8;
					}
					else
					{
						num7 = num8;
					}
				}
				float num9 = (num2 - array[num6]) / Mathf.Max(1E-06f, array[num7] - array[num6]);
				return new Vector2(_centre + (float)num * ((float)num6 + num9) * _cell, Mathf.Lerp(array2[num6], array2[num7], num9));
			}
		}

		public const float Cell = 0.02f;

		public const float Gap = 0.035f;

		public const int CloseCells = 8;

		public const int BlurCells = 2;

		public const int BlurPasses = 2;

		public const float MinStretch = 0.85f;

		public const float MaxStretch = 1.3f;

		public const float Across = 1.2f;

		public const float Flank = 1.2f;

		public const float Floor = 0.02f;

		public const float RollCore = 0.025f;

		public const float RollLayer = 0.009f;

		public static Field NewField()
		{
			return new Field(-1.5f, -1.3f, 1.5f, 1.9f, 0.02f);
		}

		public static void Shape(Field ground, Field body, Field into, float[] scratch)
		{
			float[] h = ground.H;
			float[] h2 = body.H;
			float[] h3 = into.H;
			for (int i = 0; i < h3.Length; i++)
			{
				h3[i] = Mathf.Max(h[i], h2[i] + 0.035f);
			}
			into.Close(8, scratch);
			into.Slope(1.2f);
			into.Dilate(4, scratch);
			into.Blur(2, 2, scratch);
			for (int j = 0; j < h3.Length; j++)
			{
				h3[j] = Mathf.Max(h3[j], h[j] + 0.004f);
			}
		}

		public static void Tuck(Field f, in Cover c)
		{
			if (c.TuckSide == 0)
			{
				return;
			}
			for (int i = 0; i < f.Nx; i++)
			{
				float num = (f.X(i) - c.TuckX) * (float)c.TuckSide;
				if (!(num <= 0f))
				{
					for (int j = 0; j < f.Nz; j++)
					{
						f.H[j * f.Nx + i] -= num * 3f;
					}
				}
			}
		}

		public static float Lay(Sheet sheet, Field f, in Cover c, Vector3[] into)
		{
			//IL_0072: 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)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			float num = sheet.MaxZ - sheet.MinZ;
			float num2 = Mathf.Clamp((c.FootZ - c.TopZ) / num, 0.85f, 1.3f);
			float num3 = (sheet.MinX + sheet.MaxX) * 0.5f;
			float centre = c.CentreX;
			Dictionary<int, Row> rows = new Dictionary<int, Row>();
			for (int i = 0; i < sheet.Flat.Length; i++)
			{
				Vector2 val = sheet.Flat[i];
				float num4 = c.TopZ + (val.y - sheet.MinZ) * num2;
				float along = (val.x - num3) * 1.2f;
				float num5 = (num4 - f.Z0) / f.Cell - 0.5f;
				int num6 = Mathf.FloorToInt(num5);
				float num7 = Mathf.Clamp01(num5 - (float)num6);
				Vector2 val2 = RowAt(num6).At(along);
				Vector2 val3 = RowAt(num6 + 1).At(along);
				Vector2 val4 = Vector2.Lerp(val2, val3, num7);
				float num8 = ((val4.x > f.X0 && val4.x < f.X0 + (float)f.Nx * f.Cell) ? Mathf.Max(val4.y, f.Sample(val4.x, num4)) : val4.y);
				into[i] = new Vector3(val4.x, num8 + c.Lift, num4);
			}
			return num2;
			Row RowAt(int j)
			{
				j = Mathf.Clamp(j, 0, f.Nz - 1);
				if (!rows.TryGetValue(j, out var value))
				{
					value = (rows[j] = new Row(f, j, centre));
				}
				return value;
			}
		}

		public static void Roll(Sheet sheet, Field f, in Cover c, float stretch, Vector3[] laid, float front, Vector3[] into)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			float num = (sheet.MaxZ - sheet.MinZ) * stretch;
			front = Mathf.Clamp(front, 0f, num);
			float num2 = SpiralAngle(num - front);
			float num3 = 0.025f + 0.009f * num2 / ((float)Math.PI * 2f);
			float num4 = c.TopZ + num - front;
			for (int i = 0; i < sheet.Flat.Length; i++)
			{
				float num5 = (sheet.MaxZ - sheet.Flat[i].y) * stretch;
				if (num5 <= front)
				{
					into[i] = laid[i];
					continue;
				}
				float num6 = SpiralAngle(num - num5);
				float num7 = 0.025f + 0.009f * num6 / ((float)Math.PI * 2f);
				float num8 = num2 - num6;
				float x = laid[i].x;
				float num9 = float.MinValue;
				for (int j = -2; j <= 2; j++)
				{
					num9 = Mathf.Max(num9, f.Sample(x, num4 + (float)j * 0.5f * num3));
				}
				num9 += c.Lift;
				into[i] = new Vector3(x, num9 + num3 - num7 * Mathf.Cos(num8), num4 - num7 * Mathf.Sin(num8));
			}
		}

		private static float SpiralAngle(float wound)
		{
			float num = 0.0014323944f;
			return (-0.025f + Mathf.Sqrt(0.00062500004f + 2f * num * Mathf.Max(0f, wound))) / num;
		}
	}
	internal static class Blankets
	{
		internal sealed class Model
		{
			public Mesh Original;

			public BedParts Parts;

			public int[] Triangles;

			public readonly Mesh[] Without = (Mesh[])(object)new Mesh[4];

			public Sheet[] Sheets;

			public Field Ground;
		}

		public const string ObjectName = "DoubleBed_blanket";

		public const float SeenWithin = 40f;

		public const float FootZ = 1.4f;

		public const float Outward = 0.08f;

		private const int Finer = 3;

		private static readonly Dictionary<Mesh, Model> s_models = new Dictionary<Mesh, Model>();

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

		private static readonly HashSet<Mesh> s_unknown = new HashSet<Mesh>();

		public static bool Drawn => (int)SystemInfo.graphicsDeviceType != 4;

		public static void Wake(Bed bed)
		{
			BedBlankets bedBlankets = default(BedBlankets);
			if (Drawn && !BedSides.IsSecond(bed) && !((Object)(object)BedSides.SecondSide(((Component)bed).gameObject) == (Object)null) && !((Object)(object)bed.m_nview == (Object)null) && bed.m_nview.GetZDO() != null && !((Component)bed).TryGetComponent<BedBlankets>(ref bedBlankets))
			{
				((Component)bed).gameObject.AddComponent<BedBlankets>();
			}
		}

		public static void Install()
		{
			Bed[] array = Object.FindObjectsByType<Bed>((FindObjectsSortMode)0);
			foreach (Bed val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Wake(val);
				}
			}
		}

		public static void Uninstall()
		{
			BedBlankets[] array = Object.FindObjectsByType<BedBlankets>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (BedBlankets obj in array)
			{
				obj.Restore();
				Object.DestroyImmediate((Object)(object)obj);
			}
			foreach (Model value in s_models.Values)
			{
				Mesh[] without = value.Without;
				foreach (Mesh val in without)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)val);
					}
				}
			}
			s_models.Clear();
			s_originals.Clear();
			s_unknown.Clear();
			Measure.Uninstall();
		}

		public static Mesh OriginalOf(Mesh mesh)
		{
			if (!((Object)(object)mesh != (Object)null) || !s_originals.TryGetValue(mesh, out var value))
			{
				return mesh;
			}
			return value;
		}

		public static Model ModelOf(Mesh original)
		{
			if ((Object)(object)original == (Object)null || s_unknown.Contains(original))
			{
				return null;
			}
			if (s_models.TryGetValue(original, out var value))
			{
				return value;
			}
			string why;
			if (!original.isReadable)
			{
				why = "its mesh cannot be read";
			}
			else if (original.subMeshCount != 1)
			{
				why = $"{original.subMeshCount} submeshes";
			}
			else
			{
				int[] triangles = original.triangles;
				BedParts bedParts = BedParts.Read(original.vertices, triangles, out why);
				if (bedParts != null)
				{
					Dictionary<Mesh, Model> dictionary = s_models;
					Model obj = new Model
					{
						Original = original,
						Parts = bedParts,
						Triangles = triangles
					};
					value = obj;
					dictionary[original] = obj;
					return value;
				}
			}
			s_unknown.Add(original);
			DoubleBedPlugin.Log.LogWarning((object)("No blankets on the dragon bed's mesh '" + ((Object)original).name + "': " + why + ". The bed works as before."));
			return null;
		}

		public static Mesh Without(Model model, int mask)
		{
			if (mask == 0)
			{
				return model.Original;
			}
			Mesh val = model.Without[mask];
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<Mesh>(model.Original);
				((Object)val).name = string.Format("{0}_{1}{2}", ((Object)model.Original).name, "DoubleBed_blanket", mask);
				val.SetTriangles(model.Parts.TrianglesWithout(model.Triangles, (mask & 1) != 0, (mask & 2) != 0), 0, false);
				model.Without[mask] = val;
				s_originals[val] = model.Original;
			}
			return val;
		}

		public static bool Cloth(Model model)
		{
			if (model.Sheets != null)
			{
				return true;
			}
			Vector3[] vertices = model.Original.vertices;
			Vector2[] uv = model.Original.uv;
			if (uv == null || uv.Length != vertices.Length)
			{
				return false;
			}
			BedParts parts = model.Parts;
			model.Sheets = new Sheet[2]
			{
				Sheet.From(vertices, uv, model.Triangles, parts.Parts[parts.Fur1], 3),
				Sheet.From(vertices, uv, model.Triangles, parts.Parts[parts.Fur2], 3)
			};
			model.Ground = Drape.NewField();
			model.Ground.Fill(0f);
			parts.Ground(vertices, model.Triangles, model.Ground);
			return true;
		}
	}
	internal sealed class BedBlankets : MonoBehaviour
	{
		private const float LookEvery = 0.1f;

		private Bed m_first;

		private Bed m_second;

		private Transform m_middle;

		private WearNTear m_wear;

		private readonly List<(MeshFilter Filter, Blankets.Model Model)> m_filters = new List<(MeshFilter, Blankets.Model)>();

		private Blankets.Model m_near;

		private MeshRenderer m_newRenderer;

		private MeshRenderer m_wornRenderer;

		private Blanket[] m_blankets;

		private bool m_tried;

		private int m_mask;

		private float m_nextLook;

		public Blanket this[int side]
		{
			get
			{
				Blanket[] blankets = m_blankets;
				if (blankets == null)
				{
					return null;
				}
				return blankets[side];
			}
		}

		public Blankets.Model Near => m_near;

		private bool Ready()
		{
			if (m_blankets != null)
			{
				return true;
			}
			if (m_tried)
			{
				return false;
			}
			m_tried = true;
			m_first = ((Component)this).GetComponent<Bed>();
			m_second = BedSides.SecondSide(((Component)this).gameObject);
			m_middle = ((Component)this).transform.Find("DoubleBed_side2/spawnpoint_both");
			m_wear = ((Component)this).GetComponent<WearNTear>();
			if ((Object)(object)m_first == (Object)null || (Object)(object)m_second == (Object)null || (Object)(object)m_middle == (Object)null || (Object)(object)m_wear == (Object)null || (Object)(object)m_wear.m_new == (Object)null)
			{
				return false;
			}
			GameObject[] array = (GameObject[])(object)new GameObject[2] { m_wear.m_new, m_wear.m_worn };
			foreach (GameObject val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshFilter[] componentsInChildren = val.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter filter in componentsInChildren)
				{
					if (m_filters.Exists(((MeshFilter Filter, Blankets.Model Model) f) => (Object)(object)f.Filter == (Object)(object)filter))
					{
						continue;
					}
					Blankets.Model model = Blankets.ModelOf(Blankets.OriginalOf(filter.sharedMesh));
					if (model != null && InBedSpace(((Component)filter).transform))
					{
						m_filters.Add((filter, model));
						if (m_near == null || model.Original.vertexCount > m_near.Original.vertexCount)
						{
							m_near = model;
						}
					}
				}
			}
			if (m_near == null || !Blankets.Cloth(m_near))
			{
				return false;
			}
			foreach (var filter2 in m_filters)
			{
				var (val2, _) = filter2;
				if (filter2.Model == m_near)
				{
					if (((Component)val2).transform.IsChildOf(m_wear.m_new.transform))
					{
						m_newRenderer = ((Component)val2).GetComponent<MeshRenderer>();
					}
					else
					{
						m_wornRenderer = ((Component)val2).GetComponent<MeshRenderer>();
					}
				}
			}
			if ((Object)(object)m_newRenderer == (Object)null)
			{
				return false;
			}
			m_blankets = new Blanket[2]
			{
				new Blanket(this, 0, m_near.Sheets[0]),
				new Blanket(this, 1, m_near.Sheets[1])
			};
			return true;
		}

		private bool InBedSpace(Transform t)
		{
			//IL_0006: 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_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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 val = ((Component)this).transform.worldToLocalMatrix * t.localToWorldMatrix;
			for (int i = 0; i < 16; i++)
			{
				float num = ((Matrix4x4)(ref val))[i];
				Matrix4x4 identity = Matrix4x4.identity;
				if (Mathf.Abs(num - ((Matrix4x4)(ref identity))[i]) > 0.001f)
				{
					return false;
				}
			}
			return true;
		}

		private void Update()
		{
			if (!Ready())
			{
				((Behaviour)this).enabled = false;
				return;
			}
			if (Settings.Blankets == null || !Settings.Blankets.Value || !Seen() || Broken())
			{
				Rest();
				return;
			}
			if (Time.time >= m_nextLook)
			{
				m_nextLook = Time.time + 0.1f;
				Look();
			}
			MeshRenderer look = (((Object)(object)m_wornRenderer != (Object)null && (Object)(object)m_wear.m_worn != (Object)(object)m_wear.m_new && m_wear.m_worn.activeInHierarchy) ? m_wornRenderer : m_newRenderer);
			int num = 0;
			for (int i = 0; i < 2; i++)
			{
				m_blankets[i].Tick(look);
				if (m_blankets[i].Showing)
				{
					num |= 1 << i;
				}
			}
			Show(num);
		}

		private bool Seen()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null));
			if ((Object)(object)val != (Object)null)
			{
				Vector3 val2 = val.position - ((Component)this).transform.position;
				return ((Vector3)(ref val2)).sqrMagnitude < 1600f;
			}
			return false;
		}

		private bool Broken()
		{
			if ((Object)(object)m_wear.m_broken != (Object)null && (Object)(object)m_wear.m_broken != (Object)(object)m_wear.m_new)
			{
				return m_wear.m_broken.activeInHierarchy;
			}
			return false;
		}

		private void Look()
		{
			//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_001b: 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_0037: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_009b: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.InverseTransformPoint(m_first.m_spawnPoint.position);
			Vector3 val2 = ((Component)this).transform.InverseTransformPoint(m_second.m_spawnPoint.position);
			Vector3 val3 = ((Component)this).transform.InverseTransformPoint(m_middle.position);
			Player val4 = null;
			Player val5 = null;
			Player val6 = null;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer == (Object)null || !((Character)allPlayer).InBed())
				{
					continue;
				}
				Vector3 val7 = ((Component)this).transform.InverseTransformPoint(((Component)allPlayer).transform.position);
				if (!(Mathf.Abs(val7.y - val3.y) > 0.6f))
				{
					if (Across(val7, val3) < 0.25f)
					{
						val6 = allPlayer;
					}
					else if (Across(val7, val) < 0.3f)
					{
						val4 = allPlayer;
					}
					else if (Across(val7, val2) < 0.3f)
					{
						val5 = allPlayer;
					}
				}
			}
			Cover[] array = new Cover[2];
			Player[] array2 = (Player[])(object)new Player[2];
			bool[] array3 = new bool[2];
			if ((Object)(object)val6 != (Object)null)
			{
				array[0] = new Cover
				{
					CentreX = val3.x - 0.15f,
					FootZ = 1.4f
				};
				array[1] = new Cover
				{
					CentreX = val3.x + 0.15f,
					FootZ = 1.4f,
					Lift = 0.015f
				};
				array2[0] = (array2[1] = val6);
				array3[0] = (array3[1] = true);
			}
			else
			{
				array[0] = new Cover
				{
					CentreX = val.x - 0.08f,
					FootZ = 1.4f,
					TuckSide = 1,
					TuckX = val3.x - 0.06f
				};
				array[1] = new Cover
				{
					CentreX = val2.x + 0.08f,
					FootZ = 1.4f,
					TuckSide = -1,
					TuckX = val3.x + 0.06f
				};
				array2[0] = val4;
				array2[1] = val5;
				array3[0] = (Object)(object)val4 != (Object)null;
				array3[1] = (Object)(object)val5 != (Object)null;
			}
			for (int i = 0; i < 2; i++)
			{
				m_blankets[i].Want(array3[i], array2[i], array[i], val3);
			}
		}

		private static float Across(Vector3 a, Vector3 b)
		{
			//IL_0000: 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_000d: 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_001a: 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)
			Vector2 val = new Vector2(a.x - b.x, a.z - b.z);
			return ((Vector2)(ref val)).magnitude;
		}

		private void Show(int mask)
		{
			if (mask == m_mask)
			{
				return;
			}
			m_mask = mask;
			foreach (var (val, model) in m_filters)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.sharedMesh = Blankets.Without(model, mask);
				}
			}
		}

		private void Rest()
		{
			if (m_blankets != null)
			{
				Blanket[] blankets = m_blankets;
				for (int i = 0; i < blankets.Length; i++)
				{
					blankets[i].Rest();
				}
			}
			Show(0);
		}

		public void Restore()
		{
			if (m_blankets != null)
			{
				Blanket[] blankets = m_blankets;
				for (int i = 0; i < blankets.Length; i++)
				{
					blankets[i].Destroy(now: true);
				}
			}
			m_blankets = null;
			m_mask = -1;
			Show(0);
		}

		private void OnDestroy()
		{
			if (m_blankets != null)
			{
				Blanket[] blankets = m_blankets;
				for (int i = 0; i < blankets.Length; i++)
				{
					blankets[i].Destroy(now: false);
				}
			}
		}
	}
	internal sealed class Blanket
	{
		private const float Gather = 0.25f;

		private const float GatherTime = 0.35f;

		private const float UnrollTime = 1.1f;

		private const float RollUpTime = 0.7f;

		private const float ReturnTime = 0.3f;

		private const float RollStart = 0.45f;

		private const float ReshapeTime = 1f;

		private const float LiftHeight = 0.2f;

		private const float RescanFirst = 2f;

		private const float Rescan = 6f;

		private const float RescanFirstFor = 8f;

		private const float SettleWait = 3f;

		private const float Underside = 0.004f;

		private const float ReshapeMean = 0.015f;

		private const float ReshapeFarthest = 0.1f;

		private readonly BedBlankets m_bed;

		private readonly int m_side;

		private readonly Sheet m_sheet;

		private readonly GameObject m_object;

		private readonly Mesh m_mesh;

		private readonly MeshRenderer m_renderer;

		private readonly Vector3[] m_from;

		private readonly Vector3[] m_to;

		private readonly Vector3[] m_now;

		private readonly Vector3[] m_laid;

		private readonly Vector3[] m_rolled;

		private readonly Vector3[] m_vertices;

		private readonly Vector3[] m_normals;

		private readonly Field m_body;

		private readonly Field m_shape;

		private readonly Field m_rollShape;

		private readonly float[] m_scratch;

		private float m_progress;

		private int m_direction;

		private bool m_reshaping;

		private float m_t;

		private Cover m_rollCover;

		private float m_rollStretch;

		private bool m_wanted;

		private Player m_player;

		private Cover m_cover;

		private Vector3 m_middle;

		private Measure m_measure;

		private float m_since;

		private float m_nextScan;

		private float m_nextSettle;

		private float m_lastHead = float.MaxValue;

		private Vector3 m_lastBody;

		private int m_still;

		private const float Slow = 1f;

		public string Report = "not measured yet";

		public float Stretch;

		public float TopZ;

		public string Reshaped = "";

		public bool Showing
		{
			get
			{
				if (!(m_progress > 0f))
				{
					return m_direction > 0;
				}
				return true;
			}
		}

		private bool IsOut
		{
			get
			{
				if (m_progress >= 1f)
				{
					return m_direction == 0;
				}
				return false;
			}
		}

		public string State
		{
			get
			{
				if (m_direction <= 0)
				{
					if (m_direction >= 0)
					{
						if (Showing)
						{
							if (!m_reshaping)
							{
								return "out";
							}
							return "reshaping";
						}
						return "in (the bed's fur)";
					}
					return $"going back ({m_progress:P0})";
				}
				return $"coming out ({m_progress:P0})";
			}
		}

		public Player Sleeper => m_player;

		public Field Shape => m_shape;

		public Field Body => m_body;

		public Vector3[] Now => m_now;

		public Sheet Sheet => m_sheet;

		public Blanket(BedBlankets bed, int side, Sheet sheet)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			m_bed = bed;
			m_side = side;
			m_sheet = sheet;
			int num = sheet.Rest.Length;
			m_from = (Vector3[])(object)new Vector3[num];
			m_to = (Vector3[])(object)new Vector3[num];
			m_laid = (Vector3[])(object)new Vector3[num];
			m_rolled = (Vector3[])(object)new Vector3[num];
			m_now = (Vector3[])sheet.Rest.Clone();
			m_vertices = (Vector3[])(object)new Vector3[num * 2];
			m_normals = (Vector3[])(object)new Vector3[num * 2];
			m_body = new Field(bed.Near.Ground);
			m_shape = new Field(bed.Near.Ground);
			m_rollShape = new Field(bed.Near.Ground);
			m_scratch = new float[m_shape.H.Length];
			Vector2[] array = (Vector2[])(object)new Vector2[num * 2];
			sheet.Uv.CopyTo(array, 0);
			sheet.Uv.CopyTo(array, num);
			int[] triangles = sheet.Triangles;
			int[] array2 = new int[triangles.Length * 2];
			triangles.CopyTo(array2, 0);
			for (int i = 0; i < triangles.Length; i += 3)
			{
				array2[triangles.Length + i] = triangles[i] + num;
				array2[triangles.Length + i + 1] = triangles[i + 2] + num;
				array2[triangles.Length + i + 2] = triangles[i + 1] + num;
			}
			m_mesh = new Mesh
			{
				name = "DoubleBed_blanket" + (side + 1)
			};
			m_mesh.MarkDynamic();
			Write(first: true, array, array2);
			m_object = new GameObject("DoubleBed_blanket" + (side + 1));
			m_object.SetActive(false);
			m_object.layer = ((Component)bed).gameObject.layer;
			m_object.transform.SetParent(((Component)bed).transform, false);
			m_object.AddComponent<MeshFilter>().sharedMesh = m_mesh;
			m_renderer = m_object.AddComponent<MeshRenderer>();
		}

		public void Want(bool wanted, Player player, Cover cover, Vector3 middle)
		{
			//IL_009e: 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)
			if (!wanted)
			{
				if (m_wanted)
				{
					m_wanted = false;
					m_player = null;
					m_measure?.Cancel();
					m_measure = null;
					GoBack();
				}
				return;
			}
			bool num = !m_wanted || (Object)(object)player != (Object)(object)m_player;
			bool flag = Mathf.Abs(cover.CentreX - m_cover.CentreX) > 0.01f || cover.TuckSide != m_cover.TuckSide;
			m_wanted = true;
			m_player = player;
			m_cover = cover;
			m_middle = middle;
			if (num)
			{
				m_measure?.Cancel();
				m_measure = null;
				m_since = Time.time;
				m_still = 0;
				m_lastHead = float.MaxValue;
				m_nextScan = 0f;
			}
			else if (flag)
			{
				m_nextScan = 0f;
			}
		}

		public void Tick(MeshRenderer look)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (m_wanted)
			{
				if (m_measure == null && Time.time >= m_nextScan && Settled())
				{
					m_measure = Measure.Start(m_player, ((Component)m_bed).transform, m_body, m_middle);
				}
				if (m_measure != null && m_measure.Poll())
				{
					Lay(m_measure);
					m_measure = null;
					m_nextScan = Time.time + ((Time.time - m_since < 11f) ? 2f : 6f);
				}
			}
			Animate(look);
		}

		private bool Settled()
		{
			//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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0097: 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_00ca: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_player == (Object)null || Time.time - m_since > 3f)
			{
				return true;
			}
			if (Time.time < m_nextSettle)
			{
				return false;
			}
			m_nextSettle = Time.time + 0.25f;
			Transform val = Measure.Bone(m_player, "Head");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Vector3 val2 = ((Component)m_bed).transform.InverseTransformPoint(val.position);
			Vector3 val3 = ((Component)m_bed).transform.InverseTransformPoint(((Component)m_player).transform.position);
			bool flag = val2.y < m_middle.y + 0.5f;
			int num;
			if (Mathf.Abs(val2.y - m_lastHead) < 0.01f)
			{
				Vector3 val4 = val3 - m_lastBody;
				num = ((((Vector3)(ref val4)).sqrMagnitude < 0.0001f) ? 1 : 0);
			}
			else
			{
				num = 0;
			}
			bool flag2 = (byte)num != 0;
			m_lastHead = val2.y;
			m_lastBody = val3;
			m_still = ((flag && flag2) ? (m_still + 1) : 0);
			return m_still >= 2;
		}

		private void Lay(Measure measure)
		{
			Field ground = m_bed.Near.Ground;
			Cover c = m_cover;
			c.TopZ = ((IsOut && Mathf.Abs(measure.TopZ - TopZ) < 0.04f) ? TopZ : measure.TopZ);
			Drape.Shape(ground, m_body, m_shape, m_scratch);
			Drape.Tuck(m_shape, in c);
			Stretch = Drape.Lay(m_sheet, m_shape, in c, m_laid);
			TopZ = c.TopZ;
			Report = measure.Report;
			if (!IsOut)
			{
				Keep(c);
				m_direction = 1;
				return;
			}
			Moved(m_laid, m_now, out var mean, out var farthest);
			if (m_reshaping || !(mean < 0.015f) || !(farthest < 0.1f))
			{
				Reshaped = $"last reshaped at {Time.time:F0} s ({mean * 100f:F1} cm on average, {farthest * 100f:F0} at most)";
				m_now.CopyTo(m_from, 0);
				Keep(c);
				m_reshaping = true;
				m_t = 0f;
			}
		}

		private void Keep(Cover cover)
		{
			m_laid.CopyTo(m_to, 0);
			m_rollShape.CopyFrom(m_shape);
			m_rollCover = cover;
			m_rollStretch = Stretch;
		}

		private void GoBack()
		{
			if (Showing)
			{
				if (m_reshaping)
				{
					m_now.CopyTo(m_to, 0);
					m_reshaping = false;
				}
				m_direction = -1;
			}
		}

		private static void Moved(Vector3[] a, Vector3[] b, out float mean, out float farthest)
		{
			//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_001e: 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)
			float num = 0f;
			float num2 = 0f;
			for (int i = 0; i < a.Length; i++)
			{
				Vector3 val = a[i] - b[i];
				float magnitude = ((Vector3)(ref val)).magnitude;
				num += magnitude;
				num2 = Mathf.Max(num2, magnitude);
			}
			mean = num / (float)a.Length;
			farthest = num2;
		}

		private void Animate(MeshRenderer look)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			if (!Showing)
			{
				if (m_object.activeSelf)
				{
					m_object.SetActive(false);
				}
				return;
			}
			if ((Object)(object)((Renderer)m_renderer).sharedMaterial != (Object)(object)((Renderer)look).sharedMaterial)
			{
				((Renderer)m_renderer).sharedMaterial = ((Renderer)look).sharedMaterial;
				((Renderer)m_renderer).shadowCastingMode = ((Renderer)look).shadowCastingMode;
				((Renderer)m_renderer).receiveShadows = ((Renderer)look).receiveShadows;
				m_object.layer = ((Component)look).gameObject.layer;
			}
			if (!m_object.activeSelf)
			{
				m_object.SetActive(true);
			}
			if (m_direction != 0)
			{
				bool flag = m_progress < 0.25f || (m_direction < 0 && m_progress <= 0.25f);
				float num = ((m_direction <= 0) ? (flag ? 0.3f : 0.7f) : (flag ? 0.35f : 1.1f));
				float num2 = (flag ? 0.25f : 0.75f);
				m_progress = Mathf.Clamp01(m_progress + (float)m_direction * Time.deltaTime * num2 / (num * 1f));
				Pose();
				Write(first: false, null, null);
				if (m_direction > 0 && m_progress >= 1f)
				{
					m_direction = 0;
				}
				else if (m_direction < 0 && m_progress <= 0f)
				{
					m_direction = 0;
					m_object.SetActive(false);
				}
			}
			else if (m_reshaping)
			{
				m_t = Mathf.Min(1f, m_t + Time.deltaTime / 1f);
				float num3 = Mathf.SmoothStep(0f, 1f, m_t);
				for (int i = 0; i < m_now.Length; i++)
				{
					m_now[i] = Vector3.LerpUnclamped(m_from[i], m_to[i], num3);
				}
				Write(first: false, null, null);
				if (m_t >= 1f)
				{
					m_reshaping = false;
				}
			}
		}

		private void Pose()
		{
			//IL_005a: 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)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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)
			float num = (m_sheet.MaxZ - m_sheet.MinZ) * m_rollStretch;
			float num2 = Mathf.Min(0.45f, num);
			if (m_progress <= 0.25f)
			{
				float num3 = m_progress / 0.25f;
				float num4 = Mathf.SmoothStep(0f, 1f, num3);
				Vector3 val = Vector3.up * (Mathf.Sin(num3 * (float)Math.PI) * 0.2f);
				Drape.Roll(m_sheet, m_rollShape, in m_rollCover, m_rollStretch, m_to, num2, m_rolled);
				for (int i = 0; i < m_now.Length; i++)
				{
					m_now[i] = Vector3.LerpUnclamped(m_sheet.Rest[i], m_rolled[i], num4) + val;
				}
			}
			else
			{
				float num5 = Mathf.SmoothStep(0f, 1f, (m_progress - 0.25f) / 0.75f);
				Drape.Roll(m_sheet, m_rollShape, in m_rollCover, m_rollStretch, m_to, num2 + (num - num2) * num5, m_now);
			}
		}

		public void Rest()
		{
			m_measure?.Cancel();
			m_measure = null;
			m_wanted = false;
			m_player = null;
			if (Showing)
			{
				m_progress = 0f;
				m_direction = 0;
				m_reshaping = false;
				m_sheet.Rest.CopyTo(m_now, 0);
				Write(first: false, null, null);
				m_object.SetActive(false);
			}
		}

		private void Write(bool first, Vector2[] uv, int[] triangles)
		{
			//IL_0014: 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_0054: 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_0066: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_009f: 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_00a6: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0130: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			int num = m_now.Length;
			for (int i = 0; i < num; i++)
			{
				m_normals[i] = Vector3.zero;
			}
			int[] triangles2 = m_sheet.Triangles;
			for (int j = 0; j < triangles2.Length; j += 3)
			{
				int num2 = triangles2[j];
				int num3 = triangles2[j + 1];
				int num4 = triangles2[j + 2];
				Vector3 val = Vector3.Cross(m_now[num3] - m_now[num2], m_now[num4] - m_now[num2]);
				ref Vector3 reference = ref m_normals[num2];
				reference += val;
				ref Vector3 reference2 = ref m_normals[num3];
				reference2 += val;
				ref Vector3 reference3 = ref m_normals[num4];
				reference3 += val;
			}
			for (int k = 0; k < num; k++)
			{
				Vector3 val2 = ((((Vector3)(ref m_normals[k])).sqrMagnitude > 1E-12f) ? ((Vector3)(ref m_normals[k])).normalized : Vector3.up);
				m_normals[k] = val2;
				m_normals[num + k] = -val2;
				m_vertices[k] = m_now[k];
				m_vertices[num + k] = m_now[k] - val2 * 0.004f;
			}
			m_mesh.vertices = m_vertices;
			m_mesh.normals = m_normals;
			if (first)
			{
				m_mesh.uv = uv;
				m_mesh.triangles = triangles;
			}
			m_mesh.RecalculateTangents();
			m_mesh.RecalculateBounds();
		}

		public void Destroy(bool now)
		{
			m_measure?.Cancel();
			m_measure = null;
			if (now)
			{
				if ((Object)(object)m_object != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)m_object);
				}
				Object.DestroyImmediate((Object)(object)m_mesh);
			}
			else
			{
				if ((Object)(object)m_object != (Object)null)
				{
					Object.Destroy((Object)(object)m_object);
				}
				Object.Destroy((Object)(object)m_mesh);
			}
		}

		public override string ToString()
		{
			return string.Format("side {0}'s fur: {1}{2}", m_side + 1, State, ((Object)(object)m_player != (Object)null) ? (", over " + m_player.GetPlayerName()) : (m_wanted ? ", over nobody (forced)" : "")) + (Showing ? string.Format(", chest at z {0:F2}, stretched {1:F2}{2}", TopZ, Stretch, (Reshaped.Length > 0) ? (", " + Reshaped) : "") : "");
		}
	}
	internal sealed class Measure
	{
		private const float ArmorRoom = 0.04f;

		private const float Wait = 1f;

		private static readonly (string From, string To, float Radius)[] s_skeleton = new(string, string, float)[16]
		{
			("Hips", "Spine", 0.14f),
			("Spine", "Spine1", 0.13f),
			("Spine1", "Spine2", 0.13f),
			("Spine2", "Neck", 0.14f),
			("LeftUpLeg", "LeftLeg", 0.08f),
			("LeftLeg", "LeftFoot", 0.06f),
			("LeftFoot", "LeftToeBase", 0.045f),
			("RightUpLeg", "RightLeg", 0.08f),
			("RightLeg", "RightFoot", 0.06f),
			("RightFoot", "RightToeBase", 0.045f),
			("LeftArm", "LeftForeArm", 0.055f),
			("LeftForeArm", "LeftHand", 0.045f),
			("LeftHand", "LeftHandMiddle3_end", 0.04f),
			("RightArm", "RightForeArm", 0.055f),
			("RightForeArm", "RightHand", 0.045f),
			("RightHand", "RightHandMiddle3_end", 0.04f)
		};

		private static readonly Dictionary<SkinnedMeshRenderer, (Target Target, int Users)> s_opened = new Dictionary<SkinnedMeshRenderer, (Target, int)>();

		private static Mesh s_baked;

		private static readonly List<Vector3> s_points = new List<Vector3>();

		private readonly Field m_body;

		private readonly Transform m_bed;

		private readonly Dictionary<string, Transform> m_bones = new Dictionary<string, Transform>();

		private readonly List<SkinnedMeshRenderer> m_waiting = new List<SkinnedMeshRenderer>();

		private readonly StringBuilder m_report = new StringBuilder();

		private float m_neckZ = float.MinValue;

		private float m_topY = float.MaxValue;

		private const float Highest = 0.6f;

		private int m_pending;

		private float m_deadline;

		private bool m_closed;

		private bool m_skeletonDone;

		public float TopZ;

		private const float NearBones = 0.35f;

		private const float SmallestPiece = 0.1f;

		private const float LargestPiece = 3f;

		private List<(Vector3 A, Vector3 B)> m_boneSegments;

		public string Report => m_report.ToString();

		private Measure(Field body, Transform bed)
		{
			m_body = body;
			m_bed = bed;
		}

		public static Transform Bone(Player player, string name)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)((Character)player).m_visual == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Character)player).m_visual.GetComponentsInChildren<Transform>();
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == name)
				{
					return val;
				}
			}
			return null;
		}

		public static Measure Start(Player player, Transform bed, Field body, Vector3 spot)
		{
			//IL_0000: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			float z = spot.z;
			Measure measure = new Measure(body, bed)
			{
				TopZ = z - 0.48f,
				m_topY = spot.y + 0.6f
			};
			body.Fill(float.MinValue);
			if ((Object)(object)player == (Object)null || (Object)(object)((Character)player).m_visual == (Object)null)
			{
				measure.m_report.Append("nobody: flat on the bed");
				measure.m_closed = true;
				return measure;
			}
			Transform[] componentsInChildren = ((Character)player).m_visual.GetComponentsInChildren<Transform>();
			foreach (Transform val in componentsInChildren)
			{
				if (!measure.m_bones.ContainsKey(((Object)val).name))
				{
					measure.m_bones[((Object)val).name] = val;
				}
			}
			if (measure.m_bones.TryGetValue("Neck", out var value))
			{
				measure.m_neckZ = measure.InBed(value.position).z;
			}
			if (measure.m_bones.TryGetValue("LeftArm", out var value2) && measure.m_bones.TryGetValue("RightArm", out var value3))
			{
				measure.TopZ = Mathf.Clamp((measure.InBed(value2.position).z + measure.InBed(value3.position).z) * 0.5f + 0.1f, z - 0.85f, z - 0.2f);
			}
			VisEquipment visEquipment = ((Humanoid)player).m_visEquipment;
			List<Transform> list = new List<Transform>();
			if ((Object)(object)visEquipment != (Object)null)
			{
				GameObject[] array = (GameObject[])(object)new GameObject[3] { visEquipment.m_hairItemInstance, visEquipment.m_beardItemInstance, visEquipment.m_helmetItemInstance };
				foreach (GameObject val2 in array)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						list.Add(val2.transform);
					}
				}
			}
			Renderer[] componentsInChildren2 = ((Character)player).m_visual.GetComponentsInChildren<Renderer>();
			foreach (Renderer renderer in componentsInChildren2)
			{
				if (!renderer.enabled || !((Component)renderer).gameObject.activeInHierarchy || list.Exists((Transform t) => ((Component)renderer).transform.IsChildOf(t)))
				{
					continue;
				}
				Renderer obj = renderer;
				SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((obj is SkinnedMeshRenderer) ? obj : null);
				if (val3 != null)
				{
					measure.Skinned(val3);
					continue;
				}
				Renderer obj2 = renderer;
				MeshRenderer val4 = (MeshRenderer)(object)((obj2 is MeshRenderer) ? obj2 : null);
				if (val4 != null)
				{
					measure.Plain(val4);
				}
			}
			measure.m_deadline = Time.time + 1f;
			if (measure.m_pending == 0)
			{
				measure.m_closed = true;
			}
			return measure;
		}

		private Transform BoneOrNull(string name)
		{
			if (!m_bones.TryGetValue(name, out var value))
			{
				return null;
			}
			return value;
		}

		private Vector3 InBed(Vector3 world)
		{
			//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)
			return m_bed.InverseTransformPoint(world);
		}

		private bool LeftOut(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!(p.z < m_neckZ))
			{
				return p.y > m_topY;
			}
			return true;
		}

		private void Skinned(SkinnedMeshRenderer skinned)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			Mesh sharedMesh = skinned.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				return;
			}
			if (sharedMesh.isReadable)
			{
				if ((Object)(object)s_baked == (Object)null)
				{
					s_baked = new Mesh
					{
						name = "DoubleBed_blanket_measure"
					};
				}
				skinned.BakeMesh(s_baked, true);
				s_baked.GetVertices(s_points);
				Points(skinned, s_points, "skinned here");
			}
			else if (!((Renderer)skinned).isVisible)
			{
				Skeleton(((Object)skinned).name, "not drawn now (hidden, or out of view)");
			}
			else if (SystemInfo.supportsAsyncGPUReadback)
			{
				Open(skinned);
				m_waiting.Add(skinned);
				m_pending++;
			}
			else
			{
				Skeleton(((Object)skinned).name, "cannot be read");
			}
		}

		private void Plain(MeshRenderer plain)
		{
			//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)
			//IL_0055: 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_0064: 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_006f: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_00b5: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result t