Decompiled source of Build Ease v0.3.16

BuildEase.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Build Ease")]
[assembly: AssemblyDescription("Easy UE-style building for Valheim.")]
[assembly: AssemblyCompany("Obelisk")]
[assembly: AssemblyProduct("Build Ease")]
[assembly: AssemblyFileVersion("0.3.16.0")]
[assembly: ComVisible(false)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.3.16.0")]
namespace Obelisk.UEPlacementEditor;

internal static class AAABuildMenuCompatibility
{
	private const string PluginGuid = "Azumatt.AAABuildMenu";

	private const string EnhancedBuildMenuTypeName = "AAABuildMenu.EnhancedBuildMenu";

	private static readonly FieldRef<Player, PieceTable> BuildPieces = AccessTools.FieldRefAccess<Player, PieceTable>("m_buildPieces");

	private static readonly FieldRef<PieceTable, List<List<Piece>>> AvailablePieces = AccessTools.FieldRefAccess<PieceTable, List<List<Piece>>>("m_availablePieces");

	[ThreadStatic]
	private static int _requirementEvaluationDepth;

	private static bool _resolved;

	private static bool _available;

	private static MethodInfo _applyFilterMethod;

	private static Func<bool> _activeGetter;

	private static Func<bool> _hasActiveFilter;

	private static Action<bool> _setNeedsRefresh;

	private static Action<Player> _setupPlacementGhost;

	private static FieldInfo _categoryMastersField;

	private static FieldInfo _selectedPieceField;

	private static FieldInfo _columnsField;

	private static Player _forcedPlayer;

	private static PieceTable _forcedTable;

	private static Piece _forcedPiece;

	private static PieceCategory _forcedCategory;

	private static bool _forcedPieceWasInjected;

	internal static bool IsRequirementEvaluationActive => _requirementEvaluationDepth > 0;

	internal static bool IsAvailable
	{
		get
		{
			EnsureResolved();
			return _available;
		}
	}

	internal static MethodBase ApplyFilterMethod
	{
		get
		{
			EnsureResolved();
			return _applyFilterMethod;
		}
	}

	internal static PieceTable GetBuildPieces(Player player)
	{
		if (!((Object)(object)player == (Object)null))
		{
			return BuildPieces.Invoke(player);
		}
		return null;
	}

	internal static bool BeginRequirementEvaluation(Player player, PieceTable pieceTable)
	{
		if (!IsRuntimeActive() || !IsLocalEditorTable(player, pieceTable))
		{
			return false;
		}
		_requirementEvaluationDepth++;
		return true;
	}

	internal static void EndRequirementEvaluation(bool entered)
	{
		if (entered && _requirementEvaluationDepth > 0)
		{
			_requirementEvaluationDepth--;
		}
	}

	internal static bool TryHandleFilteredCopySelection(Player player, Piece sampledWorldPiece)
	{
		//IL_0246: 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_0072: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: 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_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		if (!CopyPieceExecutionContextPatch.IsCopyPieceCall || !IsRuntimeActive() || !HasActiveFilter() || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)sampledWorldPiece == (Object)null || (Object)(object)Plugin.Controller == (Object)null || !Plugin.Controller.IsActive)
		{
			return false;
		}
		PieceTable val = BuildPieces.Invoke(player);
		if ((Object)(object)val == (Object)null || !TryFindMasterPiece(sampledWorldPiece, out var availablePiece, out var category) || !TryGetCategoryIndex(val, category, out var categoryIndex) || !TryGetCategoryIndex(val, val.GetSelectedCategory(), out var categoryIndex2))
		{
			return false;
		}
		List<List<Piece>> previousViews = CaptureAvailablePieceViews(val);
		Vector2Int[] previousIndices = ((val.m_selectedPiece != null) ? ((Vector2Int[])val.m_selectedPiece.Clone()) : Array.Empty<Vector2Int>());
		Piece enhancedSelectedPiece = GetEnhancedSelectedPiece();
		Piece selectedPiece = val.GetSelectedPiece();
		GameObject placementGhost = EditorController.GetPlacementGhost(player);
		bool flag = IsMatchingGhost(placementGhost, selectedPiece) && IsFinite(placementGhost.transform.position) && IsFinite(placementGhost.transform.rotation);
		Vector3 previousGhostPosition = (flag ? placementGhost.transform.position : Vector3.zero);
		Quaternion previousGhostRotation = (flag ? placementGhost.transform.rotation : Quaternion.identity);
		PieceTable forcedTable = _forcedTable;
		Piece forcedPiece = _forcedPiece;
		PieceCategory forcedCategory = _forcedCategory;
		bool forcedPieceWasInjected = _forcedPieceWasInjected;
		try
		{
			val.SetCategory(categoryIndex);
			if (!TryGetSelectedCategoryList(val, out var category2, out var pieces) || category2 != category)
			{
				RestorePreviousSelection(player, val, previousViews, previousIndices, categoryIndex2, enhancedSelectedPiece, selectedPiece, flag, previousGhostPosition, previousGhostRotation);
				return false;
			}
			RemovePreviousInjectedPiece(val, category2, pieces);
			int selectedIndex;
			bool forcedPieceWasInjected2 = InsertOrSelectPiece(pieces, availablePiece, out selectedIndex);
			val.SetSelected(ToGridIndex(selectedIndex));
			SetEnhancedSelectedPiece(availablePiece);
			_setupPlacementGhost(player);
			if (!IsMatchingGhost(EditorController.GetPlacementGhost(player), availablePiece))
			{
				RestorePreviousSelection(player, val, previousViews, previousIndices, categoryIndex2, enhancedSelectedPiece, selectedPiece, flag, previousGhostPosition, previousGhostRotation);
				return false;
			}
			if (forcedPieceWasInjected && (Object)(object)forcedPiece != (Object)null && ((Object)(object)forcedTable != (Object)(object)val || forcedCategory != category2))
			{
				RemoveInjectedPiece(forcedTable, forcedCategory, forcedPiece);
			}
			_forcedPlayer = player;
			_forcedTable = val;
			_forcedPiece = availablePiece;
			_forcedCategory = category2;
			_forcedPieceWasInjected = forcedPieceWasInjected2;
			return true;
		}
		catch (Exception arg)
		{
			try
			{
				RestorePreviousSelection(player, val, previousViews, previousIndices, categoryIndex2, enhancedSelectedPiece, selectedPiece, flag, previousGhostPosition, previousGhostRotation);
			}
			catch
			{
			}
			Plugin.LogError($"AAABuildMenu filtered sampling compatibility failed: {arg}");
			return false;
		}
	}

	internal static void AfterApplyFilter(Player player, PieceTable pieceTable)
	{
		if (!IsRuntimeActive() || !IsLocalPlayerTable(player, pieceTable))
		{
			return;
		}
		try
		{
			if (!IsLocalEditorTable(player, pieceTable) || !MaintainForcedSelection(player, pieceTable))
			{
				Piece selectedPiece = pieceTable.GetSelectedPiece();
				GameObject placementGhost = EditorController.GetPlacementGhost(player);
				bool flag = (Object)(object)selectedPiece != (Object)null && !selectedPiece.m_repairPiece && !selectedPiece.m_removePiece;
				if ((flag && !IsMatchingGhost(placementGhost, selectedPiece)) || (!flag && (Object)(object)placementGhost != (Object)null))
				{
					_setupPlacementGhost(player);
				}
			}
		}
		catch (Exception arg)
		{
			Plugin.LogError($"AAABuildMenu filter reconciliation failed: {arg}");
		}
	}

	internal static void OnBuildMenuOpening()
	{
		ReleaseForcedSelection(requestFilterRefresh: true);
	}

	internal static void OnEditorExit()
	{
		ReleaseForcedSelection(requestFilterRefresh: true);
	}

	private static bool MaintainForcedSelection(Player player, PieceTable pieceTable)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_forcedPiece == (Object)null)
		{
			return false;
		}
		if (Hud.IsPieceSelectionVisible() || (Object)(object)player != (Object)(object)_forcedPlayer || (Object)(object)pieceTable != (Object)(object)_forcedTable || pieceTable.GetSelectedCategory() != _forcedCategory || (Object)(object)Plugin.Controller == (Object)null || !Plugin.Controller.IsActive)
		{
			ReleaseForcedSelection(requestFilterRefresh: true);
			return false;
		}
		if (!TryGetSelectedCategoryList(pieceTable, out var _, out var pieces))
		{
			ReleaseForcedSelection(requestFilterRefresh: true);
			return false;
		}
		_forcedPieceWasInjected = InsertOrSelectPiece(pieces, _forcedPiece, out var selectedIndex);
		pieceTable.SetSelected(ToGridIndex(selectedIndex));
		SetEnhancedSelectedPiece(_forcedPiece);
		if (!IsMatchingGhost(EditorController.GetPlacementGhost(player), _forcedPiece))
		{
			_setupPlacementGhost(player);
		}
		return true;
	}

	private static void RemovePreviousInjectedPiece(PieceTable pieceTable, PieceCategory category, List<Piece> filteredView)
	{
		//IL_0021: 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)
		if (_forcedPieceWasInjected && !((Object)(object)_forcedPiece == (Object)null) && !((Object)(object)pieceTable != (Object)(object)_forcedTable) && category == _forcedCategory)
		{
			RemoveMatchingPieces(filteredView, _forcedPiece);
		}
	}

	private static void RemoveInjectedPiece(PieceTable pieceTable, PieceCategory category, Piece piece)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected I4, but got Unknown
		if (!((Object)(object)pieceTable == (Object)null) && !((Object)(object)piece == (Object)null))
		{
			List<List<Piece>> list = AvailablePieces.Invoke(pieceTable);
			int num = (int)category;
			if (list != null && num >= 0 && num < list.Count)
			{
				RemoveMatchingPieces(list[num], piece);
			}
		}
	}

	private static void RemoveMatchingPieces(List<Piece> pieces, Piece piece)
	{
		if (pieces == null || (Object)(object)piece == (Object)null)
		{
			return;
		}
		string prefabName = GetPrefabName(piece);
		for (int num = pieces.Count - 1; num >= 0; num--)
		{
			Piece val = pieces[num];
			if ((Object)(object)val != (Object)null && string.Equals(GetPrefabName(val), prefabName, StringComparison.Ordinal))
			{
				pieces.RemoveAt(num);
			}
		}
	}

	private static void RestorePreviousSelection(Player player, PieceTable pieceTable, List<List<Piece>> previousViews, Vector2Int[] previousIndices, int previousCategoryIndex, Piece previousSelectedPiece, Piece previousTableSelectedPiece, bool restoreGhostPose, Vector3 previousGhostPosition, Quaternion previousGhostRotation)
	{
		//IL_0063: 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)
		RestoreAvailablePieceViews(pieceTable, previousViews);
		if (pieceTable.m_selectedPiece != null && previousIndices != null)
		{
			Array.Copy(previousIndices, pieceTable.m_selectedPiece, Math.Min(previousIndices.Length, pieceTable.m_selectedPiece.Length));
		}
		pieceTable.SetCategory(previousCategoryIndex);
		SetEnhancedSelectedPiece(previousSelectedPiece);
		_setupPlacementGhost(player);
		GameObject placementGhost = EditorController.GetPlacementGhost(player);
		if (restoreGhostPose && IsMatchingGhost(placementGhost, previousTableSelectedPiece))
		{
			placementGhost.transform.SetPositionAndRotation(previousGhostPosition, previousGhostRotation);
		}
	}

	private static bool TryFindMasterPiece(Piece sampledWorldPiece, out Piece availablePiece, out PieceCategory category)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: 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_0038: Expected I4, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected I4, but got Unknown
		availablePiece = null;
		category = (PieceCategory)0;
		if (!(_categoryMastersField.GetValue(null) is IDictionary dictionary))
		{
			return false;
		}
		string prefabName = GetPrefabName(sampledWorldPiece);
		PieceCategory category2 = sampledWorldPiece.m_category;
		if (TryFindMasterPieceInCategory(dictionary, category2, prefabName, out availablePiece))
		{
			category = (PieceCategory)(int)category2;
			return true;
		}
		foreach (DictionaryEntry item in dictionary)
		{
			if (!(item.Key is PieceCategory val) || !(item.Value is IList list))
			{
				continue;
			}
			for (int i = 0; i < list.Count; i++)
			{
				object? obj = list[i];
				Piece val2 = (Piece)((obj is Piece) ? obj : null);
				if ((Object)(object)val2 != (Object)null && string.Equals(GetPrefabName(val2), prefabName, StringComparison.Ordinal))
				{
					availablePiece = val2;
					category = (PieceCategory)(int)val;
					return true;
				}
			}
		}
		return false;
	}

	private static bool TryFindMasterPieceInCategory(IDictionary categoryMasters, PieceCategory category, string prefabName, out Piece availablePiece)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		availablePiece = null;
		if (!(categoryMasters[category] is IList list))
		{
			return false;
		}
		for (int i = 0; i < list.Count; i++)
		{
			object? obj = list[i];
			Piece val = (Piece)((obj is Piece) ? obj : null);
			if ((Object)(object)val != (Object)null && string.Equals(GetPrefabName(val), prefabName, StringComparison.Ordinal))
			{
				availablePiece = val;
				return true;
			}
		}
		return false;
	}

	private static bool TryGetCategoryIndex(PieceTable pieceTable, PieceCategory category, out int categoryIndex)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		categoryIndex = -1;
		if ((Object)(object)pieceTable == (Object)null || pieceTable.m_categories == null)
		{
			return false;
		}
		for (int i = 0; i < pieceTable.m_categories.Count; i++)
		{
			if (pieceTable.m_categories[i] == category)
			{
				categoryIndex = i;
				return true;
			}
		}
		return false;
	}

	private static List<List<Piece>> CaptureAvailablePieceViews(PieceTable pieceTable)
	{
		List<List<Piece>> list = AvailablePieces.Invoke(pieceTable);
		List<List<Piece>> list2 = new List<List<Piece>>(list?.Count ?? 0);
		if (list == null)
		{
			return list2;
		}
		for (int i = 0; i < list.Count; i++)
		{
			List<Piece> list3 = list[i];
			list2.Add((list3 != null) ? new List<Piece>(list3) : null);
		}
		return list2;
	}

	private static void RestoreAvailablePieceViews(PieceTable pieceTable, List<List<Piece>> snapshot)
	{
		List<List<Piece>> list = AvailablePieces.Invoke(pieceTable);
		if (list == null || snapshot == null)
		{
			return;
		}
		while (list.Count > snapshot.Count)
		{
			list.RemoveAt(list.Count - 1);
		}
		for (int i = 0; i < snapshot.Count; i++)
		{
			List<Piece> list2 = snapshot[i];
			if (i >= list.Count)
			{
				list.Add((list2 != null) ? new List<Piece>(list2) : new List<Piece>());
				continue;
			}
			List<Piece> list3 = list[i];
			if (list3 == null)
			{
				list[i] = ((list2 != null) ? new List<Piece>(list2) : new List<Piece>());
				continue;
			}
			list3.Clear();
			if (list2 != null)
			{
				list3.AddRange(list2);
			}
		}
	}

	private static bool TryGetSelectedCategoryList(PieceTable pieceTable, out PieceCategory category, out List<Piece> pieces)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected I4, but got Unknown
		category = (PieceCategory)(int)pieceTable.GetSelectedCategory();
		List<List<Piece>> list = AvailablePieces.Invoke(pieceTable);
		int num = (int)category;
		if (list == null || num < 0 || num >= list.Count)
		{
			pieces = null;
			return false;
		}
		pieces = list[num];
		return pieces != null;
	}

	private static bool InsertOrSelectPiece(List<Piece> filteredView, Piece piece, out int selectedIndex)
	{
		string prefabName = GetPrefabName(piece);
		int num = -1;
		for (int num2 = filteredView.Count - 1; num2 >= 0; num2--)
		{
			Piece val = filteredView[num2];
			if (!((Object)(object)val == (Object)null) && string.Equals(GetPrefabName(val), prefabName, StringComparison.Ordinal))
			{
				num = num2;
				filteredView.RemoveAt(num2);
			}
		}
		selectedIndex = ((num >= 0) ? Mathf.Min(num, filteredView.Count) : 0);
		filteredView.Insert(selectedIndex, piece);
		return num < 0;
	}

	private static Vector2Int ToGridIndex(int linearIndex)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		int num = 15;
		if (_columnsField != null && _columnsField.GetValue(null) is int num2)
		{
			num = Mathf.Clamp(num2, 1, 64);
		}
		return new Vector2Int(linearIndex % num, linearIndex / num);
	}

	private static bool IsMatchingGhost(GameObject ghost, Piece piece)
	{
		if ((Object)(object)ghost != (Object)null && (Object)(object)piece != (Object)null && (Object)(object)ghost.GetComponent<Piece>() != (Object)null)
		{
			return string.Equals(Utils.GetPrefabName(ghost), GetPrefabName(piece), StringComparison.Ordinal);
		}
		return false;
	}

	private static bool IsFinite(Vector3 value)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
		{
			return !float.IsInfinity(value.z);
		}
		return false;
	}

	private static bool IsFinite(Quaternion value)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z) && !float.IsInfinity(value.z) && !float.IsNaN(value.w))
		{
			return !float.IsInfinity(value.w);
		}
		return false;
	}

	private static string GetPrefabName(Piece piece)
	{
		if (!((Object)(object)piece == (Object)null))
		{
			return Utils.GetPrefabName(((Component)piece).gameObject);
		}
		return string.Empty;
	}

	private static Piece GetEnhancedSelectedPiece()
	{
		object? value = _selectedPieceField.GetValue(null);
		return (Piece)((value is Piece) ? value : null);
	}

	private static void SetEnhancedSelectedPiece(Piece piece)
	{
		_selectedPieceField.SetValue(null, piece);
	}

	private static bool HasActiveFilter()
	{
		try
		{
			return _hasActiveFilter();
		}
		catch
		{
			return false;
		}
	}

	private static bool IsRuntimeActive()
	{
		if (!IsAvailable)
		{
			return false;
		}
		try
		{
			return _activeGetter();
		}
		catch
		{
			return false;
		}
	}

	private static bool IsLocalEditorTable(Player player, PieceTable pieceTable)
	{
		if (IsLocalPlayerTable(player, pieceTable) && (Object)(object)Plugin.Controller != (Object)null)
		{
			return Plugin.Controller.IsActive;
		}
		return false;
	}

	private static bool IsLocalPlayerTable(Player player, PieceTable pieceTable)
	{
		if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer && (Object)(object)pieceTable != (Object)null)
		{
			return (Object)(object)BuildPieces.Invoke(player) == (Object)(object)pieceTable;
		}
		return false;
	}

	private static void ReleaseForcedSelection(bool requestFilterRefresh)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		bool flag = (Object)(object)_forcedPiece != (Object)null;
		_forcedPlayer = null;
		_forcedTable = null;
		_forcedPiece = null;
		_forcedCategory = (PieceCategory)0;
		_forcedPieceWasInjected = false;
		if (requestFilterRefresh && flag && IsAvailable)
		{
			try
			{
				_setNeedsRefresh(obj: true);
			}
			catch
			{
			}
		}
	}

	private static void EnsureResolved()
	{
		if (_resolved)
		{
			return;
		}
		_resolved = true;
		if (!Chainloader.PluginInfos.ContainsKey("Azumatt.AAABuildMenu"))
		{
			return;
		}
		try
		{
			Type type = OptionalModTypeResolver.FindLoadedType("AAABuildMenu.EnhancedBuildMenu");
			_applyFilterMethod = ((type == null) ? null : AccessTools.Method(type, "ApplyFilter", new Type[3]
			{
				typeof(Player),
				typeof(PieceTable),
				typeof(bool)
			}, (Type[])null));
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.PropertyGetter(type, "Active"));
			MethodInfo methodInfo2 = ((type == null) ? null : AccessTools.Method(type, "HasActiveFilter", Type.EmptyTypes, (Type[])null));
			MethodInfo methodInfo3 = ((type == null) ? null : AccessTools.PropertySetter(type, "NeedsRefresh"));
			_categoryMastersField = ((type == null) ? null : AccessTools.Field(type, "_categoryMasters"));
			_selectedPieceField = ((type == null) ? null : AccessTools.Field(type, "SelectedPiece"));
			_columnsField = ((type == null) ? null : AccessTools.Field(type, "Columns"));
			MethodInfo methodInfo4 = AccessTools.Method(typeof(Player), "SetupPlacementGhost", Type.EmptyTypes, (Type[])null);
			if (_applyFilterMethod == null || methodInfo == null || methodInfo2 == null || methodInfo3 == null || _categoryMastersField == null || _selectedPieceField == null || _columnsField == null || methodInfo4 == null)
			{
				Plugin.LogError("AAABuildMenu was detected, but its compatibility API does not match version 1.0.1; integration is disabled.");
				return;
			}
			_activeGetter = AccessTools.MethodDelegate<Func<bool>>(methodInfo, (object)null, true);
			_hasActiveFilter = AccessTools.MethodDelegate<Func<bool>>(methodInfo2, (object)null, true);
			_setNeedsRefresh = AccessTools.MethodDelegate<Action<bool>>(methodInfo3, (object)null, true);
			_setupPlacementGhost = AccessTools.MethodDelegate<Action<Player>>(methodInfo4, (object)null, true);
			_available = _activeGetter != null && _hasActiveFilter != null && _setNeedsRefresh != null && _setupPlacementGhost != null;
		}
		catch (Exception arg)
		{
			_available = false;
			Plugin.LogError($"AAABuildMenu compatibility initialization failed: {arg}");
		}
	}
}
[HarmonyPatch]
internal static class AAABuildMenuApplyFilterPatch
{
	private static bool Prepare()
	{
		return AAABuildMenuCompatibility.IsAvailable;
	}

	private static MethodBase TargetMethod()
	{
		return AAABuildMenuCompatibility.ApplyFilterMethod;
	}

	private static void Prefix(Player __0, PieceTable __1, out bool __state)
	{
		__state = AAABuildMenuCompatibility.BeginRequirementEvaluation(__0, __1);
	}

	[HarmonyPriority(0)]
	private static void Postfix(Player __0, PieceTable __1)
	{
		AAABuildMenuCompatibility.AfterApplyFilter(__0, __1);
	}

	private static Exception Finalizer(Exception __exception, bool __state)
	{
		AAABuildMenuCompatibility.EndRequirementEvaluation(__state);
		return __exception;
	}
}
[HarmonyPatch]
internal static class AAABuildMenuHudUpdateBuildRequirementPatch
{
	private static bool Prepare()
	{
		return AAABuildMenuCompatibility.IsAvailable;
	}

	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(typeof(Hud), "UpdateBuild", new Type[2]
		{
			typeof(Player),
			typeof(bool)
		}, (Type[])null);
	}

	[HarmonyPriority(800)]
	private static void Prefix(Player __0, out bool __state)
	{
		PieceTable buildPieces = AAABuildMenuCompatibility.GetBuildPieces(__0);
		__state = AAABuildMenuCompatibility.BeginRequirementEvaluation(__0, buildPieces);
	}

	private static Exception Finalizer(Exception __exception, bool __state)
	{
		AAABuildMenuCompatibility.EndRequirementEvaluation(__state);
		return __exception;
	}
}
[HarmonyPatch]
internal static class AAABuildMenuCopySelectionPatch
{
	private static bool Prepare()
	{
		return AAABuildMenuCompatibility.IsAvailable;
	}

	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(typeof(Player), "SetSelectedPiece", new Type[1] { typeof(Piece) }, (Type[])null);
	}

	[HarmonyPriority(0)]
	private static bool Prefix(Player __instance, Piece __0, ref bool __result)
	{
		if (!AAABuildMenuCompatibility.TryHandleFilteredCopySelection(__instance, __0))
		{
			return true;
		}
		__result = true;
		return false;
	}
}
[HarmonyPatch]
internal static class AAABuildMenuBuildMenuOpenPatch
{
	private static bool Prepare()
	{
		return AAABuildMenuCompatibility.IsAvailable;
	}

	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(typeof(Hud), "TogglePieceSelection", (Type[])null, (Type[])null);
	}

	private static void Prefix()
	{
		if (!Hud.IsPieceSelectionVisible())
		{
			AAABuildMenuCompatibility.OnBuildMenuOpening();
		}
	}
}
internal enum EditMode
{
	Translate,
	Rotate
}
internal enum CoordinateSpace
{
	World,
	Local
}
internal sealed class EditorController : MonoBehaviour
{
	private enum TargetStatusKind
	{
		NoGhost,
		SpecialPiece,
		Piece
	}

	private struct PlacementRotationSnapshot
	{
		internal int PlaceRotation;

		internal float ScrollCurrentAmount;

		internal float RotatePieceTimer;

		internal bool PerfectPlacementAvailable;

		internal bool PerfectPlacementHadEntry;

		internal Vector3 PerfectPlacementRotation;
	}

	internal sealed class DemolitionPickupTransaction
	{
		internal readonly HashSet<int> ExistingDropIds = new HashSet<int>();

		internal readonly Dictionary<string, int> RemainingResources = new Dictionary<string, int>();

		internal Vector3 Center;

		internal float ExpiresAt;
	}

	private static readonly FieldRef<Player, GameObject> PlacementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

	private static readonly FieldRef<Player, GameObject> PlacementMarker = AccessTools.FieldRefAccess<Player, GameObject>("m_placementMarkerInstance");

	private static readonly FieldRef<Player, PlacementStatus> PlacementStatus = AccessTools.FieldRefAccess<Player, PlacementStatus>("m_placementStatus");

	private static readonly FieldRef<Player, int> PlaceRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask");

	private static readonly FieldRef<Player, int> RemoveRayMask = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

	private static readonly FieldRef<Player, float> MaximumPlaceDistance = AccessTools.FieldRefAccess<Player, float>("m_maxPlaceDistance");

	private static readonly FieldRef<Player, int> PlaceRotation = AccessTools.FieldRefAccess<Player, int>("m_placeRotation");

	private static readonly FieldRef<bool> EnableAutoPickup = AccessTools.StaticFieldRefAccess<bool>(AccessTools.Field(typeof(Player), "m_enableAutoPickup"));

	private static readonly FieldRef<Player, float> ScrollCurrentAmount = AccessTools.FieldRefAccess<Player, float>("m_scrollCurrAmount");

	private static readonly FieldRef<Player, float> RotatePieceTimer = AccessTools.FieldRefAccess<Player, float>("m_rotatePieceTimer");

	private static readonly MethodInfo UpdatePlacementMethod = AccessTools.Method(typeof(Player), "UpdatePlacement", new Type[2]
	{
		typeof(bool),
		typeof(float)
	}, (Type[])null);

	private static readonly Action<Player, bool, float> UpdatePlacementInvoker = CreateUpdatePlacementInvoker();

	private static readonly string[] HotbarButtons = new string[8] { "Hotbar1", "Hotbar2", "Hotbar3", "Hotbar4", "Hotbar5", "Hotbar6", "Hotbar7", "Hotbar8" };

	private static readonly KeyCode[] HotbarKeys;

	private static bool _externalModeResolversInitialized;

	private static Func<bool> _perfectPlacementBuildingMode;

	private static Func<bool> _perfectPlacementEditingMode;

	private static Func<bool> _buildCameraMode;

	private static bool _moveBuildPiecesPresent;

	private static bool _moveBuildPiecesResolved;

	private static Func<bool> _moveBuildPiecesEnabled;

	private static Func<Player, bool> _moveBuildPiecesBlocksBuildAction;

	private static Func<KeyboardShortcut> _moveBuildPiecesBuildModeHotkey;

	private static Func<KeyboardShortcut> _moveBuildPiecesWorldModeHotkey;

	private static Func<KeyboardShortcut> _moveBuildPiecesMixedModeHotkey;

	private static FieldInfo _moveBuildPiecesPendingRequest;

	private static IDictionary _perfectPlacementPlayersData;

	private static FieldRef<object, Vector3> _perfectPlacementPlaceRotation;

	private const float RightMouseClickTime = 0.28f;

	private const float RightMouseLookThreshold = 0.35f;

	private const float BuildSnapDistance = 0.5f;

	private const float BuildSnapSearchRadius = 10f;

	private const int MaximumSnapPieceBufferSize = 16384;

	private const int MaximumClippingBufferSize = 32768;

	private const float DemolitionPickupRadius = 3f;

	private const float DemolitionPickupInterval = 0.1f;

	private const float DemolitionPickupDuration = 5f;

	private const float HammerEquipTimeout = 8f;

	private const float CameraRayFollowPositionEpsilonSquared = 1E-06f;

	private const float CameraRayFollowDirectionDotThreshold = 0.9999995f;

	private const float TranslationStepEpsilon = 0.001f;

	private const int ToolbarWindowId = 20260714;

	private static readonly Color CameraLightColor;

	private static readonly GUILayoutOption HeaderWidth;

	private static readonly GUILayoutOption TranslateWidth;

	private static readonly GUILayoutOption RotateWidth;

	private static readonly GUILayoutOption SpaceWidth;

	private static readonly GUILayoutOption SnapWidth;

	private static readonly GUILayoutOption CameraLightWidth;

	private static readonly GUILayoutOption CameraRayFollowWidth;

	private static readonly GUILayoutOption ResetWidth;

	private static readonly GUILayoutOption ExitWidth;

	private static readonly Rect ToolbarDragRect;

	private readonly List<Character> _nearbyCharacters = new List<Character>(16);

	private readonly List<Transform> _sourceSnapPoints = new List<Transform>(32);

	private readonly List<Transform> _destinationSnapPoints = new List<Transform>(128);

	private readonly List<Piece> _nearbyPieces = new List<Piece>(64);

	private readonly HashSet<Piece> _nearbyPieceSet = new HashSet<Piece>();

	private readonly HashSet<ItemDrop> _demolitionPickupDrops = new HashSet<ItemDrop>();

	private readonly List<DemolitionPickupTransaction> _demolitionPickupTransactions = new List<DemolitionPickupTransaction>(8);

	private readonly PlacementGhostVisual _placementGhostVisual = new PlacementGhostVisual();

	private Collider[] _targetColliders = Array.Empty<Collider>();

	private Renderer[] _targetGeometryRenderers = Array.Empty<Renderer>();

	private Collider[] _snapPieceBuffer = (Collider[])(object)new Collider[256];

	private Collider[] _clippingBuffer = (Collider[])(object)new Collider[256];

	private Collider[] _demolitionPickupBuffer = (Collider[])(object)new Collider[128];

	private RaycastHit[] _surfaceRaycastBuffer = (RaycastHit[])(object)new RaycastHit[64];

	private int _itemLayerMask;

	private int _pieceLayerMask;

	private GizmoRenderer _gizmo;

	private Camera _editorCamera;

	private GameObject _targetGhost;

	private Piece _targetPiece;

	private Piece _targetSelectedPiece;

	private Piece _observedSelectedPiece;

	private bool _observedSelectedPieceCompatible;

	private bool _hasCachedPlacementStatus;

	private PlacementStatus _cachedPlacementStatus;

	private Vector3 _desiredPosition;

	private Quaternion _desiredRotation;

	private bool _copiedPieceThisPlacementUpdate;

	private bool _hasSampledPlacementRotation;

	private bool _sampledCopySucceededThisPlacementUpdate;

	private int _sampledPlaceRotation;

	private Quaternion _sampledPlacementRotation;

	private EditMode _mode;

	private CoordinateSpace _space;

	private bool _surfaceSnapEnabled;

	private bool _cameraRayFollowEnabled;

	private bool _cameraRayFollowUpdatePending;

	private bool _hasCameraRayFollowInput;

	private Vector3 _lastCameraRayFollowOrigin;

	private Vector3 _lastCameraRayFollowDirection;

	private bool _hasTemporaryPivot;

	private bool _surfaceSupportInvalid;

	private Vector3 _temporaryPivotLocal;

	private bool _active;

	private bool _placementUpdateFailed;

	private bool _editorEntryPending;

	private bool _pendingEquipIssued;

	private bool _pendingOwnEquipAction;

	private Player _pendingEntryPlayer;

	private Inventory _pendingEntryInventory;

	private ItemData _pendingEntryHammer;

	private float _pendingEntryDeadline;

	private bool _rightMouseActive;

	private bool _rightMouseMoved;

	private bool _rightMouseMenuWasVisible;

	private float _rightMouseDownTime;

	private float _rightMouseLookMagnitude;

	private Vector3 _rightMouseStartCameraPosition;

	private float _rightMouseStartYaw;

	private float _rightMouseStartPitch;

	private bool _cameraCapturedLastFrame;

	private bool _cameraPositionDirty;

	private Vector3 _cameraPosition;

	private float _cameraYaw;

	private float _cameraPitch;

	private float _cameraSpeedScale = 1f;

	private Light _cameraLight;

	private volatile bool _cameraLightSettingsDirty;

	private volatile bool _ghostPreviewSettingsDirty;

	private bool _blueGhostPreviewEnabled;

	private volatile bool _toolbarLabelsDirty;

	private EditorLanguage _language = EditorLanguage.English;

	private bool _languageInitialized;

	private float _nextDemolitionPickupTime;

	private float _lastDemolitionPickupErrorTime = float.NegativeInfinity;

	private Player _distancePlayer;

	private bool _insidePlacementUpdate;

	private float _originalPlaceDistance;

	private float _appliedPlaceDistance;

	private int _uiInputBlockedThroughFrame = -1;

	private int _placementInputBlockedThroughFrame = -1;

	private int _reserveHotkeysThroughFrame = -1;

	private Rect _toolbarRect = new Rect(10f, 10f, 1290f, 86f);

	private WindowFunction _toolbarWindowFunction;

	private bool _toolbarDragging;

	private TargetStatusKind _targetStatusKind;

	private string _targetStatusPieceToken;

	private string _targetStatusText = string.Empty;

	private string _spaceButtonLabel;

	private string _surfaceSnapButtonLabel;

	private string _cameraLightButtonLabel;

	private string _cameraRayFollowButtonLabel;

	private string _exitButtonLabel;

	private GizmoAxis _dragAxis;

	private Plane _dragPlane;

	private Vector3 _dragWorldAxis;

	private Vector3 _dragStartRootPosition;

	private Vector3 _dragStartPivot;

	private Vector3 _dragStartPlanePoint;

	private Quaternion _dragStartRotation;

	private float _dragStartAxisParameter;

	private Vector3 _dragStartVector;

	private bool _dragUsesScreenSpace;

	private Vector2 _dragStartMouse;

	private Vector2 _dragScreenDirection;

	private float _dragScreenScale;

	private float _dragBoundsTranslationStep;

	private float _dragSnapPointTranslationStep;

	private static int _suppressMenuFrame;

	private static int _buildMenuConsumedEscapeFrame;

	internal bool IsActive => _active;

	internal bool HasGizmoTarget
	{
		get
		{
			if ((Object)(object)_targetGhost != (Object)null)
			{
				return (Object)(object)_targetPiece != (Object)null;
			}
			return false;
		}
	}

	internal Transform TargetTransform
	{
		get
		{
			if (!HasGizmoTarget)
			{
				return null;
			}
			return _targetGhost.transform;
		}
	}

	internal Vector3 GizmoPivot
	{
		get
		{
			//IL_0029: 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_003b: 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)
			if (!HasGizmoTarget || !_hasTemporaryPivot)
			{
				if (!HasGizmoTarget)
				{
					return Vector3.zero;
				}
				return _targetGhost.transform.position;
			}
			return _targetGhost.transform.TransformPoint(_temporaryPivotLocal);
		}
	}

	internal Camera EditorCamera
	{
		get
		{
			if ((Object)(object)_editorCamera == (Object)null)
			{
				_editorCamera = ResolveGameCamera();
			}
			return _editorCamera;
		}
	}

	internal EditMode Mode => _mode;

	internal CoordinateSpace Space => _space;

	internal float ActiveEditorRange => GetEditorRange();

	internal bool ShouldExtendBuildStationRange
	{
		get
		{
			if (!_active || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if (IsEditorBlockedInCurrentInterior(Player.m_localPlayer))
			{
				return false;
			}
			if (AAABuildMenuCompatibility.IsRequirementEvaluationActive)
			{
				return true;
			}
			if (!_insidePlacementUpdate)
			{
				return false;
			}
			Piece selectedPiece = Player.m_localPlayer.GetSelectedPiece();
			if ((Object)(object)selectedPiece != (Object)null && !selectedPiece.m_repairPiece)
			{
				return !selectedPiece.m_removePiece;
			}
			return false;
		}
	}

	internal bool ShouldRenderEditorOverlay
	{
		get
		{
			if (_active && !IsGameUiBlockingEditorInput())
			{
				return !Hud.IsPieceSelectionVisible();
			}
			return false;
		}
	}

	private bool ShouldRenderToolbar
	{
		get
		{
			if (ShouldRenderEditorOverlay)
			{
				return Plugin.ShowToolbar.Value;
			}
			return false;
		}
	}

	internal bool ShouldReserveEditorHotkeys
	{
		get
		{
			if (!_active && !_editorEntryPending)
			{
				return Time.frameCount <= _reserveHotkeysThroughFrame;
			}
			return true;
		}
	}

	internal bool ShouldOwnEscapeInput => ShouldRenderEditorOverlay;

	internal static bool SuppressMenuThisFrame => Time.frameCount == _suppressMenuFrame;

	internal static bool BuildMenuConsumedEscapeThisFrame => Time.frameCount == _buildMenuConsumedEscapeFrame;

	private bool IsEditorInputSuppressed
	{
		get
		{
			if (!IsGameUiBlockingEditorInput())
			{
				return Time.frameCount <= _uiInputBlockedThroughFrame;
			}
			return true;
		}
	}

	private bool IsCameraCaptured
	{
		get
		{
			if (_active && !IsEditorInputSuppressed)
			{
				return _rightMouseActive;
			}
			return false;
		}
	}

	private void Awake()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		_itemLayerMask = LayerMask.GetMask(new string[1] { "item" });
		_pieceLayerMask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" });
		_toolbarWindowFunction = new WindowFunction(DrawToolbarWindow);
		_gizmo = ((Component)this).gameObject.AddComponent<GizmoRenderer>();
		_gizmo.Controller = this;
		((Behaviour)_gizmo).enabled = false;
		Plugin.ToggleEditorKey.SettingChanged += OnToolbarHotkeySettingChanged;
		Plugin.ToggleSurfaceSnapKey.SettingChanged += OnToolbarHotkeySettingChanged;
		Plugin.ToggleCoordinateSpaceKey.SettingChanged += OnToolbarHotkeySettingChanged;
		Plugin.ToggleCameraLightKey.SettingChanged += OnToolbarHotkeySettingChanged;
		Plugin.ToggleCameraRayFollowKey.SettingChanged += OnToolbarHotkeySettingChanged;
		Plugin.CameraLightRange.SettingChanged += OnCameraLightSettingChanged;
		Plugin.CameraLightIntensity.SettingChanged += OnCameraLightSettingChanged;
		Plugin.BlueGhostPreview.SettingChanged += OnGhostPreviewSettingChanged;
		_blueGhostPreviewEnabled = Plugin.BlueGhostPreview.Value;
		Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnGameLanguageChanged));
	}

	private void OnDestroy()
	{
		Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(OnGameLanguageChanged));
		CancelPendingEditorEntry(removeOwnedEquipAction: true);
		_placementGhostVisual.Restore();
		DestroyCameraLight();
		Plugin.ToggleEditorKey.SettingChanged -= OnToolbarHotkeySettingChanged;
		Plugin.ToggleSurfaceSnapKey.SettingChanged -= OnToolbarHotkeySettingChanged;
		Plugin.ToggleCoordinateSpaceKey.SettingChanged -= OnToolbarHotkeySettingChanged;
		Plugin.ToggleCameraLightKey.SettingChanged -= OnToolbarHotkeySettingChanged;
		Plugin.ToggleCameraRayFollowKey.SettingChanged -= OnToolbarHotkeySettingChanged;
		Plugin.CameraLightRange.SettingChanged -= OnCameraLightSettingChanged;
		Plugin.CameraLightIntensity.SettingChanged -= OnCameraLightSettingChanged;
		Plugin.BlueGhostPreview.SettingChanged -= OnGhostPreviewSettingChanged;
		_toolbarWindowFunction = null;
	}

	private void Update()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		if (_toolbarDragging && (!Plugin.ShowToolbar.Value || !Input.GetMouseButton(0)))
		{
			_toolbarDragging = false;
		}
		if (_cameraLightSettingsDirty)
		{
			_cameraLightSettingsDirty = false;
			ApplyCameraLightSettings();
		}
		if (_ghostPreviewSettingsDirty)
		{
			_ghostPreviewSettingsDirty = false;
			ApplyGhostPreviewSetting();
		}
		if (_toolbarLabelsDirty)
		{
			_toolbarLabelsDirty = false;
			RefreshToolbarLabels();
		}
		UpdateDemolitionAutoPickupSafe();
		if (EditorInputFirewall.IsEditorShortcutDown(Plugin.ToggleEditorKey.Value) && !IsGameUiBlockingEditorInput())
		{
			_reserveHotkeysThroughFrame = Time.frameCount;
			if (_active)
			{
				ExitEditor();
			}
			else if (_editorEntryPending)
			{
				CancelPendingEditorEntry(removeOwnedEquipAction: true);
			}
			else
			{
				BeginEditorEntry();
			}
			return;
		}
		if (_editorEntryPending)
		{
			UpdatePendingEditorEntry();
		}
		if (!_active)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)GameCamera.instance == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting() || !((Character)localPlayer).InPlaceMode())
		{
			ExitEditor();
			return;
		}
		if (IsEditorBlockedInCurrentInterior(localPlayer))
		{
			ExitEditor();
			((Character)localPlayer).Message((MessageType)2, "$msg_notindungeon", 0, (Sprite)null);
			return;
		}
		if (IsConflictingEditorActive())
		{
			ExitEditor();
			((Character)localPlayer).Message((MessageType)1, _language.DisableConflictingEditor, 0, (Sprite)null);
			return;
		}
		if (IsGameUiBlockingEditorInput())
		{
			_uiInputBlockedThroughFrame = Time.frameCount + 1;
			SuspendEditorInput();
			return;
		}
		if (Time.frameCount <= _uiInputBlockedThroughFrame)
		{
			SuspendEditorInput();
			return;
		}
		RefreshPlacementGhostReference(localPlayer);
		if (Input.GetKeyDown((KeyCode)27))
		{
			if (!BuildMenuConsumedEscapeThisFrame && !Hud.IsPieceSelectionVisible())
			{
				ReserveEscapeInput();
				ExitEditor();
			}
			return;
		}
		UpdateRightMouseGesture();
		if (Hud.IsPieceSelectionVisible())
		{
			CancelDrag();
			return;
		}
		bool flag = HandleCameraRayFollowShortcut();
		if (!flag)
		{
			flag = HandleCameraLightShortcut();
		}
		if (IsCameraCaptured)
		{
			CancelDrag();
			return;
		}
		if (!flag)
		{
			HandleEditorShortcuts();
		}
		HandlePointer();
	}

	private void SuspendEditorInput()
	{
		_toolbarDragging = false;
		_rightMouseActive = false;
		_rightMouseMoved = false;
		_cameraCapturedLastFrame = false;
		CancelDrag();
		if ((Object)(object)_gizmo != (Object)null)
		{
			_gizmo.HoveredAxis = GizmoAxis.None;
		}
	}

	private void UpdateRightMouseGesture()
	{
		//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_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetMouseButtonDown(1))
		{
			_rightMouseActive = true;
			_rightMouseMoved = false;
			_rightMouseMenuWasVisible = Hud.IsPieceSelectionVisible();
			_rightMouseDownTime = Time.unscaledTime;
			_rightMouseLookMagnitude = 0f;
			_rightMouseStartCameraPosition = _cameraPosition;
			_rightMouseStartYaw = _cameraYaw;
			_rightMouseStartPitch = _cameraPitch;
			if (_rightMouseMenuWasVisible)
			{
				Hud.HidePieceSelection();
			}
		}
		if (!_rightMouseActive || !Input.GetMouseButtonUp(1))
		{
			return;
		}
		float num = Time.unscaledTime - _rightMouseDownTime;
		bool num2 = !_rightMouseMoved && num <= 0.28f;
		_rightMouseActive = false;
		_cameraCapturedLastFrame = false;
		if (num2)
		{
			_cameraPosition = _rightMouseStartCameraPosition;
			_cameraYaw = _rightMouseStartYaw;
			_cameraPitch = _rightMouseStartPitch;
			_cameraPositionDirty = true;
			if (!_rightMouseMenuWasVisible)
			{
				ToggleBuildMenu();
			}
		}
		_rightMouseMenuWasVisible = false;
	}

	private void HandleEditorShortcuts()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (EditorInputFirewall.IsEditorShortcutDown(Plugin.ToggleCoordinateSpaceKey.Value))
		{
			ToggleCoordinateSpace();
		}
		else if (EditorInputFirewall.IsEditorShortcutDown(Plugin.ToggleSurfaceSnapKey.Value))
		{
			ToggleSurfaceSnapping();
		}
		else if (Input.GetKeyDown((KeyCode)119))
		{
			SetEditMode(EditMode.Translate);
		}
		else if (Input.GetKeyDown((KeyCode)101) || Input.GetKeyDown((KeyCode)114))
		{
			SetEditMode(EditMode.Rotate);
		}
	}

	private bool HandleCameraLightShortcut()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (!EditorInputFirewall.IsEditorShortcutDown(Plugin.ToggleCameraLightKey.Value))
		{
			return false;
		}
		ToggleCameraLight();
		return true;
	}

	private bool HandleCameraRayFollowShortcut()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (!EditorInputFirewall.IsEditorShortcutDown(Plugin.ToggleCameraRayFollowKey.Value))
		{
			return false;
		}
		ToggleCameraRayFollow();
		return true;
	}

	private void SetEditMode(EditMode mode)
	{
		if (_mode != mode)
		{
			CancelDrag();
			_mode = mode;
		}
	}

	private void ToggleCoordinateSpace()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_0095: 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_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		Transform val = (HasGizmoTarget ? _targetGhost.transform : null);
		Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : Vector3.zero);
		Quaternion val3 = (((Object)(object)val != (Object)null) ? val.rotation : Quaternion.identity);
		int num;
		int num2;
		if ((Object)(object)val != (Object)null && IsFinite(val2))
		{
			num = (IsFinite(val3) ? 1 : 0);
			if (num != 0)
			{
				num2 = (_hasTemporaryPivot ? 1 : 0);
				goto IL_006b;
			}
		}
		else
		{
			num = 0;
		}
		num2 = 0;
		goto IL_006b;
		IL_006b:
		bool flag = (byte)num2 != 0;
		bool flag2 = flag;
		Vector3 val4 = (flag2 ? GizmoPivot : val2);
		if (flag2 && !IsFinite(val4))
		{
			flag2 = false;
			val4 = val2;
		}
		if (num != 0)
		{
			_desiredPosition = val2;
			_desiredRotation = val3;
		}
		CancelDrag();
		_space = ((_space == CoordinateSpace.World) ? CoordinateSpace.Local : CoordinateSpace.World);
		RefreshToolbarLabels();
		_placementInputBlockedThroughFrame = Mathf.Max(_placementInputBlockedThroughFrame, Time.frameCount);
		if (num != 0 && HasGizmoTarget)
		{
			_targetGhost.transform.SetPositionAndRotation(val2, val3);
			_desiredPosition = val2;
			_desiredRotation = val3;
			if (flag2)
			{
				SetTemporaryPivot(val4);
			}
			else if (flag)
			{
				ClearTemporaryPivot(clearSurfaceSupport: false);
			}
		}
	}

	private void ToggleSurfaceSnapping()
	{
		CancelDrag();
		_surfaceSnapEnabled = !_surfaceSnapEnabled;
		_placementInputBlockedThroughFrame = Mathf.Max(_placementInputBlockedThroughFrame, Time.frameCount);
		if (!_surfaceSnapEnabled)
		{
			ClearTemporaryPivot(clearSurfaceSupport: false);
			if (HasGizmoTarget && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				ValidateEditedGhost(Player.m_localPlayer, _targetPiece, flashGuardStone: false);
			}
		}
		if (_cameraRayFollowEnabled)
		{
			_cameraRayFollowUpdatePending = true;
		}
		RefreshToolbarLabels();
	}

	private void ToggleCameraLight()
	{
		if ((Object)(object)_cameraLight != (Object)null)
		{
			DestroyCameraLight();
		}
		else
		{
			CreateCameraLight();
		}
		RefreshToolbarLabels();
	}

	private void ToggleCameraRayFollow()
	{
		CancelDrag();
		_cameraRayFollowEnabled = !_cameraRayFollowEnabled;
		_cameraRayFollowUpdatePending = _cameraRayFollowEnabled;
		_hasCameraRayFollowInput = false;
		_placementInputBlockedThroughFrame = Mathf.Max(_placementInputBlockedThroughFrame, Time.frameCount);
		RefreshToolbarLabels();
	}

	private void CreateCameraLight()
	{
		//IL_0028: 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_0036: Expected O, but got Unknown
		//IL_004e: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		DestroyCameraLight();
		Camera editorCamera = EditorCamera;
		if ((Object)(object)editorCamera == (Object)null)
		{
			Plugin.LogError("Could not create camera light: editor camera is unavailable");
			return;
		}
		GameObject val = null;
		try
		{
			val = new GameObject("Build Ease Camera Light")
			{
				hideFlags = (HideFlags)61
			};
			val.transform.SetParent(((Component)editorCamera).transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			_cameraLight = val.AddComponent<Light>();
			((Behaviour)_cameraLight).enabled = false;
			_cameraLight.type = (LightType)2;
			_cameraLight.color = CameraLightColor;
			_cameraLight.renderMode = (LightRenderMode)0;
			ApplyCameraLightSettings();
			((Behaviour)_cameraLight).enabled = true;
		}
		catch (Exception arg)
		{
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
			_cameraLight = null;
			Plugin.LogError($"Could not create camera light: {arg}");
		}
	}

	private void DestroyCameraLight()
	{
		GameObject val = null;
		if ((Object)(object)_cameraLight != (Object)null)
		{
			((Behaviour)_cameraLight).enabled = false;
			val = ((Component)_cameraLight).gameObject;
		}
		_cameraLight = null;
		if ((Object)(object)val != (Object)null)
		{
			Object.Destroy((Object)(object)val);
		}
	}

	private void ApplyCameraLightSettings()
	{
		if (!((Object)(object)_cameraLight == (Object)null))
		{
			_cameraLight.range = GetSafeConfigValue(Plugin.CameraLightRange.Value, 100f, 1f, 100f);
			_cameraLight.intensity = GetSafeConfigValue(Plugin.CameraLightIntensity.Value, 1.5f, 0f, 10f);
			_cameraLight.shadows = (LightShadows)0;
			_cameraLight.shadowStrength = 0f;
		}
	}

	private void HandlePointer()
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		Camera editorCamera = EditorCamera;
		if ((Object)(object)editorCamera == (Object)null)
		{
			return;
		}
		if (_dragAxis != GizmoAxis.None)
		{
			if (Input.GetMouseButton(0))
			{
				ContinueDrag(editorCamera);
			}
			else
			{
				CancelDrag();
			}
		}
		else if (!IsPointerOverToolbar())
		{
			_gizmo.HoveredAxis = (HasGizmoTarget ? _gizmo.HitTest(editorCamera, Input.mousePosition) : GizmoAxis.None);
			if (Input.GetMouseButtonDown(0) && _gizmo.HoveredAxis != GizmoAxis.None)
			{
				_placementInputBlockedThroughFrame = Mathf.Max(_placementInputBlockedThroughFrame, Time.frameCount);
				BeginDrag(editorCamera, _gizmo.HoveredAxis);
			}
		}
	}

	private bool BeginDrag(Camera camera, GizmoAxis axis)
	{
		//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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: 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_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: 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_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_036a: 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_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0385: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_039a: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		if (!HasGizmoTarget)
		{
			return false;
		}
		if (axis == GizmoAxis.Center && _mode != EditMode.Translate)
		{
			return false;
		}
		Vector3 gizmoPivot = GizmoPivot;
		_dragStartRootPosition = _targetGhost.transform.position;
		_dragStartPivot = gizmoPivot;
		_dragStartRotation = _targetGhost.transform.rotation;
		_dragUsesScreenSpace = false;
		_dragBoundsTranslationStep = 0f;
		_dragSnapPointTranslationStep = 0f;
		_dragStartMouse = Vector2.op_Implicit(Input.mousePosition);
		Ray val = camera.ScreenPointToRay(Input.mousePosition);
		if (axis == GizmoAxis.Center)
		{
			_dragPlane = new Plane(((Component)camera).transform.forward, gizmoPivot);
			float num = default(float);
			if (!((Plane)(ref _dragPlane)).Raycast(val, ref num))
			{
				return false;
			}
			_dragStartPlanePoint = ((Ray)(ref val)).GetPoint(num);
			_dragAxis = axis;
			_gizmo.ActiveAxis = axis;
			return true;
		}
		_dragWorldAxis = GetWorldAxis(axis);
		if (_mode == EditMode.Translate)
		{
			_dragBoundsTranslationStep = GetProjectedTargetSize(_dragWorldAxis);
			_dragSnapPointTranslationStep = GetProjectedSnapPointSpan(_dragWorldAxis);
			if (Mathf.Abs(Vector3.Dot(_dragWorldAxis, ((Component)camera).transform.forward)) > 0.96f)
			{
				float num2 = Mathf.Max(0.5f, camera.WorldToScreenPoint(gizmoPivot).z);
				float num3 = 2f * num2 * Mathf.Tan(camera.fieldOfView * ((float)Math.PI / 180f) * 0.5f);
				_dragUsesScreenSpace = true;
				_dragScreenDirection = Vector2.up * ((Vector3.Dot(_dragWorldAxis, ((Component)camera).transform.forward) >= 0f) ? 1f : (-1f));
				_dragScreenScale = num3 / Mathf.Max(1f, (float)Screen.height);
			}
			if (_dragUsesScreenSpace)
			{
				_dragAxis = axis;
				_gizmo.ActiveAxis = axis;
				return true;
			}
			Vector3 val2 = Vector3.Cross(_dragWorldAxis, Vector3.Cross(((Component)camera).transform.forward, _dragWorldAxis));
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				val2 = Vector3.Cross(_dragWorldAxis, ((Component)camera).transform.up);
			}
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			_dragPlane = new Plane(((Vector3)(ref val2)).normalized, gizmoPivot);
			float num4 = default(float);
			if (!((Plane)(ref _dragPlane)).Raycast(val, ref num4))
			{
				return false;
			}
			_dragStartAxisParameter = Vector3.Dot(((Ray)(ref val)).GetPoint(num4) - gizmoPivot, _dragWorldAxis);
		}
		else
		{
			if (Mathf.Abs(Vector3.Dot(_dragWorldAxis, ((Component)camera).transform.forward)) < 0.12f)
			{
				Vector3 val3 = camera.WorldToScreenPoint(gizmoPivot);
				Vector3 val4 = camera.WorldToScreenPoint(gizmoPivot + _dragWorldAxis) - val3;
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(val4.x, val4.y);
				_dragUsesScreenSpace = true;
				Vector2 dragScreenDirection;
				if (!(((Vector2)(ref val5)).sqrMagnitude > 0.001f))
				{
					dragScreenDirection = Vector2.right;
				}
				else
				{
					Vector2 val6 = new Vector2(0f - val5.y, val5.x);
					dragScreenDirection = ((Vector2)(ref val6)).normalized;
				}
				_dragScreenDirection = dragScreenDirection;
				_dragScreenScale = 0.35f;
			}
			if (_dragUsesScreenSpace)
			{
				_dragAxis = axis;
				_gizmo.ActiveAxis = axis;
				return true;
			}
			_dragPlane = new Plane(_dragWorldAxis, gizmoPivot);
			float num5 = default(float);
			if (!((Plane)(ref _dragPlane)).Raycast(val, ref num5))
			{
				return false;
			}
			Vector3 val7 = ((Ray)(ref val)).GetPoint(num5) - gizmoPivot;
			if (((Vector3)(ref val7)).sqrMagnitude < 0.0001f)
			{
				return false;
			}
			_dragStartVector = ((Vector3)(ref val7)).normalized;
		}
		_dragAxis = axis;
		_gizmo.ActiveAxis = axis;
		return true;
	}

	private void ContinueDrag(Camera camera)
	{
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: 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_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: 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_006d: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: 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_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: 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_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 references)
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		if (!HasGizmoTarget)
		{
			CancelDrag();
			return;
		}
		bool flag;
		Vector3 val3;
		if (_dragAxis == GizmoAxis.Center)
		{
			flag = ContinueCenterDrag(camera);
		}
		else if (_mode == EditMode.Translate)
		{
			float num;
			if (_dragUsesScreenSpace)
			{
				num = Vector2.Dot(Vector2.op_Implicit(Input.mousePosition) - _dragStartMouse, _dragScreenDirection) * _dragScreenScale;
			}
			else
			{
				Ray val = camera.ScreenPointToRay(Input.mousePosition);
				float num2 = default(float);
				if (!((Plane)(ref _dragPlane)).Raycast(val, ref num2))
				{
					return;
				}
				num = Vector3.Dot(((Ray)(ref val)).GetPoint(num2) - _dragStartPivot, _dragWorldAxis) - _dragStartAxisParameter;
			}
			float num3 = 0f;
			if (IsBoundsStepModifierHeld())
			{
				num3 = _dragBoundsTranslationStep;
			}
			else if (IsShiftHeld())
			{
				num3 = ((_dragSnapPointTranslationStep > 0.001f) ? _dragSnapPointTranslationStep : _dragBoundsTranslationStep);
			}
			if (num3 > 0.001f)
			{
				num = Mathf.Round(num / num3) * num3;
			}
			Vector3 val2 = _dragStartRootPosition + _dragWorldAxis * num;
			flag = false;
			if (IsFinite(val2))
			{
				val3 = _targetGhost.transform.position - val2;
				if (((Vector3)(ref val3)).sqrMagnitude > 1E-08f)
				{
					_targetGhost.transform.position = val2;
					_desiredPosition = val2;
					_surfaceSupportInvalid = false;
					flag = true;
				}
			}
		}
		else
		{
			float num4;
			if (_dragUsesScreenSpace)
			{
				num4 = Vector2.Dot(Vector2.op_Implicit(Input.mousePosition) - _dragStartMouse, _dragScreenDirection) * _dragScreenScale;
			}
			else
			{
				Ray val4 = camera.ScreenPointToRay(Input.mousePosition);
				float num5 = default(float);
				if (!((Plane)(ref _dragPlane)).Raycast(val4, ref num5))
				{
					return;
				}
				Vector3 val5 = ((Ray)(ref val4)).GetPoint(num5) - _dragStartPivot;
				if (((Vector3)(ref val5)).sqrMagnitude <= 0.0001f)
				{
					return;
				}
				num4 = Vector3.SignedAngle(_dragStartVector, ((Vector3)(ref val5)).normalized, _dragWorldAxis);
			}
			float num6 = (IsShiftHeld() ? 90f : GetRotationStep());
			if (num6 > 0f)
			{
				num4 = Mathf.Round(num4 / num6) * num6;
			}
			Quaternion val6 = Quaternion.AngleAxis(num4, _dragWorldAxis);
			Quaternion val7 = val6 * _dragStartRotation;
			Vector3 val8 = _dragStartPivot + val6 * (_dragStartRootPosition - _dragStartPivot);
			flag = false;
			if (IsFinite(val7) && IsFinite(val8))
			{
				if (!(Quaternion.Angle(_targetGhost.transform.rotation, val7) > 0.001f))
				{
					val3 = _targetGhost.transform.position - val8;
					if (!(((Vector3)(ref val3)).sqrMagnitude > 1E-08f))
					{
						goto IL_02fa;
					}
				}
				_targetGhost.transform.SetPositionAndRotation(val8, val7);
				_desiredPosition = val8;
				_desiredRotation = val7;
				if (!_hasTemporaryPivot)
				{
					_surfaceSupportInvalid = false;
				}
				flag = true;
			}
		}
		goto IL_02fa;
		IL_02fa:
		if (flag && _cameraRayFollowEnabled)
		{
			_cameraRayFollowUpdatePending = true;
		}
		if (flag && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			ValidateEditedGhost(Player.m_localPlayer, _targetPiece, flashGuardStone: false);
		}
	}

	private bool ContinueCenterDrag(Camera camera)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_005f: 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_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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if (_surfaceSnapEnabled)
		{
			return TryUpdateSurfaceSnap(camera.ScreenPointToRay(Input.mousePosition), _dragStartRotation);
		}
		Ray val = camera.ScreenPointToRay(Input.mousePosition);
		float num = default(float);
		if (!((Plane)(ref _dragPlane)).Raycast(val, ref num))
		{
			return false;
		}
		Vector3 val2 = ((Ray)(ref val)).GetPoint(num) - _dragStartPlanePoint;
		Vector3 val3 = _dragStartRootPosition + val2;
		if (IsFinite(val3))
		{
			Vector3 val4 = _targetGhost.transform.position - val3;
			if (!(((Vector3)(ref val4)).sqrMagnitude <= 1E-08f))
			{
				ClearTemporaryPivot();
				_targetGhost.transform.position = val3;
				_desiredPosition = val3;
				return true;
			}
		}
		return false;
	}

	private bool TryUpdateSurfaceSnap(Ray ray, Quaternion rotation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//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_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: 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_012f: 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_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: 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_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: 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_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || !TryGetSurfaceHit(localPlayer, ray, out var result))
		{
			return false;
		}
		Transform transform = _targetGhost.transform;
		Vector3 position = transform.position;
		Vector3 gizmoPivot = GizmoPivot;
		bool surfaceSupportInvalid = _surfaceSupportInvalid;
		Piece val = (((Object)(object)((RaycastHit)(ref result)).collider != (Object)null) ? ((Component)((RaycastHit)(ref result)).collider).GetComponentInParent<Piece>() : null);
		WearNTear val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<WearNTear>() : null);
		bool flag = (Object)(object)val2 != (Object)null && !val2.m_supports;
		Vector3 val3 = ((RaycastHit)(ref result)).point + ((RaycastHit)(ref result)).normal * 50f;
		transform.SetPositionAndRotation(val3, rotation);
		bool flag2 = false;
		float num = float.MaxValue;
		Vector3 val4 = ((RaycastHit)(ref result)).point;
		Collider[] targetColliders = _targetColliders;
		Vector3 val8;
		foreach (Collider val5 in targetColliders)
		{
			if ((Object)(object)val5 == (Object)null || !val5.enabled || !((Component)val5).gameObject.activeInHierarchy || val5.isTrigger)
			{
				continue;
			}
			MeshCollider val6 = (MeshCollider)(object)((val5 is MeshCollider) ? val5 : null);
			if (val6 == null || val6.convex)
			{
				Vector3 val7 = val5.ClosestPoint(((RaycastHit)(ref result)).point);
				val8 = val7 - ((RaycastHit)(ref result)).point;
				float sqrMagnitude = ((Vector3)(ref val8)).sqrMagnitude;
				if (IsFinite(val7) && sqrMagnitude < num)
				{
					flag2 = true;
					num = sqrMagnitude;
					val4 = val7;
				}
			}
		}
		Vector3 val9 = (flag2 ? (((RaycastHit)(ref result)).point + (val3 - val4)) : ((RaycastHit)(ref result)).point);
		if (!IsFinite(val9))
		{
			transform.SetPositionAndRotation(position, rotation);
			return false;
		}
		if (!IsPositionWithinEditorRange(localPlayer, val9))
		{
			transform.SetPositionAndRotation(position, rotation);
			return false;
		}
		transform.SetPositionAndRotation(val9, rotation);
		Vector3 val10 = ((RaycastHit)(ref result)).point;
		if (TryFindClosestBuildSnap(out var source, out var destination))
		{
			Vector3 val11 = destination.position - (source.position - val9);
			if (IsFinite(val11) && IsPositionWithinEditorRange(localPlayer, val11) && !IsOverlappingOtherPiece(val11, rotation))
			{
				val9 = (transform.position = val11);
				val10 = destination.position;
			}
		}
		_desiredPosition = val9;
		_desiredRotation = rotation;
		SetTemporaryPivot(val10);
		_surfaceSupportInvalid = flag;
		val8 = position - val9;
		if (!(((Vector3)(ref val8)).sqrMagnitude > 1E-08f))
		{
			val8 = gizmoPivot - val10;
			if (!(((Vector3)(ref val8)).sqrMagnitude > 1E-08f))
			{
				return surfaceSupportInvalid != flag;
			}
		}
		return true;
	}

	private bool TryGetSurfaceHit(Player player, Ray ray, out RaycastHit result)
	{
		//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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: 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)
		float num = (((Object)(object)_targetPiece != (Object)null) ? Mathf.Max(0f, (float)_targetPiece.m_extraPlacementDistance) : 0f);
		float num2 = Mathf.Clamp(Vector3.Distance(((Ray)(ref ray)).origin, ((Component)player).transform.position) + GetEditorRange() + num + 5f, 10f, 500f);
		int num3;
		while (true)
		{
			num3 = Physics.RaycastNonAlloc(ray, _surfaceRaycastBuffer, num2, PlaceRayMask.Invoke(player), (QueryTriggerInteraction)0);
			if (num3 < _surfaceRaycastBuffer.Length || _surfaceRaycastBuffer.Length >= 2048)
			{
				break;
			}
			Array.Resize(ref _surfaceRaycastBuffer, _surfaceRaycastBuffer.Length * 2);
		}
		bool result2 = false;
		float num4 = float.MaxValue;
		result = default(RaycastHit);
		for (int i = 0; i < num3; i++)
		{
			RaycastHit val = _surfaceRaycastBuffer[i];
			Collider collider = ((RaycastHit)(ref val)).collider;
			if (!((Object)(object)collider == (Object)null) && !((Object)(object)collider.attachedRigidbody != (Object)null) && !((Object)(object)((Component)collider).transform == (Object)(object)_targetGhost.transform) && !((Component)collider).transform.IsChildOf(_targetGhost.transform) && !(((RaycastHit)(ref val)).distance >= num4))
			{
				result = val;
				num4 = ((RaycastHit)(ref val)).distance;
				result2 = true;
			}
		}
		return result2;
	}

	private bool TryFindClosestBuildSnap(out Transform source, out Transform destination)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		_sourceSnapPoints.Clear();
		_destinationSnapPoints.Clear();
		_nearbyPieces.Clear();
		_nearbyPieceSet.Clear();
		_targetPiece.GetSnapPoints(_sourceSnapPoints);
		int num = FillSnapPieceBuffer(_targetGhost.transform.position);
		for (int i = 0; i < num; i++)
		{
			Collider val = _snapPieceBuffer[i];
			Piece val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Piece>() : null);
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)_targetPiece) && _nearbyPieceSet.Add(val2))
			{
				val2.GetSnapPoints(_destinationSnapPoints);
				_nearbyPieces.Add(val2);
			}
		}
		source = null;
		destination = null;
		float num2 = 0.25f;
		float num3 = float.MaxValue;
		foreach (Transform sourceSnapPoint in _sourceSnapPoints)
		{
			if ((Object)(object)sourceSnapPoint == (Object)null)
			{
				continue;
			}
			foreach (Transform destinationSnapPoint in _destinationSnapPoints)
			{
				if (!((Object)(object)destinationSnapPoint == (Object)null) && !((Object)(object)destinationSnapPoint == (Object)(object)sourceSnapPoint) && !destinationSnapPoint.IsChildOf(_targetGhost.transform))
				{
					Vector3 val3 = sourceSnapPoint.position - destinationSnapPoint.position;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude <= num2 && sqrMagnitude < num3)
					{
						num3 = sqrMagnitude;
						source = sourceSnapPoint;
						destination = destinationSnapPoint;
					}
				}
			}
		}
		if ((Object)(object)source != (Object)null)
		{
			return (Object)(object)destination != (Object)null;
		}
		return false;
	}

	private int FillSnapPieceBuffer(Vector3 center)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		int num;
		while (true)
		{
			num = Physics.OverlapSphereNonAlloc(center, 10f, _snapPieceBuffer, _pieceLayerMask, (QueryTriggerInteraction)0);
			if (num < _snapPieceBuffer.Length || _snapPieceBuffer.Length >= 16384)
			{
				break;
			}
			Array.Resize(ref _snapPieceBuffer, Mathf.Min(_snapPieceBuffer.Length * 2, 16384));
		}
		return num;
	}

	private bool IsOverlappingOtherPiece(Vector3 position, Quaternion rotation)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		foreach (Piece nearbyPiece in _nearbyPieces)
		{
			if (!((Object)(object)nearbyPiece == (Object)null) && !((Object)(object)nearbyPiece == (Object)(object)_targetPiece))
			{
				Vector3 val = position - ((Component)nearbyPiece).transform.position;
				if (!(((Vector3)(ref val)).sqrMagnitude >= 0.0025f) && Utils.CustomStartsWith(((Object)((Component)nearbyPiece).gameObject).name, ((Object)_targetGhost).name) && (!_targetPiece.m_allowRotatedOverlap || Quaternion.Angle(((Component)nearbyPiece).transform.rotation, rotation) <= 10f))
				{
					return true;
				}
			}
		}
		return false;
	}

	private void SetTemporaryPivot(Vector3 worldPosition)
	{
		//IL_0008: 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_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		if (!HasGizmoTarget || !IsFinite(worldPosition))
		{
			ClearTemporaryPivot();
			return;
		}
		Vector3 val = _targetGhost.transform.InverseTransformPoint(worldPosition);
		if (!IsFinite(val))
		{
			ClearTemporaryPivot();
			return;
		}
		_temporaryPivotLocal = val;
		_hasTemporaryPivot = true;
	}

	private void ClearTemporaryPivot(bool clearSurfaceSupport = true)
	{
		//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)
		_hasTemporaryPivot = false;
		if (clearSurfaceSupport)
		{
			_surfaceSupportInvalid = false;
		}
		_temporaryPivotLocal = Vector3.zero;
	}

	private static bool IsPositionWithinEditorRange(Player player, Vector3 position)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		float editorRange = GetEditorRange();
		if ((Object)(object)player != (Object)null)
		{
			Vector3 val = position - ((Component)player).transform.position;
			return ((Vector3)(ref val)).sqrMagnitude <= editorRange * editorRange;
		}
		return false;
	}

	private static float GetRotationStep()
	{
		float value = Plugin.RotationSnap.Value;
		if (float.IsNaN(value) || float.IsInfinity(value))
		{
			return 5f;
		}
		if (value <= 0f)
		{
			return 0f;
		}
		return Mathf.Clamp(value, 0.1f, 360f);
	}

	private static bool IsShiftHeld()
	{
		if (!Input.GetKey((KeyCode)304))
		{
			return Input.GetKey((KeyCode)303);
		}
		return true;
	}

	private static bool IsBoundsStepModifierHeld()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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)
		KeyCode value = Plugin.BoundsStepModifier.Value;
		if ((int)value != 0)
		{
			return Input.GetKey(value);
		}
		return false;
	}

	private void CancelDrag()
	{
		_dragAxis = GizmoAxis.None;
		_dragUsesScreenSpace = false;
		_dragBoundsTranslationStep = 0f;
		_dragSnapPointTranslationStep = 0f;
		if ((Object)(object)_gizmo != (Object)null)
		{
			_gizmo.ActiveAxis = GizmoAxis.None;
		}
	}

	internal void UpdatePlayerPlacement(Player player, float dt)
	{
		//IL_01fd: 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_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		_copiedPieceThisPlacementUpdate = false;
		_hasSampledPlacementRotation = false;
		_sampledCopySucceededThisPlacementUpdate = false;
		if (!_active || (Object)(object)player != (Object)(object)Player.m_localPlayer || _placementUpdateFailed || IsGameUiBlockingEditorInput() || Time.frameCount <= _uiInputBlockedThroughFrame || Time.frameCount <= _placementInputBlockedThroughFrame)
		{
			return;
		}
		HandlePlayerHotkeys(player);
		if (!((Character)player).InPlaceMode())
		{
			ExitEditor();
			return;
		}
		bool flag = IsVanillaCopyRequested();
		if (Input.GetMouseButton(1) || _rightMouseActive || _dragAxis != GizmoAxis.None || IsPointerOverToolbar() || (!flag && IsPointerOverGizmo()))
		{
			return;
		}
		if (UpdatePlacementInvoker == null)
		{
			_placementUpdateFailed = true;
			Plugin.LogError("Player.UpdatePlacement(bool,float) was not found");
			ExitEditor();
			return;
		}
		try
		{
			bool flag2 = HasGizmoTarget && !Hud.IsPieceSelectionVisible();
			PlacementRotationSnapshot snapshot = (flag2 ? CapturePlacementRotation(player) : default(PlacementRotationSnapshot));
			Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null);
			Quaternion rotation = default(Quaternion);
			bool flag3 = false;
			if ((Object)(object)val != (Object)null && ShouldRenderEditorOverlay && !Hud.IsPieceSelectionVisible())
			{
				Camera editorCamera = EditorCamera;
				if ((Object)(object)editorCamera != (Object)null)
				{
					Ray val2 = editorCamera.ScreenPointToRay(Input.mousePosition);
					if (IsFinite(((Ray)(ref val2)).direction))
					{
						Vector3 direction = ((Ray)(ref val2)).direction;
						if (((Vector3)(ref direction)).sqrMagnitude > 0.0001f)
						{
							rotation = val.rotation;
							val.rotation = Quaternion.LookRotation(((Ray)(ref val2)).direction, ((Component)editorCamera).transform.up);
							flag3 = true;
						}
					}
				}
			}
			_insidePlacementUpdate = true;
			try
			{
				UpdatePlacementInvoker(player, arg2: true, dt);
			}
			finally
			{
				_insidePlacementUpdate = false;
				if (_sampledCopySucceededThisPlacementUpdate && _hasSampledPlacementRotation)
				{
					FinalizeSampledPlacementState(player);
				}
				else if (flag2 && !_copiedPieceThisPlacementUpdate)
				{
					RestorePlacementRotation(player, snapshot);
				}
				_copiedPieceThisPlacementUpdate = false;
				_hasSampledPlacementRotation = false;
				_sampledCopySucceededThisPlacementUpdate = false;
				if (flag3 && (Object)(object)val != (Object)null)
				{
					val.rotation = rotation;
				}
			}
		}
		catch (Exception arg)
		{
			_placementUpdateFailed = true;
			Plugin.LogError($"Player.UpdatePlacement failed: {arg}");
			((Character)player).Message((MessageType)1, _language.PlacementError, 0, (Sprite)null);
			ExitEditor();
		}
	}

	private static void HandlePlayerHotkeys(Player player)
	{
		for (int i = 0; i < HotbarButtons.Length; i++)
		{
			if (Input.GetKeyDown(HotbarKeys[i]) || ZInput.GetButtonDown(HotbarButtons[i]))
			{
				player.UseHotbarItem(i + 1);
				break;
			}
		}
		if ((ZInput.GetButtonDown("Hide") || ZInput.GetButtonDown("JoyHide")) && !((Character)player).InAttack())
		{
			((Humanoid)player).HideHandItems(false, true);
		}
	}

	private static bool IsVanillaCopyRequested()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		bool num = (ZInput.GetButtonDown("Remove") || ZInput.GetButtonDown("JoyRemove")) && (ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltKeys")) && ((int)ZInput.InputLayout == 0 || !ZInput.IsGamepadActive());
		bool flag = ZInput.GetButton("JoyAltKeys") && (ZInput.GetButtonDown("Attack") || ZInput.GetButtonDown("JoyPlace")) && !Hud.InRadial();
		return num || flag;
	}

	internal bool ShouldBlockVanillaPlacement(Player player)
	{
		if (!_active || (Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			return false;
		}
		if (IsEditorBlockedInCurrentInterior(player))
		{
			((Character)player).Message((MessageType)2, "$msg_notindungeon", 0, (Sprite)null);
			return true;
		}
		if (IsCurrentGhostOutsideEditorRange(player))
		{
			((Character)player).Message((MessageType)2, "$msg_invalidplacement", 0, (Sprite)null);
			return true;