Decompiled source of PerfectPlacement v1.1.7

PerfectPlacement.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using PerfectPlacement;
using PerfectPlacement.Patches.Compatibility.WardIsLove;
using ServerSync;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PerfectPlacement")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("PerfectPlacement")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E3FE707A-B402-4C69-8C3D-E9C0C709715D")]
[assembly: AssemblyFileVersion("1.1.7")]
[assembly: AssemblyCompany("Azumatt_and_ValheimPlusDevs")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.7.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<d2611e69-7574-4774-9a94-599aa53096f7>Embedded]
	internal sealed class <d2611e69-7574-4774-9a94-599aa53096f7>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<d2611e69-7574-4774-9a94-599aa53096f7>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class <e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[<d2611e69-7574-4774-9a94-599aa53096f7>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class <30de3432-c0c0-453d-9746-1305176a74f7>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <30de3432-c0c0-453d-9746-1305176a74f7>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace AllManagersModTemplate
{
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			PerfectPlacementPlugin.PerfectPlacementLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("PerfectPlacement_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_AllManagersModTemplate_Version);
			PerfectPlacementPlugin.PerfectPlacementLogger.LogDebug((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("1.1.7");
			val.Write(RpcHandlers.ComputeHashForMod().Replace("-", ""));
			peer.m_rpc.Invoke("PerfectPlacement_VersionCheck", new object[1] { val });
		}
	}
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			PerfectPlacementPlugin.PerfectPlacementLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "PerfectPlacementRequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + PerfectPlacementPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				PerfectPlacementPlugin.PerfectPlacementLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_AllManagersModTemplate_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			string text3 = ComputeHashForMod().Replace("-", "");
			PerfectPlacementPlugin.PerfectPlacementLogger.LogInfo((object)("Version check, local: 1.1.7,  remote: " + text));
			if (text2 != text3 || text != "1.1.7")
			{
				PerfectPlacementPlugin.ConnectionError = "PerfectPlacement Installed: 1.1.7 " + text3 + "\n Needed: " + text + " " + text2;
				if (ZNet.instance.IsServer())
				{
					PerfectPlacementPlugin.PerfectPlacementLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				PerfectPlacementPlugin.PerfectPlacementLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				PerfectPlacementPlugin.PerfectPlacementLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}

		public static string ComputeHashForMod()
		{
			using SHA256 sHA = SHA256.Create();
			byte[] array = sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location));
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("X2"));
			}
			return stringBuilder.ToString();
		}
	}
}
namespace PerfectPlacement
{
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[BepInPlugin("Azumatt_and_ValheimPlusDevs.PerfectPlacement", "PerfectPlacement", "1.1.7")]
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	public class PerfectPlacementPlugin : BaseUnityPlugin
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(0)]
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(0)]
		internal class PlayerData
		{
			public Vector3 PlaceRotation = Vector3.zero;

			public bool Opposite;

			[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(1)]
			public Piece LastPiece;

			public KeyCode LastKeyCode;
		}

		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(2)]
			[UsedImplicitly]
			public string Category;

			[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer;
		}

		internal const string ModName = "PerfectPlacement";

		internal const string ModVersion = "1.1.7";

		internal const string Author = "Azumatt_and_ValheimPlusDevs";

		private const string ModGUID = "Azumatt_and_ValheimPlusDevs.PerfectPlacement";

		private static string ConfigFileName = "Azumatt_and_ValheimPlusDevs.PerfectPlacement.cfg";

		private static string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("Azumatt_and_ValheimPlusDevs.PerfectPlacement");

		public static readonly ManualLogSource PerfectPlacementLogger;

		private static readonly ConfigSync ConfigSync;

		internal static readonly Dictionary<Player, PlayerData> PlayersData;

		private static ConfigEntry<Toggle> _serverConfigLocked;

		internal static ConfigEntry<Toggle> fpmIsEnabled;

		internal static ConfigEntry<KeyCode> fpmrotateY;

		internal static ConfigEntry<KeyCode> fpmrotateX;

		internal static ConfigEntry<KeyCode> fpmrotateZ;

		internal static ConfigEntry<KeyCode> fpmcopyRotationParallel;

		internal static ConfigEntry<KeyCode> fpmcopyRotationPerpendicular;

		internal static ConfigEntry<Toggle> abmIsEnabled;

		internal static ConfigEntry<KeyCode> abmenterAdvancedBuildingMode;

		internal static ConfigEntry<KeyCode> abmexitAdvancedBuildingMode;

		internal static ConfigEntry<KeyCode> abmcopyObjectRotation;

		internal static ConfigEntry<KeyCode> abmpasteObjectRotation;

		internal static ConfigEntry<KeyCode> abmincreaseScrollSpeed;

		internal static ConfigEntry<KeyCode> abmdecreaseScrollSpeed;

		internal static ConfigEntry<Toggle> aemIsEnabled;

		internal static ConfigEntry<KeyCode> aementerAdvancedEditingMode;

		internal static ConfigEntry<KeyCode> aemresetAdvancedEditingMode;

		internal static ConfigEntry<KeyCode> aemabortAndExitAdvancedEditingMode;

		internal static ConfigEntry<KeyCode> aemconfirmPlacementOfAdvancedEditingMode;

		internal static ConfigEntry<KeyCode> aemcopyObjectRotation;

		internal static ConfigEntry<KeyCode> aempasteObjectRotation;

		internal static ConfigEntry<KeyCode> aemincreaseScrollSpeed;

		internal static ConfigEntry<KeyCode> aemdecreaseScrollSpeed;

		internal static ConfigEntry<Toggle> gridAlignmentEnabled;

		internal static ConfigEntry<KeyCode> alignToGrid;

		internal static ConfigEntry<KeyCode> alignToggle;

		internal static ConfigEntry<KeyCode> changeDefaultAlignment;

		public void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			_serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, new ConfigDescription("If on, the configuration is locked and can be changed by server admins only.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5
				}
			}));
			ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked);
			fpmIsEnabled = config("1 - General", "Enable Free Placement Rotation", Toggle.On, new ConfigDescription("If on, Free Placement Rotation is enabled. Everything in section 2 will be affected.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
			fpmrotateY = config<KeyCode>("2 - Free Placement Rotation", "Rotate Y", (KeyCode)308, "The key to rotate the object you are placing on the Y axis, Rotates placement marker by 1 degree with keep ability to attach to nearly pieces.", synchronizedSetting: false);
			fpmrotateX = config<KeyCode>("2 - Free Placement Rotation", "Rotate X", (KeyCode)99, "The key to rotate the object you are placing on the X axis, Rotates placement marker by 1 degree with keep ability to attach to nearly pieces.", synchronizedSetting: false);
			fpmrotateZ = config<KeyCode>("2 - Free Placement Rotation", "Rotate Z", (KeyCode)118, "The key to rotate the object you are placing on the Z axis, Rotates placement marker by 1 degree with keep ability to attach to nearly pieces.", synchronizedSetting: false);
			fpmcopyRotationParallel = config<KeyCode>("2 - Free Placement Rotation", "Copy Rotation Parallel", (KeyCode)102, "Copy rotation of placement marker from target piece in front of you.", synchronizedSetting: false);
			fpmcopyRotationPerpendicular = config<KeyCode>("2 - Free Placement Rotation", "Copy Rotation Perpendicular", (KeyCode)103, "Set rotation to be perpendicular to piece in front of you.", synchronizedSetting: false);
			abmIsEnabled = config("1 - General", "Enable Advanced Building Mode", Toggle.On, new ConfigDescription("If on, Advanced Building Mode is enabled. Everything in section 3 will be affected.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			abmenterAdvancedBuildingMode = config<KeyCode>("3 - Advanced Building Mode", "Enter Advanced Building Mode", (KeyCode)282, "The key to enter Advanced Building Mode when building", synchronizedSetting: false);
			abmexitAdvancedBuildingMode = config<KeyCode>("3 - Advanced Building Mode", "Exit Advanced Building Mode", (KeyCode)284, "The key to exit Advanced Building Mode when building", synchronizedSetting: false);
			abmcopyObjectRotation = config<KeyCode>("3 - Advanced Building Mode", "Copy Object Rotation", (KeyCode)263, "Copy the object rotation of the currently selected object in ABM", synchronizedSetting: false);
			abmpasteObjectRotation = config<KeyCode>("3 - Advanced Building Mode", "Paste Object Rotation", (KeyCode)264, "Apply the copied object rotation to the currently selected object in ABM", synchronizedSetting: false);
			abmincreaseScrollSpeed = config<KeyCode>("3 - Advanced Building Mode", "Increase Scroll Speed", (KeyCode)270, "Increases the amount an object rotates and moves. Holding Shift will increase in increments of 10 instead of 1.", synchronizedSetting: false);
			abmdecreaseScrollSpeed = config<KeyCode>("3 - Advanced Building Mode", "Decrease Scroll Speed", (KeyCode)269, "Decreases the amount an object rotates and moves. Holding Shift will decrease in increments of 10 instead of 1.", synchronizedSetting: false);
			aemIsEnabled = config("1 - General", "Enable Advanced Editing Mode", Toggle.On, new ConfigDescription("If on, Advanced Editing Mode is enabled. Everything in section 4 will be affected.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			aementerAdvancedEditingMode = config<KeyCode>("4 - Advanced Editing Mode", "Enter Advanced Editing Mode", (KeyCode)256, "The key to enter Advanced Editing Mode", synchronizedSetting: false);
			aemresetAdvancedEditingMode = config<KeyCode>("4 - Advanced Editing Mode", "Reset Advanced Editing Mode", (KeyCode)288, "The key to reset the object to its original position and rotation", synchronizedSetting: false);
			aemabortAndExitAdvancedEditingMode = config<KeyCode>("4 - Advanced Editing Mode", "Abort and Exit Advanced Editing Mode", (KeyCode)289, "The key to abort and exit Advanced Editing Mode and reset the object", synchronizedSetting: false);
			aemconfirmPlacementOfAdvancedEditingMode = config<KeyCode>("4 - Advanced Editing Mode", "Confirm Placement of Advanced Editing Mode", (KeyCode)271, "The key to confirm the placement of the object and place it", synchronizedSetting: false);
			aemcopyObjectRotation = config<KeyCode>("4 - Advanced Editing Mode", "Copy Object Rotation", (KeyCode)263, "The key to copy the object rotation of the currently selected object in AEM", synchronizedSetting: false);
			aempasteObjectRotation = config<KeyCode>("4 - Advanced Editing Mode", "Paste Object Rotation", (KeyCode)264, "The key to apply the copied object rotation to the currently selected object in AEM", synchronizedSetting: false);
			aemincreaseScrollSpeed = config<KeyCode>("4 - Advanced Editing Mode", "Increase Scroll Speed", (KeyCode)270, "The key to increase the scroll speed. Increases the amount an object rotates and moves. Holding Shift will increase in increments of 10 instead of 1.", synchronizedSetting: false);
			aemdecreaseScrollSpeed = config<KeyCode>("4 - Advanced Editing Mode", "Decrease Scroll Speed", (KeyCode)269, "The key to decrease the scroll speed. Decreases the amount an object rotates and moves. Holding Shift will increase in increments of 10 instead of 1.", synchronizedSetting: false);
			gridAlignmentEnabled = config("1 - General", "Enable Grid Alignment", Toggle.Off, new ConfigDescription("If off, Grid Alignment is disabled overall, all code for it will be skipped. Everything in section 5 will be affected.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			alignToGrid = config<KeyCode>("5 - Grid Alignment", "Align to Grid", (KeyCode)308, "The key to enable grid alignment while building", synchronizedSetting: false);
			alignToggle = config<KeyCode>("5 - Grid Alignment", "Align Toggle", (KeyCode)288, "The key to toggle grid alignment while building", synchronizedSetting: false);
			changeDefaultAlignment = config<KeyCode>("5 - Grid Alignment", "Change Default Alignment", (KeyCode)287, "The key to change the default alignment", synchronizedSetting: false);
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private void Start()
		{
			AutoDoc();
		}

		internal void AutoDoc()
		{
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				PerfectPlacementLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				PerfectPlacementLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				PerfectPlacementLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		private ConfigEntry<T> config<[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting;
			return val2;
		}

		private ConfigEntry<T> config<[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		static PerfectPlacementPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			PerfectPlacementLogger = Logger.CreateLogSource("PerfectPlacement");
			ConfigSync = new ConfigSync("Azumatt_and_ValheimPlusDevs.PerfectPlacement")
			{
				DisplayName = "PerfectPlacement",
				CurrentVersion = "1.1.7",
				MinimumRequiredVersion = "1.1.7"
			};
			PlayersData = new Dictionary<Player, PlayerData>();
			_serverConfigLocked = null;
			fpmIsEnabled = null;
			fpmrotateY = null;
			fpmrotateX = null;
			fpmrotateZ = null;
			fpmcopyRotationParallel = null;
			fpmcopyRotationPerpendicular = null;
			abmIsEnabled = null;
			abmenterAdvancedBuildingMode = null;
			abmexitAdvancedBuildingMode = null;
			abmcopyObjectRotation = null;
			abmpasteObjectRotation = null;
			abmincreaseScrollSpeed = null;
			abmdecreaseScrollSpeed = null;
			aemIsEnabled = null;
			aementerAdvancedEditingMode = null;
			aemresetAdvancedEditingMode = null;
			aemabortAndExitAdvancedEditingMode = null;
			aemconfirmPlacementOfAdvancedEditingMode = null;
			aemcopyObjectRotation = null;
			aempasteObjectRotation = null;
			aemincreaseScrollSpeed = null;
			aemdecreaseScrollSpeed = null;
			gridAlignmentEnabled = null;
			alignToGrid = null;
			alignToggle = null;
			changeDefaultAlignment = null;
		}
	}
}
namespace PerfectPlacement.Patches
{
	public class Util
	{
		internal static Vector3 ClampAngles(Vector3 angles)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(ClampAngle(angles.x), ClampAngle(angles.y), ClampAngle(angles.z));
		}

		internal static int ClampPlaceRotation(int index)
		{
			if (index < 0)
			{
				index = 16 + index;
			}
			else if (index >= 16)
			{
				index -= 16;
			}
			return index;
		}

		private static float ClampAngle(float angle)
		{
			if (angle < 0f)
			{
				angle = 360f + angle;
			}
			else if (angle >= 360f)
			{
				angle -= 360f;
			}
			return angle;
		}

		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		public static Character getPlayerCharacter(Player __instance)
		{
			return (Character)(object)__instance;
		}
	}
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	internal class ABM
	{
		public static bool isActive;

		private static Player PlayerInstance;

		private static bool controlFlag;

		private static bool shiftFlag;

		private static bool altFlag;

		public static bool exitOnNextIteration;

		private static bool blockDefaultFunction;

		private static Piece component;

		private const float BASE_TRANSLATION_DISTANCE = 0.1f;

		private const float BASE_ROTATION_ANGLE_DEGREES = 3f;

		private static float currentModificationSpeed = 1f;

		private const float MIN_MODIFICATION_SPEED = 1f;

		private const float MAX_MODIFICATION_SPEED = 30f;

		private static Quaternion savedRotation;

		public static void Run(ref Player __instance)
		{
			//IL_0020: 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_00cf: 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)
			PlayerInstance = __instance;
			if (AEM.isActive)
			{
				if (isActive)
				{
					exitMode();
				}
				return;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.abmexitAdvancedBuildingMode.Value))
			{
				if (isActive)
				{
					exitMode();
				}
				return;
			}
			if (exitOnNextIteration)
			{
				isActive = false;
				blockDefaultFunction = false;
				exitOnNextIteration = false;
				component = null;
			}
			if (isActive && (Object)(object)component == (Object)null)
			{
				exitMode();
			}
			else if ((Object)(object)selectedPrefab() == (Object)null || (Object)(object)PlayerInstance.m_placementGhost == (Object)null)
			{
				if (isActive)
				{
					exitMode();
				}
			}
			else if (isInBuildMode() && IsHoeOrTerrainTool(selectedPrefab()))
			{
				if (isActive)
				{
					exitMode();
				}
			}
			else if (isActive)
			{
				if (Vector3.Distance(((Component)PlayerInstance).transform.position, ((Component)component).transform.position) > PlayerInstance.m_maxPlaceDistance)
				{
					exitMode();
				}
				isRunning();
				listenToHotKeysAndDoWork();
			}
			else if (Input.GetKeyDown(PerfectPlacementPlugin.abmenterAdvancedBuildingMode.Value))
			{
				startMode();
			}
		}

		private static void listenToHotKeysAndDoWork()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: 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_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: 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_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: 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_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			if (Input.GetKeyDown((KeyCode)306))
			{
				controlFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)306))
			{
				controlFlag = false;
			}
			if (Input.GetKeyDown((KeyCode)304))
			{
				shiftFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)304))
			{
				shiftFlag = false;
			}
			if (Input.GetKeyDown((KeyCode)308))
			{
				altFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)308))
			{
				altFlag = false;
			}
			changeModificationSpeed();
			if (Input.GetKeyUp(PerfectPlacementPlugin.abmcopyObjectRotation.Value))
			{
				savedRotation = ((Component)component).transform.rotation;
			}
			if (Input.GetKeyUp(PerfectPlacementPlugin.abmpasteObjectRotation.Value))
			{
				((Component)component).transform.rotation = savedRotation;
			}
			float num4 = 3f * currentModificationSpeed;
			if (Input.GetAxis("Mouse ScrollWheel") > 0f)
			{
				Quaternion rotation;
				if (controlFlag)
				{
					num += 1f;
					rotation = Quaternion.Euler(((Component)component).transform.eulerAngles.x + num4 * num, ((Component)component).transform.eulerAngles.y, ((Component)component).transform.eulerAngles.z);
				}
				else if (altFlag)
				{
					num2 += 1f;
					rotation = Quaternion.Euler(((Component)component).transform.eulerAngles.x, ((Component)component).transform.eulerAngles.y, ((Component)component).transform.eulerAngles.z + num4 * num2);
				}
				else
				{
					num3 += 1f;
					rotation = Quaternion.Euler(((Component)component).transform.eulerAngles.x, ((Component)component).transform.eulerAngles.y + num4 * num3, ((Component)component).transform.eulerAngles.z);
				}
				((Component)component).transform.rotation = rotation;
			}
			if (Input.GetAxis("Mouse ScrollWheel") < 0f)
			{
				Quaternion rotation2;
				if (controlFlag)
				{
					num -= 1f;
					rotation2 = Quaternion.Euler(((Component)component).transform.eulerAngles.x + num4 * num, ((Component)component).transform.eulerAngles.y, ((Component)component).transform.eulerAngles.z);
				}
				else if (altFlag)
				{
					num2 -= 1f;
					rotation2 = Quaternion.Euler(((Component)component).transform.eulerAngles.x, ((Component)component).transform.eulerAngles.y, ((Component)component).transform.eulerAngles.z + num4 * num2);
				}
				else
				{
					num3 -= 1f;
					rotation2 = Quaternion.Euler(((Component)component).transform.eulerAngles.x, ((Component)component).transform.eulerAngles.y + num4 * num3, ((Component)component).transform.eulerAngles.z);
				}
				((Component)component).transform.rotation = rotation2;
			}
			float num5 = 0.1f * currentModificationSpeed;
			if (Input.GetKeyDown((KeyCode)273))
			{
				if (controlFlag)
				{
					((Component)component).transform.Translate(Vector3.up * num5);
				}
				else
				{
					((Component)component).transform.Translate(Vector3.forward * num5);
				}
			}
			if (Input.GetKeyDown((KeyCode)274))
			{
				if (controlFlag)
				{
					((Component)component).transform.Translate(Vector3.down * num5);
				}
				else
				{
					((Component)component).transform.Translate(Vector3.back * num5);
				}
			}
			if (Input.GetKeyDown((KeyCode)276))
			{
				((Component)component).transform.Translate(Vector3.left * num5);
			}
			if (Input.GetKeyDown((KeyCode)275))
			{
				((Component)component).transform.Translate(Vector3.right * num5);
			}
			try
			{
				isValidPlacement();
			}
			catch
			{
			}
		}

		private static void isValidPlacement()
		{
			//IL_0006: 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_00c3: 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_0128: 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_00e1: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			PlayerInstance.m_placementStatus = (PlacementStatus)0;
			if (component.m_groundOnly || component.m_groundPiece || component.m_cultivatedGroundOnly)
			{
				PlayerInstance.m_placementMarkerInstance.SetActive(false);
			}
			StationExtension val = ((Component)component).GetComponent<StationExtension>();
			if ((Object)(object)val != (Object)null)
			{
				CraftingStation val2 = val.FindClosestStationInRange(((Component)component).transform.position);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val.StartConnectionEffect(val2, 1f);
				}
				else
				{
					val.StopConnectionEffect();
					PlayerInstance.m_placementStatus = (PlacementStatus)7;
				}
				if (val.OtherExtensionInRange(component.m_spaceRequirement))
				{
					PlayerInstance.m_placementStatus = (PlacementStatus)5;
				}
			}
			if (component.m_onlyInTeleportArea && !Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(((Component)component).transform.position, (Type)16, 0f)))
			{
				PlayerInstance.m_placementStatus = (PlacementStatus)6;
			}
			if (!component.m_allowedInDungeons && ((Component)component).transform.position.y > 3000f)
			{
				PlayerInstance.m_placementStatus = (PlacementStatus)11;
			}
			if (Location.IsInsideNoBuildLocation(PlayerInstance.m_placementGhost.transform.position))
			{
				PlayerInstance.m_placementStatus = (PlacementStatus)3;
			}
			float num = (Object.op_Implicit((Object)(object)((Component)component).GetComponent<PrivateArea>()) ? ((Component)component).GetComponent<PrivateArea>().m_radius : 0f);
			if (!PrivateArea.CheckAccess(PlayerInstance.m_placementGhost.transform.position, num, true, false))
			{
				PlayerInstance.m_placementStatus = (PlacementStatus)4;
			}
			if (WardIsLovePlugin.IsLoaded() && WardIsLovePlugin.WardEnabled().Value && WardMonoscript.CheckInWardMonoscript(PlayerInstance.m_placementGhost.transform.position) && !WardMonoscript.CheckAccess(PlayerInstance.m_placementGhost.transform.position, num))
			{
				PlayerInstance.m_placementStatus = (PlacementStatus)4;
			}
			if ((int)PlayerInstance.m_placementStatus != 0)
			{
				component.SetInvalidPlacementHeightlight(true);
			}
			else
			{
				component.SetInvalidPlacementHeightlight(false);
			}
		}

		private static void startMode()
		{
			notifyUser("Starting ABM", (MessageType)1);
			isActive = true;
			blockDefaultFunction = true;
			component = PlayerInstance.m_placementGhost.GetComponent<Piece>();
		}

		private static void exitMode()
		{
			notifyUser("Exiting ABM", (MessageType)1);
			exitOnNextIteration = true;
			isActive = false;
			component = null;
		}

		private static bool isInBuildMode()
		{
			return ((Character)PlayerInstance).InPlaceMode();
		}

		private static GameObject selectedPrefab()
		{
			if ((Object)(object)PlayerInstance.m_buildPieces != (Object)null)
			{
				try
				{
					return PlayerInstance.m_buildPieces.GetSelectedPrefab();
				}
				catch
				{
					return null;
				}
			}
			return null;
		}

		private static bool IsHoeOrTerrainTool(GameObject selectedPrefab)
		{
			string[] source = new string[4] { "paved_road", "mud_road", "raise", "path" };
			string[] source2 = new string[2] { "cultivate", "replant" };
			if (((Object)selectedPrefab).name.ToLower().Contains("sapling"))
			{
				return true;
			}
			if (source.Contains(((Object)selectedPrefab).name) || source2.Contains(((Object)selectedPrefab).name))
			{
				return true;
			}
			return false;
		}

		private static void notifyUser(string Message, MessageType position = 1)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			MessageHud.instance.ShowMessage(position, "ABM: " + Message, 0, (Sprite)null);
		}

		private static void isRunning()
		{
			if (isActive)
			{
				MessageHud.instance.ShowMessage((MessageType)2, "ABM is active", 0, (Sprite)null);
			}
		}

		private static void changeModificationSpeed()
		{
			//IL_0018: 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)
			float num = 1f;
			if (shiftFlag)
			{
				num = 10f;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.abmincreaseScrollSpeed.Value))
			{
				currentModificationSpeed = Mathf.Clamp(currentModificationSpeed + num, 1f, 30f);
				notifyUser("Modification Speed: " + currentModificationSpeed, (MessageType)1);
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.abmdecreaseScrollSpeed.Value))
			{
				currentModificationSpeed = Mathf.Clamp(currentModificationSpeed - num, 1f, 30f);
				notifyUser("Modification Speed: " + currentModificationSpeed, (MessageType)1);
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	internal class AEM
	{
		public static bool isActive;

		public static Player PlayerInstance;

		private static bool controlFlag;

		private static bool shiftFlag;

		private static bool altFlag;

		public static Vector3 HitPoint;

		public static Vector3 HitNormal;

		public static Piece HitPiece;

		public static GameObject HitObject;

		public static Heightmap HitHeightmap;

		private static Quaternion InitialRotation;

		private static Vector3 InitialPosition;

		private static bool isInExistence;

		private const float BASE_TRANSLATION_DISTANCE = 0.1f;

		private const float BASE_ROTATION_ANGLE_DEGREES = 3f;

		private static float currentModificationSpeed = 1f;

		private const float MIN_MODIFICATION_SPEED = 1f;

		private const float MAX_MODIFICATION_SPEED = 30f;

		private static Quaternion savedRotation;

		public static bool forceExitNextIteration;

		public static bool ExecuteRayCast(Player playerInstance)
		{
			//IL_0011: 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_0069: 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_0084: 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_0090: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			int placeRayMask = playerInstance.m_placeRayMask;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val, 50f, placeRayMask) && Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody) && Vector3.Distance(Util.getPlayerCharacter(playerInstance).m_eye.position, ((RaycastHit)(ref val)).point) < playerInstance.m_maxPlaceDistance)
			{
				HitPoint = ((RaycastHit)(ref val)).point;
				HitNormal = ((RaycastHit)(ref val)).normal;
				HitPiece = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
				HitObject = ((Component)((RaycastHit)(ref val)).collider).gameObject;
				HitHeightmap = ((Component)((RaycastHit)(ref val)).collider).GetComponent<Heightmap>();
				InitialRotation = ((Component)HitPiece).transform.rotation;
				InitialPosition = ((Component)HitPiece).transform.position;
				return isValidRayCastTarget();
			}
			resetObjectInfo();
			return false;
		}

		public static bool checkForObject()
		{
			if ((Object)(object)PlayerInstance == (Object)null)
			{
				return false;
			}
			if (!ExecuteRayCast(PlayerInstance))
			{
				return false;
			}
			return true;
		}

		public static void run()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (forceExitNextIteration)
			{
				forceExitNextIteration = false;
				resetObjectInfo();
				isActive = false;
				return;
			}
			if (isInBuildMode())
			{
				if (isActive)
				{
					exitMode();
					resetObjectTransform();
				}
				return;
			}
			if (ABM.isActive)
			{
				if (isActive)
				{
					exitMode();
					resetObjectTransform();
				}
				return;
			}
			if (!isActive && Input.GetKeyDown(PerfectPlacementPlugin.aementerAdvancedEditingMode.Value))
			{
				if (checkForObject())
				{
					startMode();
				}
				return;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.aemabortAndExitAdvancedEditingMode.Value))
			{
				exitMode();
				resetObjectTransform();
			}
			if (!isActive)
			{
				return;
			}
			if (hitPieceStillExists())
			{
				try
				{
					if ((Object)(object)((Component)HitPiece).GetComponent<ZNetView>() == (Object)null)
					{
						Debug.Log((object)"AEM: Error, network object empty. Code: 2.");
						exitMode();
						return;
					}
				}
				catch
				{
					Debug.Log((object)"AEM: Error, network object empty. Code: 3.");
					exitMode();
				}
				isRunning();
				listenToHotKeysAndDoWork();
			}
			else
			{
				exitMode();
			}
		}

		private static void listenToHotKeysAndDoWork()
		{
			//IL_0017: 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_005c: 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_008b: 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_017e: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: 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_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			if (Input.GetKeyDown(PerfectPlacementPlugin.aemresetAdvancedEditingMode.Value))
			{
				resetObjectTransform();
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.aemconfirmPlacementOfAdvancedEditingMode.Value))
			{
				if (isContainer())
				{
					dropContainerContents();
				}
				GameObject val = Object.Instantiate<GameObject>(((Component)HitPiece).gameObject, ((Component)HitPiece).transform.position, ((Component)HitPiece).transform.rotation);
				HitPiece.m_placeEffect.Create(((Component)HitPiece).transform.position, ((Component)HitPiece).transform.rotation, val.transform, 1f, -1);
				ZNetView component = ((Component)HitPiece).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null)
				{
					Debug.Log((object)"AEM: Error, network object empty.");
					resetObjectTransform();
					exitMode();
				}
				else
				{
					component.ClaimOwnership();
					ZNetScene.instance.Destroy(((Component)HitPiece).gameObject);
					Debug.Log((object)"AEM: Executed.");
					exitMode();
				}
				return;
			}
			if (Input.GetKeyDown((KeyCode)306))
			{
				controlFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)306))
			{
				controlFlag = false;
			}
			if (Input.GetKeyDown((KeyCode)304))
			{
				shiftFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)304))
			{
				shiftFlag = false;
			}
			if (Input.GetKeyDown((KeyCode)308))
			{
				altFlag = true;
			}
			if (Input.GetKeyUp((KeyCode)308))
			{
				altFlag = false;
			}
			changeModificationSpeed();
			if (Input.GetKeyUp(PerfectPlacementPlugin.aemcopyObjectRotation.Value))
			{
				savedRotation = ((Component)HitPiece).transform.rotation;
			}
			if (Input.GetKeyUp(PerfectPlacementPlugin.aempasteObjectRotation.Value))
			{
				((Component)HitPiece).transform.rotation = savedRotation;
			}
			if (Vector3.Distance(((Component)PlayerInstance).transform.position, ((Component)HitPiece).transform.position) > PlayerInstance.m_maxPlaceDistance)
			{
				resetObjectTransform();
				exitMode();
			}
			float num4 = 3f * currentModificationSpeed;
			if (Input.GetAxis("Mouse ScrollWheel") > 0f)
			{
				Quaternion rotation;
				if (controlFlag)
				{
					num += 1f;
					rotation = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x + num4 * num, ((Component)HitPiece).transform.eulerAngles.y, ((Component)HitPiece).transform.eulerAngles.z);
				}
				else if (altFlag)
				{
					num2 += 1f;
					rotation = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x, ((Component)HitPiece).transform.eulerAngles.y, ((Component)HitPiece).transform.eulerAngles.z + num4 * num2);
				}
				else
				{
					num3 += 1f;
					rotation = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x, ((Component)HitPiece).transform.eulerAngles.y + num4 * num3, ((Component)HitPiece).transform.eulerAngles.z);
				}
				((Component)HitPiece).transform.rotation = rotation;
			}
			if (Input.GetAxis("Mouse ScrollWheel") < 0f)
			{
				Quaternion rotation2;
				if (controlFlag)
				{
					num -= 1f;
					rotation2 = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x + num4 * num, ((Component)HitPiece).transform.eulerAngles.y, ((Component)HitPiece).transform.eulerAngles.z);
				}
				else if (altFlag)
				{
					num2 -= 1f;
					rotation2 = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x, ((Component)HitPiece).transform.eulerAngles.y, ((Component)HitPiece).transform.eulerAngles.z + num4 * num2);
				}
				else
				{
					num3 -= 1f;
					rotation2 = Quaternion.Euler(((Component)HitPiece).transform.eulerAngles.x, ((Component)HitPiece).transform.eulerAngles.y + num4 * num3, ((Component)HitPiece).transform.eulerAngles.z);
				}
				((Component)HitPiece).transform.rotation = rotation2;
			}
			float num5 = 0.1f * currentModificationSpeed;
			if (Input.GetKeyDown((KeyCode)273))
			{
				if (controlFlag)
				{
					((Component)HitPiece).transform.Translate(Vector3.up * num5);
				}
				else
				{
					((Component)HitPiece).transform.Translate(Vector3.forward * num5);
				}
			}
			if (Input.GetKeyDown((KeyCode)274))
			{
				if (controlFlag)
				{
					((Component)HitPiece).transform.Translate(Vector3.down * num5);
				}
				else
				{
					((Component)HitPiece).transform.Translate(Vector3.back * num5);
				}
			}
			if (Input.GetKeyDown((KeyCode)276))
			{
				((Component)HitPiece).transform.Translate(Vector3.left * num5);
			}
			if (Input.GetKeyDown((KeyCode)275))
			{
				((Component)HitPiece).transform.Translate(Vector3.right * num5);
			}
		}

		private static bool hitPieceStillExists()
		{
			try
			{
				if (isActive)
				{
					isInExistence = true;
				}
			}
			catch
			{
				isInExistence = false;
			}
			return isInExistence;
		}

		private static bool isValidRayCastTarget()
		{
			//IL_0018: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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)
			bool result = true;
			if (HitPiece.m_onlyInTeleportArea && !Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(((Component)HitPiece).transform.position, (Type)16, 0f)))
			{
				result = false;
			}
			if (!HitPiece.m_allowedInDungeons && ((Component)HitPiece).transform.position.y > 3000f)
			{
				result = false;
			}
			if (Location.IsInsideNoBuildLocation(((Component)HitPiece).transform.position))
			{
				result = false;
			}
			float num = (Object.op_Implicit((Object)(object)((Component)HitPiece).GetComponent<PrivateArea>()) ? ((Component)HitPiece).GetComponent<PrivateArea>().m_radius : 0f);
			if (!PrivateArea.CheckAccess(((Component)HitPiece).transform.position, num, true, false))
			{
				result = false;
			}
			if (WardIsLovePlugin.IsLoaded() && WardIsLovePlugin.WardEnabled().Value && WardMonoscript.CheckInWardMonoscript(((Component)HitPiece).transform.position) && !WardMonoscript.CheckAccess(((Component)HitPiece).transform.position, num))
			{
				result = false;
			}
			return result;
		}

		private static bool isInBuildMode()
		{
			return ((Character)PlayerInstance).InPlaceMode();
		}

		private static void resetObjectTransform()
		{
			//IL_0015: 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)
			notifyUser("Object has been reset to initial position & rotation.", (MessageType)1);
			((Component)HitPiece).transform.position = InitialPosition;
			((Component)HitPiece).transform.rotation = InitialRotation;
		}

		private static void resetObjectInfo()
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			HitPoint = Vector3.zero;
			HitNormal = Vector3.zero;
			HitObject = null;
			HitPiece = null;
			HitHeightmap = null;
			InitialRotation = default(Quaternion);
			InitialPosition = default(Vector3);
		}

		private static void startMode()
		{
			notifyUser("Entering AEM", (MessageType)1);
			isActive = true;
		}

		private static void exitMode()
		{
			notifyUser("Exiting AEM", (MessageType)1);
			forceExitNextIteration = true;
		}

		private static void notifyUser(string Message, MessageType position = 1)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			MessageHud.instance.ShowMessage(position, "AEM: " + Message, 0, (Sprite)null);
		}

		private static void isRunning()
		{
			if (isActive)
			{
				MessageHud.instance.ShowMessage((MessageType)2, "AEM is active", 0, (Sprite)null);
			}
		}

		private static bool isContainer()
		{
			return (Object)(object)((Component)HitPiece).GetComponent<Container>() != (Object)null;
		}

		private static void dropContainerContents()
		{
			((Component)HitPiece).GetComponent<Container>().DropAllItems();
		}

		private static void changeModificationSpeed()
		{
			//IL_0018: 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)
			float num = 1f;
			if (shiftFlag)
			{
				num = 10f;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.aemincreaseScrollSpeed.Value))
			{
				currentModificationSpeed = Mathf.Clamp(currentModificationSpeed + num, 1f, 30f);
				notifyUser("Modification Speed: " + currentModificationSpeed, (MessageType)1);
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.aemdecreaseScrollSpeed.Value))
			{
				currentModificationSpeed = Mathf.Clamp(currentModificationSpeed - num, 1f, 30f);
				notifyUser("Modification Speed: " + currentModificationSpeed, (MessageType)1);
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
	public static class BlockCameraScrollInAEM
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		private static void Prefix(GameCamera __instance)
		{
			if (AEM.isActive)
			{
				__instance.m_maxDistance = __instance.m_distance;
				__instance.m_minDistance = __instance.m_distance;
			}
			else
			{
				__instance.m_maxDistance = 6f;
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[HarmonyPatch(typeof(Player), "Update")]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	public static class Player_Update_Patch
	{
		private static GameObject timeObj = null;

		private static double savedEnvMinutes = -1.0;

		private static void Postfix(ref Player __instance, ref Vector3 ___m_moveDir, ref Vector3 ___m_lookDir, ref GameObject ___m_placementGhost, Transform ___m_eye)
		{
			if (((Character)__instance).m_nview.IsValid() && ((Character)__instance).m_nview.IsOwner())
			{
				if (PerfectPlacementPlugin.aemIsEnabled.Value == PerfectPlacementPlugin.Toggle.On)
				{
					AEM.PlayerInstance = __instance;
					AEM.run();
				}
				if (PerfectPlacementPlugin.abmIsEnabled.Value == PerfectPlacementPlugin.Toggle.On)
				{
					ABM.Run(ref __instance);
				}
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	public static class ModifyPUpdatePlacement
	{
		private static void Postfix(Player __instance, bool takeInput, float dt)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (PerfectPlacementPlugin.fpmIsEnabled.Value != 0 && !ABM.isActive && ((Character)__instance).InPlaceMode() && takeInput && !Hud.IsPieceSelectionVisible())
			{
				if (!PerfectPlacementPlugin.PlayersData.ContainsKey(__instance))
				{
					PerfectPlacementPlugin.PlayersData[__instance] = new PerfectPlacementPlugin.PlayerData();
				}
				RotateWithWheel(__instance);
				SyncRotationWithTargetInFront(__instance, PerfectPlacementPlugin.fpmcopyRotationParallel.Value, perpendicular: false);
				SyncRotationWithTargetInFront(__instance, PerfectPlacementPlugin.fpmcopyRotationPerpendicular.Value, perpendicular: true);
			}
		}

		private static void RotateWithWheel(Player __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_012a: 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_0114: 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_00ca: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			float axis = Input.GetAxis("Mouse ScrollWheel");
			PerfectPlacementPlugin.PlayerData playerData = PerfectPlacementPlugin.PlayersData[__instance];
			if (!axis.Equals(0f) || ZInput.GetButton("JoyRotate"))
			{
				if (Input.GetKey(PerfectPlacementPlugin.fpmrotateY.Value))
				{
					playerData.PlaceRotation += Vector3.up * Mathf.Sign(axis);
					__instance.m_placeRotation = (int)(playerData.PlaceRotation.y / 22.5f);
				}
				else if (Input.GetKey(PerfectPlacementPlugin.fpmrotateX.Value))
				{
					playerData.PlaceRotation += Vector3.right * Mathf.Sign(axis);
				}
				else if (Input.GetKey(PerfectPlacementPlugin.fpmrotateZ.Value))
				{
					playerData.PlaceRotation += Vector3.forward * Mathf.Sign(axis);
				}
				else
				{
					__instance.m_placeRotation = Util.ClampPlaceRotation(__instance.m_placeRotation);
					playerData.PlaceRotation = new Vector3(0f, (float)__instance.m_placeRotation * 22.5f, 0f);
				}
				playerData.PlaceRotation = Util.ClampAngles(playerData.PlaceRotation);
				Vector3 placeRotation = playerData.PlaceRotation;
				Debug.Log((object)("Angle " + ((object)(Vector3)(ref placeRotation)).ToString()));
			}
		}

		private static void SyncRotationWithTargetInFront(Player __instance, KeyCode keyCode, bool perpendicular)
		{
			//IL_000f: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_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)
			Vector3 val = default(Vector3);
			Vector3 val2 = default(Vector3);
			Piece val3 = default(Piece);
			Heightmap val4 = default(Heightmap);
			Collider val5 = default(Collider);
			if (!((Object)(object)__instance.m_placementGhost == (Object)null) && Input.GetKeyUp(keyCode) && __instance.PieceRayTest(ref val, ref val2, ref val3, ref val4, ref val5, false) && (Object)(object)val3 != (Object)null)
			{
				PerfectPlacementPlugin.PlayerData playerData = PerfectPlacementPlugin.PlayersData[__instance];
				Quaternion val6 = ((Component)val3).transform.rotation;
				if (perpendicular)
				{
					val6 *= Quaternion.Euler(0f, 90f, 0f);
				}
				if (playerData.LastKeyCode != keyCode || (Object)(object)playerData.LastPiece != (Object)(object)val3)
				{
					playerData.Opposite = false;
				}
				playerData.LastKeyCode = keyCode;
				playerData.LastPiece = val3;
				if (playerData.Opposite)
				{
					val6 *= Quaternion.Euler(0f, 180f, 0f);
				}
				playerData.Opposite = !playerData.Opposite;
				playerData.PlaceRotation = ((Quaternion)(ref val6)).eulerAngles;
				Vector3 placeRotation = playerData.PlaceRotation;
				Debug.Log((object)("Sync Angle " + ((object)(Vector3)(ref placeRotation)).ToString()));
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	public static class ModifyPlacingRestrictionOfGhost
	{
		private static void Postfix(Player __instance, bool flashGuardStone)
		{
			if (PerfectPlacementPlugin.fpmIsEnabled.Value != 0 && !ABM.isActive)
			{
				UpdatePlacementGhost(__instance, flashGuardStone);
			}
		}

		private static void UpdatePlacementGhost(Player __instance, bool flashGuardStone)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0710: 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_00cb: 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_0093: 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_0717: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Invalid comparison between Unknown and I4
			//IL_0125: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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_01d8: 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_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: 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_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Invalid comparison between Unknown and I4
			//IL_02bd: 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_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_055b: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: 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_057d: 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_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_0693: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.m_placementGhost == (Object)null)
			{
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					__instance.m_placementMarkerInstance.SetActive(false);
				}
				return;
			}
			bool flag = ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltPlace");
			Piece component = __instance.m_placementGhost.GetComponent<Piece>();
			bool flag2 = component.m_waterPiece || component.m_noInWater;
			Vector3 val = default(Vector3);
			Vector3 up = default(Vector3);
			Piece val2 = default(Piece);
			Heightmap val3 = default(Heightmap);
			Collider val4 = default(Collider);
			if (__instance.PieceRayTest(ref val, ref up, ref val2, ref val3, ref val4, flag2))
			{
				__instance.m_placementStatus = (PlacementStatus)0;
				if ((Object)(object)__instance.m_placementMarkerInstance == (Object)null)
				{
					__instance.m_placementMarkerInstance = Object.Instantiate<GameObject>(__instance.m_placeMarker, val, Quaternion.identity);
				}
				__instance.m_placementMarkerInstance.SetActive(true);
				__instance.m_placementMarkerInstance.transform.position = val;
				__instance.m_placementMarkerInstance.transform.rotation = Quaternion.LookRotation(up);
				if (component.m_groundOnly || component.m_groundPiece || component.m_cultivatedGroundOnly)
				{
					__instance.m_placementMarkerInstance.SetActive(false);
				}
				WearNTear val5 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<WearNTear>() : null);
				StationExtension component2 = ((Component)component).GetComponent<StationExtension>();
				if ((Object)(object)component2 != (Object)null)
				{
					CraftingStation val6 = component2.FindClosestStationInRange(val);
					if (Object.op_Implicit((Object)(object)val6))
					{
						component2.StartConnectionEffect(val6, 1f);
					}
					else
					{
						component2.StopConnectionEffect();
						__instance.m_placementStatus = (PlacementStatus)7;
					}
					if (component2.OtherExtensionInRange(component.m_spaceRequirement))
					{
						__instance.m_placementStatus = (PlacementStatus)5;
					}
				}
				if (Object.op_Implicit((Object)(object)val5) && !val5.m_supports)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_waterPiece && (Object)(object)val4 == (Object)null && !flag)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_noInWater && (Object)(object)val4 != (Object)null)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_groundPiece && (Object)(object)val3 == (Object)null)
				{
					__instance.m_placementGhost.SetActive(false);
					__instance.m_placementStatus = (PlacementStatus)1;
					return;
				}
				if (component.m_groundOnly && (Object)(object)val3 == (Object)null)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_cultivatedGroundOnly && ((Object)(object)val3 == (Object)null || !val3.IsCultivated(val)))
				{
					__instance.m_placementStatus = (PlacementStatus)9;
				}
				if (component.m_notOnWood && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val5) && ((int)val5.m_materialType == 0 || (int)val5.m_materialType == 3))
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_notOnTiltingSurface && (double)up.y < 0.800000011920929)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_inCeilingOnly && (double)up.y > -0.5)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_notOnFloor && (double)up.y > 0.100000001490116)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
				if (component.m_onlyInTeleportArea && !Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(val, (Type)16, 0f)))
				{
					__instance.m_placementStatus = (PlacementStatus)6;
				}
				if (!component.m_allowedInDungeons && ((Character)__instance).InInterior())
				{
					__instance.m_placementStatus = (PlacementStatus)11;
				}
				if (Object.op_Implicit((Object)(object)val3))
				{
					up = Vector3.up;
				}
				__instance.m_placementGhost.SetActive(true);
				Quaternion rotation = Quaternion.Euler(PerfectPlacementPlugin.PlayersData.ContainsKey(__instance) ? PerfectPlacementPlugin.PlayersData[__instance].PlaceRotation : ((float)__instance.m_placeRotation * 22.5f * Vector3.up));
				if (((component.m_groundPiece || component.m_clipGround) && Object.op_Implicit((Object)(object)val3)) || component.m_clipEverything)
				{
					if (Object.op_Implicit((Object)(object)__instance.m_buildPieces.GetSelectedPrefab().GetComponent<TerrainModifier>()) && component.m_allowAltGroundPlacement && component.m_groundPiece && !ZInput.GetButton("AltPlace") && !ZInput.GetButton("JoyAltPlace"))
					{
						float groundHeight = ZoneSystem.instance.GetGroundHeight(((Component)__instance).transform.position);
						val.y = groundHeight;
					}
					__instance.m_placementGhost.transform.position = val;
					__instance.m_placementGhost.transform.rotation = rotation;
				}
				else
				{
					Collider[] componentsInChildren = __instance.m_placementGhost.GetComponentsInChildren<Collider>();
					if (componentsInChildren.Length != 0)
					{
						__instance.m_placementGhost.transform.position = val + up * 50f;
						__instance.m_placementGhost.transform.rotation = rotation;
						Vector3 val7 = Vector3.zero;
						float num = 999999f;
						Collider[] array = componentsInChildren;
						foreach (Collider val8 in array)
						{
							if (val8.isTrigger || !val8.enabled)
							{
								continue;
							}
							MeshCollider val9 = (MeshCollider)(object)((val8 is MeshCollider) ? val8 : null);
							if (!((Object)(object)val9 != (Object)null) || val9.convex)
							{
								Vector3 val10 = val8.ClosestPoint(val);
								float num2 = Vector3.Distance(val10, val);
								if ((double)num2 < (double)num)
								{
									val7 = val10;
									num = num2;
								}
							}
						}
						Vector3 val11 = __instance.m_placementGhost.transform.position - val7;
						if (component.m_waterPiece)
						{
							val11.y = 3f;
						}
						__instance.m_placementGhost.transform.position = val + val11;
						__instance.m_placementGhost.transform.rotation = rotation;
					}
				}
				if (!flag)
				{
					__instance.m_tempPieces.Clear();
					Transform val12 = default(Transform);
					Transform val13 = default(Transform);
					if (__instance.FindClosestSnapPoints(__instance.m_placementGhost.transform, 0.5f, ref val12, ref val13, __instance.m_tempPieces))
					{
						_ = val13.parent.position;
						Vector3 val14 = val13.position - (val12.position - __instance.m_placementGhost.transform.position);
						if (!__instance.IsOverlappingOtherPiece(val14, __instance.m_placementGhost.transform.rotation, ((Object)__instance.m_placementGhost).name, __instance.m_tempPieces, component.m_allowRotatedOverlap))
						{
							__instance.m_placementGhost.transform.position = val14;
						}
					}
				}
				if (Location.IsInsideNoBuildLocation(__instance.m_placementGhost.transform.position))
				{
					__instance.m_placementStatus = (PlacementStatus)3;
				}
				if (!PrivateArea.CheckAccess(__instance.m_placementGhost.transform.position, Object.op_Implicit((Object)(object)((Component)component).GetComponent<PrivateArea>()) ? ((Component)component).GetComponent<PrivateArea>().m_radius : 0f, flashGuardStone, false))
				{
					__instance.m_placementStatus = (PlacementStatus)4;
				}
				if (WardIsLovePlugin.IsLoaded() && WardIsLovePlugin.WardEnabled().Value && WardMonoscript.CheckInWardMonoscript(__instance.m_placementGhost.transform.position))
				{
					WardMonoscript wardMonoscript = WardMonoscriptExt.GetWardMonoscript(__instance.m_placementGhost.transform.position);
					if (wardMonoscript != null && !WardMonoscript.CheckAccess(__instance.m_placementGhost.transform.position, wardMonoscript.GetWardRadius(), flashGuardStone))
					{
						__instance.m_placementStatus = (PlacementStatus)4;
					}
				}
				if (__instance.CheckPlacementGhostVSPlayers())
				{
					__instance.m_placementStatus = (PlacementStatus)2;
				}
				if ((int)component.m_onlyInBiome != 0 && (Heightmap.FindBiome(__instance.m_placementGhost.transform.position) & component.m_onlyInBiome) == 0)
				{
					__instance.m_placementStatus = (PlacementStatus)8;
				}
				if (component.m_noClipping && __instance.TestGhostClipping(__instance.m_placementGhost, 0.2f))
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
			}
			else
			{
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					__instance.m_placementMarkerInstance.SetActive(false);
				}
				__instance.m_placementGhost.SetActive(false);
				__instance.m_placementStatus = (PlacementStatus)1;
			}
			__instance.SetPlacementGhostValid((int)__instance.m_placementStatus == 0);
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	public static class Player_UpdatePlacementGhost_Patch
	{
		private static Vector3? ghostPosition;

		private static Quaternion? ghostRotation;

		private static Vector3? markerPosition;

		private static Quaternion? markerRotation;

		private static void Prefix(ref Player __instance, bool flashGuardStone)
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (ABM.isActive)
			{
				if (Object.op_Implicit((Object)(object)__instance.m_placementGhost))
				{
					ghostPosition = __instance.m_placementGhost.transform.position + Vector3.zero;
					ghostRotation = __instance.m_placementGhost.transform.rotation * Quaternion.identity;
				}
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					markerPosition = __instance.m_placementMarkerInstance.transform.position + Vector3.zero;
					markerRotation = __instance.m_placementMarkerInstance.transform.rotation * Quaternion.identity;
				}
			}
		}

		private static void Postfix(ref Player __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			if (ABM.isActive)
			{
				__instance.m_placementGhost.transform.position = ghostPosition.Value;
				__instance.m_placementGhost.transform.rotation = ghostRotation.Value;
				ghostPosition = null;
				ghostRotation = null;
				__instance.m_placementMarkerInstance.transform.position = markerPosition.Value;
				__instance.m_placementMarkerInstance.transform.rotation = markerRotation.Value;
				markerPosition = null;
				markerRotation = null;
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					__instance.m_placementMarkerInstance.SetActive(false);
				}
			}
			if (ABM.exitOnNextIteration)
			{
				try
				{
					if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
					{
						__instance.m_placementMarkerInstance.SetActive(false);
					}
				}
				catch
				{
				}
			}
			if (PerfectPlacementPlugin.gridAlignmentEnabled.Value == PerfectPlacementPlugin.Toggle.On && (GridAlignment.AlignPressed ^ GridAlignment.AlignToggled))
			{
				GridAlignment.UpdatePlacementGhost(__instance);
			}
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[HarmonyPatch(typeof(Player), "Update")]
	public static class GridAlignment
	{
		public static int DefaultAlignment = 100;

		public static bool AlignPressed = false;

		public static bool AlignToggled = false;

		private static void Postfix(ref Player __instance)
		{
			//IL_001c: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (!((Character)__instance).IsPlayer() || PerfectPlacementPlugin.gridAlignmentEnabled.Value == PerfectPlacementPlugin.Toggle.Off)
			{
				return;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.alignToGrid.Value))
			{
				AlignPressed = true;
			}
			if (Input.GetKeyUp(PerfectPlacementPlugin.alignToGrid.Value))
			{
				AlignPressed = false;
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.changeDefaultAlignment.Value))
			{
				if (DefaultAlignment == 50)
				{
					DefaultAlignment = 100;
				}
				else if (DefaultAlignment == 100)
				{
					DefaultAlignment = 200;
				}
				else if (DefaultAlignment == 200)
				{
					DefaultAlignment = 400;
				}
				else
				{
					DefaultAlignment = 50;
				}
				MessageHud.instance.ShowMessage((MessageType)1, "Default grid alignment set to " + (float)DefaultAlignment / 100f, 0, (Sprite)null);
			}
			if (Input.GetKeyDown(PerfectPlacementPlugin.alignToggle.Value))
			{
				AlignToggled = !AlignToggled;
				MessageHud.instance.ShowMessage((MessageType)1, "Grid alignment by default " + (AlignToggled ? "enabled" : "disabled"), 0, (Sprite)null);
			}
		}

		private static float FixAlignment(float f)
		{
			int num = (int)Mathf.Round(f * 100f);
			if (num <= 0)
			{
				return (float)DefaultAlignment / 100f;
			}
			if (num <= 50)
			{
				return 0.5f;
			}
			if (num <= 100)
			{
				return 1f;
			}
			if (num <= 200)
			{
				return 2f;
			}
			return 4f;
		}

		public static void GetAlignment(Piece piece, out Vector3 alignment, out Vector3 offset)
		{
			//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_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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> list = new List<Transform>();
			piece.GetSnapPoints(list);
			if (list.Count != 0)
			{
				Vector3 val = Vector3.positiveInfinity;
				Vector3 val2 = Vector3.negativeInfinity;
				foreach (Transform item in list)
				{
					Vector3 localPosition = item.localPosition;
					val = Vector3.Min(val, localPosition);
					val2 = Vector3.Max(val2, localPosition);
				}
				alignment = val2 - val;
				alignment.x = FixAlignment(alignment.x);
				alignment.y = FixAlignment(alignment.y);
				alignment.z = FixAlignment(alignment.z);
				offset = val2;
				string name = ((Object)piece).name;
				if ((name == "iron_grate" || name == "wood_gate") ? true : false)
				{
					offset.y = val.y;
				}
				if (((Object)piece).name == "wood_gate")
				{
					alignment.x = 4f;
				}
			}
			else if (piece.m_notOnFloor || ((Object)piece).name == "sign" || ((Object)piece).name == "itemstand")
			{
				alignment = new Vector3(0.5f, 0.5f, 0f);
				offset = new Vector3(0f, 0f, 0f);
				if (((Object)piece).name == "sign")
				{
					alignment.y = 0.25f;
				}
			}
			else if (((Object)piece).name == "piece_walltorch")
			{
				alignment = new Vector3(0f, 0.5f, 0.5f);
				offset = new Vector3(0f, 0f, 0f);
			}
			else
			{
				alignment = new Vector3(0.5f, 0f, 0.5f);
				offset = new Vector3(0f, 0f, 0f);
			}
		}

		public static float Align(float value, out float alpha)
		{
			float num = Mathf.Round(value);
			alpha = value - num;
			return num;
		}

		public static void UpdatePlacementGhost(Player player)
		{
			//IL_004a: 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_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_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_0066: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b9: 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_0171: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player.m_placementGhost == (Object)null || !((Character)player).IsPlayer() || ABM.isActive)
			{
				return;
			}
			bool num = ZInput.GetButton("AltPlace") || ZInput.GetButton("JoyAltPlace");
			Piece component = player.m_placementGhost.GetComponent<Piece>();
			Vector3 val = ((Component)component).transform.position;
			val = Quaternion.Inverse(((Component)component).transform.rotation) * val;
			GetAlignment(component, out var alignment, out var offset);
			val += offset;
			Vector3 val2 = val;
			((Vector3)(ref val))..ctor(val.x / alignment.x, val.y / alignment.y, val.z / alignment.z);
			((Vector3)(ref val))..ctor(Align(val.x, out var alpha), Align(val.y, out var alpha2), Align(val.z, out var alpha3));
			if (num)
			{
				float num2 = 0.2f;
				if (Mathf.Abs(alpha) >= num2 && Mathf.Abs(alpha) >= Mathf.Abs(alpha2) && Mathf.Abs(alpha) >= Mathf.Abs(alpha3))
				{
					val.x += Mathf.Sign(alpha);
				}
				else if (Mathf.Abs(alpha2) >= num2 && Mathf.Abs(alpha2) >= Mathf.Abs(alpha3))
				{
					val.y += Mathf.Sign(alpha2);
				}
				else if (Mathf.Abs(alpha3) >= num2)
				{
					val.z += Mathf.Sign(alpha3);
				}
			}
			((Vector3)(ref val))..ctor(val.x * alignment.x, val.y * alignment.y, val.z * alignment.z);
			if (alignment.x <= 0f)
			{
				val.x = val2.x;
			}
			if (alignment.y <= 0f)
			{
				val.y = val2.y;
			}
			if (alignment.z <= 0f)
			{
				val.z = val2.z;
			}
			val -= offset;
			val = ((Component)component).transform.rotation * val;
			((Component)component).transform.position = val;
		}
	}
}
namespace PerfectPlacement.Patches.Compatibility
{
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	public class ModCompat
	{
		public static T InvokeMethod<[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(2)] T>(Type type, object instance, string methodName, object[] parameter)
		{
			return (T)(type.GetMethod(methodName)?.Invoke(instance, parameter));
		}

		public static T GetField<[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(2)] T>(Type type, object instance, string fieldName)
		{
			return (T)(type.GetField(fieldName)?.GetValue(instance));
		}
	}
}
namespace PerfectPlacement.Patches.Compatibility.WardIsLove
{
	public class CustomCheck : ModCompat
	{
		[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
		public static Type ClassType()
		{
			return Type.GetType("WardIsLove.Util.CustomCheck, WardIsLove");
		}

		public static bool CheckAccess(long playerID, Vector3 point, float radius = 0f, bool flash = true)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			return ModCompat.InvokeMethod<bool>(ClassType(), null, "CheckAccess", new object[4] { playerID, point, radius, flash });
		}
	}
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	public class WardIsLovePlugin : ModCompat
	{
		private const string GUID = "Azumatt.WardIsLove";

		private static readonly Version MinVersion = new Version(2, 3, 3);

		public static Type ClassType()
		{
			return Type.GetType("WardIsLove.WardIsLovePlugin, WardIsLove");
		}

		public static bool IsLoaded()
		{
			if (Chainloader.PluginInfos.ContainsKey("Azumatt.WardIsLove"))
			{
				return Chainloader.PluginInfos["Azumatt.WardIsLove"].Metadata.Version >= MinVersion;
			}
			return false;
		}

		public static ConfigEntry<bool> WardEnabled()
		{
			return ModCompat.GetField<ConfigEntry<bool>>(ClassType(), null, "WardEnabled");
		}
	}
	[<30de3432-c0c0-453d-9746-1305176a74f7>NullableContext(1)]
	[<e01ef41d-c0c9-4c03-a3c6-30846ae87bb6>Nullable(0)]
	public class WardMonoscript : ModCompat
	{
		public object targetScript;

		public static Type ClassType()
		{
			return Type.GetType("WardIsLove.Util.WardMonoscript, WardIsLove");
		}

		public WardMonoscript(object targetScript)
		{
			this.targetScript = targetScript;
		}

		public static bool CheckInWardMonoscript(Vector3 point, bool flash = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ModCompat.InvokeMethod<bool>(ClassType(), null, "CheckInWardMonoscript", new object[2] { point, flash });