Decompiled source of ModularLadders v1.0.0

BepInEx/plugins/ModularLadders/ModularLadders.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 Stigi
{
	internal static class Icons
	{
		public sealed class Pose
		{
			public string Suffix;

			public float Yaw;

			public float Pitch;

			public float Roll;

			public float Segments = 1f;
		}

		public static Sprite Load(string prefab)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0090: 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)
			try
			{
				using Stream stream = typeof(Icons).Assembly.GetManifestResourceStream("Stigi.icons." + prefab + ".png");
				if (stream == null)
				{
					return null;
				}
				byte[] array = new byte[stream.Length];
				stream.Read(array, 0, array.Length);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					name = prefab + "_icon"
				};
				if (!ImageConversion.LoadImage(val, array))
				{
					return null;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			}
			catch (Exception ex)
			{
				StigiPlugin.Log.LogWarning((object)("Icon " + prefab + ": " + ex.Message));
				return null;
			}
		}

		public static void Render(GameObject prefab, string path, int size, Pose pose)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0043: 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_0059: Expected O, but got Unknown
			//IL_064e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: 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)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Expected O, but got Unknown
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			int num = FreeLayer();
			GameObject val = new GameObject("StigiIconRig");
			List<Light> list = new List<Light>();
			bool fog = RenderSettings.fog;
			AmbientMode ambientMode = RenderSettings.ambientMode;
			Color ambientLight = RenderSettings.ambientLight;
			RenderTexture val2 = null;
			try
			{
				val.transform.position = new Vector3(0f, 6000f, 0f);
				GameObject val3 = new GameObject("model");
				val3.transform.SetParent(val.transform, false);
				WearNTear component = prefab.GetComponent<WearNTear>();
				GameObject val4 = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new : prefab);
				int num2 = Mathf.Max(1, Mathf.CeilToInt(pose.Segments));
				for (int i = 0; i < num2; i++)
				{
					GameObject obj = Object.Instantiate<GameObject>(val4, val3.transform, false);
					obj.SetActive(true);
					obj.transform.localPosition = Vector3.up * (2f * (float)i);
					Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(true);
					for (int j = 0; j < componentsInChildren.Length; j++)
					{
						((Component)componentsInChildren[j]).gameObject.layer = num;
					}
				}
				foreach (Transform item in val3.transform)
				{
					item.localPosition -= Vector3.up * (2f * pose.Segments / 2f);
				}
				val3.transform.localRotation = Quaternion.AngleAxis(pose.Roll, Vector3.forward) * Quaternion.Euler(pose.Pitch, pose.Yaw, 0f);
				Renderer[] componentsInChildren2 = val3.GetComponentsInChildren<Renderer>(true);
				Bounds bounds = componentsInChildren2[0].bounds;
				Renderer[] array = componentsInChildren2;
				foreach (Renderer val6 in array)
				{
					((Bounds)(ref bounds)).Encapsulate(val6.bounds);
				}
				GameObject val7 = new GameObject("cam");
				val7.transform.SetParent(val.transform, false);
				Camera val8 = val7.AddComponent<Camera>();
				((Behaviour)val8).enabled = false;
				val8.cullingMask = 1 << num;
				val8.clearFlags = (CameraClearFlags)2;
				val8.fieldOfView = 12f;
				val8.allowHDR = false;
				val8.allowMSAA = true;
				float num3 = Mathf.Max(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.y) * 1.06f / Mathf.Tan(val8.fieldOfView * 0.5f * ((float)Math.PI / 180f)) + ((Bounds)(ref bounds)).extents.z;
				val7.transform.position = ((Bounds)(ref bounds)).center - Vector3.forward * num3;
				val7.transform.rotation = Quaternion.LookRotation(Vector3.forward);
				val8.nearClipPlane = Mathf.Max(0.05f, num3 - ((Bounds)(ref bounds)).extents.z * 3f);
				val8.farClipPlane = num3 + ((Bounds)(ref bounds)).extents.z * 3f + 1f;
				Light[] array2 = Object.FindObjectsByType<Light>((FindObjectsSortMode)0);
				foreach (Light val9 in array2)
				{
					if (((Behaviour)val9).enabled && (val9.cullingMask & (1 << num)) != 0)
					{
						list.Add(val9);
						((Behaviour)val9).enabled = false;
					}
				}
				AddLight(val.transform, Quaternion.Euler(35f, 35f, 0f), 1.5f, new Color(1f, 0.96f, 0.9f), num);
				AddLight(val.transform, Quaternion.Euler(10f, -120f, 0f), 0.45f, new Color(0.85f, 0.9f, 1f), num);
				RenderSettings.fog = false;
				RenderSettings.ambientMode = (AmbientMode)3;
				RenderSettings.ambientLight = new Color(0.55f, 0.53f, 0.5f);
				int num4 = size * 4;
				val2 = (val8.targetTexture = RenderTexture.GetTemporary(num4, num4, 24, (RenderTextureFormat)0, (RenderTextureReadWrite)2));
				Color[] array3 = Grab(val8, val2, Color.black);
				Color[] array4 = Grab(val8, val2, Color.white);
				val8.targetTexture = null;
				Texture2D val10 = new Texture2D(size, size, (TextureFormat)4, false);
				Color[] array5 = (Color[])(object)new Color[size * size];
				for (int k = 0; k < size; k++)
				{
					for (int l = 0; l < size; l++)
					{
						float num5 = 0f;
						float num6 = 0f;
						float num7 = 0f;
						float num8 = 0f;
						for (int m = 0; m < 4; m++)
						{
							for (int n = 0; n < 4; n++)
							{
								int num9 = (k * 4 + m) * num4 + (l * 4 + n);
								Color val11 = array3[num9];
								Color val12 = array4[num9];
								float num10 = Mathf.Clamp01(1f - (val12.r - val11.r + (val12.g - val11.g) + (val12.b - val11.b)) / 3f);
								num5 += val11.r;
								num6 += val11.g;
								num7 += val11.b;
								num8 += num10;
							}
						}
						num8 /= 16f;
						array5[k * size + l] = ((num8 > 0.004f) ? new Color(Mathf.Clamp01(num5 / 16f / num8), Mathf.Clamp01(num6 / 16f / num8), Mathf.Clamp01(num7 / 16f / num8), num8) : new Color(0f, 0f, 0f, 0f));
					}
				}
				val10.SetPixels(array5);
				val10.Apply();
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val10));
				Object.Destroy((Object)(object)val10);
			}
			finally
			{
				foreach (Light item2 in list)
				{
					if ((Object)(object)item2 != (Object)null)
					{
						((Behaviour)item2).enabled = true;
					}
				}
				RenderSettings.fog = fog;
				RenderSettings.ambientMode = ambientMode;
				RenderSettings.ambientLight = ambientLight;
				if ((Object)(object)val2 != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val2);
				}
				Object.DestroyImmediate((Object)(object)val);
			}
		}

		private static Color[] Grab(Camera cam, RenderTexture rt, Color background)
		{
			//IL_0001: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			cam.backgroundColor = background;
			cam.Render();
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = rt;
			Texture2D val = new Texture2D(((Texture)rt).width, ((Texture)rt).height, (TextureFormat)4, false);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)rt).width, (float)((Texture)rt).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			Color[] pixels = val.GetPixels();
			Object.Destroy((Object)val);
			return pixels;
		}

		private static void AddLight(Transform parent, Quaternion rot, float intensity, Color color, int layer)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("light");
			val.transform.SetParent(parent, false);
			val.transform.rotation = rot;
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)1;
			obj.intensity = intensity;
			obj.color = color;
			obj.shadows = (LightShadows)0;
			obj.cullingMask = 1 << layer;
		}

		private static int FreeLayer()
		{
			for (int num = 31; num > 8; num--)
			{
				if (string.IsNullOrEmpty(LayerMask.LayerToName(num)))
				{
					return num;
				}
			}
			return 31;
		}
	}
	internal static class LadderMesh
	{
		public sealed class Style
		{
			public int RailSides = 8;

			public bool Hewn = true;

			public float RailRadius = 0.072f;

			public float RailWobble = 0.006f;

			public float RailJitter = 0.1f;

			public int RungSides = 7;

			public float RungRadius = 0.036f;

			public float RungInset = 0.5f;

			public Rect RailUV = new Rect(0f, 0f, 0.5f, 1f);

			public Rect RungUV = new Rect(0.5f, 0f, 0.5f, 1f);

			public Rect? EndUV;

			public float VPerMeter = 1f;

			public bool Collars;

			public bool NoRails;

			public int Seed = 1;
		}

		private sealed class Builder
		{
			private readonly List<Vector3> _v = new List<Vector3>();

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

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

			private readonly List<int>[] _tris;

			public Builder(int submeshes)
			{
				_tris = new List<int>[submeshes];
				for (int i = 0; i < submeshes; i++)
				{
					_tris[i] = new List<int>();
				}
			}

			public void Tube(Matrix4x4 m, float length, int rings, int sides, bool flat, Func<int, int, float> radius, Func<int, float, Vector2> offset, Rect uv, float vPerMeter, float vOff, Rect? cap, int sub)
			{
				//IL_0029: 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_002e: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: 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_0291: Unknown result type (might be due to invalid IL or missing references)
				//IL_0296: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a8: 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_02be: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e7: 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_00ce: 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_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: 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_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_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: 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_010a: 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_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: 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_0123: 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_0137: 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_0392: Unknown result type (might be due to invalid IL or missing references)
				//IL_0397: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: 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_01da: Unknown result type (might be due to invalid IL or missing references)
				//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ed: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fb: 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_020c: 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_03b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0404: Unknown result type (might be due to invalid IL or missing references)
				//IL_0405: Unknown result type (might be due to invalid IL or missing references)
				//IL_0407: Unknown result type (might be due to invalid IL or missing references)
				//IL_040b: Unknown result type (might be due to invalid IL or missing references)
				//IL_042a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0430: Unknown result type (might be due to invalid IL or missing references)
				//IL_0435: Unknown result type (might be due to invalid IL or missing references)
				//IL_0439: Unknown result type (might be due to invalid IL or missing references)
				//IL_045b: Unknown result type (might be due to invalid IL or missing references)
				//IL_047b: Unknown result type (might be due to invalid IL or missing references)
				Vector3[,] array = new Vector3[rings, sides];
				for (int i = 0; i < rings; i++)
				{
					float num = length * (float)i / (float)(rings - 1);
					Vector2 val = offset?.Invoke(i, num) ?? Vector2.zero;
					for (int j = 0; j < sides; j++)
					{
						float num2 = (float)Math.PI * 2f * (float)j / (float)sides;
						float num3 = radius(i, j);
						array[i, j] = new Vector3(Mathf.Cos(num2) * num3 + val.x, num, Mathf.Sin(num2) * num3 + val.y);
					}
				}
				List<int> list = _tris[sub];
				if (flat)
				{
					for (int k = 0; k < rings - 1; k++)
					{
						for (int l = 0; l < sides; l++)
						{
							int num4 = (l + 1) % sides;
							Vector3 val2 = array[k, l];
							Vector3 val3 = array[k, num4];
							Vector3 val4 = array[k + 1, num4];
							Vector3 val5 = array[k + 1, l];
							Vector3 val6 = Vector3.Cross(val5 - val2, val3 - val2);
							Vector3 val7 = ((Vector3)(ref val6)).normalized;
							if (Vector3.Dot(val7, new Vector3(val2.x + val3.x, 0f, val2.z + val3.z)) < 0f)
							{
								val7 = -val7;
							}
							int count = _v.Count;
							float num5 = ((Rect)(ref uv)).xMin + ((Rect)(ref uv)).width * (float)l / (float)sides;
							float num6 = ((Rect)(ref uv)).xMin + ((Rect)(ref uv)).width * (float)(l + 1) / (float)sides;
							Add(m, val2, val7, new Vector2(num5, vOff + val2.y * vPerMeter));
							Add(m, val3, val7, new Vector2(num6, vOff + val3.y * vPerMeter));
							Add(m, val4, val7, new Vector2(num6, vOff + val4.y * vPerMeter));
							Add(m, val5, val7, new Vector2(num5, vOff + val5.y * vPerMeter));
							list.Add(count);
							list.Add(count + 3);
							list.Add(count + 2);
							list.Add(count);
							list.Add(count + 2);
							list.Add(count + 1);
						}
					}
				}
				else
				{
					int count2 = _v.Count;
					for (int n = 0; n < rings; n++)
					{
						for (int num7 = 0; num7 <= sides; num7++)
						{
							Vector3 val8 = array[n, num7 % sides];
							float num8 = (float)Math.PI * 2f * (float)num7 / (float)sides;
							Add(m, val8, new Vector3(Mathf.Cos(num8), 0f, Mathf.Sin(num8)), new Vector2(((Rect)(ref uv)).xMin + ((Rect)(ref uv)).width * (float)num7 / (float)sides, vOff + val8.y * vPerMeter));
						}
					}
					int num9 = sides + 1;
					for (int num10 = 0; num10 < rings - 1; num10++)
					{
						for (int num11 = 0; num11 < sides; num11++)
						{
							int num12 = count2 + num10 * num9 + num11;
							int item = num12 + 1;
							int num13 = num12 + num9;
							int item2 = num13 + 1;
							list.Add(num12);
							list.Add(num13);
							list.Add(item2);
							list.Add(num12);
							list.Add(item2);
							list.Add(item);
						}
					}
				}
				if (!cap.HasValue)
				{
					return;
				}
				Rect value = cap.Value;
				for (int num14 = 0; num14 < 2; num14++)
				{
					int num15 = ((num14 != 0) ? (rings - 1) : 0);
					Vector3 n2 = ((num14 == 0) ? Vector3.down : Vector3.up);
					Vector3 val9 = Vector3.zero;
					for (int num16 = 0; num16 < sides; num16++)
					{
						val9 += array[num15, num16];
					}
					val9 /= (float)sides;
					int count3 = _v.Count;
					Add(m, val9, n2, ((Rect)(ref value)).center);
					for (int num17 = 0; num17 < sides; num17++)
					{
						float num18 = (float)Math.PI * 2f * (float)num17 / (float)sides;
						Add(m, array[num15, num17], n2, new Vector2(((Rect)(ref value)).center.x + Mathf.Cos(num18) * ((Rect)(ref value)).width / 2f, ((Rect)(ref value)).center.y + Mathf.Sin(num18) * ((Rect)(ref value)).height / 2f));
					}
					for (int num19 = 0; num19 < sides; num19++)
					{
						int item3 = count3 + 1 + num19;
						int item4 = count3 + 1 + (num19 + 1) % sides;
						if (num14 == 0)
						{
							list.Add(count3);
							list.Add(item3);
							list.Add(item4);
						}
						else
						{
							list.Add(count3);
							list.Add(item4);
							list.Add(item3);
						}
					}
				}
			}

			private void Add(Matrix4x4 m, Vector3 p, Vector3 n, Vector2 uv)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: 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_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: 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)
				_v.Add(((Matrix4x4)(ref m)).MultiplyPoint3x4(p));
				List<Vector3> n2 = _n;
				Vector3 val = ((Matrix4x4)(ref m)).MultiplyVector(n);
				n2.Add(((Vector3)(ref val)).normalized);
				_uv.Add(uv);
			}

			public Mesh ToMesh(string name)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				Mesh val = new Mesh
				{
					name = name
				};
				if (_v.Count > 65000)
				{
					val.indexFormat = (IndexFormat)1;
				}
				val.SetVertices(_v);
				val.SetNormals(_n);
				val.SetUVs(0, _uv);
				val.subMeshCount = _tris.Length;
				for (int i = 0; i < _tris.Length; i++)
				{
					val.SetTriangles(_tris[i], i);
				}
				val.RecalculateTangents();
				val.RecalculateBounds();
				return val;
			}
		}

		public const float Height = 2f;

		public const float Span = 0.62f;

		public const float RungSpacing = 0.4f;

		public static Mesh Build(Style s, bool broken, string name)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			Builder builder = new Builder((!s.Collars) ? 1 : 2);
			Random random = new Random(s.Seed);
			for (int i = 0; i < ((!s.NoRails) ? 2 : 0); i++)
			{
				float num = ((i == 0) ? (-1f) : 1f) * 0.62f / 2f;
				float num2 = (float)random.NextDouble() * 360f / (float)s.RailSides;
				float phaseA = (float)random.NextDouble() * (float)Math.PI * 2f;
				float phaseB = (float)random.NextDouble() * (float)Math.PI * 2f;
				float[] jit = new float[8 * s.RailSides];
				for (int j = 0; j < jit.Length; j++)
				{
					jit[j] = (float)(random.NextDouble() * 2.0 - 1.0);
				}
				float vOff = (float)random.NextDouble();
				Matrix4x4 m = Matrix4x4.TRS(new Vector3(num, 0f, 0f), Quaternion.Euler(0f, num2, 0f), Vector3.one);
				builder.Tube(m, 2f, 9, s.RailSides, s.Hewn, delegate(int r, int k)
				{
					float num16 = ((s.Hewn && k % 2 == 1) ? 0.84f : 1f);
					return s.RailRadius * num16 * (1f + s.RailJitter * jit[r % 8 * s.RailSides + k]);
				}, (int r, float y) => new Vector2(s.RailWobble * Mathf.Sin((float)Math.PI * y + phaseA), s.RailWobble * 0.6f * Mathf.Sin((float)Math.PI * y + phaseB)), s.RailUV, s.VPerMeter, vOff, (Rect)(((??)s.EndUV) ?? s.RailUV), 0);
			}
			int num3 = Mathf.RoundToInt(5f);
			int num4 = (broken ? (num3 / 2) : (-1));
			float num5 = 0.62f + 2f * s.RailRadius * s.RungInset;
			for (int num6 = 0; num6 < num3; num6++)
			{
				float num7 = 0.4f * ((float)num6 + 0.5f);
				float num8 = (float)(random.NextDouble() * 2.0 - 1.0) * 1.6f;
				float num9 = (float)(random.NextDouble() * 2.0 - 1.0) * 1.2f;
				float num10 = (float)random.NextDouble() * 360f;
				float rr = s.RungRadius * (0.92f + 0.16f * (float)random.NextDouble());
				float vOff2 = (float)random.NextDouble();
				float[] jit2 = new float[5 * s.RungSides];
				for (int num11 = 0; num11 < jit2.Length; num11++)
				{
					jit2[num11] = (float)(random.NextDouble() * 2.0 - 1.0);
				}
				Func<int, int, float> radius = (int r, int k) => rr * (1f + 0.16f * Mathf.Sin((float)Math.PI * (float)r / 4f)) * (1f + 0.07f * jit2[r * s.RungSides + k]);
				Quaternion val = Quaternion.Euler(0f, num9, num8) * Quaternion.Euler(0f, 0f, -90f) * Quaternion.Euler(0f, num10, 0f);
				if (num6 != num4)
				{
					Matrix4x4 m2 = Matrix4x4.TRS(new Vector3(0f, num7, 0f), val, Vector3.one) * Matrix4x4.Translate(new Vector3(0f, (0f - num5) / 2f, 0f));
					builder.Tube(m2, num5, 5, s.RungSides, flat: false, radius, null, s.RungUV, s.VPerMeter, vOff2, (Rect)(((??)s.EndUV) ?? s.RungUV), 0);
				}
				else
				{
					float num12 = s.RailRadius * (1f + s.RungInset) + 0.07f;
					for (int num13 = 0; num13 < 2; num13++)
					{
						float num14 = ((num13 == 0) ? ((0f - num5) / 2f) : (num5 / 2f - num12));
						Matrix4x4 m3 = Matrix4x4.TRS(new Vector3(0f, num7 - 0.01f * (float)((num13 == 0) ? 1 : (-1)), 0f), val, Vector3.one) * Matrix4x4.Translate(new Vector3(0f, num14, 0f));
						builder.Tube(m3, num12, 3, s.RungSides, flat: false, (int r, int k) => rr * (1f + 0.07f * jit2[r * s.RungSides + k]), null, s.RungUV, s.VPerMeter, vOff2, (Rect)(((??)s.EndUV) ?? s.RungUV), 0);
					}
				}
				if (!s.Collars)
				{
					continue;
				}
				for (int num15 = 0; num15 < 2; num15++)
				{
					Matrix4x4 m4 = Matrix4x4.Translate(new Vector3(((num15 == 0) ? (-1f) : 1f) * 0.62f / 2f, num7 - 0.035f, 0f));
					builder.Tube(m4, 0.07f, 2, 8, flat: true, (Func<int, int, float>)((int r, int k) => s.RailRadius * (1.12f + s.RailJitter)), (Func<int, float, Vector2>)null, new Rect(0f, 0f, 1f, 1f), 1f, 0f, (Rect?)new Rect(0f, 0f, 1f, 1f), 1);
				}
			}
			return builder.ToMesh(name);
		}
	}
	public class LadderSegment : MonoBehaviour, Interactable, Hoverable
	{
		[HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")]
		private static class SupportPatch
		{
			private static void Postfix(WearNTear __instance, ref float maxSupport, ref float minSupport, ref float horizontalLoss, ref float verticalLoss)
			{
				if (Losses.TryGetValue(__instance, out var value))
				{
					maxSupport = 100f;
					minSupport = 10f;
					horizontalLoss = 0.2f;
					verticalLoss = value;
				}
			}
		}

		public const float Height = 2f;

		private const float LinkTolerance = 0.3f;

		private const int MaxSegments = 200;

		private const float StepOff = 0.75f;

		private static readonly float[] StepOffs = new float[3] { 0.75f, 0.45f, 0.25f };

		private const float TopZone = 1f;

		private const float BottomZone = 1f;

		private const float LookDownY = -0.31f;

		private const float MaxStepUp = 0.35f;

		private const float BodyRadius = 0.25f;

		private const string Blocked = "Something is in the way";

		private const string NoFootingAbove = "There's nowhere to step off at the top";

		private const string NoFootingBelow = "There's nowhere to step off at the bottom";

		private const float PathOffset = 0.3f;

		private const float PathRadius = 0.15f;

		private static readonly FieldRef<Character, float> MaxAirAltitude = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude");

		private static readonly List<LadderSegment> All = new List<LadderSegment>();

		private static int _groundMask;

		private static int _blockMask;

		private static int _pathMask;

		private ZNetView _nview;

		public float m_verticalLoss = VerticalLossFor(8);

		private const float SupportMax = 100f;

		private const float SupportMin = 10f;

		private const float HorizontalLoss = 0.2f;

		private static readonly Dictionary<WearNTear, float> Losses = new Dictionary<WearNTear, float>();

		private WearNTear _wear;

		private Vector3 Foot => ((Component)this).transform.position;

		private Vector3 Top => ((Component)this).transform.position + ((Component)this).transform.up * 2f;

		private bool IsLive
		{
			get
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)this != (Object)null && (Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					return ((Component)this).transform.up.y > 0.9f;
				}
				return false;
			}
		}

		public static float VerticalLossFor(int segments)
		{
			float num = Mathf.Pow(0.1f, 1f / ((float)Mathf.Max(1, segments) - 0.5f));
			return (1f - num) / 2.1f;
		}

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			_wear = ((Component)this).GetComponent<WearNTear>();
			if ((Object)(object)_wear != (Object)null)
			{
				Losses[_wear] = m_verticalLoss;
			}
			All.Add(this);
		}

		private void OnDestroy()
		{
			All.Remove(this);
			if ((Object)(object)_wear != (Object)null)
			{
				Losses.Remove(_wear);
			}
		}

		private LadderSegment Next(bool up, HashSet<LadderSegment> seen)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (up ? Top : Foot);
			LadderSegment result = null;
			float num = 0.3f;
			foreach (LadderSegment item in All)
			{
				if (!((Object)(object)item == (Object)(object)this) && !seen.Contains(item) && item.IsLive)
				{
					float num2 = Vector3.Distance(val, up ? item.Foot : item.Top);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		private LadderSegment End(bool up, out int count)
		{
			HashSet<LadderSegment> hashSet = new HashSet<LadderSegment> { this };
			LadderSegment ladderSegment = this;
			for (count = 0; count < 200; count++)
			{
				LadderSegment ladderSegment2 = ladderSegment.Next(up, hashSet);
				if ((Object)(object)ladderSegment2 == (Object)null)
				{
					break;
				}
				hashSet.Add(ladderSegment2);
				ladderSegment = ladderSegment2;
			}
			return ladderSegment;
		}

		private bool WantsDown(Humanoid who, out LadderSegment top, out LadderSegment bottom, out int segments)
		{
			//IL_0024: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			top = End(up: true, out var count);
			bottom = End(up: false, out var count2);
			segments = count + count2 + 1;
			float y = ((Component)who).transform.position.y;
			if (y >= top.Top.y - 1f)
			{
				return true;
			}
			if (y <= BottomLevel(top, bottom) + 1f)
			{
				return false;
			}
			return (((Object)(object)who == (Object)(object)Player.m_localPlayer && (Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : ((Character)who).GetLookDir()).y < -0.31f;
		}

		private static float BottomLevel(LadderSegment top, LadderSegment bottom)
		{
			//IL_000c: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			InitMasks();
			float num = float.MaxValue;
			float num2 = bottom.Foot.y + 2f;
			float num3 = bottom.Foot.y - 1.5f;
			Vector3 val = Flat(((Component)top).transform.forward);
			Vector3[] array = (Vector3[])(object)new Vector3[2]
			{
				val,
				-val
			};
			foreach (Vector3 val2 in array)
			{
				RaycastHit[] array2 = Physics.RaycastAll(bottom.Foot + val2 * 0.75f + Vector3.up * 2f, Vector3.down, num2 - num3, _groundMask, (QueryTriggerInteraction)1);
				for (int j = 0; j < array2.Length; j++)
				{
					RaycastHit val3 = array2[j];
					if ((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<LadderSegment>() == (Object)null)
					{
						num = Mathf.Min(num, ((RaycastHit)(ref val3)).point.y);
					}
				}
			}
			if (num != float.MaxValue)
			{
				return Mathf.Max(num, bottom.Foot.y - 1.5f);
			}
			return bottom.Foot.y;
		}

		private static Vector3 TowardClimber(LadderSegment seg, Vector3 pos)
		{
			//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_0010: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			Vector3 val = Flat(((Component)seg).transform.forward);
			if (!(Vector3.Dot(pos - ((Component)seg).transform.position, val) >= 0f))
			{
				return -val;
			}
			return val;
		}

		public bool Interact(Humanoid character, bool hold, bool alt)
		{
			//IL_0045: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//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_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_00a6: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_00f8: 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_0173: 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_0182: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			if (hold || (Object)(object)character == (Object)null || !IsLive)
			{
				return false;
			}
			if (((Character)character).IsAttached() || ((Character)character).InCutscene() || ((Character)character).IsTeleporting())
			{
				return false;
			}
			LadderSegment top;
			LadderSegment bottom;
			int segments;
			bool flag = WantsDown(character, out top, out bottom, out segments);
			Vector3 val = TowardClimber(top, ((Component)character).transform.position);
			Vector3 val2 = -val;
			bool flag2;
			Vector3 spot;
			Vector3 look;
			bool ground;
			if (flag)
			{
				flag2 = FindLowest(top, bottom, (Vector3[])(object)new Vector3[2] { val2, val }, out spot, out look, out ground);
			}
			else
			{
				if (PathBlocked(top.Foot + val * 0.3f, ((Component)character).transform.position.y + 0.7f, top.Top.y + 1.2f))
				{
					((Character)character).Message((MessageType)2, "Something is in the way", 0, (Sprite)null, false);
					return false;
				}
				flag2 = FindSpot(top.Top, (Vector3[])(object)new Vector3[2] { val2, val }, -1f, 0.35f, out spot, out look, out ground);
			}
			if (!flag2)
			{
				((Character)character).Message((MessageType)2, ground ? "Something is in the way" : (flag ? "There's nowhere to step off at the bottom" : "There's nowhere to step off at the top"), 0, (Sprite)null, false);
				return false;
			}
			((Component)character).transform.position = spot;
			Rigidbody component = ((Component)character).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.linearVelocity = Vector3.zero;
			}
			MaxAirAltitude.Invoke((Character)(object)character) = spot.y;
			((Component)character).transform.rotation = Quaternion.LookRotation(look);
			((Character)character).SetLookDir(look, 0f);
			Physics.SyncTransforms();
			return false;
		}

		private static bool FindSpot(Vector3 level, Vector3[] dirs, float below, float above, out Vector3 spot, out Vector3 look, out bool ground)
		{
			//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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_002f: 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_003c: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_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_00cb: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			InitMasks();
			ground = false;
			RaycastHit val2 = default(RaycastHit);
			foreach (Vector3 val in dirs)
			{
				float[] stepOffs = StepOffs;
				foreach (float num in stepOffs)
				{
					if (!Physics.Raycast(level + val * num + Vector3.up * (above + 1f), Vector3.down, ref val2, above + 1f - below, _groundMask, (QueryTriggerInteraction)1))
					{
						continue;
					}
					ground = true;
					if (!(((RaycastHit)(ref val2)).point.y > level.y + above))
					{
						Vector3 val3 = ((RaycastHit)(ref val2)).point + Vector3.up * 0.05f;
						if (!Physics.CheckCapsule(val3 + Vector3.up * 0.45f, val3 + Vector3.up * 1.5f, 0.25f, _blockMask, (QueryTriggerInteraction)1))
						{
							spot = val3;
							look = val;
							return true;
						}
					}
				}
			}
			spot = (look = Vector3.zero);
			return false;
		}

		private static bool FindLowest(LadderSegment top, LadderSegment bottom, Vector3[] dirs, out Vector3 spot, out Vector3 look, out bool ground)
		{
			//IL_000a: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: 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_01bf: 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)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0069: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_0110: 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_011c: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_017e: 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)
			InitMasks();
			ground = false;
			float num = top.Top.y + 0.5f;
			float num2 = bottom.Foot.y - 1.5f;
			foreach (Vector3 val in dirs)
			{
				float[] stepOffs = StepOffs;
				foreach (float num3 in stepOffs)
				{
					Vector3 val2 = top.Top + val * num3;
					val2.y = num;
					RaycastHit[] array = Physics.RaycastAll(val2, Vector3.down, num - num2, _groundMask, (QueryTriggerInteraction)1);
					Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).point.y.CompareTo(((RaycastHit)(ref b)).point.y));
					RaycastHit[] array2 = array;
					for (int num4 = 0; num4 < array2.Length; num4++)
					{
						RaycastHit val3 = array2[num4];
						if ((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<LadderSegment>() != (Object)null)
						{
							continue;
						}
						ground = true;
						Vector3 val4 = ((RaycastHit)(ref val3)).point + Vector3.up * 0.05f;
						if (!Physics.CheckCapsule(val4 + Vector3.up * 0.45f, val4 + Vector3.up * 1.5f, 0.25f, _blockMask, (QueryTriggerInteraction)1))
						{
							if (PathBlocked(top.Foot + val * 0.3f, val4.y + 0.7f, top.Top.y + 1.2f))
							{
								break;
							}
							spot = val4;
							look = val;
							return true;
						}
					}
				}
			}
			spot = (look = Vector3.zero);
			return false;
		}

		private static bool PathBlocked(Vector3 column, float fromY, float toY)
		{
			//IL_0011: 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_0024: 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_0038: 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)
			InitMasks();
			if (toY - fromY < 0.3f)
			{
				return false;
			}
			Vector3 val = new Vector3(column.x, fromY + 0.15f, column.z);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(column.x, toY - 0.15f, column.z);
			Collider[] array = Physics.OverlapCapsule(val, val2, 0.15f, _pathMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)((Component)array[i]).GetComponentInParent<LadderSegment>() == (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private static void InitMasks()
		{
			if (_groundMask == 0)
			{
				_groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "vehicle" });
				_blockMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "vehicle" });
				_pathMask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "vehicle" });
			}
		}

		private static Vector3 Flat(Vector3 v)
		{
			//IL_0022: 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)
			v.y = 0f;
			if (!(((Vector3)(ref v)).sqrMagnitude > 0.0001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref v)).normalized;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			//IL_002c: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !IsLive)
			{
				return GetHoverName();
			}
			LadderSegment top;
			LadderSegment bottom;
			int segments;
			bool num = WantsDown((Humanoid)(object)localPlayer, out top, out bottom, out segments);
			float num2 = top.Top.y - bottom.Foot.y;
			string arg = (num ? "Climb down" : "Climb up");
			return Localization.instance.Localize($"{GetHoverName()} ({num2:0} m)\n[<color=yellow><b>$KEY_Use</b></color>] {arg}");
		}

		public string GetHoverName()
		{
			Piece component = ((Component)this).GetComponent<Piece>();
			if (!((Object)(object)component != (Object)null))
			{
				return "Ladder";
			}
			return Localization.instance.Localize(component.m_name);
		}

		public float GetHoverOffset()
		{
			return 0f;
		}
	}
	internal static class Prefabs
	{
		internal sealed class Variant
		{
			public string Prefab;

			public string Name;

			public string Description;

			public string Rail;

			public string Rung;

			public LadderMesh.Style Style;

			public float MinRipple = 0.015f;

			public int Segments = 8;

			public bool PoleRails;

			public float MaxRipple = 0.022f;
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class ZNetSceneAwake
		{
			[HarmonyPriority(0)]
			private static void Postfix(ZNetScene __instance)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				try
				{
					if ((Object)(object)_holder == (Object)null)
					{
						_holder = new GameObject("Stigi_Prefabs");
						_holder.SetActive(false);
						Object.DontDestroyOnLoad((Object)(object)_holder);
					}
					if (Ladders.Count == 0)
					{
						Variant[] variants = Variants;
						foreach (Variant variant in variants)
						{
							try
							{
								GameObject val = CreateLadder(__instance, variant);
								if (!((Object)(object)val == (Object)null))
								{
									Ladders.Add(val);
									VariantOf[val] = variant;
								}
							}
							catch (Exception arg)
							{
								StigiPlugin.Log.LogError((object)$"{variant.Prefab} failed: {arg}");
							}
						}
					}
					foreach (GameObject ladder in Ladders)
					{
						Register(__instance, ladder);
					}
					if ((Object)(object)ObjectDB.instance != (Object)null)
					{
						AddToHammer(ObjectDB.instance);
					}
				}
				catch (Exception arg2)
				{
					StigiPlugin.Log.LogError((object)$"Prefab registration failed: {arg2}");
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDBAwake
		{
			[HarmonyPriority(0)]
			private static void Postfix(ObjectDB __instance)
			{
				try
				{
					if ((Object)(object)ZNetScene.instance != (Object)null)
					{
						AddToHammer(__instance);
					}
				}
				catch (Exception arg)
				{
					StigiPlugin.Log.LogError((object)$"Hammer registration failed: {arg}");
				}
			}
		}

		public const float RungSpacing = 0.4f;

		public const float RailSpan = 0.62f;

		internal static readonly Variant[] Variants = new Variant[5]
		{
			new Variant
			{
				Prefab = "Stigi_Ladder",
				Name = "Wood wall ladder",
				Rail = "wood_pole2",
				Rung = "wood_pole",
				Description = "A 2 m ladder of hewn wood.",
				Style = new LadderMesh.Style
				{
					Seed = 11,
					RailUV = new Rect(0.02f, 0f, 0.46f, 1f),
					RungUV = new Rect(0.52f, 0f, 0.44f, 1f)
				}
			},
			new Variant
			{
				Prefab = "Stigi_Ladder_CoreWood",
				Segments = 9,
				Name = "Core wood wall ladder",
				Rail = "wood_pole_log",
				Rung = "wood_pole_log",
				Description = "A 2 m ladder of round core wood poles, bark still on.",
				Style = new LadderMesh.Style
				{
					Seed = 23,
					Hewn = false,
					RailSides = 10,
					RailRadius = 0.078f,
					RailWobble = 0.007f,
					RailJitter = 0.06f,
					RungSides = 8,
					RungRadius = 0.038f,
					RailUV = new Rect(0.01f, 0f, 0.46f, 1f),
					RungUV = new Rect(0.01f, 0f, 0.46f, 1f),
					EndUV = new Rect(0.56f, 0.84f, 0.16f, 0.15f)
				}
			},
			new Variant
			{
				Prefab = "Stigi_Ladder_Darkwood",
				Name = "Darkwood wall ladder",
				Rail = "darkwood_pole",
				Rung = "darkwood_pole",
				Description = "A 2 m ladder of darkwood poles, bound in black.",
				PoleRails = true,
				Style = new LadderMesh.Style
				{
					Seed = 37,
					NoRails = true,
					RailRadius = 0.085f,
					RungUV = new Rect(0.5f, 0f, 0.45f, 1f)
				}
			},
			new Variant
			{
				Prefab = "Stigi_Ladder_Ashwood",
				Name = "Ashwood wall ladder",
				Rail = "ashwood_pole_2m",
				Rung = "ashwood_pole_1m",
				Description = "A 2 m ladder of ashwood.",
				Style = new LadderMesh.Style
				{
					Seed = 41,
					RailRadius = 0.074f,
					RailUV = new Rect(0.5f, 0f, 0.48f, 1f),
					RungUV = new Rect(0.02f, 0f, 0.36f, 1f)
				}
			},
			new Variant
			{
				Prefab = "Stigi_Ladder_Dvergr",
				Segments = 10,
				Name = "Dvergr wall ladder",
				Rail = "piece_dvergr_pole",
				Rung = "piece_dvergr_pole",
				Description = "A 2 m ladder in the dvergr way, its rungs set in metal collars.",
				Style = new LadderMesh.Style
				{
					Seed = 53,
					RailRadius = 0.07f,
					RailWobble = 0f,
					RailJitter = 0.03f,
					RailUV = new Rect(0.02f, 0f, 0.4f, 1f),
					RungUV = new Rect(0.02f, 0f, 0.4f, 1f),
					Collars = true
				}
			}
		};

		private const string AfterPiece = "wood_stepladder";

		private const string HammerPrefab = "Hammer";

		private const string Usage = "\n\nStack them as high as the wood allows. From the bottom, use any segment to climb to the top of the stack; from the top, to climb back down. Partway up, look down to climb down.";

		private static readonly FieldRef<ZNetScene, Dictionary<int, GameObject>> NamedPrefabs = AccessTools.FieldRefAccess<ZNetScene, Dictionary<int, GameObject>>("m_namedPrefabs");

		private static readonly FieldRef<ObjectDB, List<Piece>> BuildPiecesCache = AccessTools.FieldRefAccess<ObjectDB, List<Piece>>("m_buildPieces");

		private static GameObject _holder;

		internal static readonly List<GameObject> Ladders = new List<GameObject>();

		internal static readonly Dictionary<GameObject, Variant> VariantOf = new Dictionary<GameObject, Variant>();

		private static void Register(ZNetScene scene, GameObject prefab)
		{
			if (!scene.m_prefabs.Contains(prefab))
			{
				scene.m_prefabs.Add(prefab);
			}
			NamedPrefabs.Invoke(scene)[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
		}

		private static GameObject CreateLadder(ZNetScene scene, Variant v)
		{
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Expected O, but got Unknown
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = scene.GetPrefab(v.Rail);
			GameObject prefab2 = scene.GetPrefab(v.Rung);
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab2 == (Object)null)
			{
				StigiPlugin.Log.LogWarning((object)(v.Prefab + ": vanilla '" + v.Rail + "' or '" + v.Rung + "' not found; skipped"));
				return null;
			}
			WearNTear component = prefab.GetComponent<WearNTear>();
			Piece component2 = prefab.GetComponent<Piece>();
			Piece component3 = prefab2.GetComponent<Piece>();
			Material[] array = (Material[])(object)new Material[3];
			for (int i = 0; i < 3; i++)
			{
				MeshRenderer val = LookParts(prefab, StateOf(component, i), "metal").FirstOrDefault();
				array[i] = (((Object)(object)val != (Object)null) ? LadderMaterial(((Renderer)val).sharedMaterial, v) : null);
			}
			if ((Object)(object)array[0] == (Object)null)
			{
				StigiPlugin.Log.LogWarning((object)(v.Prefab + ": no material on '" + v.Rail + "'; skipped"));
				return null;
			}
			for (int j = 1; j < 3; j++)
			{
				if ((Object)(object)array[j] == (Object)null)
				{
					array[j] = array[j - 1];
				}
			}
			Material val2 = null;
			if (v.Style.Collars)
			{
				val2 = prefab.GetComponentsInChildren<MeshRenderer>(true).SelectMany((MeshRenderer r) => ((Renderer)r).sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.ToLowerInvariant().Contains("metal"))) ?? array[0];
			}
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)array[0])
			{
				val2 = new Material(val2)
				{
					name = ((Object)val2).name + "_stigi"
				};
				string[] array2 = new string[3] { "_RippleDistance", "_RippleFreq", "_ValueNoiseVertex" };
				foreach (string text in array2)
				{
					if (val2.HasProperty(text) && array[0].HasProperty(text))
					{
						val2.SetFloat(text, array[0].GetFloat(text));
					}
				}
			}
			GameObject val3 = Object.Instantiate<GameObject>(prefab, _holder.transform, false);
			((Object)val3).name = v.Prefab;
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.identity;
			Collider componentInChildren = prefab.GetComponentInChildren<Collider>(true);
			int layer = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : LayerMask.NameToLayer("piece"));
			for (int num2 = val3.transform.childCount - 1; num2 >= 0; num2--)
			{
				Object.DestroyImmediate((Object)(object)((Component)val3.transform.GetChild(num2)).gameObject);
			}
			LODGroup[] components = val3.GetComponents<LODGroup>();
			for (int num = 0; num < components.Length; num++)
			{
				Object.DestroyImmediate((Object)(object)components[num]);
			}
			Renderer[] components2 = val3.GetComponents<Renderer>();
			for (int num = 0; num < components2.Length; num++)
			{
				Object.DestroyImmediate((Object)(object)components2[num]);
			}
			MeshFilter[] components3 = val3.GetComponents<MeshFilter>();
			for (int num = 0; num < components3.Length; num++)
			{
				Object.DestroyImmediate((Object)(object)components3[num]);
			}
			Collider[] components4 = val3.GetComponents<Collider>();
			for (int num = 0; num < components4.Length; num++)
			{
				Object.DestroyImmediate((Object)(object)components4[num]);
			}
			Mesh val4 = LadderMesh.Build(v.Style, broken: false, v.Prefab + "_mesh");
			Mesh val5 = LadderMesh.Build(v.Style, broken: true, v.Prefab + "_broken_mesh");
			string[] array3 = new string[3] { "new", "worn", "broken" };
			GameObject[] array4 = (GameObject[])(object)new GameObject[3];
			for (int num3 = 0; num3 < 3; num3++)
			{
				GameObject val6 = new GameObject(array3[num3]);
				val6.transform.SetParent(val3.transform, false);
				val6.layer = layer;
				val6.AddComponent<MeshFilter>().sharedMesh = ((num3 == 2) ? val5 : val4);
				((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterials = (Material[])(object)((!((Object)(object)val2 != (Object)null)) ? new Material[1] { array[num3] } : new Material[2]
				{
					array[num3],
					val2
				});
				if (v.PoleRails)
				{
					AddPoleRails(val6.transform, prefab, StateOf(component, num3), v, layer);
				}
				val6.SetActive(num3 == 0);
				array4[num3] = val6;
			}
			GameObject val7 = new GameObject("collider");
			val7.transform.SetParent(val3.transform, false);
			val7.layer = layer;
			BoxCollider obj = val7.AddComponent<BoxCollider>();
			float num4 = v.Style.RailRadius * 2f;
			obj.center = new Vector3(0f, 1f, 0f);
			obj.size = new Vector3(0.62f + num4, 2f, num4);
			AddSnapPoint(val3.transform, "Bottom", Vector3.zero);
			AddSnapPoint(val3.transform, "Top", Vector3.up * 2f);
			LODGroup val8 = val3.AddComponent<LODGroup>();
			val8.SetLODs((LOD[])(object)new LOD[1]
			{
				new LOD(0.01f, val3.GetComponentsInChildren<Renderer>(true))
			});
			val8.RecalculateBounds();
			WearNTear component4 = val3.GetComponent<WearNTear>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.m_new = array4[0];
				component4.m_worn = array4[1];
				component4.m_broken = array4[2];
				component4.m_wet = null;
				component4.m_fragmentRoots = null;
				component4.m_comOffset = Vector3.up * 1f;
			}
			Piece component5 = val3.GetComponent<Piece>();
			component5.m_name = v.Name;
			component5.m_description = v.Description + "\n\nStack them as high as the wood allows. From the bottom, use any segment to climb to the top of the stack; from the top, to climb back down. Partway up, look down to climb down.";
			component5.m_resources = CombineCost(component2, component3);
			component5.m_icon = Icons.Load(v.Prefab) ?? component2.m_icon;
			val3.AddComponent<LadderSegment>().m_verticalLoss = LadderSegment.VerticalLossFor(v.Segments);
			StigiPlugin.Log.LogInfo((object)($"Created {v.Prefab} ({val4.vertexCount} verts) in {((Object)array[0]).name}" + (((Object)(object)val2 != (Object)null) ? (" + " + ((Object)val2).name) : "")));
			return val3;
		}

		private static void AddPoleRails(Transform look, GameObject pole, GameObject state, Variant v, int layer)
		{
			//IL_002a: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00bb: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_0286: 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_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			List<MeshRenderer> list = LookParts(pole, state, null);
			if (list.Count == 0)
			{
				return;
			}
			Transform transform = pole.transform;
			bool flag = false;
			Bounds val = default(Bounds);
			foreach (MeshRenderer item in list)
			{
				Matrix4x4 val2 = transform.worldToLocalMatrix * ((Component)item).transform.localToWorldMatrix;
				Bounds bounds = ((Component)item).GetComponent<MeshFilter>().sharedMesh.bounds;
				for (int i = 0; i < 8; i++)
				{
					Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)((i & 1) * 2 - 1), (float)((i & 2) - 1), (float)(((i & 4) >> 1) - 1))));
					if (!flag)
					{
						val = new Bounds(val3, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val3);
					}
				}
			}
			float num = Mathf.Max(((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.z);
			Vector3 localScale = default(Vector3);
			((Vector3)(ref localScale))..ctor(2f * v.Style.RailRadius / num, 2f / ((Bounds)(ref val)).size.y, 2f * v.Style.RailRadius / num);
			Dictionary<Material, Material> mats = new Dictionary<Material, Material>();
			float[] array = new float[2] { -0.31f, 0.31f };
			foreach (float num2 in array)
			{
				GameObject val4 = new GameObject("rail");
				val4.transform.SetParent(look, false);
				val4.transform.localPosition = new Vector3(num2, 0f, 0f);
				val4.transform.localScale = localScale;
				GameObject val5 = new GameObject("fit");
				val5.transform.SetParent(val4.transform, false);
				val5.transform.localPosition = -new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y, ((Bounds)(ref val)).center.z);
				foreach (MeshRenderer item2 in list)
				{
					GameObject val6 = new GameObject(((Object)item2).name)
					{
						layer = layer
					};
					val6.transform.SetParent(val5.transform, false);
					val6.transform.localPosition = transform.InverseTransformPoint(((Component)item2).transform.position);
					val6.transform.localRotation = Quaternion.Inverse(transform.rotation) * ((Component)item2).transform.rotation;
					Vector3 lossyScale = ((Component)item2).transform.lossyScale;
					Vector3 lossyScale2 = transform.lossyScale;
					val6.transform.localScale = new Vector3(lossyScale.x / lossyScale2.x, lossyScale.y / lossyScale2.y, lossyScale.z / lossyScale2.z);
					val6.AddComponent<MeshFilter>().sharedMesh = ((Component)item2).GetComponent<MeshFilter>().sharedMesh;
					((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterials = ((IEnumerable<Material>)((Renderer)item2).sharedMaterials).Select((Func<Material, Material>)delegate(Material src)
					{
						if ((Object)(object)src == (Object)null)
						{
							return (Material)null;
						}
						if (!mats.TryGetValue(src, out var value))
						{
							value = (mats[src] = LadderMaterial(src, v, ownUVs: false));
						}
						return value;
					}).ToArray();
				}
			}
		}

		private static Material LadderMaterial(Material src, Variant v, bool ownUVs = true)
		{
			//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_0028: Expected O, but got Unknown
			//IL_0065: 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)
			if ((Object)(object)src == (Object)null)
			{
				return null;
			}
			Material val = new Material(src)
			{
				name = ((Object)src).name + "_stigi"
			};
			if (ownUVs)
			{
				string[] array = new string[4] { "_MainTex", "_BumpMap", "_MetallicTex", "_MetallicGlossMap" };
				foreach (string text in array)
				{
					if (val.HasProperty(text))
					{
						val.SetTextureScale(text, Vector2.one);
						val.SetTextureOffset(text, Vector2.zero);
					}
				}
			}
			if (val.HasProperty("_RippleDistance"))
			{
				val.SetFloat("_RippleDistance", Mathf.Clamp(val.GetFloat("_RippleDistance"), v.MinRipple, v.MaxRipple));
			}
			if (val.HasProperty("_RippleFreq"))
			{
				val.SetFloat("_RippleFreq", Mathf.Min(val.GetFloat("_RippleFreq"), 2f));
			}
			return val;
		}

		private static GameObject StateOf(WearNTear wear, int state)
		{
			if ((Object)(object)wear == (Object)null)
			{
				return null;
			}
			GameObject[] array = (GameObject[])(object)new GameObject[3] { wear.m_new, wear.m_worn, wear.m_broken };
			for (int num = state; num >= 0; num--)
			{
				if ((Object)(object)array[num] != (Object)null)
				{
					return array[num];
				}
			}
			return null;
		}

		private static List<MeshRenderer> LookParts(GameObject piece, GameObject state, string skipMaterial)
		{
			List<MeshRenderer> source = ((Component)(((Object)(object)state != (Object)null) ? state.transform : piece.transform)).GetComponentsInChildren<MeshRenderer>(true).Where(delegate(MeshRenderer r)
			{
				MeshFilter component = ((Component)r).GetComponent<MeshFilter>();
				return (Object)(object)((component != null) ? component.sharedMesh : null) != (Object)null;
			}).ToList();
			HashSet<Renderer> lod0 = new HashSet<Renderer>();
			HashSet<Renderer> inLods = new HashSet<Renderer>();
			LODGroup[] componentsInChildren = piece.GetComponentsInChildren<LODGroup>(true);
			for (int num = 0; num < componentsInChildren.Length; num++)
			{
				LOD[] lODs = componentsInChildren[num].GetLODs();
				for (int num2 = 0; num2 < lODs.Length; num2++)
				{
					Renderer[] renderers = lODs[num2].renderers;
					foreach (Renderer val in renderers)
					{
						if ((Object)(object)val != (Object)null)
						{
							inLods.Add(val);
							if (num2 == 0)
							{
								lod0.Add(val);
							}
						}
					}
				}
			}
			return source.Where(delegate(MeshRenderer r)
			{
				string text = ((Object)r).name.ToLowerInvariant();
				if (text.Contains("snow"))
				{
					return false;
				}
				if (((Renderer)r).sharedMaterials.Any((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.ToLowerInvariant().Contains("snow")))
				{
					return false;
				}
				if (!string.IsNullOrEmpty(skipMaterial) && ((Renderer)r).sharedMaterials.Any((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.ToLowerInvariant().Contains(skipMaterial)))
				{
					return false;
				}
				if (inLods.Contains((Renderer)(object)r))
				{
					return lod0.Contains((Renderer)(object)r);
				}
				return !text.Contains("lod") && !text.Contains("low") && !text.StartsWith("med") && !text.Contains("destruction") && !text.StartsWith("cube.");
			}).ToList();
		}

		private static Requirement[] CombineCost(Piece rail, Piece rung)
		{
			//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_00b5: 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_00d2: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>();
			foreach (Requirement req in ((IEnumerable<Requirement>)(((object)rail?.m_resources) ?? ((object)new Requirement[0]))).Concat((IEnumerable<Requirement>)(((object)rung?.m_resources) ?? ((object)new Requirement[0]))))
			{
				if (!((Object)(object)req?.m_resItem == (Object)null))
				{
					Requirement val = ((IEnumerable<Requirement>)list).FirstOrDefault((Func<Requirement, bool>)((Requirement t) => (Object)(object)t.m_resItem == (Object)(object)req.m_resItem));
					if (val != null)
					{
						val.m_amount += req.m_amount;
						continue;
					}
					list.Add(new Requirement
					{
						m_resItem = req.m_resItem,
						m_amount = req.m_amount,
						m_recover = true
					});
				}
			}
			return list.ToArray();
		}

		private static void AddSnapPoint(Transform parent, string name, Vector3 localPos)
		{
			//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_0011: 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)
			GameObject val = new GameObject(name)
			{
				tag = "snappoint"
			};
			val.transform.SetParent(parent, false);
			val.transform.localPosition = localPos;
		}

		private static void AddToHammer(ObjectDB db)
		{
			if (Ladders.Count == 0)
			{
				return;
			}
			GameObject itemPrefab = db.GetItemPrefab("Hammer");
			PieceTable val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildPieces;
			if ((Object)(object)val == (Object)null)
			{
				StigiPlugin.Log.LogWarning((object)"Hammer piece table not found (yet)");
				return;
			}
			bool flag = false;
			int num = val.m_pieces.FindIndex((GameObject p) => (Object)(object)p != (Object)null && ((Object)p).name == "wood_stepladder");
			foreach (GameObject ladder in Ladders)
			{
				if (val.m_pieces.Contains(ladder))
				{
					num = val.m_pieces.IndexOf(ladder);
					continue;
				}
				if (num >= 0)
				{
					val.m_pieces.Insert(++num, ladder);
				}
				else
				{
					val.m_pieces.Add(ladder);
				}
				flag = true;
			}
			if (flag)
			{
				BuildPiecesCache.Invoke(db)?.Clear();
				StigiPlugin.Log.LogInfo((object)$"Added {Ladders.Count} ladders to the hammer");
			}
		}
	}
	internal class Preview : MonoBehaviour
	{
		[HarmonyPatch(typeof(GameCamera), "LateUpdate")]
		private static class CameraOverride
		{
			private static void Postfix(GameCamera __instance)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if (_camPos.HasValue)
				{
					((Component)__instance).transform.SetPositionAndRotation(_camPos.Value, _camRot);
				}
				if (_camFov.HasValue)
				{
					Camera component = ((Component)__instance).GetComponent<Camera>();
					if ((Object)(object)component != (Object)null)
					{
						component.fieldOfView = _camFov.Value;
					}
				}
			}
		}

		[HarmonyPatch(typeof(MessageHud), "ShowMessage")]
		private static class Quiet
		{
			private static bool Prefix()
			{
				return !TrailerOn;
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "Start")]
		private static class MenuStart
		{
			private static void Postfix(FejdStartup __instance)
			{
				if (Enabled && !_started)
				{
					((MonoBehaviour)__instance).StartCoroutine(StartWorld(__instance));
				}
			}
		}

		private class TShot
		{
			public string Name;

			public float From;

			public float To;

			public Func<float, float, (Vector3 pos, Vector3 look, float fov)> Camera;

			public Action<float, float> Each;
		}

		public const string TriggerFile = "stigi_preview.txt";

		public const string ReportFile = "StigiPreview.txt";

		private const string WorldName = "StigiTest";

		private const string WorldSeed = "StigiTest1";

		private const string ProfileName = "stigitest";

		private const float TimeLimit = 1500f;

		internal static bool Enabled;

		internal static bool Showcase;

		internal static bool TrailerOn;

		private static float? _camFov;

		private static bool _started;

		private static Vector3? _camPos;

		private static Quaternion _camRot;

		private readonly List<string> _lines = new List<string>();

		private string _dir;

		private bool _finished;

		private const int Fps = 30;

		private float _wallFront;

		private float _floorTop;

		private string _frameDir;

		private int _framesSaved;

		private static Vector3 _origin;

		private static Quaternion _frame = Quaternion.identity;

		internal static void CheckTrigger(GameObject host)
		{
			try
			{
				string path = Path.Combine(Paths.BepInExRootPath, "stigi_preview.txt");
				if (File.Exists(path))
				{
					string text = File.ReadAllText(path).ToLowerInvariant();
					Showcase = text.Contains("showcase") || text.Contains("trailer");
					TrailerOn = text.Contains("trailer");
					File.Delete(path);
					Enabled = true;
					host.AddComponent<Preview>();
					StigiPlugin.Log.LogInfo((object)"PREVIEW: trigger found; the game will start the test world by itself");
				}
			}
			catch (Exception arg)
			{
				StigiPlugin.Log.LogError((object)$"PREVIEW trigger check failed: {arg}");
			}
		}

		private static IEnumerator StartWorld(FejdStartup menu)
		{
			_started = true;
			yield return (object)new WaitForSeconds(2f);
			try
			{
				PlayerProfile val = new PlayerProfile("stigitest", (FileSource)2);
				if (!val.Load())
				{
					val.SetName("Stigitest");
				}
				val.m_firstSpawn = false;
				val.Save();
				Game.SetProfile("stigitest", (FileSource)2);
				World.RemoveWorld("StigiTest", (FileSource)2);
				SaveSystem.InvalidateCache((SaveDataType)0);
				World val2 = new World("StigiTest", "StigiTest1")
				{
					m_fileSource = (FileSource)2,
					m_needsDB = false
				};
				SaveSystem.SetSaveNumber(0u);
				val2.SaveWorldFWLData(DateTime.Now);
				SaveSystem.InvalidateCache((SaveDataType)0);
				ZNet.SetServer(true, false, false, val2.m_name, "", val2);
				ZNet.ResetServerHost();
				AccessTools.Field(typeof(FejdStartup), "m_startingWorld").SetValue(menu, true);
				AccessTools.Method(typeof(FejdStartup), "TransitionToMainScene", (Type[])null, (Type[])null).Invoke(menu, null);
			}
			catch (Exception arg)
			{
				StigiPlugin.Log.LogError((object)$"PREVIEW could not start the world: {arg}");
			}
		}

		private void Start()
		{
			_dir = Path.Combine(Path.Combine(Paths.GameRootPath, "Stigi"), "preview");
			try
			{
				Directory.CreateDirectory(_dir);
				string[] files = Directory.GetFiles(_dir, "*.png", SearchOption.AllDirectories);
				for (int i = 0; i < files.Length; i++)
				{
					File.Delete(files[i]);
				}
			}
			catch
			{
			}
			((MonoBehaviour)this).StartCoroutine(Watchdog());
			((MonoBehaviour)this).StartCoroutine(Run());
		}

		private IEnumerator Watchdog()
		{
			yield return (object)new WaitForSecondsRealtime(1500f);
			if (!_finished)
			{
				Note("FAIL  did not finish within the time limit");
				Finish();
			}
		}

		private void Note(string text)
		{
			_lines.Add(text);
			StigiPlugin.Log.LogInfo((object)("PREVIEW " + text));
			try
			{
				File.WriteAllLines(Path.Combine(Paths.BepInExRootPath, "StigiPreview.txt"), new string[2]
				{
					string.Format("Stigi preview {0}, {1:yyyy-MM-dd HH:mm:ss}", "1.0.0", DateTime.Now),
					""
				}.Concat(_lines).ToArray());
			}
			catch
			{
			}
		}

		private void Finish()
		{
			if (!_finished)
			{
				_finished = true;
				Note("done; quitting");
				((MonoBehaviour)this).StartCoroutine(Quit());
			}
		}

		private IEnumerator Quit()
		{
			yield return (object)new WaitForSecondsRealtime(2f);
			Application.Quit();
		}

		private IEnumerator Shot(string name)
		{
			yield return (object)new WaitForEndOfFrame();
			try
			{
				Texture2D val = new Texture2D(Screen.width, Screen.height, (TextureFormat)3, false);
				val.ReadPixels(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), 0, 0);
				val.Apply();
				File.WriteAllBytes(Path.Combine(_dir, name + ".png"), ImageConversion.EncodeToPNG(val));
				Object.Destroy((Object)(object)val);
				Note("photo " + name + ".png");
			}
			catch (Exception ex)
			{
				Note("photo " + name + " failed: " + ex.Message);
			}
		}

		private static IEnumerator WaitFor(Func<bool> cond, float timeout)
		{
			float t = 0f;
			while (!cond() && t < timeout)
			{
				t += Time.deltaTime;
				yield return null;
			}
		}

		private IEnumerator Run()
		{
			yield return WaitFor(() => (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ZNetScene.instance != (Object)null && !((Character)Player.m_localPlayer).IsTeleporting(), 400f);
			Player player = Player.m_localPlayer;
			if ((Object)(object)player == (Object)null)
			{
				Note("FAIL  no player");
				Finish();
				yield break;
			}
			yield return (object)new WaitForSeconds(5f);
			player.SetGodMode(true);
			Note($"world loaded, player at {((Component)player).transform.position}");
			IEnumerator body = null;
			try
			{
				body = (Showcase ? ShowcaseSteps(player) : Steps(player));
			}
			catch (Exception ex)
			{
				Note("FAIL  " + ex);
			}
			if (body != null)
			{
				while (true)
				{
					object current;
					try
					{
						if (!body.MoveNext())
						{
							break;
						}
						current = body.Current;
						goto IL_0181;
					}
					catch (Exception ex2)
					{
						Note("FAIL  exception: " + ex2);
					}
					break;
					IL_0181:
					yield return current;
				}
			}
			_camPos = null;
			Finish();
		}

		private static GameObject Spawn(string prefab, Vector3 pos, Quaternion rot)
		{
			//IL_0018: 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)
			GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
			if ((Object)(object)prefab2 == (Object)null)
			{
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab2, pos, rot);
			WearNTear[] componentsInChildren = val.GetComponentsInChildren<WearNTear>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].m_noSupportWear = false;
			}
			Physics.SyncTransforms();
			return val;
		}

		private static Bounds ColliderBounds(GameObject go)
		{
			//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_0058: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = (from c in go.GetComponentsInChildren<Collider>()
				where c.enabled && !c.isTrigger
				select c).ToArray();
			Bounds bounds = array[0].bounds;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				((Bounds)(ref bounds)).Encapsulate(val.bounds);
			}
			return bounds;
		}

		private void RenderIcons()
		{
			Icons.Pose[] array = new Icons.Pose[4]
			{
				new Icons.Pose
				{
					Suffix = "a_upright",
					Yaw = -28f,
					Pitch = 8f
				},
				new Icons.Pose
				{
					Suffix = "d_lean_steep",
					Yaw = -20f,
					Pitch = 6f,
					Roll = -32f
				},
				new Icons.Pose
				{
					Suffix = "b_lean",
					Yaw = -28f,
					Pitch = 8f,
					Roll = -24f
				},
				new Icons.Pose
				{
					Suffix = "c_lean_tall",
					Yaw = -28f,
					Pitch = 8f,
					Roll = -30f,
					Segments = 1.5f
				}
			};
			foreach (GameObject ladder in Prefabs.Ladders)
			{
				Icons.Pose[] array2 = array;
				foreach (Icons.Pose pose in array2)
				{
					try
					{
						Icons.Render(ladder, Path.Combine(Path.Combine(_dir, "icons"), ((Object)ladder).name + "_" + pose.Suffix + ".png"), 256, pose);
					}
					catch (Exception arg)
					{
						Note($"FAIL  icon {((Object)ladder).name} {pose.Suffix}: {arg}");
					}
				}
			}
			Note($"icons rendered for {Prefabs.Ladders.Count} ladders");
		}

		private IEnumerator Steps(Player player)
		{
			EnvMan.instance.m_debugTimeOfDay = true;
			EnvMan.instance.m_debugTime = 0.5f;
			EnvMan.instance.SetForceEnvironment("Clear");
			if ((Object)(object)Hud.instance != (Object)null)
			{
				Hud.instance.m_userHidden = true;
			}
			RenderIcons();
			Vector3 val = (((Object)(object)EnvMan.instance.m_dirLight != (Object)null) ? (-((Component)EnvMan.instance.m_dirLight).transform.forward) : Vector3.forward);
			int num = Mathf.RoundToInt(Mathf.Atan2(val.x, val.z) * 57.29578f / 90f);
			_frame = Quaternion.Euler(0f, (float)num * 90f, 0f);
			Vector3 o = ((Component)player).transform.position + _frame * new Vector3(-12f, 0f, -24f);
			o.x = Mathf.Round(o.x);
			o.z = Mathf.Round(o.z);
			_origin = o;
			float num2 = float.MinValue;
			for (float num3 = -4f; num3 <= 14f; num3 += 2f)
			{
				for (float num4 = -4f; num4 <= 8f; num4 += 2f)
				{
					num2 = Mathf.Max(num2, ZoneSystem.instance.GetGroundHeight(W(num3, 0f, num4)));
				}
			}
			o.y = (_origin.y = num2 + 0.4f);
			int num5 = 0;
			HashSet<ZNetView> hashSet = new HashSet<ZNetView>();
			Collider[] array = Physics.OverlapSphere(W(4f, 0f, 4f), 40f);
			for (int i = 0; i < array.Length; i++)
			{
				ZNetView componentInParent = ((Component)array[i]).GetComponentInParent<ZNetView>();
				if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(componentInParent) && componentInParent.IsValid() && !((Object)(object)((Component)componentInParent).GetComponent<Piece>() != (Object)null) && !((Object)(object)((Component)componentInParent).GetComponent<Character>() != (Object)null))
				{
					ZNetScene.instance.Destroy(((Component)componentInParent).gameObject);
					num5++;
				}
			}
			Note($"cleared {num5} trees/rocks/bushes");
			yield return (object)new WaitForSeconds(1f);
			List<GameObject> floors = new List<GameObject>();
			for (float num6 = -4f; num6 <= 13f; num6 += 2f)
			{
				for (float num7 = -3f; num7 <= 7f; num7 += 2f)
				{
					floors.Add(Spawn("wood_floor", W(num6 + 1f, 0f, num7 + 1f), _frame));
				}
			}
			yield return null;
			float floorTop = floors.Where((GameObject f) => (Object)(object)f != (Object)null).Select(delegate(GameObject f)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL