Decompiled source of Build Ease v0.3.10

BuildEase.dll

Decompiled an hour 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.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.10.0")]
[assembly: ComVisible(false)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.3.10.0")]
namespace Obelisk.UEPlacementEditor;

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 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 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>(16);

	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 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 _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 _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 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 || !_insidePlacementUpdate || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				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.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.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 (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 = 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 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);
			}
		}
		RefreshToolbarLabels();
	}

	private void ToggleCameraLight()
	{
		if ((Object)(object)_cameraLight != (Object)null)
		{
			DestroyCameraLight();
		}
		else
		{
			CreateCameraLight();
		}
		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)
			{
				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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: 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_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_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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_025f: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: 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_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: 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_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: 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_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_0346: Unknown result type (might be due to invalid IL or missing references)
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0360: Unknown result type (might be due to invalid IL or missing references)
		//IL_0365: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: 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_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		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;
		_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)
		{
			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_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: 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_0138: 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_0074: 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_0170: 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_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_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: 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_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: 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_0252: 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_0259: 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;
			}
			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 num3;
			if (_dragUsesScreenSpace)
			{
				num3 = Vector2.Dot(Vector2.op_Implicit(Input.mousePosition) - _dragStartMouse, _dragScreenDirection) * _dragScreenScale;
			}
			else
			{
				Ray val4 = camera.ScreenPointToRay(Input.mousePosition);
				float num4 = default(float);
				if (!((Plane)(ref _dragPlane)).Raycast(val4, ref num4))
				{
					return;
				}
				Vector3 val5 = ((Ray)(ref val4)).GetPoint(num4) - _dragStartPivot;
				if (((Vector3)(ref val5)).sqrMagnitude <= 0.0001f)
				{
					return;
				}
				num3 = Vector3.SignedAngle(_dragStartVector, ((Vector3)(ref val5)).normalized, _dragWorldAxis);
			}
			float rotationStep = GetRotationStep();
			if (rotationStep > 0f)
			{
				num3 = Mathf.Round(num3 / rotationStep) * rotationStep;
			}
			Quaternion val6 = Quaternion.AngleAxis(num3, _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_029e;
					}
				}
				_targetGhost.transform.SetPositionAndRotation(val8, val7);
				_desiredPosition = val8;
				_desiredRotation = val7;
				if (!_hasTemporaryPivot)
				{
					_surfaceSupportInvalid = false;
				}
				flag = true;
			}
		}
		goto IL_029e;
		IL_029e:
		if (flag && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			ValidateEditedGhost(Player.m_localPlayer, _targetPiece, flashGuardStone: false);
		}
	}

	private bool ContinueCenterDrag(Camera camera)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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_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_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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0099: Unknown result type (might be due to invalid IL or missing references)
		if (_surfaceSnapEnabled)
		{
			return TryUpdateSurfaceSnap(camera);
		}
		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(Camera camera)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: 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_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: 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_01c2: 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_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_01e2: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: 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_01f7: 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_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: 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_0176: 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_0227: 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_0232: 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_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: 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, camera.ScreenPointToRay(Input.mousePosition), camera, out var result))
		{
			return false;
		}
		Transform transform = _targetGhost.transform;
		Vector3 position = transform.position;
		Vector3 gizmoPivot = GizmoPivot;
		bool surfaceSupportInvalid = _surfaceSupportInvalid;
		Quaternion dragStartRotation = _dragStartRotation;
		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, dragStartRotation);
		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, dragStartRotation);
			return false;
		}
		if (!IsPositionWithinEditorRange(localPlayer, val9))
		{
			transform.SetPositionAndRotation(position, dragStartRotation);
			return false;
		}
		transform.SetPositionAndRotation(val9, dragStartRotation);
		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, dragStartRotation))
			{
				val9 = (transform.position = val11);
				val10 = destination.position;
			}
		}
		_desiredPosition = val9;
		_desiredRotation = dragStartRotation;
		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, Camera camera, out RaycastHit result)
	{
		//IL_0032: 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_0065: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		float num = (((Object)(object)_targetPiece != (Object)null) ? Mathf.Max(0f, (float)_targetPiece.m_extraPlacementDistance) : 0f);
		float num2 = Mathf.Clamp(Vector3.Distance(((Component)camera).transform.position, ((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 void CancelDrag()
	{
		_dragAxis = GizmoAxis.None;
		_dragUsesScreenSpace = false;
		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 (IsCurrentGhostOutsideEditorRange(player))
		{
			((Character)player).Message((MessageType)2, "$msg_invalidplacement", 0, (Sprite)null);
			return true;
		}
		if (IsCameraCaptured || _dragAxis != GizmoAxis.None || IsPointerOverToolbar() || IsPointerOverGizmo())
		{
			return true;
		}
		return false;
	}

	internal void OnVanillaPlacementSucceeded(Player player)
	{
		//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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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)
		if (_active && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && HasGizmoTarget)
		{
			Transform transform = _targetGhost.transform;
			Vector3 position = transform.position;
			Quaternion rotation = transform.rotation;
			if (!IsFinite(position) || !IsFinite(rotation))
			{
				ClearPlacementGhostTarget();
				return;
			}
			_desiredPosition = position;
			_desiredRotation = rotation;
			CancelDrag();
			_hasCachedPlacementStatus = false;
			ValidateEditedGhost(player, _targetPiece, flashGuardStone: false);
		}
	}

	internal bool TryCaptureSampledPiecePose(Player player, Piece source, out Vector3 position, out Quaternion rotation)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0064: 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)
		position = Vector3.zero;
		rotation = Quaternion.identity;
		if (!_active || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || (Object)(object)source == (Object)null)
		{
			return false;
		}
		position = ((Component)source).transform.position;
		rotation = ((Component)source).transform.rotation;
		if (IsFinite(position))
		{
			return IsFinite(rotation);
		}
		return false;
	}

	internal void OnVanillaPieceSampled(Player player, Vector3 position, Quaternion rotation)
	{
		//IL_001e: 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_003e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: 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_00ac: 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)
		if (!_active || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !IsFinite(position) || !IsFinite(rotation))
		{
			return;
		}
		_copiedPieceThisPlacementUpdate = true;
		_hasSampledPlacementRotation = true;
		_sampledPlacementRotation = rotation;
		ClearPlacementGhostTarget();
		GameObject placementGhost = GetPlacementGhost(player);
		Piece selectedPiece = player.GetSelectedPiece();
		if (!((Object)(object)placementGhost == (Object)null) && !((Object)(object)selectedPiece == (Object)null) && IsSelectedPieceGizmoCompatible(selectedPiece))
		{
			SetPlacementGhostTarget(placementGhost, selectedPiece);
			if (HasGizmoTarget)
			{
				_desiredPosition = position;
				_desiredRotation = rotation;
				_surfaceSupportInvalid = false;
				_hasCachedPlacementStatus = false;
				_targetGhost.transform.SetPositionAndRotation(position, rotation);
			}
		}
	}

	internal void OnVanillaCopyCompleted(Player player, bool succeeded)
	{
		if (succeeded && _hasSampledPlacementRotation && _active && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
		{
			_sampledPlaceRotation = PlaceRotation.Invoke(player);
			_sampledCopySucceededThisPlacementUpdate = true;
			if (!_insidePlacementUpdate)
			{
				FinalizeSampledPlacementState(player);
				_copiedPieceThisPlacementUpdate = false;
				_hasSampledPlacementRotation = false;
				_sampledCopySucceededThisPlacementUpdate = false;
			}
		}
	}

	private void FinalizeSampledPlacementState(Player player)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		PlaceRotation.Invoke(player) = _sampledPlaceRotation;
		ScrollCurrentAmount.Invoke(player) = 0f;
		RotatePieceTimer.Invoke(player) = 0f;
		SynchronizePerfectPlacementRotation(player, _sampledPlacementRotation);
	}

	private void RefreshPlacementGhostReference(Player player)
	{
		GameObject placementGhost = GetPlacementGhost(player);
		Piece selectedPiece = player.GetSelectedPiece();
		if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)selectedPiece != (Object)(object)_targetSelectedPiece)
		{
			ClearPlacementGhostTarget();
		}
		else if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)placementGhost != (Object)null && (Object)(object)placementGhost != (Object)(object)_targetGhost && !TryRetargetPlacementGhost(placementGhost, selectedPiece))
		{
			ClearPlacementGhostTarget();
		}
		else if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)placementGhost == (Object)null && (Object)(object)_targetGhost == (Object)null && _targetGhost != null)
		{
			DetachDestroyedPlacementGhost();
		}
		if ((Object)(object)_targetSelectedPiece == (Object)null && (Object)(object)placementGhost == (Object)null)
		{
			SetTargetStatus(TargetStatusKind.NoGhost);
		}
	}

	internal void ApplyGhostOverride(Player player, bool flashGuardStone)
	{
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Invalid comparison between Unknown and I4
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: 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_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		if (!_active || (Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		GameObject placementGhost = GetPlacementGhost(player);
		if (_blueGhostPreviewEnabled)
		{
			_placementGhostVisual.Sync(placementGhost);
		}
		Piece selectedPiece = player.GetSelectedPiece();
		if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)_targetSelectedPiece != (Object)(object)selectedPiece)
		{
			ClearPlacementGhostTarget();
		}
		else if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)placementGhost != (Object)(object)_targetGhost)
		{
			if ((Object)(object)placementGhost == (Object)null)
			{
				return;
			}
			if (!TryRetargetPlacementGhost(placementGhost, selectedPiece))
			{
				ClearPlacementGhostTarget();
			}
		}
		else if ((Object)(object)_targetSelectedPiece != (Object)null && (Object)(object)_targetGhost == (Object)null && _targetGhost != null)
		{
			DetachDestroyedPlacementGhost();
		}
		bool flag = IsSelectedPieceGizmoCompatible(selectedPiece);
		if ((Object)(object)_targetSelectedPiece == (Object)null && (Object)(object)placementGhost != (Object)null && flag && (int)player.GetPlacementStatus() != 12)
		{
			SetPlacementGhostTarget(placementGhost, selectedPiece);
		}
		if (!HasGizmoTarget || (Object)(object)placementGhost != (Object)(object)_targetGhost)
		{
			if ((Object)(object)placementGhost != (Object)null && (Object)(object)selectedPiece != (Object)null && !flag)
			{
				SetTargetStatus(TargetStatusKind.SpecialPiece);
			}
			return;
		}
		Transform transform = _targetGhost.transform;
		Vector3 val = transform.position - _desiredPosition;
		if (((Vector3)(ref val)).sqrMagnitude > 1E-08f || Quaternion.Angle(transform.rotation, _desiredRotation) > 0.001f)
		{
			transform.SetPositionAndRotation(_desiredPosition, _desiredRotation);
		}
		if (!_targetGhost.activeSelf)
		{
			_targetGhost.SetActive(true);
		}
		GameObject val2 = PlacementMarker.Invoke(player);
		if ((Object)(object)val2 != (Object)null && val2.activeSelf)
		{
			val2.SetActive(false);
		}
		if (!_hasCachedPlacementStatus || flashGuardStone)
		{
			ValidateEditedGhost(player, _targetPiece, flashGuardStone);
		}
		else
		{
			RestoreCachedPlacementStatus(player, _targetPiece);
		}
	}

	internal bool ShouldSkipVanillaGhostUpdate(Player player)
	{
		if (_active && (Object)(object)player == (Object)(object)Player.m_localPlayer && HasGizmoTarget && (Object)(object)GetPlacementGhost(player) == (Object)(object)_targetGhost)
		{
			return (Object)(object)player.GetSelectedPiece() == (Object)(object)_targetSelectedPiece;
		}
		return false;
	}

	internal bool TryGetFinalPlacementPose(Player player, Piece selectedPiece, out Vector3 position, out Quaternion rotation)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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)
		position = Vector3.zero;
		rotation = Quaternion.identity;
		if (!_active || (Object)(object)player != (Object)(object)Player.m_localPlayer || !HasGizmoTarget || (Object)(object)selectedPiece == (Object)null || (Object)(object)selectedPiece != (Object)(object)_targetSelectedPiece || (Object)(object)GetPlacementGhost(player) != (Object)(object)_targetGhost || !IsFinite(_desiredPosition) || !IsFinite(_desiredRotation))
		{
			return false;
		}
		position = _desiredPosition;
		rotation = _desiredRotation;
		return true;
	}

	internal void EnforceEditorRange(Player player)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		if (_active && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && IsCurrentGhostOutsideEditorRange(player))
		{
			PlacementStatus.Invoke(player) = (PlacementStatus)1;
			GameObject placementGhost = GetPlacementGhost(player);
			Piece val = (((Object)(object)placementGhost != (Object)null) ? placementGhost.GetComponent<Piece>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.SetInvalidPlacementHeightlight(true);
			}
			if ((Object)(object)placementGhost == (Object)(object)_targetGhost)
			{
				_cachedPlacementStatus = (PlacementStatus)1;
				_hasCachedPlacementStatus = true;
			}
		}
	}

	private void SetPlacementGhostTarget(GameObject ghost, Piece selectedPiece)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		ClearTemporaryPivot();
		_targetGhost = ghost;
		_targetPiece = ghost.GetComponent<Piece>();
		_targetSelectedPiece = selectedPiece;
		if ((Object)(object)_targetPiece == (Object)null)
		{
			ClearPlacementGhostTarget();
			return;
		}
		_desiredPosition = ghost.transform.position;
		_desiredRotation = ghost.transform.rotation;
		_targetColliders = ghost.GetComponentsInChildren<Collider>(true);
		SetTargetStatus(TargetStatusKind.Piece, GetPieceStatusToken(_targetPiece, ghost));
		CancelDrag();
	}

	private bool TryRetargetPlacementGhost(GameObject ghost, Piece selectedPiece)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ghost == (Object)null || (Object)(object)_targetSelectedPiece == (Object)null || (Object)(object)selectedPiece != (Object)(object)_targetSelectedPiece || !IsFinite(_desiredPosition) || !IsFinite(_desiredRotation))
		{
			return false;
		}
		Piece component = ghost.GetComponent<Piece>();
		if ((Object)(object)component == (Object)null || !IsSelectedPieceGizmoCompatible(selectedPiece))
		{
			return false;
		}
		_targetGhost = ghost;
		_targetPiece = component;
		_targetColliders = ghost.GetComponentsInChildren<Collider>(true);
		ghost.transform.SetPositionAndRotation(_desiredPosition, _desiredRotation);
		_hasCachedPlacementStatus = false;
		SetTargetStatus(TargetStatusKind.Piece, GetPieceStatusToken(_targetPiece, ghost));
		CancelDrag();
		return true;
	}

	private void ReleasePlacementGhost()
	{
		ClearPlacementGhostTarget();
	}

	private void DetachDestroyedPlacementGhost()
	{
		_targetGhost = null;
		_targetPiece = null;
		_targetColliders = Array.Empty<Collider>();
		_hasCachedPlacementStatus = false;
		CancelDrag();
		if ((Object)(object)_gizmo != (Object)null)
		{
			_gizmo.HoveredAxis = GizmoAxis.None;
		}
	}

	private void ClearPlacementGhostTarget()
	{
		ClearTemporaryPivot();
		_targetGhost = null;
		_targetPiece = null;
		_targetSelectedPiece = null;
		_hasCachedPlacementStatus = false;
		_targetColliders = Array.Empty<Collider>();
		SetTargetStatus(TargetStatusKind.NoGhost);
		CancelDrag();
		if ((Object)(object)_gizmo != (Object)null)
		{
			_gizmo.HoveredAxis = GizmoAxis.None;
		}
	}

	private void SetTargetStatus(TargetStatusKind kind, string pieceToken = null)
	{
		if (_targetStatusKind != kind || !string.Equals(_targetStatusPieceToken, pieceToken, StringComparison.Ordinal))
		{
			_targetStatusKind = kind;
			_targetStatusPieceToken = pieceToken;
			RefreshTargetStatusText();
		}
	}

	private void RefreshTargetStatusText()
	{
		string text;
		switch (_targetStatusKind)
		{
		case TargetStatusKind.SpecialPiece:
			text = _language.SpecialPiece;
			break;
		case TargetStatusKind.Piece:
		{
			string text2 = _targetStatusPieceToken ?? string.Empty;
			if (text2.IndexOf('$') >= 0)
			{
				string text3 = Localization.instance.Localize(text2);
				if (!string.IsNullOrEmpty(text3))
				{
					text2 = text3;
				}
			}
			text = _language.PiecePrefix + text2;
			break;
		}
		default:
			text = _language.NoGhost;
			break;
		}
		_targetStatusText = text + _language.ToolbarHelp;
	}

	private static string GetPieceStatusToken(Piece piece, GameObject ghost)
	{
		if ((Object)(object)piece != (Object)null && !string.IsNullOrEmpty(piece.m_name))
		{
			return piece.m_name;
		}
		if (!((Object)(object)ghost != (Object)null))
		{
			return string.Empty;
		}
		return ((Object)ghost).name.Replace("(Clone)", string.Empty);
	}

	private void ValidateEditedGhost(Player player, Piece piece, bool flashGuardStone)
	{
		//IL_0010: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//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_003e: 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_0077: 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_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0098: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: 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_00fd: 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_0116: Expected I4, but got Unknown
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Invalid comparison between Unknown and I4
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)piece == (Object)null))
		{
			Vector3 position = ((Component)piece).transform.position;
			PlacementStatus val = (PlacementStatus)0;
			float editorRange = GetEditorRange();
			Vector3 val2 = position - ((Component)player).transform.position;
			if (((Vector3)(ref val2)).sqrMagnitude > editorRange * editorRange)
			{
				val = (PlacementStatus)1;
			}
			if (_surfaceSupportInvalid)
			{
				val = (PlacementStatus)1;
			}
			if (!piece.m_allowedInDungeons && ((Character)player).InInterior() && !EnvMan.instance.CheckInteriorBuildingOverride() && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)29))
			{
				val = (PlacementStatus)11;
			}
			if ((int)piece.m_onlyInBiome != 0 && (Heightmap.FindBiome(position) & piece.m_onlyInBiome) == 0)
			{
				val = (PlacementStatus)8;
			}
			if (Location.IsInsideNoBuildLocation(position))
			{
				val = (PlacementStatus)3;
			}
			PrivateArea component = ((Component)piece).GetComponent<PrivateArea>();
			float num = (((Object)(object)component != (Object)null) ? component.m_radius : 0f);
			if (!PrivateArea.CheckAccess(position, num, flashGuardStone, (Object)(object)component != (Object)null))
			{
				val = (PlacementStatus)4;
			}
			if (CheckEditedGhostVsCharacters(((Component)piece).gameObject, position))
			{
				val = (PlacementStatus)2;
			}
			if (piece.m_noClipping && TestEditedGhostClipping(player, ((Component)piece).gameObject, 0.2f))
			{
				val = (PlacementStatus)1;
			}
			_cachedPlacementStatus = val;
			_hasCachedPlacementStatus = true;
			PlacementStatus.Invoke(player) = (PlacementStatus)(int)val;
			piece.SetInvalidPlacementHeightlight((int)val > 0);
		}
	}

	private void RestoreCachedPlacementStatus(Player player, Piece piece)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected I4, but got Unknown
		//IL_0019: Invalid comparison between Unknown and I4
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Invalid comparison between Unknown and I4
		PlacementStatus placementStatus = player.GetPlacementStatus();
		PlacementStatus.Invoke(player) = (PlacementStatus)(int)_cachedPlacementStatus;
		bool num = (int)placementStatus > 0;
		bool flag = (int)_cachedPlacementStatus > 0;
		if (num != flag)
		{
			piece.SetInvalidPlacementHeightlight(flag);
		}
	}

	private bool CheckEditedGhostVsCharacters(GameObject ghost, Vector3 position)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		_nearbyCharacters.Clear();
		Character.GetCharactersInRange(position, 30f, _nearbyCharacters);
		Collider[] targetColliders = _targetColliders;
		Vector3 val4 = default(Vector3);
		float num = default(float);
		foreach (Collider val in targetColliders)
		{
			if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy || val.isTrigger || (Object)(object)((Component)val).gameObject == (Object)(object)ghost)
			{
				continue;
			}
			MeshCollider val2 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
			if (val2 != null && !val2.convex)
			{
				continue;
			}
			foreach (Character nearbyCharacter in _nearbyCharacters)
			{
				CapsuleCollider val3 = (((Object)(object)nearbyCharacter != (Object)null) ? nearbyCharacter.GetCollider() : null);
				if (!((Object)(object)val3 == (Object)null) && ((Collider)val3).enabled && ((Component)val3).gameObject.activeInHierarchy && Physics.ComputePenetration(val, ((Component)val).transform.position, ((Component)val).transform.rotation, (Collider)(object)val3, ((Component)val3).transform.position, ((Component)val3).transform.rotation, ref val4, ref num))
				{
					return true;
				}
			}
		}
		return false;
	}

	private bool TestEditedGhostClipping(Player player, GameObject ghost, float maxPenetration)
	{
		//IL_0006: 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_015e: 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_0178: 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)
		int num;
		while (true)
		{
			num = Physics.OverlapSphereNonAlloc(ghost.transform.position, 10f, _clippingBuffer, PlaceRayMask.Invoke(player), (QueryTriggerInteraction)0);
			if (num < _clippingBuffer.Length || _clippingBuffer.Length >= 32768)
			{
				break;
			}
			Array.Resize(ref _clippingBuffer, Mathf.Min(_clippingBuffer.Length * 2, 32768));
		}
		Collider[] array = _clippingBuffer;
		if (num == _clippingBuffer.Length)
		{
			array = Physics.OverlapSphere(ghost.transform.position, 10f, PlaceRayMask.Invoke(player), (QueryTriggerInteraction)0);
			num = array.Length;
			int newSize = num + Mathf.Max(256, num / 2);
			Array.Resize(ref array, newSize);
			_clippingBuffer = array;
		}
		Collider[] targetColliders = _targetColliders;
		Vector3 val3 = default(Vector3);
		float num2 = default(float);
		foreach (Collider val in targetColliders)
		{
			if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy)
			{
				continue;
			}
			for (int j = 0; j < num; j++)
			{
				Collider val2 = array[j];
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && ((Component)val2).gameObject.activeInHierarchy && !((Object)(object)((Component)val2).transform == (Object)(object)ghost.transform) && !((Component)val2).transform.IsChildOf(ghost.transform) && Physics.ComputePenetration(val, ((Component)val).transform.position, ((Component)val).transform.rotation, val2, ((Component)val2).transform.position, ((Component)val2).transform.rotation, ref val3, ref num2) && num2 > maxPenetration)
				{
					return true;
				}
			}
		}
		return false;
	}

	internal static bool IsGizmoCompatiblePiece(Piece piece)
	{
		if ((Object)(object)piece != (Object)null && !piece.m_groundPiece && !piece.m_groundOnly && !piece.m_cultivatedGroundOnly && !piece.m_vegetationGroundOnly && !piece.m_waterPiece && !piece.m_onlyInTeleportArea && (!(piece.m_blockRadius > 0f) || piece.m_blockingPieces == null || piece.m_blockingPieces.Count <= 0) && (Object)(object)piece.m_mustConnectTo == (Object)null && !piece.m_repairPiece && !piece.m_removePiece && !piece.m_isUpgrade && !piece.m_harvest && (Object)(object)((Component)piece).GetComponentInChildren<StationExtension>(true) == (Object)null && (Object)(object)((Component)piece).GetComponentInChildren<TerrainModifier>(true) == (Object)null)
		{
			return (Object)(object)((Component)piece).GetComponentInChildren<TerrainOp>(true) == (Object)null;
		}
		return false;
	}

	private bool IsSelectedPieceGizmoCompatible(Piece piece)
	{
		if ((Object)(object)_observedSelectedPiece != (Object)(object)piece)
		{
			_observedSelectedPiece = piece;
			_observedSelectedPieceCompatible = IsGizmoCompatiblePiece(piece);
		}
		return _observedSelectedPieceCompatible;
	}

	private void BeginEditorEntry()
	{
		Player localPlayer = Player.m_localPlayer;
		RefreshEditorLanguage();
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)GameCamera.instance == (Object)null || (Object)(object)ResolveGameCamera() == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting() || IsGameUiBlockingEditorInput())
		{
			return;
		}
		if (IsConflictingEditorActive())
		{
			((Character)localPlayer).Message((MessageType)1, _language.DisableConflictingEditor, 0, (Sprite)null);
			return;
		}
		if (IsBuildingHammer(((Humanoid)localPlayer).RightItem) && ((Character)localPlayer).InPlaceMode())
		{
			EnterEditor();
			return;
		}
		Inventory inventory = ((Humanoid)localPlayer).GetInventory();
		ItemData val = FindBuildingHammer(inventory);
		if (val == null)
		{
			((Character)localPlayer).Message((MessageType)1, _language.NoBuildingHammer, 0, (Sprite)null);
			return;
		}
		_editorEntryPending = true;
		_pendingEquipIssued = false;
		_pendingOwnEquipAction = false;
		_pendingEntryPlayer = localPlayer;
		_pendingEntryInventory = inventory;
		_pendingEntryHammer = val;
		_pendingEntryDeadline = Time.unscaledTime + 8f;
		UpdatePendingEditorEntry();
	}

	private void UpdatePendingEditorEntry()
	{
		if (!_editorEntryPending)
		{
			return;
		}
		Player pendingEntryPlayer = _pendingEntryPlayer;
		Inventory pendingEntryInventory = _pendingEntryInventory;
		ItemData pendingEntryHammer = _pendingEntryHammer;
		if ((Object)(object)pendingEntryPlayer == (Object)null || Player.m_localPlayer != pendingEntryPlayer || ((Character)pendingEntryPlayer).IsDead() || ((Character)pendingEntryPlayer).InCutscene() || ((Character)pendingEntryPlayer).IsTeleporting() || IsGameUiBlockingEditorInput())
		{
			CancelPendingEditorEntry(removeOwnedEquipAction: true);
		}
		else if (IsConflictingEditorActive())
		{
			CancelPendingEditorEntry(removeOwnedEquipAction: true);
			((Character)pendingEntryPlayer).Message((MessageType)1, _language.DisableConflictingEditor, 0, (Sprite)null);
		}
		else if (pendingEntryInventory == null || pendingEntryHammer == null || !pendingEntryInventory.ContainsItem(pendingEntryHammer) || !IsBuildingHammer(pendingEntryHammer))
		{
			FailPendingEditorEntry(pendingEntryPlayer);
		}
		else if (IsHammerEquippedForBuilding(pendingEntryPlayer, pendingEntryHammer))
		{
			CompletePendingEditorEntry(pendingEntryPlayer);
		}
		else if (Time.unscaledTime >= _pendingEntryDeadline)
		{
			FailPendingEditorEntry(pendingEntryPlayer);
		}
		else if (!_pendingEquipIssued)
		{
			if (!((Character)pendingEntryPlayer).InAttack() && !((Character)pendingEntryPlayer).InDodge() && (!((Character)pendingEntryPlayer).IsSwimming() || ((Character)pendingEntryPlayer).IsOnGround()))
			{
				bool num = pendingEntryPlayer.IsEquipActionQueued(pendingEntryHammer);
				_pendingEquipIssued = true;
				if (!num)
				{
					((Humanoid)pendingEntryPlayer).UseItem(pendingEntryInventory, pendingEntryHammer, true);
					_pendingOwnEquipAction = pendingEntryPlayer.IsEquipActionQueued(pendingEntryHammer);
				}
				if (IsHammerEquippedForBuilding(pendingEntryPlayer, pendingEntryHammer))
				{
					CompletePendingEditorEntry(pendingEntryPlayer);
				}
				else if (!pendingEntryPlayer.IsEquipActionQueued(pendingEntryHammer))
				{
					FailPendingEditorEntry(pendingEntryPlayer);
				}
			}
		}
		else if (!pendingEntryPlayer.IsEquipActionQueued(pendingEntryHammer))
		{
			FailPendingEditorEntry(pendingEntryPlayer);
		}
	}

	private void CompletePendingEditorEntry(Player player)
	{
		CancelPendingEditorEntry(removeOwnedEquipAction: false);
		if (Player.m_localPlayer == player && IsBuildingHammer(((Humanoid)player).RightItem) && ((Character)player).InPlaceMode())
		{
			EnterEditor();
		}
	}

	private void FailPendingEditorEntry(Player player)
	{
		CancelPendingEditorEntry(removeOwnedEquipAction: true);
		if (player != null)
		{
			((Character)player).Message((MessageType)1, _language.HammerEquipFailed, 0, (Sprite)null);
		}
	}

	private void CancelPendingEditorEntry(bool removeOwnedEquipActi