Decompiled source of GK2 Move Buildings v0.8.0

GK2MoveBuilding.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GK2.Framework;
using HarmonyLib;
using LazyBearTechnology;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Pathfinding;
using Rewired;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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;
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace GK2MoveBuilding
{
	internal sealed class BpPiece
	{
		public string Id;

		public int X;

		public int Y;

		public int R;

		public Dictionary<string, string> Filters;

		public string CraftId;

		public int CraftCount;

		public bool CraftInfinite;

		public Vector3 Offset => new Vector3((float)X * 0.01f, 0f, (float)Y * 0.0125f);
	}
	internal sealed class Blueprint
	{
		public const string Prefix = "GK2BP1:";

		public string Name;

		public readonly List<BpPiece> Pieces = new List<BpPiece>();

		public static string LastText;

		public static string Folder => Path.Combine(Path.Combine(Paths.ConfigPath, "GK2MoveBuilding"), "blueprints");

		public string Encode()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("v", JToken.op_Implicit(1));
			JObject val2 = val;
			if (!string.IsNullOrEmpty(Name))
			{
				val2["n"] = JToken.op_Implicit(Name);
			}
			JArray val3 = new JArray();
			foreach (BpPiece piece in Pieces)
			{
				JObject val4 = new JObject();
				val4.Add("i", JToken.op_Implicit(piece.Id));
				val4.Add("x", JToken.op_Implicit(piece.X));
				val4.Add("y", JToken.op_Implicit(piece.Y));
				val4.Add("r", JToken.op_Implicit(piece.R));
				JObject val5 = val4;
				if (piece.Filters != null && piece.Filters.Count > 0)
				{
					JObject val6 = new JObject();
					foreach (KeyValuePair<string, string> filter in piece.Filters)
					{
						val6[filter.Key] = JToken.op_Implicit(filter.Value);
					}
					val5["f"] = (JToken)(object)val6;
				}
				if (!string.IsNullOrEmpty(piece.CraftId) && piece.CraftCount > 0)
				{
					val5["c"] = (JToken)(piece.CraftInfinite ? new JArray(new object[3] { piece.CraftId, piece.CraftCount, 1 }) : new JArray(new object[2] { piece.CraftId, piece.CraftCount }));
				}
				val3.Add((JToken)(object)val5);
			}
			val2["p"] = (JToken)(object)val3;
			return "GK2BP1:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(((JToken)val2).ToString((Formatting)0, Array.Empty<JsonConverter>())));
		}

		public static bool LooksLike(string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				return text.TrimStart().StartsWith("GK2BP1:", StringComparison.Ordinal);
			}
			return false;
		}

		public static Blueprint Decode(string text, out string error)
		{
			error = null;
			try
			{
				string text2 = new string((text ?? "").Where((char c) => !char.IsWhiteSpace(c)).ToArray());
				if (!text2.StartsWith("GK2BP1:", StringComparison.Ordinal))
				{
					error = "not a blueprint";
					return null;
				}
				JObject val = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(text2.Substring("GK2BP1:".Length))));
				int num = ((val["v"] != null) ? ((int)val["v"]) : 0);
				if (num != 1)
				{
					error = "version " + num;
					return null;
				}
				Blueprint blueprint = new Blueprint
				{
					Name = (string)val["n"]
				};
				JToken obj = val["p"];
				JArray val2 = (JArray)(object)((obj is JArray) ? obj : null);
				if (val2 == null)
				{
					error = "no pieces";
					return null;
				}
				foreach (JToken item in val2)
				{
					string text3 = (string)item[(object)"i"];
					if (string.IsNullOrEmpty(text3))
					{
						continue;
					}
					BpPiece bpPiece = new BpPiece
					{
						Id = text3,
						X = ((item[(object)"x"] != null) ? ((int)item[(object)"x"]) : 0),
						Y = ((item[(object)"y"] != null) ? ((int)item[(object)"y"]) : 0),
						R = ((item[(object)"r"] != null) ? ((int)item[(object)"r"]) : 0)
					};
					JToken obj2 = item[(object)"f"];
					JObject val3 = (JObject)(object)((obj2 is JObject) ? obj2 : null);
					if (val3 != null && ((JContainer)val3).Count > 0)
					{
						bpPiece.Filters = new Dictionary<string, string>();
						foreach (KeyValuePair<string, JToken> item2 in val3)
						{
							bpPiece.Filters[item2.Key] = (string)item2.Value;
						}
					}
					JToken obj3 = item[(object)"c"];
					JArray val4 = (JArray)(object)((obj3 is JArray) ? obj3 : null);
					if (val4 != null && ((JContainer)val4).Count >= 2)
					{
						bpPiece.CraftId = (string)val4[0];
						bpPiece.CraftCount = (int)val4[1];
						bpPiece.CraftInfinite = ((JContainer)val4).Count >= 3 && (int)val4[2] == 1;
					}
					blueprint.Pieces.Add(bpPiece);
				}
				if (blueprint.Pieces.Count == 0)
				{
					error = "no pieces";
					return null;
				}
				return blueprint;
			}
			catch (Exception ex)
			{
				error = ex.Message;
				return null;
			}
		}

		public static string Save(Blueprint bp, string text)
		{
			try
			{
				Directory.CreateDirectory(Folder);
				string text2 = (string.IsNullOrEmpty(bp.Name) ? "layout" : new string(bp.Name.Select((char c) => (!Path.GetInvalidFileNameChars().Contains(c)) ? c : '_').ToArray()));
				string text3 = Path.Combine(Folder, DateTime.Now.ToString("yyyyMMdd-HHmmss") + "_" + text2 + "_" + bp.Pieces.Count + "pcs.txt");
				File.WriteAllText(text3, text, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				return text3;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not save the file: " + ex.Message));
				return null;
			}
		}

		public static Blueprint ForPaste(out string text)
		{
			text = null;
			string text2 = null;
			try
			{
				text2 = GUIUtility.systemCopyBuffer;
			}
			catch
			{
			}
			string error;
			if (LooksLike(text2))
			{
				Blueprint blueprint = Decode(text2, out error);
				if (blueprint != null)
				{
					text = text2;
					return blueprint;
				}
				Plugin.Log.LogWarning((object)("Blueprint: the clipboard string could not be read: " + error));
			}
			if (LooksLike(LastText))
			{
				Blueprint blueprint2 = Decode(LastText, out error);
				if (blueprint2 != null)
				{
					text = LastText;
					return blueprint2;
				}
			}
			try
			{
				if (Directory.Exists(Folder))
				{
					FileInfo fileInfo = (from f in new DirectoryInfo(Folder).GetFiles("*.txt")
						orderby f.LastWriteTimeUtc descending
						select f).FirstOrDefault();
					if (fileInfo != null)
					{
						string text3 = File.ReadAllText(fileInfo.FullName);
						Blueprint blueprint3 = Decode(text3, out error);
						if (blueprint3 != null)
						{
							text = text3;
							return blueprint3;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not read the blueprints folder: " + ex.Message));
			}
			return null;
		}
	}
	internal static class BpCopy
	{
		private sealed class Cand
		{
			public Wgo W;

			public Vector2 Mid;

			public Rect Foot;
		}

		internal static bool Armed;

		private static BuildData _entry;

		private static Vector3? _a;

		private static readonly HashSet<Wgo> _tinted = new HashSet<Wgo>();

		private static float _seenAt;

		private static readonly int[] Layers = new int[3] { 8, 16, 19 };

		private static List<Cand> _cands;

		private static Rect? _drawArea;

		private static List<Rect> _drawPieces;

		private static float _drawY;

		private static Texture2D _white;

		private static bool _drawLogged;

		internal static bool HasFirstCorner => _a.HasValue;

		public static BuildData NewEntry()
		{
			_entry = BuildData.GetDataForRemove();
			return _entry;
		}

		public static bool IsEntry(BuildData d)
		{
			if (d != null)
			{
				return d == _entry;
			}
			return false;
		}

		public static void OnBuildModeEntered(BuildData d)
		{
			bool flag = IsEntry(d);
			if (flag && BuildToolsLink.PlanOn)
			{
				Ui.SayPlanBusy();
				flag = false;
			}
			if (flag && !Armed)
			{
				_a = null;
				_seenAt = Time.unscaledTime;
			}
			if (!flag)
			{
				ClearTint();
			}
			Armed = flag;
			if (!flag)
			{
				_a = null;
			}
		}

		public static void Tick()
		{
			//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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (!Armed)
			{
				return;
			}
			if (Move.BuildModeActive())
			{
				_seenAt = Time.unscaledTime;
			}
			else if (Time.unscaledTime - _seenAt > 1f)
			{
				Armed = false;
				_a = null;
				_cands = null;
				_drawArea = null;
				ClearTint();
				return;
			}
			if (!_a.HasValue || !Why.HaveCenter || _cands == null)
			{
				_drawArea = null;
				return;
			}
			try
			{
				Rect val = Area(_a.Value, Why.Center);
				List<Cand> list = Inside(val);
				_drawArea = val;
				_drawY = Why.Center.y;
				_drawPieces = list.Select((Cand c) => c.Foot).ToList();
				Tint(list.Select((Cand c) => c.W).ToList());
				Frame(val, list);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: selection frame failed: " + ex.Message));
			}
		}

		public static void OnClick()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!Why.HaveCenter)
			{
				return;
			}
			if (!_a.HasValue)
			{
				_a = Why.Center;
				_drawLogged = false;
				_cands = Cands();
				return;
			}
			List<Cand> list = Inside(Area(_a.Value, Why.Center));
			_a = null;
			_drawArea = null;
			ClearTint();
			if (list.Count == 0)
			{
				_cands = null;
				Ui.Say(BpText.CopyNone);
				return;
			}
			_cands = null;
			Finish(list.Select((Cand c) => c.W).ToList());
		}

		private static Rect Area(Vector3 a, Vector3 b)
		{
			//IL_0000: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = BuildConsts.CELL_SIZE * 0.5f;
			return Rect.MinMaxRect(Mathf.Min(a.x, b.x) - val.x, Mathf.Min(a.z, b.z) - val.y, Mathf.Max(a.x, b.x) + val.x, Mathf.Max(a.z, b.z) + val.y);
		}

		public unsafe static void Draw()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if (!Armed || !_drawArea.HasValue || Event.current == null || (int)Event.current.type != 7)
			{
				return;
			}
			try
			{
				if ((Object)(object)_white == (Object)null)
				{
					_white = Texture2D.whiteTexture;
				}
				Rect value = _drawArea.Value;
				if (!_drawLogged)
				{
					_drawLogged = true;
					Vector2 val = Screen(((Rect)(ref value)).xMin, ((Rect)(ref value)).yMin);
					Vector2 val2 = Screen(((Rect)(ref value)).xMax, ((Rect)(ref value)).yMax);
					Plugin.Log.LogInfo((object)("Blueprint: OnGUI draws the area frame: screen " + ((object)(*(Vector2*)(&val))/*cast due to .constrained prefix*/).ToString() + " .. " + ((object)(*(Vector2*)(&val2))/*cast due to .constrained prefix*/).ToString() + " of " + Screen.width + "x" + Screen.height));
				}
				if (_drawPieces != null)
				{
					foreach (Rect drawPiece in _drawPieces)
					{
						Outline(drawPiece, new Color(0.35f, 1f, 0.45f, 0.95f), 2f);
					}
				}
				Outline(value, new Color(1f, 0.85f, 0.2f, 1f), 3f);
			}
			catch
			{
			}
		}

		private static void Outline(Rect r, Color c, float w)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_005a: 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_0062: 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_0064: 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_006c: 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)
			Vector2 val = Screen(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMin);
			Vector2 val2 = Screen(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMin);
			Vector2 val3 = Screen(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMax);
			Vector2 val4 = Screen(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMax);
			Line(val, val2, c, w);
			Line(val2, val3, c, w);
			Line(val3, val4, c, w);
			Line(val4, val, c, w);
		}

		private static Vector2 Screen(float x, float z)
		{
			//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = CameraSystem.WorldToScreenPoint(new Vector3(x, _drawY, z));
			return new Vector2(val.x, (float)Screen.height - val.y);
		}

		private static void Line(Vector2 a, Vector2 b, Color c, float w)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = b - a;
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (!(magnitude < 0.5f))
			{
				Matrix4x4 matrix = GUI.matrix;
				Color color = GUI.color;
				GUIUtility.RotateAroundPivot(Mathf.Atan2(val.y, val.x) * 57.29578f, a);
				GUI.color = c;
				GUI.DrawTexture(new Rect(a.x, a.y - w * 0.5f, magnitude, w), (Texture)(object)_white);
				GUI.color = color;
				GUI.matrix = matrix;
			}
		}

		private static List<Cand> Cands()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_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_00f7: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			List<Cand> list = new List<Cand>();
			foreach (Wgo item in Candidates())
			{
				try
				{
					Bounds val = default(Bounds);
					bool flag = false;
					Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren<Collider>(false);
					foreach (Collider val2 in componentsInChildren)
					{
						if (!((Object)(object)val2 == (Object)null) && val2.enabled && Array.IndexOf(Layers, ((Component)val2).gameObject.layer) >= 0)
						{
							if (!flag)
							{
								val = val2.bounds;
								flag = true;
							}
							else
							{
								((Bounds)(ref val)).Encapsulate(val2.bounds);
							}
						}
					}
					if (!flag)
					{
						Vector3 position = item.Data.Position;
						((Bounds)(ref val))..ctor(position, new Vector3(0.3f, 0.1f, 0.3f));
					}
					list.Add(new Cand
					{
						W = item,
						Mid = new Vector2(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).center.z),
						Foot = new Rect(((Bounds)(ref val)).min.x, ((Bounds)(ref val)).min.z, ((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.z)
					});
				}
				catch
				{
				}
			}
			return list;
		}

		private static List<Cand> Inside(Rect area)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (_cands != null)
			{
				return _cands.Where((Cand c) => (Object)(object)c.W != (Object)null && ((Rect)(ref area)).Contains(c.Mid)).ToList();
			}
			return new List<Cand>();
		}

		private static void Frame(Rect area, List<Cand> inside)
		{
			//IL_004f: 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)
			BuildController val = Move.Controller();
			BuildLayout val2 = (((Object)(object)val != (Object)null) ? val.BuildLayout : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				List<Rect> list = inside.Select((Cand x) => x.Foot).ToList();
				list.Add(area);
				val2.UpdateSelection(new List<Rect> { area }, list);
			}
		}

		private static IEnumerable<Wgo> Candidates()
		{
			IEnumerable<Wgo> enumerable = null;
			try
			{
				BuildManager instance = LazySingleton<BuildManager>.Instance;
				WorldZone val = (((Object)(object)instance != (Object)null) ? instance.WorldZone : null);
				if ((Object)(object)val != (Object)null)
				{
					enumerable = val.Wgos;
				}
			}
			catch
			{
			}
			if (enumerable == null)
			{
				enumerable = Object.FindObjectsOfType<Wgo>();
			}
			foreach (Wgo item in enumerable.ToList())
			{
				if (!((Object)(object)item == (Object)null) && item.Data != null && IsPiece(item.Data))
				{
					yield return item;
				}
			}
		}

		internal static bool IsPiece(WgoData d)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			try
			{
				if (d == null || d.isTempObject || string.IsNullOrEmpty(((ObjectLinkedToDefinition<WGODef>)(object)d).id))
				{
					return false;
				}
				if (d is ConveyorWgoData)
				{
					if (d.GetGameResInt("conveyor_build_is_not_removable") > 0)
					{
						return false;
					}
					if (((ObjectLinkedToDefinition<WGODef>)(object)d).id.StartsWith("zombie_carousel"))
					{
						return false;
					}
					BuildingDef value = null;
					GameBalance.Me.buildableWgos.TryGetValue(((ObjectLinkedToDefinition<WGODef>)(object)d).id, out value);
					return value != null && (int)value.buildingMode == 3;
				}
				return GameBalance.Me.IsWorkbenchExtensionId(((ObjectLinkedToDefinition<WGODef>)(object)d).id);
			}
			catch
			{
				return false;
			}
		}

		private static void Tint(List<Wgo> now)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			HashSet<Wgo> hashSet = new HashSet<Wgo>(now);
			foreach (Wgo item in _tinted.ToList())
			{
				if (hashSet.Contains(item))
				{
					continue;
				}
				try
				{
					if ((Object)(object)item != (Object)null)
					{
						item.SetSelectionTint(Color.white, 0f);
					}
				}
				catch
				{
				}
				_tinted.Remove(item);
			}
			foreach (Wgo item2 in now)
			{
				if (_tinted.Add(item2))
				{
					try
					{
						item2.SetSelectionTint(Color.green, 0.4f);
					}
					catch
					{
					}
				}
			}
		}

		private static void ClearTint()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			foreach (Wgo item in _tinted)
			{
				try
				{
					if ((Object)(object)item != (Object)null)
					{
						item.SetSelectionTint(Color.white, 0f);
					}
				}
				catch
				{
				}
			}
			_tinted.Clear();
		}

		private static void Finish(List<Wgo> wgos)
		{
			//IL_010e: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Invalid comparison between Unknown and I4
			Blueprint bp = new Blueprint
			{
				Name = null
			};
			float num = wgos.Min((Wgo w) => w.Data.Position.x);
			float num2 = wgos.Min((Wgo w) => w.Data.Position.z);
			foreach (Wgo wgo in wgos)
			{
				WgoData data = wgo.Data;
				BpPiece bpPiece = new BpPiece
				{
					Id = ((ObjectLinkedToDefinition<WGODef>)(object)data).id,
					X = Mathf.RoundToInt((data.Position.x - num) * 100f),
					Y = Mathf.RoundToInt((data.Position.z - num2) * 80f),
					R = 0
				};
				try
				{
					if (data.MainWgoPartData != null)
					{
						bpPiece.R = Mathf.Max(0, data.MainWgoPartData.rotationIndex);
					}
				}
				catch
				{
				}
				try
				{
					ConveyorChestComponent val = (ConveyorChestComponent)((data is ConveyorWgoData) ? /*isinst with value type is only supported in some contexts*/: null);
					if (val != null)
					{
						foreach (ConveyorChestSlotData slotsDatum in val.SlotsData)
						{
							if (!string.IsNullOrEmpty(slotsDatum.slotItemId))
							{
								if (bpPiece.Filters == null)
								{
									bpPiece.Filters = new Dictionary<string, string>();
								}
								bpPiece.Filters[((object)Unsafe.As<Direction, Direction>(ref slotsDatum.slotPosDirection)/*cast due to .constrained prefix*/).ToString()] = slotsDatum.slotItemId;
							}
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Blueprint: could not read the filters of " + ((ObjectLinkedToDefinition<WGODef>)(object)data).id + ": " + ex.Message));
				}
				try
				{
					List<CraftElementBase> list = ((data.CraftComponent != null) ? data.CraftComponent.CraftElementsQueue : null);
					if (list != null && list.Count > 0 && list[0] != null)
					{
						bpPiece.CraftId = list[0].CraftId;
						bpPiece.CraftCount = Mathf.Max(1, list[0].Count);
						bpPiece.CraftInfinite = list[0].IsInfinite;
					}
				}
				catch
				{
				}
				bp.Pieces.Add(bpPiece);
			}
			bp.Pieces.Sort((BpPiece a, BpPiece b) => (a.Y == b.Y) ? a.X.CompareTo(b.X) : a.Y.CompareTo(b.Y));
			Armed = false;
			_drawArea = null;
			Action<string> action = delegate(string name)
			{
				bp.Name = name;
				string text = bp.Encode();
				try
				{
					GUIUtility.systemCopyBuffer = text;
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("Blueprint: could not use the clipboard: " + ex2.Message));
				}
				Blueprint.LastText = text;
				string text2 = Blueprint.Save(bp, text);
				Plugin.Log.LogInfo((object)("Blueprint: copied " + bp.Pieces.Count + " piece(s)" + ((text2 != null) ? (" to " + text2) : "") + "; " + string.Join(", ", (from p in bp.Pieces
					group p by p.Id into g
					select g.Key + " x" + g.Count()).ToArray())));
				Ui.Say(BpText.CopyDone(bp.Pieces.Count));
			};
			Action action2 = delegate
			{
				if (Move.BuildModeActive())
				{
					Move.EndBuildMode();
					Move.ResetCursor();
					Move.DisablePointer();
				}
			};
			bool flag = false;
			try
			{
				Controller val2 = (ReInput.isReady ? ReInput.controllers.GetLastActiveController() : null);
				flag = val2 != null && (int)val2.type == 2;
			}
			catch
			{
			}
			if (flag)
			{
				action(null);
				action2();
			}
			else
			{
				BpLibrary.AskName(BpText.DefaultName(DateTime.Now), action, action2);
			}
		}
	}
	internal static class BpLibrary
	{
		private sealed class Row
		{
			public string Path;

			public Blueprint Bp;

			public string Text;

			public string Summary;

			public DateTime When;

			public string Name
			{
				get
				{
					if (!string.IsNullOrEmpty(Bp.Name))
					{
						return Bp.Name;
					}
					return "Layout";
				}
			}
		}

		internal static bool Open;

		private static List<Row> _rows = new List<Row>();

		private static Vector2 _scroll;

		private static int _renaming = -1;

		private static int _confirm = -1;

		private static string _renameText = "";

		private static float _confirmUntil;

		private static Action<Blueprint, string> _onPick;

		private static Action _onCancel;

		private static GUIStyle _name;

		private static GUIStyle _dim;

		private static GUIStyle _box;

		private static readonly InputLock _lock = new InputLock();

		private static bool _wheelGuard;

		private static Action<string> _askCommit;

		private static Action _askDone;

		private static string _askText = "";

		public static bool Show(Action<Blueprint, string> onPick, Action onCancel)
		{
			//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)
			Load();
			if (_rows.Count == 0)
			{
				return false;
			}
			_onPick = onPick;
			_onCancel = onCancel;
			_scroll = Vector2.zero;
			_renaming = -1;
			_confirm = -1;
			Open = true;
			_lock.Acquire();
			return true;
		}

		public static void Close()
		{
			Open = false;
			_renaming = -1;
			_confirm = -1;
			_askDone = null;
			_askCommit = null;
			_lock.Release();
			WheelGuard(on: false);
		}

		private static void WheelGuard(bool on)
		{
			if (on == _wheelGuard)
			{
				return;
			}
			try
			{
				if (on)
				{
					if (LazyInput.IsInputActive())
					{
						LazyInput.SetInputActivity(false);
						_wheelGuard = true;
						LazyInput.ClearAllKeysDown();
						LazyInput.ClearKey(GameKey.LeftClick);
						LazyInput.ClearKey(GameKey.RightClick);
					}
				}
				else
				{
					_wheelGuard = false;
					LazyInput.SetInputActivity(true);
				}
			}
			catch (Exception ex)
			{
				_wheelGuard = false;
				Plugin.Log.LogWarning((object)("Blueprint: wheel guard: " + ex.Message));
			}
		}

		private static void GuardOver(Rect win, float s)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			try
			{
				Vector3 mousePosition = Input.mousePosition;
				float num = (float)Screen.height - mousePosition.y;
				flag = mousePosition.x >= ((Rect)(ref win)).xMin * s && mousePosition.x <= ((Rect)(ref win)).xMax * s && num >= ((Rect)(ref win)).yMin * s && num <= ((Rect)(ref win)).yMax * s;
			}
			catch
			{
			}
			WheelGuard(flag);
		}

		public static void AskName(string offered, Action<string> commit, Action done)
		{
			//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)
			_askCommit = commit;
			_askDone = done;
			_askText = offered ?? "";
			_scroll = Vector2.zero;
			_renaming = -1;
			_confirm = -1;
			Open = true;
			_lock.Acquire();
		}

		private static void FinishAsk(bool save)
		{
			Action<string> askCommit = _askCommit;
			Action askDone = _askDone;
			string text = (_askText ?? "").Trim();
			Close();
			try
			{
				askCommit?.Invoke((save && text.Length > 0) ? text : null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: " + ex));
			}
			try
			{
				askDone?.Invoke();
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("Blueprint: " + ex2));
			}
		}

		private static void DrawAsk()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0097: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Invalid comparison between Unknown and I4
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Invalid comparison between Unknown and I4
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Invalid comparison between Unknown and I4
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Invalid comparison between Unknown and I4
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Invalid comparison between Unknown and I4
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			Styles();
			float num = Mathf.Max(1f, (float)Screen.height / 1080f);
			Matrix4x4 matrix = GUI.matrix;
			GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
			float num2 = (float)Screen.width / num;
			float num3 = (float)Screen.height / num;
			float num4 = Mathf.Min(460f, num2 - 40f);
			float num5 = 130f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((num2 - num4) / 2f, (num3 - num5) / 2f, num4, num5);
			GuardOver(val, num);
			GUI.Box(val, GUIContent.none);
			GUI.Box(val, GUIContent.none);
			GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 10f, ((Rect)(ref val)).width - 24f, ((Rect)(ref val)).height - 20f));
			GUILayout.Label(BpText.LibNameAsk, _name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) });
			GUI.SetNextControlName("bp_name");
			_askText = GUILayout.TextField(_askText, 40, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
			Event current = Event.current;
			if (GUI.GetNameOfFocusedControl() != "bp_name" && (int)current.type == 7)
			{
				GUI.FocusControl("bp_name");
			}
			bool flag = (int)current.type == 4 && ((int)current.keyCode == 13 || (int)current.keyCode == 271);
			bool flag2 = (int)current.type == 4 && (int)current.keyCode == 27;
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			bool flag3 = GUILayout.Button(BpText.LibSave, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
			bool flag4 = GUILayout.Button(BpText.LibSkip, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) });
			GUILayout.EndHorizontal();
			GUILayout.EndArea();
			GUI.matrix = matrix;
			if (flag || flag2)
			{
				current.Use();
			}
			if (flag3 || flag)
			{
				FinishAsk(save: true);
			}
			else if (flag4 || flag2)
			{
				FinishAsk(save: false);
			}
		}

		private static void Cancel()
		{
			Action onCancel = _onCancel;
			Close();
			onCancel?.Invoke();
		}

		private static void Pick(Row r)
		{
			Action<Blueprint, string> onPick = _onPick;
			Close();
			onPick?.Invoke(r.Bp, r.Text);
		}

		private static void Load()
		{
			_rows = new List<Row>();
			string text = null;
			try
			{
				text = GUIUtility.systemCopyBuffer;
			}
			catch
			{
			}
			string error;
			if (Blueprint.LooksLike(text))
			{
				Blueprint blueprint = Blueprint.Decode(text, out error);
				if (blueprint != null)
				{
					_rows.Add(new Row
					{
						Bp = blueprint,
						Text = text,
						Summary = Summarize(blueprint),
						When = DateTime.Now
					});
				}
			}
			try
			{
				if (!Directory.Exists(Blueprint.Folder))
				{
					return;
				}
				foreach (FileInfo item in from x in new DirectoryInfo(Blueprint.Folder).GetFiles("*.txt")
					orderby x.LastWriteTimeUtc descending
					select x)
				{
					try
					{
						string text2 = File.ReadAllText(item.FullName);
						Blueprint blueprint2 = Blueprint.Decode(text2, out error);
						if (blueprint2 != null)
						{
							if (_rows.Count > 0 && _rows[0].Path == null && _rows[0].Text.Trim() == text2.Trim())
							{
								_rows.RemoveAt(0);
							}
							_rows.Add(new Row
							{
								Path = item.FullName,
								Bp = blueprint2,
								Text = text2,
								Summary = Summarize(blueprint2),
								When = item.LastWriteTime
							});
						}
					}
					catch
					{
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not read the library: " + ex.Message));
			}
		}

		private static string Summarize(Blueprint bp)
		{
			string[] value = (from p in bp.Pieces
				group p by p.Id into g
				orderby g.Count() descending
				select g).Take(4).Select(delegate(IGrouping<string, BpPiece> g)
			{
				string text2 = LLBase.L(g.Key);
				return (string.IsNullOrEmpty(text2) ? g.Key : text2) + " ×" + g.Count();
			}).ToArray();
			string text = string.Join(", ", value);
			if ((from p in bp.Pieces
				group p by p.Id).Count() - 4 <= 0)
			{
				return text;
			}
			return text + " …";
		}

		private static void Save(Row r)
		{
			string text = Blueprint.Save(r.Bp, r.Text);
			if (text != null)
			{
				r.Path = text;
				r.When = DateTime.Now;
			}
		}

		private static void Rename(Row r, string name)
		{
			name = (name ?? "").Trim();
			if (name.Length == 0)
			{
				return;
			}
			r.Bp.Name = name;
			r.Text = r.Bp.Encode();
			try
			{
				if (r.Path == null)
				{
					return;
				}
				string fileName = Path.GetFileName(r.Path);
				fileName = ((fileName.Length >= 15) ? fileName.Substring(0, 15) : DateTime.Now.ToString("yyyyMMdd-HHmmss"));
				string text = new string(name.Select((char c) => (!Path.GetInvalidFileNameChars().Contains(c)) ? c : '_').ToArray());
				string text2 = Path.Combine(Blueprint.Folder, fileName + "_" + text + "_" + r.Bp.Pieces.Count + "pcs.txt");
				File.WriteAllText(r.Path, r.Text, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				if (!string.Equals(text2, r.Path, StringComparison.OrdinalIgnoreCase))
				{
					if (File.Exists(text2))
					{
						File.Delete(text2);
					}
					File.Move(r.Path, text2);
					r.Path = text2;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not rename: " + ex.Message));
			}
		}

		private static void Delete(Row r)
		{
			try
			{
				if (r.Path != null && File.Exists(r.Path))
				{
					File.Delete(r.Path);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not delete: " + ex.Message));
			}
			_rows.Remove(r);
		}

		private static void Styles()
		{
			//IL_0012: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//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_0068: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			if (_name == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1
				};
				val.normal.textColor = new Color(0.95f, 0.8f, 0.5f);
				val.clipping = (TextClipping)1;
				_name = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 12
				};
				val2.normal.textColor = new Color(0.8f, 0.78f, 0.72f);
				val2.clipping = (TextClipping)1;
				_dim = val2;
				_box = new GUIStyle(GUI.skin.box);
			}
		}

		public static void Draw()
		{
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Invalid comparison between Unknown and I4
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Invalid comparison between Unknown and I4
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Invalid comparison between Unknown and I4
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Invalid comparison between Unknown and I4
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Invalid comparison between Unknown and I4
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Invalid comparison between Unknown and I4
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			if (!Open || Event.current == null)
			{
				return;
			}
			try
			{
				if (_askCommit != null)
				{
					DrawAsk();
					return;
				}
				if (!Move.BuildModeActive())
				{
					Cancel();
					return;
				}
				Event current = Event.current;
				if ((int)current.type == 4 && (int)current.keyCode == 27 && _renaming < 0)
				{
					current.Use();
					Cancel();
					return;
				}
				Styles();
				float num = Mathf.Max(1f, (float)Screen.height / 1080f);
				Matrix4x4 matrix = GUI.matrix;
				GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
				float num2 = (float)Screen.width / num;
				float num3 = (float)Screen.height / num;
				float num4 = Mathf.Min(640f, num2 - 40f);
				float num5 = Mathf.Min(520f, num3 - 40f);
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((num2 - num4) / 2f, (num3 - num5) / 2f, num4, num5);
				GuardOver(val, num);
				GUI.Box(val, GUIContent.none);
				GUI.Box(val, GUIContent.none);
				GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 10f, ((Rect)(ref val)).width - 24f, ((Rect)(ref val)).height - 20f));
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(BpText.LibTitle, _name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) });
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("?", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(28f),
					GUILayout.Height(24f)
				}))
				{
					SaSettings.OpenFaq("move-buildings#blueprints");
				}
				if (GUILayout.Button(BpText.LibClose, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(80f),
					GUILayout.Height(24f)
				}))
				{
					Cancel();
					GUILayout.EndHorizontal();
					GUILayout.EndArea();
					GUI.matrix = matrix;
					return;
				}
				GUILayout.EndHorizontal();
				_scroll = GUILayout.BeginScrollView(_scroll, Array.Empty<GUILayoutOption>());
				if (_confirm >= 0 && Time.unscaledTime > _confirmUntil)
				{
					_confirm = -1;
				}
				for (int i = 0; i < _rows.Count; i++)
				{
					Row row = _rows[i];
					GUILayout.BeginVertical(_box, Array.Empty<GUILayoutOption>());
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					if (_renaming == i)
					{
						GUI.SetNextControlName("bp_rename");
						_renameText = GUILayout.TextField(_renameText, 40, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) });
						if (GUI.GetNameOfFocusedControl() != "bp_rename" && (int)Event.current.type == 7)
						{
							GUI.FocusControl("bp_rename");
						}
						Event current2 = Event.current;
						bool flag = (int)current2.type == 4 && ((int)current2.keyCode == 13 || (int)current2.keyCode == 271);
						bool flag2 = (int)current2.type == 4 && (int)current2.keyCode == 27;
						if (GUILayout.Button(BpText.LibSave, (GUILayoutOption[])(object)new GUILayoutOption[2]
						{
							GUILayout.Width(90f),
							GUILayout.Height(24f)
						}) || flag)
						{
							Rename(row, _renameText);
							_renaming = -1;
							if (flag)
							{
								current2.Use();
							}
						}
						else if (flag2)
						{
							_renaming = -1;
							current2.Use();
						}
					}
					else
					{
						GUILayout.Label(row.Name + ((row.Path == null) ? ("   (" + BpText.LibClipboard + ")") : ""), _name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) });
						GUILayout.FlexibleSpace();
						GUILayout.Label(string.Format(BpText.LibPieces, row.Bp.Pieces.Count), _dim, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
					}
					GUILayout.EndHorizontal();
					GUILayout.Label(row.Summary + ((row.Path != null) ? ("   ·   " + row.When.ToString("yyyy-MM-dd HH:mm")) : ""), _dim, Array.Empty<GUILayoutOption>());
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					if (GUILayout.Button(BpText.LibPaste, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
					{
						Pick(row);
						GUILayout.EndHorizontal();
						GUILayout.EndVertical();
						GUILayout.EndScrollView();
						GUILayout.EndArea();
						GUI.matrix = matrix;
						return;
					}
					if (row.Path == null)
					{
						if (GUILayout.Button(BpText.LibSaveToLibrary, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
						{
							Save(row);
						}
					}
					else
					{
						if (GUILayout.Button(BpText.LibRename, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
						{
							_renaming = i;
							_renameText = row.Name;
						}
						if (GUILayout.Button(BpText.LibCopyText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
						{
							try
							{
								GUIUtility.systemCopyBuffer = row.Text;
							}
							catch
							{
							}
						}
						bool flag3 = _confirm == i;
						if (GUILayout.Button(flag3 ? BpText.LibDeleteSure : BpText.LibDelete, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
						{
							if (flag3)
							{
								Delete(row);
								_confirm = -1;
								GUILayout.EndHorizontal();
								GUILayout.EndVertical();
								GUILayout.EndScrollView();
								GUILayout.EndArea();
								GUI.matrix = matrix;
								return;
							}
							_confirm = i;
							_confirmUntil = Time.unscaledTime + 3f;
						}
					}
					GUILayout.EndHorizontal();
					GUILayout.EndVertical();
				}
				GUILayout.EndScrollView();
				GUILayout.EndArea();
				GUI.matrix = matrix;
			}
			catch (Exception ex)
			{
				if (!(ex is ExitGUIException))
				{
					Plugin.Log.LogWarning((object)("Blueprint: library window: " + ex.Message));
				}
				GUI.matrix = Matrix4x4.identity;
			}
		}
	}
	internal sealed class InputLock
	{
		private readonly List<ControllerMap> _disabled = new List<ControllerMap>();

		private bool _held;

		public void Acquire()
		{
			//IL_0058: 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)
			if (_held)
			{
				return;
			}
			_held = true;
			try
			{
				_disabled.Clear();
				if (!ReInput.isReady)
				{
					return;
				}
				foreach (Player allPlayer in ReInput.players.AllPlayers)
				{
					if (allPlayer == null)
					{
						continue;
					}
					ControllerType[] array = (ControllerType[])(object)new ControllerType[2]
					{
						default(ControllerType),
						(ControllerType)1
					};
					foreach (ControllerType val in array)
					{
						foreach (ControllerMap allMap in allPlayer.controllers.maps.GetAllMaps(val))
						{
							if (allMap != null && allMap.enabled)
							{
								allMap.enabled = false;
								_disabled.Add(allMap);
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: input lock: " + ex.Message));
			}
		}

		public void Release()
		{
			if (!_held)
			{
				return;
			}
			_held = false;
			foreach (ControllerMap item in _disabled)
			{
				try
				{
					item.enabled = true;
				}
				catch
				{
				}
			}
			_disabled.Clear();
		}
	}
	internal enum PasteState
	{
		Idle,
		Pending,
		Choosing,
		Measuring,
		Aiming,
		Checking,
		Asking,
		Placing
	}
	internal static class BpPaste
	{
		private sealed class Item
		{
			public BpPiece P;

			public BuildingDef Def;

			public Wgo Ghost;

			public bool Blocked;

			public bool Done;

			public bool Skipped;

			public WgoData Placed;

			public int Rank;

			public int RotIdx;

			public Vector2 Delta;

			public float Fit;

			public bool Ext;
		}

		private sealed class Conn
		{
			public int Type;

			public Direction Dir;

			public Vector2 Q;

			public Vector2 Half;

			public Vector2 Belt;

			public bool Used;
		}

		internal static PasteState State = PasteState.Idle;

		private static BuildData _entry;

		private static Blueprint _bp;

		private static string _text;

		private static readonly List<Item> _items = new List<Item>();

		private static List<List<Item>> _groups = new List<List<Item>>();

		private static Item _anchor;

		private static Wgo _desk;

		private static List<Inventory> _inv;

		private static BuildingDef _curDef;

		private static int _switchFrame;

		private static Vector3 _basePos;

		private static int _gi;

		private static int _pi;

		private static int _done;

		private static int _unknown;

		private static bool _afford;

		private static bool _selfCall;

		private static bool _loggedDelta;

		private static bool _aimTurned;

		private static float _seenAt;

		private static float _askedAt;

		private static Item _current;

		private static Dictionary<string, BuildingDef> _defs;

		private static int _imperfectShown;

		private static string _imperfectFirst;

		private static int _rot;

		private static int _mi;

		private static List<BuildingDef> _mDefs = new List<BuildingDef>();

		private static readonly Dictionary<BuildingDef, Dictionary<int, Vector2>> _rel = new Dictionary<BuildingDef, Dictionary<int, Vector2>>();

		private static readonly Dictionary<BuildingDef, Dictionary<int, List<Conn>>> _conn = new Dictionary<BuildingDef, Dictionary<int, List<Conn>>>();

		private static readonly Dictionary<BuildingDef, Dictionary<int, int>> _next = new Dictionary<BuildingDef, Dictionary<int, int>>();

		private static readonly HashSet<string> Belts = new HashSet<string> { "conveyor_cell", "conveyor_splitter", "conveyor_cell_underground", "conveyor_cell_station", "conveyor_chest" };

		private static ConstructorInfo _tempCtor;

		private static bool _tempCtorLooked;

		internal static bool Active => State != PasteState.Idle;

		internal static int ItemCount => _items.Count;

		public static BuildData NewEntry()
		{
			_entry = BuildData.GetDataForRemove();
			return _entry;
		}

		public static bool IsEntry(BuildData d)
		{
			if (d != null)
			{
				return d == _entry;
			}
			return false;
		}

		public static void OnBuildModeEntered(BuildData d)
		{
			if (State == PasteState.Idle && IsEntry(d))
			{
				if (BuildToolsLink.PlanOn)
				{
					Ui.SayPlanBusy();
				}
				else
				{
					State = PasteState.Pending;
				}
			}
		}

		private static BuildingDef Def(string id)
		{
			if (_defs == null)
			{
				_defs = new Dictionary<string, BuildingDef>();
				try
				{
					foreach (BuildingDef buildingDef in GameBalance.Me.buildingDefs)
					{
						if (buildingDef != null && !string.IsNullOrEmpty(((BalanceBaseObject)buildingDef).id) && !_defs.ContainsKey(((BalanceBaseObject)buildingDef).id))
						{
							_defs[((BalanceBaseObject)buildingDef).id] = buildingDef;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Blueprint: building definitions: " + ex.Message));
				}
			}
			if (!_defs.TryGetValue(id, out var value))
			{
				return null;
			}
			return value;
		}

		private static bool IsExt(string id)
		{
			try
			{
				return GameBalance.Me.IsWorkbenchExtensionId(id);
			}
			catch
			{
				return false;
			}
		}

		private static BuildingDef PlaceDef(string id)
		{
			if (Belts.Contains(id))
			{
				return Def(id + "_cp");
			}
			if (IsExt(id))
			{
				return Def(id + "_p");
			}
			return Def(id + "_cp") ?? Def(id + "_place_p");
		}

		private static BuildingDef UnlockDef(string id, BuildingDef placing)
		{
			if (Belts.Contains(id) || IsExt(id))
			{
				return placing;
			}
			return Def(id + "_place_p") ?? placing;
		}

		private static bool Unlocked(BuildingDef d)
		{
			try
			{
				if (d == null)
				{
					return false;
				}
				if (!d.isNeedsUnlock)
				{
					return true;
				}
				KnowledgeSystem knowledgeSystem = MainGame.Instance.GameSave.knowledgeSystem;
				return knowledgeSystem.unlockedBuildings != null && knowledgeSystem.unlockedBuildings.Contains(((BalanceBaseObject)d).id) && (knowledgeSystem.lockedBuildings == null || !knowledgeSystem.lockedBuildings.Contains(((BalanceBaseObject)d).id));
			}
			catch
			{
				return true;
			}
		}

		private static int Rank(string id)
		{
			switch (id)
			{
			case "conveyor_cell":
				return 0;
			case "conveyor_splitter":
				return 1;
			case "conveyor_cell_underground":
				return 2;
			case "conveyor_cell_station":
				return 3;
			default:
				if (id.StartsWith("conveyor_chest"))
				{
					return 4;
				}
				if (!IsExt(id))
				{
					return 5;
				}
				return 6;
			}
		}

		private static void Begin()
		{
			_defs = null;
			_items.Clear();
			_groups = new List<List<Item>>();
			_anchor = null;
			_curDef = null;
			_current = null;
			_done = 0;
			_unknown = 0;
			_gi = 0;
			_pi = 0;
			_afford = false;
			_loggedDelta = false;
			_rot = 0;
			_mi = 0;
			_imperfectShown = 0;
			HintPanel.ClearNote();
			_rel.Clear();
			_next.Clear();
			_conn.Clear();
			if (!UsingPad())
			{
				State = PasteState.Choosing;
				if (!BpLibrary.Show(delegate(Blueprint bp, string text2)
				{
					if (State == PasteState.Choosing)
					{
						BeginWith(bp, text2);
					}
				}, delegate
				{
					Cancel("the library was closed", Move.BuildModeActive());
				}))
				{
					State = PasteState.Idle;
					Ui.Say(BpText.PasteNone);
					Leave();
				}
			}
			else
			{
				string text;
				Blueprint blueprint = Blueprint.ForPaste(out text);
				if (blueprint == null)
				{
					Ui.Say(BpText.PasteNone);
					Leave();
				}
				else
				{
					BeginWith(blueprint, text);
				}
			}
		}

		private static bool UsingPad()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			try
			{
				if (!ReInput.isReady)
				{
					return false;
				}
				Controller lastActiveController = ReInput.controllers.GetLastActiveController();
				return lastActiveController != null && (int)lastActiveController.type == 2;
			}
			catch
			{
				return false;
			}
		}

		private static void BeginWith(Blueprint chosen, string text)
		{
			_bp = chosen;
			_text = text;
			State = PasteState.Idle;
			List<string> list = new List<string>();
			foreach (BpPiece piece in _bp.Pieces)
			{
				BuildingDef val = PlaceDef(piece.Id);
				if (val == null)
				{
					_unknown++;
					Plugin.Log.LogWarning((object)("Blueprint: no build definition for " + piece.Id + " - the piece is left out"));
					continue;
				}
				if (!Unlocked(UnlockDef(piece.Id, val)))
				{
					string item = LLBase.L(piece.Id);
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
				_items.Add(new Item
				{
					P = piece,
					Def = val,
					Rank = Rank(piece.Id),
					Ext = IsExt(piece.Id)
				});
			}
			if (_items.Count == 0)
			{
				Ui.Say(BpText.PasteNone);
				Leave();
				return;
			}
			if (list.Count > 0)
			{
				Ui.Say(BpText.PasteLocked(string.Join(", ", list.ToArray())));
				Leave();
				return;
			}
			_items.Sort((Item a, Item b) => (a.Rank == b.Rank) ? ((a.P.Y == b.P.Y) ? a.P.X.CompareTo(b.P.X) : a.P.Y.CompareTo(b.P.Y)) : a.Rank.CompareTo(b.Rank));
			_anchor = (from i in _items
				where i.Rank <= 4
				orderby i.P.Y, i.P.X
				select i).FirstOrDefault() ?? (from i in _items
				orderby i.P.Y, i.P.X
				select i).First();
			_groups = (from i in _items
				group i by i.Def into g
				select g.ToList()).ToList();
			try
			{
				Traverse obj = Traverse.Create((object)LazySingleton<BuildManager>.Instance);
				_desk = obj.Field("currentBuildDesk").GetValue<Wgo>();
				_inv = obj.Field("additionalInventories").GetValue<List<Inventory>>();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: no build desk: " + ex.Message));
				Leave();
				return;
			}
			_mDefs = (from d in _items.Select((Item i) => i.Def).Distinct()
				where d != _anchor.Def
				select d).ToList();
			_mDefs.Add(_anchor.Def);
			foreach (Item item2 in _items)
			{
				item2.RotIdx = item2.P.R;
			}
			State = PasteState.Measuring;
			_seenAt = Time.unscaledTime;
			Plugin.Log.LogInfo((object)("Blueprint: pasting " + _items.Count + " piece(s) (" + string.Join(", ", (from i in _items
				group i by i.P.Id into g
				select g.Key + " x" + g.Count()).ToArray()) + "), first piece " + _anchor.P.Id));
		}

		private static void StartAiming()
		{
			State = PasteState.Aiming;
			_seenAt = Time.unscaledTime;
			_aimTurned = false;
			ComputeLayout();
			foreach (Item item in _items)
			{
				if (item != _anchor)
				{
					item.Ghost = SpawnGhost(item);
				}
			}
		}

		private static void Measure(BuildingDef def, BuildPointer bp, WgoBuildPointer po)
		{
			//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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_013b: 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_0054: 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_005c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, Vector2> dictionary = new Dictionary<int, Vector2>();
			Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
			Dictionary<int, List<Conn>> dictionary3 = new Dictionary<int, List<Conn>>();
			try
			{
				Wgo target = po.Target;
				Vector3 position = target.Data.Position;
				int rotationIndex = target.MainWgoPart.WgoPartData.rotationIndex;
				int key = rotationIndex;
				for (int i = 0; i < 5; i++)
				{
					Vector3 value = Traverse.Create((object)po).Field("offset").GetValue<Vector3>();
					bp.UpdatePos(position - value);
					try
					{
						Physics.SyncTransforms();
					}
					catch
					{
					}
					Bounds worldRoundedBounds = ((BuildPointerObject)po).GetWorldRoundedBounds();
					Vector3 position2 = target.Data.Position;
					dictionary[key] = new Vector2(((Bounds)(ref worldRoundedBounds)).center.x - position2.x, ((Bounds)(ref worldRoundedBounds)).center.z - position2.z);
					dictionary3[key] = ReadConnectors(target, new Vector2(position2.x, position2.z));
					if (!((BuildPointerObject)po).HasRotation())
					{
						break;
					}
					bp.Rotate();
					int num = (dictionary2[key] = target.MainWgoPart.WgoPartData.rotationIndex);
					if (num == rotationIndex)
					{
						break;
					}
					key = num;
				}
				Vector3 value2 = Traverse.Create((object)po).Field("offset").GetValue<Vector3>();
				bp.UpdatePos(position - value2);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not measure " + ((BalanceBaseObject)def).id + ": " + ex.Message));
			}
			_rel[def] = dictionary;
			_next[def] = dictionary2;
			_conn[def] = dictionary3;
			Plugin.Log.LogInfo((object)("Blueprint: " + ((BalanceBaseObject)def).id + " faces " + string.Join(", ", dictionary2.Select((KeyValuePair<int, int> kv) => kv.Key + ">" + kv.Value).ToArray()) + "; footprint middles " + string.Join(", ", dictionary.Select((KeyValuePair<int, Vector2> kv) => kv.Key + ":" + kv.Value.x.ToString("0.###") + "/" + kv.Value.y.ToString("0.###")).ToArray()) + "; entrances/exits " + string.Join(" | ", dictionary3.Select((KeyValuePair<int, List<Conn>> kv) => kv.Key + ": " + string.Join(",", kv.Value.Select((Conn c) => ((object)(ConveyorConnectionType)c.Type/*cast due to .constrained prefix*/).ToString() + " " + ((object)Unsafe.As<Direction, Direction>(ref c.Dir)/*cast due to .constrained prefix*/).ToString() + " " + c.Q.x.ToString("0.##") + "/" + c.Q.y.ToString("0.##") + " box " + (c.Half.x * 2f).ToString("0.##") + "x" + (c.Half.y * 2f).ToString("0.##")).ToArray())).ToArray())));
		}

		private static void TickMeasuring()
		{
			if (!Move.BuildModeActive())
			{
				if (Time.unscaledTime - _seenAt > 0.6f)
				{
					Cancel("build mode was left", endBuildMode: false);
				}
				return;
			}
			_seenAt = Time.unscaledTime;
			if (_mi >= _mDefs.Count)
			{
				StartAiming();
				return;
			}
			BuildingDef val = _mDefs[_mi];
			BuildPointer bp;
			WgoBuildPointer po;
			if (_curDef != val)
			{
				Switch(val);
			}
			else if (Ready(val, out bp, out po))
			{
				Measure(val, bp, po);
				_mi++;
				if (_mi >= _mDefs.Count)
				{
					StartAiming();
				}
			}
		}

		private static List<Conn> ReadConnectors(Wgo target, Vector2 origin)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected I4, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0049: 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_0072: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			List<Conn> list = new List<Conn>();
			try
			{
				ConveyorWorkbenchBuildConnector[] componentsInChildren = ((Component)target).GetComponentsInChildren<ConveyorWorkbenchBuildConnector>(true);
				foreach (ConveyorWorkbenchBuildConnector val in componentsInChildren)
				{
					if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy)
					{
						continue;
					}
					Vector3 val2 = (((Object)(object)((BuildConnector)val).BoxCollider != (Object)null) ? ((Component)((BuildConnector)val).BoxCollider).transform.TransformPoint(((BuildConnector)val).BoxCollider.center) : ((Component)val).transform.position);
					Vector2 half = Vector2.zero;
					try
					{
						BoxCollider boxCollider = ((BuildConnector)val).BoxCollider;
						if ((Object)(object)boxCollider != (Object)null)
						{
							Vector3 lossyScale = ((Component)boxCollider).transform.lossyScale;
							half = new Vector2(Mathf.Abs(boxCollider.size.x * lossyScale.x), Mathf.Abs(boxCollider.size.z * lossyScale.z)) * 0.5f;
						}
					}
					catch
					{
					}
					list.Add(new Conn
					{
						Type = (int)((BuildConnector)val).ConnectionType,
						Dir = val.Direction,
						Q = new Vector2(val2.x, val2.z) - origin,
						Half = half
					});
				}
			}
			catch
			{
			}
			return list;
		}

		private static Direction Clockwise(Direction d)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return (Direction)((d - 1) switch
			{
				0 => 4, 
				3 => 3, 
				2 => 2, 
				1 => 1, 
				_ => d, 
			});
		}

		private static float Mismatch(List<Conn> want, List<Conn> have)
		{
			float worst;
			return Mismatch(want, have, out worst);
		}

		private static float Mismatch(List<Conn> want, List<Conn> have, out float worst)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			worst = 0f;
			bool[] array = new bool[have.Count];
			Vector2 cELL_SIZE = BuildConsts.CELL_SIZE;
			foreach (Conn item in want)
			{
				int num2 = -1;
				float num3 = float.MaxValue;
				for (int i = 0; i < have.Count; i++)
				{
					if (!array[i])
					{
						Vector2 val = have[i].Q - item.Q;
						float num4 = Mathf.Sqrt(val.x / cELL_SIZE.x * (val.x / cELL_SIZE.x) + val.y / cELL_SIZE.y * (val.y / cELL_SIZE.y));
						if (have[i].Dir != item.Dir)
						{
							num4 += 3f;
						}
						if (have[i].Type != item.Type)
						{
							num4 += 50f;
						}
						if (num4 < num3)
						{
							num3 = num4;
							num2 = i;
						}
					}
				}
				if (num2 < 0)
				{
					num += 100f;
					worst = Mathf.Max(worst, 100f);
				}
				else
				{
					array[num2] = true;
					num += num3;
					worst = Mathf.Max(worst, num3);
				}
			}
			return num;
		}

		private static int Step(BuildingDef def, int idx, int turns)
		{
			if (!_next.TryGetValue(def, out var value))
			{
				return idx;
			}
			for (int i = 0; i < turns; i++)
			{
				if (!value.TryGetValue(idx, out var value2))
				{
					break;
				}
				idx = value2;
			}
			return idx;
		}

		private static Vector2 Rel(BuildingDef def, int idx)
		{
			//IL_001a: 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)
			if (!_rel.TryGetValue(def, out var value) || !value.TryGetValue(idx, out var value2))
			{
				return Vector2.zero;
			}
			return value2;
		}

		private static Vector2 Turn(Vector2 v, int k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Vector2 cELL_SIZE = BuildConsts.CELL_SIZE;
			float num = v.x / cELL_SIZE.x;
			float num2 = v.y / cELL_SIZE.y;
			for (int i = 0; i < k; i++)
			{
				float num3 = num2;
				float num4 = 0f - num;
				num = num3;
				num2 = num4;
			}
			return new Vector2(num * cELL_SIZE.x, num2 * cELL_SIZE.y);
		}

		private static Vector3 WorldAt(Item it, Vector3 anchorPos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			return new Vector3(anchorPos.x + it.Delta.x, anchorPos.y, anchorPos.z + it.Delta.y);
		}

		private static int ComputeLayout()
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ca: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0875: Unknown result type (might be due to invalid IL or missing references)
			//IL_088a: Unknown result type (might be due to invalid IL or missing references)
			//IL_088f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0894: Unknown result type (might be due to invalid IL or missing references)
			//IL_0898: Unknown result type (might be due to invalid IL or missing references)
			//IL_089a: Unknown result type (might be due to invalid IL or missing references)
			//IL_089c: Unknown result type (might be due to invalid IL or missing references)
			//IL_089d: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c5: 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_0164: 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_016d: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: 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_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: 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_02a8: 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_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: 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_0248: 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_02f7: 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_02fd: 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_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0665: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: 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_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			Item anchor = _anchor;
			int rot = _rot;
			anchor.RotIdx = Step(anchor.Def, anchor.P.R, rot);
			anchor.Delta = Vector2.zero;
			anchor.Fit = 0f;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(anchor.P.Offset.x, anchor.P.Offset.z);
			Vector2 val2 = val + Rel(anchor.Def, anchor.P.R);
			Vector2 val3 = Rel(anchor.Def, anchor.RotIdx);
			int result = 0;
			_imperfectFirst = null;
			Vector2 val4 = default(Vector2);
			foreach (Item item in _items)
			{
				if (item == anchor)
				{
					continue;
				}
				((Vector2)(ref val4))..ctor(item.P.Offset.x, item.P.Offset.z);
				item.Fit = 0f;
				Dictionary<int, List<Conn>> value;
				List<Conn> value2;
				if (rot == 0)
				{
					item.RotIdx = item.P.R;
					item.Delta = val4 - val;
				}
				else if (_conn.TryGetValue(item.Def, out value) && value.TryGetValue(item.P.R, out value2) && value2.Count > 0)
				{
					Vector2 cELL_SIZE = BuildConsts.CELL_SIZE;
					Vector2 beltHalf = new Vector2(cELL_SIZE.x, cELL_SIZE.y) * 0.5f;
					List<Conn> list = new List<Conn>();
					foreach (Conn item2 in value2)
					{
						Vector2 val5 = val4 + item2.Q;
						Vector2? val6 = null;
						foreach (Item item3 in _items)
						{
							if (item3 != item && !item3.Ext && item3.Rank <= 4)
							{
								Vector2 val7 = new Vector2(item3.P.Offset.x, item3.P.Offset.z) + Rel(item3.Def, item3.P.R);
								if (Meets(val5, item2.Half, val7, beltHalf))
								{
									val6 = val7;
									break;
								}
							}
						}
						Direction val8 = item2.Dir;
						for (int i = 0; i < rot; i++)
						{
							val8 = Clockwise(val8);
						}
						list.Add(new Conn
						{
							Type = item2.Type,
							Dir = val8,
							Q = val3 + Turn(val5 - val2, rot),
							Half = item2.Half,
							Used = val6.HasValue,
							Belt = (val6.HasValue ? (val3 + Turn(val6.Value - val2, rot)) : Vector2.zero)
						});
					}
					if (!list.Any((Conn w) => w.Used))
					{
						foreach (Conn item4 in list)
						{
							item4.Used = false;
						}
					}
					int num = Step(item.Def, item.P.R, rot);
					int num2 = num;
					Vector2 delta = Vector2.zero;
					float num3 = float.MaxValue;
					int num4 = 99;
					foreach (KeyValuePair<int, List<Conn>> item5 in value)
					{
						foreach (Conn item6 in list)
						{
							foreach (Conn item7 in item5.Value)
							{
								if (item7.Type != item6.Type)
								{
									continue;
								}
								Vector2 val9 = item6.Q - item7.Q;
								int num5 = 0;
								float num6 = 0f;
								bool[] array = new bool[item5.Value.Count];
								foreach (Conn item8 in list.OrderBy((Conn q) => (!q.Used) ? 1 : 0))
								{
									int num7 = -1;
									float num8 = float.MaxValue;
									bool flag = false;
									for (int num9 = 0; num9 < item5.Value.Count; num9++)
									{
										if (!array[num9])
										{
											Conn conn = item5.Value[num9];
											Vector2 val10 = conn.Q + val9 - item8.Q;
											float num10 = Mathf.Sqrt(val10.x / cELL_SIZE.x * (val10.x / cELL_SIZE.x) + val10.y / cELL_SIZE.y * (val10.y / cELL_SIZE.y));
											if (conn.Dir != item8.Dir)
											{
												num10 += 3f;
											}
											if (conn.Type != item8.Type)
											{
												num10 += 50f;
											}
											bool flag2 = item8.Used && conn.Type == item8.Type && Meets(conn.Q + val9, conn.Half, item8.Belt, beltHalf);
											if ((flag2 && !flag) || (flag2 == flag && num10 < num8))
											{
												num8 = num10;
												num7 = num9;
												flag = flag2;
											}
										}
									}
									if (num7 < 0)
									{
										num6 += 100f;
										if (item8.Used)
										{
											num5++;
										}
										continue;
									}
									array[num7] = true;
									num6 += num8;
									if (item8.Used && !flag)
									{
										num5++;
									}
								}
								float num11 = (float)num5 * 1000f + num6;
								if (num11 < num3 - 0.0001f || (Mathf.Abs(num11 - num3) <= 0.0001f && item5.Key == num))
								{
									num3 = num11;
									num2 = item5.Key;
									delta = val9;
									num4 = num5;
								}
							}
						}
					}
					item.RotIdx = num2;
					item.Delta = delta;
					item.Fit = ((num4 == 99) ? 100 : num4);
					if (num2 != num)
					{
						Plugin.Log.LogInfo((object)("Blueprint: " + item.P.Id + " turned " + rot + "x from facing " + item.P.R + ": the game's next facing is " + num + ", but facing " + num2 + " keeps the most belts on its entrances and exits"));
					}
					if (item.Fit > 0f)
					{
						if (result++ == 0)
						{
							_imperfectFirst = item.P.Id;
						}
						Plugin.Log.LogInfo((object)("Blueprint: " + item.P.Id + " turned " + rot + "x: " + (int)item.Fit + " of its " + list.Count((Conn w) => w.Used) + " connected entrances/exits would not touch their belt (facing " + num2 + ")"));
					}
				}
				else
				{
					item.RotIdx = Step(item.Def, item.P.R, rot);
					Vector2 val11 = val4 + Rel(item.Def, item.P.R);
					item.Delta = val3 + Turn(val11 - val2, rot) - Rel(item.Def, item.RotIdx);
				}
			}
			return result;
		}

		private static bool Meets(Vector2 conn, Vector2 half, Vector2 belt, Vector2 beltHalf)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			if (Mathf.Abs(belt.x - conn.x) < half.x * 0.5f + beltHalf.x - 0.01f)
			{
				return Mathf.Abs(belt.y - conn.y) < half.y * 0.5f + beltHalf.y - 0.01f;
			}
			return false;
		}

		private static bool HasNeighbour(Item owner, Vector2 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			Vector2 cELL_SIZE = BuildConsts.CELL_SIZE;
			foreach (Item item in _items)
			{
				if (item != owner && !item.Ext && item.Rank <= 4)
				{
					Vector2 val = new Vector2(item.P.Offset.x, item.P.Offset.z) + Rel(item.Def, item.P.R) - point;
					if (Mathf.Sqrt(val.x / cELL_SIZE.x * (val.x / cELL_SIZE.x) + val.y / cELL_SIZE.y * (val.y / cELL_SIZE.y)) <= 1f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void ApplyTurn()
		{
			int num = ComputeLayout();
			if (num == 0 || num < _imperfectShown)
			{
				_imperfectShown = num;
				HintPanel.ClearNote();
			}
			if (num > _imperfectShown)
			{
				_imperfectShown = num;
				HintPanel.Note((num == 1 && _imperfectFirst != null) ? BpText.TurnImperfectOne(LLBase.L(_imperfectFirst)) : BpText.TurnImperfect(num), 6f);
			}
			DestroyGhosts();
			foreach (Item item in _items)
			{
				if (item != _anchor)
				{
					item.Ghost = SpawnGhost(item);
				}
			}
		}

		private static void Leave(bool endBuildMode = true)
		{
			State = PasteState.Idle;
			DestroyGhosts();
			HintPanel.ClearNote();
			if (endBuildMode)
			{
				Move.EndBuildMode();
				Move.ResetCursor();
				Move.DisablePointer();
			}
		}

		public static void Cancel(string why, bool endBuildMode = true)
		{
			if (State != PasteState.Idle)
			{
				Plugin.Log.LogInfo((object)("Blueprint: paste cancelled: " + why));
				Leave(endBuildMode);
			}
		}

		private static void Switch(BuildingDef def)
		{
			_curDef = def;
			_aimTurned = false;
			_switchFrame = Time.frameCount;
			Move.SwitchPointer(_desk, BuildData.GetDataForBuild(def), (def.needItems != null) ? new List<NeedItemData>(def.needItems) : new List<NeedItemData>(), _inv);
		}

		private static bool Pointer(out BuildPointer bp, out WgoBuildPointer po)
		{
			bp = null;
			po = null;
			try
			{
				BuildController val = Move.Controller();
				if ((Object)(object)val == (Object)null || !val.IsBuildModeActive)
				{
					return false;
				}
				bp = Traverse.Create((object)val).Field("buildPointer").GetValue<BuildPointer>();
				po = (WgoBuildPointer)(((Object)(object)bp != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
				return (Object)(object)po != (Object)null && (Object)(object)po.Target != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		private static bool Ready(BuildingDef def, out BuildPointer bp, out WgoBuildPointer po)
		{
			if (!Pointer(out bp, out po))
			{
				return false;
			}
			if (Time.frameCount <= _switchFrame)
			{
				return false;
			}
			BuildingDef val = null;
			try
			{
				val = ((((BuildPointerObject)po).BuildData != null) ? ((BuildPointerObject)po).BuildData.Definition : null);
			}
			catch
			{
			}
			return val == def;
		}

		private static bool PointerActive(WgoBuildPointer po)
		{
			try
			{
				return Traverse.Create((object)po).Field("shownAsActive").GetValue<bool>();
			}
			catch
			{
				return false;
			}
		}

		private static void SetRotation(BuildPointer bp, WgoBuildPointer po, int want)
		{
			try
			{
				Wgo target = po.Target;
				if ((Object)(object)target == (Object)null || (Object)(object)target.MainWgoPart == (Object)null || target.MainWgoPart.WgoPartData == null || !((BuildPointerObject)po).HasRotation())
				{
					return;
				}
				for (int i = 0; i < 8; i++)
				{
					if (target.MainWgoPart.WgoPartData.rotationIndex == want)
					{
						break;
					}
					bp.Rotate();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not turn the pointer: " + ex.Message));
			}
		}

		private static void FixAimRotation(BuildPointer bp, WgoBuildPointer po, int want)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Wgo target = po.Target;
				if ((Object)(object)target == (Object)null || (Object)(object)target.MainWgoPart == (Object)null || target.MainWgoPart.WgoPartData == null || !((BuildPointerObject)po).HasRotation())
				{
					return;
				}
				int i;
				for (i = 0; i < 8; i++)
				{
					if (target.MainWgoPart.WgoPartData.rotationIndex == want)
					{
						break;
					}
					bp.Rotate();
				}
				if (i == 0)
				{
					return;
				}
				Traverse val = Traverse.Create((object)Move.Controller());
				try
				{
					val.Method("UpdatePointerObjectPosition", new object[1] { val.Field("lastSnappedCursorPos").GetValue<Vector3>() }).GetValue();
				}
				catch
				{
				}
				try
				{
					object value = val.Field("buildLayout").GetValue();
					if (value != null)
					{
						Traverse.Create(value).Method("UpdateBuildingMode", Array.Empty<object>()).GetValue();
					}
				}
				catch
				{
				}
				try
				{
					bp.UpdateAvailability();
				}
				catch
				{
				}
				try
				{
					val.Method("UpdateFullCoverSoftBuildAreaHints", Array.Empty<object>()).GetValue();
				}
				catch
				{
				}
				try
				{
					val.Method("UpdateDockPointsHints", new object[1] { true }).GetValue();
				}
				catch
				{
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Blueprint: could not turn the aiming pointer: " + ex.Message));
			}
		}

		private unsafe static void PlaceAt(BuildPointer bp, WgoBuildPointer po, Item it, Vector3 world)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			SetRotation(bp, po, it.RotIdx);
			Vector3 value = Traverse.Create((object)po).Field("offset").GetValue<Vector3>();
			bp.UpdatePos(world - value);
			try
			{
				Physics.SyncTransforms();
			}
			catch
			{
			}
			bp.UpdateAvailability();
			if (it.Rank == 6)
			{
				try
				{
					Traverse.Create((object)Move.Controller()).Method("UpdateFullCoverSoftBuildAreaHints", Array.Empty<object>()).GetValue();
					bp.UpdateAvailability();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Blueprint: attachment slot: " + ex.Message));
				}
			}
			if (!_loggedDelta)
			{
				_loggedDelta = true;
				try
				{
					Plugin.Log.LogInfo((object)("Blueprint: pointer at " + ((object)po.Target.Data.Position/*cast due to .constrained prefix*/).ToString() + " for a wanted " + ((object)(*(Vector3*)(&world))/*cast due to .constrained prefix*/).ToString()));
				}
				catch
				{
				}
			}
		}

		private static Vector3 WorldOf(Item it)
		{
			//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)
			return WorldAt(it, _basePos);
		}

		private static void PlaceAtSlot(BuildPointer bp, WgoBuildPointer po, Item it)
		{
			//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_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_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: 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_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing refere