Decompiled source of BuildAlignPlus v1.0.0

plugins\BuildAlignPlus.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BuildAlignPlus.Align;
using BuildAlignPlus.Localization;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("PONEIS")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Hold a key to snap build placement to neighbors or a world grid, with Satisfactory-style guide lines")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+98d7b789d470adc78991823c3a4eccda8d04f28a")]
[assembly: AssemblyProduct("BuildAlignPlus")]
[assembly: AssemblyTitle("BuildAlignPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BuildAlignPlus
{
	internal static class ModConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyCode> HoldKey;

		internal static ConfigEntry<KeyCode> ModeCycleKey;

		internal static ConfigEntry<KeyCode> GridStepKey;

		internal static ConfigEntry<float> NeighborSearchRadius;

		internal static ConfigEntry<float> SnapPull;

		internal static ConfigEntry<bool> ShowGuides;

		internal static ConfigEntry<string> DefaultMode;

		internal static ConfigEntry<string> Language;

		internal static void Bind(ConfigFile config)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			Enabled = config.Bind<bool>("General", "Enabled", true, "Master switch for BuildAlignPlus snap.");
			HoldKey = config.Bind<KeyCode>("Controls", "HoldKey", (KeyCode)308, "Hold this key while placing to activate snap. Default LeftAlt (RightAlt also works when Alt is chosen).");
			ModeCycleKey = config.Bind<KeyCode>("Controls", "ModeCycleKey", (KeyCode)288, "Press to cycle Neighbor ↔ WorldGrid.");
			GridStepKey = config.Bind<KeyCode>("Controls", "GridStepKey", (KeyCode)287, "Press to cycle world-grid step: 0.5 → 1 → 2 → 4 m.");
			NeighborSearchRadius = config.Bind<float>("Snap", "NeighborSearchRadius", 6f, new ConfigDescription("How far to search for a neighbor piece.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>()));
			SnapPull = config.Bind<float>("Snap", "SnapPull", 1.25f, new ConfigDescription("Max distance to magnetically pull the ghost onto a snap target.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>()));
			ShowGuides = config.Bind<bool>("Snap", "ShowGuides", true, "Draw Satisfactory-style guide lines while snapping.");
			DefaultMode = config.Bind<string>("Snap", "DefaultMode", "Neighbor", "Starting mode: Neighbor or WorldGrid.");
			Language = config.Bind<string>("Localization", "Language", "Auto", "Language for BuildAlignPlus messages. Auto follows the game. Values: Auto, English, Portuguese.");
			Language.SettingChanged += delegate
			{
				Loc.ApplyLanguagePreference();
			};
		}

		internal static bool IsHoldKeyDown()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = HoldKey.Value;
			if ((int)value == 308 || (int)value == 307)
			{
				if (!Input.GetKey((KeyCode)308))
				{
					return Input.GetKey((KeyCode)307);
				}
				return true;
			}
			if ((int)value == 306 || (int)value == 305)
			{
				if (!Input.GetKey((KeyCode)306))
				{
					return Input.GetKey((KeyCode)305);
				}
				return true;
			}
			if ((int)value == 304 || (int)value == 303)
			{
				if (!Input.GetKey((KeyCode)304))
				{
					return Input.GetKey((KeyCode)303);
				}
				return true;
			}
			return Input.GetKey(value);
		}

		internal static AlignMode ParseDefaultMode()
		{
			string a = DefaultMode?.Value ?? "Neighbor";
			if (string.Equals(a, "WorldGrid", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Grid", StringComparison.OrdinalIgnoreCase))
			{
				return AlignMode.WorldGrid;
			}
			return AlignMode.Neighbor;
		}
	}
	[BepInPlugin("poneis.valheim.BuildAlignPlus", "BuildAlignPlus", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "poneis.valheim.BuildAlignPlus";

		public const string PluginName = "BuildAlignPlus";

		public const string PluginVersion = "1.0.0";

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			Loc.Init();
			AlignState.Init();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "poneis.valheim.BuildAlignPlus");
			((Component)this).gameObject.AddComponent<AlignInputListener>();
			Log.LogInfo((object)"BuildAlignPlus 1.0.0 loaded.");
		}
	}
	internal sealed class AlignInputListener : MonoBehaviour
	{
		private void Update()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.Enabled.Value)
			{
				GuideRenderer.Hide();
			}
			else
			{
				if (Console.IsVisible())
				{
					return;
				}
				try
				{
					if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
					{
						return;
					}
				}
				catch
				{
				}
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer != (Object)null) || !((Character)localPlayer).InPlaceMode() || !((Object)(object)localPlayer.m_placementGhost != (Object)null))
				{
					GuideRenderer.Hide();
					return;
				}
				if (ZInput.GetKeyDown(ModConfig.ModeCycleKey.Value, true))
				{
					AlignState.CycleMode();
					((Character)localPlayer).Message((MessageType)1, AlignState.GetHudText(), 0, (Sprite)null, false);
				}
				if (ZInput.GetKeyDown(ModConfig.GridStepKey.Value, true))
				{
					AlignState.CycleGridStep();
					if (AlignState.Mode == AlignMode.WorldGrid)
					{
						((Character)localPlayer).Message((MessageType)1, AlignState.GetHudText(), 0, (Sprite)null, false);
					}
				}
				if (!ModConfig.IsHoldKeyDown())
				{
					GuideRenderer.Hide();
				}
			}
		}
	}
}
namespace BuildAlignPlus.Patches
{
	[HarmonyPatch]
	internal static class PlacementGhostPatch
	{
		private static float _nextHud;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		private static void UpdatePlacementGhostPostfix(Player __instance)
		{
			//IL_0065: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_010c: 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_0120: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_018e: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.Enabled.Value || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).InPlaceMode() || (Object)(object)__instance.m_placementGhost == (Object)null || !__instance.m_placementGhost.activeInHierarchy || !ModConfig.IsHoldKeyDown())
			{
				return;
			}
			Piece selectedPiece = __instance.GetSelectedPiece();
			GameObject placementGhost = __instance.m_placementGhost;
			Vector3 position = placementGhost.transform.position;
			bool flag = false;
			if (AlignState.Mode == AlignMode.Neighbor)
			{
				NeighborSnapService.SnapResult snapResult = NeighborSnapService.TrySnap(__instance, placementGhost, selectedPiece);
				if (snapResult.Snapped)
				{
					position = snapResult.Position;
					flag = true;
					if (snapResult.HasGuide)
					{
						GuideRenderer.ShowBoundsEdge(snapResult.RefBounds, snapResult.GuideA, snapResult.GuideB);
					}
					else
					{
						GuideRenderer.Hide();
					}
				}
				else
				{
					GuideRenderer.Hide();
				}
			}
			else
			{
				WorldGridSnapService.SnapResult snapResult2 = WorldGridSnapService.TrySnap(placementGhost, selectedPiece);
				if (snapResult2.Snapped)
				{
					position = snapResult2.Position;
					flag = true;
					if (snapResult2.HasGuide)
					{
						float gridStep = AlignState.GridStep;
						Vector3 val = position;
						GuideRenderer.Show(new Vector3(val.x - gridStep, val.y + 0.05f, val.z), new Vector3(val.x + gridStep, val.y + 0.05f, val.z), (Vector3?)new Vector3(val.x, val.y + 0.05f, val.z - gridStep), (Vector3?)new Vector3(val.x, val.y + 0.05f, val.z + gridStep));
					}
				}
				else
				{
					GuideRenderer.Hide();
				}
			}
			if (!flag)
			{
				return;
			}
			placementGhost.transform.position = position;
			if ((Object)(object)__instance.m_placementMarkerInstance != (Object)null)
			{
				Vector3 position2 = __instance.m_placementMarkerInstance.transform.position;
				position2.x = position.x;
				position2.z = position.z;
				if (!BoundsUtil.PreserveFloorY(selectedPiece))
				{
					position2.y = position.y;
				}
				__instance.m_placementMarkerInstance.transform.position = position2;
			}
			if (Time.time >= _nextHud)
			{
				_nextHud = Time.time + 1.25f;
				((Character)__instance).Message((MessageType)1, AlignState.GetHudText(), 0, (Sprite)null, false);
			}
		}
	}
}
namespace BuildAlignPlus.Localization
{
	internal static class Loc
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Tables = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private static string _activeCode = "en";

		private static string LangDir => Path.Combine(Paths.ConfigPath, "BuildAlignPlus", "lang");

		internal static void Init()
		{
			EnsureLangFolder();
			LoadEmbedded("en");
			LoadEmbedded("pt");
			LoadDiskOverrides();
			ApplyLanguagePreference();
			Plugin.Log.LogInfo((object)("Localization ready (active=" + _activeCode + ", files in " + LangDir + ")"));
		}

		internal static string T(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return key;
			}
			if (Tables.TryGetValue(_activeCode, out var value) && value.TryGetValue(key, out var value2))
			{
				return value2;
			}
			if (Tables.TryGetValue("en", out var value3) && value3.TryGetValue(key, out value2))
			{
				return value2;
			}
			return key;
		}

		internal static string Tf(string key, params object[] args)
		{
			try
			{
				return string.Format(T(key), args);
			}
			catch (FormatException)
			{
				return T(key);
			}
		}

		private static void EnsureLangFolder()
		{
			Directory.CreateDirectory(LangDir);
			WriteEmbedded("en");
			WriteEmbedded("pt");
		}

		private static void WriteEmbedded(string code)
		{
			string path = Path.Combine(LangDir, code + ".json");
			string text = ReadEmbedded(code);
			if (!string.IsNullOrEmpty(text))
			{
				File.WriteAllText(path, text, Encoding.UTF8);
			}
		}

		private static void LoadEmbedded(string code)
		{
			string text = ReadEmbedded(code);
			if (!string.IsNullOrEmpty(text))
			{
				Tables[code] = ParseFlatJson(text);
			}
		}

		private static void LoadDiskOverrides()
		{
			if (!Directory.Exists(LangDir))
			{
				return;
			}
			string[] files = Directory.GetFiles(LangDir, "*.json");
			foreach (string text in files)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
				try
				{
					Dictionary<string, string> dictionary = ParseFlatJson(File.ReadAllText(text, Encoding.UTF8));
					if (dictionary.Count == 0)
					{
						continue;
					}
					if (!Tables.TryGetValue(fileNameWithoutExtension, out var value))
					{
						Tables[fileNameWithoutExtension] = dictionary;
						continue;
					}
					foreach (KeyValuePair<string, string> item in dictionary)
					{
						value[item.Key] = item.Value;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Failed to load lang file " + text + ": " + ex.Message));
				}
			}
		}

		private static string ReadEmbedded(string code)
		{
			string text = "BuildAlignPlus.Languages." + code + ".json";
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
			if (stream == null)
			{
				Plugin.Log.LogWarning((object)("Missing embedded language resource: " + text));
				return null;
			}
			using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			return streamReader.ReadToEnd();
		}

		internal static void ApplyLanguagePreference()
		{
			string a = ModConfig.Language?.Value ?? "Auto";
			if (string.Equals(a, "Portuguese", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "pt", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "pt-BR", StringComparison.OrdinalIgnoreCase))
			{
				_activeCode = (Tables.ContainsKey("pt") ? "pt" : "en");
				return;
			}
			if (string.Equals(a, "English", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "en", StringComparison.OrdinalIgnoreCase))
			{
				_activeCode = "en";
				return;
			}
			try
			{
				string text = ((Localization.instance != null) ? Localization.instance.GetSelectedLanguage() : null);
				if (!string.IsNullOrEmpty(text) && (text.IndexOf("Portuguese", StringComparison.OrdinalIgnoreCase) >= 0 || text.StartsWith("pt", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Brazil", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					_activeCode = (Tables.ContainsKey("pt") ? "pt" : "en");
					return;
				}
			}
			catch
			{
			}
			_activeCode = "en";
		}

		internal static Dictionary<string, string> ParseFlatJson(string json)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			if (string.IsNullOrWhiteSpace(json))
			{
				return dictionary;
			}
			int i = 0;
			SkipWs(json, ref i);
			if (i >= json.Length || json[i] != '{')
			{
				return dictionary;
			}
			i++;
			while (i < json.Length)
			{
				SkipWs(json, ref i);
				if (i < json.Length && json[i] == '}')
				{
					break;
				}
				if (i < json.Length && json[i] == ',')
				{
					i++;
					continue;
				}
				if (!TryReadString(json, ref i, out var value))
				{
					break;
				}
				SkipWs(json, ref i);
				if (i >= json.Length || json[i] != ':')
				{
					break;
				}
				i++;
				SkipWs(json, ref i);
				if (!TryReadString(json, ref i, out var value2))
				{
					break;
				}
				dictionary[value] = value2;
			}
			return dictionary;
		}

		private static void SkipWs(string s, ref int i)
		{
			while (i < s.Length && char.IsWhiteSpace(s[i]))
			{
				i++;
			}
		}

		private static bool TryReadString(string s, ref int i, out string value)
		{
			value = null;
			SkipWs(s, ref i);
			if (i >= s.Length || s[i] != '"')
			{
				return false;
			}
			i++;
			StringBuilder stringBuilder = new StringBuilder();
			while (i < s.Length)
			{
				char c = s[i++];
				switch (c)
				{
				case '"':
					value = stringBuilder.ToString();
					return true;
				case '\\':
					if (i < s.Length)
					{
						char c2 = s[i++];
						StringBuilder stringBuilder2 = stringBuilder;
						stringBuilder2.Append(c2 switch
						{
							'n' => '\n', 
							'r' => '\r', 
							't' => '\t', 
							'"' => '"', 
							'\\' => '\\', 
							_ => c2, 
						});
						continue;
					}
					break;
				}
				stringBuilder.Append(c);
			}
			return false;
		}
	}
}
namespace BuildAlignPlus.Align
{
	internal enum AlignMode
	{
		Neighbor,
		WorldGrid
	}
	internal static class AlignState
	{
		private static readonly float[] GridSteps = new float[4] { 0.5f, 1f, 2f, 4f };

		internal static AlignMode Mode { get; private set; } = AlignMode.Neighbor;

		internal static int GridStepIndex { get; private set; } = 1;

		internal static float GridStep => GridSteps[GridStepIndex];

		internal static void Init()
		{
			Mode = ModConfig.ParseDefaultMode();
			GridStepIndex = 1;
		}

		internal static void CycleMode()
		{
			Mode = ((Mode == AlignMode.Neighbor) ? AlignMode.WorldGrid : AlignMode.Neighbor);
		}

		internal static void CycleGridStep()
		{
			GridStepIndex = (GridStepIndex + 1) % GridSteps.Length;
		}

		internal static string GetHudText()
		{
			if (Mode == AlignMode.Neighbor)
			{
				return Loc.T("bap_mode_neighbor");
			}
			return Loc.Tf("bap_mode_grid", GridStep);
		}
	}
	internal static class BoundsUtil
	{
		internal static bool TryGetWorldBounds(GameObject go, out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			if ((Object)(object)go == (Object)null)
			{
				return false;
			}
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			bool flag = false;
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled && !((object)val).GetType().Name.Contains("Particle"))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			if (flag)
			{
				return true;
			}
			Collider[] componentsInChildren2 = go.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger)
				{
					if (!flag)
					{
						bounds = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val2.bounds);
					}
				}
			}
			return flag;
		}

		internal static string PrefabKey(Piece piece)
		{
			if ((Object)(object)piece == (Object)null || (Object)(object)((Component)piece).gameObject == (Object)null)
			{
				return string.Empty;
			}
			return Utils.GetPrefabName(((Object)((Component)piece).gameObject).name);
		}

		internal static bool PreserveFloorY(Piece piece)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if ((Object)(object)piece == (Object)null)
			{
				return true;
			}
			if (piece.m_groundPiece)
			{
				return false;
			}
			PieceCategory category = piece.m_category;
			if ((int)category != 4)
			{
				return (int)category == 0;
			}
			return true;
		}
	}
	internal static class GuideRenderer
	{
		private static GameObject _root;

		private static LineRenderer _main;

		private static LineRenderer _cross;

		private static Material _mat;

		internal static void Show(Vector3 a, Vector3 b, Vector3? crossA = null, Vector3? crossB = null)
		{
			//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_003d: 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_0072: 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)
			if (!ModConfig.ShowGuides.Value)
			{
				Hide();
				return;
			}
			Ensure();
			_root.SetActive(true);
			SetLine(_main, a, b, new Color(0.2f, 0.95f, 1f, 0.95f));
			if (crossA.HasValue && crossB.HasValue)
			{
				((Renderer)_cross).enabled = true;
				SetLine(_cross, crossA.Value, crossB.Value, new Color(1f, 0.85f, 0.2f, 0.85f));
			}
			else
			{
				((Renderer)_cross).enabled = false;
			}
		}

		internal static void ShowBoundsEdge(Bounds refBounds, Vector3 guideA, Vector3 guideB)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0019: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Vector3 val = (guideA + guideB) * 0.5f;
			Vector3 val2 = guideB - guideA;
			Vector3 val3 = Vector3.Cross(((Vector3)(ref val2)).normalized, Vector3.up);
			if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = Vector3.right;
			}
			((Vector3)(ref val3)).Normalize();
			float num = Mathf.Max(((Bounds)(ref refBounds)).size.x, ((Bounds)(ref refBounds)).size.z) * 0.35f;
			Show(guideA, guideB, val - val3 * num, val + val3 * num);
		}

		internal static void Hide()
		{
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(false);
			}
		}

		private static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_root != (Object)null))
			{
				_root = new GameObject("BuildAlignPlus_Guides");
				Object.DontDestroyOnLoad((Object)(object)_root);
				_mat = CreateMat();
				_main = CreateLr(_root, "Main", _mat);
				_cross = CreateLr(_root, "Cross", _mat);
				_root.SetActive(false);
			}
		}

		private static LineRenderer CreateLr(GameObject parent, string name, Material mat)
		{
			//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)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent.transform, false);
			LineRenderer obj = val.AddComponent<LineRenderer>();
			((Renderer)obj).sharedMaterial = mat;
			obj.widthMultiplier = 0.04f;
			obj.positionCount = 2;
			obj.useWorldSpace = true;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			obj.numCapVertices = 2;
			obj.alignment = (LineAlignment)0;
			return obj;
		}

		private static void SetLine(LineRenderer lr, Vector3 a, Vector3 b, Color c)
		{
			//IL_0008: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			((Renderer)lr).enabled = true;
			lr.startColor = c;
			lr.endColor = c;
			lr.SetPosition(0, a);
			lr.SetPosition(1, b);
			if ((Object)(object)((Renderer)lr).sharedMaterial != (Object)null && ((Renderer)lr).sharedMaterial.HasProperty("_Color"))
			{
				((Renderer)lr).sharedMaterial.color = c;
			}
		}

		private static Material CreateMat()
		{
			//IL_0034: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			Material val = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("UI/Default") ?? Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Standard"))
			{
				color = Color.cyan
			};
			val.HasProperty("_Mode");
			return val;
		}
	}
	internal static class NeighborSnapService
	{
		internal struct SnapResult
		{
			internal bool Snapped;

			internal Vector3 Position;

			internal Bounds RefBounds;

			internal Bounds GhostBounds;

			internal Vector3 GuideA;

			internal Vector3 GuideB;

			internal bool HasGuide;
		}

		private static readonly Collider[] Hits = (Collider[])(object)new Collider[64];

		private static readonly HashSet<int> Seen = new HashSet<int>();

		internal static SnapResult TrySnap(Player player, GameObject ghost, Piece selected)
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00d2: 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_00f6: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			SnapResult result = new SnapResult
			{
				Position = ghost.transform.position
			};
			if ((Object)(object)player == (Object)null || (Object)(object)ghost == (Object)null || (Object)(object)selected == (Object)null)
			{
				return result;
			}
			if (!BoundsUtil.TryGetWorldBounds(ghost, out var ghostBounds))
			{
				return result;
			}
			Piece val = FindBestNeighbor(ghost.transform.position, ghost, selected);
			if ((Object)(object)val == (Object)null)
			{
				return result;
			}
			if (!BoundsUtil.TryGetWorldBounds(((Component)val).gameObject, out var refBounds))
			{
				return result;
			}
			Vector3 ghostPos = ghost.transform.position;
			Vector3 ghostCenter = ((Bounds)(ref ghostBounds)).center;
			Vector3 extents = ((Bounds)(ref ghostBounds)).extents;
			Vector3 center = ((Bounds)(ref refBounds)).center;
			Vector3 extents2 = ((Bounds)(ref refBounds)).extents;
			float num = Mathf.Max(0.05f, extents.x);
			float num2 = Mathf.Max(0.05f, extents.z);
			float num3 = Mathf.Max(0.05f, extents2.x);
			float num4 = Mathf.Max(0.05f, extents2.z);
			float centerX = center.x;
			float centerZ = center.z;
			float targetCenterX = center.x + num3 + num;
			float targetCenterX2 = center.x - num3 - num;
			float targetCenterZ = center.z + num4 + num2;
			float targetCenterZ2 = center.z - num4 - num2;
			Vector3 centerToPos = ghostPos - ghostCenter;
			List<(Vector3 pos, float score, Vector3 ga, Vector3 gb)> candidates = new List<(Vector3, float, Vector3, Vector3)>(8);
			AddFaceX(targetCenterX, center.x + num3);
			AddFaceX(targetCenterX2, center.x - num3);
			AddFaceZ(targetCenterZ, center.z + num4);
			AddFaceZ(targetCenterZ2, center.z - num4);
			AddCenterAlign();
			float value = ModConfig.SnapPull.Value;
			(Vector3, float, Vector3, Vector3) tuple = default((Vector3, float, Vector3, Vector3));
			bool flag = false;
			float num5 = float.MaxValue;
			for (int i = 0; i < candidates.Count; i++)
			{
				(Vector3, float, Vector3, Vector3) tuple2 = candidates[i];
				if (!(tuple2.Item2 > value) && tuple2.Item2 < num5)
				{
					num5 = tuple2.Item2;
					tuple = tuple2;
					flag = true;
				}
			}
			if (!flag)
			{
				return result;
			}
			var (position, _, _, _) = tuple;
			if (BoundsUtil.PreserveFloorY(selected))
			{
				position.y = ghostPos.y;
			}
			else
			{
				float num6 = center.y + centerToPos.y;
				if (Mathf.Abs(ghostPos.y - num6) <= value)
				{
					position.y = num6;
				}
				else
				{
					position.y = ghostPos.y;
				}
			}
			result.Snapped = true;
			result.Position = position;
			result.RefBounds = refBounds;
			result.GhostBounds = ghostBounds;
			result.GuideA = tuple.Item3;
			result.GuideB = tuple.Item4;
			result.HasGuide = true;
			return result;
			void AddCenterAlign()
			{
				//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)
				//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_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_0052: 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_006c: 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_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: 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_00db: 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_00f2: 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_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = new Vector3(centerX, ghostCenter.y, ghostCenter.z) + centerToPos;
				candidates.Add((val2, HorizontalDist(ghostPos, val2) + 0.05f, new Vector3(centerX, ((Bounds)(ref ghostBounds)).min.y, ((Bounds)(ref ghostBounds)).min.z), new Vector3(centerX, ((Bounds)(ref ghostBounds)).max.y, ((Bounds)(ref ghostBounds)).max.z)));
				Vector3 val3 = new Vector3(ghostCenter.x, ghostCenter.y, centerZ) + centerToPos;
				candidates.Add((val3, HorizontalDist(ghostPos, val3) + 0.05f, new Vector3(((Bounds)(ref ghostBounds)).min.x, ((Bounds)(ref ghostBounds)).min.y, centerZ), new Vector3(((Bounds)(ref ghostBounds)).max.x, ((Bounds)(ref ghostBounds)).max.y, centerZ)));
			}
			void AddFaceX(float num7, float faceX)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: 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_0049: 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_0076: 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_009b: 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_00b2: 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)
				Vector3 val2 = new Vector3(num7, ghostCenter.y, centerZ) + centerToPos;
				float item = HorizontalDist(ghostPos, val2);
				Vector3 item2 = default(Vector3);
				((Vector3)(ref item2))..ctor(faceX, Mathf.Min(((Bounds)(ref refBounds)).min.y, ((Bounds)(ref ghostBounds)).min.y), ((Bounds)(ref refBounds)).min.z);
				Vector3 item3 = default(Vector3);
				((Vector3)(ref item3))..ctor(faceX, Mathf.Max(((Bounds)(ref refBounds)).max.y, ((Bounds)(ref ghostBounds)).max.y), ((Bounds)(ref refBounds)).max.z);
				candidates.Add((val2, item, item2, item3));
			}
			void AddFaceZ(float num7, float faceZ)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: 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_0048: 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_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: 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_00b2: 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)
				Vector3 val2 = new Vector3(centerX, ghostCenter.y, num7) + centerToPos;
				float item = HorizontalDist(ghostPos, val2);
				Vector3 item2 = default(Vector3);
				((Vector3)(ref item2))..ctor(((Bounds)(ref refBounds)).min.x, Mathf.Min(((Bounds)(ref refBounds)).min.y, ((Bounds)(ref ghostBounds)).min.y), faceZ);
				Vector3 item3 = default(Vector3);
				((Vector3)(ref item3))..ctor(((Bounds)(ref refBounds)).max.x, Mathf.Max(((Bounds)(ref refBounds)).max.y, ((Bounds)(ref ghostBounds)).max.y), faceZ);
				candidates.Add((val2, item, item2, item3));
			}
		}

		private static float HorizontalDist(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			float num = a.x - b.x;
			float num2 = a.z - b.z;
			return Mathf.Sqrt(num * num + num2 * num2);
		}

		private static Piece FindBestNeighbor(Vector3 origin, GameObject ghost, Piece selected)
		{
			//IL_000b: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			float value = ModConfig.NeighborSearchRadius.Value;
			int num = Physics.OverlapSphereNonAlloc(origin, value, Hits, -1, (QueryTriggerInteraction)1);
			Seen.Clear();
			string text = BoundsUtil.PrefabKey(selected);
			Piece val = null;
			float num2 = float.MaxValue;
			Piece val2 = null;
			float num3 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				Collider val3 = Hits[i];
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Piece componentInParent = ((Component)val3).GetComponentInParent<Piece>();
				if ((Object)(object)componentInParent == (Object)null || (Object)(object)((Component)componentInParent).gameObject == (Object)null || !((Component)componentInParent).gameObject.activeInHierarchy || (Object)(object)((Component)componentInParent).gameObject == (Object)(object)ghost)
				{
					continue;
				}
				int instanceID = ((Object)componentInParent).GetInstanceID();
				if (!Seen.Add(instanceID) || ((Component)componentInParent).transform.IsChildOf(ghost.transform) || ghost.transform.IsChildOf(((Component)componentInParent).transform))
				{
					continue;
				}
				float num4 = HorizontalDist(origin, ((Component)componentInParent).transform.position);
				string text2 = BoundsUtil.PrefabKey(componentInParent);
				if (!string.IsNullOrEmpty(text) && text2 == text)
				{
					if (num4 < num2)
					{
						num2 = num4;
						val = componentInParent;
					}
				}
				else if (num4 < num3)
				{
					num3 = num4;
					val2 = componentInParent;
				}
			}
			return val ?? val2;
		}
	}
	internal static class WorldGridSnapService
	{
		internal struct SnapResult
		{
			internal bool Snapped;

			internal Vector3 Position;

			internal bool HasGuide;

			internal Vector3 GuideA;

			internal Vector3 GuideB;
		}

		internal static SnapResult TrySnap(GameObject ghost, Piece selected)
		{
			//IL_0020: 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_0025: 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_0054: 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_0066: 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_00ba: 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_00c8: 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)
			//IL_0087: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			SnapResult result = new SnapResult
			{
				Position = (((Object)(object)ghost != (Object)null) ? ghost.transform.position : Vector3.zero)
			};
			if ((Object)(object)ghost == (Object)null)
			{
				return result;
			}
			float gridStep = AlignState.GridStep;
			float value = ModConfig.SnapPull.Value;
			Vector3 position = ghost.transform.position;
			float num = Mathf.Round(position.x / gridStep) * gridStep;
			float num2 = Mathf.Round(position.z / gridStep) * gridStep;
			float num3 = position.y;
			if (!BoundsUtil.PreserveFloorY(selected))
			{
				float num4 = Mathf.Round(position.y / gridStep) * gridStep;
				if (Mathf.Abs(position.y - num4) <= value)
				{
					num3 = num4;
				}
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(num, num3, num2);
			float num5 = val.x - position.x;
			float num6 = val.z - position.z;
			if (num5 * num5 + num6 * num6 > value * value)
			{
				return result;
			}
			result.Snapped = true;
			result.Position = val;
			result.HasGuide = true;
			result.GuideA = new Vector3(num - gridStep, num3 + 0.05f, num2);
			result.GuideB = new Vector3(num + gridStep, num3 + 0.05f, num2);
			return result;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}