Decompiled source of Infinity Hammer v1.77.0

InfinityHammer.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Data;
using HarmonyLib;
using InfinityHammer;
using InfinityTools;
using Microsoft.CodeAnalysis;
using ServerDevcommands;
using Service;
using SoftReferenceableAssets;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using WorldEditCommands;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("InfinityHammer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+79b3eb6259117f3f99d7f5180ba85bc3b0ff7f5d")]
[assembly: AssemblyProduct("InfinityHammer")]
[assembly: AssemblyTitle("InfinityHammer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Service
{
	public class ConfigWrapper
	{
		private readonly ConfigFile ConfigFile;

		private readonly Dictionary<string, Action<Terminal, string>> SettingHandlers = new Dictionary<string, Action<Terminal, string>>();

		private readonly List<Action> Binders = new List<Action>();

		private bool BindsDone;

		private static readonly HashSet<string> Truthies = new HashSet<string> { "1", "t", "true", "yes", "on" };

		private static readonly HashSet<string> Falsies = new HashSet<string> { "0", "f", "false", "no", "off" };

		public ConfigWrapper(string command, ConfigFile configFile)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_004e: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			ConfigFile = configFile;
			new ConsoleCommand(command, "[key] [value] - Toggles or sets a config value.", (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				if (args.Length >= 2 && SettingHandlers.TryGetValue(args[1].ToLower(), out Action<Terminal, string> value))
				{
					if (args.Length == 2)
					{
						value(args.Context, "");
					}
					else
					{
						value(args.Context, string.Join(" ", args.Args, 2, args.Length - 2));
					}
				}
			}, false, false, false, false, false, (ConsoleOptionsFetcher)(() => SettingHandlers.Keys.ToList()), false, false, false);
		}

		private ConfigEntry<T> Create<T>(string group, string name, T value, ConfigDescription description)
		{
			return ConfigFile.Bind<T>(group, name, value, description);
		}

		private ConfigEntry<T> Create<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Create(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public ConfigEntry<T> Bind<T>(string group, string name, T value, ConfigDescription description)
		{
			ConfigEntry<T> val = Create(group, name, value, description);
			if (val is ConfigEntry<bool> setting)
			{
				Register(setting);
			}
			else if (val is ConfigEntry<KeyboardShortcut> setting2)
			{
				Register(setting2);
			}
			else
			{
				Register<T>(val);
			}
			return val;
		}

		public ConfigEntry<string> BindList(string group, string name, string value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public ConfigEntry<string> BindList(string group, string name, string value, ConfigDescription description)
		{
			ConfigEntry<string> val = Create(group, name, value, description);
			RegisterList(val);
			return val;
		}

		public ConfigEntry<KeyboardShortcut> BindCommand(string command, string group, string name, KeyboardShortcut value, string description, string mode = "")
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			string command2 = command;
			return BindCommand(() => command2, group, name, value, description, mode);
		}

		public ConfigEntry<KeyboardShortcut> BindCommand(Func<string> command, string group, string name, KeyboardShortcut value, string description, string mode)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return BindCommand(command, group, name, value, description, "", mode);
		}

		public ConfigEntry<KeyboardShortcut> BindCommand(Func<string> command, string group, string name, KeyboardShortcut value, string description, string offCommand, string mode)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Func<string> command2 = command;
			string text = ToKey(name);
			string text2 = "_bind_" + text;
			Helper.Command(text2, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				string text3 = command2();
				if (args.Length == 1)
				{
					args.Context.TryRunCommand(text3, false, false);
				}
				else
				{
					string args2 = HammerHelper.GetArgs(args[0], args);
					args.Context.TryRunCommand(text3 + " " + args2, false, false);
				}
			});
			ConfigEntry<KeyboardShortcut> val = Create<KeyboardShortcut>(group, name, value, description);
			RegisterCommand(val, text2, offCommand, mode);
			return val;
		}

		public ConfigEntry<KeyboardShortcut> BindWheelCommand(string command, string group, string name, KeyboardShortcut value, string description, string mode = "")
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			string command2 = command;
			return BindWheelCommand(() => command2, group, name, value, description, mode);
		}

		public ConfigEntry<KeyboardShortcut> BindWheelCommand(Func<string> command, string group, string name, KeyboardShortcut value, string description, string mode = "")
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Func<string> command2 = command;
			string text = ToKey(name);
			string text2 = "_bind_" + text;
			Helper.Command(text2, description, (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				string text3 = command2();
				if (args.Length == 1)
				{
					args.Context.TryRunCommand(text3, false, false);
				}
				else
				{
					string args2 = HammerHelper.GetArgs(args[0], args);
					args.Context.TryRunCommand(text3 + " " + args2, false, false);
				}
			});
			ConfigEntry<KeyboardShortcut> val = Create<KeyboardShortcut>(group, name, value, description);
			RegisterWheelCommand(val, text2, "", mode);
			return val;
		}

		public ConfigEntry<T> Bind<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static void AddMessage(Terminal context, string message)
		{
			context.AddString(message);
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)1, message, 0, (Sprite)null);
			}
		}

		public void Bind()
		{
			if (BindsDone)
			{
				return;
			}
			BindsDone = true;
			foreach (Action binder in Binders)
			{
				binder();
			}
		}

		private void Register(ConfigEntry<bool> setting)
		{
			ConfigEntry<bool> setting2 = setting;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				Toggle(terminal, setting2, name, value);
			});
		}

		public static string GetKeys(KeyboardShortcut key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref key)).MainKey == 0)
			{
				return "unbound";
			}
			KeyCode mainKey = ((KeyboardShortcut)(ref key)).MainKey;
			string text = ((object)(KeyCode)(ref mainKey)).ToString().ToLower();
			if (((KeyboardShortcut)(ref key)).Modifiers.Count() > 0)
			{
				text = text + "," + string.Join(",", ((KeyboardShortcut)(ref key)).Modifiers);
			}
			return text;
		}

		private void UpdateKey(KeyboardShortcut key, string command, string offCommand, string mode)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Chat.instance))
			{
				BindsDone = false;
			}
			else
			{
				BindManager.SetTemporaryBind(GetKeys(key), mode, command, offCommand);
			}
		}

		private string ToKey(string name)
		{
			return name.ToLower().Replace(' ', '_').Replace("(", "")
				.Replace(")", "");
		}

		private void RegisterCommand(ConfigEntry<KeyboardShortcut> setting, string command, string offCommand, string mode)
		{
			ConfigEntry<KeyboardShortcut> setting2 = setting;
			string command2 = command;
			string offCommand2 = offCommand;
			string mode2 = mode;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			setting2.SettingChanged += delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				UpdateKey(setting2.Value, command2, offCommand2, mode2);
			};
			Binders.Add(delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				UpdateKey(setting2.Value, command2, offCommand2, mode2);
			});
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetKey(terminal, setting2, name, value);
			});
		}

		private void UpdateWheelKey(KeyboardShortcut key, string command, string offCommand, string mode)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Chat.instance))
			{
				BindsDone = false;
				return;
			}
			List<string> list = new List<string>();
			if ((int)((KeyboardShortcut)(ref key)).MainKey != 0 || mode == "command")
			{
				list.Add("wheel");
				list.Add(GetKeys(key));
			}
			BindManager.SetTemporaryBind(string.Join(",", list), mode, command, offCommand);
		}

		private void RegisterWheelCommand(ConfigEntry<KeyboardShortcut> setting, string command, string offCommand, string mode)
		{
			ConfigEntry<KeyboardShortcut> setting2 = setting;
			string command2 = command;
			string offCommand2 = offCommand;
			string mode2 = mode;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			setting2.SettingChanged += delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				UpdateWheelKey(setting2.Value, command2, offCommand2, mode2);
			};
			Binders.Add(delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				UpdateWheelKey(setting2.Value, command2, offCommand2, mode2);
			});
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetKey(terminal, setting2, name, value);
			});
		}

		private void Register(ConfigEntry<KeyboardShortcut> setting)
		{
			ConfigEntry<KeyboardShortcut> setting2 = setting;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetKey(terminal, setting2, name, value);
			});
		}

		private void RegisterList(ConfigEntry<string> setting)
		{
			ConfigEntry<string> setting2 = setting;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				ToggleFlag(terminal, setting2, name, value);
			});
		}

		private void Register<T>(ConfigEntry<T> setting)
		{
			ConfigEntry<T> setting2 = setting;
			string name = ((ConfigEntryBase)setting2).Definition.Key;
			string key = ToKey(name);
			SettingHandlers.Add(key, delegate(Terminal terminal, string value)
			{
				SetValue<T>(terminal, setting2, name, value);
			});
		}

		private static string State(bool value)
		{
			if (!value)
			{
				return "disabled";
			}
			return "enabled";
		}

		private static string Flag(bool value)
		{
			if (!value)
			{
				return "Added";
			}
			return "Removed";
		}

		private static bool IsTruthy(string value)
		{
			return Truthies.Contains(value);
		}

		private static bool IsFalsy(string value)
		{
			return Falsies.Contains(value);
		}

		private static void Toggle(Terminal context, ConfigEntry<bool> setting, string name, string value)
		{
			if (value == "")
			{
				setting.Value = !setting.Value;
			}
			else if (IsTruthy(value))
			{
				setting.Value = true;
			}
			else if (IsFalsy(value))
			{
				setting.Value = false;
			}
			AddMessage(context, name + " " + State(setting.Value) + ".");
		}

		private static void SetKey(Terminal context, ConfigEntry<KeyboardShortcut> setting, string name, string value)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (value == "")
			{
				AddMessage(context, $"{name}: {setting.Value}.");
				return;
			}
			if (!Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result))
			{
				throw new InvalidOperationException("'" + value + "' is not a valid UnityEngine.KeyCode.");
			}
			setting.Value = new KeyboardShortcut(result, Array.Empty<KeyCode>());
			AddMessage(context, name + " set to " + value + ".");
		}

		public static int TryParseInt(string value, int defaultValue)
		{
			if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static int TryParseInt(ConfigEntry<string> setting)
		{
			if (int.TryParse(setting.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return TryParseInt((string)((ConfigEntryBase)setting).DefaultValue, 0);
		}

		private static float TryParseFloat(string value, float defaultValue)
		{
			if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static float TryParseFloat(ConfigEntry<string> setting)
		{
			if (float.TryParse(setting.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return TryParseFloat((string)((ConfigEntryBase)setting).DefaultValue, 0f);
		}

		private static HashSet<string> ParseList(string value)
		{
			return (from s in value.Split(new char[1] { ',' })
				select s.Trim().ToLower()).ToHashSet();
		}

		private static void ToggleFlag(Terminal context, ConfigEntry<string> setting, string name, string value)
		{
			if (value == "")
			{
				AddMessage(context, name + ": " + setting.Value + "\".");
				return;
			}
			HashSet<string> hashSet = ParseList(setting.Value);
			foreach (string item in ParseList(value))
			{
				bool flag = hashSet.Contains(item);
				if (flag)
				{
					hashSet.Remove(item);
				}
				else
				{
					hashSet.Add(item);
				}
				setting.Value = string.Join(",", hashSet);
				AddMessage(context, name + ": " + Flag(flag) + " \"" + item + "\".");
			}
		}

		private static void SetValue<T>(Terminal context, ConfigEntry<T> setting, string name, string value)
		{
			if (value == "")
			{
				AddMessage(context, $"{name}: {setting.Value}.");
				return;
			}
			if (value.Contains("/"))
			{
				string[] array = value.Split(new char[1] { '/' });
				value = array[0];
				for (int i = 0; i < array.Length - 1; i++)
				{
					T value2 = setting.Value;
					if (string.Equals((value2 != null) ? value2.ToString() : null, array[i], StringComparison.OrdinalIgnoreCase))
					{
						value = array[i + 1];
						break;
					}
				}
			}
			setting.Value = (T)(object)value;
			AddMessage(context, name + " set to " + value + ".");
		}
	}
	public class Log
	{
		private static ManualLogSource Logger;

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
		}

		public static void Error(string message)
		{
			Logger.LogError((object)message);
		}

		public static void Warning(string message)
		{
			Logger.LogWarning((object)message);
		}

		public static void Info(string message)
		{
			Logger.LogInfo((object)message);
		}

		public static void Debug(string message)
		{
			Logger.LogDebug((object)message);
		}
	}
	public class TerrainData
	{
		public Vector3 HeightmapPosition;

		public float?[,] Heights;

		public Color?[,] Paints;

		public Vector3 FirstNodePosition;

		public Quaternion FirstNodeRotation;

		public float DistanceBetweenNodes;

		public int Width;

		public int Height;

		public TerrainData(Vector3 heightmapPosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			HeightmapPosition = heightmapPosition;
			Heights = new float?[0, 0];
			Paints = new Color?[0, 0];
			FirstNodeRotation = Quaternion.identity;
			DistanceBetweenNodes = 1f;
			base..ctor();
		}

		public void SetReference(Vector3 center, Quaternion rotation)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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)
			FirstNodePosition -= center;
			FirstNodeRotation = rotation;
			for (int i = 0; i < Width; i++)
			{
				for (int j = 0; j < Height; j++)
				{
					if (Heights[i, j].HasValue)
					{
						Heights[i, j] -= center.y;
					}
				}
			}
		}

		public void InitializeGrid(int width, int height, Vector3 firstNodePos)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Width = width;
			Height = height;
			FirstNodePosition = firstNodePos;
			Heights = new float?[width, height];
			Paints = new Color?[width, height];
		}

		public void SetNode(int x, int z, float height, Color paint)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (x >= 0 && x < Width && z >= 0 && z < Height)
			{
				Heights[x, z] = height;
				Paints[x, z] = paint;
			}
		}

		public float? GetHeight(int x, int z)
		{
			if (x >= 0 && x < Width && z >= 0 && z < Height)
			{
				return Heights[x, z];
			}
			return null;
		}

		public Color? GetPaint(int x, int z)
		{
			if (x >= 0 && x < Width && z >= 0 && z < Height)
			{
				return Paints[x, z];
			}
			return null;
		}

		public float? FindNearestHeight(Vector3 nodePos, Vector3 placementPos, float rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = nodePos - FirstNodePosition - placementPos;
			if (rotation != 0f)
			{
				Vector3 val2 = -FirstNodePosition;
				Vector3 val3 = nodePos - placementPos;
				float num = Mathf.Cos(rotation) * val3.x - Mathf.Sin(rotation) * val3.z;
				float num2 = Mathf.Sin(rotation) * val3.x + Mathf.Cos(rotation) * val3.z;
				val.x = num + val2.x;
				val.z = num2 + val2.z;
			}
			int num3 = Mathf.RoundToInt(val.x);
			int num4 = Mathf.RoundToInt(val.z);
			if (num3 < 0 || num3 >= Width || num4 < 0 || num4 >= Height)
			{
				return null;
			}
			return GetHeight(num3, num4);
		}

		public Color? FindNearestPaint(Vector3 nodePos, Vector3 placementPos, float rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = nodePos - FirstNodePosition - placementPos;
			if (rotation != 0f)
			{
				Vector3 val2 = -FirstNodePosition;
				Vector3 val3 = nodePos - placementPos;
				float num = Mathf.Cos(rotation) * val3.x - Mathf.Sin(rotation) * val3.z;
				float num2 = Mathf.Sin(rotation) * val3.x + Mathf.Cos(rotation) * val3.z;
				val.x = num + val2.x;
				val.z = num2 + val2.z;
			}
			int num3 = Mathf.RoundToInt(val.x);
			int num4 = Mathf.RoundToInt(val.z);
			if (num3 < 0 || num3 >= Width || num4 < 0 || num4 >= Height)
			{
				return null;
			}
			return GetPaint(num3, num4);
		}
	}
	public class TerrainInfo
	{
		private static Vector3 VertexToWorld(Heightmap hmap, int x, int z)
		{
			//IL_0006: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)hmap).transform.position;
			position.x += (float)(x - hmap.m_width / 2) * hmap.m_scale;
			position.z += (float)(z - hmap.m_width / 2) * hmap.m_scale;
			return position;
		}

		private static float GetX(float x, float z, float angle)
		{
			return Mathf.Cos(angle) * x - Mathf.Sin(angle) * z;
		}

		private static float GetZ(float x, float z, float angle)
		{
			return Mathf.Sin(angle) * x + Mathf.Cos(angle) * z;
		}

		public static TerrainData GetTerrainDataWithCircle(TerrainComp compiler, Vector3 centerPos, float radius)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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)
			//IL_0144: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			TerrainData terrainData = new TerrainData(((Component)compiler.m_hmap).transform.position);
			if (radius == 0f)
			{
				return terrainData;
			}
			int num = compiler.m_width + 1;
			int num2 = num;
			int num3 = -1;
			int num4 = num;
			int num5 = -1;
			Vector3 firstNodePos = Vector3.zero;
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					Vector3 val = VertexToWorld(compiler.m_hmap, i, j);
					if (Utils.DistanceXZ(centerPos, val) <= radius)
					{
						if (!flag)
						{
							firstNodePos = val;
							flag = true;
						}
						num2 = Math.Min(num2, i);
						num3 = Math.Max(num3, i);
						num4 = Math.Min(num4, j);
						num5 = Math.Max(num5, j);
					}
				}
			}
			if (!flag)
			{
				return terrainData;
			}
			int width = num3 - num2 + 1;
			int height = num5 - num4 + 1;
			terrainData.InitializeGrid(width, height, firstNodePos);
			for (int k = 0; k < num; k++)
			{
				for (int l = 0; l < num; l++)
				{
					Vector3 val2 = VertexToWorld(compiler.m_hmap, k, l);
					if (!(Utils.DistanceXZ(centerPos, val2) > radius))
					{
						int num6 = l * num + k;
						val2.y = compiler.m_hmap.m_heights[num6];
						int x = k - num2;
						int z = l - num4;
						Color paint = ((num6 < compiler.m_paintMask.Length) ? compiler.m_paintMask[num6] : Color.clear);
						terrainData.SetNode(x, z, val2.y, paint);
					}
				}
			}
			return terrainData;
		}

		public static TerrainData GetTerrainDataWithRect(TerrainComp compiler, Vector3 centerPos, Range<float> width, Range<float> depth, float angle)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_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)
			TerrainData terrainData = new TerrainData(((Component)compiler.m_hmap).transform.position);
			if (width.Max == 0f || depth.Max == 0f)
			{
				return terrainData;
			}
			int num = compiler.m_width + 1;
			int num2 = num;
			int num3 = -1;
			int num4 = num;
			int num5 = -1;
			Vector3 firstNodePos = Vector3.zero;
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					Vector3 val = VertexToWorld(compiler.m_hmap, i, j);
					float x = val.x - centerPos.x;
					float z = val.z - centerPos.z;
					float x2 = GetX(x, z, angle);
					float z2 = GetZ(x, z, angle);
					if (Helper.Within(width, depth, Mathf.Abs(x2), Mathf.Abs(z2)))
					{
						if (!flag)
						{
							firstNodePos = val;
							flag = true;
						}
						num2 = Math.Min(num2, i);
						num3 = Math.Max(num3, i);
						num4 = Math.Min(num4, j);
						num5 = Math.Max(num5, j);
					}
				}
			}
			if (!flag)
			{
				return terrainData;
			}
			int width2 = num3 - num2 + 1;
			int height = num5 - num4 + 1;
			terrainData.InitializeGrid(width2, height, firstNodePos);
			for (int k = 0; k < num; k++)
			{
				for (int l = 0; l < num; l++)
				{
					Vector3 val2 = VertexToWorld(compiler.m_hmap, k, l);
					float x3 = val2.x - centerPos.x;
					float z3 = val2.z - centerPos.z;
					float x4 = GetX(x3, z3, angle);
					float z4 = GetZ(x3, z3, angle);
					if (Helper.Within(width, depth, Mathf.Abs(x4), Mathf.Abs(z4)))
					{
						int num6 = l * num + k;
						val2.y = compiler.m_hmap.m_heights[num6];
						int x5 = k - num2;
						int z5 = l - num4;
						Color paint = ((num6 < compiler.m_paintMask.Length) ? compiler.m_paintMask[num6] : Color.clear);
						terrainData.SetNode(x5, z5, val2.y, paint);
					}
				}
			}
			return terrainData;
		}

		public static TerrainData CollectTerrainDataInRadius(Vector3 centerPos, Quaternion centerRot, Vector3 searchPos, Range<float> radius)
		{
			//IL_0000: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			TerrainData terrainData = MergeHeightmapsWithCircle(Terrain.GetCompilers(searchPos, new Range<float>(radius.Max)).ToList(), searchPos, radius);
			terrainData.SetReference(centerPos, centerRot);
			return terrainData;
		}

		public static TerrainData CollectTerrainDataInRect(Vector3 centerPos, Quaternion centerRot, Vector3 searchPos, Range<float> width, Range<float> depth, float angle)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			float num = Math.Max(width.Max, depth.Max);
			TerrainData terrainData = MergeHeightmapsWithRect(Terrain.GetCompilers(searchPos, new Range<float>(num)).ToList(), centerPos, width, depth, angle);
			terrainData.SetReference(centerPos, centerRot);
			return terrainData;
		}

		private static TerrainData MergeHeightmapsWithCircle(List<TerrainComp> compilers, Vector3 centerPos, Range<float> radius)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			if (compilers.Count == 0)
			{
				return new TerrainData(centerPos);
			}
			float num = float.MaxValue;
			float num2 = float.MinValue;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			_ = Vector3.zero;
			bool flag = false;
			foreach (TerrainComp compiler in compilers)
			{
				int num5 = compiler.m_width + 1;
				for (int i = 0; i < num5; i++)
				{
					for (int j = 0; j < num5; j++)
					{
						Vector3 val = VertexToWorld(compiler.m_hmap, i, j);
						float num6 = Utils.DistanceXZ(centerPos, val);
						if (Helper.Within(radius, num6))
						{
							if (!flag)
							{
								flag = true;
							}
							num = Math.Min(num, val.x);
							num2 = Math.Max(num2, val.x);
							num3 = Math.Min(num3, val.z);
							num4 = Math.Max(num4, val.z);
						}
					}
				}
			}
			if (!flag)
			{
				return new TerrainData(centerPos);
			}
			int width = Mathf.RoundToInt(num2 - num) + 1;
			int height = Mathf.RoundToInt(num4 - num3) + 1;
			TerrainData terrainData = new TerrainData(centerPos);
			terrainData.InitializeGrid(width, height, new Vector3(num, 0f, num3));
			foreach (TerrainComp compiler2 in compilers)
			{
				int num7 = compiler2.m_width + 1;
				for (int k = 0; k < num7; k++)
				{
					for (int l = 0; l < num7; l++)
					{
						Vector3 val2 = VertexToWorld(compiler2.m_hmap, k, l);
						float num8 = Utils.DistanceXZ(centerPos, val2);
						if (Helper.Within(radius, num8))
						{
							int num9 = l * num7 + k;
							val2.y = compiler2.m_hmap.m_heights[num9];
							int x = Mathf.RoundToInt(val2.x - num);
							int z = Mathf.RoundToInt(val2.z - num3);
							if (!terrainData.GetHeight(x, z).HasValue)
							{
								Color paint = ((num9 < compiler2.m_paintMask.Length) ? compiler2.m_paintMask[num9] : Color.clear);
								terrainData.SetNode(x, z, val2.y, paint);
							}
						}
					}
				}
			}
			return terrainData;
		}

		private static TerrainData MergeHeightmapsWithRect(List<TerrainComp> compilers, Vector3 centerPos, Range<float> width, Range<float> depth, float angle)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_007a: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: 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_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: 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_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			if (compilers.Count == 0)
			{
				return new TerrainData(centerPos);
			}
			float num = float.MaxValue;
			float num2 = float.MinValue;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			_ = Vector3.zero;
			bool flag = false;
			foreach (TerrainComp compiler in compilers)
			{
				int num5 = compiler.m_width + 1;
				for (int i = 0; i < num5; i++)
				{
					for (int j = 0; j < num5; j++)
					{
						Vector3 val = VertexToWorld(compiler.m_hmap, i, j);
						float x = val.x - centerPos.x;
						float z = val.z - centerPos.z;
						float x2 = GetX(x, z, angle);
						float z2 = GetZ(x, z, angle);
						if (Helper.Within(width, depth, Mathf.Abs(x2), Mathf.Abs(z2)))
						{
							if (!flag)
							{
								flag = true;
							}
							num = Math.Min(num, val.x);
							num2 = Math.Max(num2, val.x);
							num3 = Math.Min(num3, val.z);
							num4 = Math.Max(num4, val.z);
						}
					}
				}
			}
			if (!flag)
			{
				return new TerrainData(centerPos);
			}
			int width2 = Mathf.RoundToInt(num2 - num) + 1;
			int height = Mathf.RoundToInt(num4 - num3) + 1;
			TerrainData terrainData = new TerrainData(centerPos);
			terrainData.InitializeGrid(width2, height, new Vector3(num, 0f, num3));
			foreach (TerrainComp compiler2 in compilers)
			{
				int num6 = compiler2.m_width + 1;
				for (int k = 0; k < num6; k++)
				{
					for (int l = 0; l < num6; l++)
					{
						Vector3 val2 = VertexToWorld(compiler2.m_hmap, k, l);
						float x3 = val2.x - centerPos.x;
						float z3 = val2.z - centerPos.z;
						float x4 = GetX(x3, z3, angle);
						float z4 = GetZ(x3, z3, angle);
						if (Helper.Within(width, depth, Mathf.Abs(x4), Mathf.Abs(z4)))
						{
							int num7 = l * num6 + k;
							val2.y = compiler2.m_hmap.m_heights[num7];
							int x5 = Mathf.RoundToInt(val2.x - num);
							int z5 = Mathf.RoundToInt(val2.z - num3);
							if (!terrainData.GetHeight(x5, z5).HasValue)
							{
								Color paint = ((num7 < compiler2.m_paintMask.Length) ? compiler2.m_paintMask[num7] : Color.clear);
								terrainData.SetNode(x5, z5, val2.y, paint);
							}
						}
					}
				}
			}
			return terrainData;
		}

		[Obsolete("Use direct TerrainData methods instead")]
		public static TerrainData? FindClosestHeightmap(List<TerrainData> heightmaps, Vector3 worldPos)
		{
			//IL_0034: 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)
			if (heightmaps.Count == 0)
			{
				return null;
			}
			if (heightmaps.Count == 1)
			{
				return heightmaps[0];
			}
			TerrainData result = null;
			float num = float.MaxValue;
			foreach (TerrainData heightmap in heightmaps)
			{
				float num2 = Vector3.Distance(worldPos, heightmap.HeightmapPosition);
				if (num2 < num)
				{
					num = num2;
					result = heightmap;
				}
			}
			return result;
		}
	}
}
namespace InfinityTools
{
	public abstract class BaseRuler : MonoBehaviour
	{
		private static LayerMask Mask = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { "terrain" }));

		private static GameObject? basePrefab;

		public static bool SnapToGround = true;

		public bool Visible = true;

		private GameObject? Center;

		protected List<GameObject> Segments = new List<GameObject>();

		public static float Offset = 0f;

		private readonly List<GameObject> OffsetSegments = new List<GameObject>();

		private static GameObject BasePrefab => basePrefab ?? (basePrefab = GetBasePrefab());

		protected static Vector3 BaseScale => BasePrefab.transform.localScale;

		private static GameObject GetBasePrefab()
		{
			GameObject prefab = ZNetScene.instance.GetPrefab("piece_workbench");
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Error: Unable to find the workbench object.");
			}
			return prefab.GetComponentInChildren<CircleProjector>().m_prefab;
		}

		public void OnDestroy()
		{
			foreach (GameObject segment in Segments)
			{
				Object.Destroy((Object)(object)segment);
			}
			foreach (GameObject offsetSegment in OffsetSegments)
			{
				Object.Destroy((Object)(object)offsetSegment);
			}
			Object.Destroy((Object)(object)Center);
			Center = null;
			Segments.Clear();
			OffsetSegments.Clear();
		}

		public void Update()
		{
			if (!Visible)
			{
				CreateSegments(0);
				CreateOffsetSegments(0);
				return;
			}
			CreateLines();
			if (SnapToGround)
			{
				Snap();
			}
			CreateOffsetSegments(Segments.Count);
			CreateOffsetLines();
		}

		protected void CreateSegments(int count)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (Segments.Count == count)
			{
				return;
			}
			foreach (GameObject segment in Segments)
			{
				Object.Destroy((Object)(object)segment);
			}
			Segments.Clear();
			Object.Destroy((Object)(object)Center);
			if (count != 0)
			{
				Center = Object.Instantiate<GameObject>(BasePrefab, ((Component)this).transform);
				Center.transform.localPosition = Vector3.zero;
				Center.transform.localRotation = Quaternion.identity;
				Center.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
				for (int i = 0; i < count; i++)
				{
					Segments.Add(Object.Instantiate<GameObject>(BasePrefab, ((Component)this).transform));
				}
			}
		}

		protected abstract void CreateLines();

		private void Snap()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject segment in Segments)
			{
				segment.transform.position = Snap(segment.transform.position);
			}
		}

		private Vector3 Snap(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(pos + Vector3.up * 500f, Vector3.down, ref val, 1000f, ((LayerMask)(ref Mask)).value))
			{
				pos.y = ((RaycastHit)(ref val)).point.y;
			}
			return pos;
		}

		private void CreateOffsetSegments(int count)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Approximately(Offset, 0f))
			{
				count = 0;
			}
			if (OffsetSegments.Count == count)
			{
				return;
			}
			foreach (GameObject offsetSegment in OffsetSegments)
			{
				Object.Destroy((Object)(object)offsetSegment);
			}
			OffsetSegments.Clear();
			for (int i = 0; i < count; i++)
			{
				OffsetSegments.Add(Object.Instantiate<GameObject>(BasePrefab, Vector3.zero, Quaternion.identity, ((Component)this).transform));
			}
		}

		private void CreateOffsetLines()
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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)
			for (int i = 0; i < OffsetSegments.Count; i++)
			{
				GameObject val = Segments[i];
				GameObject obj = OffsetSegments[i];
				obj.transform.localPosition = val.transform.localPosition + Vector3.up * Offset;
				obj.transform.localRotation = val.transform.localRotation;
				obj.transform.localScale = val.transform.localScale;
				obj.SetActive(val.activeSelf);
			}
		}

		protected Transform Get(int index)
		{
			return Segments[index].transform;
		}

		protected void Set(int index, Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Get(index).localPosition = pos;
		}

		protected void SetRot(int index, Vector3 rot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Get(index).localRotation = Quaternion.LookRotation(rot, Vector3.up);
		}
	}
	public class CircleRuler : BaseRuler
	{
		public float Radius = 20f;

		private readonly float Speed = 0.1f;

		protected override void CreateLines()
		{
			int count = Math.Max(3, (int)(Radius * 4f));
			CreateSegments(count);
			UpdateLines();
		}

		private void UpdateLines()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			int count = Segments.Count;
			float num = (float)Math.PI * 2f / (float)count;
			float num2 = Time.time * Speed;
			Vector3 pos = default(Vector3);
			for (int i = 0; i < count; i++)
			{
				float num3 = (float)i * num + num2;
				((Vector3)(ref pos))..ctor(Mathf.Sin(num3) * Radius, 0f, Mathf.Cos(num3) * Radius);
				Set(i, pos);
			}
			for (int j = 0; j < count; j++)
			{
				GameObject obj = ((j == 0) ? Segments[Segments.Count - 1] : Segments[j - 1]);
				GameObject val = ((j == Segments.Count - 1) ? Segments[0] : Segments[j + 1]);
				Vector3 val2 = obj.transform.localPosition - val.transform.localPosition;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				SetRot(j, normalized);
			}
		}
	}
	public class RectangleRuler : BaseRuler
	{
		public float Width = 20f;

		public float Depth = 20f;

		private void EdgeFix(int index, float percent, float max, float start, float end, Vector3 direction)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d8: Unknown result type (might be due to invalid IL or missing references)
			float num = percent * max;
			Transform val = Get(index);
			Vector3 baseScale = BaseRuler.BaseScale;
			if (num - start < 0.5f)
			{
				baseScale.z *= num - start + 0.5f;
				val.localPosition += direction * (0.5f - baseScale.z / 2f);
			}
			if (end - num < 0.5f)
			{
				baseScale.z *= Mathf.Max(0f, end - num + 0.5f);
				val.localPosition -= direction * (0.5f - baseScale.z / 2f);
			}
			if (baseScale.z == 0f)
			{
				((Component)val).gameObject.SetActive(false);
			}
			else
			{
				((Component)val).gameObject.SetActive(true);
			}
			val.localScale = baseScale;
		}

		protected override void CreateLines()
		{
			float num = 2f * Width + 2f * Depth;
			int num2 = Math.Max(3, (int)num);
			int num3 = (int)Mathf.Max(2f, Mathf.Ceil((float)num2 * Depth / num));
			int num4 = (int)Mathf.Max(2f, Mathf.Ceil((float)num2 * Width / num));
			num2 = 2 * (num3 + num4);
			CreateSegments(num2);
			UpdateLines(num4, num3);
		}

		private void UpdateLines(int w, int d)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: 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_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			int count = Segments.Count;
			int num = 0;
			int num2 = 0;
			while (num2 < d)
			{
				SetRot(num, Vector3.forward);
				num2++;
				num++;
			}
			int num3 = 0;
			while (num3 < w)
			{
				SetRot(num, Vector3.right);
				num3++;
				num++;
			}
			int num4 = 0;
			while (num4 < d)
			{
				SetRot(num, Vector3.back);
				num4++;
				num++;
			}
			int num5 = 0;
			while (num5 < w)
			{
				SetRot(num, Vector3.left);
				num5++;
				num++;
			}
			num = 0;
			float num6 = Time.time * 0.025f * (float)(count - 4);
			float num7 = 0.5f;
			Vector3 val = Width * Vector3.left - (Depth + num7) * Vector3.forward;
			float num8 = 0.5f;
			float end = num8 + 2f * Depth;
			float num9 = 2f * Depth * (float)d / (float)(d - 1);
			float num10 = num6 / (float)d;
			int num11 = 0;
			while (num11 < d)
			{
				float num12 = ((float)num11 / (float)d + num10) % 1f;
				Vector3 pos = val + num12 * num9 * Vector3.forward;
				Set(num, pos);
				EdgeFix(num, num12, num9, num8, end, Vector3.forward);
				num11++;
				num++;
			}
			val = Depth * Vector3.forward - (Width + num7) * Vector3.right;
			end = num8 + 2f * Width;
			num9 = 2f * Width * (float)w / (float)(w - 1);
			num10 = num6 / (float)w;
			int num13 = 0;
			while (num13 < w)
			{
				float num14 = ((float)num13 / (float)w + num10) % 1f;
				Vector3 pos2 = val + num14 * num9 * Vector3.right;
				Set(num, pos2);
				EdgeFix(num, num14, num9, num8, end, Vector3.right);
				num13++;
				num++;
			}
			val = Width * Vector3.right - (Depth + num7) * Vector3.back;
			end = num8 + 2f * Depth;
			num9 = 2f * Depth * (float)d / (float)(d - 1);
			num10 = num6 / (float)d;
			int num15 = 0;
			while (num15 < d)
			{
				float num16 = ((float)num15 / (float)d + num10) % 1f;
				Vector3 pos3 = val + num16 * num9 * Vector3.back;
				Set(num, pos3);
				EdgeFix(num, num16, num9, num8, end, Vector3.back);
				num15++;
				num++;
			}
			val = Depth * Vector3.back - (Width + num7) * Vector3.left;
			end = num8 + 2f * Width;
			num9 = 2f * Width * (float)w / (float)(w - 1);
			num10 = num6 / (float)w;
			int num17 = 0;
			while (num17 < w)
			{
				float num18 = ((float)num17 / (float)w + num10) % 1f;
				Vector3 pos4 = val + num18 * num9 * Vector3.left;
				Set(num, pos4);
				EdgeFix(num, num18, num9, num8, end, Vector3.left);
				num17++;
				num++;
			}
		}
	}
	public class RulerParameters
	{
		public bool Radius;

		public bool Ring;

		public bool Width;

		public bool Grid;

		public bool Depth;

		public bool Height;

		public bool RotateWithPlayer;

		public bool IsTargeted;

		public bool IsId;
	}
	public enum RulerShape
	{
		Circle,
		Ring,
		Frame,
		Square,
		Rectangle
	}
	public class Ruler
	{
		public static RulerShape Shape;

		public static GameObject? Projector;

		public static GameObject? Circle;

		public static GameObject? Ring;

		public static GameObject? Rectangle;

		public static GameObject? Square;

		public static GameObject? Frame;

		public static bool IsActive => (Object)(object)Projector != (Object)null;

		public static void SanityCheckShape()
		{
			if (Shape == RulerShape.Circle && (!Object.op_Implicit((Object)(object)Circle) || !Configuration.ShapeCircle))
			{
				Shape = RulerShape.Ring;
			}
			if (Shape == RulerShape.Ring && (!Object.op_Implicit((Object)(object)Ring) || !Configuration.ShapeRing))
			{
				Shape = RulerShape.Square;
			}
			if (Shape == RulerShape.Square && (!Object.op_Implicit((Object)(object)Square) || !Configuration.ShapeSquare))
			{
				Shape = RulerShape.Frame;
			}
			if (Shape == RulerShape.Frame && (!Object.op_Implicit((Object)(object)Frame) || !Configuration.ShapeFrame))
			{
				Shape = RulerShape.Rectangle;
			}
			if (Shape == RulerShape.Rectangle && (!Object.op_Implicit((Object)(object)Rectangle) || !Configuration.ShapeRectangle))
			{
				Shape = RulerShape.Circle;
			}
		}

		private static void SetTerrainGrid(float width, float height)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			float num = width - Mathf.Floor(width);
			float num2 = height - Mathf.Floor(height);
			bool flag = 0.25f < num && num < 0.75f;
			bool flag2 = 0.25f < num2 && num2 < 0.75f;
			Grid.SetPreciseMode(new Vector3(flag ? 0f : 0.5f, 0f, flag2 ? 0f : 0.5f));
		}

		private static void BuildCircle(GameObject obj, float radius)
		{
			CircleRuler component = obj.GetComponent<CircleRuler>();
			component.Visible = obj.activeSelf;
			component.Radius = radius;
		}

		private static void BuildRectangle(GameObject obj, float width, float depth)
		{
			RectangleRuler component = obj.GetComponent<RectangleRuler>();
			component.Visible = obj.activeSelf;
			component.Width = width;
			component.Depth = depth;
		}

		public static void Update()
		{
			//IL_00dd: 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_007e: 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_009c: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)Projector == (Object)null || !Object.op_Implicit((Object)(object)localPlayer) || !(Selection.Get() is ToolSelection toolSelection))
			{
				return;
			}
			GameObject placementGhost = localPlayer.m_placementGhost;
			Transform transform = ((Component)localPlayer).transform;
			Projector.SetActive(Object.op_Implicit((Object)(object)placementGhost));
			if (!Object.op_Implicit((Object)(object)placementGhost))
			{
				return;
			}
			Transform transform2 = placementGhost.transform;
			ScalingData scalingData = Scaling.Get();
			Tool tool = toolSelection.Tool;
			if (tool.IsTargetEdge)
			{
				Vector3 position = default(Vector3);
				((Vector3)(ref position))..ctor((transform.position.x + transform2.position.x) / 2f, transform2.position.y, (transform.position.z + transform2.position.z) / 2f);
				Projector.transform.position = position;
			}
			else
			{
				Projector.transform.position = transform2.position;
			}
			Quaternion rotation = transform2.rotation;
			float num = ((Quaternion)(ref rotation)).eulerAngles.y;
			if (tool.RotateWithPlayer)
			{
				num = Vector3.SignedAngle(Vector3.forward, Utils.DirectionXZ(transform2.position - transform.position), Vector3.up);
			}
			if (toolSelection.TerrainGrid)
			{
				num = 0f;
			}
			Projector.transform.rotation = Quaternion.Euler(0f, num, 0f);
			if (tool.IsTargetEdge)
			{
				float scaleZ = Utils.DistanceXZ(transform.position, transform2.position) / 2f;
				scalingData.SetScaleZ(scaleZ);
			}
			SanityCheckShape();
			RulerShape shape = Shape;
			if (toolSelection.TerrainGrid)
			{
				scalingData.SetPrecisionXZ(0.5f, 0.5f);
			}
			if ((Object)(object)Circle != (Object)null)
			{
				Circle.SetActive(shape == RulerShape.Circle || shape == RulerShape.Ring);
				BuildCircle(Circle, scalingData.X);
				if (Circle.activeSelf && toolSelection.TerrainGrid)
				{
					SetTerrainGrid(scalingData.X, scalingData.X);
				}
			}
			if ((Object)(object)Circle != (Object)null && (Object)(object)Ring != (Object)null)
			{
				Ring.SetActive(shape == RulerShape.Ring);
				BuildCircle(Ring, scalingData.Z);
			}
			if ((Object)(object)Square != (Object)null)
			{
				Square.SetActive(shape == RulerShape.Square || shape == RulerShape.Frame);
				BuildRectangle(Square, scalingData.X, scalingData.X);
				if (Square.activeSelf && toolSelection.TerrainGrid)
				{
					SetTerrainGrid(scalingData.X, scalingData.X);
				}
			}
			if ((Object)(object)Square != (Object)null && (Object)(object)Frame != (Object)null)
			{
				Frame.SetActive(shape == RulerShape.Frame);
				BuildRectangle(Frame, scalingData.Z, scalingData.Z);
				if (Frame.activeSelf && toolSelection.TerrainGrid)
				{
					SetTerrainGrid(scalingData.Z, scalingData.Z);
				}
			}
			if ((Object)(object)Rectangle != (Object)null)
			{
				Rectangle.SetActive(shape == RulerShape.Rectangle);
				BuildRectangle(Rectangle, scalingData.X, scalingData.Z);
				if (Rectangle.activeSelf && toolSelection.TerrainGrid)
				{
					SetTerrainGrid(scalingData.X, scalingData.Z);
				}
			}
			if (tool.Highlight)
			{
				if (shape == RulerShape.Circle)
				{
					HighlightCircle(Projector.transform.position, scalingData.X, scalingData.Y);
				}
				if (shape == RulerShape.Ring)
				{
					HighlightRing(Projector.transform.position, scalingData.X, scalingData.Z, scalingData.Y);
				}
				if (shape == RulerShape.Square)
				{
					HighlightRectangle(Projector.transform.position, num, scalingData.X, scalingData.X, scalingData.Y);
				}
				if (shape == RulerShape.Frame)
				{
					HighlightFrame(Projector.transform.position, num, scalingData.X, scalingData.Z, scalingData.Y);
				}
				if (shape == RulerShape.Rectangle)
				{
					HighlightRectangle(Projector.transform.position, num, scalingData.X, scalingData.Z, scalingData.Y);
				}
			}
			BaseRuler.SnapToGround = toolSelection.Tool.SnapGround;
			BaseRuler.Offset = (toolSelection.Tool.Height ? scalingData.Y : 0f);
		}

		public static string DescriptionScale(ToolSelection selection)
		{
			if ((Object)(object)Projector == (Object)null)
			{
				return "";
			}
			Tool tool = selection.Tool;
			ScalingData scalingData = Scaling.Get();
			string text = (tool.Height ? (", h: " + Format2(scalingData.Y)) : "");
			switch (Shape)
			{
			case RulerShape.Rectangle:
				return "w: " + Format2(scalingData.X) + ", d: " + Format2(scalingData.Z) + text;
			case RulerShape.Square:
				return "w: " + Format2(scalingData.X) + text;
			case RulerShape.Circle:
				return "r: " + Format2(scalingData.X) + text;
			case RulerShape.Ring:
			{
				float f3 = Mathf.Min(scalingData.X, scalingData.Z);
				float f4 = Mathf.Max(scalingData.X, scalingData.Z);
				return "r: " + Format2(f3) + "-" + Format2(f4) + text;
			}
			case RulerShape.Frame:
			{
				float f = Mathf.Min(scalingData.X, scalingData.Z);
				float f2 = Mathf.Max(scalingData.X, scalingData.Z);
				return "w: " + Format2(f) + "-" + Format2(f2) + text;
			}
			default:
				return "";
			}
		}

		public static string DescriptionPosition()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Projector == (Object)null)
			{
				return "";
			}
			Vector3 position = Projector.transform.position;
			return "x: " + Format1(position.x) + ", z: " + Format1(position.z) + ", y: " + Format1(position.y);
		}

		private static string Format1(float f)
		{
			return f.ToString("F1", CultureInfo.InvariantCulture);
		}

		private static string Format2(float f)
		{
			return f.ToString("F2", CultureInfo.InvariantCulture);
		}

		private static GameObject InitializeGameObject()
		{
			//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_001a: Expected O, but got Unknown
			Projector = new GameObject
			{
				layer = LayerMask.NameToLayer("character_trigger")
			};
			return Projector;
		}

		private static GameObject CreateCircle(GameObject obj)
		{
			GameObject obj2 = CreateChild(obj);
			obj2.AddComponent<CircleRuler>();
			return obj2;
		}

		private static GameObject CreateRectangle(GameObject obj)
		{
			GameObject obj2 = CreateChild(obj);
			obj2.AddComponent<RectangleRuler>();
			return obj2;
		}

		private static GameObject CreateChild(GameObject obj)
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			GameObject val = new GameObject();
			val.transform.SetParent(obj.transform);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			return val;
		}

		public static void Constrain(Range<float?> size, Range<float?> height)
		{
			ScalingData scalingData = Scaling.Get();
			if (size.Min.HasValue && size.Max.HasValue)
			{
				scalingData.SetScaleX(Mathf.Clamp(scalingData.X, size.Min.Value, size.Max.Value));
				scalingData.SetScaleZ(Mathf.Clamp(scalingData.Z, size.Min.Value, size.Max.Value));
			}
			if (height.Min.HasValue && height.Max.HasValue)
			{
				scalingData.SetScaleY(Mathf.Clamp(scalingData.Y, height.Min.Value, height.Max.Value));
			}
		}

		public static void InitializeProjector(Tool tool, GameObject obj)
		{
			if (tool.Width)
			{
				Square = CreateRectangle(obj);
			}
			if (tool.Frame)
			{
				Frame = CreateRectangle(obj);
			}
			if (tool.Width && tool.Depth)
			{
				Rectangle = CreateRectangle(obj);
			}
			if (tool.Radius)
			{
				Circle = CreateCircle(obj);
			}
			if (tool.Ring)
			{
				Ring = CreateCircle(obj);
			}
		}

		public static void Create(Tool tool)
		{
			Remove();
			if (tool.Radius || tool.Width || tool.Depth)
			{
				InitializeProjector(tool, InitializeGameObject());
			}
		}

		public static void Remove()
		{
			if ((Object)(object)Projector != (Object)null)
			{
				Object.Destroy((Object)(object)Projector);
			}
			Projector = null;
			if ((Object)(object)Circle != (Object)null)
			{
				Object.Destroy((Object)(object)Circle);
			}
			Circle = null;
			if ((Object)(object)Ring != (Object)null)
			{
				Object.Destroy((Object)(object)Ring);
			}
			Ring = null;
			if ((Object)(object)Frame != (Object)null)
			{
				Object.Destroy((Object)(object)Frame);
			}
			Frame = null;
			if ((Object)(object)Rectangle != (Object)null)
			{
				Object.Destroy((Object)(object)Rectangle);
			}
			Rectangle = null;
			if ((Object)(object)Square != (Object)null)
			{
				Object.Destroy((Object)(object)Square);
			}
			Square = null;
		}

		private static void HighlightCircle(Vector3 center, float radius, float height)
		{
			//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)
			Range<float> val = new Range<float>(radius);
			foreach (WearNTear s_allInstance in WearNTear.s_allInstances)
			{
				if (Object.op_Implicit((Object)(object)s_allInstance) && Object.op_Implicit((Object)(object)s_allInstance.m_nview) && s_allInstance.m_nview.GetZDO() != null && Selector.Within(s_allInstance.m_nview.GetZDO().GetPosition(), center, val, height))
				{
					s_allInstance.Highlight();
				}
			}
		}

		private static void HighlightRing(Vector3 center, float radius1, float radius2, float height)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(radius1, radius2);
			float num2 = Mathf.Max(radius1, radius2);
			Range<float> val = new Range<float>(num, num2);
			foreach (WearNTear s_allInstance in WearNTear.s_allInstances)
			{
				if (Object.op_Implicit((Object)(object)s_allInstance) && Object.op_Implicit((Object)(object)s_allInstance.m_nview) && s_allInstance.m_nview.GetZDO() != null && Selector.Within(s_allInstance.m_nview.GetZDO().GetPosition(), center, val, height))
				{
					s_allInstance.Highlight();
				}
			}
		}

		private static void HighlightRectangle(Vector3 center, float angle, float width, float depth, float height)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			Range<float> val = new Range<float>(width);
			Range<float> val2 = new Range<float>(depth);
			foreach (WearNTear s_allInstance in WearNTear.s_allInstances)
			{
				if (Object.op_Implicit((Object)(object)s_allInstance) && Object.op_Implicit((Object)(object)s_allInstance.m_nview) && s_allInstance.m_nview.GetZDO() != null && Selector.Within(s_allInstance.m_nview.GetZDO().GetPosition(), center, angle, val, val2, height))
				{
					s_allInstance.Highlight();
				}
			}
		}

		private static void HighlightFrame(Vector3 center, float angle, float size1, float size2, float height)
		{
			//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)
			float num = Mathf.Min(size1, size2);
			Mathf.Max(size1, size2);
			Range<float> val = new Range<float>(num);
			foreach (WearNTear s_allInstance in WearNTear.s_allInstances)
			{
				if (Object.op_Implicit((Object)(object)s_allInstance) && Object.op_Implicit((Object)(object)s_allInstance.m_nview) && s_allInstance.m_nview.GetZDO() != null && Selector.Within(s_allInstance.m_nview.GetZDO().GetPosition(), center, angle, val, val, height))
				{
					s_allInstance.Highlight();
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateWearNTearHover")]
	public class UpdateWearNTearHover
	{
		private static bool Prefix()
		{
			return !Ruler.IsActive;
		}
	}
	[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
	public class AddExtraInfo
	{
		private static Vector2? DefaultOffset;

		private static Vector2? ToolOffset;

		private static string DescriptionHover()
		{
			if (Object.op_Implicit((Object)(object)Ruler.Projector))
			{
				return "";
			}
			ZNetView hovered = Selector.GetHovered(Configuration.Range, Array.Empty<string>(), Configuration.IgnoredIds);
			string text = (((Object)(object)hovered == (Object)null) ? "" : Utils.GetPrefabName(((Component)hovered).gameObject));
			return "id: " + text;
		}

		private static string Description(ToolSelection selection)
		{
			if (Hud.instance.m_pieceSelectionWindow.activeSelf)
			{
				return "";
			}
			string[] source = new string[3]
			{
				DescriptionHover(),
				Ruler.DescriptionScale(selection),
				Ruler.DescriptionPosition()
			};
			return string.Join("\n", source.Where((string s) => s != ""));
		}

		private static void Prefix(Hud __instance)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = __instance.m_pieceDescription.rectTransform;
			if (!DefaultOffset.HasValue)
			{
				DefaultOffset = rectTransform.offsetMin;
			}
			if (!ToolOffset.HasValue)
			{
				ToolOffset = new Vector2(rectTransform.offsetMin.x, -160f);
			}
			if (rectTransform.offsetMin != DefaultOffset.Value)
			{
				rectTransform.offsetMin = DefaultOffset.Value;
			}
		}

		private static void Postfix(Hud __instance, Piece piece)
		{
			//IL_0032: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)piece) || !(Selection.Get() is ToolSelection selection) || !ToolOffset.HasValue)
			{
				return;
			}
			RectTransform rectTransform = __instance.m_pieceDescription.rectTransform;
			if (rectTransform.offsetMin != ToolOffset.Value)
			{
				rectTransform.offsetMin = ToolOffset.Value;
			}
			if (!Hud.instance.m_pieceSelectionWindow.activeSelf)
			{
				string text = Description(selection);
				if (__instance.m_pieceDescription.text != "")
				{
					text = "\n" + text;
				}
				TMP_Text pieceDescription = __instance.m_pieceDescription;
				pieceDescription.text += text;
			}
		}
	}
	public class ToolCmdCommand
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEvent <0>__Execute;
		}

		public ToolCmdCommand()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			object obj = <>O.<0>__Execute;
			if (obj == null)
			{
				ConsoleEvent val = Execute;
				<>O.<0>__Execute = val;
				obj = (object)val;
			}
			Helper.Command("tool_cmd", "[command] - Selects a command to be used when placed.", (ConsoleEvent)obj);
			AutoComplete.RegisterEmpty("tool_cmd");
			AutoComplete.Offsets["tool_cmd"] = 0;
		}

		protected static void Execute(ConsoleEventArgs args)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Helper.ArgsCheck(args, 2, "Missing the command.");
			if (!Hammer.HasAny())
			{
				Hammer.Equip();
			}
			string args2 = HammerHelper.GetArgs("tool_cmd", args);
			Tool tool = new Tool(new ToolData
			{
				name = "Command",
				command = args2,
				description = args2
			});
			Selection.CreateGhost(new ToolSelection(tool));
			Hammer.SelectEmpty();
			PlaceRotation.Set(Quaternion.identity);
			HammerHelper.Message(args.Context, "Selected command " + tool.Name + ".");
		}
	}
	public class ToolCommand
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEvent <0>__Execute;
		}

		public ToolCommand()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			object obj = <>O.<0>__Execute;
			if (obj == null)
			{
				ConsoleEvent val = Execute;
				<>O.<0>__Execute = val;
				obj = (object)val;
			}
			Helper.Command("tool", "[tool] - Selects a tool to be used when placed.", (ConsoleEvent)obj);
			AutoComplete.Register("tool", (Func<int, int, List<string>>)((int index, int subIndex) => (from tool in ToolManager.GetAll()
				select tool.Name).ToList()));
		}

		protected static void Execute(ConsoleEventArgs args)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Helper.ArgsCheck(args, 2, "Missing the tool name.");
			if (!Hammer.HasAny())
			{
				Hammer.Equip();
			}
			string args2 = HammerHelper.GetArgs("tool", args);
			if (!ToolManager.TryGetTool(Hammer.Get(), args2, out Tool tool))
			{
				tool = new Tool(new ToolData
				{
					name = "Command",
					command = args2,
					description = args2
				});
			}
			Hammer.SelectRepair();
			Selection.CreateGhost(new ToolSelection(tool));
			PlaceRotation.Set(Quaternion.identity);
			HammerHelper.Message(args.Context, "Selected tool " + tool.Name + ".");
		}
	}
	public class ToolData
	{
		[DefaultValue("")]
		public string name = "";

		[DefaultValue("")]
		public string description = "";

		[DefaultValue("")]
		public string icon = "";

		public string command = "";

		public CommandData[]? commands;

		[DefaultValue("")]
		public string continuous = "";

		[DefaultValue("")]
		public string initialHeight = "";

		[DefaultValue("")]
		public string initialSize = "";

		[DefaultValue("")]
		public string initialShape = "";

		[DefaultValue("false")]
		public string targetEdge = "false";

		[DefaultValue("false")]
		public string snapGround = "false";

		[DefaultValue("false")]
		public string snapPiece = "false";

		[DefaultValue("")]
		public string playerHeight = "";

		[DefaultValue("false")]
		public string highlight = "false";

		[DefaultValue("false")]
		public string terrainGrid = "false";

		[DefaultValue(null)]
		public bool? instant;

		[DefaultValue(null)]
		public int? tabIndex;

		[DefaultValue(null)]
		public int? index;
	}
	public class CommandData
	{
		public string command = "";

		public string keys = "";
	}
	public class Tool
	{
		public string Name;

		private List<CommandValue> Commands;

		private readonly string description;

		private readonly string iconName;

		private Sprite? icon;

		private readonly string continuous;

		public float? InitialHeight;

		public float? InitialSize;

		public string InitialShape;

		private readonly string snapGround;

		private readonly string playerHeight;

		private readonly string highlight;

		private readonly string terrainGrid;

		private readonly string snapPiece;

		public bool Instant;

		public int? TabIndex;

		public int? Index;

		public bool Radius;

		public bool Ring;

		public bool Width;

		public bool Frame;

		public bool Depth;

		public bool Height;

		public bool RotateWithPlayer;

		private readonly string targetEdge;

		public bool IsId;

		public string Description => DisplayKeys(description);

		public Sprite? Icon => icon ?? (icon = HammerHelper.FindSprite(iconName));

		public bool Continuous
		{
			get
			{
				if (!(continuous == "true"))
				{
					return HammerHelper.IsDown(continuous);
				}
				return true;
			}
		}

		public bool SnapGround
		{
			get
			{
				if (!(snapGround == "true"))
				{
					return HammerHelper.IsDown(snapGround);
				}
				return true;
			}
		}

		public bool PlayerHeight
		{
			get
			{
				if (!(playerHeight == "true"))
				{
					return HammerHelper.IsDown(playerHeight);
				}
				return true;
			}
		}

		public bool Highlight
		{
			get
			{
				if (!(highlight == "true"))
				{
					return HammerHelper.IsDown(highlight);
				}
				return true;
			}
		}

		public bool TerrainGrid
		{
			get
			{
				if (!(terrainGrid == "true"))
				{
					return HammerHelper.IsDown(terrainGrid);
				}
				return true;
			}
		}

		public bool SnapPiece
		{
			get
			{
				if (!(snapPiece == "true"))
				{
					return HammerHelper.IsDown(snapPiece);
				}
				return true;
			}
		}

		public bool IsTargetEdge
		{
			get
			{
				if (!(targetEdge == "true"))
				{
					return HammerHelper.IsDown(targetEdge);
				}
				return true;
			}
		}

		public Tool(ToolData data)
		{
			Name = data.name;
			description = data.description.Replace("\\n", "\n");
			iconName = data.icon;
			continuous = data.continuous;
			InitialHeight = ((data.initialHeight == "") ? null : new float?(Parse.Float(data.initialHeight, 0f)));
			InitialSize = ((data.initialSize == "") ? null : new float?(Parse.Float(data.initialSize, 0f)));
			InitialShape = data.initialShape;
			snapGround = data.snapGround;
			playerHeight = data.playerHeight;
			highlight = data.highlight;
			terrainGrid = data.terrainGrid;
			snapPiece = data.snapPiece;
			TabIndex = data.tabIndex;
			targetEdge = data.targetEdge;
			Index = data.index;
			Commands = ((data.commands == null) ? GetCommands(data.command) : data.commands.Select((CommandData c) => new CommandValue(c.command, c.keys)).ToList());
			Instant = Commands.All((CommandValue c) => !c.Command.Contains("<") && !c.Command.Contains("hammer "));
			Instant = ((!data.instant.HasValue) ? Instant : data.instant.Value);
			RotateWithPlayer = true;
			foreach (CommandValue command in Commands)
			{
				ParseParameters(command.Command);
			}
		}

		public string GetCommand()
		{
			IEnumerable<CommandValue> source = Commands.Where((CommandValue c) => c.IsDown());
			return string.Join("; ", source.Select((CommandValue c) => c.Command));
		}

		private void ParseParameters(string command)
		{
			string[] array = command.Split(new char[1] { ' ' }).ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].Contains("<id>"))
				{
					IsId = true;
				}
				if (array[i].Contains("<a>"))
				{
					RotateWithPlayer = false;
				}
				if (array[i].Contains("<r>"))
				{
					Radius = true;
				}
				if (array[i].Contains("<r2>"))
				{
					Ring = true;
				}
				if (array[i].Contains("<w>"))
				{
					Width = true;
				}
				if (array[i].Contains("<w2>"))
				{
					Frame = true;
				}
				if (array[i].Contains("<d>"))
				{
					Depth = true;
				}
				if (array[i].Contains("<h>"))
				{
					Height = true;
				}
			}
		}

		private List<CommandValue> GetCommands(string rawCommand)
		{
			string[] array = rawCommand.Split(new char[1] { ';' });
			Commands = new List<CommandValue>();
			string[] array2 = array;
			foreach (string text in array2)
			{
				int num = text.IndexOf("keys=", StringComparison.Ordinal);
				if (num == -1)
				{
					Commands.Add(new CommandValue(text, ""));
					continue;
				}
				int num2 = text.IndexOf(" ", num + 5, StringComparison.Ordinal);
				if (num2 == -1)
				{
					num2 = text.Length;
				}
				string keys = text.Substring(num + 5, num2 - num - 5);
				string command = text.Substring(0, num - 1) + text.Substring(num2);
				Commands.Add(new CommandValue(command, keys));
			}
			return Commands;
		}

		private static string DisplayKeys(string text)
		{
			//IL_0014: 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)
			InputBinding val = ((IEnumerable<InputBinding>)(object)ZInput.instance.GetButtonDef("AltPlace").ButtonAction.bindings).FirstOrDefault();
			string text2 = "";
			text2 = ZInput.instance.MapKeyFromPath(((InputBinding)(ref val)).effectivePath).ToLowerInvariant();
			return text.Replace("<mod1>", Configuration.ModifierKey1()).Replace("<mod2>", Configuration.ModifierKey2()).Replace("<alt>", text2);
		}
	}
	public class CommandValue
	{
		public string Command = Plain(MultiCommands.Split(ReplaceHelpers(command)));

		public string[] Keys;

		public string[] BannedKeys;

		public CommandValue(string command, string keys)
		{
			List<string> list = new List<string>();
			list.AddRange(from k in Parse.Split(keys, ',')
				where k[0] != '-'
				select k);
			Keys = list.ToArray();
			List<string> list2 = new List<string>();
			list2.AddRange(from k in Parse.Split(keys, ',')
				where k[0] == '-'
				select k.Substring(1));
			BannedKeys = list2.ToArray();
			base..ctor();
		}

		public bool IsDown()
		{
			if (Keys.All(HammerHelper.IsDown))
			{
				return !BannedKeys.Any(HammerHelper.IsDown);
			}
			return false;
		}

		private static string ReplaceHelpers(string command)
		{
			return command.Replace("hoe_", "tool_").Replace("hammer_command", "").Replace("<area>", "from=<x>,<z>,<y> circle=<r>-<r2> angle=<a> rect=<w>-<w2>,<d> ignore=<ignore> id=<include>")
				.Replace("<place>", "from=<x>,<z>,<y>")
				.Replace("<to>", "to=<x>,<z>,<y> circle=<r>-<r2> rect=<w>-<w2>,<d>");
		}

		private static string Plain(string[] commands)
		{
			for (int i = 0; i < commands.Length; i++)
			{
				commands[i] = Aliasing.Plain(commands[i]);
			}
			return string.Join("; ", commands);
		}
	}
	public class InitialData
	{
		public static string Get()
		{
			return "hammer:\n- name: Pipette\n  description: |-\n    Press <mod1> to pick up.\n    Press <mod2> to freeze.\n  icon: hammer\n  command: hammer pick=<mod1> freeze=<mod2>\n  index: 1\n- name: Building pipette\n  description: |-\n    Select entire buildings.\n    Press <mod1> to pick up.\n    Press <mod2> to freeze.\n  icon: hammer\n  command: hammer connect pick=<mod1> freeze=<mod2>\n- name: Area pipette\n  description: |-\n    Select multiple objects.\n    Press <mod1> to pick up.\n    Press <mod2> to freeze.\n  icon: hammer\n  command: hammer pick=<mod1> freeze=<mod2> height=<h> <area>\n  initialHeight: 0\n  highlight: true\nhoe:\n- name: Level\n  description: |-\n    Flattens terrain.\n    Hold <mod1> to smooth.\n    Hold <mod2> for free mode.\n    Hold <alt> for player height.\n  icon: mud_road\n  command: terrain level smooth=<mod1>?.5:0 <area>\n  index: 10\n  terrainGrid: -<mod2>\n  playerHeight: <alt>\n- name: Raise\n  description: |-\n    Raises terrain.\n    Hold <mod1> to smooth.\n    Hold <mod2> for free mode.\n  icon: raise\n  command: terrain raise=<h> smooth=<mod1>?.5:0 <area>\n  initialHeight: 0.2\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Pave\n  description: |-\n    Paves terrain.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: paved_road\n  command: terrain paint=paved <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Grass\n  description: |-\n    Grass.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: replant\n  command: terrain paint=grass <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Dirt\n  description: |-\n    Dirt.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: Hoe\n  command: terrain paint=dirt <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Cultivate\n  description: |-\n    Cultivates terrain.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: cultivate\n  command: terrain paint=cultivated <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: DarkGrass\n  description: |-\n    Dark Grass.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: trophyabomination\n  command: terrain paint=grass_dark <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: PatchyGrass\n  description: |-\n    Patchy Grass.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: iron_wall_2x2\n  command: terrain paint=patches <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: MossyPaving\n  description: |-\n    Paving with moss.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: trophygreydwarfshaman\n  command: terrain paint=paved_moss <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: DarkPaving\n  description: |-\n    Dark Paving.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: tar\n  command: terrain paint=paved_dark <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Reset\n  description: |-\n    Resets terrain.\n    Hold <mod1> for single use.\n    Hold <mod2> for free mode.\n  icon: Hoe\n  command: terrain reset <area>\n  continuous: -<mod1>\n  terrainGrid: -<mod2>\n  snapGround : true\n- name: Slope\n  description: Slope between you and aim point.\n  icon: wood_wall_roof_45\n  command: terrain slope <to>\n  targetEdge: true\n  initialShape: rectangle\n- name: Remove\n  description: |-\n    Removes objects.\n    Hold <mod1> to also reset the terrain.\n  icon: softdeath\n  commands:\n  - command: object remove id=* <area>\n  - command: terrain reset <area>\n    keys: <mod1>\n  highlight: true\n- name: Tame\n  description: |-\n    Tames creatures.\n    Hold <mod1> to untame\n  icon: Carrot\n  commands:\n  - command: object tame <area>\n    keys: -<mod1>\n  - command: object wild <area>\n    keys: <mod1>\n";
		}
	}
	public class ToolExportCommand
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEvent <0>__Execute;
		}

		public ToolExportCommand()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			object obj = <>O.<0>__Execute;
			if (obj == null)
			{
				ConsoleEvent val = Execute;
				<>O.<0>__Execute = val;
				obj = (object)val;
			}
			Helper.Command("tool_export", "[name] - Exports a tool", (ConsoleEvent)obj);
			AutoComplete.Register("tool_export", (Func<int, int, List<string>>)((int index, int subIndex) => (from tool in ToolManager.GetAll()
				select tool.Name).ToList()));
		}

		protected static void Execute(ConsoleEventArgs args)
		{
			Helper.ArgsCheck(args, 2, "Missing the tool name.");
			string args2 = HammerHelper.GetArgs("tool_export", args);
			string text = ToolManager.Export(Hammer.Get(), args2);
			if (string.IsNullOrEmpty(text))
			{
				HammerHelper.Message(args.Context, "Unable to find the tool " + args2 + ".");
				return;
			}
			GUIUtility.systemCopyBuffer = text;
			HammerHelper.Message(args.Context, "Exported tool " + args2 + " to the clipboard.");
		}
	}
	public class ToolImportCommand
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ConsoleEvent <0>__Execute;
		}

		public ToolImportCommand()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			object obj = <>O.<0>__Execute;
			if (obj == null)
			{
				ConsoleEvent val = Execute;
				<>O.<0>__Execute = val;
				obj = (object)val;
			}
			Helper.Command("tool_import", "[hammer/hoe/etc[data] - Imports a new tool.", (ConsoleEvent)obj);
			AutoComplete.Register("tool_import", (Func<int, int, List<string>>)delegate(int index, int subIndex)
			{
				if (index == 0)
				{
					Dictionary<string, List<Tool>>.KeyCollection keys = ToolManager.Tools.Keys;
					List<string> list = new List<string>(keys.Count);
					list.AddRange(keys);
					return list;
				}
				return ParameterInfo.Create("Tool data");
			});
		}

		protected static void Execute(ConsoleEventArgs args)
		{
			Helper.ArgsCheck(args, 2, "Missing the equipment.");
			Helper.ArgsCheck(args, 3, "Missing the tool data.");
			string text = args[1];
			string args2 = HammerHelper.GetArgs("tool_import " + text, args);
			ToolData toolData = ToolManager.Import(text, args2);
			HammerHelper.Message(args.Context, "Imported tool " + toolData.name + " to " + text + ".");
		}
	}
	[HarmonyPatch]
	public class ToolManager
	{
		public const string CmdMod1 = "<mod1>";

		public const string CmdMod2 = "<mod2>";

		public const string CmdAlt = "<alt>";

		public static string FilePath = Path.Combine(Paths.ConfigPath, "infinity_tools.yaml");

		public static string Pattern = "infinity_tools.yaml";

		private static Dictionary<string, List<ToolData>> ToolData = new Dictionary<string, List<ToolData>>();

		public static Dictionary<string, List<Tool>> Tools = new Dictionary<string, List<Tool>>();

		public static void CreateFile()
		{
			if (!File.Exists(FilePath))
			{
				File.WriteAllText(FilePath, InitialData.Get());
			}
		}

		public static void ToFile()
		{
			string contents = Yaml.Serializer().Serialize((object)ToolData);
			File.WriteAllText(FilePath, contents);
		}

		public static ToolData Import(string equipment, string tool)
		{
			ToolData toolData = Yaml.Deserialize<ToolData>(tool.Replace("\\n", "\n"), "Import");
			Add(equipment, toolData);
			return toolData;
		}

		public static void Add(string equipment, ToolData tool)
		{
			if (!ToolData.ContainsKey(equipment))
			{
				ToolData.Add(equipment, new List<ToolData>());
			}
			ToolData[equipment].Add(tool);
			ToFile();
		}

		public static string Export(string equipment, string name)
		{
			if (!TryGetToolData(equipment, name, out ToolData tool) && !TryGetToolData(name, out tool, out equipment))
			{
				return "";
			}
			string text = Yaml.Serializer().Serialize((object)tool).Replace("\r\n", "\\n")
				.Replace("\n", "\\n");
			return "tool_import " + equipment + " " + text;
		}

		public static bool TryGetTool(string equipment, string name, out Tool tool)
		{
			string name2 = name;
			tool = null;
			if (Tools.TryGetValue(equipment, out List<Tool> value))
			{
				tool = value.FirstOrDefault((Tool tool) => string.Equals(tool.Name, name2, StringComparison.OrdinalIgnoreCase));
			}
			if (tool == null)
			{
				tool = Tools.Values.SelectMany((L