Decompiled source of TidyTerrain v0.1.1

AskaTidyTerrain.dll

Decompiled a day 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 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.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 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("AskaTidyTerrain")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1")]
[assembly: AssemblyInformationalVersion("0.1.1+8edde25dd5244eb2a60169a7a69309ac44f0660f")]
[assembly: AssemblyProduct("Aska Tidy Terrain")]
[assembly: AssemblyTitle("AskaTidyTerrain")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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);
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class CharacterSpawnPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Spawned")]
		public static void Spawned(Character __instance)
		{
			//IL_0026: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			if (__instance.IsPlayer() && ((NetworkBehaviour)__instance).GetLocalAuthorityMask() == 1 && !((Object)(object)((Component)__instance).GetComponentInChildren<TidyTerrainTool>() != (Object)null))
			{
				GameObject val = new GameObject("TidyTerrain_Tool");
				val.transform.SetParent(((Component)__instance).gameObject.transform, false);
				val.AddComponent<TidyTerrainTool>();
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[TidyTerrain] tool attached to local player '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)((Component)__instance).gameObject).name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'.");
				}
				log.LogInfo(val2);
			}
		}
	}
	internal static class GroundHeight
	{
		private const float RaycastStartHeightMeters = 200f;

		private const float RaycastMaxDistanceMeters = 400f;

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

		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 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_0066: 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);
					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;
		}
	}
	[BepInPlugin("smithio.aska.tidyterrain", "Aska Tidy Terrain", "0.1.1")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "smithio.aska.tidyterrain";

		public const string PluginName = "Aska Tidy Terrain";

		public const string PluginVersion = "0.1.1";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ConfigEnabled;

		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;

		public override void Load()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00d4: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			ConfigEnabled = ((BasePlugin)this).Config.Bind<bool>("TidyTerrain", "Enabled", true, "Master on/off switch for Tidy Terrain.");
			ClassInjector.RegisterTypeInIl2Cpp<TidyTerrainTool>();
			Harmony val = new Harmony("smithio.aska.tidyterrain");
			Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)null);
			ArmingReport.TryPatch(val, 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", null, new HarmonyMethod(typeof(LevelingCompletionPatch), "OnRunOnAreaPostfix", (Type[])null));
			ArmingReport.LogTotal();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Aska Tidy Terrain");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("0.1.1");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded.");
			}
			log.LogInfo(val2);
		}
	}
	internal static class TidyTerrainService
	{
		private const float PositionMatchEpsilonMeters = 0.05f;

		private static VegetationSystemPro _vegetationSystemPro;

		private static readonly List<Vector3> _movedWorldGenPositions = new List<Vector3>();

		private const float CellCenterMatchEpsilonMeters = 0.01f;

		public static int ResnapRegion(Vector3 center, float radius)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00cf: 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) && 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);
			}
			if (_movedWorldGenPositions.Count > 0)
			{
				RefreshMovedWorldGenCells();
			}
			return num2;
		}

		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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_00af: 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)
			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) && 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			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;
			}
			float num = groundY - Plugin.SinkOffset;
			if (Mathf.Abs(position.y - num) <= Plugin.Tolerance)
			{
				return false;
			}
			if (name == "InventoryItemInstance")
			{
				if (!Plugin.Vegetation)
				{
					return false;
				}
				return ResnapInventoryItemInstance(worldInstance, position, num);
			}
			if (!Plugin.WorldGen)
			{
				return false;
			}
			return movedWorldGen = ResnapBiomeItemInstance(worldInstance, ((Component)obj).transform, position, num);
		}

		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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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
			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)((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;
				}
				float3 val3 = default(float3);
				((float3)(ref val3))..ctor(currentPos.x, groundY, currentPos.z);
				positions[num] = val3;
				Vector3 val4 = default(Vector3);
				((Vector3)(ref val4))..ctor(currentPos.x, groundY, currentPos.z);
				objTransform.position = val4;
				_movedWorldGenPositions.Add(val4);
				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;
			}
		}
	}
	public class TidyTerrainTool : MonoBehaviour
	{
		private void Update()
		{
			LevelingCompletionPatch.Tick();
			_ = Plugin.ConfigEnabled.Value;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "AskaTidyTerrain";

		public const string PLUGIN_NAME = "Aska Tidy Terrain";

		public const string PLUGIN_VERSION = "0.1.1";
	}
}