Decompiled source of MoveBuildPieces v1.0.1

MoveBuildPieces.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Obelisk.MoveBuildPieces;

[BepInPlugin("obelisk.valheim.movebuildpieces", "MoveBuildPieces", "1.0.1")]
public sealed class MoveBuildPiecesPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "obelisk.valheim.movebuildpieces";

	public const string PluginName = "MoveBuildPieces";

	public const string PluginVersion = "1.0.1";

	private static ConfigEntry<bool> _enabled;

	private static ConfigEntry<KeyboardShortcut> _moveHotkey;

	private static ConfigEntry<bool> _blockTerrainModifiers;

	private static ConfigEntry<bool> _blockDynamicObjects;

	private Harmony _harmony;

	internal static bool IsEnabled => _enabled.Value;

	internal static KeyboardShortcut MoveHotkey => _moveHotkey.Value;

	internal static bool BlockTerrainModifiers => _blockTerrainModifiers.Value;

	internal static bool BlockDynamicObjects => _blockDynamicObjects.Value;

	private void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Expected O, but got Unknown
		_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable moving already built pieces while in build mode.");
		_moveHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Move hotkey", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Press while hovering a buildable player-built piece in build mode to start or cancel moving it.");
		_blockTerrainModifiers = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "Block terrain modifiers", true, "Do not move pieces that contain TerrainModifier or TerrainOp components.");
		_blockDynamicObjects = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "Block dynamic objects", true, "Do not move ships, carts, characters, or pieces with non-kinematic rigidbodies.");
		MoveController.Initialize();
		_harmony = new Harmony("obelisk.valheim.movebuildpieces");
		_harmony.PatchAll();
	}

	private void OnDestroy()
	{
		MoveController.Reset();
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}
[HarmonyPatch(typeof(Player), "Update")]
internal static class PlayerUpdatePatch
{
	private static void Postfix(Player __instance)
	{
		MoveController.Update(__instance);
	}
}
[HarmonyPatch(typeof(Player), "LateUpdate")]
internal static class PlayerLateUpdatePatch
{
	private static void Postfix(Player __instance)
	{
		MoveController.UpdateVisuals(__instance);
	}
}
[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
{
	typeof(Piece),
	typeof(RequirementMode)
})]
internal static class PlayerHaveRequirementsPatch
{
	private static bool Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		if (MoveController.ShouldBypassRequirements(__instance, piece, mode))
		{
			__result = true;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Player), "TryPlacePiece")]
internal static class PlayerTryPlacePiecePatch
{
	private static bool Prefix(Player __instance, Piece piece, ref bool __result)
	{
		if (!MoveController.IsMovingWith(__instance, piece))
		{
			return true;
		}
		__result = false;
		MoveController.TryFinishMove(__instance);
		return false;
	}
}
internal static class MoveController
{
	private sealed class MoveState
	{
		public Player Player;

		public Piece Piece;

		public ZNetView NetView;

		public string PrefabName;

		public Vector3 OriginalPosition;

		public Quaternion OriginalRotation;

		public List<EffectArea> OriginalBaseAreas;

		public GameObject HighlightedGhost;

		public bool GhostHighlighted;
	}

	private sealed class MoveSelectionOverride
	{
		public Player Player;

		public string PrefabName;
	}

	private static class SupportCollidersBuffer
	{
		public static readonly Collider[] Items = (Collider[])(object)new Collider[128];
	}

	private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

	private static readonly FieldInfo PlacementStatusField = AccessTools.Field(typeof(Player), "m_placementStatus");

	private static readonly MethodInfo SetupPlacementGhostMethod = AccessTools.Method(typeof(Player), "SetupPlacementGhost", (Type[])null, (Type[])null);

	private static readonly MethodInfo UpdateAvailablePiecesListMethod = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null);

	private static readonly MethodInfo ClearCachedSupportMethod = AccessTools.Method(typeof(WearNTear), "RPC_ClearCachedSupport", (Type[])null, (Type[])null);

	private static readonly Color GhostColor = new Color(0.22f, 0.66f, 1f, 0.75f);

	private static readonly Color GhostEmissionColor = new Color(0.05f, 0.42f, 0.9f, 0.9f);

	private static readonly Color LinkColor = new Color(1f, 0.9f, 0.2f, 0.92f);

	private static readonly Color RingColor = new Color(1f, 0.95f, 0.35f, 0.9f);

	private const int RingSegments = 28;

	private const float LinkWidth = 0.075f;

	private const float DashLength = 0.35f;

	private const float MinRingRadius = 0.6f;

	private const float MaxRingRadius = 8f;

	private const float RingPadding = 0.25f;

	private const float TopLinkPadding = 0.15f;

	private const float DefaultLinkHeight = 1.25f;

	private const float MinUsefulBoundsSize = 0.05f;

	private static readonly List<Collider> SupportColliders = new List<Collider>();

	private static readonly HashSet<WearNTear> SupportPieces = new HashSet<WearNTear>();

	private static readonly RaycastHit[] FloorHits = (RaycastHit[])(object)new RaycastHit[16];

	private static MoveState _state;

	private static MoveSelectionOverride _selectionOverride;

	private static GameObject _lineObject;

	private static LineRenderer _dashLine;

	private static LineRenderer _originRing;

	private static LineRenderer _ghostRing;

	private static Texture2D _dashTexture;

	private static int _floorMask;

	public static void Initialize()
	{
		Reset();
	}

	public static void Reset()
	{
		_state = null;
		DestroyLine();
	}

	public static void Update(Player player)
	{
		//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)
		if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		if (ShouldCancelForUiOrState(player))
		{
			Cancel(player, showMessage: false);
			return;
		}
		if (!IsUiBlockingInput())
		{
			KeyboardShortcut moveHotkey = MoveBuildPiecesPlugin.MoveHotkey;
			if (((KeyboardShortcut)(ref moveHotkey)).IsDown())
			{
				if (_state != null)
				{
					Cancel(player, showMessage: true);
				}
				else
				{
					StartMove(player);
				}
			}
		}
		if (_state != null)
		{
			UpdateMoveGhostValidity(player);
		}
	}

	public static void UpdateVisuals(Player player)
	{
		if (MoveBuildPiecesPlugin.IsEnabled && !((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && _state != null)
		{
			UpdateLineAndGhost(player);
		}
	}

	public static bool IsMovingWith(Player player, Piece selectedPiece)
	{
		if (_state == null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player || (Object)(object)selectedPiece == (Object)null)
		{
			return false;
		}
		return Utils.GetPrefabName(((Component)selectedPiece).gameObject) == _state.PrefabName;
	}

	public static bool ShouldBypassRequirements(Player player, Piece piece, RequirementMode mode)
	{
		//IL_0014: 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_0019: Invalid comparison between Unknown and I4
		//IL_0056: 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)
		if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null)
		{
			return false;
		}
		if ((int)mode != 0 && (int)mode != 2)
		{
			return false;
		}
		string prefabName = Utils.GetPrefabName(((Component)piece).gameObject);
		if (_state != null && (Object)(object)player == (Object)(object)_state.Player && prefabName == _state.PrefabName)
		{
			return CanBypassResourceRequirements(player, piece, mode);
		}
		if (_selectionOverride != null && (Object)(object)player == (Object)(object)_selectionOverride.Player && prefabName == _selectionOverride.PrefabName)
		{
			return CanBypassResourceRequirements(player, piece, mode);
		}
		return false;
	}

	public static void TryFinishMove(Player player)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		if (_state == null || (Object)(object)player != (Object)(object)_state.Player)
		{
			return;
		}
		GameObject placementGhost = GetPlacementGhost(player);
		if ((Object)(object)placementGhost == (Object)null)
		{
			Message(player, "$msg_invalidplacement");
			Cancel(player, showMessage: false);
			return;
		}
		if ((int)GetPlacementStatus(player) != 0)
		{
			Message(player, "$msg_invalidplacement");
			return;
		}
		Vector3 position = placementGhost.transform.position;
		Quaternion rotation = placementGhost.transform.rotation;
		if (ValidateMoveDestination(player, position, showMessage: true) && ValidateMoveTarget(player, _state.Piece))
		{
			MovePiece(_state, position, rotation);
			Message(player, "Moved " + Localization.instance.Localize(_state.Piece.m_name));
			_state.Piece.m_placeEffect.Create(position, rotation, ((Component)_state.Piece).transform, 1f, -1);
			Cancel(player, showMessage: false);
		}
	}

	private static void StartMove(Player player)
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if (!((Character)player).InPlaceMode())
		{
			return;
		}
		Piece hoveringPiece = player.GetHoveringPiece();
		if ((Object)(object)hoveringPiece == (Object)null)
		{
			Message(player, "Hover a build piece to move it");
		}
		else
		{
			if (!ValidateMoveTarget(player, hoveringPiece))
			{
				return;
			}
			if (!SelectMovePiece(player, hoveringPiece))
			{
				Message(player, "$msg_missingrequirement");
				return;
			}
			SetupPlacementGhostMethod?.Invoke(player, Array.Empty<object>());
			if ((Object)(object)GetPlacementGhost(player) == (Object)null)
			{
				Message(player, "$msg_invalidplacement");
				return;
			}
			List<EffectArea> baseAreasAt = GetBaseAreasAt(((Component)hoveringPiece).transform.position);
			if (baseAreasAt.Count == 0)
			{
				Message(player, "Only pieces inside a base territory can be moved");
				return;
			}
			_state = new MoveState
			{
				Player = player,
				Piece = hoveringPiece,
				NetView = ((Component)hoveringPiece).GetComponent<ZNetView>(),
				PrefabName = Utils.GetPrefabName(((Component)hoveringPiece).gameObject),
				OriginalPosition = ((Component)hoveringPiece).transform.position,
				OriginalRotation = ((Component)hoveringPiece).transform.rotation,
				OriginalBaseAreas = baseAreasAt
			};
			Message(player, "Move mode: place the ghost to move " + Localization.instance.Localize(hoveringPiece.m_name));
			UpdateMoveGhostValidity(player);
		}
	}

	private static bool SelectMovePiece(Player player, Piece piece)
	{
		_selectionOverride = new MoveSelectionOverride
		{
			Player = player,
			PrefabName = Utils.GetPrefabName(((Component)piece).gameObject)
		};
		try
		{
			UpdateAvailablePiecesListMethod?.Invoke(player, Array.Empty<object>());
			return player.SetSelectedPiece(piece);
		}
		finally
		{
			_selectionOverride = null;
		}
	}

	private static bool ValidateMoveTarget(Player player, Piece piece)
	{
		//IL_0037: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)piece == (Object)null || (Object)(object)player == (Object)null)
		{
			return false;
		}
		if (!piece.m_canBeRemoved || !piece.IsPlacedByPlayer())
		{
			Message(player, "Only player-built removable pieces can be moved");
			return false;
		}
		if (Location.IsInsideNoBuildLocation(((Component)piece).transform.position))
		{
			Message(player, "$msg_nobuildzone");
			return false;
		}
		if (!PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false))
		{
			Message(player, "$msg_privatezone");
			return false;
		}
		if (!IsInsideBaseTerritory(((Component)piece).transform.position))
		{
			Message(player, "Only pieces inside a base territory can be moved");
			return false;
		}
		ZNetView component = ((Component)piece).GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null || !component.IsValid())
		{
			Message(player, "$msg_invalidplacement");
			return false;
		}
		if (!piece.CanBeRemoved())
		{
			Message(player, "$msg_cantremovenow");
			return false;
		}
		if (MoveBuildPiecesPlugin.BlockTerrainModifiers && HasTerrainMutation(piece))
		{
			Message(player, "Pieces that modify terrain are blocked");
			return false;
		}
		if (MoveBuildPiecesPlugin.BlockDynamicObjects && HasBlockedDynamicComponent(piece))
		{
			Message(player, "Dynamic pieces are blocked");
			return false;
		}
		if (IsContainerInUse(piece))
		{
			Message(player, "$msg_inuse");
			return false;
		}
		return true;
	}

	private static bool HasTerrainMutation(Piece piece)
	{
		if (!((Object)(object)((Component)piece).GetComponentInChildren<TerrainModifier>(true) != (Object)null))
		{
			return (Object)(object)((Component)piece).GetComponentInChildren<TerrainOp>(true) != (Object)null;
		}
		return true;
	}

	private static bool HasBlockedDynamicComponent(Piece piece)
	{
		if ((Object)(object)((Component)piece).GetComponentInChildren<Ship>(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren<Vagon>(true) != (Object)null || (Object)(object)((Component)piece).GetComponentInChildren<Character>(true) != (Object)null)
		{
			return true;
		}
		Rigidbody[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Rigidbody>(true);
		foreach (Rigidbody val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && !val.isKinematic)
			{
				return true;
			}
		}
		return false;
	}

	private static bool IsContainerInUse(Piece piece)
	{
		Container[] componentsInChildren = ((Component)piece).GetComponentsInChildren<Container>(true);
		foreach (Container val in componentsInChildren)
		{
			if ((Object)(object)val != (Object)null && val.IsInUse())
			{
				return true;
			}
		}
		return false;
	}

	private static bool IsInsideBaseTerritory(Vector3 point)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		return (Object)(object)EffectArea.IsPointInsideArea(point, (Type)4, 0.05f) != (Object)null;
	}

	private static bool ValidateMoveDestination(Player player, Vector3 targetPosition, bool showMessage)
	{
		//IL_0000: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		if (Location.IsInsideNoBuildLocation(targetPosition))
		{
			if (showMessage)
			{
				Message(player, "$msg_nobuildzone");
			}
			return false;
		}
		if (!PrivateArea.CheckAccess(targetPosition, 0f, true, false))
		{
			if (showMessage)
			{
				Message(player, "$msg_privatezone");
			}
			return false;
		}
		if (!IsInsideMoveTerritory(targetPosition))
		{
			if (showMessage)
			{
				Message(player, "Target is outside the original base territory");
			}
			return false;
		}
		if ((Object)(object)_state?.Piece != (Object)null && !HasRequiredBuildStationInRange(_state.Piece, ((Component)player).transform.position))
		{
			if (showMessage)
			{
				Message(player, "$msg_missingstation");
			}
			return false;
		}
		if ((Object)(object)_state?.Piece != (Object)null && !HasRequiredBuildStationInRange(_state.Piece, targetPosition))
		{
			if (showMessage)
			{
				Message(player, "$msg_missingstation");
			}
			return false;
		}
		return true;
	}

	private static bool CanBypassResourceRequirements(Player player, Piece piece, RequirementMode mode)
	{
		//IL_000c: 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)
		if (!player.HaveRequirements(piece, (RequirementMode)1))
		{
			return false;
		}
		if ((int)mode == 0)
		{
			return HasRequiredBuildStationInRange(piece, ((Component)player).transform.position);
		}
		return true;
	}

	private static bool HasRequiredBuildStationInRange(Piece piece, Vector3 point)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)piece == (Object)null || (Object)(object)piece.m_craftingStation == (Object)null)
		{
			return true;
		}
		if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)22))
		{
			return true;
		}
		return (Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, point) != (Object)null;
	}

	private static bool IsInsideMoveTerritory(Vector3 point)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if (_state?.OriginalBaseAreas == null || _state.OriginalBaseAreas.Count == 0)
		{
			return false;
		}
		foreach (EffectArea originalBaseArea in _state.OriginalBaseAreas)
		{
			if (IsPointInsideArea(originalBaseArea, point))
			{
				return true;
			}
		}
		return false;
	}

	private static List<EffectArea> GetBaseAreasAt(Vector3 point)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		List<EffectArea> list = new List<EffectArea>();
		foreach (EffectArea allArea in EffectArea.GetAllAreas())
		{
			if (IsPointInsideArea(allArea, point))
			{
				list.Add(allArea);
			}
		}
		return list;
	}

	private static bool IsPointInsideArea(EffectArea area, Vector3 point)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)area == (Object)null || (area.m_type & 4) == 0)
		{
			return false;
		}
		Collider component = ((Component)area).GetComponent<Collider>();
		if (!((Object)(object)component == (Object)null))
		{
			Bounds bounds = component.bounds;
			if (((Bounds)(ref bounds)).Contains(point))
			{
				return Vector3.Distance(component.ClosestPoint(point), point) <= 0.1f;
			}
		}
		return false;
	}

	private static void MovePiece(MoveState state, Vector3 targetPosition, Quaternion targetRotation)
	{
		//IL_0016: 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_0033: 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_0045: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		ZNetView netView = state.NetView;
		if (!netView.IsOwner())
		{
			netView.ClaimOwnership();
		}
		ClearSupportCachesNear(state.OriginalPosition);
		ClearSupportCachesNear(targetPosition);
		ZDO zDO = netView.GetZDO();
		zDO.SetPosition(targetPosition);
		zDO.SetRotation(targetRotation);
		((Component)state.Piece).transform.SetPositionAndRotation(targetPosition, targetRotation);
		Rigidbody[] componentsInChildren = ((Component)state.Piece).GetComponentsInChildren<Rigidbody>(true);
		foreach (Rigidbody val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				val.position = targetPosition;
				val.rotation = targetRotation;
				val.linearVelocity = Vector3.zero;
				val.angularVelocity = Vector3.zero;
			}
		}
		Physics.SyncTransforms();
		ClearSupportCachesNear(targetPosition);
	}

	private static void ClearSupportCachesNear(Vector3 position)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (ClearCachedSupportMethod == null)
		{
			return;
		}
		SupportColliders.Clear();
		SupportPieces.Clear();
		int num = Physics.OverlapSphereNonAlloc(position, 8f, SupportCollidersBuffer.Items, LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }));
		for (int i = 0; i < num; i++)
		{
			Collider val = SupportCollidersBuffer.Items[i];
			WearNTear val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<WearNTear>() : null);
			if ((Object)(object)val2 != (Object)null && SupportPieces.Add(val2))
			{
				ClearCachedSupportMethod.Invoke(val2, new object[1] { ZDOMan.GetSessionID() });
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.InvokeRPC(ZNetView.Everybody, "RPC_ClearCachedSupport", Array.Empty<object>());
				}
			}
		}
	}

	private static void UpdateMoveGhostValidity(Player player)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Invalid comparison between Unknown and I4
		GameObject placementGhost = GetPlacementGhost(player);
		if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null)
		{
			Cancel(player, showMessage: false);
			return;
		}
		bool flag = ValidateMoveDestination(player, placementGhost.transform.position, showMessage: false);
		Piece component = placementGhost.GetComponent<Piece>();
		if (!((Object)(object)component != (Object)null))
		{
			return;
		}
		if (flag && (int)GetPlacementStatus(player) == 0)
		{
			component.SetInvalidPlacementHeightlight(false);
			if ((Object)(object)_state.HighlightedGhost != (Object)(object)placementGhost || !_state.GhostHighlighted)
			{
				ApplyMoveGhostHighlight(placementGhost);
				_state.HighlightedGhost = placementGhost;
				_state.GhostHighlighted = true;
			}
		}
		else
		{
			component.SetInvalidPlacementHeightlight(true);
			_state.GhostHighlighted = false;
		}
	}

	private static void UpdateLineAndGhost(Player player)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_0072: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		GameObject placementGhost = GetPlacementGhost(player);
		if (_state == null || (Object)(object)placementGhost == (Object)null || (Object)(object)_state.Piece == (Object)null)
		{
			Cancel(player, showMessage: false);
			return;
		}
		EnsureLine();
		Vector3 position = ((Component)_state.Piece).transform.position;
		Vector3 position2 = placementGhost.transform.position;
		Vector3 val = ProjectToGround(position);
		Vector3 val2 = ProjectToGround(position2);
		Vector3 topLinkPoint = GetTopLinkPoint(((Component)_state.Piece).gameObject, val);
		Vector3 topLinkPoint2 = GetTopLinkPoint(placementGhost, val2);
		float ringRadius = GetRingRadius(((Component)_state.Piece).gameObject);
		float ringRadius2 = GetRingRadius(placementGhost);
		UpdateLinkObject(val, val2, topLinkPoint, topLinkPoint2, ringRadius, ringRadius2, placementGhost.activeInHierarchy);
		UpdateMoveGhostValidity(player);
	}

	private static void UpdateLinkObject(Vector3 groundStart, Vector3 groundEnd, Vector3 linkStart, Vector3 linkEnd, float originRingRadius, float ghostRingRadius, bool visible)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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_0081: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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_00bb: 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)
		if (!((Object)(object)_lineObject == (Object)null) && !((Object)(object)_dashLine == (Object)null) && !((Object)(object)_originRing == (Object)null) && !((Object)(object)_ghostRing == (Object)null))
		{
			if (!IsFinite(linkStart) || !IsFinite(linkEnd) || Vector3.Distance(linkStart, linkEnd) <= 0.05f)
			{
				linkStart = groundStart + Vector3.up * 1.25f;
				linkEnd = groundEnd + Vector3.up * 1.25f;
			}
			float num = Vector3.Distance(linkStart, linkEnd);
			bool num2 = visible && num > 0.05f;
			SetLineVisible(num2);
			if (num2)
			{
				DrawRing(_originRing, groundStart, originRingRadius);
				DrawRing(_ghostRing, groundEnd, ghostRingRadius);
				DrawDash(linkStart, linkEnd, num);
			}
		}
	}

	private static void ApplyMoveGhostHighlight(GameObject ghost)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: 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)
		Renderer[] componentsInChildren = ghost.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Material[] materials = val.materials;
			foreach (Material val2 in materials)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					SetMaterialColor(val2, "_Color", GhostColor);
					SetMaterialColor(val2, "_BaseColor", GhostColor);
					SetMaterialColor(val2, "_TintColor", GhostColor);
					SetMaterialColor(val2, "_EmissionColor", GhostEmissionColor);
					val2.EnableKeyword("_EMISSION");
				}
			}
		}
	}

	private static void SetMaterialColor(Material material, string property, Color color)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		if (material.HasProperty(property))
		{
			material.SetColor(property, color);
		}
	}

	private static Vector3 ProjectToGround(Vector3 worldPosition)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (TryFindFloorY(worldPosition, 4f, out var floorY))
		{
			return new Vector3(worldPosition.x, floorY + 0.03f, worldPosition.z);
		}
		return worldPosition;
	}

	private static Vector3 GetTopLinkPoint(GameObject gameObject, Vector3 fallbackGroundPoint)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: 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_0038: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (TryGetObjectBounds(gameObject, out var bounds))
		{
			Vector3 center = ((Bounds)(ref bounds)).center;
			float num = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(center.x, num, center.z);
			if (IsFinite(val))
			{
				return val;
			}
		}
		Piece component = gameObject.GetComponent<Piece>();
		if ((Object)(object)component != (Object)null && TryGetSnapPointBounds(component, out bounds))
		{
			Vector3 center2 = ((Bounds)(ref bounds)).center;
			float num2 = Mathf.Max(((Bounds)(ref bounds)).max.y + 0.15f, fallbackGroundPoint.y + 0.35f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(center2.x, num2, center2.z);
			if (IsFinite(val2))
			{
				return val2;
			}
		}
		return fallbackGroundPoint + Vector3.up * 1.25f;
	}

	private static bool TryGetObjectBounds(GameObject gameObject, out Bounds bounds)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		bool hasBounds = TryCollectColliderBounds(gameObject, out bounds);
		if (!IsUsefulBounds(bounds, hasBounds))
		{
			hasBounds = TryCollectRendererBounds(gameObject, out bounds);
		}
		if (!IsUsefulBounds(bounds, hasBounds))
		{
			hasBounds = TryCollectMeshBounds(gameObject, out bounds);
		}
		return IsUsefulBounds(bounds, hasBounds);
	}

	private static float GetRingRadius(GameObject gameObject)
	{
		//IL_000c: 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_0025: 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)
		if (TryGetObjectBounds(gameObject, out var bounds))
		{
			float num = Mathf.Sqrt(((Bounds)(ref bounds)).extents.x * ((Bounds)(ref bounds)).extents.x + ((Bounds)(ref bounds)).extents.z * ((Bounds)(ref bounds)).extents.z);
			if (IsFinite(num) && num > 0f)
			{
				return Mathf.Clamp(num + 0.25f, 0.6f, 8f);
			}
		}
		return 0.6f;
	}

	private static bool TryCollectColliderBounds(GameObject gameObject, out Bounds bounds)
	{
		//IL_0003: 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)
		bool hasBounds = false;
		bounds = default(Bounds);
		Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(true);
		foreach (Collider val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger)
			{
				AddBounds(ref bounds, ref hasBounds, val.bounds);
			}
		}
		return hasBounds;
	}

	private static bool TryCollectRendererBounds(GameObject gameObject, out Bounds bounds)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		bool hasBounds = false;
		bounds = default(Bounds);
		Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && val.enabled && !(((object)val).GetType().Name == "ParticleSystemRenderer"))
			{
				AddBounds(ref bounds, ref hasBounds, val.bounds);
			}
		}
		return hasBounds;
	}

	private static bool TryCollectMeshBounds(GameObject gameObject, out Bounds bounds)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		bool hasBounds = false;
		bounds = default(Bounds);
		MeshFilter[] componentsInChildren = gameObject.GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val in componentsInChildren)
		{
			Mesh val2 = (((Object)(object)val != (Object)null) ? val.sharedMesh : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				Bounds bounds2 = val2.bounds;
				Vector3 val3 = ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center);
				Vector3 val4 = Vector3.Scale(((Bounds)(ref bounds2)).size, Abs(((Component)val).transform.lossyScale));
				AddBounds(ref bounds, ref hasBounds, new Bounds(val3, val4));
			}
		}
		return hasBounds;
	}

	private static bool TryGetSnapPointBounds(Piece piece, out Bounds bounds)
	{
		//IL_0010: 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_0038: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		List<Transform> list = new List<Transform>();
		piece.GetSnapPoints(list);
		bool hasBounds = false;
		bounds = default(Bounds);
		Bounds candidate = default(Bounds);
		foreach (Transform item in list)
		{
			if (!((Object)(object)item == (Object)null))
			{
				((Bounds)(ref candidate))..ctor(item.position, Vector3.one * 0.05f);
				AddBounds(ref bounds, ref hasBounds, candidate);
			}
		}
		return hasBounds;
	}

	private static void AddBounds(ref Bounds bounds, ref bool hasBounds, Bounds candidate)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		if (IsFinite(((Bounds)(ref candidate)).center) && IsFinite(((Bounds)(ref candidate)).size))
		{
			if (!hasBounds)
			{
				bounds = candidate;
				hasBounds = true;
			}
			else
			{
				((Bounds)(ref bounds)).Encapsulate(candidate);
			}
		}
	}

	private static bool IsUsefulBounds(Bounds bounds, bool hasBounds)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		if (hasBounds && IsFinite(((Bounds)(ref bounds)).center) && IsFinite(((Bounds)(ref bounds)).size))
		{
			Vector3 size = ((Bounds)(ref bounds)).size;
			return ((Vector3)(ref size)).sqrMagnitude >= 0.0025000002f;
		}
		return false;
	}

	private static Vector3 Abs(Vector3 vector)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(Mathf.Abs(vector.x), Mathf.Abs(vector.y), Mathf.Abs(vector.z));
	}

	private static bool IsFinite(Vector3 vector)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		if (IsFinite(vector.x) && IsFinite(vector.y))
		{
			return IsFinite(vector.z);
		}
		return false;
	}

	private static bool IsFinite(float value)
	{
		if (!float.IsNaN(value))
		{
			return !float.IsInfinity(value);
		}
		return false;
	}

	private static bool TryFindFloorY(Vector3 worldPosition, float searchHeight, out float floorY)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: 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_00c3: 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)
		floorY = worldPosition.y;
		if (_floorMask == 0)
		{
			_floorMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "water" });
		}
		int num = Physics.RaycastNonAlloc(worldPosition + Vector3.up * 0.25f, Vector3.down, FloorHits, searchHeight, _floorMask, (QueryTriggerInteraction)1);
		bool flag = false;
		float num2 = float.NegativeInfinity;
		for (int i = 0; i < num; i++)
		{
			RaycastHit val = FloorHits[i];
			if (!(((RaycastHit)(ref val)).normal.y < 0.7f) && !(((RaycastHit)(ref val)).point.y > worldPosition.y + 0.2f) && !(((RaycastHit)(ref val)).point.y <= num2))
			{
				num2 = ((RaycastHit)(ref val)).point.y;
				flag = true;
			}
		}
		if (flag)
		{
			floorY = num2;
		}
		return flag;
	}

	private static void DrawRing(LineRenderer ring, Vector3 center, float radius)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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)
		if (ring.positionCount != 28)
		{
			ring.positionCount = 28;
		}
		for (int i = 0; i < 28; i++)
		{
			float num = (float)i / 28f * (float)Math.PI * 2f;
			Vector3 val = center + (Vector3.right * Mathf.Cos(num) + Vector3.forward * Mathf.Sin(num)) * radius;
			ring.SetPosition(i, val);
		}
	}

	private static void DrawDash(Vector3 from, Vector3 to, float length)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		_dashLine.positionCount = 2;
		_dashLine.SetPosition(0, from);
		_dashLine.SetPosition(1, to);
		Material material = ((Renderer)_dashLine).material;
		if (!((Object)(object)material == (Object)null))
		{
			EnsureDashTexture();
			material.mainTexture = (Texture)(object)_dashTexture;
			material.mainTextureScale = new Vector2(Mathf.Max(0.01f, length / 0.35f), 1f);
			material.mainTextureOffset = new Vector2((0f - Time.time) * 1.6f, 0f);
		}
	}

	private static void EnsureDashTexture()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_dashTexture != (Object)null))
		{
			_dashTexture = new Texture2D(10, 1, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)1
			};
			Color[] array = (Color[])(object)new Color[10];
			for (int i = 0; i < 10; i++)
			{
				array[i] = (Color)((i < 6) ? Color.white : new Color(1f, 1f, 1f, 0f));
			}
			_dashTexture.SetPixels(array);
			_dashTexture.Apply();
		}
	}

	private static bool ShouldCancelForUiOrState(Player player)
	{
		if (_state == null)
		{
			return false;
		}
		if (!MoveBuildPiecesPlugin.IsEnabled || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)_state.Player || !((Character)player).InPlaceMode() || ((Character)player).IsDead())
		{
			return true;
		}
		if ((Object)(object)_state.NetView == (Object)null || !_state.NetView.IsValid() || (Object)(object)_state.Piece == (Object)null)
		{
			return true;
		}
		if (IsUiBlockingInput() || Hud.IsPieceSelectionVisible())
		{
			return true;
		}
		return ZInput.GetKeyDown((KeyCode)27, true);
	}

	private static bool IsUiBlockingInput()
	{
		if (!Menu.IsVisible() && !InventoryGui.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen())
		{
			if ((Object)(object)Chat.instance != (Object)null)
			{
				return Chat.instance.HasFocus();
			}
			return false;
		}
		return true;
	}

	private static void Cancel(Player player, bool showMessage)
	{
		if (_state != null && showMessage)
		{
			Message(player, "Move cancelled");
		}
		_state = null;
		DestroyLine();
	}

	private static GameObject GetPlacementGhost(Player player)
	{
		object? obj = PlacementGhostField?.GetValue(player);
		return (GameObject)((obj is GameObject) ? obj : null);
	}

	private static PlacementStatus GetPlacementStatus(Player player)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		object obj = PlacementStatusField?.GetValue(player);
		if (obj is PlacementStatus)
		{
			return (PlacementStatus)obj;
		}
		return (PlacementStatus)1;
	}

	private static void EnsureLine()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		if (!((Object)(object)_lineObject != (Object)null))
		{
			_lineObject = new GameObject("MoveBuildPieces_LinkVisuals");
			Object.DontDestroyOnLoad((Object)(object)_lineObject);
			_dashLine = CreateLineRenderer("MoveBuildPieces_Dash", loop: false, tiled: true);
			_originRing = CreateLineRenderer("MoveBuildPieces_OriginRing", loop: true, tiled: false);
			_ghostRing = CreateLineRenderer("MoveBuildPieces_GhostRing", loop: true, tiled: false);
			SetLineVisible(visible: false);
		}
	}

	private static LineRenderer CreateLineRenderer(string name, bool loop, bool tiled)
	{
		//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_006f: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Expected O, but got Unknown
		GameObject val = new GameObject(name);
		val.transform.SetParent(_lineObject.transform, false);
		LineRenderer val2 = val.AddComponent<LineRenderer>();
		val2.useWorldSpace = true;
		val2.loop = loop;
		val2.numCapVertices = 4;
		val2.numCornerVertices = 2;
		val2.textureMode = (LineTextureMode)(tiled ? 1 : 0);
		val2.alignment = (LineAlignment)0;
		val2.positionCount = 0;
		val2.widthMultiplier = 0.075f;
		val2.startColor = (loop ? RingColor : LinkColor);
		val2.endColor = (loop ? RingColor : LinkColor);
		((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)val2).receiveShadows = false;
		Shader val3 = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
		if ((Object)(object)val3 != (Object)null)
		{
			((Renderer)val2).material = new Material(val3)
			{
				name = name + "_Material",
				renderQueue = 3100
			};
		}
		((Renderer)val2).enabled = false;
		return val2;
	}

	private static void SetLineVisible(bool visible)
	{
		if ((Object)(object)_dashLine != (Object)null)
		{
			((Renderer)_dashLine).enabled = visible;
		}
		if ((Object)(object)_originRing != (Object)null)
		{
			((Renderer)_originRing).enabled = visible;
		}
		if ((Object)(object)_ghostRing != (Object)null)
		{
			((Renderer)_ghostRing).enabled = visible;
		}
	}

	private static void DestroyLine()
	{
		if ((Object)(object)_lineObject != (Object)null)
		{
			Object.Destroy((Object)(object)_lineObject);
		}
		_lineObject = null;
		_dashLine = null;
		_originRing = null;
		_ghostRing = null;
	}

	private static void Message(Player player, string text)
	{
		if ((Object)(object)player != (Object)null)
		{
			((Character)player).Message((MessageType)2, text, 0, (Sprite)null);
		}
	}
}