Decompiled source of TidyTerrain v1.4.0

TidyTerrain.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AskaShared.Game;
using AwesomeTechnologies.VegetationSystem;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Fusion;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Combat;
using SSSGame.Pathfinding;
using SandSailorStudio.Render;
using SandSailorStudio.TerrainTools;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("TidyTerrain")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0")]
[assembly: AssemblyInformationalVersion("1.4.0+03d3833ed921e714abd93ef8b53f39dc1beca10f")]
[assembly: AssemblyProduct("Tidy Terrain")]
[assembly: AssemblyTitle("TidyTerrain")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AskaTidyTerrain
{
	internal static class ArmingReport
	{
		internal static int Armed;

		internal static int Attempted;

		internal static bool TryPatch(Harmony harmony, MethodBase target, string label, HarmonyMethod prefix = null, HarmonyMethod postfix = null)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			Attempted++;
			bool flag = default(bool);
			if (target == null)
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[arm-fail] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": target method not found");
				}
				log.LogWarning(val);
				return false;
			}
			try
			{
				harmony.Patch(target, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Armed++;
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[armed] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(label);
				}
				log2.LogInfo(val2);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				bool flag2 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(13, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[arm-fail] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log3.LogWarning(val);
				return false;
			}
		}

		internal static void LogTotal()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] armed ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Armed);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Attempted);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" patches.");
			}
			log.LogInfo(val);
		}
	}
	internal enum BoulderAction
	{
		Resnap,
		Destroy
	}
	internal static class BoulderService
	{
		private const string BouldersSection = "TidyTerrain.Boulders";

		private const string ActionDescription = "Resnap = move this boulder onto the new ground, half-buried; Destroy = blow it up instead. Destroyed boulders drop nothing.";

		private const string ExplosionEffectsDescription = "Play the game's rock-destruction explosion when a boulder set to Destroy is removed. False removes it silently.";

		private const bool DefaultExplosionEffects = true;

		private const float GrowthCheckIntervalSeconds = 1f;

		private static bool _initialized;

		private static int _descriptorCountAtInit;

		private static float _nextGrowthCheckTime;

		private static bool _initFailureLogged;

		private static bool _lookupFailureLogged;

		private static bool _knownLookupFailureLogged;

		private static bool _explosionEffectsBound;

		private static ConfigEntry<bool> _explosionEffects;

		private static readonly Dictionary<IntPtr, ConfigEntry<BoulderAction>> _actionsByDescriptor = new Dictionary<IntPtr, ConfigEntry<BoulderAction>>();

		private static readonly HashSet<IntPtr> _boulderDescriptors = new HashSet<IntPtr>();

		internal static bool ExplosionEffects
		{
			get
			{
				if (_explosionEffects == null)
				{
					return true;
				}
				return _explosionEffects.Value;
			}
		}

		internal static void BindGlobalConfig()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (_explosionEffectsBound)
			{
				return;
			}
			_explosionEffectsBound = true;
			try
			{
				_explosionEffects = Plugin.PublicConfig.Bind<bool>("TidyTerrain.Boulders", "ExplosionEffects", true, "Play the game's rock-destruction explosion when a boulder set to Destroy is removed. False removes it silently.");
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(84, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulders: binding [");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("TidyTerrain.Boulders");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] ExplosionEffects failed; destruction FX stay on: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		internal static void EnsureInitialized()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (_initialized && !DescriptorTableChanged())
			{
				return;
			}
			try
			{
				TryInitialize();
			}
			catch (Exception ex)
			{
				if (!_initFailureLogged)
				{
					_initFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(101, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulder init failed; boulder handling is inactive and further attempts will be silent: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		internal static bool TryGetAction(BiomeItemDescriptor descriptor, out BoulderAction action)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			action = BoulderAction.Resnap;
			if (!_initialized || descriptor == null)
			{
				return false;
			}
			try
			{
				if (!_actionsByDescriptor.TryGetValue(((Il2CppObjectBase)descriptor).Pointer, out var value))
				{
					return false;
				}
				action = value.Value;
				return true;
			}
			catch (Exception ex)
			{
				if (!_lookupFailureLogged)
				{
					_lookupFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(121, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulder action lookup failed; affected boulders keep vanilla behavior and further failures will be silent: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
				return false;
			}
		}

		internal static bool IsKnownBoulderDescriptor(BiomeItemDescriptor descriptor)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (descriptor == null)
			{
				return false;
			}
			if (!_initialized)
			{
				return true;
			}
			try
			{
				return _boulderDescriptors.Contains(((Il2CppObjectBase)descriptor).Pointer);
			}
			catch (Exception ex)
			{
				if (!_knownLookupFailureLogged)
				{
					_knownLookupFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(117, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulder identity lookup failed; affected instances are left alone and further failures will be silent: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
				return true;
			}
		}

		private static bool DescriptorTableChanged()
		{
			float time = Time.time;
			if (time < _nextGrowthCheckTime)
			{
				return false;
			}
			_nextGrowthCheckTime = time + 1f;
			try
			{
				BiomeProceduralDataHandler handler = BiomeItemInstance.Handler;
				if (handler == null)
				{
					return false;
				}
				Dictionary<int, BiomeItemDescriptor> descriptorsTable = handler._descriptorsTable;
				if (descriptorsTable == null)
				{
					return false;
				}
				return descriptorsTable.Count != _descriptorCountAtInit;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static void TryInitialize()
		{
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Expected O, but got Unknown
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Expected O, but got Unknown
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Expected O, but got Unknown
			if (RetentionService.IsWindowOpen)
			{
				return;
			}
			BiomeProceduralDataHandler handler = BiomeItemInstance.Handler;
			if (handler == null)
			{
				return;
			}
			Dictionary<int, BiomeItemDescriptor> descriptorsTable = handler._descriptorsTable;
			if (descriptorsTable == null)
			{
				return;
			}
			int count = descriptorsTable.Count;
			if (count == 0)
			{
				return;
			}
			Dictionary<string, List<BiomeItemDescriptor>> dictionary = new Dictionary<string, List<BiomeItemDescriptor>>();
			HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Enumerator<int, BiomeItemDescriptor> enumerator = descriptorsTable.GetEnumerator();
			while (enumerator.MoveNext())
			{
				BiomeItemDescriptor value = enumerator.Current.Value;
				if (value == null)
				{
					continue;
				}
				num++;
				if (!IsBoulder(value))
				{
					continue;
				}
				try
				{
					hashSet.Add(((Il2CppObjectBase)value).Pointer);
				}
				catch (Exception)
				{
				}
				string text = DescriptorName(value);
				if (string.IsNullOrEmpty(text))
				{
					num3++;
					continue;
				}
				num2++;
				if (!dictionary.TryGetValue(text, out var value2))
				{
					value2 = new List<BiomeItemDescriptor>();
					dictionary.Add(text, value2);
				}
				value2.Add(value);
			}
			if (num == 0)
			{
				return;
			}
			List<string> unbindable = null;
			Dictionary<string, ConfigEntry<BoulderAction>> entries = new Dictionary<string, ConfigEntry<BoulderAction>>();
			List<string> names = new List<string>(dictionary.Keys);
			names.Sort(StringComparer.Ordinal);
			ConfigBatch.Run(Plugin.PublicConfig, delegate
			{
				int num5 = 0;
				foreach (string item in names)
				{
					try
					{
						bool num6 = ConfigBatch.IsNew(Plugin.PublicConfig, "TidyTerrain.Boulders", item);
						entries[item] = Plugin.PublicConfig.Bind<BoulderAction>("TidyTerrain.Boulders", item, BoulderAction.Resnap, "Resnap = move this boulder onto the new ground, half-buried; Destroy = blow it up instead. Destroyed boulders drop nothing.");
						if (num6)
						{
							num5++;
						}
					}
					catch (Exception)
					{
						entries.Remove(item);
						if (unbindable == null)
						{
							unbindable = new List<string>();
						}
						unbindable.Add(item);
					}
				}
				return num5;
			});
			Dictionary<IntPtr, ConfigEntry<BoulderAction>> dictionary2 = new Dictionary<IntPtr, ConfigEntry<BoulderAction>>();
			int num4 = 0;
			foreach (string item2 in names)
			{
				if (!entries.TryGetValue(item2, out var value3))
				{
					continue;
				}
				foreach (BiomeItemDescriptor item3 in dictionary[item2])
				{
					if (item3 != null)
					{
						try
						{
							dictionary2[((Il2CppObjectBase)item3).Pointer] = value3;
						}
						catch (Exception)
						{
							num4++;
						}
					}
				}
			}
			_actionsByDescriptor.Clear();
			foreach (KeyValuePair<IntPtr, ConfigEntry<BoulderAction>> item4 in dictionary2)
			{
				_actionsByDescriptor.Add(item4.Key, item4.Value);
			}
			_boulderDescriptors.Clear();
			foreach (IntPtr item5 in hashSet)
			{
				_boulderDescriptors.Add(item5);
			}
			bool initialized = _initialized;
			int descriptorCountAtInit = _descriptorCountAtInit;
			_initialized = true;
			_descriptorCountAtInit = count;
			bool flag = default(bool);
			if (num3 > 0)
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(93, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulders: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" boulder descriptor(s) had no readable name and cannot be configured.");
				}
				log.LogWarning(val);
			}
			if (unbindable != null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(110, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulders: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(unbindable.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type(s) have names BepInEx cannot use as config keys and will keep vanilla behavior: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", unbindable));
				}
				log2.LogWarning(val);
			}
			if (num4 > 0)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(102, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulders: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num4);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" descriptor(s) could not be indexed for lookup and will keep vanilla behavior.");
				}
				log3.LogWarning(val);
			}
			string text2 = (initialized ? $"re-enumerated (descriptor table changed {descriptorCountAtInit} -> {count})" : "initialized");
			ManualLogSource log4 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(106, 6, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] boulders ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" descriptor(s) walked, ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" boulder descriptor(s) across ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(dictionary.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" type(s), ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(entries.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" [");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("TidyTerrain.Boulders");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] entries bound.");
			}
			log4.LogInfo(val2);
		}

		private static bool IsBoulder(BiomeItemDescriptor descriptor)
		{
			try
			{
				return !descriptor.IsHarvestable && !descriptor._removableByTerraforming && !descriptor.HasHealthData();
			}
			catch (Exception)
			{
				return false;
			}
		}

		internal static string DescriptorName(BiomeItemDescriptor descriptor)
		{
			try
			{
				GameObject biomeItemPrefab = descriptor._biomeItemPrefab;
				if ((Object)(object)biomeItemPrefab != (Object)null)
				{
					return ((Object)biomeItemPrefab).name;
				}
			}
			catch (Exception)
			{
			}
			try
			{
				VegetationItemInfoPro biomeInfo = descriptor.GetBiomeInfo();
				if (biomeInfo != null && !string.IsNullOrEmpty(biomeInfo.Name))
				{
					return biomeInfo.Name;
				}
			}
			catch (Exception)
			{
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class CharacterSpawnPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Spawned")]
		public static void Spawned(Character __instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			LocalPlayerTool.AttachOnSpawn(__instance, Plugin.Log, "TidyTerrain_Tool", Vector3.zero, typeof(TidyTerrainTool));
		}
	}
	internal static class ConfigBatch
	{
		internal static void Run(ConfigFile config, Func<int> bindAll)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			int num;
			try
			{
				num = bindAll();
			}
			finally
			{
				config.SaveOnConfigSet = saveOnConfigSet;
			}
			if (!(num > 0 && saveOnConfigSet))
			{
				return;
			}
			try
			{
				config.Save();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(120, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] saving the config after binding ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" new entr(ies) threw; they apply this session but may not be in the file: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		internal static bool IsNew(ConfigFile config, string section, string key)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return !config.ContainsKey(new ConfigDefinition(section, key));
		}
	}
	internal readonly struct QueryCircle
	{
		internal float X { get; }

		internal float Z { get; }

		internal float Radius { get; }

		internal QueryCircle(float x, float z, float radius)
		{
			X = x;
			Z = z;
			Radius = radius;
		}
	}
	internal sealed class Footprint
	{
		private struct Tile
		{
			public float CenterX;

			public float CenterZ;

			public float HalfWidth;

			public float HalfHeight;

			public float Cos;

			public float Sin;
		}

		private const float ClusterJoinMeters = 10f;

		private readonly List<Tile> _tiles = new List<Tile>();

		internal bool IsEmpty => _tiles.Count == 0;

		internal void AddTile(float centerX, float centerZ, float width, float height, float blend, float rotationDegrees)
		{
			double num = (double)rotationDegrees * Math.PI / 180.0;
			_tiles.Add(new Tile
			{
				CenterX = centerX,
				CenterZ = centerZ,
				HalfWidth = width * 0.5f + blend,
				HalfHeight = height * 0.5f + blend,
				Cos = (float)Math.Cos(num),
				Sin = (float)Math.Sin(num)
			});
		}

		internal bool Contains(float x, float z)
		{
			for (int i = 0; i < _tiles.Count; i++)
			{
				Tile tile = _tiles[i];
				float num = x - tile.CenterX;
				float num2 = z - tile.CenterZ;
				float value = num * tile.Cos - num2 * tile.Sin;
				float value2 = num * tile.Sin + num2 * tile.Cos;
				if (Math.Abs(value) <= tile.HalfWidth && Math.Abs(value2) <= tile.HalfHeight)
				{
					return true;
				}
			}
			return false;
		}

		internal List<QueryCircle> QueryCircles()
		{
			int count = _tiles.Count;
			float[] array = new float[count];
			float[] array2 = new float[count];
			float[] array3 = new float[count];
			float[] array4 = new float[count];
			for (int i = 0; i < count; i++)
			{
				Tile tile = _tiles[i];
				float num = Math.Abs(tile.HalfWidth * tile.Cos) + Math.Abs(tile.HalfHeight * tile.Sin);
				float num2 = Math.Abs(tile.HalfWidth * tile.Sin) + Math.Abs(tile.HalfHeight * tile.Cos);
				array[i] = tile.CenterX - num;
				array2[i] = tile.CenterX + num;
				array3[i] = tile.CenterZ - num2;
				array4[i] = tile.CenterZ + num2;
			}
			int[] array5 = new int[count];
			for (int j = 0; j < count; j++)
			{
				array5[j] = j;
			}
			for (int k = 0; k < count; k++)
			{
				for (int l = k + 1; l < count; l++)
				{
					if (array[l] - array2[k] <= 10f && array[k] - array2[l] <= 10f && array3[l] - array4[k] <= 10f && array3[k] - array4[l] <= 10f)
					{
						array5[Root(array5, k)] = Root(array5, l);
					}
				}
			}
			Dictionary<int, float[]> dictionary = new Dictionary<int, float[]>();
			List<int> list = new List<int>();
			for (int m = 0; m < count; m++)
			{
				int num3 = Root(array5, m);
				if (!dictionary.TryGetValue(num3, out var value))
				{
					dictionary.Add(num3, new float[4]
					{
						array[m],
						array2[m],
						array3[m],
						array4[m]
					});
					list.Add(num3);
				}
				else
				{
					value[0] = Math.Min(value[0], array[m]);
					value[1] = Math.Max(value[1], array2[m]);
					value[2] = Math.Min(value[2], array3[m]);
					value[3] = Math.Max(value[3], array4[m]);
				}
			}
			List<QueryCircle> list2 = new List<QueryCircle>(list.Count);
			foreach (int item in list)
			{
				float[] array6 = dictionary[item];
				float num4 = (array6[1] - array6[0]) * 0.5f;
				float num5 = (array6[3] - array6[2]) * 0.5f;
				list2.Add(new QueryCircle(array6[0] + num4, array6[2] + num5, (float)Math.Sqrt(num4 * num4 + num5 * num5)));
			}
			return list2;
		}

		internal void Clear()
		{
			_tiles.Clear();
		}

		private static int Root(int[] parent, int i)
		{
			while (parent[i] != i)
			{
				parent[i] = parent[parent[i]];
				i = parent[i];
			}
			return i;
		}
	}
	internal static class GridCellCompletion
	{
		private struct AwaitingGrid
		{
			public TerraformingGridState State;

			public float GiveUpTime;
		}

		private static bool _warnedMarkThrow;

		private static bool _warnedSpawnThrow;

		private static bool _warnedShape;

		private static bool _marking;

		private const float LinkWaitSeconds = 10f;

		private static readonly List<AwaitingGrid> _awaiting = new List<AwaitingGrid>();

		private const int SamplesPerSide = 5;

		private const float SampleSpanFraction = 0.8f;

		public static void RefreshCellsHeightsPostfix(TerraformingGrid __instance)
		{
			if (_marking || !Plugin.ConfigEnabled.Value || !Plugin.ConfigAutoCompleteLevelCells.Value)
			{
				return;
			}
			try
			{
				MarkAlreadyLevel(__instance);
			}
			catch (Exception ex)
			{
				WarnOnce(ref _warnedMarkThrow, "marking already-level grid cells", ex);
			}
		}

		public static void SpawnedPostfix(TerraformingGridState __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && Plugin.ConfigEnabled.Value && Plugin.ConfigAutoCompleteLevelCells.Value)
			{
				_awaiting.Add(new AwaitingGrid
				{
					State = __instance,
					GiveUpTime = Time.time + 10f
				});
			}
		}

		internal static void Tick()
		{
			for (int num = _awaiting.Count - 1; num >= 0; num--)
			{
				AwaitingGrid awaitingGrid = _awaiting[num];
				try
				{
					if ((Object)(object)awaitingGrid.State == (Object)null)
					{
						_awaiting.RemoveAt(num);
					}
					else
					{
						TerraformingGrid grid = awaitingGrid.State._grid;
						if ((Object)(object)grid == (Object)null || grid.GetCellsCount() == 0)
						{
							if (Time.time >= awaitingGrid.GiveUpTime)
							{
								_awaiting.RemoveAt(num);
							}
						}
						else
						{
							_awaiting.RemoveAt(num);
							grid.RefreshCellsHeights(false, true);
						}
					}
				}
				catch (Exception ex)
				{
					_awaiting.RemoveAt(num);
					WarnOnce(ref _warnedSpawnThrow, "refreshing a newly spawned leveling grid", ex);
				}
			}
		}

		internal static void Reset()
		{
			_awaiting.Clear();
		}

		private static void WarnOnce(ref bool warned, string what, Exception ex)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (!warned)
			{
				warned = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(50, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(what);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" threw (further throws suppressed): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogWarning(val);
			}
		}

		private static void MarkAlreadyLevel(TerraformingGrid grid)
		{
			if ((Object)(object)grid == (Object)null)
			{
				return;
			}
			TerraformingGridState state = grid._state;
			if ((Object)(object)state == (Object)null || !((SimulationBehaviour)state).HasStateAuthority)
			{
				return;
			}
			int cellsCount = grid.GetCellsCount();
			if (cellsCount == 0)
			{
				return;
			}
			Il2CppStructArray<int> gridInteractMap = grid.gridInteractMap;
			Il2CppStructArray<bool> grid2 = ((PlacementGrid)grid).grid;
			if (gridInteractMap == null || grid2 == null || ((Il2CppArrayBase<int>)(object)gridInteractMap).Length < cellsCount || ((Il2CppArrayBase<bool>)(object)grid2).Length < cellsCount)
			{
				WarnShapeOnce(cellsCount, gridInteractMap, grid2);
				return;
			}
			int[] array = new int[cellsCount];
			bool[] array2 = new bool[cellsCount];
			float[][] array3 = new float[cellsCount][];
			bool[] array4 = new bool[cellsCount];
			float cellSize = CellSize(grid);
			for (int i = 0; i < cellsCount; i++)
			{
				array[i] = ((Il2CppArrayBase<int>)(object)gridInteractMap)[i];
				array2[i] = ((Il2CppArrayBase<bool>)(object)grid2)[i];
				if (array2[i] && array[i] == 0)
				{
					GatherCandidate(grid, gridInteractMap, i, cellSize, out array4[i], out array3[i]);
				}
			}
			List<int> list = LevelCellSelection.SelectAlreadyLevel(array, array2, array3, grid.ReferenceLevel, grid.levelError, array4);
			if (list.Count == 0)
			{
				return;
			}
			_marking = true;
			try
			{
				foreach (int item in list)
				{
					grid.MarkCellInteracted(item, true);
				}
			}
			finally
			{
				_marking = false;
			}
		}

		internal static void GatherCandidate(TerraformingGrid grid, Il2CppStructArray<int> interactMap, int cell, float cellSize, out bool accepted, out float[] samples)
		{
			samples = null;
			accepted = false;
			if (!(Math.Abs(grid.GetCellAverageHeight(cell) - grid.ReferenceLevel) > grid.levelError))
			{
				accepted = GameAcceptsIfHoed(grid, interactMap, cell);
				if (accepted && cellSize > 0f)
				{
					samples = SampleCell(grid, cell, cellSize);
				}
			}
		}

		private static float[] SampleCell(TerraformingGrid grid, int cell, float cellSize)
		{
			//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_000f: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Vector3 cellPosition = ((DynamicPlacementGrid)grid).GetCellPosition(cell);
			Transform transform = ((Component)grid).transform;
			Vector3 right = transform.right;
			Vector3 forward = transform.forward;
			float num = cellSize * 0.8f;
			float num2 = num / 4f;
			float[] array = new float[25];
			int num3 = 0;
			for (int i = 0; i < 5; i++)
			{
				for (int j = 0; j < 5; j++)
				{
					float num4 = (float)i * num2 - num * 0.5f;
					float num5 = (float)j * num2 - num * 0.5f;
					array[num3++] = TerrainSampler.SampleHeight(cellPosition + right * num4 + forward * num5);
				}
			}
			return array;
		}

		internal static float CellSize(TerraformingGrid grid)
		{
			PlacementGridConstants constants = ((PlacementGrid)grid).constants;
			if (!((Object)(object)constants != (Object)null))
			{
				return 0f;
			}
			return constants.tileSize;
		}

		internal static bool GameAcceptsIfHoed(TerraformingGrid grid, Il2CppStructArray<int> interactMap, int cell)
		{
			int num = ((Il2CppArrayBase<int>)(object)interactMap)[cell];
			((Il2CppArrayBase<int>)(object)interactMap)[cell] = 1;
			try
			{
				return grid.IsCellLeveled(cell);
			}
			finally
			{
				((Il2CppArrayBase<int>)(object)interactMap)[cell] = num;
			}
		}

		private static void WarnShapeOnce(int count, Il2CppStructArray<int> interactMap, Il2CppStructArray<bool> realMap)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!_warnedShape)
			{
				_warnedShape = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(139, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] a leveling grid's cell arrays do not match its ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" cells ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(stroke counts: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((interactMap == null) ? "missing" : ((Il2CppArrayBase<int>)(object)interactMap).Length.ToString());
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cell mask: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((realMap == null) ? "missing" : ((Il2CppArrayBase<bool>)(object)realMap).Length.ToString());
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); its already-level cells are not marked.");
				}
				log.LogWarning(val);
			}
		}
	}
	internal sealed class GroundSample
	{
		private readonly Vector3 _at;

		private readonly Transform _selfExclude;

		private bool _taken;

		private bool _found;

		private float _groundY;

		internal GroundSample(Vector3 at, Transform selfExclude)
		{
			//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)
			_at = at;
			_selfExclude = selfExclude;
		}

		internal bool TryGetY(out float groundY)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!_taken)
			{
				_found = GroundHeight.TrySampleGroundY(_at, _selfExclude, out _groundY);
				_taken = true;
			}
			groundY = _groundY;
			return _found;
		}
	}
	internal static class GroundHeight
	{
		private const float RaycastStartHeightMeters = 200f;

		private const float RaycastMaxDistanceMeters = 400f;

		private const int InitialHitCapacity = 64;

		private static Il2CppStructArray<RaycastHit> _hits;

		private static readonly Dictionary<int, bool> _isTerrainByCollider = new Dictionary<int, bool>();

		private const float SupportProbeMarginMeters = 0.25f;

		private const float SupportClearanceMeters = 0.1f;

		internal static void BeginPass()
		{
			_isTerrainByCollider.Clear();
		}

		public static bool TrySampleGroundY(Vector3 atPos, Transform selfExclude, out float groundY)
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0007: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			groundY = 0f;
			try
			{
				int num = CastDown(new Vector3(atPos.x, atPos.y + 200f, atPos.z), 400f);
				bool flag = false;
				float num2 = float.NegativeInfinity;
				bool flag2 = false;
				float num3 = float.NegativeInfinity;
				for (int i = 0; i < num; i++)
				{
					RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i];
					Collider collider = ((RaycastHit)(ref val)).collider;
					if (!IsSameOrRelatedTransform(((Object)(object)collider != (Object)null) ? ((Component)collider).transform : null, selfExclude))
					{
						if ((Object)(object)collider != (Object)null && IsTerrain(collider) && (!flag || ((RaycastHit)(ref val)).point.y > num2))
						{
							flag = true;
							num2 = ((RaycastHit)(ref val)).point.y;
						}
						if (!flag2 || ((RaycastHit)(ref val)).point.y > num3)
						{
							flag2 = true;
							num3 = ((RaycastHit)(ref val)).point.y;
						}
					}
				}
				if (flag)
				{
					groundY = num2;
					return true;
				}
				if (flag2)
				{
					groundY = num3;
					return true;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag3 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(43, 3, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] ground raycast at (");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(atPos.x, "F2");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(",");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(atPos.z, "F2");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
			}
			return false;
		}

		internal static bool TryFindSupportBetween(Vector3 atPos, Transform selfExclude, float currentY, float groundY, out string supportName)
		{
			//IL_0014: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			supportName = null;
			float num = Mathf.Max(currentY, groundY);
			float num2 = Mathf.Min(currentY, groundY);
			Vector3 origin = new Vector3(atPos.x, num + 0.25f, atPos.z);
			float distance = num - num2 + 0.25f;
			int num3 = CastDown(origin, distance);
			for (int i = 0; i < num3; i++)
			{
				RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i];
				Collider collider = ((RaycastHit)(ref val)).collider;
				if (!((Object)(object)collider == (Object)null) && !IsSameOrRelatedTransform(((Component)collider).transform, selfExclude) && !IsTerrain(collider) && !(((RaycastHit)(ref val)).point.y <= num2 + 0.1f))
				{
					supportName = ((Object)((Component)collider).gameObject).name;
					return true;
				}
			}
			return false;
		}

		private static int CastDown(Vector3 origin, float distance)
		{
			//IL_0014: 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)
			if (_hits == null)
			{
				_hits = new Il2CppStructArray<RaycastHit>(64L);
			}
			int num;
			while (true)
			{
				num = Physics.RaycastNonAlloc(origin, Vector3.down, _hits, distance, -5, (QueryTriggerInteraction)0);
				if (num < ((Il2CppArrayBase<RaycastHit>)(object)_hits).Length)
				{
					break;
				}
				_hits = new Il2CppStructArray<RaycastHit>((long)(((Il2CppArrayBase<RaycastHit>)(object)_hits).Length * 2));
			}
			return num;
		}

		private static bool IsTerrain(Collider collider)
		{
			int instanceID = ((Object)collider).GetInstanceID();
			if (!_isTerrainByCollider.TryGetValue(instanceID, out var value))
			{
				value = (Object)(object)((Component)collider).gameObject.GetComponent<Terrain>() != (Object)null;
				_isTerrainByCollider.Add(instanceID, value);
			}
			return value;
		}

		private static bool IsSameOrRelatedTransform(Transform hitTransform, Transform selfExclude)
		{
			if ((Object)(object)hitTransform == (Object)null || (Object)(object)selfExclude == (Object)null)
			{
				return false;
			}
			if ((Object)(object)hitTransform == (Object)(object)selfExclude)
			{
				return true;
			}
			if (hitTransform.IsChildOf(selfExclude))
			{
				return true;
			}
			if (selfExclude.IsChildOf(hitTransform))
			{
				return true;
			}
			return false;
		}
	}
	internal static class LevelCellSelection
	{
		internal static List<int> SelectAlreadyLevel(int[] hoes, bool[] real, float[][] samples, float target, float tolerance, bool[] acceptedIfHoed)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < hoes.Length; i++)
			{
				if (real[i] && hoes[i] == 0 && acceptedIfHoed[i] && AllWithin(samples[i], target, tolerance))
				{
					list.Add(i);
				}
			}
			return list;
		}

		private static bool AllWithin(float[] samples, float target, float tolerance)
		{
			if (samples == null || samples.Length == 0)
			{
				return false;
			}
			for (int i = 0; i < samples.Length; i++)
			{
				if (Math.Abs(samples[i] - target) > tolerance)
				{
					return false;
				}
			}
			return true;
		}
	}
	internal static class LevelingCompletionPatch
	{
		private struct PendingPass
		{
			public IntPtr Grid;

			public Footprint Footprint;

			public float Y;

			public float DueTime;
		}

		private const float BlendBandMeters = 1.5f;

		private const float FallbackCellSizeMeters = 2f;

		private static readonly List<PendingPass> _pending = new List<PendingPass>();

		private static bool _warnedCellSize;

		private static bool _warnedCellMask;

		internal static void OnRunOnAreaPrefix(TerraformingToolOperation operation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			try
			{
				if ((int)operation == 2)
				{
					RetentionService.OnLevelTile();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(62, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] LevelingCompletionPatch RunOnArea prefix threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		public static void OnGridCompletedPrefix(TerraformingGridState __instance)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			try
			{
				if (!Plugin.ConfigEnabled.Value || !Plugin.AutoResnap)
				{
					return;
				}
				TerraformingGrid val = (((Object)(object)__instance != (Object)null) ? __instance._grid : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				IntPtr pointer = ((Il2CppObjectBase)val).Pointer;
				foreach (PendingPass item in _pending)
				{
					if (item.Grid == pointer)
					{
						return;
					}
				}
				Footprint footprint = BuildGridFootprint(val);
				if (!footprint.IsEmpty)
				{
					_pending.Add(new PendingPass
					{
						Grid = pointer,
						Footprint = footprint,
						Y = val.ReferenceLevel,
						DueTime = Time.time + Plugin.AutoResnapDelay
					});
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(68, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] LevelingCompletionPatch grid-completion prefix threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
			}
		}

		private static Footprint BuildGridFootprint(TerraformingGrid grid)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0109: 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_0111: 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)
			float num = 2f;
			PlacementGridConstants constants = ((PlacementGrid)grid).constants;
			if ((Object)(object)constants != (Object)null)
			{
				num = constants.tileSize;
			}
			else if (!_warnedCellSize)
			{
				_warnedCellSize = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(95, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] a leveling grid has no PlacementGridConstants; its re-snap pass assumes ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(2f, "F1");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" m cells.");
				}
				log.LogWarning(val);
			}
			Footprint footprint = new Footprint();
			int cellsCount = grid.GetCellsCount();
			Il2CppStructArray<bool> grid2 = ((PlacementGrid)grid).grid;
			bool flag2 = grid2 != null && ((Il2CppArrayBase<bool>)(object)grid2).Length >= cellsCount;
			if (!flag2 && !_warnedCellMask)
			{
				_warnedCellMask = true;
				Plugin.Log.LogWarning((object)($"[TidyTerrain] a completed leveling grid's cell mask does not match its {cellsCount} cells; " + "its re-snap pass covers every cell of the grid."));
			}
			for (int i = 0; i < cellsCount; i++)
			{
				if (!flag2 || ((Il2CppArrayBase<bool>)(object)grid2)[i])
				{
					Vector3 cellPosition = ((DynamicPlacementGrid)grid).GetCellPosition(i);
					footprint.AddTile(cellPosition.x, cellPosition.z, num, num, 1.5f, 0f);
				}
			}
			return footprint;
		}

		internal static void Tick()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			if (_pending.Count == 0)
			{
				return;
			}
			float time = Time.time;
			bool flag = default(bool);
			for (int num = _pending.Count - 1; num >= 0; num--)
			{
				PendingPass pendingPass = _pending[num];
				if (!(time < pendingPass.DueTime))
				{
					_pending.RemoveAt(num);
					try
					{
						if (Plugin.ConfigEnabled.Value && Plugin.AutoResnap)
						{
							TidyTerrainService.ResnapRegion(pendingPass.Footprint, pendingPass.Y);
							StructureResnapService.ResnapRegion(pendingPass.Footprint, pendingPass.Y);
						}
					}
					catch (Exception ex)
					{
						ManualLogSource log = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] LevelingCompletionPatch Tick() threw: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
						}
						log.LogError(val);
					}
				}
			}
		}

		internal static void Reset()
		{
			_pending.Clear();
		}
	}
	internal static class MovedWorldGenRegistry
	{
		private struct Entry
		{
			public float Y;

			public bool Logged;
		}

		private const float XZMatchEpsilonMeters = 0.05f;

		private static readonly XzIndex<Entry> _entries = new XzIndex<Entry>(0.05f);

		internal static int Count => _entries.Count;

		internal static Vector3 PositionAt(int i)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(_entries.XAt(i), _entries.ValueAt(i).Y, _entries.ZAt(i));
		}

		internal static void Record(Vector3 newPos)
		{
			//IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			_entries.Record(newPos.x, newPos.z, new Entry
			{
				Y = newPos.y
			});
		}

		internal static bool TryGetRecordedY(Vector3 pos, out float recordedY)
		{
			//IL_0005: 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)
			if (!_entries.TryGet(pos.x, pos.z, out var value))
			{
				recordedY = 0f;
				return false;
			}
			recordedY = value.Y;
			return true;
		}

		internal static bool TryMarkLogged(Vector3 pos)
		{
			//IL_0005: 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)
			int num = _entries.IndexOf(pos.x, pos.z);
			if (num < 0 || _entries.ValueAt(num).Logged)
			{
				return false;
			}
			Entry value = _entries.ValueAt(num);
			value.Logged = true;
			_entries.SetValueAt(num, value);
			return true;
		}

		internal static void Clear()
		{
			_entries.Clear();
		}
	}
	[BepInPlugin("mugsy33.tidyterrain", "Tidy Terrain", "1.4.0")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.tidyterrain";

		public const string PluginName = "Tidy Terrain";

		public const string PluginVersion = "1.4.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ConfigEnabled;

		internal static ConfigEntry<bool> ConfigResnapStructures;

		internal static ConfigEntry<bool> ConfigAutoCompleteLevelCells;

		internal static ConfigFile PublicConfig;

		internal static readonly bool Vegetation = true;

		internal static readonly bool WorldGen = true;

		internal static readonly bool Corpses = true;

		internal static readonly float Tolerance = 0.1f;

		internal static readonly float SinkOffset = 0.25f;

		internal static readonly bool AutoResnap = true;

		internal static readonly float AutoResnapDelay = 0.75f;

		internal static readonly float CaveMargin = 0f;

		internal static readonly bool CaveExclusion = true;

		internal static readonly float BoulderSinkFraction = 0.5f;

		internal static readonly float SinkCapFraction = 0.15f;

		internal static readonly float StructureRadiusMargin = 10f;

		public override void Load()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ConfigEnabled = ((BasePlugin)this).Config.Bind<bool>("TidyTerrain", "Enabled", true, "Master on/off switch for Tidy Terrain.");
			ConfigResnapStructures = ((BasePlugin)this).Config.Bind<bool>("TidyTerrain", "ResnapStructures", true, "Move player-built structures vertically onto the new ground height after a leveling job, so buildings are not left floating or half-buried. Only the height changes - position and rotation are untouched.");
			ConfigAutoCompleteLevelCells = ((BasePlugin)this).Config.Bind<bool>("TidyTerrain", "AutoCompleteLevelCells", true, "Cells of a Terrain Level Field or building floor plan that are already at the target height count as done without hoeing.");
			PublicConfig = ((BasePlugin)this).Config;
			BoulderService.BindGlobalConfig();
			ClassInjector.RegisterTypeInIl2Cpp<TidyTerrainTool>();
			Harmony harmony = new Harmony("mugsy33.tidyterrain");
			Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)null);
			HarmonyMethod postfix = null;
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(HeightmapTool), "RunOnArea", new Type[6]
			{
				typeof(TerraformingToolOperation),
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(Vector3),
				typeof(float)
			}, (Type[])null), "SSSGame.HeightmapTool.RunOnArea", new HarmonyMethod(typeof(LevelingCompletionPatch), "OnRunOnAreaPrefix", (Type[])null), postfix);
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(TerraformingGridState), "Rpc_TurnIntoResultStructure", (Type[])null, (Type[])null), "SSSGame.TerraformingGridState.Rpc_TurnIntoResultStructure", new HarmonyMethod(typeof(LevelingCompletionPatch), "OnGridCompletedPrefix", (Type[])null));
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(BiomeItemInstance), "_OnActivateInstance", (Type[])null, (Type[])null), "SSSGame.BiomeItemInstance._OnActivateInstance", null, new HarmonyMethod(typeof(ProxyActivationPatch), "OnActivateInstancePostfix", (Type[])null));
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(BiomeItemInstance), "_RefreshGameObject", (Type[])null, (Type[])null), "SSSGame.BiomeItemInstance._RefreshGameObject", null, new HarmonyMethod(typeof(ProxyActivationPatch), "RefreshGameObjectPostfix", (Type[])null));
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(TerraformingGrid), "RefreshCellsHeights", (Type[])null, (Type[])null), "SSSGame.TerraformingGrid.RefreshCellsHeights", null, new HarmonyMethod(typeof(GridCellCompletion), "RefreshCellsHeightsPostfix", (Type[])null));
			ArmingReport.TryPatch(harmony, AccessTools.Method(typeof(TerraformingGridState), "Spawned", (Type[])null, (Type[])null), "SSSGame.TerraformingGridState.Spawned", null, new HarmonyMethod(typeof(GridCellCompletion), "SpawnedPostfix", (Type[])null));
			ArmingReport.LogTotal();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Tidy Terrain");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.4.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log.LogInfo(val);
		}
	}
	internal static class ProxyActivationPatch
	{
		private static bool _warnedThrow;

		public static void OnActivateInstancePostfix(BiomeItemInstance __instance)
		{
			Align(__instance);
		}

		public static void RefreshGameObjectPostfix(BiomeItemInstance __instance)
		{
			Align(__instance);
		}

		private static void Align(BiomeItemInstance instance)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			if (!Plugin.ConfigEnabled.Value || !Plugin.WorldGen)
			{
				return;
			}
			try
			{
				if (instance == null || MovedWorldGenRegistry.Count == 0)
				{
					return;
				}
				GameObject gameObject = ((WorldItemInstance)instance).gameObject;
				if (!((Object)(object)gameObject == (Object)null))
				{
					Transform transform = gameObject.transform;
					if (!((Object)(object)transform == (Object)null))
					{
						ProxyAlignment.Align(instance, transform, "activation");
					}
				}
			}
			catch (Exception ex)
			{
				if (!_warnedThrow)
				{
					_warnedThrow = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(64, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] proxy re-align threw (further throws suppressed): ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogWarning(val);
				}
			}
		}
	}
	internal enum ProxyAlignResult
	{
		Unregistered,
		Aligned,
		Corrected
	}
	internal static class ProxyAlignment
	{
		internal static ProxyAlignResult Align(BiomeItemInstance instance, Transform t, string source)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = t.position;
			if (!MovedWorldGenRegistry.TryGetRecordedY(position, out var recordedY))
			{
				return ProxyAlignResult.Unregistered;
			}
			bool num = Mathf.Abs(position.y - recordedY) > Plugin.Tolerance;
			if (num)
			{
				t.position = new Vector3(position.x, recordedY, position.z);
			}
			if (!num)
			{
				return ProxyAlignResult.Aligned;
			}
			return ProxyAlignResult.Corrected;
		}
	}
	internal static class ProxySweepService
	{
		private const float SweepIntervalSeconds = 2f;

		private const float SweepRangeMeters = 120f;

		private const float QueryRadiusMeters = 1f;

		private const float XZMatchEpsilonMeters = 0.05f;

		private const int HasGameObjectContexts = 311;

		private static int _cursor;

		private static bool _warnedThrow;

		private static List<WorldItemInstance> _scratch;

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

		internal static void Reset()
		{
			_refreshPending.Clear();
			_cursor = 0;
		}

		internal static void Tick(Vector3 playerPos)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			int count = MovedWorldGenRegistry.Count;
			if (!Plugin.WorldGen || count == 0)
			{
				return;
			}
			int num = (int)Math.Ceiling((float)count * Time.unscaledDeltaTime / 2f);
			if (num < 1)
			{
				num = 1;
			}
			else if (num > count)
			{
				num = count;
			}
			try
			{
				Sweep(playerPos, count, num);
			}
			catch (Exception ex)
			{
				if (!_warnedThrow)
				{
					_warnedThrow = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(61, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] proxy sweep threw (further throws suppressed): ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogWarning(val);
				}
			}
		}

		private static void Sweep(Vector3 playerPos, int count, int budget)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0060: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			ResourceManager resourceManager = TidyTerrainService.GetResourceManager();
			if ((Object)(object)resourceManager == (Object)null)
			{
				return;
			}
			if (_scratch == null)
			{
				_scratch = new List<WorldItemInstance>();
			}
			float num = 14400f;
			for (int i = 0; i < budget; i++)
			{
				if (_cursor >= count)
				{
					_cursor = 0;
				}
				int num2 = _cursor++;
				Vector3 val = MovedWorldGenRegistry.PositionAt(num2);
				float num3 = val.x - playerPos.x;
				float num4 = val.z - playerPos.z;
				if (num3 * num3 + num4 * num4 > num)
				{
					continue;
				}
				_scratch.Clear();
				resourceManager.GetAllInstancesList(_scratch, val, Quaternion.identity, new Vector3(1f, 1f, 1f), (SDFShape)1, (IWorldItemInstanceFilter)null, (InstanceActivationContext)1024, false);
				int count2 = _scratch.Count;
				for (int j = 0; j < count2; j++)
				{
					BiomeItemInstance val2 = TidyTerrainService.AsBiomeItemInstance(_scratch[j]);
					if (val2 == null)
					{
						continue;
					}
					GameObject gameObject = ((WorldItemInstance)val2).gameObject;
					if ((Object)(object)gameObject == (Object)null)
					{
						if (IsOnEntry(val2, val))
						{
							RestoreProxy(num2, val, val2);
						}
						continue;
					}
					Transform transform = gameObject.transform;
					if (!((Object)(object)transform == (Object)null))
					{
						if (IsOnEntry(val2, val))
						{
							_refreshPending.Remove(num2);
						}
						ProxyAlignment.Align(val2, transform, "sweep");
					}
				}
			}
		}

		private static bool IsOnEntry(BiomeItemInstance instance, Vector3 entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0020: 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)
			Vector3 position = ((WorldItemInstance)instance).GetPosition();
			if (Mathf.Abs(position.x - entry.x) <= 0.05f)
			{
				return Mathf.Abs(position.z - entry.z) <= 0.05f;
			}
			return false;
		}

		private static void RestoreProxy(int entryIndex, Vector3 entry, BiomeItemInstance instance)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if (!_refreshPending.Contains(entryIndex) && (((WorldItemInstance)instance).GetContexts() & 0x137) != 0)
			{
				_refreshPending.Add(entryIndex);
				instance.ForceRefreshGameObject();
				bool flag = (Object)(object)((WorldItemInstance)instance).gameObject != (Object)null;
				string text = (((Object)(object)((WorldItemInstance)instance).gameObject != (Object)null) ? ((Object)((WorldItemInstance)instance).gameObject).name : "world-gen object");
				ManualLogSource log = Plugin.Log;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(109, 4, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] proxy sweep: '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' at (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(entry.x, "F1");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(entry.z, "F1");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") had no proxy in a GameObject context; ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ForceRefreshGameObject() -> proxy ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(flag ? "restored" : "still missing");
				}
				log.LogInfo(val);
			}
		}
	}
	internal static class RetentionService
	{
		private const string RetentionSection = "TidyTerrain.Retention";

		private const string RetentionDescription = "Keep this type when leveling (re-snapped to new ground); false = vanilla deletion. Other tools always remove it.";

		private const float CloseDelayPadSeconds = 0.25f;

		private const float GrowthCheckIntervalSeconds = 1f;

		private static bool _initialized;

		private static int _descriptorCountAtInit;

		private static float _nextGrowthCheckTime;

		private static bool _initFailureLogged;

		private static bool _windowOpen;

		private static float _lastLevelTileTime;

		private static readonly Dictionary<string, List<BiomeItemDescriptor>> _deletable = new Dictionary<string, List<BiomeItemDescriptor>>();

		private static readonly Dictionary<string, ConfigEntry<bool>> _keepEntries = new Dictionary<string, ConfigEntry<bool>>();

		private static readonly List<BiomeItemDescriptor> _flipped = new List<BiomeItemDescriptor>();

		internal static bool IsWindowOpen => _windowOpen;

		internal static void OnLevelTile()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			try
			{
				EnsureInitialized();
				if (_windowOpen)
				{
					_lastLevelTileTime = Time.time;
				}
				else if (_initialized && Plugin.ConfigEnabled.Value)
				{
					OpenWindow();
					_lastLevelTileTime = Time.time;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(50, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] RetentionService.OnLevelTile threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		internal static void Tick()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			try
			{
				EnsureInitialized();
				if (_windowOpen)
				{
					float num = Plugin.AutoResnapDelay + 0.25f;
					if (!(Time.time - _lastLevelTileTime < num))
					{
						CloseWindow();
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] RetentionService.Tick threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		internal static void ForceClose()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			try
			{
				if (_windowOpen)
				{
					CloseWindow();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(49, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] RetentionService.ForceClose threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private static void EnsureInitialized()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (_initialized && !DescriptorTableChanged())
			{
				return;
			}
			try
			{
				TryInitialize();
			}
			catch (Exception ex)
			{
				if (!_initFailureLogged)
				{
					_initFailureLogged = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(96, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] retention init failed; retention is inactive and further attempts will be silent: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		private static bool DescriptorTableChanged()
		{
			float time = Time.time;
			if (time < _nextGrowthCheckTime)
			{
				return false;
			}
			_nextGrowthCheckTime = time + 1f;
			try
			{
				BiomeProceduralDataHandler handler = BiomeItemInstance.Handler;
				if (handler == null)
				{
					return false;
				}
				Dictionary<int, BiomeItemDescriptor> descriptorsTable = handler._descriptorsTable;
				if (descriptorsTable == null)
				{
					return false;
				}
				return descriptorsTable.Count != _descriptorCountAtInit;
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static void TryInitialize()
		{
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Expected O, but got Unknown
			if (_windowOpen)
			{
				return;
			}
			BiomeProceduralDataHandler handler = BiomeItemInstance.Handler;
			if (handler == null)
			{
				return;
			}
			Dictionary<int, BiomeItemDescriptor> descriptorsTable = handler._descriptorsTable;
			if (descriptorsTable == null)
			{
				return;
			}
			int count = descriptorsTable.Count;
			if (count == 0)
			{
				return;
			}
			Dictionary<string, List<BiomeItemDescriptor>> dictionary = new Dictionary<string, List<BiomeItemDescriptor>>();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			Enumerator<int, BiomeItemDescriptor> enumerator = descriptorsTable.GetEnumerator();
			while (enumerator.MoveNext())
			{
				BiomeItemDescriptor value = enumerator.Current.Value;
				if (value == null)
				{
					continue;
				}
				num++;
				GameObject biomeItemPrefab = value._biomeItemPrefab;
				string text = (((Object)(object)biomeItemPrefab != (Object)null) ? ((Object)biomeItemPrefab).name : null);
				bool removableByTerraforming = value._removableByTerraforming;
				if (removableByTerraforming && string.IsNullOrEmpty(text))
				{
					num3++;
				}
				else if (removableByTerraforming)
				{
					num2++;
					if (!dictionary.TryGetValue(text, out var value2))
					{
						value2 = new List<BiomeItemDescriptor>();
						dictionary.Add(text, value2);
					}
					value2.Add(value);
				}
			}
			if (num == 0)
			{
				return;
			}
			_deletable.Clear();
			_keepEntries.Clear();
			foreach (KeyValuePair<string, List<BiomeItemDescriptor>> item in dictionary)
			{
				_deletable.Add(item.Key, item.Value);
			}
			List<string> unbindable = null;
			List<string> names = new List<string>(_deletable.Keys);
			names.Sort(StringComparer.Ordinal);
			ConfigBatch.Run(Plugin.PublicConfig, delegate
			{
				int num4 = 0;
				foreach (string item2 in names)
				{
					try
					{
						bool num5 = ConfigBatch.IsNew(Plugin.PublicConfig, "TidyTerrain.Retention", item2);
						_keepEntries[item2] = Plugin.PublicConfig.Bind<bool>("TidyTerrain.Retention", item2, true, "Keep this type when leveling (re-snapped to new ground); false = vanilla deletion. Other tools always remove it.");
						if (num5)
						{
							num4++;
						}
					}
					catch (Exception)
					{
						_keepEntries.Remove(item2);
						if (unbindable == null)
						{
							unbindable = new List<string>();
						}
						unbindable.Add(item2);
					}
				}
				return num4;
			});
			bool initialized = _initialized;
			int descriptorCountAtInit = _descriptorCountAtInit;
			_initialized = true;
			_descriptorCountAtInit = count;
			bool flag = default(bool);
			if (num3 > 0)
			{
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(94, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] retention: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num3);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" deletable descriptor(s) had no prefab name and cannot be configured.");
				}
				log.LogWarning(val);
			}
			if (unbindable != null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(111, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] retention: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(unbindable.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" type(s) have names BepInEx cannot use as config keys and will keep vanilla behavior: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", unbindable));
				}
				log2.LogWarning(val);
			}
			string text2 = (initialized ? $"re-enumerated (descriptor table changed {descriptorCountAtInit} -> {count})" : "initialized");
			ManualLogSource log3 = Plugin.Log;
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(72, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] retention ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" descriptor(s), ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" deletable, ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_keepEntries.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" [");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("TidyTerrain.Retention");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] entries bound.");
			}
			log3.LogInfo(val2);
		}

		private static void OpenWindow()
		{
			_flipped.Clear();
			foreach (KeyValuePair<string, ConfigEntry<bool>> keepEntry in _keepEntries)
			{
				if (!keepEntry.Value.Value || !_deletable.TryGetValue(keepEntry.Key, out var value))
				{
					continue;
				}
				foreach (BiomeItemDescriptor item in value)
				{
					if (item != null && item._removableByTerraforming)
					{
						item._removableByTerraforming = false;
						_flipped.Add(item);
					}
				}
			}
			_windowOpen = true;
		}

		private static void CloseWindow()
		{
			int num = 0;
			foreach (BiomeItemDescriptor item in _flipped)
			{
				if (item != null)
				{
					item._removableByTerraforming = true;
					num++;
				}
			}
			_flipped.Clear();
			_windowOpen = false;
		}
	}
	internal static class StructureResnapService
	{
		private static SettlementManager _settlementManager;

		internal static int ResnapRegion(Footprint footprint, float y)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.ConfigEnabled.Value || !Plugin.ConfigResnapStructures.Value)
			{
				return 0;
			}
			if (footprint.IsEmpty)
			{
				return 0;
			}
			Settlement playerSettlement = GetPlayerSettlement();
			if ((Object)(object)playerSettlement == (Object)null)
			{
				return 0;
			}
			Structure settlementCore = GetSettlementCore(playerSettlement);
			HashSet<IntPtr> handled = new HashSet<IntPtr>();
			int num = 0;
			foreach (QueryCircle item in footprint.QueryCircles())
			{
				num += ResnapCircle(playerSettlement, settlementCore, new Vector3(item.X, y, item.Z), item.Radius, handled);
			}
			return num;
		}

		private static int ResnapCircle(Settlement settlement, Structure core, Vector3 center, float radius, HashSet<IntPtr> handled)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Expected O, but got Unknown
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			float num = radius + Plugin.StructureRadiusMargin;
			List<Structure> val = new List<Structure>();
			bool flag = default(bool);
			try
			{
				Vector3 val2 = center;
				float num2 = num;
				settlement.FindStructuresInRange(ref val2, ref num2, val, (Predicate<Structure>)null);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(93, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[TidyTerrain] Settlement.FindStructuresInRange threw; structures were not handled this pass: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log.LogError(val3);
				return 0;
			}
			int count;
			try
			{
				count = val.Count;
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[TidyTerrain] reading the structure result list's Count threw: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex2);
				}
				log2.LogError(val3);
				return 0;
			}
			if (count <= 0)
			{
				return 0;
			}
			float num3 = num * num;
			int num4 = 0;
			for (int i = 0; i < count; i++)
			{
				string text = "<unknown>";
				try
				{
					Structure val4 = val[i];
					if ((Object)(object)val4 == (Object)null)
					{
						continue;
					}
					text = SafeName(val4);
					if (!val4.IsActive || val4.Dismantled || IsSettlementCore(val4, core))
					{
						continue;
					}
					Transform transform = ((Component)val4).transform;
					if ((Object)(object)transform == (Object)null || IsStackedOnAnotherStructure(transform, out var _))
					{
						continue;
					}
					Vector3 position = transform.position;
					float num5 = position.x - center.x;
					float num6 = position.z - center.z;
					if (num5 * num5 + num6 * num6 > num3 || !handled.Add(((Il2CppObjectBase)val4).Pointer))
					{
						continue;
					}
					GroundSample groundSample = new GroundSample(position, transform);
					if (!TidyTerrainService.IsInsideCave(position, groundSample, out var _, out var _) && groundSample.TryGetY(out var groundY))
					{
						float num7 = groundY - position.y;
						if (!(Mathf.Abs(num7) <= Plugin.Tolerance) && !IsSupportedFromBelow(transform, position, groundY, out var _))
						{
							transform.position = new Vector3(position.x, groundY, position.z);
							UpdateNavigation(val4, text);
							ShiftPlacementGrid(val4, text, num7);
							num4++;
						}
					}
				}
				catch (Exception ex3)
				{
					ManualLogSource log3 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(45, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[TidyTerrain] error processing structure '");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex3);
					}
					log3.LogError(val3);
				}
			}
			return num4;
		}

		private static bool IsStackedOnAnotherStructure(Transform t, out string carrierLabel)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			carrierLabel = "<unknown>";
			try
			{
				Transform parent = t.parent;
				while ((Object)(object)parent != (Object)null)
				{
					Structure component = ((Component)parent).GetComponent<Structure>();
					if ((Object)(object)component != (Object)null)
					{
						carrierLabel = SafeName(component);
						return true;
					}
					parent = parent.parent;
				}
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(75, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] structure parent-chain check threw; skipping this structure: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				carrierLabel = "<parent-chain check threw>";
				return true;
			}
		}

		private static bool IsSupportedFromBelow(Transform t, Vector3 pos, float groundY, out string supportLabel)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			supportLabel = "<unknown>";
			try
			{
				if (!GroundHeight.TryFindSupportBetween(pos, t, pos.y, groundY, out var supportName))
				{
					return false;
				}
				supportLabel = (string.IsNullOrEmpty(supportName) ? "<unnamed>" : supportName);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(70, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] structure support probe threw; skipping this structure: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				supportLabel = "<support probe threw>";
				return true;
			}
		}

		private static void UpdateNavigation(Structure structure, string structureLabel)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			try
			{
				StructureNavigation componentInChildren = ((Component)structure).GetComponentInChildren<StructureNavigation>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					((NavMeshStructure)componentInChildren).UpdateLocalNavMesh();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(97, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] structure '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(structureLabel);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': navmesh update after the move threw (the structure was still moved): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private static void ShiftPlacementGrid(Structure structure, string structureLabel, float deltaY)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			try
			{
				PlacementGrid componentInChildren = ((Component)structure).GetComponentInChildren<PlacementGrid>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					componentInChildren.gridY += deltaY;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(94, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] structure '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(structureLabel);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': PlacementGrid.gridY fix-up threw (the structure was still moved): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private static bool IsSettlementCore(Structure structure, Structure core)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if ((Object)(object)core == (Object)null)
			{
				return false;
			}
			try
			{
				return ((Il2CppObjectBase)structure).Pointer == ((Il2CppObjectBase)core).Pointer;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(71, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] comparing a structure against the settlement core threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				return false;
			}
		}

		private static Structure GetSettlementCore(Settlement settlement)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			try
			{
				return settlement._settlementCore;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(93, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading Settlement._settlementCore threw; the core is not protected this pass: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				return null;
			}
		}

		internal static Settlement GetPlayerSettlement()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			try
			{
				if ((Object)(object)_settlementManager == (Object)null)
				{
					_settlementManager = Object.FindObjectOfType<SettlementManager>();
				}
				if ((Object)(object)_settlementManager == (Object)null)
				{
					return null;
				}
				return _settlementManager.GetPlayerSettlement();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(91, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] locating the player settlement threw; structures were not handled this pass: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				return null;
			}
		}

		private static string SafeName(Structure structure)
		{
			string text = "<unknown>";
			try
			{
				if ((Object)(object)((Component)structure).gameObject != (Object)null)
				{
					text = ((Object)((Component)structure).gameObject).name;
				}
			}
			catch (Exception)
			{
			}
			try
			{
				string structureName = structure.StructureName;
				if (!string.IsNullOrEmpty(structureName))
				{
					return text + " (" + structureName + ")";
				}
			}
			catch (Exception)
			{
			}
			return text;
		}
	}
	internal static class TidyTerrainService
	{
		private const float PositionMatchEpsilonMeters = 0.05f;

		private static VegetationSystemPro _vegetationSystemPro;

		private static CavesManager _cavesManager;

		private static ResourceManager _resourceManager;

		private static GlobalSpellManager _globalSpellManager;

		private static bool _caveQueryUnavailableLogged;

		private static bool _boulderQueryUnavailableLogged;

		private static bool _boulderFxUnavailableLogged;

		private static readonly HashSet<string> _boulderMeshWarnedTypes = new HashSet<string>();

		private static readonly HashSet<string> _worldGenMeshWarnedTypes = new HashSet<string>();

		private static readonly XzIndex<float> _movedWorldGenPositions = new XzIndex<float>(0.05f);

		private const string CaveMeshLayerName = "Interior";

		private static int _caveMeshLayer = -2;

		private const float RoofProbeStartOffsetMeters = 0.1f;

		private const float RoofProbeMarginMeters = 0.25f;

		private const float CellCenterMatchEpsilonMeters = 0.01f;

		public static int ResnapRegion(Footprint footprint, float y)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_00a3: 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_00ab: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			_movedWorldGenPositions.Clear();
			GroundHeight.BeginPass();
			if (footprint.IsEmpty)
			{
				return 0;
			}
			List<QueryCircle> circles = footprint.QueryCircles();
			Il2CppArrayBase<ItemObject> val;
			bool movedWorldGen = default(bool);
			try
			{
				val = Object.FindObjectsOfType<ItemObject>();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(53, 1, ref movedWorldGen);
				if (movedWorldGen)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] FindObjectsOfType<ItemObject>() threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
				return 0;
			}
			int num = 0;
			foreach (ItemObject item in val)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				try
				{
					Transform transform = ((Component)item).transform;
					if ((Object)(object)transform == (Object)null)
					{
						continue;
					}
					Vector3 position = transform.position;
					if (footprint.Contains(position.x, position.z))
					{
						GroundSample ground = new GroundSample(position, transform);
						if (!IsInsideCave(position, ground, out var _, out var _) && ResnapOne(item, ground, out movedWorldGen))
						{
							num++;
						}
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(35, 2, ref movedWorldGen);
					if (movedWorldGen)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] error processing '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SafeName(item));
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
					}
					log2.LogError(val2);
				}
			}
			if (Plugin.Corpses)
			{
				num += ResnapCorpsesInRegion(footprint);
			}
			int num2 = 0;
			int destroyedCount = 0;
			int worldGenResnapped = 0;
			if (Plugin.WorldGen)
			{
				num2 = ResnapSupplementaryInstancesInRegion(footprint, circles, y, out destroyedCount, out worldGenResnapped);
				num += num2 + worldGenResnapped;
			}
			if (_movedWorldGenPositions.Count > 0)
			{
				RefreshMovedWorldGenCells();
			}
			return num;
		}

		internal static bool IsInsideCave(Vector3 pos, GroundSample ground, out float ceilingY, out bool caveFoundAtXZ)
		{
			//IL_0028: 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_0048: 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)
			ceilingY = 0f;
			caveFoundAtXZ = false;
			bool flag = false;
			try
			{
				CavesManager cavesManager = GetCavesManager();
				float num = default(float);
				if ((Object)(object)cavesManager == (Object)null)
				{
					WarnCaveQueryUnavailableOnce("no CavesManager found in scene");
				}
				else if (cavesManager.GetCaveCeilingHeight(pos.x, pos.z, Plugin.CaveMargin, ref num))
				{
					caveFoundAtXZ = true;
					ceilingY = num;
					flag = pos.y < num;
				}
				if (!flag)
				{
					flag = IsUnderCaveRoof(pos, ground);
				}
			}
			catch (Exception value)
			{
				WarnCaveQueryUnavailableOnce($"GetCaveCeilingHeight threw: {value}");
				return false;
			}
			if (!Plugin.CaveExclusion)
			{
				return false;
			}
			return flag;
		}

		private static bool IsUnderCaveRoof(Vector3 pos, GroundSample ground)
		{
			//IL_0046: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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 (_caveMeshLayer == -2)
			{
				_caveMeshLayer = LayerMask.NameToLayer("Interior");
				if (_caveMeshLayer < 0)
				{
					Plugin.Log.LogWarning((object)"[TidyTerrain] no 'Interior' layer in this build; cave-roof detection is off and objects in a cave the ceiling query does not cover may be re-snapped to the surface.");
				}
			}
			if (_caveMeshLayer < 0)
			{
				return false;
			}
			if (!ground.TryGetY(out var groundY))
			{
				return false;
			}
			float num = groundY - pos.y;
			if (num <= 0f)
			{
				return false;
			}
			return Physics.Raycast(new Vector3(pos.x, pos.y + 0.1f, pos.z), Vector3.up, num + 0.25f, 1 << _caveMeshLayer, (QueryTriggerInteraction)2);
		}

		private static void WarnCaveQueryUnavailableOnce(string reason)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!_caveQueryUnavailableLogged)
			{
				_caveQueryUnavailableLogged = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(99, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] cave detection unavailable (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(reason);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); objects inside caves may be re-snapped to the surface.");
				}
				log.LogWarning(val);
			}
		}

		internal static CavesManager GetCavesManager()
		{
			if ((Object)(object)_cavesManager == (Object)null)
			{
				_cavesManager = Object.FindObjectOfType<CavesManager>();
			}
			return _cavesManager;
		}

		internal static ResourceManager GetResourceManager()
		{
			if ((Object)(object)_resourceManager == (Object)null)
			{
				_resourceManager = Object.FindObjectOfType<ResourceManager>();
			}
			return _resourceManager;
		}

		private static GlobalSpellManager GetGlobalSpellManager()
		{
			if ((Object)(object)_globalSpellManager == (Object)null)
			{
				_globalSpellManager = Object.FindObjectOfType<GlobalSpellManager>();
			}
			return _globalSpellManager;
		}

		private static VegetationSystemPro GetVegetationSystemPro()
		{
			if ((Object)(object)_vegetationSystemPro == (Object)null)
			{
				_vegetationSystemPro = Object.FindObjectOfType<VegetationSystemPro>();
			}
			return _vegetationSystemPro;
		}

		private static void RefreshMovedWorldGenCells()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			bool flag = default(bool);
			try
			{
				VegetationSystemPro vegetationSystemPro = GetVegetationSystemPro();
				if ((Object)(object)vegetationSystemPro == (Object)null)
				{
					Plugin.Log.LogWarning((object)"[TidyTerrain] no VegetationSystemPro found in scene; world-gen array writes were made but not marked dirty.");
					_movedWorldGenPositions.Clear();
					return;
				}
				List<VegetationCell> val;
				try
				{
					val = vegetationSystemPro.VegetationCellList;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(68, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] reading VegetationSystemPro.VegetationCellList threw: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
					}
					log.LogError(val2);
					val = null;
				}
				if (val == null || val.Count == 0)
				{
					Plugin.Log.LogWarning((object)"[TidyTerrain] VegetationCellList unavailable/empty; falling back to global SetVegetationCellsDirty().");
					try
					{
						vegetationSystemPro.SetVegetationCellsDirty();
					}
					catch (Exception ex2)
					{
						ManualLogSource log2 = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(56, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] fallback SetVegetationCellsDirty() threw: ");
							((BepInExLogInterpolatedS