Decompiled source of BUG TerraGrid v1.0.0

BUG_TerraGrid.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("Check")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.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]
	[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]
	[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 BUG_TerraGrid
{
	internal sealed class AreaGrid
	{
		public readonly List<Vector3> Points = new List<Vector3>();

		public readonly List<int> Indices = new List<int>();

		public readonly List<int> Rows = new List<int>();

		public readonly List<int> Columns = new List<int>();

		public int RowCount { get; private set; }

		public int ColumnCount { get; private set; }

		public void Select(PlanetData planet, Vector3 from, Vector3 to, bool shortWay)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			PlatformSystem platform = planet.factory.platformSystem;
			platform.EnsureReformData();
			Select(planet.aux.mainGrid.segment, platform.latitudeCount, planet.realRadius + 0.2f, from, to, shortWay, (float lat, float lon) => platform.GetReformIndexForSegment(lat, lon), platform.reformData.Length);
		}

		internal void Select(int segment, int latitudeCount, float radius, Vector3 from, Vector3 to, bool shortWay, Func<float, float, int> index, int indexCount)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			Points.Clear();
			Indices.Clear();
			Rows.Clear();
			Columns.Clear();
			RowCount = 0;
			ColumnCount = 0;
			float num = Turn(from);
			float num2 = Turn(to);
			float num3 = num;
			float num4 = Mathf.Repeat(num2 - num, 1f);
			if (num4 > 0.5f == shortWay)
			{
				num3 = num2;
				num4 = 1f - num4;
			}
			int num5 = latitudeCount / 10 * 10;
			int val = OddTenth(Latitude(from, segment));
			int val2 = OddTenth(Latitude(to, segment));
			for (int i = Math.Min(val, val2); i <= Math.Max(val, val2); i += 2)
			{
				if (Math.Abs(i) >= num5)
				{
					continue;
				}
				int num6 = PlanetGrid.DetermineLongitudeSegmentCount(Math.Abs(i) / 10, segment);
				int num7 = num6 * 5;
				int num8 = Column(num3, num7);
				int num9 = Mod(Column(num3 + num4, num7) - num8, num7) + 1;
				if (num4 * (float)num7 >= (float)(num7 - 1))
				{
					num9 = num7;
				}
				int num10 = 0;
				for (int j = 0; j < num9; j++)
				{
					int num11 = 2 * Mod(num8 + j, num7) + 1 - num7;
					int num12 = index((float)i / 10f, (float)num11 / 10f);
					if (num12 >= 0 && num12 < indexCount)
					{
						Points.Add(Surface((float)i / 10f / (float)segment, (float)num11 / 10f / (float)num6, radius));
						Indices.Add(num12);
						Rows.Add(RowCount);
						Columns.Add(num10++);
					}
				}
				if (num10 != 0)
				{
					RowCount++;
					ColumnCount = Math.Max(ColumnCount, num10);
				}
			}
		}

		public long BlockKey(int i, int size)
		{
			return ((long)(Rows[i] / size) << 32) | (uint)(Columns[i] / size);
		}

		public static long TileKey(int segment, Vector3 p)
		{
			//IL_0000: 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)
			int num = OddTenth(Latitude(p, segment));
			return ((long)num << 32) | (uint)Column(ring: PlanetGrid.DetermineLongitudeSegmentCount(Math.Abs(num) / 10, segment) * 5, turn: Turn(p));
		}

		private static float Turn(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Atan2(p.x, 0f - p.z) / ((float)Math.PI * 2f);
		}

		private static float Latitude(Vector3 p, int segment)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Asin(Mathf.Clamp(((Vector3)(ref p)).normalized.y, -1f, 1f)) / ((float)Math.PI * 2f) * (float)segment;
		}

		private static int OddTenth(float segments)
		{
			float num = segments * 10f;
			float num2 = Mathf.Round(num);
			int num3 = (int)Mathf.Abs(num2);
			if (num3 % 2 != 1)
			{
				num3 = Mathf.FloorToInt(Mathf.Abs(num));
				if (num3 % 2 != 1)
				{
					num3++;
				}
			}
			if (!(num2 >= 0f))
			{
				return -num3;
			}
			return num3;
		}

		private static int Column(float turn, int ring)
		{
			return Mod((OddTenth(Mathf.Repeat(turn + 0.5f, 1f) * (float)ring / 5f - (float)ring / 10f) + ring - 1) / 2, ring);
		}

		private static int Mod(int x, int m)
		{
			return (x % m + m) % m;
		}

		private static Vector3 Surface(float latTurns, float lonTurns, float radius)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			float num = latTurns * 2f * (float)Math.PI;
			float num2 = lonTurns * 2f * (float)Math.PI;
			return new Vector3(Mathf.Cos(num) * Mathf.Sin(num2), Mathf.Sin(num), (0f - Mathf.Cos(num)) * Mathf.Cos(num2)) * radius;
		}
	}
	[HarmonyPatch(typeof(BuildTool_Reform))]
	internal static class AreaTool
	{
		private static readonly AreaGrid Area = new AreaGrid();

		private static BuildTool_Reform? _tool;

		private static Vector3[]? _savedPoints;

		private static int[]? _savedIndices;

		private static int _savedSize;

		private static int _shownSize;

		private static Vector3[] _points = (Vector3[])(object)new Vector3[400];

		private static int[] _indices = new int[400];

		private static Vector3? _corner;

		private static bool _on;

		private static (PlanetData?, long, long, bool) _lastKey;

		public static bool On
		{
			get
			{
				return _on;
			}
			set
			{
				if (!value)
				{
					Release();
				}
				_on = value;
			}
		}

		public static bool ShortWay { get; set; } = true;

		[HarmonyPrefix]
		[HarmonyPatch("UpdateBrushMode")]
		private static bool UpdateBrushMode(BuildTool_Reform __instance, Vector3 currentCastPos)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!_on)
			{
				return true;
			}
			Hover(__instance, currentCastPos);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("_OnClose")]
		private static void OnClose(BuildTool_Reform __instance)
		{
			if (__instance == _tool)
			{
				Release();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("_OnFree")]
		private static void OnFree(BuildTool_Reform __instance)
		{
			if (__instance == _tool)
			{
				Release();
			}
		}

		private static void Hover(BuildTool_Reform tool, Vector3 cursor)
		{
			//IL_0076: 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_0082: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if (_tool != tool)
			{
				Release();
				_tool = tool;
				_savedPoints = tool.cursorPoints;
				_savedIndices = tool.cursorIndices;
				_savedSize = (_shownSize = tool.brushSize);
			}
			if (tool.brushSize != _shownSize)
			{
				_savedSize = tool.brushSize;
			}
			int segment = ((BuildTool)tool).planet.aux.mainGrid.segment;
			(PlanetData, long, long, bool) lastKey = (((BuildTool)tool).planet, AreaGrid.TileKey(segment, _corner ?? cursor), AreaGrid.TileKey(segment, cursor), ShortWay);
			if (!lastKey.Equals(_lastKey))
			{
				Area.Select(((BuildTool)tool).planet, _corner ?? cursor, cursor, ShortWay);
				_lastKey = lastKey;
			}
			int count = Area.Points.Count;
			Show(tool, count, (count > 0) ? Area.Points[count / 2] : cursor);
			string text = (_corner.HasValue ? Text.Selected(Area.ColumnCount, Area.RowCount, count) : "Click the first corner");
			if (!ShortWay)
			{
				text += " — long way around";
			}
			PaintJob current = PaintJob.Current;
			if (current != null)
			{
				text = Text.Painting(current.Done, current.Total, PaintJob.Paused) + "\n" + text;
			}
			((BuildTool)tool).actionBuild.model.cursorText = text;
			UICursor.SetCursor((ECursor)8);
			if (VFInput._buildConfirm.onDown && !VFInput.onGUI)
			{
				if (!_corner.HasValue)
				{
					_corner = cursor;
				}
				else if (PaintJob.Start(tool, Area, Brush.Capture(tool)))
				{
					_corner = null;
				}
			}
		}

		private static void Show(BuildTool_Reform tool, int count, Vector3 center)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Max(1, (int)Math.Ceiling(Math.Sqrt(count)));
			int num2 = num * num;
			if (_indices.Length < num2)
			{
				_indices = new int[num2];
				_points = (Vector3[])(object)new Vector3[num2];
			}
			Area.Points.CopyTo(_points);
			Area.Indices.CopyTo(_indices);
			for (int i = count; i < num2; i++)
			{
				_indices[i] = -1;
			}
			tool.cursorPoints = _points;
			tool.cursorIndices = _indices;
			tool.cursorPointCount = count;
			tool.brushSize = (_shownSize = num);
			tool.reformCenterPoint = center;
		}

		private static void Release()
		{
			_corner = null;
			if (_tool != null)
			{
				_tool.cursorPoints = _savedPoints;
				_tool.cursorIndices = _savedIndices;
				_tool.brushSize = _savedSize;
				_tool.cursorPointCount = 0;
				for (int i = 0; i < _tool.cursorIndices.Length; i++)
				{
					_tool.cursorIndices[i] = -1;
				}
			}
			_tool = null;
			_savedPoints = null;
			_savedIndices = null;
			ShortWay = true;
			_lastKey = default((PlanetData, long, long, bool));
		}
	}
	internal readonly struct Brush
	{
		public readonly int Mode;

		public readonly int Color;

		public readonly int Type;

		public readonly bool Bury;

		public readonly ItemProto? Item;

		public Brush(int mode, int color, int type, bool bury, ItemProto? item)
		{
			Mode = mode;
			Color = color;
			Type = type;
			Bury = bury;
			Item = item;
		}

		public static Brush Capture(BuildTool_Reform tool)
		{
			return new Brush(tool.reformMode, tool.brushColor, tool.brushType, tool.buryVeins, tool.handItem);
		}
	}
	internal static class GameReform
	{
		private static readonly MethodInfo Prepare = AccessTools.Method(typeof(BuildTool_Reform), "PrepareBrushPoints", (Type[])null, (Type[])null);

		private static readonly MethodInfo Flatten = AccessTools.Method(typeof(BuildTool_Reform), "DoFlattenExecute", (Type[])null, (Type[])null);

		private static readonly MethodInfo Restore = AccessTools.Method(typeof(BuildTool_Reform), "DoRestoreExecute", (Type[])null, (Type[])null);

		private static readonly FieldInfo Pit = AccessTools.Field(typeof(BuildTool_Reform), "removeBasePitRuinId");

		private static readonly FieldInfo Line = AccessTools.Field(typeof(BuildTool_Reform), "lineDrawingMode");

		private static readonly FieldInfo Package = AccessTools.Field(typeof(BuildTool), "tmpPackage");

		private static readonly MethodInfo HandCount = AccessTools.PropertySetter(typeof(Player), "inhandItemCount");

		private static readonly MethodInfo HandInc = AccessTools.PropertySetter(typeof(Player), "inhandItemInc");

		private const float Radius = 0.990946f;

		internal static string? Measure(BuildTool_Reform tool, Brush brush, List<List<Vector3>> blocks, out int tiles, out long sand)
		{
			Player player = ((BuildTool)tool).player;
			long cost = 0L;
			long gain = 0L;
			int count = 0;
			int items = 0;
			List<Vector3> snapped = new List<Vector3>();
			string text = WithBrush(tool, brush, delegate
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: 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)
				//IL_0175: 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)
				foreach (List<Vector3> block in blocks)
				{
					snapped.Clear();
					foreach (Vector3 item in block)
					{
						Snap(tool, item);
						if ((int)Pit.GetValue(tool) != 0)
						{
							return "A Dark Fog base pit is in the selection; remove it with the normal foundation brush first.";
						}
						if (tool.cursorIndices[0] >= 0)
						{
							count++;
							if (brush.Mode == 1)
							{
								int cost2 = 0;
								int gain2 = 0;
								Compute(tool, 0.990946f, ref cost2, ref gain2);
								cost += cost2;
								gain += gain2;
							}
							else
							{
								items += tool.cursorPointCount;
								for (int i = 0; i < tool.cursorPointCount; i++)
								{
									snapped.Add(tool.cursorPoints[i]);
								}
							}
						}
					}
					if (snapped.Count > 0)
					{
						float radius;
						Vector3 val = Center(block, out radius);
						int num2 = 0;
						int num3 = 0;
						((BuildTool)tool).factory.ComputeFlattenTerrainReform(snapped.ToArray(), val, radius, snapped.Count, ref num2, ref num3, 3f, 1f);
						cost += num2;
						gain += num3;
					}
				}
				return (string)null;
			});
			tiles = count;
			sand = 0L;
			if (text != null || count == 0)
			{
				return text;
			}
			if (brush.Mode == 1)
			{
				sand = cost - gain;
			}
			else
			{
				if (brush.Item == null)
				{
					return "Pick a foundation first.";
				}
				int id = ((Proto)brush.Item).ID;
				int num = ItemCount(player, id) + ((player.inhandItemId == id) ? player.inhandItemCount : 0);
				if (num < items)
				{
					return Text.LackOfItems(items, num);
				}
				sand = WithHandGuard(player, id, (Func<long>)delegate
				{
					CopyPackage(tool);
					return tool.GetNeedSandCountByInc(id, items, Clamp(cost), Clamp(gain));
				});
				if (GameMain.data.history.HasFeatureKey(1100001) && GameMain.sandboxToolsEnabled)
				{
					sand = 0L;
				}
			}
			if (sand > player.sandCount)
			{
				return Text.NotEnoughSoil(sand, player.sandCount);
			}
			return null;
		}

		internal static bool Apply(BuildTool_Reform tool, Brush brush, List<Vector3> block)
		{
			return WithBrush(tool, brush, delegate
			{
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: 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)
				List<Vector3> list = new List<Vector3>(block.Count);
				List<int> list2 = new List<int>(block.Count);
				foreach (Vector3 item in block)
				{
					Snap(tool, item);
					if ((int)Pit.GetValue(tool) != 0)
					{
						UIRealtimeTip.Popup("A Dark Fog base pit is in the selection; remove it with the normal foundation brush first.", true, 0);
						return false;
					}
					if (tool.cursorIndices[0] >= 0)
					{
						list2.Add(tool.cursorIndices[0]);
						for (int i = 0; i < tool.cursorPointCount; i++)
						{
							list.Add(tool.cursorPoints[i]);
						}
					}
				}
				if (list2.Count == 0)
				{
					return true;
				}
				int num = (int)Math.Ceiling(Math.Sqrt(list2.Count));
				int num2 = Math.Max(100, Math.Max(num * num, list.Count));
				tool.cursorPoints = (Vector3[])(object)new Vector3[num2];
				list.CopyTo(tool.cursorPoints);
				tool.cursorIndices = new int[num2];
				for (int j = 0; j < num2; j++)
				{
					tool.cursorIndices[j] = ((j < list2.Count) ? list2[j] : (-1));
				}
				tool.cursorPointCount = list.Count;
				tool.brushSize = num;
				tool.reformCenterPoint = Center(block, out var radius);
				int cost = 0;
				int gain = 0;
				Compute(tool, radius, ref cost, ref gain);
				if (brush.Mode == 1)
				{
					return Execute(tool, Restore, radius, cost - gain);
				}
				if (brush.Item == null)
				{
					return false;
				}
				Player player = ((BuildTool)tool).player;
				return WithHandGuard(player, ((Proto)brush.Item).ID, delegate
				{
					TopUp(player, ((Proto)brush.Item).ID, tool.cursorPointCount - player.inhandItemCount);
					if (NativeCount(player, ((Proto)brush.Item).ID) + player.inhandItemCount < tool.cursorPointCount)
					{
						UIRealtimeTip.Popup(Text.LackOfItem, true, 1);
						return false;
					}
					CopyPackage(tool);
					int need = tool.GetNeedSandCountByInc(((Proto)brush.Item).ID, tool.cursorPointCount, cost, gain);
					if (GameMain.data.history.HasFeatureKey(1100001) && GameMain.sandboxToolsEnabled)
					{
						need = 0;
					}
					return Execute(tool, Flatten, radius, need);
				});
			});
		}

		private static MethodInfo? DeliveryCount()
		{
			return Harmony.GetPatchInfo((MethodBase)Flatten)?.Transpilers.Select((Patch p) => p.PatchMethod.DeclaringType?.GetMethod("GetItemCount", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(StorageComponent),
				typeof(int)
			}, null)).FirstOrDefault((MethodInfo m) => m != null && m.ReturnType == typeof(int));
		}

		private static int NativeCount(Player player, int itemId)
		{
			MethodInfo methodInfo = DeliveryCount();
			if (!(methodInfo == null))
			{
				return (int)methodInfo.Invoke(null, new object[2] { player.package, itemId });
			}
			return player.package.GetItemCount(itemId);
		}

		internal static int ItemCount(Player player, int itemId)
		{
			int num = NativeCount(player, itemId);
			int num2;
			if (DeliveryCount() == null)
			{
				DeliveryPackage deliveryPackage = player.deliveryPackage;
				if (deliveryPackage != null && deliveryPackage.unlocked)
				{
					num2 = deliveryPackage.GetItemCount(itemId);
					goto IL_0030;
				}
			}
			num2 = 0;
			goto IL_0030;
			IL_0030:
			return num + num2;
		}

		private static void TopUp(Player player, int itemId, int need)
		{
			DeliveryPackage deliveryPackage = player.deliveryPackage;
			if (DeliveryCount() != null || deliveryPackage == null || !deliveryPackage.unlocked)
			{
				return;
			}
			int num = need - player.package.GetItemCount(itemId);
			int num4 = default(int);
			int num6 = default(int);
			int num7 = default(int);
			while (num > 0)
			{
				int num2 = itemId;
				int num3 = num;
				deliveryPackage.TakeItems(ref num2, ref num3, ref num4);
				if (num2 != itemId || num3 <= 0)
				{
					break;
				}
				int num5 = player.package.AddItemStacked(itemId, num3, num4, ref num6);
				if (num5 < num3)
				{
					deliveryPackage.AddItem(itemId, num3 - num5, num6, ref num7);
					break;
				}
				num -= num5;
			}
		}

		private static bool Execute(BuildTool_Reform tool, MethodInfo action, float radius, int need)
		{
			if (((BuildTool)tool).player.sandCount - need < 0)
			{
				UIRealtimeTip.Popup(Text.NotEnoughSoilPile, true, 0);
				return false;
			}
			action.Invoke(tool, new object[3] { radius, need, true });
			return true;
		}

		private static void Compute(BuildTool_Reform tool, float radius, ref int cost, ref int gain)
		{
			//IL_0054: 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)
			if (tool.reformMode == 1)
			{
				((BuildTool)tool).factory.ComputeRestoreTerrainReform(tool.cursorPoints, tool.cursorIndices, tool.brushSize * tool.brushSize, tool.reformCenterPoint, radius, tool.cursorPointCount, ref cost, ref gain, 3f, 1f);
			}
			else
			{
				((BuildTool)tool).factory.ComputeFlattenTerrainReform(tool.cursorPoints, tool.reformCenterPoint, radius, tool.cursorPointCount, ref cost, ref gain, 3f, 1f);
			}
		}

		internal static Vector3 Center(List<Vector3> points, out float radius)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//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_0068: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			foreach (Vector3 point in points)
			{
				val += point;
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = points[0];
			Vector3 val3 = normalized * ((Vector3)(ref val2)).magnitude;
			float num = 0f;
			foreach (Vector3 point2 in points)
			{
				float val4 = num;
				val2 = point2 - val3;
				num = Math.Max(val4, ((Vector3)(ref val2)).magnitude);
			}
			radius = num + 0.990946f;
			return val3;
		}

		private static void CopyPackage(BuildTool_Reform tool)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			StorageComponent val = (StorageComponent)Package.GetValue(tool);
			if (val == null || val.size != ((BuildTool)tool).player.package.size)
			{
				val = new StorageComponent(((BuildTool)tool).player.package.size);
				Package.SetValue(tool, val);
			}
			Array.Copy(((BuildTool)tool).player.package.grids, val.grids, val.size);
		}

		private static int Clamp(long value)
		{
			return (int)Math.Max(-2147483648L, Math.Min(2147483647L, value));
		}

		private static T WithBrush<T>(BuildTool_Reform tool, Brush brush, Func<T> body)
		{
			//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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] cursorPoints = tool.cursorPoints;
			int[] cursorIndices = tool.cursorIndices;
			int cursorPointCount = tool.cursorPointCount;
			int brushSize = tool.brushSize;
			Vector3 reformCenterPoint = tool.reformCenterPoint;
			int num = (int)Line.GetValue(tool);
			int reformMode = tool.reformMode;
			int brushColor = tool.brushColor;
			int brushType = tool.brushType;
			bool buryVeins = tool.buryVeins;
			ItemProto handItem = tool.handItem;
			try
			{
				tool.cursorPoints = (Vector3[])(object)new Vector3[100];
				tool.cursorIndices = new int[100];
				for (int i = 0; i < 100; i++)
				{
					tool.cursorIndices[i] = -1;
				}
				tool.brushSize = 1;
				Line.SetValue(tool, 0);
				tool.reformMode = brush.Mode;
				tool.brushColor = brush.Color;
				tool.brushType = brush.Type;
				tool.buryVeins = brush.Bury;
				tool.handItem = brush.Item;
				return body();
			}
			finally
			{
				tool.cursorPoints = cursorPoints;
				tool.cursorIndices = cursorIndices;
				tool.cursorPointCount = cursorPointCount;
				tool.brushSize = brushSize;
				tool.reformCenterPoint = reformCenterPoint;
				Line.SetValue(tool, num);
				tool.reformMode = reformMode;
				tool.brushColor = brushColor;
				tool.brushType = brushType;
				tool.buryVeins = buryVeins;
				tool.handItem = handItem;
			}
		}

		private static void Snap(BuildTool_Reform tool, Vector3 point)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			tool.cursorIndices[0] = -1;
			Prepare.Invoke(tool, new object[1] { point });
		}

		private static T WithHandGuard<T>(Player player, int itemId, Func<T> body)
		{
			if (player.inhandItemId == itemId || player.inhandItemCount == 0)
			{
				return body();
			}
			int inhandItemCount = player.inhandItemCount;
			int inhandItemInc = player.inhandItemInc;
			HandCount.Invoke(player, new object[1] { 0 });
			HandInc.Invoke(player, new object[1] { 0 });
			try
			{
				return body();
			}
			finally
			{
				HandCount.Invoke(player, new object[1] { inhandItemCount });
				HandInc.Invoke(player, new object[1] { inhandItemInc });
			}
		}
	}
	internal sealed class PaintJob
	{
		public readonly PlanetFactory Factory;

		public readonly List<List<Vector3>> Blocks = new List<List<Vector3>>();

		public readonly List<Vector3> Centers = new List<Vector3>();

		public readonly List<Brush> Brushes = new List<Brush>();

		public int Total;

		public int Done;

		private bool _waiting;

		public static PaintJob? Current { get; private set; }

		public static bool Paused { get; set; }

		public static int BlockSize { get; set; } = 12;

		public PaintJob(PlanetFactory factory)
		{
			Factory = factory;
		}

		public void Add(Brush brush, List<List<Vector3>> blocks, int count)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			HashSet<Vector3> hashSet = new HashSet<Vector3>();
			foreach (List<Vector3> block in blocks)
			{
				hashSet.UnionWith(block);
			}
			float radius;
			for (int num = Blocks.Count - 1; num >= 0; num--)
			{
				int num2 = Blocks[num].RemoveAll(hashSet.Contains);
				if (num2 != 0)
				{
					Total -= num2;
					if (Blocks[num].Count == 0)
					{
						Blocks.RemoveAt(num);
						Centers.RemoveAt(num);
						Brushes.RemoveAt(num);
					}
					else
					{
						Centers[num] = GameReform.Center(Blocks[num], out radius);
					}
				}
			}
			foreach (List<Vector3> block2 in blocks)
			{
				Blocks.Add(block2);
				Centers.Add(GameReform.Center(block2, out radius));
				Brushes.Add(brush);
			}
			Total += count;
			_waiting = false;
		}

		public static bool Start(BuildTool_Reform tool, AreaGrid area, Brush brush)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			int num = ((brush.Mode == 1) ? Math.Min(BlockSize, 10) : BlockSize);
			int size = Math.Max(24, num);
			List<Vector3> list = new List<Vector3>();
			List<long> list2 = new List<long>();
			List<long> list3 = new List<long>();
			HashSet<int> hashSet = new HashSet<int>();
			for (int i = 0; i < area.Points.Count; i++)
			{
				if (hashSet.Add(area.Indices[i]))
				{
					list.Add(area.Points[i]);
					list2.Add(area.BlockKey(i, num));
					list3.Add(area.BlockKey(i, size));
				}
			}
			int tiles;
			long sand;
			string text = GameReform.Measure(tool, brush, Split(list, list3), out tiles, out sand);
			ManualLogSource? log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)($"Area: {list.Count} tiles ({tiles} to paint), mode {brush.Mode}, item {((Proto)(brush.Item?)).ID ?? 0}, soil ~{sand} of {((BuildTool)tool).player.sandCount}" + ((text != null) ? (", refused: " + text) : "")));
			}
			if (text != null)
			{
				UIRealtimeTip.Popup(text, true, 0);
				return false;
			}
			if (tiles == 0)
			{
				return true;
			}
			List<List<Vector3>> blocks = Split(list, list2);
			if (Current != null && Current.Factory == ((BuildTool)tool).factory)
			{
				Current.Add(brush, blocks, list.Count);
				Tick();
				return true;
			}
			Current = new PaintJob(((BuildTool)tool).factory);
			Current.Add(brush, blocks, list.Count);
			((BuildTool)tool).player.ClearOrders();
			((BuildTool)tool).controller.actionMine.miningType = (EObjectType)0;
			((BuildTool)tool).controller.actionMine.miningId = 0;
			((BuildTool)tool).controller.actionMine.miningTick = 0;
			GameScenarioLogic gameScenario = GameMain.gameScenario;
			if (gameScenario != null)
			{
				gameScenario.NotifyOnDoReformOpt(1);
			}
			Tick();
			return true;
		}

		internal static List<List<Vector3>> Split(IList<Vector3> points, IList<long> keys)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			List<List<Vector3>> list = new List<List<Vector3>>();
			Dictionary<long, List<Vector3>> dictionary = new Dictionary<long, List<Vector3>>();
			for (int i = 0; i < points.Count; i++)
			{
				if (!dictionary.TryGetValue(keys[i], out var value))
				{
					value = new List<Vector3>();
					dictionary[keys[i]] = value;
					list.Add(value);
				}
				value.Add(points[i]);
			}
			return list;
		}

		public static void Tick()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			PaintJob current = Current;
			if (current == null)
			{
				return;
			}
			Player mainPlayer = GameMain.mainPlayer;
			if (GameMain.data == null || mainPlayer == null)
			{
				Stop(notify: false, null);
				return;
			}
			PendingTiles.Draw(current.Factory.planet, current.Blocks);
			if (GameMain.isPaused || Paused)
			{
				return;
			}
			BuildTool_Reform val = mainPlayer.controller?.actionBuild?.reformTool;
			if (val == null || mainPlayer.factory != current.Factory || ((BuildTool)val).factory != current.Factory)
			{
				Stop(notify: true, "Area painting stopped: you left the planet.");
				return;
			}
			try
			{
				int num = -1;
				float num2 = mainPlayer.mecha.buildArea * mainPlayer.mecha.buildArea;
				for (int i = 0; i < current.Centers.Count; i++)
				{
					Vector3 val2 = current.Centers[i] - mainPlayer.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude <= num2)
					{
						num2 = sqrMagnitude;
						num = i;
					}
				}
				if (num < 0)
				{
					if (!current._waiting)
					{
						UIRealtimeTip.Popup(Text.OutOfRange, true, 0);
					}
					current._waiting = true;
					return;
				}
				current._waiting = false;
				List<Vector3> list = current.Blocks[num];
				Brush brush = current.Brushes[num];
				current.Blocks.RemoveAt(num);
				current.Centers.RemoveAt(num);
				current.Brushes.RemoveAt(num);
				if (!GameReform.Apply(val, brush, list))
				{
					Stop(notify: true, null);
					return;
				}
				current.Done += list.Count;
				if (current.Blocks.Count == 0)
				{
					Stop(notify: true, (current.Done > list.Count) ? Text.Complete(current.Done) : null);
				}
			}
			catch (Exception ex)
			{
				Stop(notify: true, "Area painting stopped; see the BepInEx log.");
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)ex);
				}
			}
		}

		public static void Cancel()
		{
			if (Current != null)
			{
				Stop(notify: true, "Area painting cancelled.");
			}
		}

		private static void Stop(bool notify, string? message)
		{
			Current = null;
			Paused = false;
			PendingTiles.Clear();
			if (notify)
			{
				GameScenarioLogic gameScenario = GameMain.gameScenario;
				if (gameScenario != null)
				{
					gameScenario.NotifyOnDoReformOpt(2);
				}
			}
			if (message != null)
			{
				UIRealtimeTip.Popup(message, true, 0);
			}
		}
	}
	internal static class PendingTiles
	{
		private static readonly Color Tint = new Color(0.35f, 0.85f, 1f);

		private static Mesh? _mesh;

		private static Material? _material;

		private static bool _noShader;

		private static int _shownBlocks = -1;

		private static float _builtAt;

		internal static bool Enabled { get; set; } = true;

		internal static void Draw(PlanetData planet, List<List<Vector3>> blocks)
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_01ae: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || blocks.Count == 0 || planet != GameMain.localPlanet || planet.data == null || !Ready())
			{
				return;
			}
			if ((Object)(object)_mesh == (Object)null || (_shownBlocks != blocks.Count && Time.unscaledTime - _builtAt > 0.25f))
			{
				List<Vector3> list = new List<Vector3>();
				List<int> list2 = new List<int>();
				float floor = planet.realRadius + 0.2f;
				float num = (float)Math.PI * 2f * planet.realRadius / ((float)planet.factory.platformSystem.segment * 5f);
				Build(blocks, num * 0.42f, (Vector3 p) => Math.Max(planet.data.QueryModifiedHeight(p), floor) + 0.15f, list, list2);
				if (_mesh == null)
				{
					_mesh = new Mesh
					{
						indexFormat = (IndexFormat)1
					};
				}
				_mesh.Clear();
				_mesh.SetVertices(list);
				Color[] array = (Color[])(object)new Color[list.Count];
				for (int num2 = 0; num2 < array.Length; num2++)
				{
					array[num2] = Color.white;
				}
				_mesh.colors = array;
				_mesh.SetTriangles(list2, 0);
				_mesh.RecalculateBounds();
				_shownBlocks = blocks.Count;
				_builtAt = Time.unscaledTime;
			}
			_material.color = new Color(Tint.r, Tint.g, Tint.b, 0.3f + 0.15f * Mathf.Sin(Time.unscaledTime * 4f));
			Graphics.DrawMesh(_mesh, Matrix4x4.identity, _material, 0, (Camera)null, 0, (MaterialPropertyBlock)null, (ShadowCastingMode)0, false);
		}

		internal static void Clear()
		{
			if ((Object)(object)_mesh != (Object)null)
			{
				Object.Destroy((Object)(object)_mesh);
			}
			_mesh = null;
			_shownBlocks = -1;
		}

		private static bool Ready()
		{
			//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)
			//IL_006d: Expected O, but got Unknown
			if ((Object)(object)_material != (Object)null)
			{
				return true;
			}
			if (_noShader)
			{
				return false;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("UI/Default");
			if ((Object)(object)val == (Object)null)
			{
				_noShader = true;
				ManualLogSource? log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"No transparent shader found; pending blocks are not highlighted");
				}
				return false;
			}
			_material = new Material(val)
			{
				renderQueue = 3000
			};
			return true;
		}

		internal static void Build(List<List<Vector3>> blocks, float half, Func<Vector3, float> height, List<Vector3> vertices, List<int> triangles)
		{
			//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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			foreach (List<Vector3> block in blocks)
			{
				foreach (Vector3 item in block)
				{
					Vector3 current = item;
					Vector3 normalized = ((Vector3)(ref current)).normalized;
					Vector3 val = Vector3.Cross(Vector3.up, normalized);
					val = ((((Vector3)(ref val)).sqrMagnitude < 1E-06f) ? Vector3.right : ((Vector3)(ref val)).normalized);
					Vector3 val2 = Vector3.Cross(normalized, val);
					Vector3 val3 = normalized * height(current);
					int count = vertices.Count;
					vertices.Add(val3 + (-val - val2) * half);
					vertices.Add(val3 + (val - val2) * half);
					vertices.Add(val3 + (val + val2) * half);
					vertices.Add(val3 + (-val + val2) * half);
					triangles.Add(count);
					triangles.Add(count + 1);
					triangles.Add(count + 2);
					triangles.Add(count);
					triangles.Add(count + 2);
					triangles.Add(count + 3);
				}
			}
		}
	}
	[BepInPlugin("bug.dsp.terragrid", "BUG_TerraGrid", "1.0.0")]
	[BepInIncompatibility("ExcelDsp.Painter")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "bug.dsp.terragrid";

		public const string Name = "BUG_TerraGrid";

		public const string Version = "1.0.0";

		internal static ManualLogSource? Log;

		private Harmony? _harmony;

		private ConfigEntry<KeyboardShortcut>? _areaKey;

		private ConfigEntry<KeyboardShortcut>? _wayKey;

		private ConfigEntry<KeyboardShortcut>? _cancelKey;

		private ConfigEntry<KeyboardShortcut>? _pauseKey;

		public void Awake()
		{
			//IL_0027: 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_007b: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_areaKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "AreaMode", KeyboardShortcut.Deserialize("D + LeftControl"), "Turn area mode of the foundation tool on or off (off also closes the tool)");
			_wayKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "LongWayAround", KeyboardShortcut.Deserialize("P + LeftControl"), "Between the two corners, go the short way or the long way around the planet");
			_cancelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "Cancel", KeyboardShortcut.Deserialize("D + LeftControl + LeftShift"), "Cancel the painting in progress");
			_pauseKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "PauseResume", KeyboardShortcut.Deserialize("P + LeftControl + LeftShift"), "Pause or resume the painting in progress");
			ConfigEntry<int> blockSize = ((BaseUnityPlugin)this).Config.Bind<int>("Painting", "BlockSize", 12, new ConfigDescription("Areas are painted in BlockSize x BlockSize blocks, one block per frame. Larger is faster but each frame does more work (restore: at most 10)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			ConfigEntry<bool> pending = ((BaseUnityPlugin)this).Config.Bind<bool>("Painting", "ShowPendingTiles", true, "Mark tiles still to be painted (for example out of mecha range) with blue squares");
			PaintJob.BlockSize = blockSize.Value;
			blockSize.SettingChanged += delegate
			{
				PaintJob.BlockSize = blockSize.Value;
			};
			PendingTiles.Enabled = pending.Value;
			pending.SettingChanged += delegate
			{
				PendingTiles.Enabled = pending.Value;
			};
			_harmony = new Harmony("bug.dsp.terragrid");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BUG_TerraGrid 1.0.0 loaded");
		}

		public void OnDestroy()
		{
			AreaTool.On = false;
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
		}

		public void Update()
		{
			//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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _cancelKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				PaintJob.Cancel();
			}
			else
			{
				value = _areaKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					AreaTool.On = !AreaTool.On;
					if (!AreaTool.On)
					{
						CloseTool();
					}
					UIRealtimeTip.Popup(Text.Mode(AreaTool.On), false, 0);
				}
			}
			value = _pauseKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				if (PaintJob.Current != null)
				{
					PaintJob.Paused = !PaintJob.Paused;
					UIRealtimeTip.Popup(Text.Paused(PaintJob.Paused), false, 0);
				}
			}
			else
			{
				value = _wayKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown() && AreaTool.On)
				{
					AreaTool.ShortWay = !AreaTool.ShortWay;
					UIRealtimeTip.Popup(Text.Way(AreaTool.ShortWay), false, 0);
				}
			}
			PaintJob.Tick();
		}

		private static void CloseTool()
		{
			Player mainPlayer = GameMain.mainPlayer;
			BuildTool_Reform val = ((mainPlayer == null) ? null : mainPlayer.controller?.actionBuild?.reformTool);
			if (val != null && ((BuildTool)val).active)
			{
				mainPlayer.SetHandItems(0, 0, 0);
				((BuildTool)val)._Close();
			}
		}
	}
	internal static class Text
	{
		public const string SelectStart = "Click the first corner";

		public const string PitInSelection = "A Dark Fog base pit is in the selection; remove it with the normal foundation brush first.";

		public const string SelectFoundation = "Pick a foundation first.";

		public const string Cancelled = "Area painting cancelled.";

		public const string LeftPlanet = "Area painting stopped: you left the planet.";

		public const string Failed = "Area painting stopped; see the BepInEx log.";

		public const string LongPath = "long way around";

		public static string LackOfItem => Localization.Translate("物品不足");

		public static string NotEnoughSoilPile => Localization.Translate("沙土不足");

		public static string OutOfRange => Localization.Translate("目标超出范围") + " — painting continues when you get close to the blue squares.";

		public static string Mode(bool on)
		{
			if (!on)
			{
				return "Area painting off";
			}
			return "Area painting on";
		}

		public static string Way(bool shortest)
		{
			if (!shortest)
			{
				return "Long way around the planet";
			}
			return "Short way between corners";
		}

		public static string Paused(bool paused)
		{
			if (!paused)
			{
				return "Area painting resumed";
			}
			return "Area painting paused";
		}

		public static string Selected(int columns, int rows, int count)
		{
			return $"Selected: {columns} × {rows} ({count} tiles)";
		}

		public static string Painting(int done, int total, bool paused)
		{
			return $"Painting: {done}/{total} ({((total > 0) ? (done * 100 / total) : 0)}%)" + (paused ? " (paused)" : "");
		}

		public static string Complete(int tiles)
		{
			return $"Area painting done: {tiles} tiles.";
		}

		public static string LackOfItems(int need, int have)
		{
			return $"{LackOfItem} — need {need}, have {have}.";
		}

		public static string NotEnoughSoil(long need, long have)
		{
			return $"{NotEnoughSoilPile} — need ≈{need}, have {have}.";
		}
	}
}