Decompiled source of TidyTerrain v1.3.2

TidyTerrain.dll

Decompiled a week 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;
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 Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Combat;
using SSSGame.Pathfinding;
using SandSailorStudio.Render;
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.3.1")]
[assembly: AssemblyInformationalVersion("1.3.1+61db2b6096859eec2edb32d6f5d8388e52c06cb7")]
[assembly: AssemblyProduct("Tidy Terrain")]
[assembly: AssemblyTitle("TidyTerrain")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.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_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Expected O, but got Unknown
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Expected O, but got Unknown
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: 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> list = null;
			Dictionary<string, ConfigEntry<BoulderAction>> dictionary2 = new Dictionary<string, ConfigEntry<BoulderAction>>();
			List<string> list2 = new List<string>(dictionary.Keys);
			list2.Sort(StringComparer.Ordinal);
			foreach (string item in list2)
			{
				try
				{
					dictionary2[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.");
				}
				catch (Exception)
				{
					dictionary2.Remove(item);
					if (list == null)
					{
						list = new List<string>();
					}
					list.Add(item);
				}
			}
			Dictionary<IntPtr, ConfigEntry<BoulderAction>> dictionary3 = new Dictionary<IntPtr, ConfigEntry<BoulderAction>>();
			int num4 = 0;
			foreach (string item2 in list2)
			{
				if (!dictionary2.TryGetValue(item2, out var value3))
				{
					continue;
				}
				foreach (BiomeItemDescriptor item3 in dictionary[item2])
				{
					if (item3 != null)
					{
						try
						{
							dictionary3[((Il2CppObjectBase)item3).Pointer] = value3;
						}
						catch (Exception)
						{
							num4++;
						}
					}
				}
			}
			_actionsByDescriptor.Clear();
			foreach (KeyValuePair<IntPtr, ConfigEntry<BoulderAction>> item4 in dictionary3)
			{
				_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 (list != null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(110, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] boulders: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.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(", ", list));
				}
				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>(dictionary2.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 GroundHeight
	{
		private const float RaycastStartHeightMeters = 200f;

		private const float RaycastMaxDistanceMeters = 400f;

		private const float SupportProbeMarginMeters = 0.25f;

		private const float SupportClearanceMeters = 0.1f;

		public static bool TrySampleGroundY(Vector3 atPos, Transform selfExclude, out float groundY)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			groundY = 0f;
			try
			{
				Il2CppStructArray<RaycastHit> val = Physics.RaycastAll(new Vector3(atPos.x, atPos.y + 200f, atPos.z), Vector3.down, 400f);
				int num = ((Il2CppArrayBase<RaycastHit>)(object)val)?.Length ?? 0;
				bool flag = false;
				float num2 = float.NegativeInfinity;
				bool flag2 = false;
				float num3 = float.NegativeInfinity;
				for (int i = 0; i < num; i++)
				{
					RaycastHit val2 = ((Il2CppArrayBase<RaycastHit>)(object)val)[i];
					Collider collider = ((RaycastHit)(ref val2)).collider;
					if (!IsSameOrRelatedTransform(((Object)(object)collider != (Object)null) ? ((Component)collider).transform : null, selfExclude))
					{
						if ((Object)(object)collider != (Object)null && (Object)(object)((Component)collider).gameObject.GetComponent<Terrain>() != (Object)null && (!flag || ((RaycastHit)(ref val2)).point.y > num2))
						{
							flag = true;
							num2 = ((RaycastHit)(ref val2)).point.y;
						}
						if (!flag2 || ((RaycastHit)(ref val2)).point.y > num3)
						{
							flag2 = true;
							num3 = ((RaycastHit)(ref val2)).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 val3 = new BepInExErrorLogInterpolatedStringHandler(43, 3, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[TidyTerrain] ground raycast at (");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(atPos.x, "F2");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(",");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(atPos.z, "F2");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(") threw: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log.LogError(val3);
			}
			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_0036: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			supportName = null;
			float num = Mathf.Max(currentY, groundY);
			float num2 = Mathf.Min(currentY, groundY);
			Vector3 val = new Vector3(atPos.x, num + 0.25f, atPos.z);
			float num3 = num - num2 + 0.25f;
			Il2CppStructArray<RaycastHit> val2 = Physics.RaycastAll(val, Vector3.down, num3);
			int num4 = ((Il2CppArrayBase<RaycastHit>)(object)val2)?.Length ?? 0;
			for (int i = 0; i < num4; i++)
			{
				RaycastHit val3 = ((Il2CppArrayBase<RaycastHit>)(object)val2)[i];
				Collider collider = ((RaycastHit)(ref val3)).collider;
				if (!((Object)(object)collider == (Object)null) && !IsSameOrRelatedTransform(((Component)collider).transform, selfExclude) && !((Object)(object)((Component)collider).gameObject.GetComponent<Terrain>() != (Object)null) && !(((RaycastHit)(ref val3)).point.y <= num2 + 0.1f))
				{
					supportName = ((Object)((Component)collider).gameObject).name;
					return true;
				}
			}
			return false;
		}

		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 LevelingCompletionPatch
	{
		private const float MaxRadiusMeters = 200f;

		private static bool _hasPending;

		private static float _minX = float.MaxValue;

		private static float _maxX = float.MinValue;

		private static float _minZ = float.MaxValue;

		private static float _maxZ = float.MinValue;

		private static float _lastY;

		private static float _lastLevelActivityTime;

		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);
			}
		}

		internal static void OnRunOnAreaPostfix(TerraformingToolOperation operation, float width, float height, float blendDistance, Vector3 position, float rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((int)operation == 2)
				{
					float num = width * 0.5f;
					float num2 = height * 0.5f;
					float num3 = position.x - num;
					float num4 = position.x + num;
					float num5 = position.z - num2;
					float num6 = position.z + num2;
					if (num3 < _minX)
					{
						_minX = num3;
					}
					if (num4 > _maxX)
					{
						_maxX = num4;
					}
					if (num5 < _minZ)
					{
						_minZ = num5;
					}
					if (num6 > _maxZ)
					{
						_maxZ = num6;
					}
					_lastY = position.y;
					_hasPending = true;
					_lastLevelActivityTime = Time.time;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] LevelingCompletionPatch RunOnArea postfix threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		internal static void Tick()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Plugin.ConfigEnabled.Value && Plugin.AutoResnap && _hasPending && !(Time.time - _lastLevelActivityTime < Plugin.AutoResnapDelay))
				{
					float num = (_minX + _maxX) * 0.5f;
					float num2 = (_minZ + _maxZ) * 0.5f;
					Vector3 center = new Vector3(num, _lastY, num2);
					float num3 = _maxX - _minX;
					float num4 = _maxZ - _minZ;
					float num5 = 0.5f * Mathf.Sqrt(num3 * num3 + num4 * num4) + 2f;
					if (num5 > 200f)
					{
						num5 = 200f;
					}
					TidyTerrainService.ResnapRegion(center, num5);
					StructureResnapService.ResnapRegion(center, num5);
					ResetAccumulator();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				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);
			}
		}

		private static void ResetAccumulator()
		{
			_hasPending = false;
			_minX = float.MaxValue;
			_maxX = float.MinValue;
			_minZ = float.MaxValue;
			_maxZ = float.MinValue;
			_lastY = 0f;
		}
	}
	internal static class MovedWorldGenRegistry
	{
		private struct Entry
		{
			public float X;

			public float Y;

			public float Z;

			public bool Logged;
		}

		private const float XZMatchEpsilonMeters = 0.05f;

		private static readonly List<Entry> _entries = new List<Entry>();

		internal static int Count => _entries.Count;

		internal static Vector3 PositionAt(int i)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Entry entry = _entries[i];
			return new Vector3(entry.X, entry.Y, entry.Z);
		}

		internal static void Record(Vector3 newPos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			int num = IndexOf(newPos.x, newPos.z);
			if (num >= 0)
			{
				Entry value = _entries[num];
				value.Y = newPos.y;
				value.Logged = false;
				_entries[num] = value;
			}
			else
			{
				_entries.Add(new Entry
				{
					X = newPos.x,
					Y = newPos.y,
					Z = newPos.z
				});
			}
		}

		internal static bool TryGetRecordedY(Vector3 pos, out float recordedY)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			int num = IndexOf(pos.x, pos.z);
			if (num < 0)
			{
				recordedY = 0f;
				return false;
			}
			recordedY = _entries[num].Y;
			return true;
		}

		internal static bool TryMarkLogged(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			int num = IndexOf(pos.x, pos.z);
			if (num < 0 || _entries[num].Logged)
			{
				return false;
			}
			Entry value = _entries[num];
			value.Logged = true;
			_entries[num] = value;
			return true;
		}

		internal static void Clear()
		{
			_entries.Clear();
		}

		private static int IndexOf(float x, float z)
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				Entry entry = _entries[i];
				if (Mathf.Abs(entry.X - x) <= 0.05f && Mathf.Abs(entry.Z - z) <= 0.05f)
				{
					return i;
				}
			}
			return -1;
		}
	}
	[BepInPlugin("mugsy33.tidyterrain", "Tidy Terrain", "1.3.2")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.tidyterrain";

		public const string PluginName = "Tidy Terrain";

		public const string PluginVersion = "1.3.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ConfigEnabled;

		internal static ConfigEntry<bool> ConfigResnapStructures;

		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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_010b: 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_012a: Expected O, but got Unknown
			//IL_012a: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ConfigMigration.Run(((BasePlugin)this).Config, 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.");
			PublicConfig = ((BasePlugin)this).Config;
			BoulderService.BindGlobalConfig();
			ClassInjector.RegisterTypeInIl2Cpp<TidyTerrainTool>();
			Harmony harmony = new Harmony("mugsy33.tidyterrain");
			Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)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), new HarmonyMethod(typeof(LevelingCompletionPatch), "OnRunOnAreaPostfix", (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.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.3.2");
				((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 float _nextSweepTime;

		private static bool _warnedThrow;

		private static List<WorldItemInstance> _scratch;

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

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

		internal static void Tick(Vector3 playerPos)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.WorldGen || MovedWorldGenRegistry.Count == 0)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup < _nextSweepTime)
			{
				return;
			}
			_nextSweepTime = realtimeSinceStartup + 2f;
			try
			{
				Sweep(playerPos);
			}
			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)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			ResourceManager resourceManager = TidyTerrainService.GetResourceManager();
			if ((Object)(object)resourceManager == (Object)null)
			{
				return;
			}
			if (_scratch == null)
			{
				_scratch = new List<WorldItemInstance>();
			}
			float num = 14400f;
			int count = MovedWorldGenRegistry.Count;
			for (int i = 0; i < count; i++)
			{
				Vector3 val = MovedWorldGenRegistry.PositionAt(i);
				float num2 = val.x - playerPos.x;
				float num3 = val.z - playerPos.z;
				if (num2 * num2 + num3 * num3 > 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(i, val, val2);
						}
						continue;
					}
					Transform transform = gameObject.transform;
					if (!((Object)(object)transform == (Object)null))
					{
						if (IsOnEntry(val2, val))
						{
							_refreshPending.Remove(i);
						}
						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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Expected O, but got Unknown
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: 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> list = null;
			List<string> list2 = new List<string>(_deletable.Keys);
			list2.Sort(StringComparer.Ordinal);
			foreach (string item2 in list2)
			{
				try
				{
					_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.");
				}
				catch (Exception)
				{
					_keepEntries.Remove(item2);
					if (list == null)
					{
						list = new List<string>();
					}
					list.Add(item2);
				}
			}
			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 (list != null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(111, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] retention: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.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(", ", list));
				}
				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(Vector3 center, float radius)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.ConfigEnabled.Value || !Plugin.ConfigResnapStructures.Value)
			{
				return 0;
			}
			Settlement playerSettlement = GetPlayerSettlement();
			if ((Object)(object)playerSettlement == (Object)null)
			{
				return 0;
			}
			float num = radius + Plugin.StructureRadiusMargin;
			List<Structure> val = new List<Structure>();
			bool flag = default(bool);
			try
			{
				Vector3 val2 = center;
				float num2 = num;
				playerSettlement.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;
			}
			Structure settlementCore = GetSettlementCore(playerSettlement);
			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, settlementCore))
					{
						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) && !TidyTerrainService.IsInsideCave(position, out var _, out var _) && GroundHeight.TrySampleGroundY(position, transform, 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;
			}
		}

		private 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 List<Vector3> _movedWorldGenPositions = new List<Vector3>();

		private const float CellCenterMatchEpsilonMeters = 0.01f;

		public static int ResnapRegion(Vector3 center, float radius)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			_movedWorldGenPositions.Clear();
			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;
			}
			float num = radius * radius;
			int num2 = 0;
			foreach (ItemObject item in val)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				string text = "<unknown>";
				try
				{
					Transform transform = ((Component)item).transform;
					if (!((Object)(object)transform == (Object)null))
					{
						text = (((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : text);
						Vector3 position = transform.position;
						float num3 = position.x - center.x;
						float num4 = position.z - center.z;
						if (!(num3 * num3 + num4 * num4 > num) && !IsInsideCave(position, out var _, out var _) && ResnapOne(item, out movedWorldGen))
						{
							num2++;
						}
					}
				}
				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>(text);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
					}
					log2.LogError(val2);
				}
			}
			if (Plugin.Corpses)
			{
				num2 += ResnapCorpsesInRegion(center, num);
			}
			int num5 = 0;
			int destroyedCount = 0;
			int worldGenResnapped = 0;
			if (Plugin.WorldGen)
			{
				num5 = ResnapSupplementaryInstancesInRegion(center, radius, out destroyedCount, out worldGenResnapped);
				num2 += num5 + worldGenResnapped;
			}
			if (_movedWorldGenPositions.Count > 0)
			{
				RefreshMovedWorldGenCells();
			}
			return num2;
		}

		internal static bool IsInsideCave(Vector3 pos, 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)
			ceilingY = 0f;
			caveFoundAtXZ = false;
			bool result = 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;
					result = pos.y < num;
				}
			}
			catch (Exception value)
			{
				WarnCaveQueryUnavailableOnce($"GetCaveCeilingHeight threw: {value}");
				return false;
			}
			if (!Plugin.CaveExclusion)
			{
				return false;
			}
			return result;
		}

		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);
			}
		}

		private 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Expected O, but got Unknown
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
						}
						log2.LogError(val2);
					}
					_movedWorldGenPositions.Clear();
					return;
				}
				List<VegetationCell> list = new List<VegetationCell>();
				bool flag2 = false;
				int num = 0;
				foreach (Vector3 movedWorldGenPosition in _movedWorldGenPositions)
				{
					VegetationCell val3 = null;
					try
					{
						for (int i = 0; i < val.Count; i++)
						{
							VegetationCell val4 = val[i];
							if (val4 != null)
							{
								Bounds vegetationCellBounds = val4.VegetationCellBounds;
								if (movedWorldGenPosition.x >= ((Bounds)(ref vegetationCellBounds)).min.x && movedWorldGenPosition.x <= ((Bounds)(ref vegetationCellBounds)).max.x && movedWorldGenPosition.z >= ((Bounds)(ref vegetationCellBounds)).min.z && movedWorldGenPosition.z <= ((Bounds)(ref vegetationCellBounds)).max.z)
								{
									val3 = val4;
									break;
								}
							}
						}
					}
					catch (Exception ex3)
					{
						ManualLogSource log3 = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(63, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] scanning VegetationCellList for position ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Vector3>(movedWorldGenPosition);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" threw: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex3);
						}
						log3.LogError(val2);
						val3 = null;
					}
					if (val3 == null)
					{
						flag2 = true;
						num++;
						continue;
					}
					bool flag3 = false;
					Bounds vegetationCellBounds2 = val3.VegetationCellBounds;
					Vector3 center = ((Bounds)(ref vegetationCellBounds2)).center;
					for (int j = 0; j < list.Count; j++)
					{
						vegetationCellBounds2 = list[j].VegetationCellBounds;
						if (Vector3.Distance(((Bounds)(ref vegetationCellBounds2)).center, center) <= 0.01f)
						{
							flag3 = true;
							break;
						}
					}
					if (!flag3)
					{
						list.Add(val3);
					}
				}
				int num2 = 0;
				foreach (VegetationCell item in list)
				{
					try
					{
						vegetationSystemPro.ClearCache(item);
						num2++;
					}
					catch (Exception ex4)
					{
						ManualLogSource log4 = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(48, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] ClearCache(VegetationCell) threw: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex4);
						}
						log4.LogError(val2);
					}
				}
				if (!flag2)
				{
					return;
				}
				Plugin.Log.LogWarning((object)"[TidyTerrain] one or more moved world-gen positions did not match a loaded VegetationCell; falling back to global SetVegetationCellsDirty() as a safety net.");
				try
				{
					vegetationSystemPro.SetVegetationCellsDirty();
				}
				catch (Exception ex5)
				{
					ManualLogSource log5 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(58, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] safety-net SetVegetationCellsDirty() threw: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex5);
					}
					log5.LogError(val2);
				}
			}
			catch (Exception ex6)
			{
				ManualLogSource log6 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(49, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] RefreshMovedWorldGenCells() threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex6);
				}
				log6.LogError(val2);
			}
			finally
			{
				_movedWorldGenPositions.Clear();
			}
		}

		private static int ResnapCorpsesInRegion(Vector3 center, float radiusSq)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//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_00bb: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			Il2CppArrayBase<CreatureItemObject> val;
			bool flag = default(bool);
			try
			{
				val = Object.FindObjectsOfType<CreatureItemObject>();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(61, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] FindObjectsOfType<CreatureItemObject>() threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
				return 0;
			}
			int num = 0;
			foreach (CreatureItemObject item in val)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				string text = "<unknown>";
				try
				{
					Transform transform = ((Component)item).transform;
					if (!((Object)(object)transform == (Object)null))
					{
						text = (((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : text);
						Vector3 position = transform.position;
						float num2 = position.x - center.x;
						float num3 = position.z - center.z;
						if (!(num2 * num2 + num3 * num3 > radiusSq) && !IsInsideCave(position, out var _, out var _) && ResnapCorpse(item))
						{
							num++;
						}
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(42, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] error processing corpse '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex2);
					}
					log2.LogError(val2);
				}
			}
			return num;
		}

		private static bool ResnapCorpse(CreatureItemObject creatureObj)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_009b: 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)
			bool fullyDead;
			try
			{
				fullyDead = creatureObj._fullyDead;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading CreatureItemObject._fullyDead threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				return false;
			}
			if (!fullyDead)
			{
				return false;
			}
			Transform transform;
			bool flag2 = default(bool);
			try
			{
				transform = ((Component)creatureObj).transform;
				if ((Object)(object)transform == (Object)null)
				{
					return false;
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading corpse transform threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
				}
				log2.LogError(val);
				return false;
			}
			if (GroundHeight.TrySampleGroundY(transform.position, transform, out var groundY) && Mathf.Abs(transform.position.y - groundY) <= Plugin.Tolerance)
			{
				return false;
			}
			try
			{
				return creatureObj._SnapToTerrain(1f);
			}
			catch (Exception ex3)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] CreatureItemObject._SnapToTerrain threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex3);
				}
				log3.LogError(val);
				return false;
			}
		}

		private static bool ResnapOne(ItemObject obj, out bool movedWorldGen)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			movedWorldGen = false;
			WorldItemInstance worldInstance;
			try
			{
				worldInstance = ((WorldItemObject)obj).WorldInstance;
			}
			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] reading WorldInstance threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
				return false;
			}
			if (worldInstance == null)
			{
				return false;
			}
			string name;
			bool flag2 = default(bool);
			try
			{
				name = ((MemberInfo)((Il2CppObjectBase)worldInstance).Cast<Object>().GetIl2CppType()).Name;
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(53, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] reading WorldInstance real type threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
				}
				log2.LogError(val);
				return false;
			}
			if (name != "InventoryItemInstance" && name != "BiomeItemInstance")
			{
				return false;
			}
			Vector3 position;
			try
			{
				position = worldInstance.GetPosition();
			}
			catch (Exception ex3)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[TidyTerrain] GetPosition() threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex3);
				}
				log3.LogError(val);
				return false;
			}
			if (!GroundHeight.TrySampleGroundY(((Component)obj).transform.position, ((Component)obj).transform, out var groundY))
			{
				return false;
			}
			if (name == "InventoryItemInstance")
			{
				if (!Plugin.Vegetation)
				{
					return false;
				}
				float num = groundY - Plugin.SinkOffset;
				if (Mathf.Abs(position.y - num) <= Plugin.Tolerance)
				{
					return false;
				}
				return ResnapInventoryItemInstance(worldInstance, position, num);
			}
			if (!Plugin.WorldGen)
			{
				return false;
			}
			float num2 = groundY - WorldGenSinkOffset(worldInstance);
			if (Mathf.Abs(position.y - num2) <= Plugin.Tolerance)
			{
				return false;
			}
			return movedWorldGen = ResnapBiomeItemInstance(worldInstance, ((Component)obj).transform, position, num2);
		}

		private static string SafeName(ItemObject obj)
		{
			try
			{
				return ((Object)(object)((Component)obj).gameObject != (Object)null) ? ((Object)((Component)obj).gameObject).name : "<unknown>";
			}
			catch
			{
				return "<unknown>";
			}
		}

		private static string SafeName(CreatureItemObject obj)
		{
			try
			{
				return ((Object)(object)((Component)obj).gameObject != (Object)null) ? ((Object)((Component)obj).gameObject).name : "<unknown>";
			}
			catch
			{
				return "<unknown>";
			}
		}

		private static bool ResnapInventoryItemInstance(WorldItemInstance wi, Vector3 currentPos, float groundY)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			try
			{
				InventoryItemInstance obj = ((Il2CppObjectBase)wi).Cast<InventoryItemInstance>();
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(currentPos.x, groundY, currentPos.z);
				bool flag = true;
				bool flag2 = false;
				obj.SetPosition(ref val, ref flag, ref flag2);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag3 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(51, 1, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] InventoryItemInstance re-snap threw: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogError(val2);
				return false;
			}
		}

		private static bool ResnapBiomeItemInstance(WorldItemInstance wi, Transform objTransform, Vector3 currentPos, float groundY)
		{
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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)
			bool flag = default(bool);
			try
			{
				BiomeItemInstancesBuffer buffer = ((Il2CppObjectBase)wi).Cast<BiomeItemInstance>().GetBuffer();
				if (buffer == null)
				{
					Plugin.Log.LogError((object)"[TidyTerrain] BiomeItemInstance.GetBuffer() returned null; skipping.");
					return false;
				}
				InstancesDataArrays instances = buffer.instances;
				if (instances == null)
				{
					Plugin.Log.LogError((object)"[TidyTerrain] buffer.instances is null; skipping.");
					return false;
				}
				NativeList<float3> positions = instances.positions;
				if (positions == null)
				{
					Plugin.Log.LogError((object)"[TidyTerrain] arrays.positions is null; skipping.");
					return false;
				}
				int num = -1;
				int length = positions.Length;
				for (int i = 0; i < length; i++)
				{
					float3 val = positions[i];
					float num2 = val.x - currentPos.x;
					float num3 = val.z - currentPos.z;
					if (Mathf.Abs(num2) <= 0.05f && Mathf.Abs(num3) <= 0.05f)
					{
						num = i;
						break;
					}
				}
				if (num < 0)
				{
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(116, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] no VSP array slot position-matched '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)objTransform != (Object)null && (Object)(object)((Component)objTransform).gameObject != (Object)null) ? ((Object)((Component)objTransform).gameObject).name : "<unknown>");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' ");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(positions.Length=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(length);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("); skipping world-gen re-snap for this object.");
					}
					log.LogWarning(val2);
					return false;
				}
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(currentPos.x, groundY, currentPos.z);
				if ((Object)(object)objTransform != (Object)null)
				{
					objTransform.position = val3;
				}
				float3 val4 = default(float3);
				((float3)(ref val4))..ctor(currentPos.x, groundY, currentPos.z);
				positions[num] = val4;
				_movedWorldGenPositions.Add(val3);
				MovedWorldGenRegistry.Record(val3);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[TidyTerrain] BiomeItemInstance re-snap threw: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val5);
				return false;
			}
		}

		private static int ResnapSupplementaryInstancesInRegion(Vector3 center, float radius, out int destroyedCount, out int worldGenResnapped)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid 

AskaShared.dll

Decompiled a week ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Mugsy33")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Ship-in-Release infrastructure shared by ASKA BepInEx mods (config GUID migration).")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AskaShared")]
[assembly: AssemblyTitle("AskaShared")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 AskaShared
{
	public static class ConfigMigration
	{
		private const string NewPrefix = "mugsy33.";

		private const string OldPrefix = "smithio.aska.";

		public static void Run(ConfigFile config, ManualLogSource log)
		{
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			bool flag = false;
			string text = null;
			bool flag2 = default(bool);
			try
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(config.ConfigFilePath);
				if (!fileNameWithoutExtension.StartsWith("mugsy33.", StringComparison.Ordinal))
				{
					return;
				}
				string text2 = "smithio.aska." + fileNameWithoutExtension.Substring("mugsy33.".Length);
				text = Path.Combine(Paths.ConfigPath, fileNameWithoutExtension + ".cfg");
				string text3 = Path.Combine(Paths.ConfigPath, text2 + ".cfg");
				string text4 = Path.Combine(Paths.ConfigPath, text2 + ".cfg.migrated");
				if (File.Exists(text))
				{
					if (File.Exists(text4))
					{
						File.Delete(text4);
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Deleted migrated legacy configuration: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
						}
						log.LogInfo(val);
					}
					else if (File.Exists(text3))
					{
						File.Move(text3, text4, overwrite: true);
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration renamed to ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
						}
						log.LogInfo(val);
					}
				}
				else if (File.Exists(text3))
				{
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration detected: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
					}
					log.LogInfo(val);
					string text5 = text + ".tmp";
					File.Copy(text3, text5, overwrite: true);
					File.Move(text5, text, overwrite: true);
					flag = true;
					val = new BepInExInfoLogInterpolatedStringHandler(33, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Migrated legacy configuration to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					}
					log.LogInfo(val);
					config.Reload();
					File.Move(text3, text4, overwrite: true);
					val = new BepInExInfoLogInterpolatedStringHandler(32, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Legacy configuration renamed to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text4);
					}
					log.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(62, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Configuration migration failed; using existing configuration. ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log.LogWarning(val2);
				if (flag && text != null)
				{
					try
					{
						File.Delete(text);
						return;
					}
					catch
					{
						return;
					}
				}
			}
		}
	}
}