Decompiled source of GradualTerrain v1.0.2

plugins/GradualTerrain.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GradualTerrain.modules;
using HarmonyLib;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("GradualTerrain")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GradualTerrain")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
namespace GradualTerrain
{
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void setDebugLogging(bool state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (state)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				GradualTerrain.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				GradualTerrain.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				GradualTerrain.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				GradualTerrain.Log.LogError((object)message);
			}
		}
	}
	internal class ValConfig
	{
		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<float> MaxTerrainHeightAdjustment;

		public static ConfigEntry<float> MinTerrainHeightAdjustment;

		public static ConfigEntry<int> AdjustmentRange;

		public static ConfigEntry<float> MaxAdjustmentMineSlope;

		public static ConfigEntry<float> MaxAdjustmentHillSlope;

		public static ConfigEntry<float> RingIncrements;

		public static ConfigEntry<float> OffsetFromCenter;

		public static ConfigEntry<float> CircularGranularity;

		public static ConfigEntry<float> OperationRadius;

		public static ConfigEntry<int> ChangesPerInterval;

		public static ConfigEntry<float> TerrainSmoothingModifier;

		public static ConfigEntry<float> TerrainSmoothingPower;

		public static ConfigEntry<bool> PaintTerrainDuringChange;

		public static ConfigEntry<bool> SmoothTerrainOnChange;

		public static ConfigEntry<bool> AdjustmentSquare;

		public static ConfigEntry<float> AdjustmentPower;

		public static ConfigEntry<bool> EnableBiomeSpecificHeightAdjustments;

		public static Dictionary<Biome, ConfigEntry<float>> BiomeBasedMinTerrainAdjust = new Dictionary<Biome, ConfigEntry<float>>();

		public static Dictionary<Biome, ConfigEntry<float>> BiomeBasedMaxTerrainAdjust = new Dictionary<Biome, ConfigEntry<float>>();

		public ValConfig(ConfigFile cf)
		{
			cfg = cf;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(cf);
			Logger.setDebugLogging(EnableDebugMode.Value);
			SetupMainFileWatcher();
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_001a: 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_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected I4, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.enableDebugLogging;
			MaxTerrainHeightAdjustment = BindServerConfig("Terrain Height Adjustment", "MaxTerrainHeightAdjustment", 12f, "The height terrain can be raised compared to its original position (vanilla default 8).", advanced: false, 0f, 2000f);
			MinTerrainHeightAdjustment = BindServerConfig("Terrain Height Adjustment", "MinTerrainHeightAdjustment", -12f, "The depth terrain can be lowered to compared to its original position (vanilla default 8).", advanced: false, -2000f, 0f);
			EnableBiomeSpecificHeightAdjustments = BindServerConfig("Gradual Digging", "EnableBiomeSpecificHeightAdjustments", value: true, "Uses biome-specific configurations for height map adjustments. This allows for things such as, leveling mountains but not turning plains into an ocean.", null, advanced: true);
			EnableBiomeSpecificHeightAdjustments.SettingChanged += delegate
			{
				BiomeConfiguration.ClearCache();
			};
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				int num = (int)value;
				if (num != 0 && (num & (num - 1)) == 0)
				{
					Tuple<float, float> biomeDefaultHeightAdjustments = GetBiomeDefaultHeightAdjustments(value);
					ConfigEntry<float> val2 = BindServerConfig($"Terrain Height Adjustment Per Biome - {(object)value}", "MinTerrainHeightAdjustment", biomeDefaultHeightAdjustments.Item2, $"Minimum terrain height adjustment for {(object)value}.", advanced: true, -2000f, 0f);
					ConfigEntry<float> val3 = BindServerConfig($"Terrain Height Adjustment Per Biome - {(object)value}", "MaxTerrainHeightAdjustment", biomeDefaultHeightAdjustments.Item1, $"Maximum terrain height adjustment for {(object)value}.", advanced: true, 0f, 2000f);
					val2.SettingChanged += delegate
					{
						BiomeConfiguration.ClearCache();
					};
					val3.SettingChanged += delegate
					{
						BiomeConfiguration.ClearCache();
					};
					BiomeBasedMinTerrainAdjust.Add(value, val2);
					BiomeBasedMaxTerrainAdjust.Add(value, val3);
				}
			}
			AdjustmentRange = BindServerConfig("Gradual Digging", "AdjustmentRange", 60, "The range that gradual terrain modifications will be applied", advanced: false, 0, 100);
			MaxAdjustmentMineSlope = BindServerConfig("Gradual Digging", "MaxAdjustmentMineSlope", 0.5f, "The force that smoothing is applied outward from the target operation.");
			MaxAdjustmentHillSlope = BindServerConfig("Gradual Digging", "MaxAdjustmentHillSlope", 0.75f, "The force that smoothing is applied outward from the target operation.");
		}

		private static Tuple<float, float> GetBiomeDefaultHeightAdjustments(Biome targetBiome)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			Tuple<float, float> tuple = new Tuple<float, float>(0f, 0f);
			if ((int)targetBiome <= 16)
			{
				if ((int)targetBiome <= 4)
				{
					if ((int)targetBiome == 1)
					{
						goto IL_0066;
					}
					if ((int)targetBiome == 4)
					{
						goto IL_0054;
					}
				}
				else if ((int)targetBiome == 8 || (int)targetBiome == 16)
				{
					return new Tuple<float, float>(10f, -10f);
				}
			}
			else if ((int)targetBiome <= 64)
			{
				if ((int)targetBiome == 32)
				{
					goto IL_0066;
				}
				if ((int)targetBiome == 64)
				{
					goto IL_0054;
				}
			}
			else
			{
				if ((int)targetBiome == 256)
				{
					return new Tuple<float, float>(300f, -300f);
				}
				if ((int)targetBiome == 512)
				{
					return new Tuple<float, float>(10f, -20f);
				}
			}
			return new Tuple<float, float>(8f, -8f);
			IL_0054:
			return new Tuple<float, float>(6f, -50f);
			IL_0066:
			return new Tuple<float, float>(8f, -8f);
		}

		internal static void SetupMainFileWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
			fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
			fileSystemWatcher.Path = Path.GetDirectoryName(cfg.ConfigFilePath);
			fileSystemWatcher.Filter = "MidnightsFX.GradualTerrain.cfg";
			fileSystemWatcher.Changed += OnConfigFileChanged;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			if (ZNet.instance.IsServer())
			{
				Logger.LogInfo("Configuration file has been changed, reloading settings.");
				cfg.Reload();
			}
		}

		public static ConfigEntry<float[]> BindServerConfig(string catagory, string key, float[] value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float[]>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<int> BindServerConfig(string catagory, string key, int value, string description, bool advanced = false, int valmin = 0, int valmax = 150)
		{
			//IL_001a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<int>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
	[BepInPlugin("MidnightsFX.GradualTerrain", "GradualTerrain", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class GradualTerrain : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.GradualTerrain";

		public const string PluginName = "GradualTerrain";

		public const string PluginVersion = "1.0.2";

		internal static ManualLogSource Log;

		internal ValConfig cfg;

		public void Awake()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			Log.LogInfo((object)"Breaking things down smoothly.");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			new Harmony("MidnightsFX.GradualTerrain").PatchAll(executingAssembly);
		}
	}
}
namespace GradualTerrain.modules
{
	internal static class BiomeConfiguration
	{
		internal class HeightLimits
		{
			public float Min;

			public float Max;
		}

		private static ConditionalWeakTable<Heightmap, HeightLimits> cache = new ConditionalWeakTable<Heightmap, HeightLimits>();

		internal static float CurrentMin = -8f;

		internal static float CurrentMax = 8f;

		private static HeightLimits envelopeLimits;

		internal static HeightLimits GetHeightLimits(Heightmap hmap)
		{
			if ((Object)(object)hmap == (Object)null || !ValConfig.EnableBiomeSpecificHeightAdjustments.Value)
			{
				return new HeightLimits
				{
					Min = ValConfig.MinTerrainHeightAdjustment.Value,
					Max = ValConfig.MaxTerrainHeightAdjustment.Value
				};
			}
			if (cache.TryGetValue(hmap, out var value))
			{
				return value;
			}
			HeightLimits heightLimits = ComputeLimits(hmap);
			cache.Add(hmap, heightLimits);
			return heightLimits;
		}

		internal static HeightLimits GetHeightLimitsAt(Vector3 worldPos, Heightmap fallback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Heightmap val = Heightmap.FindHeightmap(worldPos);
			return GetHeightLimits(((Object)(object)val != (Object)null) ? val : fallback);
		}

		internal static void SetCurrentLimits(Vector3 worldPos, Heightmap fallback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HeightLimits heightLimitsAt = GetHeightLimitsAt(worldPos, fallback);
			CurrentMin = heightLimitsAt.Min;
			CurrentMax = heightLimitsAt.Max;
		}

		internal static void SetEnvelopeLimits()
		{
			HeightLimits heightLimits = GetEnvelopeLimits();
			CurrentMin = heightLimits.Min;
			CurrentMax = heightLimits.Max;
		}

		private static HeightLimits GetEnvelopeLimits()
		{
			if (!ValConfig.EnableBiomeSpecificHeightAdjustments.Value)
			{
				return new HeightLimits
				{
					Min = ValConfig.MinTerrainHeightAdjustment.Value,
					Max = ValConfig.MaxTerrainHeightAdjustment.Value
				};
			}
			if (envelopeLimits != null)
			{
				return envelopeLimits;
			}
			float num = ValConfig.MinTerrainHeightAdjustment.Value;
			float num2 = ValConfig.MaxTerrainHeightAdjustment.Value;
			foreach (ConfigEntry<float> value in ValConfig.BiomeBasedMinTerrainAdjust.Values)
			{
				num = Mathf.Min(num, value.Value);
			}
			foreach (ConfigEntry<float> value2 in ValConfig.BiomeBasedMaxTerrainAdjust.Values)
			{
				num2 = Mathf.Max(num2, value2.Value);
			}
			envelopeLimits = new HeightLimits
			{
				Min = num,
				Max = num2
			};
			return envelopeLimits;
		}

		internal static void ClearCache()
		{
			cache = new ConditionalWeakTable<Heightmap, HeightLimits>();
			envelopeLimits = null;
		}

		private static HeightLimits ComputeLimits(Heightmap hmap)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			BiomeSector[] cornerBiomes = hmap.m_cornerBiomes;
			float num = 0f;
			float num2 = 0f;
			int num3 = 0;
			for (int i = 0; i < cornerBiomes.Length; i++)
			{
				if (cornerBiomes[i] == null)
				{
					continue;
				}
				Biome biome = cornerBiomes[i].Biome;
				bool flag = false;
				for (int j = 0; j < i; j++)
				{
					if (cornerBiomes[j] != null && cornerBiomes[j].Biome == biome)
					{
						flag = true;
						break;
					}
				}
				if (!flag && ValConfig.BiomeBasedMinTerrainAdjust.TryGetValue(biome, out var value) && ValConfig.BiomeBasedMaxTerrainAdjust.TryGetValue(biome, out var value2))
				{
					num += value.Value;
					num2 += value2.Value;
					num3++;
				}
			}
			if (num3 == 0)
			{
				return new HeightLimits
				{
					Min = ValConfig.MinTerrainHeightAdjustment.Value,
					Max = ValConfig.MaxTerrainHeightAdjustment.Value
				};
			}
			return new HeightLimits
			{
				Min = num / (float)num3,
				Max = num2 / (float)num3
			};
		}
	}
	internal static class GradualDigging
	{
		[HarmonyPatch(typeof(TerrainComp))]
		internal static class OwnerSmoothing
		{
			internal sealed class SmoothRequest
			{
				public Vector3 Center;

				public float CenterHeight;

				public int Range;

				public float MinAdjust;

				public float MaxAdjust;

				public float MineSlope;

				public float HillSlope;

				public float AffectedRadius;
			}

			private struct SeamVertex
			{
				public int Index;

				public long Key;

				public float Distance;
			}

			private const string SmoothRpc = "GradualTerrain_RPC_SmoothTerrain";

			private const int SmoothRpcVersion = 1;

			[HarmonyPostfix]
			[HarmonyPatch("Initialize")]
			private static void RegisterSmoothRpc(TerrainComp __instance)
			{
				ZNetView nview = __instance.m_nview;
				if (!((Object)(object)nview == (Object)null))
				{
					nview.Unregister("GradualTerrain_RPC_SmoothTerrain");
					nview.Register<ZPackage>("GradualTerrain_RPC_SmoothTerrain", (Action<long, ZPackage>)delegate(long sender, ZPackage pkg)
					{
						RPC_SmoothTerrain(__instance, sender, pkg);
					});
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch("DoOperation")]
			private static void QueueSmoothing(TerrainComp __instance, Vector3 pos, Settings modifier)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if (modifier != null && modifier.m_raise && ValConfig.AdjustmentRange.Value > 0 && __instance.m_initialized && __instance.IsOwner() && ContainsCenter(__instance, pos))
				{
					((MonoBehaviour)__instance).StartCoroutine(SmoothAfterOperation(__instance, pos, modifier.GetRadius()));
				}
			}

			private static IEnumerator SmoothAfterOperation(TerrainComp centerComp, Vector3 center, float opRadius)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				yield return null;
				if (!((Object)(object)centerComp == (Object)null) && centerComp.m_initialized && centerComp.IsOwner())
				{
					CoordinateSmoothing(centerComp, center, opRadius);
				}
			}

			private static void CoordinateSmoothing(TerrainComp centerComp, Vector3 center, float opRadius)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: 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_014a: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01eb: 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_0224: Unknown result type (might be due to invalid IL or missing references)
				//IL_0345: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
				int value = ValConfig.AdjustmentRange.Value;
				if (value <= 0)
				{
					return;
				}
				Heightmap hmap = centerComp.m_hmap;
				if ((Object)(object)hmap == (Object)null || hmap.m_buildData == null)
				{
					return;
				}
				int num = default(int);
				int num2 = default(int);
				hmap.WorldToVertex(center, ref num, ref num2);
				int num3 = hmap.m_width + 1;
				int num4 = num2 * num3 + num;
				if (num4 < 0 || num4 >= hmap.m_buildData.m_baseHeights.Count)
				{
					Logger.LogWarning($"Got invalid index for centerpoint: pos: {center} idx: {num4} x: {num} y: {num2} rowlen: {num3}");
					return;
				}
				BiomeConfiguration.HeightLimits heightLimitsAt = BiomeConfiguration.GetHeightLimitsAt(center, hmap);
				SmoothRequest smoothRequest = new SmoothRequest
				{
					Center = center,
					CenterHeight = hmap.m_buildData.m_baseHeights[num4] + ((Component)hmap).transform.position.y + centerComp.m_levelDelta[num4],
					Range = value,
					MinAdjust = heightLimitsAt.Min,
					MaxAdjust = heightLimitsAt.Max,
					MineSlope = ValConfig.MaxAdjustmentMineSlope.Value,
					HillSlope = ValConfig.MaxAdjustmentHillSlope.Value,
					AffectedRadius = Mathf.Max(opRadius, (float)value)
				};
				Logger.LogDebug($"Starting gradual terrain change from {center} at height {smoothRequest.CenterHeight} with limits ->  max:{heightLimitsAt.Max} min:{heightLimitsAt.Min}, coordinated on tile {((Component)hmap).transform.position}");
				List<Heightmap> list = new List<Heightmap>();
				Heightmap.FindHeightmap(center, (float)value, list);
				list.RemoveAll((Heightmap h) => h.IsDistantLod || h.m_buildData == null);
				float freshRadius = opRadius * 1.5f + 2f * hmap.m_scale;
				Dictionary<long, float> settled = SettleSeamVertices(list, center, value, freshRadius);
				bool flag = false;
				foreach (Heightmap item in list)
				{
					Dictionary<int, float> seamStarts = SeamStartsFor(item, center, value, settled);
					TerrainComp val = TerrainComp.FindTerrainCompiler(((Component)item).transform.position);
					if ((Object)(object)val == (Object)null)
					{
						flag |= ApplySmoothing(item, null, smoothRequest, seamStarts);
					}
					else if (val.m_initialized && !((Object)(object)val.m_nview == (Object)null) && val.m_nview.IsValid())
					{
						if (!val.m_nview.HasOwner())
						{
							val.m_nview.ClaimOwnership();
						}
						if (val.m_nview.IsOwner())
						{
							flag |= ApplySmoothing(item, val, smoothRequest, seamStarts);
							continue;
						}
						Logger.LogDebug($"Sending terrain smoothing for tile {((Component)item).transform.position} to its owner {val.m_nview.GetZDO().GetOwner()}.");
						val.m_nview.InvokeRPC("GradualTerrain_RPC_SmoothTerrain", new object[1] { WriteRequest(smoothRequest, seamStarts) });
					}
				}
				if (flag && Object.op_Implicit((Object)(object)ClutterSystem.instance))
				{
					ClutterSystem.instance.ResetGrass(center, smoothRequest.AffectedRadius);
				}
			}

			private static void RPC_SmoothTerrain(TerrainComp comp, long sender, ZPackage pkg)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: 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_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				if (!comp.m_initialized || !comp.IsOwner())
				{
					Logger.LogDebug($"Dropping terrain smoothing for {((Component)comp).transform.position}: not the owner here.");
					return;
				}
				if (!ReadRequest(pkg, out var request, out var seamStarts))
				{
					Logger.LogWarning($"Ignoring terrain smoothing for {((Component)comp).transform.position} from {sender}: it was sent by an incompatible version of GradualTerrain.");
					return;
				}
				Heightmap hmap = comp.m_hmap;
				if (!((Object)(object)hmap == (Object)null) && !hmap.IsDistantLod && hmap.m_buildData != null)
				{
					Logger.LogDebug($"Smoothing tile {((Component)hmap).transform.position} for a dig at {request.Center}, sent by {sender}.");
					if (ApplySmoothing(hmap, comp, request, seamStarts) && Object.op_Implicit((Object)(object)ClutterSystem.instance))
					{
						ClutterSystem.instance.ResetGrass(request.Center, request.AffectedRadius);
					}
				}
			}

			private static bool ApplySmoothing(Heightmap hmap, TerrainComp comp, SmoothRequest request, Dictionary<int, float> seamStarts)
			{
				TerrainComp val = SmoothHeightmap(hmap, comp, request, seamStarts);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				val.m_lastOpRadius = request.AffectedRadius;
				val.Save(false);
				val.m_hmap.Poke(0, false);
				return true;
			}

			private static bool ContainsCenter(TerrainComp comp, Vector3 point)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: 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_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				float num = comp.m_size / 2f;
				Vector3 position = ((Component)comp).transform.position;
				if (point.x >= position.x - num && point.x < position.x + num && point.z >= position.z - num)
				{
					return point.z < position.z + num;
				}
				return false;
			}

			private static ZPackage WriteRequest(SmoothRequest request, Dictionary<int, float> seamStarts)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				ZPackage val = new ZPackage();
				val.Write(1);
				val.Write(request.Center);
				val.Write(request.CenterHeight);
				val.Write(request.Range);
				val.Write(request.MinAdjust);
				val.Write(request.MaxAdjust);
				val.Write(request.MineSlope);
				val.Write(request.HillSlope);
				val.Write(request.AffectedRadius);
				val.Write(seamStarts.Count);
				foreach (KeyValuePair<int, float> seamStart in seamStarts)
				{
					val.Write(seamStart.Key);
					val.Write(seamStart.Value);
				}
				return val;
			}

			private static bool ReadRequest(ZPackage pkg, out SmoothRequest request, out Dictionary<int, float> seamStarts)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				request = null;
				seamStarts = null;
				if (pkg.ReadInt() != 1)
				{
					return false;
				}
				request = new SmoothRequest
				{
					Center = pkg.ReadVector3(),
					CenterHeight = pkg.ReadSingle(),
					Range = pkg.ReadInt(),
					MinAdjust = pkg.ReadSingle(),
					MaxAdjust = pkg.ReadSingle(),
					MineSlope = pkg.ReadSingle(),
					HillSlope = pkg.ReadSingle(),
					AffectedRadius = pkg.ReadSingle()
				};
				int num = pkg.ReadInt();
				seamStarts = new Dictionary<int, float>(num);
				for (int i = 0; i < num; i++)
				{
					int key = pkg.ReadInt();
					seamStarts[key] = pkg.ReadSingle();
				}
				return true;
			}

			internal static Dictionary<long, float> SettleSeamVertices(List<Heightmap> reachable, Vector3 center, int range, float freshRadius)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: 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_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: 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)
				Dictionary<long, Vector2> dictionary = new Dictionary<long, Vector2>();
				foreach (Heightmap item in reachable)
				{
					TerrainComp val = TerrainComp.FindTerrainCompiler(((Component)item).transform.position);
					if ((Object)(object)val == (Object)null || !val.m_initialized)
					{
						continue;
					}
					bool flag = val.m_lastOpPoint == center;
					foreach (SeamVertex item2 in SeamVerticesInRange(item, center, range))
					{
						if (val.m_modifiedHeight[item2.Index] && (flag || !(item2.Distance <= freshRadius)))
						{
							float num = val.m_levelDelta[item2.Index];
							dictionary[item2.Key] = (dictionary.TryGetValue(item2.Key, out var value) ? new Vector2(Mathf.Min(value.x, num), Mathf.Max(value.y, num)) : new Vector2(num, num));
						}
					}
				}
				Dictionary<long, float> dictionary2 = new Dictionary<long, float>(dictionary.Count);
				foreach (KeyValuePair<long, Vector2> item3 in dictionary)
				{
					dictionary2[item3.Key] = ((item3.Value.x == item3.Value.y) ? item3.Value.x : ((item3.Value.x + item3.Value.y) * 0.5f));
				}
				return dictionary2;
			}

			private static Dictionary<int, float> SeamStartsFor(Heightmap hmap, Vector3 center, int range, Dictionary<long, float> settled)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				Dictionary<int, float> dictionary = new Dictionary<int, float>();
				if (settled.Count == 0)
				{
					return dictionary;
				}
				foreach (SeamVertex item in SeamVerticesInRange(hmap, center, range))
				{
					if (settled.TryGetValue(item.Key, out var value))
					{
						dictionary[item.Index] = value;
					}
				}
				return dictionary;
			}

			private static IEnumerable<SeamVertex> SeamVerticesInRange(Heightmap hmap, Vector3 center, int range)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				float scale = hmap.m_scale;
				int width = hmap.m_width;
				int rowLength = width + 1;
				int half = width / 2;
				Vector3 pos = ((Component)hmap).transform.position;
				GetVertexWindow(hmap, center, range, out var x0, out var x1, out var y, out var y2);
				for (int i = y; i <= y2; i++)
				{
					bool edgeRow = i == 0 || i == width;
					for (int j = x0; j <= x1; j++)
					{
						if (edgeRow || j == 0 || j == width)
						{
							float num = pos.x + (float)(j - half) * scale;
							float num2 = pos.z + (float)(i - half) * scale;
							float num3 = center.x - num;
							float num4 = center.z - num2;
							float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
							if (!(num5 > (float)range))
							{
								yield return new SeamVertex
								{
									Index = i * rowLength + j,
									Key = SeamKey(num, num2, scale),
									Distance = num5
								};
							}
						}
					}
				}
			}

			private static long SeamKey(float worldX, float worldZ, float scale)
			{
				long num = Mathf.RoundToInt(worldX / scale);
				long num2 = Mathf.RoundToInt(worldZ / scale);
				return (num << 32) ^ (num2 & 0xFFFFFFFFu);
			}

			private static void GetVertexWindow(Heightmap hmap, Vector3 center, int range, out int x0, out int x1, out int y0, out int y1)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				int num = default(int);
				int num2 = default(int);
				hmap.WorldToVertex(center, ref num, ref num2);
				int num3 = Mathf.CeilToInt((float)range / hmap.m_scale);
				x0 = Mathf.Max(0, num - num3);
				x1 = Mathf.Min(hmap.m_width, num + num3);
				y0 = Mathf.Max(0, num2 - num3);
				y1 = Mathf.Min(hmap.m_width, num2 + num3);
			}

			internal static TerrainComp SmoothHeightmap(Heightmap hmap, TerrainComp comp, SmoothRequest request, Dictionary<int, float> seamStarts)
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: 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_0097: 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_00b3: 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_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
				if (hmap.m_buildData == null)
				{
					return null;
				}
				List<float> baseHeights = hmap.m_buildData.m_baseHeights;
				float scale = hmap.m_scale;
				int width = hmap.m_width;
				int num = width + 1;
				int num2 = width / 2;
				Vector3 position = ((Component)hmap).transform.position;
				Vector3 center = request.Center;
				float centerHeight = request.CenterHeight;
				GetVertexWindow(hmap, center, request.Range, out var x, out var x2, out var y, out var y2);
				float minAdjust = request.MinAdjust;
				float maxAdjust = request.MaxAdjust;
				bool flag = false;
				for (int i = y; i <= y2; i++)
				{
					for (int j = x; j <= x2; j++)
					{
						float num3 = position.x + (float)(j - num2) * scale;
						float num4 = position.z + (float)(i - num2) * scale;
						float num5 = center.x - num3;
						float num6 = center.z - num4;
						float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
						if (num7 > (float)request.Range)
						{
							continue;
						}
						int num8 = i * num + j;
						float num9 = baseHeights[num8];
						float num10 = (((Object)(object)comp != (Object)null) ? comp.m_levelDelta[num8] : 0f);
						float num11 = num10;
						if ((j == 0 || j == width || i == 0 || i == width) && seamStarts.TryGetValue(num8, out var value))
						{
							num11 = value;
						}
						float num12 = num9 + position.y + num11;
						float num13 = num7 * request.MineSlope;
						float num14 = num7 * request.HillSlope;
						float num15;
						if (num12 > centerHeight + num13)
						{
							num15 = Mathf.Clamp(centerHeight + num13 - position.y - num9, minAdjust, maxAdjust);
						}
						else if (num12 < centerHeight - num14)
						{
							num15 = Mathf.Clamp(centerHeight - num14 - position.y - num9, minAdjust, maxAdjust);
						}
						else
						{
							if (num11 == num10)
							{
								continue;
							}
							num15 = num11;
						}
						if ((Object)(object)comp == (Object)null)
						{
							if ((Object)(object)ZoneSystem.instance == (Object)null || !ZoneSystem.instance.IsZoneLoaded(position))
							{
								return null;
							}
							comp = hmap.GetAndCreateTerrainCompiler();
							if ((Object)(object)comp == (Object)null || !comp.m_initialized)
							{
								return null;
							}
						}
						comp.m_levelDelta[num8] = num15;
						comp.m_modifiedHeight[num8] = true;
						flag = true;
					}
				}
				if (!flag)
				{
					return null;
				}
				return comp;
			}
		}
	}
	internal class HeightmapPatches
	{
		[HarmonyPatch(typeof(TerrainComp))]
		internal static class TerrainCompositionPatches
		{
			[HarmonyTranspiler]
			[HarmonyPatch("ApplyToHeightmap")]
			private static IEnumerable<CodeInstruction> ApplyToHeightmap(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)8f, (string)null)
				}).RemoveInstructions(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<float>>((Func<float>)MinTerrainAdjustNoNeg) })
					.ThrowIfNotMatch("Unable to patch min terrain adjustment.", Array.Empty<CodeMatch>())
					.Advance(1)
					.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)8f, (string)null)
					})
					.RemoveInstructions(1)
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<float>>((Func<float>)MaxTerrainAdjust) })
					.ThrowIfNotMatch("Unable to patch max terrain adjustment.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			[HarmonyTranspiler]
			[HarmonyPatch("LevelTerrain")]
			private static IEnumerable<CodeInstruction> LevelTerrain(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)(-8f), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)8f, (string)null)
				}).RemoveInstructions(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					Transpilers.EmitDelegate<Func<float>>((Func<float>)MinTerrainAdjust),
					Transpilers.EmitDelegate<Func<float>>((Func<float>)MaxTerrainAdjust)
				})
					.ThrowIfNotMatch("Unable to patch terrain level height adjustments.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			[HarmonyTranspiler]
			[HarmonyPatch("RaiseTerrain")]
			private static IEnumerable<CodeInstruction> RaiseTerrain(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)(-8f), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)8f, (string)null)
				}).RemoveInstructions(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					Transpilers.EmitDelegate<Func<float>>((Func<float>)MinTerrainAdjust),
					Transpilers.EmitDelegate<Func<float>>((Func<float>)MaxTerrainAdjust)
				})
					.ThrowIfNotMatch("Unable to patch terrain level height adjustments.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			[HarmonyPrefix]
			[HarmonyPatch("LevelTerrain")]
			private static void LevelTerrainPrefix(TerrainComp __instance, Vector3 worldPos)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				BiomeConfiguration.SetCurrentLimits(worldPos, __instance.m_hmap);
			}

			[HarmonyPrefix]
			[HarmonyPatch("RaiseTerrain")]
			private static void RaiseTerrainPrefix(TerrainComp __instance, Vector3 worldPos)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				BiomeConfiguration.SetCurrentLimits(worldPos, __instance.m_hmap);
			}

			[HarmonyPrefix]
			[HarmonyPatch("ApplyToHeightmap")]
			private static void ApplyToHeightmapPrefix()
			{
				BiomeConfiguration.SetEnvelopeLimits();
			}

			internal static float MinTerrainAdjustNoNeg()
			{
				return Mathf.Abs(BiomeConfiguration.CurrentMin);
			}

			internal static float MinTerrainAdjust()
			{
				return BiomeConfiguration.CurrentMin;
			}

			internal static float MaxTerrainAdjust()
			{
				return BiomeConfiguration.CurrentMax;
			}
		}
	}
}