Decompiled source of Building Pieces v1.1.2

plugins/InvertedStoneRamp.dll

Decompiled 33 minutes ago
using System;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace OctoberJemini.InvertedStoneRamp;

[BepInPlugin("OctoberJemini.InvertedStoneRamp", "Inverted Stone Ramp", "1.1.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Guid = "OctoberJemini.InvertedStoneRamp";

	private const string SourceName = "stone_wall_2x1";

	private const string PrefabName = "oct_stone_ramp_2x1_inverted";

	private GameObject ramp;

	private bool iconRendered;

	private void Awake()
	{
		PrefabManager.OnVanillaPrefabsAvailable += RegisterPiece;
		PieceManager.OnPiecesRegistered += RenderIcon;
	}

	private void RegisterPiece()
	{
		//IL_013f: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: 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_029a: 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_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Expected O, but got Unknown
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Expected O, but got Unknown
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Expected O, but got Unknown
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Expected O, but got Unknown
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)ramp))
		{
			return;
		}
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("stone_wall_2x1");
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Vanilla stone wall unavailable.");
			}
			WearNTear component = prefab.GetComponent<WearNTear>();
			Material val = StoneMaterial(component.m_new, null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Vanilla stone material unavailable.");
			}
			Material material = StoneMaterial(component.m_worn, val);
			Material material2 = StoneMaterial(component.m_broken, val);
			GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("oct_stone_ramp_2x1_inverted", prefab);
			for (int num = val2.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num)).gameObject);
			}
			Collider[] components = val2.GetComponents<Collider>();
			foreach (Collider val3 in components)
			{
				Object.DestroyImmediate((Object)(object)val3);
			}
			Renderer[] components2 = val2.GetComponents<Renderer>();
			foreach (Renderer val4 in components2)
			{
				Object.DestroyImmediate((Object)(object)val4);
			}
			MeshFilter[] components3 = val2.GetComponents<MeshFilter>();
			foreach (MeshFilter val5 in components3)
			{
				Object.DestroyImmediate((Object)(object)val5);
			}
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			Mesh val6 = CreateWedge();
			WearNTear component2 = val2.GetComponent<WearNTear>();
			component2.m_new = Visual(val2, "new", val6, val);
			component2.m_worn = Visual(val2, "worn", val6, material);
			component2.m_broken = Visual(val2, "broken", val6, material2);
			component2.m_worn.SetActive(false);
			component2.m_broken.SetActive(false);
			component2.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { component2.m_new };
			Bounds bounds = val6.bounds;
			component2.m_comOffset = ((Bounds)(ref bounds)).center;
			MeshCollider val7 = val2.AddComponent<MeshCollider>();
			val7.sharedMesh = val6;
			val7.convex = true;
			float[] array = new float[2] { -0.5f, 0.5f };
			foreach (float num2 in array)
			{
				Vector3[] array2 = (Vector3[])(object)new Vector3[4]
				{
					new Vector3(num2, -0.5f, -1f),
					new Vector3(num2, 0.5f, -1f),
					new Vector3(num2, 0.5f, 1f),
					new Vector3(num2, 0f, 0f)
				};
				foreach (Vector3 localPosition in array2)
				{
					GameObject val8 = new GameObject("Snap");
					val8.tag = "snappoint";
					val8.transform.SetParent(val2.transform, false);
					val8.transform.localPosition = localPosition;
				}
			}
			PieceConfig val9 = new PieceConfig();
			val9.Name = "Inverted Stone Ramp 2x1";
			val9.Description = "A stone wedge with a flat top and sloped underside.";
			val9.PieceTable = "Hammer";
			val9.Category = "BuildingStonecutter";
			val9.Usage = new string[2] { "Building", "Wall" };
			val9.CraftingStation = "piece_stonecutter";
			val9.AllowedInDungeons = false;
			RequirementConfig[] array3 = (RequirementConfig[])(object)new RequirementConfig[1];
			RequirementConfig val10 = new RequirementConfig();
			val10.Item = "Stone";
			val10.Amount = 2;
			val10.Recover = true;
			array3[0] = val10;
			val9.Requirements = array3;
			PieceConfig val11 = val9;
			if (!PieceManager.Instance.AddPiece(new CustomPiece(val2, false, val11)))
			{
				throw new InvalidOperationException("Could not register inverted ramp.");
			}
			ramp = val2;
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterPiece;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Inverted Stone Ramp 2x1: 2 Stone, Stonecutter, separate Hammer piece.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Inverted ramp registration failed: " + ex));
		}
	}

	private static Material StoneMaterial(GameObject state, Material fallback)
	{
		if (!Object.op_Implicit((Object)(object)state))
		{
			return fallback;
		}
		MeshRenderer componentInChildren = state.GetComponentInChildren<MeshRenderer>(true);
		if (!Object.op_Implicit((Object)(object)componentInChildren) || !Object.op_Implicit((Object)(object)((Renderer)componentInChildren).sharedMaterial))
		{
			return fallback;
		}
		return ((Renderer)componentInChildren).sharedMaterial;
	}

	private static GameObject Visual(GameObject parent, string name, Mesh mesh, Material material)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		GameObject val = new GameObject(name);
		val.layer = parent.layer;
		val.transform.SetParent(parent.transform, false);
		val.AddComponent<MeshFilter>().sharedMesh = mesh;
		((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
		return val;
	}

	private static Mesh CreateWedge()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Expected O, but got Unknown
		//IL_01a0: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[6]
		{
			new Vector3(-1f, -0.5f, -0.5f),
			new Vector3(-1f, 0.5f, -0.5f),
			new Vector3(1f, 0.5f, -0.5f),
			new Vector3(-1f, -0.5f, 0.5f),
			new Vector3(-1f, 0.5f, 0.5f),
			new Vector3(1f, 0.5f, 0.5f)
		};
		int[] array2 = new int[24]
		{
			0, 1, 2, 3, 5, 4, 0, 3, 4, 0,
			4, 1, 1, 4, 5, 1, 5, 2, 0, 2,
			5, 0, 5, 3
		};
		Vector3[] array3 = (Vector3[])(object)new Vector3[array2.Length];
		Vector2[] array4 = (Vector2[])(object)new Vector2[array2.Length];
		Color[] array5 = (Color[])(object)new Color[array2.Length];
		int[] array6 = new int[array2.Length];
		for (int i = 0; i < array2.Length; i++)
		{
			Vector3 val = array[array2[i]];
			float num = ((i < 6 || i >= 12) ? ((val.x + 1f) * 0.225f) : ((val.z + 0.5f) * 0.45f));
			float num2 = ((i < 12) ? ((val.y + 0.5f) * 0.225f) : ((val.z + 0.5f) * 0.225f));
			ref Vector2 reference = ref array4[i];
			reference = new Vector2(0.025f + num, 0.025f + num2);
			ref Vector3 reference2 = ref array3[i];
			reference2 = new Vector3(0f - val.z, val.y, val.x);
			ref Color reference3 = ref array5[i];
			reference3 = Color.white;
			array6[i] = i;
		}
		Mesh val2 = new Mesh();
		((Object)val2).name = "OCT_InvertedStoneWedge";
		val2.vertices = array3;
		val2.triangles = array6;
		val2.uv = array4;
		val2.colors = array5;
		Mesh val3 = val2;
		val3.RecalculateNormals();
		val3.RecalculateTangents();
		val3.RecalculateBounds();
		return val3;
	}

	private void RenderIcon()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)ramp) || iconRendered || (int)SystemInfo.graphicsDeviceType == 4)
		{
			return;
		}
		try
		{
			using (Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("inverted-ramp-icon.png"))
			{
				using MemoryStream memoryStream = new MemoryStream();
				if (stream == null)
				{
					throw new InvalidOperationException("Inverted wedge icon missing.");
				}
				stream.CopyTo(memoryStream);
				Texture2D val = AssetUtils.LoadImage(memoryStream.ToArray());
				((Texture)val).filterMode = (FilterMode)1;
				ramp.GetComponent<Piece>().m_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			iconRendered = true;
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Inverted ramp thumbnail: " + ex.Message));
		}
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterPiece;
		PieceManager.OnPiecesRegistered -= RenderIcon;
	}
}

plugins/RoofCorners45.dll

Decompiled 33 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[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 OctoberJemini.RoofCorners45
{
	internal struct RoofVertex
	{
		public Vector3 P;

		public Vector3 N;

		public Vector2 UV;

		public Vector2 UV2;

		public Color Color;

		public static RoofVertex Lerp(RoofVertex a, RoofVertex b, float t)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0062: 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_006f: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			return new RoofVertex
			{
				P = Vector3.LerpUnclamped(a.P, b.P, t),
				N = Vector3.LerpUnclamped(a.N, b.N, t),
				UV = Vector2.LerpUnclamped(a.UV, b.UV, t),
				UV2 = Vector2.LerpUnclamped(a.UV2, b.UV2, t),
				Color = Color.LerpUnclamped(a.Color, b.Color, t)
			};
		}
	}
	internal sealed class RoofData
	{
		public RoofVertex[] Vertices;

		public int[][] Groups;
	}
	internal static class RoofMeshCuts
	{
		private static Dictionary<string, RoofData> assets;

		public static RoofData Get(string key)
		{
			//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_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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if (assets == null)
			{
				assets = new Dictionary<string, RoofData>();
				using Stream input = typeof(Plugin).Assembly.GetManifestResourceStream("roof-meshes.bin");
				using BinaryReader binaryReader = new BinaryReader(input);
				int num = binaryReader.ReadInt32();
				for (int i = 0; i < num; i++)
				{
					string key2 = Encoding.UTF8.GetString(binaryReader.ReadBytes(binaryReader.ReadInt32()));
					RoofVertex[] array = new RoofVertex[binaryReader.ReadInt32()];
					for (int j = 0; j < array.Length; j++)
					{
						array[j] = new RoofVertex
						{
							P = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
							N = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
							UV = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()),
							Color = new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
							UV2 = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle())
						};
					}
					int[][] array2 = new int[binaryReader.ReadInt32()][];
					for (int k = 0; k < array2.Length; k++)
					{
						array2[k] = new int[binaryReader.ReadInt32()];
						for (int l = 0; l < array2[k].Length; l++)
						{
							array2[k][l] = binaryReader.ReadInt32();
						}
					}
					assets.Add(key2, new RoofData
					{
						Vertices = array,
						Groups = array2
					});
				}
			}
			if (!assets.TryGetValue(key, out var value))
			{
				throw new InvalidOperationException("Missing native roof mesh " + key);
			}
			return value;
		}

		internal static List<RoofVertex> Clip(List<RoofVertex> polygon, Vector4 plane)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			List<RoofVertex> list = new List<RoofVertex>();
			if (polygon.Count == 0)
			{
				return list;
			}
			RoofVertex a = polygon[polygon.Count - 1];
			float num = Distance(a.P, plane);
			foreach (RoofVertex item in polygon)
			{
				float num2 = Distance(item.P, plane);
				if (num >= 0f != num2 >= 0f)
				{
					list.Add(RoofVertex.Lerp(a, item, num / (num - num2)));
				}
				if (num2 >= 0f)
				{
					list.Add(item);
				}
				a = item;
				num = num2;
			}
			return list;
		}

		private static float Distance(Vector3 p, Vector4 plane)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			return plane.x * p.x + plane.y * p.y + plane.z * p.z + plane.w;
		}

		public static Vector4[] Planes(bool half, int side, float width)
		{
			//IL_002a: 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_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_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_00db: 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_0074: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Tan((float)Math.PI / 8f);
			if (!half)
			{
				if (side != 0)
				{
					return (Vector4[])(object)new Vector4[2]
					{
						new Vector4(1f, 0f, 0f, 1f),
						new Vector4(-1f, 0f, num, width - 1f - num)
					};
				}
				return (Vector4[])(object)new Vector4[2]
				{
					new Vector4(-1f, 0f, 0f, 1f),
					new Vector4(1f, 0f, num, width - 1f - num)
				};
			}
			return (Vector4[])(object)new Vector4[2]
			{
				new Vector4(1f, 0f, 0f, 0.5f),
				new Vector4(-1f, 0f, 0f, 0.5f)
			};
		}

		public static Matrix4x4 Placement(bool half, int side, float bottom, float width)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (half)
			{
				return Matrix4x4.identity;
			}
			float num = Mathf.Sqrt(0.5f);
			if (side != 0)
			{
				return Matrix4x4.TRS(new Vector3(1f - width * num, 0f - bottom, 1f - (2f - width) * num), Quaternion.Euler(0f, 45f, 0f), Vector3.one);
			}
			return Matrix4x4.TRS(new Vector3(0f, 0f - bottom, 2f - width), Quaternion.Euler(0f, 90f, 0f), Vector3.one);
		}

		public static Mesh Cut(RoofData data, Matrix4x4 toRoot, bool half, float bottom, float width)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: 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_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 inverse = ((Matrix4x4)(ref toRoot)).inverse;
			Matrix4x4 inverse2 = ((Matrix4x4)(ref toRoot)).inverse;
			Matrix4x4 transpose = ((Matrix4x4)(ref inverse2)).transpose;
			Matrix4x4 transpose2 = ((Matrix4x4)(ref toRoot)).transpose;
			List<RoofVertex> list = new List<RoofVertex>();
			List<int[]> list2 = new List<int[]>();
			int[][] groups = data.Groups;
			foreach (int[] array in groups)
			{
				List<int> list3 = new List<int>();
				for (int j = 0; j < (half ? 1 : 2); j++)
				{
					Vector4[] array2 = Planes(half, j, width);
					Matrix4x4 val = Placement(half, j, bottom, width);
					for (int k = 0; k < array.Length; k += 3)
					{
						List<RoofVertex> list4 = new List<RoofVertex>();
						Vector3 val2;
						for (int l = 0; l < 3; l++)
						{
							RoofVertex item = data.Vertices[array[k + l]];
							item.P = ((Matrix4x4)(ref toRoot)).MultiplyPoint3x4(item.P);
							val2 = ((Matrix4x4)(ref transpose)).MultiplyVector(item.N);
							item.N = ((Vector3)(ref val2)).normalized;
							list4.Add(item);
						}
						Vector4[] array3 = array2;
						foreach (Vector4 plane in array3)
						{
							list4 = Clip(list4, plane);
						}
						if (list4.Count < 3)
						{
							continue;
						}
						int count = list.Count;
						foreach (RoofVertex item2 in list4)
						{
							RoofVertex current = item2;
							current.P = ((Matrix4x4)(ref inverse)).MultiplyPoint3x4(((Matrix4x4)(ref val)).MultiplyPoint3x4(current.P));
							val2 = ((Matrix4x4)(ref transpose2)).MultiplyVector(((Matrix4x4)(ref val)).MultiplyVector(current.N));
							current.N = ((Vector3)(ref val2)).normalized;
							list.Add(current);
						}
						for (int n = 1; n < list4.Count - 1; n++)
						{
							list3.Add(count);
							list3.Add(count + n);
							list3.Add(count + n + 1);
						}
					}
				}
				list2.Add(list3.ToArray());
			}
			Vector3[] array4 = (Vector3[])(object)new Vector3[list.Count];
			Vector3[] array5 = (Vector3[])(object)new Vector3[array4.Length];
			Vector2[] array6 = (Vector2[])(object)new Vector2[array4.Length];
			Vector2[] array7 = (Vector2[])(object)new Vector2[array4.Length];
			Color[] array8 = (Color[])(object)new Color[array4.Length];
			for (int num = 0; num < array4.Length; num++)
			{
				array4[num] = list[num].P;
				array5[num] = list[num].N;
				array6[num] = list[num].UV;
				array7[num] = list[num].UV2;
				array8[num] = list[num].Color;
			}
			Mesh val3 = new Mesh
			{
				name = "OctRoof_TrueCut",
				indexFormat = (IndexFormat)(array4.Length > 65535),
				vertices = array4,
				normals = array5,
				uv = array6,
				uv2 = array7,
				colors = array8,
				subMeshCount = list2.Count
			};
			for (int num2 = 0; num2 < list2.Count; num2++)
			{
				val3.SetTriangles(list2[num2], num2);
			}
			val3.RecalculateTangents();
			val3.RecalculateBounds();
			return val3;
		}

		public static Mesh CutBox(Vector3[] corners, Vector4[] planes, Matrix4x4 place, Matrix4x4 fromRoot)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0134: 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_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: 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_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: 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_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: 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)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			int[][] obj = new int[6][]
			{
				new int[4] { 0, 3, 2, 1 },
				new int[4] { 4, 5, 6, 7 },
				new int[4] { 0, 1, 5, 4 },
				new int[4] { 3, 7, 6, 2 },
				new int[4] { 0, 4, 7, 3 },
				new int[4] { 1, 2, 6, 5 }
			};
			List<List<RoofVertex>> list = new List<List<RoofVertex>>();
			int[][] array = obj;
			foreach (int[] obj2 in array)
			{
				List<RoofVertex> list2 = new List<RoofVertex>();
				int[] array2 = obj2;
				foreach (int num in array2)
				{
					list2.Add(new RoofVertex
					{
						P = corners[num]
					});
				}
				list.Add(list2);
			}
			foreach (Vector4 val in planes)
			{
				List<List<RoofVertex>> list3 = new List<List<RoofVertex>>();
				List<RoofVertex> list4 = new List<RoofVertex>();
				bool flag = false;
				bool flag2 = false;
				foreach (List<RoofVertex> item in list)
				{
					foreach (RoofVertex item2 in item)
					{
						float num2 = Distance(item2.P, val);
						flag = flag || num2 < -1E-06f;
						flag2 = flag2 || num2 > 1E-06f;
					}
				}
				foreach (List<RoofVertex> item3 in list)
				{
					List<RoofVertex> list5 = Clip(item3, val);
					if (list5.Count < 3)
					{
						continue;
					}
					list3.Add(list5);
					foreach (RoofVertex v in list5)
					{
						if (Math.Abs(Distance(v.P, val)) < 0.0001f && !list4.Exists(delegate(RoofVertex q)
						{
							//IL_0001: Unknown result type (might be due to invalid IL or missing references)
							//IL_000c: Unknown result type (might be due to invalid IL or missing references)
							//IL_0011: Unknown result type (might be due to invalid IL or missing references)
							//IL_0016: Unknown result type (might be due to invalid IL or missing references)
							Vector3 val5 = q.P - v.P;
							return ((Vector3)(ref val5)).sqrMagnitude < 1E-10f;
						}))
						{
							list4.Add(v);
						}
					}
				}
				if (flag && flag2 && list4.Count >= 3)
				{
					Vector3 centre = Vector3.zero;
					foreach (RoofVertex item4 in list4)
					{
						centre += item4.P;
					}
					centre /= (float)list4.Count;
					Vector3 val2 = new Vector3(val.x, val.y, val.z);
					Vector3 val3 = -((Vector3)(ref val2)).normalized;
					val2 = list4[0].P - centre;
					Vector3 u = ((Vector3)(ref val2)).normalized;
					Vector3 w = Vector3.Cross(val3, u);
					list4.Sort((RoofVertex a, RoofVertex b) => Mathf.Atan2(Vector3.Dot(a.P - centre, w), Vector3.Dot(a.P - centre, u)).CompareTo(Mathf.Atan2(Vector3.Dot(b.P - centre, w), Vector3.Dot(b.P - centre, u))));
					list3.Add(list4);
				}
				list = list3;
			}
			List<Vector3> list6 = new List<Vector3>();
			List<int> list7 = new List<int>();
			foreach (List<RoofVertex> item5 in list)
			{
				int count = list6.Count;
				foreach (RoofVertex item6 in item5)
				{
					list6.Add(((Matrix4x4)(ref fromRoot)).MultiplyPoint3x4(((Matrix4x4)(ref place)).MultiplyPoint3x4(item6.P)));
				}
				for (int num3 = 1; num3 < item5.Count - 1; num3++)
				{
					list7.Add(count);
					list7.Add(count + num3);
					list7.Add(count + num3 + 1);
				}
			}
			if (list6.Count < 4)
			{
				return null;
			}
			double num4 = 0.0;
			for (int num5 = 0; num5 < list7.Count; num5 += 3)
			{
				num4 += (double)Vector3.Dot(list6[list7[num5]], Vector3.Cross(list6[list7[num5 + 1]], list6[list7[num5 + 2]])) / 6.0;
			}
			if (Math.Abs(num4) < 1E-10)
			{
				return null;
			}
			Mesh val4 = new Mesh
			{
				name = "OctRoof_CutCollider",
				vertices = list6.ToArray(),
				triangles = list7.ToArray()
			};
			val4.RecalculateBounds();
			return val4;
		}
	}
	[BepInPlugin("OctoberJemini.RoofCorners45", "Roof Corners 45", "0.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "OctoberJemini.RoofCorners45";

		private bool registered;

		private const float CornerWidth = 1f;

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Register;
		}

		private static string MeshKey(Transform child, Transform root, string source)
		{
			List<int> list = new List<int>();
			while ((Object)(object)child != (Object)(object)root)
			{
				list.Add(child.GetSiblingIndex());
				child = child.parent;
			}
			list.Reverse();
			foreach (int item in list)
			{
				source = source + "/" + item;
			}
			return source;
		}

		private static void Snap(GameObject root, string name, Vector3 point)
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				tag = "snappoint"
			};
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = point;
		}

		private static void Reshape(GameObject root, string source, float rise, bool half)
		{
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00f4: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_015c: 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)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01b9: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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_01db: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: 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_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: 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_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: 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_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: 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_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			float bottom = ((rise != 1f) ? (-1) : 0);
			Matrix4x4 worldToLocalMatrix = root.transform.worldToLocalMatrix;
			MeshFilter[] componentsInChildren = root.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.sharedMesh))
				{
					RoofData data = RoofMeshCuts.Get(MeshKey(((Component)val).transform, root.transform, source));
					val.sharedMesh = RoofMeshCuts.Cut(data, worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix, half, bottom, 1f);
				}
			}
			Collider[] componentsInChildren2 = root.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
				if (!Object.op_Implicit((Object)(object)val3))
				{
					throw new InvalidOperationException("Unsupported roof collider " + ((object)val2).GetType().Name);
				}
				Matrix4x4 val4 = worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix;
				Vector3 val5 = val3.size / 2f;
				Vector3 center = val3.center;
				Vector3[] array = (Vector3[])(object)new Vector3[8]
				{
					center + new Vector3(0f - val5.x, 0f - val5.y, 0f - val5.z),
					center + new Vector3(val5.x, 0f - val5.y, 0f - val5.z),
					center + new Vector3(val5.x, val5.y, 0f - val5.z),
					center + new Vector3(0f - val5.x, val5.y, 0f - val5.z),
					center + new Vector3(0f - val5.x, 0f - val5.y, val5.z),
					center + new Vector3(val5.x, 0f - val5.y, val5.z),
					center + new Vector3(val5.x, val5.y, val5.z),
					center + new Vector3(0f - val5.x, val5.y, val5.z)
				};
				for (int j = 0; j < array.Length; j++)
				{
					array[j] = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(array[j]);
				}
				for (int k = 0; k < (half ? 1 : 2); k++)
				{
					Mesh val6 = RoofMeshCuts.CutBox(array, RoofMeshCuts.Planes(half, k, 1f), RoofMeshCuts.Placement(half, k, bottom, 1f), ((Matrix4x4)(ref val4)).inverse);
					if (Object.op_Implicit((Object)(object)val6))
					{
						GameObject val7 = new GameObject("OctRoofCutCollider")
						{
							layer = ((Component)val3).gameObject.layer
						};
						val7.transform.SetParent(((Component)val3).transform, false);
						MeshCollider obj = val7.AddComponent<MeshCollider>();
						obj.sharedMesh = val6;
						obj.convex = true;
						((Collider)obj).sharedMaterial = ((Collider)val3).sharedMaterial;
						((Collider)obj).isTrigger = ((Collider)val3).isTrigger;
						((Collider)obj).enabled = ((Collider)val3).enabled;
					}
				}
				Object.DestroyImmediate((Object)(object)val3);
			}
			Transform[] componentsInChildren3 = root.GetComponentsInChildren<Transform>(true);
			foreach (Transform val8 in componentsInChildren3)
			{
				if (((Component)val8).CompareTag("snappoint"))
				{
					if (half)
					{
						Vector3 val9 = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(val8.position);
						val9.x = Mathf.Clamp(val9.x, -0.5f, 0.5f);
						val8.position = root.transform.TransformPoint(val9);
					}
					else
					{
						Object.DestroyImmediate((Object)(object)((Component)val8).gameObject);
					}
				}
			}
			if (!half)
			{
				float num = Mathf.Tan((float)Math.PI / 8f);
				float num2 = Mathf.Sqrt(0.5f);
				float num3 = 1f;
				Snap(root, "Bottom wall corner", new Vector3(1f, 0f, 1f));
				Snap(root, "Bottom side 1", new Vector3(1f, 0f, 1f - num3));
				Snap(root, "Bottom side 2", new Vector3(1f - num3 * num2, 0f, 1f + num3 * num2));
				Snap(root, "Top hip", new Vector3(-1f, rise, 1f - 2f * num));
				Snap(root, "Top side 1", new Vector3(-1f, rise, 1f - num3));
				Snap(root, "Top side 2", new Vector3(1f - num3 * num2 - 2f * num2, rise, 1f + num3 * num2 - 2f * num2));
			}
			LODGroup[] componentsInChildren4 = root.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				componentsInChildren4[i].RecalculateBounds();
			}
			WearNTear component = root.GetComponent<WearNTear>();
			if (!half)
			{
				component.m_comOffset = new Vector3(0f, rise / 2f, 0.5f);
			}
		}

		private void Register()
		{
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0183: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Expected O, but got Unknown
			if (registered)
			{
				return;
			}
			try
			{
				int num = 0;
				bool[] array = new bool[2] { false, true };
				foreach (bool flag in array)
				{
					int[] array2 = new int[3] { 26, 45, 67 };
					for (int j = 0; j < array2.Length; j++)
					{
						int num2 = array2[j];
						bool[] array3 = new bool[2] { false, true };
						foreach (bool flag2 in array3)
						{
							float rise = num2 switch
							{
								45 => 2, 
								26 => 1, 
								_ => 4, 
							};
							string text = (flag2 ? "darkwood_roof" : "wood_roof");
							string text2 = ((num2 == 26) ? "" : ("_" + num2));
							string text3 = text + text2;
							string text4 = "oct_roof_" + (flag2 ? "shingle" : "thatch") + "_" + num2 + (flag ? "_half_width" : "_outer_turn45");
							if (PieceManager.Instance.GetPiece(text4) == null)
							{
								GameObject prefab = PrefabManager.Instance.GetPrefab(text3);
								if (!Object.op_Implicit((Object)(object)prefab))
								{
									throw new InvalidOperationException("Missing roof " + text3);
								}
								GameObject val = PrefabManager.Instance.CreateClonedPrefab(text4, prefab);
								Reshape(val, text3, rise, flag);
								List<RequirementConfig> list = new List<RequirementConfig>
								{
									new RequirementConfig
									{
										Item = "Wood",
										Amount = (flag ? 1 : 2),
										Recover = true
									}
								};
								if (flag2)
								{
									list.Add(new RequirementConfig
									{
										Item = "Tar",
										Amount = 1,
										Recover = true
									});
								}
								PieceConfig val2 = new PieceConfig();
								val2.Name = (flag2 ? "Shingle" : "Thatch") + " Roof " + num2 + "° - " + (flag ? "Half Width" : "Outer 45° Turn");
								val2.Description = (flag ? "A true 1m cut of the standard roof panel. Original board widths, texture scale, length and slope." : ("Cut roof panels for a 45-degree wall turn (135-degree inside angle). Covers 1m along each wall. Original board widths and " + num2 + "-degree roof slope."));
								val2.PieceTable = "Hammer";
								val2.Category = "BuildingWorkbench";
								val2.Usage = new string[2] { "Building", "Roof" };
								val2.CraftingStation = "piece_workbench";
								val2.Requirements = list.ToArray();
								PieceConfig val3 = val2;
								GameObject val4 = (flag ? prefab : PrefabManager.Instance.GetPrefab(text + "_ocorner" + text2));
								val.GetComponent<Piece>().m_icon = val4.GetComponent<Piece>().m_icon;
								if (!PieceManager.Instance.AddPiece(new CustomPiece(val, false, val3)))
								{
									throw new InvalidOperationException("Could not register " + text4);
								}
								num++;
							}
						}
					}
				}
				registered = true;
				PrefabManager.OnVanillaPrefabsAvailable -= Register;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered " + num + " cut roofs with native-width boards and native icons."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Roof registration failed: " + ex));
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
		}
	}
}

plugins/TowerStairs.dll

Decompiled 33 minutes ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace OctoberJemini.TowerStairs;

[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("OctoberJemini.TowerStairs", "Tower Stairs", "0.4.2")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Guid = "OctoberJemini.TowerStairs";

	private readonly List<GameObject> pieces = new List<GameObject>();

	private bool registered;

	private bool iconsDone;

	private void Awake()
	{
		PrefabManager.OnVanillaPrefabsAvailable += Register;
		PieceManager.OnPiecesRegistered += Icons;
	}

	private static Vector3 V(Point p)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3((float)p.X, (float)p.Y, (float)p.Z);
	}

	private static Mesh MakeMesh(StairLayout layout, int direction, bool walkingCollision = false, bool smooth = false)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Expected O, but got Unknown
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		StairGeometry stairGeometry = layout.Build(direction, walkingCollision);
		Vector3[] array = (Vector3[])(object)new Vector3[stairGeometry.Vertices.Count];
		Vector2[] array2 = (Vector2[])(object)new Vector2[array.Length];
		Color[] array3 = (Color[])(object)new Color[array.Length];
		for (int i = 0; i < array.Length; i++)
		{
			ref Vector3 reference = ref array[i];
			reference = V(stairGeometry.Vertices[i]);
			ref Vector2 reference2 = ref array2[i];
			reference2 = new Vector2((float)stairGeometry.UVs[i].X, (float)stairGeometry.UVs[i].Y);
			ref Color reference3 = ref array3[i];
			reference3 = Color.white;
		}
		Mesh val = new Mesh();
		((Object)val).name = "TowerStairs_" + layout.Id + "_" + direction;
		val.vertices = array;
		val.uv = array2;
		val.colors = array3;
		val.triangles = stairGeometry.Triangles.ToArray();
		Mesh val2 = val;
		if (smooth)
		{
			for (int j = 0; j < array2.Length; j++)
			{
				ref Vector2 reference4 = ref array2[j];
				reference4 = new Vector2(0.05f + array2[j].x * 0.8f, 0.53f + array2[j].y * 0.55f);
			}
			val2.uv = array2;
		}
		val2.RecalculateNormals();
		val2.RecalculateTangents();
		val2.RecalculateBounds();
		return val2;
	}

	private static GameObject Visual(GameObject parent, string name, Mesh mesh, Material material)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		GameObject val = new GameObject(name);
		val.layer = parent.layer;
		val.transform.SetParent(parent.transform, false);
		val.AddComponent<MeshFilter>().sharedMesh = mesh;
		((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
		return val;
	}

	private static Material MaterialFor(GameObject state, Material fallback)
	{
		if (!Object.op_Implicit((Object)(object)state))
		{
			return fallback;
		}
		MeshRenderer componentInChildren = state.GetComponentInChildren<MeshRenderer>(true);
		if (!Object.op_Implicit((Object)(object)componentInChildren) || !Object.op_Implicit((Object)(object)((Renderer)componentInChildren).sharedMaterial))
		{
			return fallback;
		}
		return ((Renderer)componentInChildren).sharedMaterial;
	}

	private static Material SmoothMaterialFor(GameObject state, Material fallback)
	{
		if (Object.op_Implicit((Object)(object)state))
		{
			MeshRenderer[] componentsInChildren = state.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val2) && ((Object)val2).name.StartsWith("stonefloor_2x2"))
					{
						return val2;
					}
				}
			}
		}
		return fallback;
	}

	private void Register()
	{
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		//IL_034a: Unknown result type (might be due to invalid IL or missing references)
		//IL_034f: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bb: Expected O, but got Unknown
		//IL_0616: Unknown result type (might be due to invalid IL or missing references)
		//IL_061d: Expected O, but got Unknown
		//IL_0651: Unknown result type (might be due to invalid IL or missing references)
		//IL_065b: Expected O, but got Unknown
		if (registered)
		{
			return;
		}
		try
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("stone_stair");
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Vanilla stone_stair not available.");
			}
			WearNTear component = prefab.GetComponent<WearNTear>();
			Material val = MaterialFor(component.m_new, null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Stone stair material not available.");
			}
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("stone_floor_2x2");
			if (!Object.op_Implicit((Object)(object)prefab2))
			{
				throw new InvalidOperationException("Vanilla stone_floor_2x2 unavailable.");
			}
			WearNTear component2 = prefab2.GetComponent<WearNTear>();
			Material val2 = SmoothMaterialFor(component2.m_new, null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				throw new InvalidOperationException("Smooth stone floor material unavailable.");
			}
			StairLayout[] array = StairLayout.All();
			foreach (StairLayout stairLayout in array)
			{
				int[] array2 = new int[2] { 1, -1 };
				foreach (int num in array2)
				{
					bool[] array3 = new bool[2] { false, true };
					foreach (bool flag in array3)
					{
						if (flag && (stairLayout.Legacy || stairLayout.Length != 2.0))
						{
							continue;
						}
						WearNTear val3 = (flag ? component2 : component);
						Material val4 = (flag ? val2 : val);
						string text = ((num == 1) ? "cw" : "ccw");
						string text2 = "oct_tower_stairs_" + stairLayout.Id + (flag ? "_smooth" : "") + "_" + text;
						if (PieceManager.Instance.GetPiece(text2) == null)
						{
							GameObject val5 = PrefabManager.Instance.CreateClonedPrefab(text2, prefab);
							for (int num2 = val5.transform.childCount - 1; num2 >= 0; num2--)
							{
								Object.DestroyImmediate((Object)(object)((Component)val5.transform.GetChild(num2)).gameObject);
							}
							Collider[] components = val5.GetComponents<Collider>();
							foreach (Collider val6 in components)
							{
								Object.DestroyImmediate((Object)(object)val6);
							}
							Renderer[] components2 = val5.GetComponents<Renderer>();
							foreach (Renderer val7 in components2)
							{
								Object.DestroyImmediate((Object)(object)val7);
							}
							MeshFilter[] components3 = val5.GetComponents<MeshFilter>();
							foreach (MeshFilter val8 in components3)
							{
								Object.DestroyImmediate((Object)(object)val8);
							}
							val5.transform.localRotation = Quaternion.identity;
							val5.transform.localScale = Vector3.one;
							Mesh val9 = MakeMesh(stairLayout, num, walkingCollision: false, flag);
							WearNTear component3 = val5.GetComponent<WearNTear>();
							component3.m_new = Visual(val5, "new", val9, val4);
							component3.m_worn = Visual(val5, "worn", val9, flag ? SmoothMaterialFor(val3.m_worn, val4) : MaterialFor(val3.m_worn, val4));
							component3.m_broken = Visual(val5, "broken", val9, flag ? SmoothMaterialFor(val3.m_broken, val4) : MaterialFor(val3.m_broken, val4));
							component3.m_worn.SetActive(false);
							component3.m_broken.SetActive(false);
							Bounds bounds = val9.bounds;
							component3.m_comOffset = ((Bounds)(ref bounds)).center;
							component3.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { component3.m_new };
							AddPlacementColliders(val5, stairLayout, num);
							bool[] array4 = new bool[2] { false, true };
							foreach (bool flag2 in array4)
							{
								Snap(val5, "Start " + (flag2 ? "outer" : "wall"), stairLayout.Edge(0.0, flag2, 0.0, num));
								Snap(val5, "End " + (flag2 ? "outer" : "wall"), stairLayout.Edge(1.0, flag2, stairLayout.Rise, num));
							}
							Snap(val5, "Start centre", Midpoint(stairLayout.Edge(0.0, free: false, 0.0, num), stairLayout.Edge(0.0, free: true, 0.0, num)));
							Snap(val5, "End centre", Midpoint(stairLayout.Edge(1.0, free: false, stairLayout.Rise, num), stairLayout.Edge(1.0, free: true, stairLayout.Rise, num)));
							PieceConfig val10 = new PieceConfig();
							val10.Name = "Tower Stairs " + stairLayout.Label + (flag ? " Smooth Stone " : " Stone ") + ((num == 1) ? "Clockwise" : "Counterclockwise");
							val10.Enabled = !flag && !stairLayout.Legacy && stairLayout.Length != 1.0;
							val10.Description = (stairLayout.Legacy ? "Original R4 exterior prototype." : $"Fits {stairLayout.Length}m poles turned {stairLayout.Angle * 180.0 / Math.PI} degrees. {stairLayout.Width}m wide, {stairLayout.Rise}m rise. Align wall edge with pole centreline; rotate {(int)Math.Round(stairLayout.Angle / (Math.PI / 8.0))} clicks between sections.");
							val10.PieceTable = "Hammer";
							val10.Category = "BuildingStonecutter";
							val10.Usage = new string[2] { "Building", "Stairs" };
							val10.CraftingStation = "piece_stonecutter";
							RequirementConfig[] array5 = (RequirementConfig[])(object)new RequirementConfig[1];
							RequirementConfig val11 = new RequirementConfig();
							val11.Item = "Stone";
							val11.Amount = 8;
							val11.Recover = true;
							array5[0] = val11;
							val10.Requirements = array5;
							PieceConfig val12 = val10;
							if (!PieceManager.Instance.AddPiece(new CustomPiece(val5, false, val12)))
							{
								throw new InvalidOperationException("Could not register " + text2);
							}
							pieces.Add(val5);
						}
					}
				}
			}
			RegisterRailings();
			registered = true;
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered original R4 stairs and pole-matched inside/outside stairs in both directions.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Tower stair registration failed: " + ex));
		}
	}

	private static Point Midpoint(Point a, Point b)
	{
		return new Point((a.X + b.X) / 2.0, (a.Y + b.Y) / 2.0, (a.Z + b.Z) / 2.0);
	}

	private static void AddPlacementColliders(GameObject parent, StairLayout layout, int direction)
	{
		//IL_0078: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Expected O, but got Unknown
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		StairGeometry stairGeometry = layout.Build(direction, walkingCollision: true);
		if (stairGeometry.Vertices.Count % 24 != 0 || stairGeometry.Triangles.Count != stairGeometry.Vertices.Count / 24 * 36)
		{
			throw new InvalidOperationException("Unexpected stair collision cell layout.");
		}
		for (int i = 0; i < stairGeometry.Vertices.Count / 24; i++)
		{
			Vector3[] array = (Vector3[])(object)new Vector3[24];
			int[] array2 = new int[36];
			for (int j = 0; j < 24; j++)
			{
				ref Vector3 reference = ref array[j];
				reference = V(stairGeometry.Vertices[i * 24 + j]);
			}
			for (int k = 0; k < 36; k++)
			{
				array2[k] = stairGeometry.Triangles[i * 36 + k] - i * 24;
			}
			Mesh val = new Mesh();
			((Object)val).name = ((Object)parent).name + "_collision_" + i;
			val.vertices = array;
			val.triangles = array2;
			Mesh val2 = val;
			val2.RecalculateBounds();
			GameObject val3 = new GameObject("collider_" + i);
			val3.layer = parent.layer;
			val3.transform.SetParent(parent.transform, false);
			MeshCollider val4 = val3.AddComponent<MeshCollider>();
			val4.sharedMesh = val2;
			val4.convex = true;
		}
	}

	private static void Snap(GameObject parent, string name, Point p)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.tag = "snappoint";
		val.transform.SetParent(parent.transform, false);
		val.transform.localPosition = V(p);
	}

	private void Icons()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		OrderPieces();
		if (iconsDone || !registered || (int)SystemInfo.graphicsDeviceType == 4)
		{
			return;
		}
		foreach (GameObject piece in pieces)
		{
			try
			{
				string resource = (((Object)piece).name.StartsWith("oct_tower_rail_") ? (((Object)piece).name + ".png") : (((Object)piece).name.Substring("oct_tower_stairs_".Length) + ".png"));
				piece.GetComponent<Piece>().m_icon = LoadIcon(resource);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Stair thumbnail: " + ex.Message));
			}
		}
		iconsDone = true;
	}

	private static Sprite LoadIcon(string resource)
	{
		//IL_0063: 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)
		using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream(resource);
		using MemoryStream memoryStream = new MemoryStream();
		if (stream == null)
		{
			throw new InvalidOperationException("Missing thumbnail " + resource);
		}
		stream.CopyTo(memoryStream);
		Texture2D val = AssetUtils.LoadImage(memoryStream.ToArray());
		((Texture)val).filterMode = (FilterMode)1;
		return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= Register;
		PieceManager.OnPiecesRegistered -= Icons;
	}

	private static Mesh RailTimberMesh(GameObject source)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//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_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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: 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_013d: 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_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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		MeshFilter componentInChildren = source.GetComponent<WearNTear>().m_new.GetComponentInChildren<MeshFilter>(true);
		if (!Object.op_Implicit((Object)(object)componentInChildren))
		{
			throw new InvalidOperationException("Wood beam mesh missing.");
		}
		Mesh val = Object.Instantiate<Mesh>(componentInChildren.sharedMesh);
		Vector3[] vertices = val.vertices;
		Matrix4x4 val2 = source.transform.worldToLocalMatrix * ((Component)componentInChildren).transform.localToWorldMatrix;
		Bounds val3 = default(Bounds);
		((Bounds)(ref val3))..ctor(((Matrix4x4)(ref val2)).MultiplyPoint3x4(vertices[0]), Vector3.zero);
		for (int i = 0; i < vertices.Length; i++)
		{
			ref Vector3 reference = ref vertices[i];
			reference = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(vertices[i]);
			((Bounds)(ref val3)).Encapsulate(vertices[i]);
		}
		Vector3 size = ((Bounds)(ref val3)).size;
		Quaternion val4 = Quaternion.FromToRotation((Vector3)(((!(size.x >= size.y) || !(size.x >= size.z)) ? ((size.y >= size.z) ? 1 : 2) : 0) switch
		{
			1 => Vector3.up, 
			0 => Vector3.right, 
			_ => Vector3.forward, 
		}), Vector3.forward);
		for (int j = 0; j < vertices.Length; j++)
		{
			Vector3 val5 = vertices[j] - ((Bounds)(ref val3)).center;
			((Vector3)(ref val5))..ctor(val5.x / size.x, val5.y / size.y, val5.z / size.z);
			ref Vector3 reference2 = ref vertices[j];
			reference2 = val4 * val5;
		}
		((Object)val).name = "TowerRail_Timber";
		val.vertices = vertices;
		val.RecalculateNormals();
		val.RecalculateTangents();
		val.RecalculateBounds();
		return val;
	}

	private static Vector2[] TimberLongitudinalUV(Mesh mesh)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] vertices = mesh.vertices;
		Vector2[] uv = mesh.uv;
		int[] triangles = mesh.triangles;
		Vector2[] array = (Vector2[])(object)new Vector2[vertices.Length];
		float[] array2 = new float[vertices.Length];
		Vector2 val8 = default(Vector2);
		for (int i = 0; i < triangles.Length; i += 3)
		{
			int num = triangles[i];
			int num2 = triangles[i + 1];
			int num3 = triangles[i + 2];
			Vector3 val = vertices[num2] - vertices[num];
			Vector3 val2 = vertices[num3] - vertices[num];
			Vector3 val3 = Vector3.Cross(val, val2);
			float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
			if (!(sqrMagnitude < 1E-12f))
			{
				Vector2 val4 = uv[num2] - uv[num];
				Vector2 val5 = uv[num3] - uv[num];
				Vector3 val6 = Vector3.Cross(val2, val3) / sqrMagnitude;
				Vector3 val7 = Vector3.Cross(val3, val) / sqrMagnitude;
				((Vector2)(ref val8))..ctor(val6.z * val4.x + val7.z * val5.x, val6.z * val4.y + val7.z * val5.y);
				float num4 = Mathf.Sqrt(sqrMagnitude);
				int[] array3 = new int[3] { num, num2, num3 };
				foreach (int num5 in array3)
				{
					ref Vector2 reference = ref array[num5];
					reference += val8 * num4;
					array2[num5] += num4;
				}
			}
		}
		for (int k = 0; k < array.Length; k++)
		{
			if (array2[k] > 0f)
			{
				ref Vector2 reference2 = ref array[k];
				reference2 /= array2[k];
			}
		}
		return array;
	}

	private static List<Mesh> RailTimberSections(List<RailBeam> beams, Mesh template)
	{
		//IL_004a: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		List<Mesh> list = new List<Mesh>();
		Vector3[] vertices = template.vertices;
		Vector2[] uv = template.uv;
		Vector2[] array = TimberLongitudinalUV(template);
		foreach (RailBeam beam in beams)
		{
			Mesh val = Object.Instantiate<Mesh>(template);
			Vector2[] array2 = (Vector2[])(object)new Vector2[uv.Length];
			float num = Vector3.Distance(V(beam.A), V(beam.B)) + 0.012f;
			for (int i = 0; i < array2.Length; i++)
			{
				float num2 = (float)beam.TextureStart - 0.006f + (vertices[i].z + 0.5f) * num - 0.5f;
				ref Vector2 reference = ref array2[i];
				reference = uv[i] + array[i] * (num2 - vertices[i].z);
			}
			val.uv = array2;
			val.RecalculateTangents();
			list.Add(val);
		}
		return list;
	}

	private static GameObject RailVisual(GameObject parent, string name, List<RailBeam> beams, List<Mesh> meshes, Material material)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.layer = parent.layer;
		val.transform.SetParent(parent.transform, false);
		for (int i = 0; i < beams.Count; i++)
		{
			RailBeam railBeam = beams[i];
			GameObject val2 = Visual(val, "Timber", meshes[i], material);
			Vector3 val3 = V(railBeam.A);
			Vector3 val4 = V(railBeam.B);
			val2.transform.localPosition = (val3 + val4) / 2f;
			val2.transform.localRotation = Quaternion.LookRotation(val4 - val3);
			val2.transform.localScale = new Vector3((float)railBeam.Size, (float)railBeam.Size, Vector3.Distance(val3, val4) + 0.012f);
		}
		return val;
	}

	private void RegisterRailings()
	{
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0356: Unknown result type (might be due to invalid IL or missing references)
		//IL_0362: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Expected O, but got Unknown
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: 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_03a0: 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_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_03db: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dd: 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_0414: Unknown result type (might be due to invalid IL or missing references)
		//IL_0419: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cb: Expected O, but got Unknown
		//IL_0606: Unknown result type (might be due to invalid IL or missing references)
		//IL_060d: Expected O, but got Unknown
		//IL_0641: Unknown result type (might be due to invalid IL or missing references)
		//IL_064b: Expected O, but got Unknown
		GameObject prefab = PrefabManager.Instance.GetPrefab("wood_beam_1");
		if (!Object.op_Implicit((Object)(object)prefab))
		{
			throw new InvalidOperationException("Vanilla wood_beam_1 unavailable.");
		}
		WearNTear component = prefab.GetComponent<WearNTear>();
		Mesh template = RailTimberMesh(prefab);
		Material val = MaterialFor(component.m_new, null);
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("Wood beam material unavailable.");
		}
		StairLayout[] array = StairLayout.All();
		Bounds val6 = default(Bounds);
		foreach (StairLayout stairLayout in array)
		{
			if (stairLayout.Legacy || stairLayout.Length != 2.0)
			{
				continue;
			}
			bool[] array2 = new bool[2] { false, true };
			foreach (bool flag in array2)
			{
				bool[] array3 = new bool[2] { false, true };
				foreach (bool flag2 in array3)
				{
					int[] array4 = new int[2] { 1, -1 };
					foreach (int num in array4)
					{
						string text = "oct_tower_rail_" + stairLayout.Id + (flag ? "_curved" : "_fitted") + (flag2 ? "_open" : "_wall") + ((num == 1) ? "_cw" : "_ccw");
						if (PieceManager.Instance.GetPiece(text) != null)
						{
							continue;
						}
						GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(text, prefab);
						for (int num2 = val2.transform.childCount - 1; num2 >= 0; num2--)
						{
							Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(num2)).gameObject);
						}
						Collider[] components = val2.GetComponents<Collider>();
						foreach (Collider val3 in components)
						{
							Object.DestroyImmediate((Object)(object)val3);
						}
						Renderer[] components2 = val2.GetComponents<Renderer>();
						foreach (Renderer val4 in components2)
						{
							Object.DestroyImmediate((Object)(object)val4);
						}
						MeshFilter[] components3 = val2.GetComponents<MeshFilter>();
						foreach (MeshFilter val5 in components3)
						{
							Object.DestroyImmediate((Object)(object)val5);
						}
						val2.transform.localRotation = Quaternion.identity;
						val2.transform.localScale = Vector3.one;
						List<RailBeam> list = RailGeometry.Build(stairLayout, num, flag2, flag);
						List<Mesh> meshes = RailTimberSections(list, template);
						WearNTear component2 = val2.GetComponent<WearNTear>();
						component2.m_new = RailVisual(val2, "new", list, meshes, val);
						component2.m_worn = RailVisual(val2, "worn", list, meshes, MaterialFor(component.m_worn, val));
						component2.m_broken = RailVisual(val2, "broken", list, meshes, MaterialFor(component.m_broken, val));
						component2.m_worn.SetActive(false);
						component2.m_broken.SetActive(false);
						component2.m_fragmentRoots = (GameObject[])(object)new GameObject[1] { component2.m_new };
						((Bounds)(ref val6))..ctor(V(list[0].A), Vector3.zero);
						foreach (RailBeam item in list)
						{
							Vector3 val7 = V(item.A);
							Vector3 val8 = V(item.B);
							((Bounds)(ref val6)).Encapsulate(val7);
							((Bounds)(ref val6)).Encapsulate(val8);
							GameObject val9 = new GameObject("collider");
							val9.layer = val2.layer;
							val9.transform.SetParent(val2.transform, false);
							val9.transform.localPosition = (val7 + val8) / 2f;
							val9.transform.localRotation = Quaternion.LookRotation(val8 - val7);
							val9.AddComponent<BoxCollider>().size = new Vector3((float)item.Size, (float)item.Size, Vector3.Distance(val7, val8) + 0.012f);
						}
						component2.m_comOffset = ((Bounds)(ref val6)).center;
						Snap(val2, "Stair lower mount", stairLayout.Edge(0.0, flag2, 0.0, num));
						Snap(val2, "Stair upper mount", stairLayout.Edge(1.0, flag2, stairLayout.Rise, num));
						Snap(val2, "Handrail lower joint", RailGeometry.Path(stairLayout, num, flag2, flag, 0.0, 1.0));
						Snap(val2, "Handrail upper joint", RailGeometry.Path(stairLayout, num, flag2, flag, 1.0, 1.0));
						PieceConfig val10 = new PieceConfig();
						val10.Enabled = flag;
						val10.Name = "Tower Rail " + stairLayout.Label + " " + ((flag2 == stairLayout.Inside) ? "Inner Edge" : "Outer Edge") + " " + (flag ? "Curved" : "Fitted") + " " + ((num == 1) ? "Clockwise" : "Counterclockwise");
						val10.Description = string.Format("Wood railing for Tower Stairs {0}. {1} edge, {2}m rise, 1m handrail height. Snap Stair lower/upper mount to matching stair corner. {3}", stairLayout.Label, flag2 ? "open" : "wall", stairLayout.Rise, flag ? "Curved handrail with posts anchored to the straight stair edge." : "Straight handrail follows the polygon edge.");
						val10.PieceTable = "Hammer";
						val10.Category = "BuildingWorkbench";
						val10.Usage = new string[1] { "Building" };
						val10.CraftingStation = "piece_workbench";
						RequirementConfig[] array5 = (RequirementConfig[])(object)new RequirementConfig[1];
						RequirementConfig val11 = new RequirementConfig();
						val11.Item = "Wood";
						val11.Amount = 4;
						val11.Recover = true;
						array5[0] = val11;
						val10.Requirements = array5;
						PieceConfig val12 = val10;
						if (!PieceManager.Instance.AddPiece(new CustomPiece(val2, false, val12)))
						{
							throw new InvalidOperationException("Could not register " + text);
						}
						pieces.Add(val2);
					}
				}
			}
		}
	}

	private void OrderPieces()
	{
		PieceTable pieceTable = PieceManager.Instance.GetPieceTable("Hammer");
		if (!Object.op_Implicit((Object)(object)pieceTable))
		{
			return;
		}
		HashSet<GameObject> owned = new HashSet<GameObject>(pieces);
		int num = pieceTable.m_pieces.FindIndex((GameObject p) => owned.Contains(p));
		if (num < 0)
		{
			return;
		}
		pieceTable.m_pieces.RemoveAll((GameObject p) => owned.Contains(p));
		List<GameObject> list = new List<GameObject>();
		StairLayout[] array = StairLayout.All();
		foreach (StairLayout layout in array)
		{
			if (layout.Legacy || layout.Length != 2.0)
			{
				continue;
			}
			string[] array2 = new string[2] { "cw", "ccw" };
			foreach (string dir in array2)
			{
				string[] array3 = new string[1] { "" };
				foreach (string finish in array3)
				{
					List<GameObject> list2 = pieces;
					Predicate<GameObject> match = (GameObject x) => ((Object)x).name == "oct_tower_stairs_" + layout.Id + finish + "_" + dir;
					GameObject val = list2.Find(match);
					if (Object.op_Implicit((Object)(object)val))
					{
						list.Add(val);
					}
				}
				bool[] array4 = new bool[2] { true, false };
				foreach (bool flag in array4)
				{
					bool free = flag == layout.Inside;
					GameObject val2 = pieces.Find((GameObject x) => ((Object)x).name == "oct_tower_rail_" + layout.Id + "_curved" + (free ? "_open" : "_wall") + "_" + dir);
					if (Object.op_Implicit((Object)(object)val2))
					{
						list.Add(val2);
					}
				}
			}
		}
		pieceTable.m_pieces.InsertRange(Math.Min(num, pieceTable.m_pieces.Count), list);
	}
}
public struct Point
{
	public double X;

	public double Y;

	public double Z;

	public Point(double x, double y, double z)
	{
		X = x;
		Y = y;
		Z = z;
	}
}
public sealed class StairGeometry
{
	public const double Radius = 4.0;

	public const double Width = 2.0;

	public const double Rise = 1.0;

	public const double Angle = Math.PI / 8.0;

	public const double Thickness = 0.3;

	public const int Steps = 5;

	public const int Divisions = 3;

	public readonly List<Point> Vertices = new List<Point>();

	public readonly List<int> Triangles = new List<int>();

	public readonly List<Point> UVs = new List<Point>();

	public static Point Edge(double t, bool outer, double y, int direction)
	{
		if (!outer)
		{
			return new Point((double)direction * 4.0 * Math.Sin(Math.PI / 8.0) * t, y, 4.0 * (Math.Cos(Math.PI / 8.0) - 1.0) * t);
		}
		return new Point((double)direction * 6.0 * Math.Sin(Math.PI / 8.0 * t), y, 6.0 * Math.Cos(Math.PI / 8.0 * t) - 4.0);
	}

	internal void Quad(Point a, Point b, Point c, Point d, Point outward)
	{
		double num = b.X - a.X;
		double num2 = b.Y - a.Y;
		double num3 = b.Z - a.Z;
		double num4 = c.X - a.X;
		double num5 = c.Y - a.Y;
		double num6 = c.Z - a.Z;
		double num7 = num2 * num6 - num3 * num5;
		double num8 = num3 * num4 - num * num6;
		double num9 = num * num5 - num2 * num4;
		if (num7 * outward.X + num8 * outward.Y + num9 * outward.Z < 0.0)
		{
			Point point = b;
			b = d;
			d = point;
		}
		int count = Vertices.Count;
		bool flag = Math.Abs(outward.Y) > 0.5;
		bool flag2 = Math.Abs(outward.X) > Math.Abs(outward.Z);
		Point[] array = new Point[4] { a, b, c, d };
		for (int i = 0; i < array.Length; i++)
		{
			Point item = array[i];
			Vertices.Add(item);
			double num10 = (flag ? Math.Abs(item.X) : (flag2 ? (item.Z + 0.5) : Math.Abs(item.X)));
			double num11 = (flag ? (item.Z + 0.5) : (item.Y + 0.3));
			UVs.Add(new Point(0.025 + num10 * 0.25, 0.025 + num11 * 0.125, 0.0));
		}
		Triangles.AddRange(new int[6]
		{
			count,
			count + 1,
			count + 2,
			count,
			count + 2,
			count + 3
		});
	}

	public static StairGeometry Build(int direction)
	{
		if (direction != 1 && direction != -1)
		{
			throw new ArgumentException("Direction must be +1 or -1.");
		}
		StairGeometry stairGeometry = new StairGeometry();
		for (int i = 0; i < 5; i++)
		{
			double y = (double)(i + 1) * 1.0 / 5.0;
			for (int j = 0; j < 3; j++)
			{
				double num = ((double)i + (double)j / 3.0) / 5.0;
				double num2 = ((double)i + (double)(j + 1) / 3.0) / 5.0;
				Point a = Edge(num, outer: false, y, direction);
				Point point = Edge(num, outer: true, y, direction);
				Point point2 = Edge(num2, outer: true, y, direction);
				Point point3 = Edge(num2, outer: false, y, direction);
				Point point4 = Edge(num, outer: false, num * 1.0 - 0.3, direction);
				Point point5 = Edge(num, outer: true, num * 1.0 - 0.3, direction);
				Point point6 = Edge(num2, outer: false, num2 * 1.0 - 0.3, direction);
				Point c = Edge(num2, outer: true, num2 * 1.0 - 0.3, direction);
				double num3 = Math.PI / 8.0 * (num + num2) / 2.0;
				Point outward = new Point((double)direction * Math.Sin(num3), 0.0, Math.Cos(num3));
				stairGeometry.Quad(a, point, point2, point3, new Point(0.0, 1.0, 0.0));
				stairGeometry.Quad(point4, point6, c, point5, new Point(0.0, -1.0, 0.0));
				stairGeometry.Quad(a, point3, point6, point4, new Point(0.0 - outward.X, 0.0, 0.0 - outward.Z));
				stairGeometry.Quad(point, point5, c, point2, outward);
				stairGeometry.Quad(a, point4, point5, point, new Point((double)(-direction) * Math.Cos(Math.PI / 8.0 * num), 0.0, Math.Sin(Math.PI / 8.0 * num)));
				stairGeometry.Quad(point3, point2, c, point6, new Point((double)direction * Math.Cos(Math.PI / 8.0 * num2), 0.0, 0.0 - Math.Sin(Math.PI / 8.0 * num2)));
			}
		}
		return stairGeometry;
	}
}
public sealed class StairLayout
{
	public string Id;

	public string Label;

	public double Length;

	public double Angle;

	public double Width;

	public double Rise;

	public int Steps;

	public bool Inside;

	public bool Legacy;

	public bool SmoothWalking;

	public static StairLayout[] All()
	{
		List<StairLayout> list = new List<StairLayout>();
		list.Add(new StairLayout
		{
			Id = "r4_outer",
			Label = "R4",
			Legacy = true,
			Rise = 1.0,
			Angle = Math.PI / 8.0
		});
		bool[] array = new bool[2] { true, false };
		foreach (bool flag in array)
		{
			bool[] array2 = new bool[2] { false, true };
			foreach (bool flag2 in array2)
			{
				list.Add(new StairLayout
				{
					Id = (flag ? "pole1_turn2_" : "pole2_turn1_") + (flag2 ? "inside" : "outside"),
					Label = (flag ? "2m / 2 clicks" : "2m / 1 click") + (flag2 ? " Inside" : " Outside"),
					Length = 2.0,
					Angle = (flag ? (Math.PI / 4.0) : (Math.PI / 8.0)),
					Width = ((flag2 && flag) ? 1 : 2),
					Rise = ((flag && flag2) ? 0.4 : (flag ? 0.6 : 1.0)),
					Steps = ((flag && flag2) ? 2 : (flag ? 3 : 5)),
					Inside = flag2
				});
			}
		}
		foreach (StairLayout item in list)
		{
			if (item.Id == "pole1_turn2_inside")
			{
				item.Label = "2m / 2 clicks Inside 1m wide";
			}
		}
		list.Add(new StairLayout
		{
			Id = "pole2_turn2_inside_wide",
			Label = "2m / 2 clicks Inside 2m wide",
			Length = 2.0,
			Angle = Math.PI / 4.0,
			Width = 2.0,
			Rise = 0.4,
			Steps = 2,
			Inside = true
		});
		bool[] array3 = new bool[2] { false, true };
		foreach (bool flag3 in array3)
		{
			list.Add(new StairLayout
			{
				Id = "pole1_turn2_restored_" + (flag3 ? "inside" : "outside"),
				Label = "1m / 2 clicks " + (flag3 ? "Inside" : "Outside"),
				Length = 1.0,
				Angle = Math.PI / 4.0,
				Width = (flag3 ? 1 : 2),
				Rise = (flag3 ? 0.4 : 0.6),
				Steps = (flag3 ? 2 : 3),
				Inside = flag3
			});
		}
		foreach (StairLayout item2 in list)
		{
			if (!item2.Legacy && item2.Length == 2.0 && Math.Abs(item2.Angle - Math.PI / 4.0) < 1E-09)
			{
				item2.Rise = 1.0;
				item2.Steps = 8;
				item2.SmoothWalking = true;
			}
		}
		foreach (StairLayout item3 in list)
		{
			if (!item3.Legacy && item3.Length == 2.0)
			{
				item3.Label = "2M-" + ((item3.Angle > 0.5) ? "45°" : "22.5°") + " " + (item3.Inside ? "Inner" : "Outer") + ((item3.Inside && item3.Width == 1.0) ? " Narrow" : "");
			}
		}
		list.Sort(delegate(StairLayout a, StairLayout b)
		{
			int num = ((a.Legacy || a.Length != 2.0) ? 1 : 0);
			int value = ((b.Legacy || b.Length != 2.0) ? 1 : 0);
			int num2 = num.CompareTo(value);
			if (num2 != 0)
			{
				return num2;
			}
			num2 = b.Angle.CompareTo(a.Angle);
			if (num2 != 0)
			{
				return num2;
			}
			num2 = b.Inside.CompareTo(a.Inside);
			return (num2 != 0) ? num2 : a.Width.CompareTo(b.Width);
		});
		return list.ToArray();
	}

	public Point Edge(double t, bool free, double y, int direction)
	{
		if (Legacy)
		{
			return StairGeometry.Edge(t, free, y, direction);
		}
		double num = ((!free) ? 0.0 : (Inside ? (0.0 - Width) : Width));
		double num2 = num * Math.Tan(Angle / 2.0);
		return new Point((double)direction * (0.0 - num2 + t * (Length + 2.0 * num2)), y, num);
	}

	public StairGeometry Build(int direction, bool walkingCollision = false)
	{
		if (Legacy)
		{
			return StairGeometry.Build(direction);
		}
		if (direction != 1 && direction != -1)
		{
			throw new ArgumentException("Invalid direction");
		}
		if (Inside && Width >= Length / (2.0 * Math.Tan(Angle / 2.0)))
		{
			throw new ArgumentException("Stairs reach circle centre");
		}
		StairGeometry stairGeometry = new StairGeometry();
		for (int i = 0; i < Steps; i++)
		{
			double num = (double)i / (double)Steps;
			double num2 = (double)(i + 1) / (double)Steps;
			double num3 = num2 * Rise;
			double y = ((walkingCollision && SmoothWalking) ? (num * Rise) : num3);
			Point a = Edge(num, free: false, y, direction);
			Point point = Edge(num, free: true, y, direction);
			Point point2 = Edge(num2, free: true, num3, direction);
			Point point3 = Edge(num2, free: false, num3, direction);
			Point point4 = Edge(num, free: false, num * Rise - 0.3, direction);
			Point point5 = Edge(num, free: true, num * Rise - 0.3, direction);
			Point point6 = Edge(num2, free: false, num2 * Rise - 0.3, direction);
			Point c = Edge(num2, free: true, num2 * Rise - 0.3, direction);
			double num4 = ((!Inside) ? 1 : (-1));
			stairGeometry.Quad(a, point, point2, point3, new Point(0.0, 1.0, 0.0));
			stairGeometry.Quad(point4, point6, c, point5, new Point(0.0, -1.0, 0.0));
			stairGeometry.Quad(a, point3, point6, point4, new Point(0.0, 0.0, 0.0 - num4));
			stairGeometry.Quad(point, point5, c, point2, new Point(0.0, 0.0, num4));
			stairGeometry.Quad(a, point4, point5, point, new Point(-direction, 0.0, 0.0));
			stairGeometry.Quad(point3, point2, c, point6, new Point(direction, 0.0, 0.0));
		}
		double num5 = double.MaxValue;
		double num6 = double.MinValue;
		double num7 = double.MaxValue;
		double num8 = double.MinValue;
		foreach (Point vertex in stairGeometry.Vertices)
		{
			num5 = Math.Min(num5, vertex.X);
			num6 = Math.Max(num6, vertex.X);
			num7 = Math.Min(num7, vertex.Z);
			num8 = Math.Max(num8, vertex.Z);
		}
		double num9 = Math.Min(0.62 / Math.Max(num6 - num5, num8 - num7), 0.29 / Math.Max(num8 - num7, Rise + 0.3));
		for (int j = 0; j < stairGeometry.Vertices.Count; j += 4)
		{
			Point point7 = stairGeometry.Vertices[j];
			Point point8 = stairGeometry.Vertices[j + 1];
			Point point9 = stairGeometry.Vertices[j + 2];
			double value = (point8.Y - point7.Y) * (point9.Z - point7.Z) - (point8.Z - point7.Z) * (point9.Y - point7.Y);
			double value2 = (point8.Z - point7.Z) * (point9.X - point7.X) - (point8.X - point7.X) * (point9.Z - point7.Z);
			double value3 = (point8.X - point7.X) * (point9.Y - point7.Y) - (point8.Y - point7.Y) * (point9.X - point7.X);
			bool flag = Math.Abs(value2) > Math.Max(Math.Abs(value), Math.Abs(value3));
			for (int k = 0; k < 4; k++)
			{
				Point point10 = stairGeometry.Vertices[j + k];
				double num10 = ((Math.Abs(value) > Math.Abs(value3) && !flag) ? (point10.Z - num7) : (point10.X - num5));
				double num11 = (flag ? (point10.Z - num7) : (point10.Y + 0.3));
				stairGeometry.UVs[j + k] = new Point(0.025 + num10 * num9, 0.025 + num11 * num9, 0.0);
			}
		}
		return stairGeometry;
	}
}
public struct RailBeam
{
	public Point A;

	public Point B;

	public double Size;

	public double TextureStart;

	public RailBeam(Point a, Point b, double size, double textureStart = 0.0)
	{
		A = a;
		B = b;
		Size = size;
		TextureStart = textureStart;
	}
}
public static class RailGeometry
{
	public const double Height = 1.0;

	public static Point Path(StairLayout l, int dir, bool free, bool curved, double t, double height)
	{
		if (!curved)
		{
			return l.Edge(t, free, t * l.Rise + height, dir);
		}
		double num = l.Length / (2.0 * Math.Tan(l.Angle / 2.0));
		double num2 = ((!free) ? 0.0 : (l.Inside ? (0.0 - l.Width) : l.Width));
		double num3 = (num + num2) / Math.Cos(l.Angle / 2.0);
		double num4 = (t - 0.5) * l.Angle;
		return new Point((double)dir * (l.Length / 2.0 + num3 * Math.Sin(num4)), t * l.Rise + height, 0.0 - num + num3 * Math.Cos(num4));
	}

	public static List<RailBeam> Build(StairLayout l, int dir, bool free, bool curved)
	{
		List<RailBeam> list = new List<RailBeam>();
		int num = ((!curved) ? 1 : 12);
		double[] array = new double[2] { 0.45, 1.0 };
		foreach (double num2 in array)
		{
			double num3 = ((num2 == 1.0) ? 0.613 : 0.217);
			for (int j = 0; j < num; j++)
			{
				Point a = Path(l, dir, free, curved, (double)j / (double)num, num2);
				Point b = Path(l, dir, free, curved, (double)(j + 1) / (double)num, num2);
				list.Add(new RailBeam(a, b, (num2 == 1.0) ? 0.2 : 0.14, num3));
				num3 += Math.Sqrt(Math.Pow(b.X - a.X, 2.0) + Math.Pow(b.Y - a.Y, 2.0) + Math.Pow(b.Z - a.Z, 2.0));
			}
		}
		Point point = l.Edge(0.0, free, 0.0, dir);
		Point point2 = l.Edge(1.0, free, 0.0, dir);
		double num4 = Math.Sqrt(Math.Pow(point2.X - point.X, 2.0) + Math.Pow(point2.Z - point.Z, 2.0));
		int num5 = Math.Max(1, (int)Math.Ceiling(num4 / 0.75));
		for (int k = 0; k <= num5; k++)
		{
			double num6 = (double)k / (double)num5;
			double y = ((num6 == 0.0) ? 0.0 : (Math.Ceiling(num6 * (double)l.Steps - 1E-08) * l.Rise / (double)l.Steps - 0.05));
			list.Add(new RailBeam(l.Edge(num6, free, y, dir), Path(l, dir, free, curved, num6, 1.0), 0.18, 0.131 + (double)k * 0.371));
		}
		return list;
	}
}