Decompiled source of PrecisionBuild v1.1.1

PrecisionBuild.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using GUIFramework;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
using UnityEngine.UI;

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

[BepInProcess("valheim.exe")]
[BepInPlugin("com.awuushy.precisionbuild", "PrecisionBuild", "1.1.1")]
public class BuildGridPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.awuushy.precisionbuild";

	public const string PluginName = "PrecisionBuild";

	public const string PluginVersion = "1.1.1";

	public static ConfigEntry<bool> ModEnabled;

	public static ConfigEntry<KeyCode> ToggleGridKey;

	public static ConfigEntry<KeyCode> CycleGridSizeKey;

	public static ConfigEntry<KeyCode> CycleRotationKey;

	public static ConfigEntry<KeyCode> ToggleSnapTargetKey;

	public static ConfigEntry<float> ConfigGridSize;

	public static ConfigEntry<bool> SnapToCellCenters;

	public static ConfigEntry<bool> ShowVisualGrid;

	public static ConfigEntry<bool> ShowFootprint;

	public static ConfigEntry<bool> ShowKeyHints;

	public static ConfigEntry<bool> SnapAllPieces;

	public static ConfigEntry<string> GridColorHex;

	public static ConfigEntry<string> ActiveNodeColorHex;

	public static ConfigEntry<string> FootprintColorHex;

	public static ConfigEntry<float> GridLineWidth;

	public static ConfigEntry<int> GridRadiusCells;

	public static bool IsGridActive = true;

	public static float CurrentGridSize = 0.25f;

	public static float CurrentRotationDegrees = 22.5f;

	public static bool IsSnapToCenter = false;

	private static readonly float[] s_gridSizes = new float[4] { 0.125f, 0.25f, 0.5f, 1f };

	private static int s_currentSizeIndex = 1;

	private static readonly float[] s_rotationSteps = new float[4] { 90f, 45f, 22.5f, 5f };

	private static int s_currentRotationIndex = 2;

	private Harmony m_harmony;

	private static readonly FieldInfo s_placeRotationDegreesField = AccessTools.Field(typeof(Player), "m_placeRotationDegrees");

	public static BuildGridPlugin Instance { get; private set; }

	private void Awake()
	{
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Expected O, but got Unknown
		//IL_02bc: 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_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Master switch for PrecisionBuild mod.");
		ToggleGridKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Hotkeys", "ToggleGridKey", (KeyCode)98, "Key to toggle building grid on/off. B is completely free in Valheim.");
		CycleGridSizeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Hotkeys", "CycleGridSizeKey", (KeyCode)110, "Key to cycle through grid sizes (0.125m -> 0.25m -> 0.5m -> 1.0m).");
		CycleRotationKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Hotkeys", "CycleRotationKey", (KeyCode)107, "Key to cycle rotation angle steps (90° -> 45° -> 22.5° -> 5°).");
		ToggleSnapTargetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2. Hotkeys", "ToggleSnapTargetKey", (KeyCode)106, "Key to toggle grid snap target between Intersections (corners) and Cell Centers.");
		ConfigGridSize = ((BaseUnityPlugin)this).Config.Bind<float>("3. Grid", "DefaultGridSize", 0.25f, "Default grid cell size in meters (0.125, 0.25, 0.5, 1.0).");
		SnapToCellCenters = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Grid", "SnapToCellCenters", false, "Default snap target mode: false = Intersections (corners), true = Cell Centers.");
		ShowVisualGrid = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Grid", "ShowVisualGrid", true, "Whether to display the semi-transparent grid on the surface.");
		ShowFootprint = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Grid", "ShowFootprint", false, "Whether to display the rectangular footprint boundary of the object being placed (Default: false).");
		ShowKeyHints = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Grid", "ShowKeyHints", true, "Whether to display compact hotkey hints in the build mode HUD.");
		SnapAllPieces = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Grid", "SnapAllPieces", true, "If true, grid snapping applies to ALL building pieces (walls, floors, roofs, pillars, beams, chests, furniture, etc.).");
		GridRadiusCells = ((BaseUnityPlugin)this).Config.Bind<int>("3. Grid", "GridRadiusCells", 8, "How many grid cells to draw in each direction around the cursor.");
		GridColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("4. Visuals", "GridColor", "#FFFFFF45", "Color of the surface grid lines in HEX format with alpha (Default: translucent white #FFFFFF45).");
		ActiveNodeColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("4. Visuals", "ActiveNodeColor", "#FFFFFFFF", "Color of the active snap node marker at the grid intersection (Default: pure white #FFFFFFFF).");
		FootprintColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("4. Visuals", "FootprintColor", "#FFFFFF85", "Color of the projected item footprint outline (Default: crisp white #FFFFFF85).");
		GridLineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("4. Visuals", "GridLineWidth", 0.014f, "Physical thickness of the rendered grid lines in meters.");
		CurrentGridSize = Mathf.Clamp(ConfigGridSize.Value, 0.05f, 5f);
		for (int i = 0; i < s_gridSizes.Length; i++)
		{
			if (Mathf.Approximately(s_gridSizes[i], CurrentGridSize))
			{
				s_currentSizeIndex = i;
				break;
			}
		}
		IsSnapToCenter = SnapToCellCenters.Value;
		m_harmony = new Harmony("com.awuushy.precisionbuild");
		m_harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded successfully! Hotkeys: Toggle=[{2}], Size=[{3}], Rotation=[{4}], Target=[{5}]", "PrecisionBuild", "1.1.1", ToggleGridKey.Value, CycleGridSizeKey.Value, CycleRotationKey.Value, ToggleSnapTargetKey.Value));
	}

	private void Update()
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		if (!ModEnabled.Value)
		{
			GridRenderer.Hide();
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || !((Character)localPlayer).InPlaceMode())
		{
			GridRenderer.Hide();
			return;
		}
		if (IsGridActive)
		{
			SetPlayerRotationDegrees(localPlayer, CurrentRotationDegrees);
		}
		else
		{
			SetPlayerRotationDegrees(localPlayer, 22.5f);
		}
		if (IsTextInputActive())
		{
			return;
		}
		if (Input.GetKeyDown(ToggleGridKey.Value))
		{
			IsGridActive = !IsGridActive;
			if (!IsGridActive)
			{
				GridRenderer.Hide();
			}
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, BuildGridLocalization.GridToggleStatus(IsGridActive, CurrentGridSize), 0, (Sprite)null, false, true);
			}
		}
		if (Input.GetKeyDown(CycleGridSizeKey.Value))
		{
			s_currentSizeIndex = (s_currentSizeIndex + 1) % s_gridSizes.Length;
			CurrentGridSize = s_gridSizes[s_currentSizeIndex];
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, BuildGridLocalization.GridStepChanged(CurrentGridSize), 0, (Sprite)null, false, true);
			}
		}
		if (Input.GetKeyDown(CycleRotationKey.Value))
		{
			s_currentRotationIndex = (s_currentRotationIndex + 1) % s_rotationSteps.Length;
			CurrentRotationDegrees = s_rotationSteps[s_currentRotationIndex];
			SetPlayerRotationDegrees(localPlayer, CurrentRotationDegrees);
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, BuildGridLocalization.RotationStepChanged(CurrentRotationDegrees), 0, (Sprite)null, false, true);
			}
		}
		if (Input.GetKeyDown(ToggleSnapTargetKey.Value))
		{
			IsSnapToCenter = !IsSnapToCenter;
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, BuildGridLocalization.SnapTargetChanged(IsSnapToCenter), 0, (Sprite)null, false, true);
			}
		}
	}

	public static void SetPlayerRotationDegrees(Player p, float degrees)
	{
		if (s_placeRotationDegreesField != null && (Object)(object)p != (Object)null)
		{
			s_placeRotationDegreesField.SetValue(p, degrees);
		}
	}

	private void OnDestroy()
	{
		GridRenderer.Destroy();
		if (m_harmony != null)
		{
			m_harmony.UnpatchSelf();
		}
	}

	public static bool IsTextInputActive()
	{
		if (Console.IsVisible())
		{
			return true;
		}
		if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
		{
			return true;
		}
		if (TextInput.IsVisible())
		{
			return true;
		}
		if (Menu.IsVisible())
		{
			return true;
		}
		try
		{
			if (Hud.IsPieceSelectionVisible())
			{
				return true;
			}
			if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_buildUi != (Object)null && Hud.instance.m_buildUi.SearchFieldFocused)
			{
				return true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)EventSystem.current != (Object)null)
			{
				GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
				if ((Object)(object)currentSelectedGameObject != (Object)null && ((Object)(object)currentSelectedGameObject.GetComponent<InputField>() != (Object)null || (Object)(object)currentSelectedGameObject.GetComponent<TMP_InputField>() != (Object)null || (Object)(object)currentSelectedGameObject.GetComponent<GuiInputField>() != (Object)null))
				{
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	public static Color ParseColor(string hex, Color fallback)
	{
		//IL_0008: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(hex))
		{
			return fallback;
		}
		Color result = default(Color);
		if (ColorUtility.TryParseHtmlString(hex, ref result))
		{
			return result;
		}
		return fallback;
	}
}
public static class BuildGridLocalization
{
	public static bool IsRussian()
	{
		if (Localization.instance != null)
		{
			string selectedLanguage = Localization.instance.GetSelectedLanguage();
			if (!string.IsNullOrEmpty(selectedLanguage) && selectedLanguage.IndexOf("Russian", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	public static string GridToggleStatus(bool active, float size)
	{
		if (IsRussian())
		{
			string arg = (active ? "<color=#00FFAA>ВКЛ</color>" : "<color=#FF6666>ВЫКЛ</color>");
			return $"Сетка строительства: {arg} [{size:0.##}м]";
		}
		string arg2 = (active ? "<color=#00FFAA>ON</color>" : "<color=#FF6666>OFF</color>");
		return $"Build Grid: {arg2} [{size:0.##}m]";
	}

	public static string GridStepChanged(float size)
	{
		if (IsRussian())
		{
			return $"Шаг сетки: <color=#FFFFFF>{size:0.##}м</color>";
		}
		return $"Grid Step: <color=#FFFFFF>{size:0.##}m</color>";
	}

	public static string RotationStepChanged(float angle)
	{
		if (IsRussian())
		{
			return $"Шаг вращения: <color=#FFFFFF>{angle:0.#}°</color>";
		}
		return $"Rotation Step: <color=#FFFFFF>{angle:0.#}°</color>";
	}

	public static string SnapTargetChanged(bool toCenter)
	{
		if (IsRussian())
		{
			if (!toCenter)
			{
				return "Привязка: <color=#00FFAA>Узлы сетки</color>";
			}
			return "Привязка: <color=#00FFAA>Центры ячеек</color>";
		}
		if (!toCenter)
		{
			return "Snap Target: <color=#00FFAA>Intersections</color>";
		}
		return "Snap Target: <color=#00FFAA>Cell Centers</color>";
	}

	public static string CompactKeyHint(string toggleKey, string sizeKey, string rotKey, string targetKey, bool active, float size, float rot, bool isCenter)
	{
		if (IsRussian())
		{
			if (!active)
			{
				return $"<color=#EAA623>[{toggleKey}]</color> Сетка: <color=#888888>ВЫКЛ</color>";
			}
			string text = (isCenter ? "Центры" : "Узлы");
			return $"<color=#EAA623>[{toggleKey}]</color> Сетка: <color=#00FFAA>ВКЛ</color>    <color=#EAA623>[{sizeKey}]</color> Шаг: <color=#FFFFFF>{size:0.##}м</color>    <color=#EAA623>[{rotKey}]</color> Угол: <color=#FFFFFF>{rot:0.#}°</color>    <color=#EAA623>[{targetKey}]</color> <color=#00FFAA>{text}</color>";
		}
		if (!active)
		{
			return $"<color=#EAA623>[{toggleKey}]</color> Grid: <color=#888888>OFF</color>";
		}
		string text2 = (isCenter ? "Centers" : "Corners");
		return $"<color=#EAA623>[{toggleKey}]</color> Grid: <color=#00FFAA>ON</color>    <color=#EAA623>[{sizeKey}]</color> Step: <color=#FFFFFF>{size:0.##}m</color>    <color=#EAA623>[{rotKey}]</color> Angle: <color=#FFFFFF>{rot:0.#}°</color>    <color=#EAA623>[{targetKey}]</color> <color=#00FFAA>{text2}</color>";
	}
}
public static class GridRenderer
{
	private static GameObject s_visualizerObject;

	private static MeshFilter s_meshFilter;

	private static MeshRenderer s_meshRenderer;

	private static Mesh s_gridMesh;

	private static Material s_gridMaterial;

	private static Texture2D s_proceduralGridTexture;

	private static readonly List<Vector3> s_vertices = new List<Vector3>(2048);

	private static readonly List<Vector2> s_uvs = new List<Vector2>(2048);

	private static readonly List<Color> s_colors = new List<Color>(2048);

	private static readonly List<int> s_triangles = new List<int>(4096);

	private static Transform s_lastPieceTransform = null;

	private static Vector3 s_lastSnappedPoint = Vector3.negativeInfinity;

	private static Vector3 s_lastGridCenter = Vector3.negativeInfinity;

	private static Quaternion s_lastGhostRotation = Quaternion.identity;

	private static float s_lastGridSize = -1f;

	private static bool s_isVisible = false;

	private static readonly Dictionary<int, Bounds> s_boundsCache = new Dictionary<int, Bounds>();

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

	public static Texture2D GetOrCreateGridTexture()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)s_proceduralGridTexture == (Object)null)
		{
			int num = 256;
			s_proceduralGridTexture = new Texture2D(num, num, (TextureFormat)4, true);
			((Object)s_proceduralGridTexture).name = "BuildGridTexture_White";
			((Texture)s_proceduralGridTexture).wrapMode = (TextureWrapMode)0;
			((Texture)s_proceduralGridTexture).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[num * num];
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					int num2 = Math.Min(j, num - 1 - j);
					int num3 = Math.Min(i, num - 1 - i);
					float num4 = Math.Min(num2, num3);
					float num5 = Mathf.Clamp01(1f - num4 / 2.5f);
					float num6 = Mathf.Clamp01(1f - num4 / 8.5f) * 0.35f;
					float num7 = Mathf.Sqrt((float)(num2 * num2 + num3 * num3));
					float num8 = Mathf.Clamp01(1f - num7 / 7f) * 0.85f;
					float num9 = Mathf.Clamp01(num5 + num6);
					float num10 = 0.03f;
					float num11 = Mathf.Max(num10, Mathf.Max(num9, num8));
					ref Color reference = ref array[i * num + j];
					reference = new Color(1f, 1f, 1f, num11);
				}
			}
			s_proceduralGridTexture.SetPixels(array);
			s_proceduralGridTexture.Apply(true, false);
		}
		return s_proceduralGridTexture;
	}

	private static Material GetOrCreateMaterial()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		if ((Object)(object)s_gridMaterial == (Object)null)
		{
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("GUI/Text Shader");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Hidden/Internal-Colored");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Transparent");
			}
			if ((Object)(object)val != (Object)null)
			{
				Material val2 = new Material(val);
				((Object)val2).name = "BuildGridMaterial";
				((Object)val2).hideFlags = (HideFlags)61;
				s_gridMaterial = val2;
				s_gridMaterial.mainTexture = (Texture)(object)GetOrCreateGridTexture();
				s_gridMaterial.SetInt("_SrcBlend", 5);
				s_gridMaterial.SetInt("_DstBlend", 10);
				s_gridMaterial.SetInt("_Cull", 0);
				s_gridMaterial.SetInt("_ZWrite", 0);
				s_gridMaterial.renderQueue = 3100;
			}
		}
		return s_gridMaterial;
	}

	private static void EnsureVisualizerObject()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		if ((Object)(object)s_visualizerObject == (Object)null)
		{
			GameObject val = new GameObject("_BuildGridVisualizer");
			((Object)val).hideFlags = (HideFlags)61;
			s_visualizerObject = val;
			s_meshFilter = s_visualizerObject.AddComponent<MeshFilter>();
			s_meshRenderer = s_visualizerObject.AddComponent<MeshRenderer>();
			((Renderer)s_meshRenderer).sharedMaterial = GetOrCreateMaterial();
			((Renderer)s_meshRenderer).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)s_meshRenderer).receiveShadows = false;
			((Renderer)s_meshRenderer).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)s_meshRenderer).reflectionProbeUsage = (ReflectionProbeUsage)0;
			Mesh val2 = new Mesh();
			((Object)val2).name = "BuildGridMesh";
			((Object)val2).hideFlags = (HideFlags)61;
			s_gridMesh = val2;
			s_meshFilter.sharedMesh = s_gridMesh;
		}
	}

	public static void UpdateGrid(Piece hitPiece, Collider collider, Vector3 hitPoint, Vector3 hitNormal, Vector3 snappedWorldPoint, float gridSize, GameObject placementGhost)
	{
		//IL_0030: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: 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_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: 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_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: 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_014f: 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)
		EnsureVisualizerObject();
		Transform val = (((Object)(object)hitPiece != (Object)null) ? ((Component)hitPiece).transform : null);
		Quaternion val2 = (((Object)(object)placementGhost != (Object)null) ? placementGhost.transform.rotation : Quaternion.identity);
		Vector3 val4 = default(Vector3);
		if ((Object)(object)hitPiece != (Object)null)
		{
			Vector3 val3 = val.InverseTransformPoint(hitPoint);
			float num = Mathf.Round(val3.x / 2f) * 2f;
			float num2 = Mathf.Round(val3.y / 2f) * 2f;
			float num3 = Mathf.Round(val3.z / 2f) * 2f;
			((Vector3)(ref val4))..ctor(num, num2, num3);
		}
		else
		{
			float num4 = Mathf.Round(hitPoint.x / 2f) * 2f;
			float num5 = Mathf.Round(hitPoint.y / 2f) * 2f;
			float num6 = Mathf.Round(hitPoint.z / 2f) * 2f;
			((Vector3)(ref val4))..ctor(num4, num5, num6);
		}
		if ((Object)(object)val != (Object)(object)s_lastPieceTransform || Mathf.Abs(gridSize - s_lastGridSize) > 0.001f || Vector3.SqrMagnitude(val4 - s_lastGridCenter) > 0.01f || Vector3.SqrMagnitude(snappedWorldPoint - s_lastSnappedPoint) > 0.0001f || Quaternion.Angle(val2, s_lastGhostRotation) > 0.5f)
		{
			s_lastPieceTransform = val;
			s_lastGridSize = gridSize;
			s_lastGridCenter = val4;
			s_lastSnappedPoint = snappedWorldPoint;
			s_lastGhostRotation = val2;
			BuildMesh(hitPiece, collider, hitPoint, hitNormal, snappedWorldPoint, gridSize, placementGhost);
		}
		if (!s_isVisible)
		{
			s_visualizerObject.SetActive(true);
			s_isVisible = true;
		}
	}

	public static Bounds GetPieceLocalBounds(Piece p)
	{
		//IL_0009: 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_0022: 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_003e: 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_0219: 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_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: 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_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_017c: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: 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_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: 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_0146: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null)
		{
			return new Bounds(Vector3.zero, new Vector3(2f, 2f, 0.2f));
		}
		int instanceID = ((Object)p).GetInstanceID();
		if (s_boundsCache.TryGetValue(instanceID, out var value))
		{
			return value;
		}
		Transform transform = ((Component)p).transform;
		s_collidersCache.Clear();
		((Component)p).GetComponentsInChildren<Collider>(true, s_collidersCache);
		bool flag = false;
		Bounds val = default(Bounds);
		((Bounds)(ref val))..ctor(Vector3.zero, Vector3.zero);
		Vector3 val5 = default(Vector3);
		Bounds val6 = default(Bounds);
		Vector3 val9 = default(Vector3);
		Bounds val10 = default(Bounds);
		for (int i = 0; i < s_collidersCache.Count; i++)
		{
			Collider val2 = s_collidersCache[i];
			if ((Object)(object)val2 == (Object)null || val2.isTrigger || !val2.enabled)
			{
				continue;
			}
			BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
			if ((Object)(object)val3 != (Object)null)
			{
				Vector3 val4 = transform.InverseTransformPoint(((Component)val3).transform.TransformPoint(val3.center));
				Vector3 size = val3.size;
				Vector3 lossyScale = ((Component)val3).transform.lossyScale;
				((Vector3)(ref val5))..ctor(Mathf.Abs(size.x * lossyScale.x), Mathf.Abs(size.y * lossyScale.y), Mathf.Abs(size.z * lossyScale.z));
				((Bounds)(ref val6))..ctor(val4, val5);
				if (!flag)
				{
					val = val6;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(val6);
				}
			}
			else
			{
				Bounds bounds = val2.bounds;
				Vector3 val7 = transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
				Vector3 val8 = transform.InverseTransformVector(((Bounds)(ref bounds)).size);
				((Vector3)(ref val9))..ctor(Mathf.Abs(val8.x), Mathf.Abs(val8.y), Mathf.Abs(val8.z));
				((Bounds)(ref val10))..ctor(val7, val9);
				if (!flag)
				{
					val = val10;
					flag = true;
				}
				else
				{
					((Bounds)(ref val)).Encapsulate(val10);
				}
			}
		}
		s_collidersCache.Clear();
		if (flag)
		{
			Vector3 size2 = ((Bounds)(ref val)).size;
			if (!(((Vector3)(ref size2)).sqrMagnitude < 0.01f))
			{
				goto IL_0223;
			}
		}
		((Bounds)(ref val))..ctor(Vector3.zero, new Vector3(2f, 2f, 0.2f));
		goto IL_0223;
		IL_0223:
		if (s_boundsCache.Count > 512)
		{
			s_boundsCache.Clear();
		}
		s_boundsCache[instanceID] = val;
		return val;
	}

	private static void BuildMesh(Piece hitPiece, Collider collider, Vector3 hitPoint, Vector3 hitNormal, Vector3 snappedWorldPoint, float gridSize, GameObject placementGhost)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_0079: 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_009d: 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_00dd: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: 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_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		s_vertices.Clear();
		s_uvs.Clear();
		s_colors.Clear();
		s_triangles.Clear();
		Color gridColor = BuildGridPlugin.ParseColor(BuildGridPlugin.GridColorHex.Value, new Color(1f, 1f, 1f, 0.45f));
		Color activeNodeColor = BuildGridPlugin.ParseColor(BuildGridPlugin.ActiveNodeColorHex.Value, new Color(1f, 1f, 1f, 0.95f));
		Color footprintColor = BuildGridPlugin.ParseColor(BuildGridPlugin.FootprintColorHex.Value, new Color(1f, 1f, 1f, 0.85f));
		float radiusMeters = Mathf.Clamp((float)BuildGridPlugin.GridRadiusCells.Value * gridSize, 1.8f, 10f);
		Vector3 worldNormal;
		if ((Object)(object)hitPiece != (Object)null)
		{
			worldNormal = BuildPieceSurfacePlane(hitPiece, hitPoint, hitNormal, snappedWorldPoint, gridSize, radiusMeters, gridColor, activeNodeColor);
		}
		else
		{
			worldNormal = Vector3.up;
			BuildTerrainPlane(hitPoint, snappedWorldPoint, gridSize, radiusMeters, gridColor, activeNodeColor);
		}
		if (BuildGridPlugin.ShowFootprint.Value && (Object)(object)placementGhost != (Object)null)
		{
			BuildFootprintOnly(placementGhost, snappedWorldPoint, worldNormal, gridSize, footprintColor);
		}
		s_gridMesh.Clear();
		s_gridMesh.SetVertices(s_vertices);
		s_gridMesh.SetUVs(0, s_uvs);
		s_gridMesh.SetColors(s_colors);
		s_gridMesh.SetTriangles(s_triangles, 0);
		s_gridMesh.RecalculateBounds();
	}

	private static Vector3 BuildPieceSurfacePlane(Piece hitPiece, Vector3 hitPoint, Vector3 hitNormal, Vector3 snappedWorldPoint, float gridSize, float radiusMeters, Color gridColor, Color activeNodeColor)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_0020: 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_0046: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: 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_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: 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_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0285: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_054f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0550: Unknown result type (might be due to invalid IL or missing references)
		//IL_055a: Unknown result type (might be due to invalid IL or missing references)
		//IL_055f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0564: Unknown result type (might be due to invalid IL or missing references)
		//IL_0567: Unknown result type (might be due to invalid IL or missing references)
		//IL_0569: Unknown result type (might be due to invalid IL or missing references)
		//IL_056e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0572: Unknown result type (might be due to invalid IL or missing references)
		//IL_0577: Unknown result type (might be due to invalid IL or missing references)
		//IL_057a: Unknown result type (might be due to invalid IL or missing references)
		//IL_057c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0581: Unknown result type (might be due to invalid IL or missing references)
		//IL_0585: Unknown result type (might be due to invalid IL or missing references)
		//IL_058a: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_043b: Unknown result type (might be due to invalid IL or missing references)
		Transform transform = ((Component)hitPiece).transform;
		Vector3 val = transform.InverseTransformPoint(hitPoint);
		Vector3 val2 = transform.InverseTransformDirection(hitNormal);
		Bounds pieceLocalBounds = GetPieceLocalBounds(hitPiece);
		bool flag = ((Bounds)(ref pieceLocalBounds)).size.y > 1.2f && (((Bounds)(ref pieceLocalBounds)).size.z < 0.8f || ((Bounds)(ref pieceLocalBounds)).size.x < 0.8f) && val.y < ((Bounds)(ref pieceLocalBounds)).max.y - 0.15f;
		float num = Mathf.Abs(val2.x);
		float num2 = Mathf.Abs(val2.y);
		float num3 = Mathf.Abs(val2.z);
		if (flag)
		{
			num2 = 0f;
		}
		Vector3 val3;
		Vector3 val4;
		float num4;
		float num5;
		float num7;
		Vector3 val5;
		if (num2 >= num && num2 >= num3)
		{
			val3 = Vector3.right;
			val4 = Vector3.forward;
			num4 = val.x;
			num5 = val.z;
			float num6 = ((val2.y >= 0f) ? 1f : (-1f));
			num7 = ((num6 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.y : ((Bounds)(ref pieceLocalBounds)).min.y);
			val5 = Vector3.up * num6;
		}
		else if (num3 >= num && num3 >= num2)
		{
			val3 = Vector3.right;
			val4 = Vector3.up;
			num4 = val.x;
			num5 = val.y;
			float num8 = ((Mathf.Abs(val2.z) > 0.1f) ? Mathf.Sign(val2.z) : ((val.z >= ((Bounds)(ref pieceLocalBounds)).center.z) ? 1f : (-1f)));
			num7 = ((num8 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.z : ((Bounds)(ref pieceLocalBounds)).min.z);
			val5 = Vector3.forward * num8;
		}
		else
		{
			val3 = Vector3.forward;
			val4 = Vector3.up;
			num4 = val.z;
			num5 = val.y;
			float num9 = ((Mathf.Abs(val2.x) > 0.1f) ? Mathf.Sign(val2.x) : ((val.x >= ((Bounds)(ref pieceLocalBounds)).center.x) ? 1f : (-1f)));
			num7 = ((num9 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.x : ((Bounds)(ref pieceLocalBounds)).min.x);
			val5 = Vector3.right * num9;
		}
		Vector3 val6 = transform.TransformDirection(val5);
		Vector3 val7 = ((Vector3)(ref val6)).normalized;
		if ((Object)(object)Camera.main != (Object)null)
		{
			Vector3 forward = ((Component)Camera.main).transform.forward;
			if (Vector3.Dot(val7, forward) > 0f)
			{
				val7 = -val7;
			}
		}
		float num10 = 0.015f;
		float num11 = Mathf.Round(num4 / 2f) * 2f;
		float num12 = Mathf.Round(num5 / 2f) * 2f;
		float num13 = num11 - radiusMeters;
		float num14 = num11 + radiusMeters;
		float num15 = num12 - radiusMeters;
		float num16 = num12 + radiusMeters;
		int num17 = 12;
		float num18 = (num14 - num13) / (float)num17;
		float num19 = (num16 - num15) / (float)num17;
		int count = s_vertices.Count;
		Vector3 val8 = default(Vector3);
		for (int i = 0; i <= num17; i++)
		{
			float num20 = num15 + (float)i * num19;
			for (int j = 0; j <= num17; j++)
			{
				float num21 = num13 + (float)j * num18;
				if (num2 >= num && num2 >= num3)
				{
					((Vector3)(ref val8))..ctor(num21, num7, num20);
				}
				else if (num3 >= num && num3 >= num2)
				{
					((Vector3)(ref val8))..ctor(num21, num20, num7);
				}
				else
				{
					((Vector3)(ref val8))..ctor(num7, num20, num21);
				}
				Vector3 item = transform.TransformPoint(val8) + val7 * num10;
				s_vertices.Add(item);
				s_uvs.Add(new Vector2(num21 / gridSize, num20 / gridSize));
				float num22 = Mathf.Sqrt((num21 - num4) * (num21 - num4) + (num20 - num5) * (num20 - num5));
				float num23 = Mathf.Clamp01(1f - num22 / radiusMeters);
				num23 *= num23;
				s_colors.Add(new Color(gridColor.r, gridColor.g, gridColor.b, gridColor.a * num23));
			}
		}
		int num24 = num17 + 1;
		for (int k = 0; k < num17; k++)
		{
			for (int l = 0; l < num17; l++)
			{
				int num25 = count + k * num24 + l;
				int item2 = num25 + 1;
				int num26 = count + (k + 1) * num24 + l;
				int item3 = num26 + 1;
				s_triangles.Add(num25);
				s_triangles.Add(num26);
				s_triangles.Add(item2);
				s_triangles.Add(item2);
				s_triangles.Add(num26);
				s_triangles.Add(item3);
				s_triangles.Add(num25);
				s_triangles.Add(item2);
				s_triangles.Add(num26);
				s_triangles.Add(item2);
				s_triangles.Add(item3);
				s_triangles.Add(num26);
			}
		}
		Vector3 center = snappedWorldPoint + val7 * (num10 + 0.003f);
		Vector3 val9 = transform.TransformDirection(val3);
		Vector3 normalized = ((Vector3)(ref val9)).normalized;
		Vector3 val10 = transform.TransformDirection(val4);
		Vector3 normalized2 = ((Vector3)(ref val10)).normalized;
		float size = Mathf.Clamp(gridSize * 0.35f, 0.06f, 0.14f);
		AddSnapIndicator(center, normalized, normalized2, size, activeNodeColor);
		return val7;
	}

	private static void BuildTerrainPlane(Vector3 hitPoint, Vector3 snappedWorldPoint, float gridSize, float radiusMeters, Color gridColor, Color activeNodeColor)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: 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_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_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: 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_016c: 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)
		Vector3 up = Vector3.up;
		float num = 0.015f;
		float num2 = Mathf.Round(hitPoint.x / 2f) * 2f;
		float num3 = Mathf.Round(hitPoint.z / 2f) * 2f;
		float num4 = num2 - radiusMeters;
		float num5 = num2 + radiusMeters;
		float num6 = num3 - radiusMeters;
		float num7 = num3 + radiusMeters;
		int num8 = 12;
		float num9 = (num5 - num4) / (float)num8;
		float num10 = (num7 - num6) / (float)num8;
		int count = s_vertices.Count;
		Vector3 item = default(Vector3);
		for (int i = 0; i <= num8; i++)
		{
			float num11 = num6 + (float)i * num10;
			for (int j = 0; j <= num8; j++)
			{
				float num12 = num4 + (float)j * num9;
				float num13 = 0f;
				if ((Object)(object)ZoneSystem.instance != (Object)null)
				{
					num13 = ZoneSystem.instance.GetGroundHeight(new Vector3(num12, 0f, num11));
				}
				((Vector3)(ref item))..ctor(num12, num13 + num, num11);
				s_vertices.Add(item);
				s_uvs.Add(new Vector2(num12 / gridSize, num11 / gridSize));
				float num14 = Mathf.Sqrt((num12 - hitPoint.x) * (num12 - hitPoint.x) + (num11 - hitPoint.z) * (num11 - hitPoint.z));
				float num15 = Mathf.Clamp01(1f - num14 / radiusMeters);
				num15 *= num15;
				s_colors.Add(new Color(gridColor.r, gridColor.g, gridColor.b, gridColor.a * num15));
			}
		}
		int num16 = num8 + 1;
		for (int k = 0; k < num8; k++)
		{
			for (int l = 0; l < num8; l++)
			{
				int num17 = count + k * num16 + l;
				int item2 = num17 + 1;
				int num18 = count + (k + 1) * num16 + l;
				int item3 = num18 + 1;
				s_triangles.Add(num17);
				s_triangles.Add(num18);
				s_triangles.Add(item2);
				s_triangles.Add(item2);
				s_triangles.Add(num18);
				s_triangles.Add(item3);
				s_triangles.Add(num17);
				s_triangles.Add(item2);
				s_triangles.Add(num18);
				s_triangles.Add(item2);
				s_triangles.Add(item3);
				s_triangles.Add(num18);
			}
		}
		Vector3 center = snappedWorldPoint + up * (num + 0.003f);
		float size = Mathf.Clamp(gridSize * 0.35f, 0.07f, 0.16f);
		AddSnapIndicator(center, Vector3.right, Vector3.forward, size, activeNodeColor);
	}

	private static void BuildFootprintOnly(GameObject ghost, Vector3 baseSnappedPos, Vector3 worldNormal, float gridSize, Color footprintColor)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: 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_0147: 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_014c: 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)
		Piece component = ghost.GetComponent<Piece>();
		if (!((Object)(object)component == (Object)null))
		{
			GetGhostFootprint(component, out var minXZ, out var maxXZ);
			float num = 0.006f;
			Color fillColor = default(Color);
			((Color)(ref fillColor))..ctor(footprintColor.r, footprintColor.g, footprintColor.b, footprintColor.a * 0.12f);
			float lineWidth = 0.012f;
			Vector3 w = baseSnappedPos + ghost.transform.rotation * new Vector3(minXZ.x, 0f, minXZ.y) + worldNormal * num;
			Vector3 w2 = baseSnappedPos + ghost.transform.rotation * new Vector3(maxXZ.x, 0f, minXZ.y) + worldNormal * num;
			Vector3 w3 = baseSnappedPos + ghost.transform.rotation * new Vector3(maxXZ.x, 0f, maxXZ.y) + worldNormal * num;
			Vector3 w4 = baseSnappedPos + ghost.transform.rotation * new Vector3(minXZ.x, 0f, maxXZ.y) + worldNormal * num;
			AddFootprintQuad(w, w2, w3, w4, worldNormal, lineWidth, footprintColor, fillColor);
		}
	}

	private static void GetGhostFootprint(Piece ghostPiece, out Vector2 minXZ, out Vector2 maxXZ)
	{
		//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_000a: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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_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)
		Bounds pieceLocalBounds = GetPieceLocalBounds(ghostPiece);
		minXZ = new Vector2(((Bounds)(ref pieceLocalBounds)).min.x, ((Bounds)(ref pieceLocalBounds)).min.z);
		maxXZ = new Vector2(((Bounds)(ref pieceLocalBounds)).max.x, ((Bounds)(ref pieceLocalBounds)).max.z);
	}

	private static void AddFootprintQuad(Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, Vector3 normal, float lineWidth, Color lineColor, Color fillColor)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_001c: 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_0027: 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_0029: 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_0044: 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_005a: 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_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: 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)
		AddLineQuad(w0, w1, normal, lineWidth, lineColor);
		AddLineQuad(w1, w2, normal, lineWidth, lineColor);
		AddLineQuad(w2, w3, normal, lineWidth, lineColor);
		AddLineQuad(w3, w0, normal, lineWidth, lineColor);
		int count = s_vertices.Count;
		s_vertices.Add(w0);
		s_vertices.Add(w1);
		s_vertices.Add(w2);
		s_vertices.Add(w3);
		s_uvs.Add(new Vector2(0.5f, 0.5f));
		s_uvs.Add(new Vector2(0.5f, 0.5f));
		s_uvs.Add(new Vector2(0.5f, 0.5f));
		s_uvs.Add(new Vector2(0.5f, 0.5f));
		s_colors.Add(fillColor);
		s_colors.Add(fillColor);
		s_colors.Add(fillColor);
		s_colors.Add(fillColor);
		s_triangles.Add(count);
		s_triangles.Add(count + 1);
		s_triangles.Add(count + 2);
		s_triangles.Add(count);
		s_triangles.Add(count + 2);
		s_triangles.Add(count + 3);
		s_triangles.Add(count);
		s_triangles.Add(count + 2);
		s_triangles.Add(count + 1);
		s_triangles.Add(count);
		s_triangles.Add(count + 3);
		s_triangles.Add(count + 2);
	}

	private static void AddLineQuad(Vector3 start, Vector3 end, Vector3 normal, float width, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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_002c: 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_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_0050: 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_0060: 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_0070: 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_0072: 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_0083: 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_00b5: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = end - start;
		float magnitude = ((Vector3)(ref val)).magnitude;
		if (!(magnitude < 0.0001f))
		{
			val /= magnitude;
			Vector3 val2 = Vector3.Cross(normal, val);
			Vector3 val3 = ((Vector3)(ref val2)).normalized * (width * 0.5f);
			int count = s_vertices.Count;
			s_vertices.Add(start - val3);
			s_vertices.Add(start + val3);
			s_vertices.Add(end + val3);
			s_vertices.Add(end - val3);
			s_uvs.Add(new Vector2(0.5f, 0.5f));
			s_uvs.Add(new Vector2(0.5f, 0.5f));
			s_uvs.Add(new Vector2(0.5f, 0.5f));
			s_uvs.Add(new Vector2(0.5f, 0.5f));
			s_colors.Add(color);
			s_colors.Add(color);
			s_colors.Add(color);
			s_colors.Add(color);
			s_triangles.Add(count);
			s_triangles.Add(count + 1);
			s_triangles.Add(count + 2);
			s_triangles.Add(count);
			s_triangles.Add(count + 2);
			s_triangles.Add(count + 3);
			s_triangles.Add(count);
			s_triangles.Add(count + 2);
			s_triangles.Add(count + 1);
			s_triangles.Add(count);
			s_triangles.Add(count + 3);
			s_triangles.Add(count + 2);
		}
	}

	private static void AddSnapIndicator(Vector3 center, Vector3 uAxis, Vector3 vAxis, float size, Color color)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_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_0016: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: 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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_003f: 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_005d: 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_0073: 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_00a2: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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_0107: Unknown result type (might be due to invalid IL or missing references)
		float num = size * 0.5f;
		Vector3 item = center + vAxis * num;
		Vector3 item2 = center - vAxis * num;
		Vector3 item3 = center + uAxis * num;
		Vector3 item4 = center - uAxis * num;
		int count = s_vertices.Count;
		s_vertices.Add(item);
		s_vertices.Add(item3);
		s_vertices.Add(item2);
		s_vertices.Add(item4);
		s_uvs.Add(new Vector2(0f, 0.5f));
		s_uvs.Add(new Vector2(0.5f, 0f));
		s_uvs.Add(new Vector2(0f, -0.5f));
		s_uvs.Add(new Vector2(-0.5f, 0f));
		s_colors.Add(color);
		s_colors.Add(color);
		s_colors.Add(color);
		s_colors.Add(color);
		s_triangles.Add(count);
		s_triangles.Add(count + 1);
		s_triangles.Add(count + 2);
		s_triangles.Add(count);
		s_triangles.Add(count + 2);
		s_triangles.Add(count + 3);
		s_triangles.Add(count);
		s_triangles.Add(count + 2);
		s_triangles.Add(count + 1);
		s_triangles.Add(count);
		s_triangles.Add(count + 3);
		s_triangles.Add(count + 2);
	}

	public static void Hide()
	{
		//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_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 ((Object)(object)s_visualizerObject != (Object)null && s_isVisible)
		{
			s_visualizerObject.SetActive(false);
			s_isVisible = false;
			s_lastPieceTransform = null;
			s_lastSnappedPoint = Vector3.negativeInfinity;
			s_lastGridCenter = Vector3.negativeInfinity;
			s_boundsCache.Clear();
		}
	}

	public static void Destroy()
	{
		s_boundsCache.Clear();
		if ((Object)(object)s_visualizerObject != (Object)null)
		{
			Object.Destroy((Object)(object)s_visualizerObject);
			s_visualizerObject = null;
		}
		if ((Object)(object)s_gridMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)s_gridMaterial);
			s_gridMaterial = null;
		}
		if ((Object)(object)s_proceduralGridTexture != (Object)null)
		{
			Object.Destroy((Object)(object)s_proceduralGridTexture);
			s_proceduralGridTexture = null;
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
public static class PlayerPlacementPatch
{
	private static readonly FieldInfo s_placementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

	private static readonly FieldInfo s_manualSnapPointField = AccessTools.Field(typeof(Player), "m_manualSnapPoint");

	private static readonly FieldInfo s_tempSnapPoints1Field = AccessTools.Field(typeof(Player), "m_tempSnapPoints1");

	private static readonly FieldInfo s_tempPiecesField = AccessTools.Field(typeof(Player), "m_tempPieces");

	private static MethodInfo s_pieceRayTestMethod;

	private static readonly object[] s_rayArgs = new object[6];

	private static readonly MethodInfo s_setPlacementGhostValidMethod = AccessTools.Method(typeof(Player), "SetPlacementGhostValid", new Type[1] { typeof(bool) }, (Type[])null);

	private static readonly object[] s_ghostValidFalseArgs = new object[1] { false };

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

	public static float SnapCoordinate(float val, float gridSize, bool snapToCenter)
	{
		if (snapToCenter)
		{
			return (Mathf.Floor(val / gridSize) + 0.5f) * gridSize;
		}
		return Mathf.Round(val / gridSize) * gridSize;
	}

	private static bool InitReflection()
	{
		if (s_pieceRayTestMethod == null)
		{
			s_pieceRayTestMethod = AccessTools.Method(typeof(Player), "PieceRayTest", new Type[6]
			{
				typeof(Vector3).MakeByRefType(),
				typeof(Vector3).MakeByRefType(),
				typeof(Piece).MakeByRefType(),
				typeof(Heightmap).MakeByRefType(),
				typeof(Collider).MakeByRefType(),
				typeof(bool)
			}, (Type[])null);
		}
		return s_pieceRayTestMethod != null;
	}

	[HarmonyPostfix]
	public static void Postfix(Player __instance, bool flashGuardStone)
	{
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Expected O, but got Unknown
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Expected O, but got Unknown
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: 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_04dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_051b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0520: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0500: Unknown result type (might be due to invalid IL or missing references)
		//IL_0502: Unknown result type (might be due to invalid IL or missing references)
		//IL_0504: 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_0512: Unknown result type (might be due to invalid IL or missing references)
		//IL_0514: Unknown result type (might be due to invalid IL or missing references)
		//IL_0519: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_062c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0654: Unknown result type (might be due to invalid IL or missing references)
		//IL_0656: Unknown result type (might be due to invalid IL or missing references)
		//IL_0658: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_058e: Unknown result type (might be due to invalid IL or missing references)
		//IL_059c: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_042d: Unknown result type (might be due to invalid IL or missing references)
		//IL_041f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0446: Unknown result type (might be due to invalid IL or missing references)
		//IL_044d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0452: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: 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_0456: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0463: Unknown result type (might be due to invalid IL or missing references)
		//IL_0468: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0471: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
		if (!BuildGridPlugin.ModEnabled.Value || !BuildGridPlugin.IsGridActive)
		{
			GridRenderer.Hide();
			return;
		}
		GameObject val = null;
		if (s_placementGhostField != null)
		{
			object? value = s_placementGhostField.GetValue(__instance);
			val = (GameObject)((value is GameObject) ? value : null);
		}
		if ((Object)(object)val == (Object)null)
		{
			GridRenderer.Hide();
			return;
		}
		Piece component = val.GetComponent<Piece>();
		if ((Object)(object)component == (Object)null)
		{
			GridRenderer.Hide();
		}
		else
		{
			if (!InitReflection())
			{
				return;
			}
			bool flag = HasNativeSnapPoints(component);
			if (!BuildGridPlugin.SnapAllPieces.Value && flag)
			{
				List<Piece> list = null;
				if (s_tempPiecesField != null)
				{
					list = s_tempPiecesField.GetValue(__instance) as List<Piece>;
				}
				if (list != null && list.Count > 0)
				{
					GridRenderer.Hide();
					return;
				}
			}
			bool flag2 = component.m_waterPiece || !component.m_noInWater;
			s_rayArgs[0] = Vector3.zero;
			s_rayArgs[1] = Vector3.zero;
			s_rayArgs[2] = null;
			s_rayArgs[3] = null;
			s_rayArgs[4] = null;
			s_rayArgs[5] = flag2;
			if (!(bool)s_pieceRayTestMethod.Invoke(__instance, s_rayArgs))
			{
				GridRenderer.Hide();
				return;
			}
			Vector3 val2 = (Vector3)s_rayArgs[0];
			Vector3 val3 = (Vector3)s_rayArgs[1];
			Piece val4 = (Piece)s_rayArgs[2];
			_ = (Heightmap)s_rayArgs[3];
			Collider collider = (Collider)s_rayArgs[4];
			float currentGridSize = BuildGridPlugin.CurrentGridSize;
			Vector3 up = Vector3.up;
			Vector3 val9 = default(Vector3);
			if ((Object)(object)val4 != (Object)null)
			{
				Transform transform = ((Component)val4).transform;
				Vector3 val5 = transform.InverseTransformPoint(val2);
				Vector3 val6 = transform.InverseTransformDirection(val3);
				Bounds pieceLocalBounds = GridRenderer.GetPieceLocalBounds(val4);
				bool flag3 = ((Bounds)(ref pieceLocalBounds)).size.y > 1.2f && (((Bounds)(ref pieceLocalBounds)).size.z < 0.8f || ((Bounds)(ref pieceLocalBounds)).size.x < 0.8f) && val5.y < ((Bounds)(ref pieceLocalBounds)).max.y - 0.15f;
				float num = Mathf.Abs(val6.x);
				float num2 = Mathf.Abs(val6.y);
				float num3 = Mathf.Abs(val6.z);
				if (flag3)
				{
					num2 = 0f;
				}
				bool isSnapToCenter = BuildGridPlugin.IsSnapToCenter;
				Vector3 val7 = default(Vector3);
				Vector3 val8;
				if (num2 >= num && num2 >= num3)
				{
					float num4 = SnapCoordinate(val5.x, currentGridSize, isSnapToCenter);
					float num5 = SnapCoordinate(val5.z, currentGridSize, isSnapToCenter);
					float num6 = ((val6.y >= 0f) ? 1f : (-1f));
					float num7 = ((num6 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.y : ((Bounds)(ref pieceLocalBounds)).min.y);
					((Vector3)(ref val7))..ctor(num4, num7, num5);
					val8 = Vector3.up * num6;
				}
				else if (num3 >= num && num3 >= num2)
				{
					float num8 = SnapCoordinate(val5.x, currentGridSize, isSnapToCenter);
					float num9 = SnapCoordinate(val5.y, currentGridSize, isSnapToCenter);
					float num10 = ((Mathf.Abs(val6.z) > 0.1f) ? Mathf.Sign(val6.z) : ((val5.z >= ((Bounds)(ref pieceLocalBounds)).center.z) ? 1f : (-1f)));
					float num11 = ((num10 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.z : ((Bounds)(ref pieceLocalBounds)).min.z);
					((Vector3)(ref val7))..ctor(num8, num9, num11);
					val8 = Vector3.forward * num10;
				}
				else
				{
					float num12 = SnapCoordinate(val5.z, currentGridSize, isSnapToCenter);
					float num13 = SnapCoordinate(val5.y, currentGridSize, isSnapToCenter);
					float num14 = ((Mathf.Abs(val6.x) > 0.1f) ? Mathf.Sign(val6.x) : ((val5.x >= ((Bounds)(ref pieceLocalBounds)).center.x) ? 1f : (-1f)));
					float num15 = ((num14 > 0f) ? ((Bounds)(ref pieceLocalBounds)).max.x : ((Bounds)(ref pieceLocalBounds)).min.x);
					((Vector3)(ref val7))..ctor(num15, num13, num12);
					val8 = Vector3.right * num14;
				}
				val9 = transform.TransformPoint(val7);
				Vector3 val10 = transform.TransformDirection(val8);
				up = ((Vector3)(ref val10)).normalized;
			}
			else
			{
				bool isSnapToCenter2 = BuildGridPlugin.IsSnapToCenter;
				float num16 = SnapCoordinate(val2.x, currentGridSize, isSnapToCenter2);
				float num17 = SnapCoordinate(val2.z, currentGridSize, isSnapToCenter2);
				float num18 = val2.y;
				if ((Object)(object)ZoneSystem.instance != (Object)null)
				{
					num18 = ZoneSystem.instance.GetGroundHeight(new Vector3(num16, 0f, num17));
				}
				((Vector3)(ref val9))..ctor(num16, num18, num17);
				up = Vector3.up;
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				Vector3 forward = ((Component)Camera.main).transform.forward;
				if (Vector3.Dot(up, forward) > 0f)
				{
					up = -up;
				}
			}
			Vector3 val11 = Vector3.zero;
			bool flag4 = false;
			if (s_manualSnapPointField != null && s_tempSnapPoints1Field != null)
			{
				int num19 = (int)s_manualSnapPointField.GetValue(__instance);
				List<Transform> list2 = s_tempSnapPoints1Field.GetValue(__instance) as List<Transform>;
				if (num19 >= 0 && list2 != null && num19 < list2.Count && (Object)(object)list2[num19] != (Object)null)
				{
					val11 = val.transform.rotation * -list2[num19].localPosition;
					flag4 = true;
				}
			}
			if (!flag4)
			{
				val11 = CalculateSurfaceAlignmentOffset(val, val9, up, val.transform.rotation);
			}
			val.transform.position = val9 + val11;
			if (Location.IsInsideNoBuildLocation(val.transform.position))
			{
				SetPlacementGhostValid(__instance, valid: false);
			}
			else
			{
				PrivateArea component2 = ((Component)component).GetComponent<PrivateArea>();
				float num20 = (((Object)(object)component2 != (Object)null) ? component2.m_radius : 0f);
				bool flag5 = (Object)(object)component2 != (Object)null;
				if (!PrivateArea.CheckAccess(val.transform.position, num20, flashGuardStone, flag5))
				{
					SetPlacementGhostValid(__instance, valid: false);
				}
			}
			if (BuildGridPlugin.ShowVisualGrid.Value)
			{
				GridRenderer.UpdateGrid(val4, collider, val2, val3, val9, currentGridSize, val);
			}
			else
			{
				GridRenderer.Hide();
			}
		}
	}

	private static void SetPlacementGhostValid(Player player, bool valid)
	{
		if (s_setPlacementGhostValidMethod != null && (Object)(object)player != (Object)null)
		{
			s_ghostValidFalseArgs[0] = valid;
			s_setPlacementGhostValidMethod.Invoke(player, s_ghostValidFalseArgs);
		}
	}

	public static Vector3 CalculateSurfaceAlignmentOffset(GameObject ghost, Vector3 targetPoint, Vector3 normal, Quaternion rot)
	{
		//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_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_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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		s_ghostCollidersList.Clear();
		ghost.GetComponentsInChildren<Collider>(false, s_ghostCollidersList);
		if (s_ghostCollidersList.Count == 0)
		{
			return Vector3.zero;
		}
		Transform transform = ghost.transform;
		Vector3 position = transform.position;
		Quaternion rotation = transform.rotation;
		transform.position = targetPoint + normal * 50f;
		transform.rotation = rot;
		Vector3 val = Vector3.zero;
		float num = 999999f;
		for (int i = 0; i < s_ghostCollidersList.Count; i++)
		{
			Collider val2 = s_ghostCollidersList[i];
			if ((Object)(object)val2 == (Object)null || val2.isTrigger || !val2.enabled)
			{
				continue;
			}
			MeshCollider val3 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
			if (!((Object)(object)val3 != (Object)null) || val3.convex)
			{
				Vector3 val4 = val2.ClosestPoint(targetPoint);
				float num2 = Vector3.Distance(val4, targetPoint);
				if (num2 < num)
				{
					val = val4;
					num = num2;
				}
			}
		}
		s_ghostCollidersList.Clear();
		Vector3 result;
		if (num < 999990f)
		{
			result = transform.position - val;
		}
		else
		{
			Piece component = ghost.GetComponent<Piece>();
			Bounds pieceLocalBounds = GridRenderer.GetPieceLocalBounds(component);
			float num3 = Mathf.Abs(Vector3.Dot(rot * ((Bounds)(ref pieceLocalBounds)).extents, normal));
			result = normal * num3;
		}
		transform.position = position;
		transform.rotation = rotation;
		return result;
	}

	private static bool HasNativeSnapPoints(Piece piece)
	{
		if ((Object)(object)piece == (Object)null)
		{
			return false;
		}
		Transform transform = ((Component)piece).transform;
		int childCount = transform.childCount;
		for (int i = 0; i < childCount; i++)
		{
			if (((Component)transform.GetChild(i)).CompareTag("snappoint"))
			{
				return true;
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(KeyHints), "UpdateHints")]
public static class KeyHintsPatch
{
	private static GameObject s_hintObject;

	private static TextMeshProUGUI s_hintText;

	private static readonly FieldInfo s_buildHintsField = AccessTools.Field(typeof(KeyHints), "m_buildHints");

	private static readonly FieldInfo s_buildRotateKeyField = AccessTools.Field(typeof(KeyHints), "m_buildRotateKey");

	[HarmonyPostfix]
	public static void Postfix(KeyHints __instance)
	{
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		if (!BuildGridPlugin.ModEnabled.Value || !BuildGridPlugin.ShowKeyHints.Value)
		{
			if ((Object)(object)s_hintObject != (Object)null && s_hintObject.activeSelf)
			{
				s_hintObject.SetActive(false);
			}
		}
		else
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			GameObject val = (GameObject)((s_buildHintsField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
			{
				if ((Object)(object)s_hintObject != (Object)null && s_hintObject.activeSelf)
				{
					s_hintObject.SetActive(false);
				}
				return;
			}
			if ((Object)(object)s_hintObject == (Object)null || (Object)(object)s_hintText == (Object)null)
			{
				s_hintObject = null;
				s_hintText = null;
				EnsureHintUI(__instance, val);
			}
			if ((Object)(object)s_hintText != (Object)null)
			{
				((TMP_Text)s_hintText).text = BuildGridLocalization.CompactKeyHint(((object)BuildGridPlugin.ToggleGridKey.Value).ToString(), ((object)BuildGridPlugin.CycleGridSizeKey.Value).ToString(), ((object)BuildGridPlugin.CycleRotationKey.Value).ToString(), ((object)BuildGridPlugin.ToggleSnapTargetKey.Value).ToString(), BuildGridPlugin.IsGridActive, BuildGridPlugin.CurrentGridSize, BuildGridPlugin.CurrentRotationDegrees, BuildGridPlugin.IsSnapToCenter);
				if (!s_hintObject.activeSelf)
				{
					s_hintObject.SetActive(true);
				}
			}
		}
	}

	private static void EnsureHintUI(KeyHints keyHints, GameObject buildHints)
	{
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)s_hintObject == (Object)null) || !((Object)(object)buildHints != (Object)null))
		{
			return;
		}
		TextMeshProUGUI val = (TextMeshProUGUI)((s_buildRotateKeyField != null) ? /*isinst with value type is only supported in some contexts*/: null);
		if ((Object)(object)val != (Object)null)
		{
			Transform val2 = (((Object)(object)buildHints.transform.parent != (Object)null) ? buildHints.transform.parent : buildHints.transform);
			s_hintObject = Object.Instantiate<GameObject>(((Component)val).gameObject, val2);
			((Object)s_hintObject).name = "BuildGrid_KeyHintBar";
			LayoutElement component = s_hintObject.GetComponent<LayoutElement>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			for (int num = s_hintObject.transform.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)s_hintObject.transform.GetChild(num)).gameObject);
			}
			RectTransform component2 = s_hintObject.GetComponent<RectTransform>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.anchorMin = new Vector2(0.5f, 0f);
				component2.anchorMax = new Vector2(0.5f, 0f);
				component2.pivot = new Vector2(0.5f, 0f);
				component2.sizeDelta = new Vector2(950f, 30f);
				RectTransform component3 = buildHints.GetComponent<RectTransform>();
				float num2 = (((Object)(object)component3 != (Object)null) ? (component3.anchoredPosition.y + 65f) : 70f);
				component2.anchoredPosition = new Vector2(0f, num2);
			}
			s_hintText = s_hintObject.GetComponent<TextMeshProUGUI>();
			if ((Object)(object)s_hintText != (Object)null)
			{
				((TMP_Text)s_hintText).fontSize = ((TMP_Text)val).fontSize * 0.9f;
				((TMP_Text)s_hintText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)s_hintText).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)s_hintText).overflowMode = (TextOverflowModes)0;
			}
		}
	}
}