Decompiled source of VoxelTerrain v0.27.53

VoxelTerrain.dll

Decompiled 5 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.Scripting;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("VoxelTerrain")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.27.53.0")]
[assembly: AssemblyInformationalVersion("0.27.53+33978ac5b5b587d08ef51bb5516ff23de2782190")]
[assembly: AssemblyProduct("VoxelTerrain")]
[assembly: AssemblyTitle("VoxelTerrain")]
[assembly: AssemblyVersion("0.27.53.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 VoxelTerrain
{
	internal static class PoolBudget
	{
		public const long MaxBytes = 50331648L;

		public static long Kept;
	}
	internal static class ArrayPool<T>
	{
		private const int MinShift = 8;

		private const int Classes = 96;

		private static readonly Stack<T[]>[] _bins;

		private static readonly int ElemBytes;

		private static long _kept;

		public static readonly long[] Requests;

		public static readonly long[] Misses;

		public static long DroppedBytes;

		public static long KeptBytes => _kept * ElemBytes;

		private static int SizeOfClass(int c)
		{
			if (c == 0)
			{
				return 256;
			}
			int num = 8 + (c - 1) / 4;
			return (c - 1) % 4 + 5 << num - 2;
		}

		public static string TopMisses(int n)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool[] array = new bool[96];
			for (int i = 0; i < n; i++)
			{
				int num = -1;
				for (int j = 0; j < 96; j++)
				{
					if (!array[j] && Misses[j] > 0 && (num < 0 || Misses[j] > Misses[num]))
					{
						num = j;
					}
				}
				if (num < 0)
				{
					break;
				}
				array[num] = true;
				long num2 = (long)SizeOfClass(num) * (long)ElemBytes / 1024;
				stringBuilder.Append((i > 0) ? ", " : "").Append((num2 >= 1024) ? $"{(double)num2 / 1024.0:0.#} MB" : $"{num2} KB").Append(' ')
					.Append(Misses[num])
					.Append('/')
					.Append(Requests[num]);
			}
			Array.Clear(Requests, 0, 96);
			Array.Clear(Misses, 0, 96);
			if (stringBuilder.Length <= 0)
			{
				return "none";
			}
			return stringBuilder.ToString();
		}

		static ArrayPool()
		{
			_bins = new Stack<T[]>[96];
			ElemBytes = Marshal.SizeOf(typeof(T));
			Requests = new long[96];
			Misses = new long[96];
			for (int i = 0; i < 96; i++)
			{
				_bins[i] = new Stack<T[]>();
			}
		}

		private static int Class(int n, out int size)
		{
			if (n <= 256)
			{
				size = 256;
				return 0;
			}
			int num = 31 - LeadingZeros((uint)(n - 1));
			int num2 = 1 << num - 2;
			int num3 = (n + num2 - 1) / num2;
			size = num3 * num2;
			return (num - 8) * 4 + (num3 - 4);
		}

		private static int LeadingZeros(uint x)
		{
			int num = 0;
			if (x == 0)
			{
				return 32;
			}
			while ((x & 0x80000000u) == 0)
			{
				x <<= 1;
				num++;
			}
			return num;
		}

		public static T[] Rent(int n)
		{
			int size;
			int num = Class(n, out size);
			if (num >= 96)
			{
				PackedMesh.Count((long)n * (long)ElemBytes);
				return new T[n];
			}
			Interlocked.Increment(ref Requests[num]);
			Stack<T[]> stack = _bins[num];
			lock (stack)
			{
				if (stack.Count > 0)
				{
					T[] array = stack.Pop();
					Interlocked.Add(ref _kept, -array.Length);
					Interlocked.Add(ref PoolBudget.Kept, -array.Length * ElemBytes);
					Interlocked.Increment(ref PackedMesh.PoolHits);
					return array;
				}
			}
			PackedMesh.Count((long)size * (long)ElemBytes);
			Interlocked.Increment(ref PackedMesh.PoolMisses);
			Interlocked.Increment(ref Misses[num]);
			return new T[size];
		}

		public static void Return(T[] a)
		{
			if (a == null)
			{
				return;
			}
			int size;
			int num = Class(a.Length, out size);
			if (num >= 96 || size != a.Length)
			{
				return;
			}
			long num2 = (long)a.Length * (long)ElemBytes;
			if (Interlocked.Add(ref PoolBudget.Kept, num2) > 50331648)
			{
				Interlocked.Add(ref PoolBudget.Kept, -num2);
				Interlocked.Add(ref DroppedBytes, num2);
				return;
			}
			Stack<T[]> stack = _bins[num];
			lock (stack)
			{
				stack.Push(a);
			}
			Interlocked.Add(ref _kept, a.Length);
		}
	}
	internal sealed class CarrySkill : MonoBehaviour
	{
		internal static readonly SkillType Skill = (SkillType)StringExtensionMethods.GetStableHashCode("VoxelTerrain.LoadCarrying");

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _scale;

		private static SkillDef _def;

		private float _timer;

		public static void Bind(ConfigFile cfg, Harmony harmony)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			_enabled = cfg.Bind<bool>("Gameplay", "ExtraSkills", true, "Skill 'Load carrying' (rises while moving overloaded, more carry weight).");
			_scale = cfg.Bind<float>("Gameplay", "CarryWeightScale", 1f, new ConfigDescription("'Load carrying' extra carry weight, times the default: +1 kg per level up to 30, +1.5 up to 50, +2 up to 75, +3 up to 100 (+185 kg at 100).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Skills), "IsSkillValid", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CarrySkill), "IsSkillValidPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), new HarmonyMethod(typeof(CarrySkill), "GetSkillDefPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CarrySkill), "LanguagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), "GetMaxCarryWeight", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CarrySkill), "CarryWeightPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void IsSkillValidPostfix(SkillType type, ref bool __result)
		{
			//IL_0004: 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 (!__result && type == Skill)
			{
				__result = true;
			}
		}

		private static bool GetSkillDefPrefix(SkillType type, ref SkillDef __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0031: Expected O, but got Unknown
			if (type != Skill)
			{
				return true;
			}
			if (_def == null)
			{
				_def = new SkillDef
				{
					m_skill = Skill,
					m_increseStep = 1f
				};
			}
			_def.m_description = (Russian() ? "Немного больше переносимый вес. Растёт, когда идёшь с перегрузом." : "A little more carry weight. Rises while you move overloaded.");
			if ((Object)(object)_def.m_icon == (Object)null)
			{
				_def.m_icon = FindIcon();
			}
			__result = _def;
			return false;
		}

		private static Sprite FindIcon()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Invalid comparison between Unknown and I4
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = instance.GetItemPrefab("BeltStrength");
			ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val != (Object)null && val.m_itemData.m_shared.m_icons.Length != 0)
			{
				return val.m_itemData.m_shared.m_icons[0];
			}
			Player localPlayer = Player.m_localPlayer;
			Skills val2 = (((Object)(object)localPlayer != (Object)null) ? ((Character)localPlayer).GetSkills() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				foreach (SkillDef skill in val2.m_skills)
				{
					if ((int)skill.m_skill == 102)
					{
						return skill.m_icon;
					}
				}
			}
			return null;
		}

		private static bool Russian()
		{
			return PlatformPrefs.GetString("language", "English") == "Russian";
		}

		private static void LanguagePostfix(Localization __instance)
		{
			//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)
			MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null);
			if (__instance != null && !(methodInfo == null))
			{
				methodInfo.Invoke(__instance, new object[2]
				{
					"skill_" + ((object)Skill/*cast due to .constrained prefix*/).ToString().ToLower(),
					Russian() ? "Переноска тяжестей" : "Load carrying"
				});
			}
		}

		private static void CarryWeightPostfix(Player __instance, ref float __result)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (_enabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				float level = (((Object)(object)((Character)__instance).GetSkills() != (Object)null) ? ((Character)__instance).GetSkillLevel(Skill) : 0f);
				__result += Bonus(level) * _scale.Value * Game.m_carryWeightRate;
			}
		}

		internal static float Bonus(float level)
		{
			level = Mathf.Clamp(level, 0f, 100f);
			return Mathf.Min(level, 30f) * 1f + Mathf.Clamp(level - 30f, 0f, 20f) * 1.5f + Mathf.Clamp(level - 50f, 0f, 25f) * 2f + Mathf.Clamp(level - 75f, 0f, 25f) * 3f;
		}

		private void Update()
		{
			//IL_002d: 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_0042: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!_enabled.Value || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !((Character)localPlayer).IsEncumbered())
			{
				return;
			}
			Vector3 val = ((Character)localPlayer).GetMoveDir();
			if (((Vector3)(ref val)).sqrMagnitude <= 0.01f)
			{
				return;
			}
			val = ((Character)localPlayer).GetVelocity();
			if (!(((Vector3)(ref val)).sqrMagnitude <= 0.25f))
			{
				_timer += Time.deltaTime;
				if (_timer > 1f)
				{
					_timer = 0f;
					((Character)localPlayer).RaiseSkill(Skill, 0.4f);
				}
			}
		}
	}
	internal static class ChunkPool
	{
		internal sealed class Objects
		{
			public GameObject Go;

			public MeshFilter TopFilter;

			public MeshFilter WallFilter;

			public MeshFilter DirtFilter;

			public MeshRenderer TopRenderer;

			public MeshRenderer WallRenderer;

			public MeshRenderer DirtRenderer;

			public MeshCollider Collider;

			public VoxelTag Tag;
		}

		private const int Max = 4000;

		private static readonly Stack<Objects> _free = new Stack<Objects>();

		private static GameObject _holder;

		public static Objects Take()
		{
			while (_free.Count > 0)
			{
				Objects objects = _free.Pop();
				if ((Object)(object)objects.Go != (Object)null && (Object)(object)objects.TopRenderer != (Object)null && (Object)(object)objects.WallRenderer != (Object)null && (Object)(object)objects.DirtRenderer != (Object)null && (Object)(object)objects.Collider != (Object)null && (Object)(object)objects.Tag != (Object)null)
				{
					return objects;
				}
			}
			return null;
		}

		public static void Give(Objects o)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (o == null || (Object)(object)o.Go == (Object)null)
			{
				return;
			}
			if (_free.Count >= 4000)
			{
				Object.Destroy((Object)(object)o.Go);
				return;
			}
			if ((Object)(object)_holder == (Object)null)
			{
				_holder = new GameObject("VoxelTerrain chunk pool");
				_holder.SetActive(false);
			}
			o.Go.SetActive(false);
			o.Go.transform.SetParent(_holder.transform, false);
			if ((Object)(object)o.TopFilter != (Object)null)
			{
				o.TopFilter.sharedMesh = null;
			}
			if ((Object)(object)o.WallFilter != (Object)null)
			{
				o.WallFilter.sharedMesh = null;
			}
			if ((Object)(object)o.DirtFilter != (Object)null)
			{
				o.DirtFilter.sharedMesh = null;
			}
			if ((Object)(object)o.Collider != (Object)null)
			{
				o.Collider.sharedMesh = null;
			}
			if ((Object)(object)o.Tag != (Object)null)
			{
				o.Tag.Zone = null;
			}
			_free.Push(o);
		}
	}
	internal sealed class DensityGrid
	{
		public const int B = 16;

		public const int Shift = 4;

		public const int Mask = 15;

		public readonly int NX;

		public readonly int NY;

		public readonly int NZ;

		public readonly int BX;

		public readonly int BY;

		public readonly int BZ;

		private readonly sbyte[][] _bricks;

		private readonly float[] _heights;

		private readonly float _y0;

		private readonly float _cell;

		private readonly float _q;

		public int BrickCount => _bricks.Length;

		public float Y0 => _y0;

		public int AllocatedBricks
		{
			get
			{
				int num = 0;
				sbyte[][] bricks = _bricks;
				for (int i = 0; i < bricks.Length; i++)
				{
					if (bricks[i] != null)
					{
						num++;
					}
				}
				return num;
			}
		}

		public sbyte this[int i]
		{
			get
			{
				int x = i % NX;
				int num = i / NX;
				return Get(x, num % NY, num / NY);
			}
			set
			{
				int x = i % NX;
				int num = i / NX;
				Set(x, num % NY, num / NY, value);
			}
		}

		public DensityGrid(int nx, int ny, int nz, float[] heights, float y0, float cell, float q)
		{
			NX = nx;
			NY = ny;
			NZ = nz;
			BX = nx + 15 >> 4;
			BY = ny + 15 >> 4;
			BZ = nz + 15 >> 4;
			_bricks = new sbyte[BX * BY * BZ][];
			_heights = heights;
			_y0 = y0;
			_cell = cell;
			_q = q;
		}

		public float Height(int x, int z)
		{
			return _heights[z * NX + x];
		}

		public bool ColumnIsFormula(int x, int z)
		{
			int num = (z >> 4) * BY * BX + (x >> 4);
			for (int i = 0; i < BY; i++)
			{
				if (_bricks[num + i * BX] != null)
				{
					return false;
				}
			}
			return true;
		}

		public sbyte Formula(int x, int y, int z)
		{
			return (sbyte)Mathf.Clamp(Mathf.RoundToInt((_heights[z * NX + x] - (_y0 + (float)y * _cell)) * _q), -127, 127);
		}

		private int Brick(int x, int y, int z)
		{
			return ((z >> 4) * BY + (y >> 4)) * BX + (x >> 4);
		}

		private static int Local(int x, int y, int z)
		{
			return (((z & 0xF) << 4) + (y & 0xF) << 4) + (x & 0xF);
		}

		public sbyte Get(int x, int y, int z)
		{
			sbyte[] array = _bricks[Brick(x, y, z)];
			if (array != null)
			{
				return array[Local(x, y, z)];
			}
			return Formula(x, y, z);
		}

		public void Set(int x, int y, int z, sbyte v)
		{
			int num = Brick(x, y, z);
			sbyte[] array = _bricks[num];
			if (array == null)
			{
				if (Formula(x, y, z) == v)
				{
					return;
				}
				array = new sbyte[4096];
				int num2 = x >> 4 << 4;
				int num3 = y >> 4 << 4;
				int num4 = z >> 4 << 4;
				for (int i = 0; i < 16; i++)
				{
					for (int j = 0; j < 16; j++)
					{
						for (int k = 0; k < 16; k++)
						{
							int x2 = Mathf.Min(num2 + k, NX - 1);
							int y2 = num3 + j;
							int z2 = Mathf.Min(num4 + i, NZ - 1);
							array[((i << 4) + j << 4) + k] = Formula(x2, y2, z2);
						}
					}
				}
				array[Local(x, y, z)] = v;
				_bricks[num] = array;
			}
			else
			{
				array[Local(x, y, z)] = v;
			}
		}
	}
	internal static class FallDamage
	{
		private static ConfigEntry<float> _safe;

		private static ConfigEntry<float> _full;

		private static readonly FieldRef<SEMan, Character> _character = AccessTools.FieldRefAccess<SEMan, Character>("m_character");

		private static readonly FieldRef<Character, float> _maxAir = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude");

		public static void Bind(ConfigFile config, Harmony harmony)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			_safe = config.Bind<float>("Player", "FallSafeHeight", 6f, new ConfigDescription("Falls up to this height (m) do no damage (game: 4).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			_full = config.Bind<float>("Player", "FallFullDamageHeight", 36f, new ConfigDescription("A fall from this height (m) does 100 damage, linear from FallSafeHeight (game: 20). 0 = game's fall damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			harmony.Patch((MethodBase)AccessTools.Method(typeof(SEMan), "ModifyFallDamage", (Type[])null, (Type[])null), new HarmonyMethod(typeof(FallDamage), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void Prefix(SEMan __instance, ref float baseDamage, ref float damage)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (!(_full.Value <= 0f))
			{
				Character val = _character.Invoke(__instance);
				if (!((Object)(object)val == (Object)null) && val.IsPlayer())
				{
					float num = Mathf.Max(0f, _maxAir.Invoke(val) - ((Component)val).transform.position.y);
					float num2 = Mathf.Max(1f, _full.Value - _safe.Value);
					damage = (baseDamage = Mathf.Clamp01((num - _safe.Value) / num2) * 100f);
				}
			}
		}
	}
	internal static class GroundContacts
	{
		private sealed class Entry
		{
			public Bounds Box;

			public List<long> Cells = new List<long>();
		}

		private const float CellSize = 4f;

		private static readonly Dictionary<WearNTear, Entry> _grounded = new Dictionary<WearNTear, Entry>();

		private static readonly Dictionary<long, List<WearNTear>> _byCell = new Dictionary<long, List<WearNTear>>();

		private static readonly List<Collider> _cols = new List<Collider>();

		private static readonly FieldRef<WearNTear, float> _support = AccessTools.FieldRefAccess<WearNTear, float>("m_support");

		private static readonly FieldRef<WearNTear, List<Collider>> _supportColliders = AccessTools.FieldRefAccess<WearNTear, List<Collider>>("m_supportColliders");

		private static readonly Func<WearNTear, float> _maxSupport = AccessTools.MethodDelegate<Func<WearNTear, float>>(AccessTools.Method(typeof(WearNTear), "GetMaxSupport", (Type[])null, (Type[])null), (object)null, true);

		public static long Told;

		public static long Checked;

		public static int Count => _grounded.Count;

		public static void Patch(Harmony harmony)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			harmony.Patch((MethodBase)AccessTools.Method(typeof(WearNTear), "UpdateSupport", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(GroundContacts), "SupportPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(WearNTear), "OnDestroy", (Type[])null, (Type[])null), new HarmonyMethod(typeof(GroundContacts), "DestroyPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void Clear()
		{
			_grounded.Clear();
			_byCell.Clear();
		}

		private static long Key(int x, int z)
		{
			return ((long)x << 32) ^ (uint)z;
		}

		private static void SupportPostfix(WearNTear __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			bool flag = _support.Invoke(__instance) >= _maxSupport(__instance);
			bool flag2 = _grounded.ContainsKey(__instance);
			if (flag != flag2)
			{
				if (flag)
				{
					File(__instance);
				}
				else
				{
					Unfile(__instance);
				}
			}
		}

		private static void DestroyPrefix(WearNTear __instance)
		{
			Unfile(__instance);
		}

		private static void File(WearNTear w)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			_cols.Clear();
			((Component)w).GetComponentsInChildren<Collider>(false, _cols);
			bool flag = false;
			Bounds box = default(Bounds);
			foreach (Collider col in _cols)
			{
				if (!((Object)(object)col == (Object)null) && !col.isTrigger && col.enabled)
				{
					if (!flag)
					{
						box = col.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref box)).Encapsulate(col.bounds);
					}
				}
			}
			if (!flag)
			{
				return;
			}
			((Bounds)(ref box)).Expand(0.3f);
			Entry entry = new Entry
			{
				Box = box
			};
			int num = Mathf.FloorToInt(((Bounds)(ref box)).min.x / 4f);
			int num2 = Mathf.FloorToInt(((Bounds)(ref box)).max.x / 4f);
			int num3 = Mathf.FloorToInt(((Bounds)(ref box)).min.z / 4f);
			int num4 = Mathf.FloorToInt(((Bounds)(ref box)).max.z / 4f);
			for (int i = num; i <= num2; i++)
			{
				for (int j = num3; j <= num4; j++)
				{
					long num5 = Key(i, j);
					if (!_byCell.TryGetValue(num5, out var value))
					{
						value = (_byCell[num5] = new List<WearNTear>());
					}
					value.Add(w);
					entry.Cells.Add(num5);
				}
			}
			_grounded[w] = entry;
		}

		private static void Unfile(WearNTear w)
		{
			if ((Object)(object)w == (Object)null || !_grounded.TryGetValue(w, out var value))
			{
				return;
			}
			foreach (long cell in value.Cells)
			{
				if (_byCell.TryGetValue(cell, out var value2))
				{
					value2.Remove(w);
					if (value2.Count == 0)
					{
						_byCell.Remove(cell);
					}
				}
			}
			_grounded.Remove(w);
		}

		public static void Touching(Vector3 c, float r, List<WearNTear> into)
		{
			//IL_0000: 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_0027: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.FloorToInt((c.x - r) / 4f);
			int num2 = Mathf.FloorToInt((c.x + r) / 4f);
			int num3 = Mathf.FloorToInt((c.z - r) / 4f);
			int num4 = Mathf.FloorToInt((c.z + r) / 4f);
			float num5 = r * r;
			for (int i = num; i <= num2; i++)
			{
				for (int j = num3; j <= num4; j++)
				{
					if (!_byCell.TryGetValue(Key(i, j), out var value))
					{
						continue;
					}
					for (int num6 = value.Count - 1; num6 >= 0; num6--)
					{
						WearNTear val = value[num6];
						if ((Object)(object)val == (Object)null)
						{
							value.RemoveAt(num6);
						}
						else
						{
							Checked++;
							if (!into.Contains(val) && _grounded.TryGetValue(val, out var value2) && ((Bounds)(ref value2.Box)).SqrDistance(c) <= num5)
							{
								into.Add(val);
							}
						}
					}
				}
			}
		}
	}
	internal static class GroundPiles
	{
		private const int MaxPile = 60000;

		private const int PerTick = 200;

		private const float Range = 64f;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _radius;

		private static int _cursor;

		private static int _itemMask;

		private static readonly Collider[] _near = (Collider[])(object)new Collider[32];

		private static readonly FieldRef<List<ItemDrop>> _instances = AccessTools.StaticFieldRefAccess<List<ItemDrop>>(AccessTools.Field(typeof(ItemDrop), "s_instances"));

		private static readonly FieldRef<ItemDrop, ZNetView> _nview = AccessTools.FieldRefAccess<ItemDrop, ZNetView>("m_nview");

		private static readonly FieldRef<ItemDrop, Rigidbody> _body = AccessTools.FieldRefAccess<ItemDrop, Rigidbody>("m_body");

		public static void Bind(ConfigFile config, Harmony harmony)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			_enabled = config.Bind<bool>("Items", "GroundPiles", true, "Identical dropped items lying together merge into one pile of any size (e.g. Stone x1000). Picking it up takes what fits, the rest stays.");
			_radius = config.Bind<float>("Items", "PileRadius", 1.5f, new ConfigDescription("Items closer than this (m) merge into one pile.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 4f), Array.Empty<object>()));
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Humanoid), "Pickup", (Type[])null, (Type[])null), new HarmonyMethod(typeof(GroundPiles), "PickupPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(ItemDrop), "SlowUpdate", (Type[])null, (Type[])null), new HarmonyMethod(typeof(GroundPiles), "SlowUpdatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static bool Stackable(ItemDrop d)
		{
			if (d.m_itemData.m_shared.m_maxStackSize > 1)
			{
				return d.m_itemData.m_shared.m_autoStack;
			}
			return false;
		}

		public static void Tick()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!_enabled.Value || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			List<ItemDrop> list = _instances.Invoke();
			if ((Object)(object)localPlayer == (Object)null || list == null || list.Count == 0)
			{
				return;
			}
			if (_itemMask == 0)
			{
				_itemMask = LayerMask.GetMask(new string[1] { "item" });
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			int num = Mathf.Min(200, list.Count);
			for (int i = 0; i < num; i++)
			{
				_cursor = (_cursor + 1) % list.Count;
				ItemDrop val = list[_cursor];
				if (Mergeable(val))
				{
					Vector3 val2 = ((Component)val).transform.position - position;
					if (!(((Vector3)(ref val2)).sqrMagnitude > 4096f) && MergeAround(val))
					{
						break;
					}
				}
			}
		}

		private static bool Mergeable(ItemDrop d)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)d == (Object)null || !Stackable(d) || d.IsPiece())
			{
				return false;
			}
			ZNetView val = _nview.Invoke(d);
			if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner())
			{
				return false;
			}
			Rigidbody val2 = _body.Invoke(d);
			if (!((Object)(object)val2 == (Object)null) && !val2.IsSleeping())
			{
				Vector3 linearVelocity = val2.linearVelocity;
				return ((Vector3)(ref linearVelocity)).sqrMagnitude < 0.04f;
			}
			return true;
		}

		private static bool MergeAround(ItemDrop a)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(((Component)a).transform.position, _radius.Value, _near, _itemMask, (QueryTriggerInteraction)1);
			bool result = false;
			a.Load();
			for (int i = 0; i < num; i++)
			{
				Rigidbody attachedRigidbody = _near[i].attachedRigidbody;
				ItemDrop val = (((Object)(object)attachedRigidbody != (Object)null) ? ((Component)attachedRigidbody).GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)a || !Mergeable(val))
				{
					continue;
				}
				val.Load();
				ItemData itemData = a.m_itemData;
				ItemData itemData2 = val.m_itemData;
				if (!(itemData2.m_shared.m_name != itemData.m_shared.m_name) && itemData2.m_quality == itemData.m_quality && itemData2.m_variant == itemData.m_variant && itemData2.m_worldLevel == itemData.m_worldLevel && itemData.m_stack + itemData2.m_stack <= 60000)
				{
					ItemDrop val2 = ((itemData.m_stack >= itemData2.m_stack) ? a : val);
					ItemDrop val3 = (((Object)(object)val2 == (Object)(object)a) ? val : a);
					ItemData itemData3 = val2.m_itemData;
					itemData3.m_stack += val3.m_itemData.m_stack;
					ItemDrop.SaveToZDO(val2.m_itemData, _nview.Invoke(val2).GetZDO(), -1);
					ZNetScene.instance.Destroy(((Component)val3).gameObject);
					result = true;
					if ((Object)(object)val3 == (Object)(object)a)
					{
						break;
					}
				}
			}
			return result;
		}

		private static void SlowUpdatePrefix(ItemDrop __instance)
		{
			ItemData itemData = __instance.m_itemData;
			if (itemData.m_shared.m_maxStackSize > 1 && itemData.m_stack > itemData.m_shared.m_maxStackSize)
			{
				__instance.m_autoDestroy = false;
			}
		}

		private static bool PickupPrefix(Humanoid __instance, GameObject go, bool autoPickupDelay, ref bool __result)
		{
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val == (Object)null || (Object)(object)go == (Object)null)
			{
				return true;
			}
			ItemDrop component = go.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			component.Load();
			ItemData itemData = component.m_itemData;
			int maxStackSize = itemData.m_shared.m_maxStackSize;
			if (maxStackSize <= 1 || itemData.m_stack <= maxStackSize)
			{
				return true;
			}
			__result = false;
			if (((Character)val).IsTeleporting() || !component.CanPickup(autoPickupDelay))
			{
				return false;
			}
			Inventory inventory = ((Humanoid)val).GetInventory();
			int num = inventory.FindFreeStackSpace(itemData.m_shared.m_name, (float)itemData.m_worldLevel) + inventory.GetEmptySlots() * maxStackSize;
			int num2 = int.MaxValue;
			if (itemData.m_shared.m_weight > 0f)
			{
				num2 = Mathf.Max(maxStackSize, Mathf.FloorToInt((val.GetMaxCarryWeight() - inventory.GetTotalWeight()) / itemData.m_shared.m_weight));
			}
			int num3 = Mathf.Min(itemData.m_stack, Mathf.Min(num, num2));
			if (num3 <= 0)
			{
				((Character)val).Message((MessageType)2, "$msg_noroom", 0, (Sprite)null, false);
				return false;
			}
			int i;
			int stack;
			for (i = 0; i < num3; i += stack)
			{
				ItemData val2 = itemData.Clone();
				val2.m_stack = Mathf.Min(maxStackSize, num3 - i);
				stack = val2.m_stack;
				if (!inventory.AddItem(val2))
				{
					break;
				}
			}
			if (i <= 0)
			{
				((Character)val).Message((MessageType)2, "$msg_noroom", 0, (Sprite)null, false);
				return false;
			}
			itemData.m_stack -= i;
			if (itemData.m_stack <= 0)
			{
				ZNetScene.instance.Destroy(go);
			}
			else
			{
				ItemDrop.SaveToZDO(itemData, _nview.Invoke(component).GetZDO(), -1);
			}
			((Humanoid)val).m_pickupEffects.Create(((Component)val).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)val).GetZDOID());
			((Character)val).ShowPickupMessage(itemData, i);
			__result = true;
			return false;
		}
	}
	internal static class LodCut
	{
		private sealed class Lod
		{
			public Heightmap Map;

			public Mesh Mesh;

			public Vector3[] Original;

			public Vector3[] Work;

			public bool Changed;

			public bool Dirty;
		}

		private const float Drop = 600f;

		private const float Step = 4f;

		private static readonly List<Lod> _lods = new List<Lod>();

		private static Vector3 _last = new Vector3(float.NaN, 0f, 0f);

		private static readonly HashSet<Vector2s> _covered = new HashSet<Vector2s>();

		private static readonly HashSet<Vector2s> _coveredNow = new HashSet<Vector2s>();

		private static readonly FieldRef<Heightmap, Mesh> _renderMesh = AccessTools.FieldRefAccess<Heightmap, Mesh>("m_renderMesh");

		private static readonly Func<float> _hideDistance = AccessTools.MethodDelegate<Func<float>>(AccessTools.Method(typeof(Heightmap), "GetLodHideDistance", (Type[])null, (Type[])null), (object)null, true);

		private static int _rr;

		private const float Overlap = 2f;

		private const float Gentle = 16f;

		private const float GentleDrop = 12f;

		private const float DeepAt = 32f;

		public static float HideDistance()
		{
			if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return 128f;
			}
			try
			{
				return _hideDistance();
			}
			catch
			{
				return 128f;
			}
		}

		public static void Patch(Harmony harmony)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Heightmap), "RebuildRenderMesh", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(LodCut), "RebuildPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void RebuildPostfix(Heightmap __instance)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsDistantLod)
			{
				return;
			}
			Mesh val = _renderMesh.Invoke(__instance);
			if (!((Object)(object)val == (Object)null))
			{
				_lods.RemoveAll((Lod l) => (Object)(object)l.Map == (Object)null || (Object)(object)l.Map == (Object)(object)__instance);
				Lod lod = new Lod
				{
					Map = __instance,
					Mesh = val,
					Original = val.vertices,
					Changed = true
				};
				lod.Work = (Vector3[])lod.Original.Clone();
				_lods.Add(lod);
				if (!float.IsNaN(_last.x))
				{
					Apply(lod, _last);
				}
			}
		}

		public static string DescribeAt(float x, float z)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			foreach (Lod lod in _lods)
			{
				if ((Object)(object)lod.Map == (Object)null || (Object)(object)lod.Mesh == (Object)null)
				{
					continue;
				}
				Vector3 position = ((Component)lod.Map).transform.position;
				int num = -1;
				float num2 = float.MaxValue;
				for (int i = 0; i < lod.Original.Length; i++)
				{
					float num3 = lod.Original[i].x + position.x - x;
					float num4 = lod.Original[i].z + position.z - z;
					float num5 = num3 * num3 + num4 * num4;
					if (num5 < num2)
					{
						num2 = num5;
						num = i;
					}
				}
				if (num >= 0 && !(num2 > 225f))
				{
					MeshRenderer component = ((Component)lod.Map).GetComponent<MeshRenderer>();
					stringBuilder.Append($"distant terrain {((Object)lod.Map).name}: vertex {Mathf.Sqrt(num2):0.0} m away, height {lod.Original[num].y + position.y:0.0} -> now {lod.Work[num].y + position.y:0.0}" + string.Format(" (inside voxel ground {0:0} m), renderer {1}; ", Inside(x, z), ((Object)(object)component == (Object)null) ? "none" : ((((Renderer)component).enabled && !((Renderer)component).forceRenderingOff) ? "drawn" : "off")));
				}
			}
			if (stringBuilder.Length <= 0)
			{
				return "no distant terrain vertex within 15 m";
			}
			return stringBuilder.ToString();
		}

		public static void SetCovered(IEnumerable<VoxelZone> zones)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			_coveredNow.Clear();
			foreach (VoxelZone zone in zones)
			{
				if (zone.Ready)
				{
					_coveredNow.Add(zone.Zone);
				}
			}
			if (!_coveredNow.SetEquals(_covered))
			{
				_covered.Clear();
				_covered.UnionWith(_coveredNow);
				_last = new Vector3(float.NaN, 0f, 0f);
			}
		}

		public static void Update(Camera cam)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			if ((Object)(object)cam == (Object)null || _lods.Count == 0 || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return;
			}
			if (float.IsNaN(_last.x))
			{
				_last = Vector3.zero;
				_lods.RemoveAll((Lod l) => (Object)(object)l.Map == (Object)null || (Object)(object)l.Mesh == (Object)null || (Object)(object)_renderMesh.Invoke(l.Map) != (Object)(object)l.Mesh);
				foreach (Lod lod2 in _lods)
				{
					lod2.Dirty = true;
				}
			}
			for (int num = 0; num < _lods.Count; num++)
			{
				_rr = (_rr + 1) % _lods.Count;
				Lod lod = _lods[_rr];
				if (lod.Dirty)
				{
					lod.Dirty = false;
					if (!((Object)(object)lod.Map == (Object)null) && !((Object)(object)lod.Mesh == (Object)null) && !((Object)(object)_renderMesh.Invoke(lod.Map) != (Object)(object)lod.Mesh))
					{
						Apply(lod, _last);
						break;
					}
				}
			}
		}

		public static bool Verify(Vector3 p, float radius)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00c0: 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)
			bool result = false;
			float num = radius * radius;
			foreach (Lod lod in _lods)
			{
				if ((Object)(object)lod.Map == (Object)null || (Object)(object)lod.Mesh == (Object)null || lod.Dirty || (Object)(object)_renderMesh.Invoke(lod.Map) != (Object)(object)lod.Mesh)
				{
					continue;
				}
				Vector3 position = ((Component)lod.Map).transform.position;
				for (int i = 0; i < lod.Original.Length; i++)
				{
					float num2 = lod.Original[i].x + position.x;
					float num3 = lod.Original[i].z + position.z;
					float num4 = num2 - p.x;
					float num5 = num3 - p.z;
					if (!(num4 * num4 + num5 * num5 > num) && Covered(num2, num3) && DropAt(Inside(num2, num3)) > 1f && lod.Work[i].y >= lod.Original[i].y - 0.01f)
					{
						lod.Dirty = true;
						result = true;
						break;
					}
				}
			}
			return result;
		}

		private static bool Covered(float x, float z)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return _covered.Contains(ZoneSystem.GetZone(new Vector3(x, 0f, z)));
		}

		private static float Inside(float x, float z)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0033: 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_004a: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Vector2s zone = ZoneSystem.GetZone(new Vector3(x, 0f, z));
			if (!_covered.Contains(zone))
			{
				return 0f;
			}
			Vector3 zonePos = ZoneSystem.GetZonePos(zone);
			float num = 32f;
			float num2 = x - (zonePos.x - num);
			float num3 = zonePos.x + num - x;
			float num4 = z - (zonePos.z - num);
			float num5 = zonePos.z + num - z;
			float num6 = 32f;
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					if ((j != 0 || i != 0) && !_covered.Contains(new Vector2s(zone.x + j, zone.y + i)))
					{
						float num7 = ((j < 0) ? num2 : ((j > 0) ? num3 : 0f));
						float num8 = ((i < 0) ? num4 : ((i > 0) ? num5 : 0f));
						num6 = Mathf.Min(num6, Mathf.Sqrt(num7 * num7 + num8 * num8));
					}
				}
			}
			return num6;
		}

		private static float DropAt(float inside)
		{
			if (inside <= 2f)
			{
				return 0f;
			}
			if (inside < 16f)
			{
				float num = (inside - 2f) / 14f;
				return 12f * num * num * (3f - 2f * num);
			}
			if (inside < 32f)
			{
				float num2 = (inside - 16f) / 16f;
				return 12f + 588f * num2 * num2 * (3f - 2f * num2);
			}
			return 600f;
		}

		private static void Apply(Lod l, Vector3 cam)
		{
			//IL_000b: 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)
			//IL_001e: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)l.Map).transform.position;
			bool flag = _covered.Count > 0 && !float.IsNaN(cam.x) && cam.x < 1000000f;
			if (!flag && !l.Changed)
			{
				return;
			}
			bool changed = false;
			for (int i = 0; i < l.Original.Length; i++)
			{
				Vector3 val = l.Original[i];
				if (flag)
				{
					float x = val.x + position.x;
					float z = val.z + position.z;
					if (Covered(x, z))
					{
						float num = DropAt(Inside(x, z));
						if (num > 0f)
						{
							val.y -= num;
							changed = true;
						}
					}
				}
				l.Work[i] = val;
			}
			l.Mesh.vertices = l.Work;
			l.Mesh.RecalculateBounds();
			l.Changed = changed;
		}
	}
	[BepInPlugin("moxy.voxelterrain", "VoxelTerrain", "0.27.53")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private struct ModSnap
		{
			public Vector3 Pos;

			public bool Level;

			public bool Smooth;

			public bool Paint;

			public bool Square;

			public bool Player;

			public bool HeightCheck;

			public float LevelOffset;

			public float LevelRadius;

			public float SmoothRadius;

			public float SmoothPower;

			public float PaintRadius;

			public float Strength;

			public PaintType Type;
		}

		private sealed class OwnZone
		{
			public float[] Heights;

			public Color32[] Paint;

			public Color32[] Colors;

			public uint Revision;

			public bool Complete;
		}

		private sealed class GroundJob
		{
			public uint Rev;

			public bool Loaded;

			public volatile bool Done;

			public OwnZone Result;

			public float Started;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static LogCallback <0>__PhysxLog;
		}

		private static readonly MethodInfo _hmBuild = AccessTools.Method(typeof(HeightmapBuilder), "Build", (Type[])null, (Type[])null);

		private static readonly FieldRef<Heightmap, List<float>> _hmHeights = AccessTools.FieldRefAccess<Heightmap, List<float>>("m_heights");

		private readonly Dictionary<Vector2s, OwnZone> _ownZones = new Dictionary<Vector2s, OwnZone>();

		private Vector2s? _ownTarget;

		private static readonly FieldRef<ZDOMan, List<ZDO>[]> _bySector = AccessTools.FieldRefAccess<ZDOMan, List<ZDO>[]>("m_objectsBySector");

		private OwnZone _ownTargetData;

		private readonly Queue<Vector2s> _ownOrder = new Queue<Vector2s>();

		private const int OwnZoneMax = 400;

		private readonly Dictionary<Vector2s, Heightmap> _nbHm = new Dictionary<Vector2s, Heightmap>();

		private readonly List<Vector2s> _pruneBuf = new List<Vector2s>();

		private readonly Dictionary<Vector2s, GroundJob> _groundJobs = new Dictionary<Vector2s, GroundJob>();

		internal static volatile bool GroundJobDone;

		private static readonly HashSet<Vector2s> _paintFollow = new HashSet<Vector2s>();

		private static float _paintFollowAt;

		private static readonly List<Vector4> _grassAfterPaint = new List<Vector4>();

		internal static int GroundClears;

		internal static int GroundSync;

		internal static int VanillaRegens;

		internal static int VanillaRegensLast;

		private static readonly HashSet<Heightmap> _noMesh = new HashSet<Heightmap>();

		private static int _meshesSkipped;

		private static readonly List<Heightmap> _restore = new List<Heightmap>();

		private int _restored;

		public const string Guid = "moxy.voxelterrain";

		public const string Version = "0.27.53";

		internal static ManualLogSource Log;

		private static Plugin _self;

		private ConfigEntry<KeyboardShortcut> _caveDebugKey;

		private static ConfigEntry<bool> _devMode;

		private static ConfigEntry<bool> _ownGround;

		private static ConfigEntry<bool> _checkOwnGround;

		private bool _pickMode;

		private bool _savedCapture;

		private static readonly FieldRef<GameCamera, bool> _mouseCapture = AccessTools.FieldRefAccess<GameCamera, bool>("m_mouseCapture");

		private ConfigEntry<KeyboardShortcut> _revertKey;

		private ConfigEntry<KeyboardShortcut> _wallLookKey;

		private ConfigEntry<KeyboardShortcut> _soilLookKey;

		private int _soilLook = -1;

		private float _nextStatsLog;

		private int _lastLoggedCalls;

		private int _wallLook;

		private Material _wallMatFixed;

		private ConfigEntry<float> _cellSize;

		private ConfigEntry<float> _digRadius;

		private ConfigEntry<float> _depthBelow;

		private ConfigEntry<float> _heightAbove;

		private ConfigEntry<float> _loadDistance;

		private ConfigEntry<string> _wallMaterial;

		private ConfigEntry<string> _soilMaterial;

		private ConfigEntry<float> _soilDepth;

		private ConfigEntry<float> _stonePerM3;

		private ConfigEntry<bool> _digScale;

		private string _lastPickaxe;

		private Material _soilMat;

		private bool _soilSearched;

		private ConfigEntry<bool> _showStatus;

		private readonly Dictionary<Vector2s, VoxelZone> _zones = new Dictionary<Vector2s, VoxelZone>();

		private readonly HashSet<Vector2s> _saved = new HashSet<Vector2s>();

		private readonly HashSet<Vector2s> _resetGrassFor = new HashSet<Vector2s>();

		private string _world;

		private float _nextScan;

		private Material _wallMat;

		private bool _wallMatSearched;

		private string _message;

		private float _messageUntil;

		private static FieldRef<Attack, Humanoid> _attackCharacter;

		private static FieldRef<Character, Rigidbody> _body = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body");

		private static int _rescues;

		private static FieldRef<Attack, ItemData> _attackWeapon;

		private readonly List<RaycastCommand> _visCmds = new List<RaycastCommand>();

		private readonly List<VoxelZone> _visZones = new List<VoxelZone>();

		private NativeArray<RaycastCommand> _visCmdArr;

		private NativeArray<RaycastHit> _visHitArr;

		private JobHandle _visJob;

		private bool _visPending;

		private bool _skipVis;

		private bool _visWaited;

		private int _visSkipped;

		private int _probeCount;

		private const int ProbeW = 96;

		private const int ProbeH = 54;

		private int _probeIndex;

		private int _probeMask;

		private Vector3 _visPos = new Vector3(float.NaN, 0f, 0f);

		private Quaternion _visRot;

		private float _visSettleUntil;

		private readonly List<VoxelZone> _zoneOrder = new List<VoxelZone>();

		private Vector3 _sortFrom;

		private Comparison<VoxelZone> _byEdgeDistance;

		private readonly List<Vector2s> _scanDrop = new List<Vector2s>();

		private readonly List<(float, Vector2s)> _scanCandidates = new List<(float, Vector2s)>();

		private readonly Dictionary<Vector2s, VoxelZone> _warm = new Dictionary<Vector2s, VoxelZone>();

		private readonly List<Vector2s> _warmOrder = new List<Vector2s>();

		private static ConfigEntry<int> _warmZones;

		private static readonly double[] _scanMs = new double[5];

		private static readonly int[] _scanN = new int[5];

		private static readonly string[] ScanNames = new string[5] { "put away", "brought back", "evicted", "created", "destroyed" };

		private static readonly double[] _attachMs = new double[6];

		private static readonly int[] _attachN = new int[6];

		private static readonly string[] AttachNames = new string[6] { "margin syncs", "heightmap lookups", "attaches", "water hide / clip", "provisional checks", "sort" };

		private readonly Dictionary<Vector2s, VoxelZone> _replacing = new Dictionary<Vector2s, VoxelZone>();

		private const int ColliderZones = 3;

		private readonly List<(float, Vector2s)> _dropOrder = new List<(float, Vector2s)>();

		private readonly List<(float, Vector2s)> _unparkBuf = new List<(float, Vector2s)>();

		private const int UnparkMargin = 6;

		private static ConfigEntry<int> _maxZones;

		private const double ScanBudgetMs = 3.0;

		private bool _createWaited;

		private int _createDeferred;

		private bool _worldMode;

		private static ConfigEntry<float> _activeDistance;

		private static ConfigEntry<double> _meshBudget;

		private static ConfigEntry<float> _hoeStamina;

		private static ConfigEntry<float> _cultivatorStamina;

		private static ConfigEntry<float> _hammerStamina;

		private readonly Dictionary<Vector2s, float> _areaReadySince = new Dictionary<Vector2s, float>();

		private static readonly List<ZDO> _zoneZdos = new List<ZDO>();

		private readonly List<Vector2s> _rebuild = new List<Vector2s>();

		private float _nextProvisionalCheck;

		private static readonly FieldRef<LocationProxy, bool> _locationNeedsSpawn = AccessTools.FieldRefAccess<LocationProxy, bool>("m_locationNeedsSpawn");

		private readonly Dictionary<Vector2s, float[]> _provisional = new Dictionary<Vector2s, float[]>();

		private readonly List<(string Label, Material Mat)> _looks = new List<(string, Material)>();

		private readonly List<MeshRenderer> _undergroundHidden = new List<MeshRenderer>();

		private float _nextWaterDiag;

		private readonly HashSet<string> _waterDiagSeen = new HashSet<string>();

		private static readonly FieldRef<WaterVolume, float[]> _wvDepth = AccessTools.FieldRefAccess<WaterVolume, float[]>("m_normalizedDepth");

		private static int _giCalls;

		private static int _giMiss;

		private static int _giOther;

		private static int _giFlipped;

		private static int _giOk;

		private static string _giOtherName = "-";

		private static int _giSteep;

		private static int _giTilt20;

		private static int _giCleared;

		private static int _giNoBiome;

		private static int _vCalls;

		private static int _vOk;

		private static int _vTilt20;

		private static int _vSteep;

		private static int _vCleared;

		private static bool _inVoxelProbe;

		private static double _giVegSum;

		private static double _giAltSum;

		private bool _holding;

		private Vector3 _holdPos;

		private float _holdStart;

		private Vector3? _caveLogout;

		private float _caveLogoutUntil;

		private bool _forceHold;

		internal static bool LoadingHold;

		private float _loadingHoldStart;

		private bool _wasTeleporting;

		private static readonly FieldRef<Player, bool> _teleportingRef = AccessTools.FieldRefAccess<Player, bool>("m_teleporting");

		private static Vector3? _logoutBefore;

		private static float _spawnWaitStart = -1f;

		private const string WallPieceName = "voxel_level_wall";

		private static GameObject _wallPiece;

		private static GameObject _wallHolder;

		private const float WallRadius = 2f;

		private static PieceTable _hoeTable;

		private static readonly FieldRef<Player, HashSet<string>> _knownRecipes = AccessTools.FieldRefAccess<Player, HashSet<string>>("m_knownRecipes");

		private static readonly HashSet<PieceTable> _tablesSeen = new HashSet<PieceTable>();

		private static readonly FieldRef<Player, int> _placeRotation = AccessTools.FieldRefAccess<Player, int>("m_placeRotation");

		private static readonly FieldRef<Player, float> _placeRotationDeg = AccessTools.FieldRefAccess<Player, float>("m_placeRotationDegrees");

		private static readonly FieldRef<Player, GameObject> _marker = AccessTools.FieldRefAccess<Player, GameObject>("m_placementMarkerInstance");

		private static readonly FieldRef<Player, GameObject> _ghost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private static GameObject _planeGhost;

		private static Vector3 _planeUp;

		private static int _planeFrame;

		private static CircleProjector _slicesHidden;

		private static GameObject _planeMarker;

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

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

		private static readonly FieldRef<CircleProjector, List<GameObject>> _segments = AccessTools.FieldRefAccess<CircleProjector, List<GameObject>>("m_segments");

		private static readonly FieldRef<Humanoid, ItemData> _rightItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem");

		private static readonly FieldRef<Character, ZSyncAnimation> _zanimRef = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		private readonly List<VoxelZone> _nb = new List<VoxelZone>();

		private static Action<WearNTear, long> _clearSupport;

		internal static long WearHeld;

		private static readonly HashSet<WearNTear> _held = new HashSet<WearNTear>();

		private static readonly List<WearNTear> _release = new List<WearNTear>();

		private static List<WearNTear> _heldScan;

		private static int _heldScanAt;

		internal static long HeldReleased;

		private static readonly Collider[] _areaHits = (Collider[])(object)new Collider[1024];

		private static readonly HashSet<WearNTear> _areaSeen = new HashSet<WearNTear>();

		private static int _areaMask;

		internal static long AreaTold;

		private static readonly List<WearNTear> _notifyList = new List<WearNTear>();

		private static readonly RaycastHit[] _ghHits = (RaycastHit[])(object)new RaycastHit[16];

		private static int _placeMask;

		private static int _waterLayers;

		private static int _passLayers;

		private static int _rescueMask;

		private static int _rescued;

		private float _nextRescue;

		private static readonly string[] LapNames = new string[13]
		{
			"underground water", "rescue + sea depth", "zone scan", "cave visibility", "meshing jobs", "retire + merge + paint", "distant terrain", "game terrain restore", "net + export + input + holds", "ray results + screen probes",
			"zone attach + sort", "zone upkeep (borders, colliders, detail, swaps)", "ray batch schedule"
		};

		private const int Laps = 13;

		private readonly double[] _lapSum = new double[13];

		private readonly Stopwatch _lapWatch = new Stopwatch();

		private int _lapFrames;

		private float _nextLapLog;

		private readonly double[] _lapFrame = new double[13];

		private readonly double[] _lapWorst = new double[13];

		private readonly double[] _lapWorstNoGc = new double[13];

		private double _worstFrame;

		private double _worstNoGcFrame;

		private string _worstMeshing = "";

		private string _worstNoGcMeshing = "";

		private string _worstNoGcScan = "";

		private string _worstAttach = "";

		private string _worstNoGcAttach = "";

		private double _avgFrameMs;

		private int _gcFrames;

		private double _gcExcessSum;

		private double _gcExcessMax;

		private int _createFrames;

		private int _createOverlap;

		private int _gcLast;

		private int _gcWindow;

		private long _monoLast;

		private long _allocWindow;

		private bool _worstGc;

		private string _worstScan = "";

		private readonly long[] _lapAlloc = new long[13];

		private long _lapHeap;

		private readonly Dictionary<VoxelZone, (long R, long G, long C)> _memOf = new Dictionary<VoxelZone, (long, long, long)>();

		private readonly List<VoxelZone> _memDead = new List<VoxelZone>();

		private readonly List<VoxelZone> _memQueue = new List<VoxelZone>();

		private int _memNext;

		private int _memAt;

		private long _memR;

		private long _memG;

		private long _memC;

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

		private static int _rescuesWindow;

		private static int _rescueRepeats;

		private static int _physxFails;

		private static int _physxLogged;

		[ThreadStatic]
		private static bool t_inPhysxLog;

		private static readonly FieldRef<List<Heightmap>> _allHeightmaps = AccessTools.StaticFieldRefAccess<List<Heightmap>>(AccessTools.Field(typeof(Heightmap), "s_heightmaps"));

		private float _nextSelfCheck;

		private int _selfFixGround;

		private int _selfFixSheet;

		private static ConfigEntry<KeyboardShortcut> _partsViewKey;

		private bool _partsView;

		private float _nextPartsView;

		private static Material[] _partsViewMats;

		private static readonly FieldRef<List<ItemDrop>> _itemDrops = AccessTools.StaticFieldRefAccess<List<ItemDrop>>(AccessTools.Field(typeof(ItemDrop), "s_instances"));

		private Vector2s _urgent = new Vector2s(short.MinValue, short.MinValue);

		private float _looseStoneDebt;

		private GUIStyle _style;

		private string _statusText;

		private float _statusAt;

		private const int TerrainFileVersion = 1;

		private static readonly FieldRef<ZDOMan, Dictionary<ZDOID, ZDO>> _zdosById = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID");

		private int _compilerPrefab;

		private readonly Dictionary<Vector2s, uint> _exported = new Dictionary<Vector2s, uint>();

		private bool _exportDone;

		private float _nextExport;

		private readonly List<(Vector2s, Heightmap)> _ownCheck = new List<(Vector2s, Heightmap)>();

		private readonly HashSet<Vector2s> _exportNear = new HashSet<Vector2s>();

		private readonly List<ZDO> _exportBuf = new List<ZDO>();

		private const int NetProtocol = 1;

		private const int ZoneChunk = 512;

		private bool _remote;

		private ZRoutedRpc _rpcFor;

		private readonly Dictionary<Vector2s, List<VoxelEdit>> _remoteEdits = new Dictionary<Vector2s, List<VoxelEdit>>();

		private readonly Dictionary<Vector2s, float> _zoneRequested = new Dictionary<Vector2s, float>();

		private readonly Dictionary<Vector2s, List<VoxelEdit>> _incoming = new Dictionary<Vector2s, List<VoxelEdit>>();

		private readonly Dictionary<Vector2s, int> _incomingTotal = new Dictionary<Vector2s, int>();

		private readonly Dictionary<Vector2s, List<(int Seq, VoxelEdit Edit)>> _early = new Dictionary<Vector2s, List<(int, VoxelEdit)>>();

		private bool _indexReceived;

		private float _nextIndexRequest;

		private readonly Dictionary<Vector2s, int> _serverCount = new Dictionary<Vector2s, int>();

		private readonly Dictionary<Vector2s, (byte[] Data, uint Revision)> _remoteTerrain = new Dictionary<Vector2s, (byte[], uint)>();

		private readonly Dictionary<Vector2s, float> _terrainRequested = new Dictionary<Vector2s, float>();

		private int OwnZoneCount => _ownZones.Count;

		internal static bool PickMode
		{
			get
			{
				if ((Object)(object)_self != (Object)null)
				{
					return _self._pickMode;
				}
				return false;
			}
		}

		private bool OwnPath
		{
			get
			{
				if (_ownGround.Value && HeightmapBuilder.instance != null)
				{
					return WorldGenerator.instance != null;
				}
				return false;
			}
		}

		private static float WaterLevel
		{
			get
			{
				if (!((Object)(object)ZoneSystem.instance != (Object)null))
				{
					return 30f;
				}
				return ZoneSystem.instance.m_waterLevel;
			}
		}

		private bool LoadTerrainEdits(Vector2s id, out float[] level, out float[] smooth)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			bool[] painted;
			Color[] paint;
			return LoadTerrainEdits(id, out level, out smooth, out painted, out paint);
		}

		private bool LoadTerrainEdits(Vector2s id, out float[] level, out float[] smooth, out bool[] painted, out Color[] paint)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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)
			uint revision;
			byte[] array = LiveTerrainData(id, out revision);
			return DecodeTerrainEdits(id, array, (array == null) ? TerrainFile(id) : null, out level, out smooth, out painted, out paint);
		}

		private static bool DecodeTerrainEdits(Vector2s id, byte[] data, string file, out float[] level, out float[] smooth, out bool[] painted, out Color[] paint)
		{
			//IL_017e: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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)
			level = (smooth = null);
			painted = null;
			paint = null;
			try
			{
				if (data == null)
				{
					if (file == null || !File.Exists(file))
					{
						return false;
					}
					using BinaryReader binaryReader = new BinaryReader(File.OpenRead(file));
					if (binaryReader.ReadInt32() != 1129600086 || binaryReader.ReadInt32() != 1)
					{
						return false;
					}
					binaryReader.ReadUInt32();
					binaryReader.ReadSingle();
					binaryReader.ReadSingle();
					binaryReader.ReadSingle();
					data = binaryReader.ReadBytes(binaryReader.ReadInt32());
				}
				ZPackage val = new ZPackage(Utils.Decompress(data));
				val.ReadInt();
				val.ReadInt();
				val.ReadVector3();
				val.ReadSingle();
				int num = val.ReadInt();
				level = new float[num];
				smooth = new float[num];
				for (int i = 0; i < num; i++)
				{
					if (val.ReadBool())
					{
						level[i] = val.ReadSingle();
						smooth[i] = val.ReadSingle();
					}
				}
				int num2 = val.ReadInt();
				painted = new bool[num2];
				paint = (Color[])(object)new Color[num2];
				for (int j = 0; j < num2; j++)
				{
					bool flag;
					painted[j] = (flag = val.ReadBool());
					if (flag)
					{
						paint[j] = new Color(val.ReadSingle(), val.ReadSingle(), val.ReadSingle(), val.ReadSingle());
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)$"Terrain edits {id.x},{id.y}: {ex.Message}");
				return false;
			}
		}

		private float[] ComputeGround(Vector2s id, Vector3 center, int width, float scale, out int modifiers, out bool edits)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Color32[] paint;
			Color32[] colors;
			return ComputeGround(id, center, width, scale, out modifiers, out edits, out paint, out colors);
		}

		private float[] ComputeGround(Vector2s id, Vector3 center, int width, float scale, out int modifiers, out bool edits, out Color32[] paint, out Color32[] colors)
		{
			//IL_0000: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			List<ModSnap> mods = SnapModifiers(center, (float)width * scale * 0.5f);
			uint revision;
			byte[] array = LiveTerrainData(id, out revision);
			return ComputeGroundCore(id, center, width, scale, mods, array, (array == null) ? TerrainFile(id) : null, HeightmapBuilder.instance, WorldGenerator.instance, out modifiers, out edits, out paint, out colors);
		}

		private static List<ModSnap> SnapModifiers(Vector3 center, float half)
		{
			//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_004f: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b3: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			List<ModSnap> list = new List<ModSnap>();
			foreach (TerrainModifier allInstance in TerrainModifier.GetAllInstances())
			{
				if (!((Object)(object)allInstance == (Object)null) && ((Behaviour)allInstance).enabled)
				{
					Vector3 position = ((Component)allInstance).transform.position;
					float num = allInstance.GetRadius() + 4f;
					if (!(position.x + num < center.x - half) && !(position.x - num > center.x + half) && !(position.z + num < center.z - half) && !(position.z - num > center.z + half))
					{
						list.Add(new ModSnap
						{
							Pos = position,
							Level = allInstance.m_level,
							Smooth = allInstance.m_smooth,
							Paint = allInstance.m_paintCleared,
							Square = allInstance.m_square,
							Player = allInstance.m_playerModifiction,
							HeightCheck = allInstance.m_paintHeightCheck,
							LevelOffset = allInstance.m_levelOffset,
							LevelRadius = allInstance.m_levelRadius,
							SmoothRadius = allInstance.m_smoothRadius,
							SmoothPower = allInstance.m_smoothPower,
							PaintRadius = allInstance.m_paintRadius,
							Strength = allInstance.m_paintStrength,
							Type = allInstance.m_paintType
						});
					}
				}
			}
			return list;
		}

		private static float[] ComputeGroundCore(Vector2s id, Vector3 center, int width, float scale, List<ModSnap> mods, byte[] tc, string tcFile, HeightmapBuilder builder, WorldGenerator gen, out int modifiers, out bool edits, out Color32[] paint, out Color32[] colors)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: 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)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			modifiers = 0;
			edits = false;
			PackedMesh.Count(((long)width + 1L) * ((long)width + 1L) * 72);
			HMBuildData val = new HMBuildData(center, width, scale, false, gen);
			_hmBuild.Invoke(builder, new object[1] { val });
			int num = width + 1;
			float[] array = val.m_baseHeights.ToArray();
			Color32[] array2 = (Color32[])(object)new Color32[num * num];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = Color32.op_Implicit(val.m_baseMask[i]);
			}
			colors = VertexColors(val.m_cornerBiomes, width);
			float[] array3 = null;
			float[] levelOnly = null;
			foreach (ModSnap mod in mods)
			{
				Vector3 pos = mod.Pos;
				if (mod.Player && array3 == null)
				{
					array3 = (float[])array.Clone();
					levelOnly = (float[])array.Clone();
				}
				if (mod.Level)
				{
					Level(array, num, center, scale, pos + Vector3.up * mod.LevelOffset, mod.LevelRadius, mod.Square, array3, levelOnly, mod.Player);
				}
				if (mod.Smooth)
				{
					Smooth(array, num, center, scale, pos + Vector3.up * mod.LevelOffset, mod.SmoothRadius, levelOnly, mod.SmoothPower, mod.Player);
				}
				if (mod.Paint)
				{
					PaintMask(array2, array, num, center, scale, pos, mod.PaintRadius, mod.Type, mod.HeightCheck, mod.Strength);
				}
				modifiers++;
			}
			paint = array2;
			if (DecodeTerrainEdits(id, tc, tcFile, out var level, out var smooth, out var painted, out var paint2) && level.Length == array.Length)
			{
				if (painted != null && painted.Length == array2.Length)
				{
					for (int j = 0; j < array2.Length; j++)
					{
						if (painted[j])
						{
							array2[j] = Color32.op_Implicit(paint2[j]);
						}
					}
				}
				edits = true;
				if (array3 == null)
				{
					array3 = (float[])array.Clone();
				}
				for (int k = 0; k < array.Length; k++)
				{
					if (level[k] != 0f || smooth[k] != 0f)
					{
						array[k] = Mathf.Clamp(array[k] + level[k] + smooth[k], array3[k] - 8f, array3[k] + 8f);
					}
				}
			}
			return array;
		}

		private static Color32[] VertexColors(BiomeSector[] corners, int width)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00ad: 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_00b4: 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_00bf: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			int num = width + 1;
			Color32[] array = (Color32[])(object)new Color32[num * num];
			bool flag = corners[0] == corners[1] && corners[0] == corners[2] && corners[0] == corners[3];
			Color32 biomeColor = Heightmap.GetBiomeColor(corners[0]);
			Color32 biomeColor2 = Heightmap.GetBiomeColor(corners[1]);
			Color32 biomeColor3 = Heightmap.GetBiomeColor(corners[2]);
			Color32 biomeColor4 = Heightmap.GetBiomeColor(corners[3]);
			for (int i = 0; i < num; i++)
			{
				float num2 = DUtils.SmoothStep(0f, 1f, (float)((double)i / (double)width));
				for (int j = 0; j < num; j++)
				{
					if (flag)
					{
						array[i * num + j] = biomeColor;
						continue;
					}
					float num3 = DUtils.SmoothStep(0f, 1f, (float)((double)j / (double)width));
					array[i * num + j] = Color32.Lerp(Color32.Lerp(biomeColor, biomeColor2, num3), Color32.Lerp(biomeColor3, biomeColor4, num3), num2);
				}
			}
			return array;
		}

		internal static void PaintMask(Color32[] mask, float[] h, int pitch, Vector3 center, float scale, Vector3 worldPos, float radius, PaintType type, bool heightCheck, float strength)
		{
			//IL_0024: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected I4, but got Unknown
			//IL_0148: 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_0151: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Invalid comparison between Unknown and I4
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			int num = pitch - 1;
			worldPos.x -= 0.5f;
			worldPos.z -= 0.5f;
			float num2 = worldPos.y - center.y;
			Vector3 val = worldPos - center;
			int num3 = (num + 1) / 2;
			int num4 = Mathf.FloorToInt(val.x / scale + 0.5f + (float)num3);
			int num5 = Mathf.FloorToInt(val.z / scale + 0.5f + (float)num3);
			float num6 = radius / scale;
			int num7 = Mathf.CeilToInt(num6);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num4, (float)num5);
			for (int i = num5 - num7; i <= num5 + num7; i++)
			{
				for (int j = num4 - num7; j <= num4 + num7; j++)
				{
					if (j >= 0 && i >= 0 && j < pitch && i < pitch && (!heightCheck || !(h[i * pitch + j] > num2)))
					{
						float num8 = 1f - Mathf.Clamp01(Vector2.Distance(val2, new Vector2((float)j, (float)i)) / num6);
						num8 = Mathf.Pow(num8, 0.1f) * strength;
						Color val3 = Color32.op_Implicit(mask[i * pitch + j]);
						float a = val3.a;
						switch ((int)type)
						{
						case 0:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskDirt, num8);
							break;
						case 1:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskCultivated, num8);
							break;
						case 2:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskPaved, num8);
							break;
						case 3:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskNothing, num8);
							break;
						case 4:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskClearVegetation, num8);
							break;
						case 5:
							val3 = Color.Lerp(val3, Heightmap.m_paintMaskDeepSnow, num8);
							break;
						}
						if ((int)type != 4)
						{
							val3.a = a;
						}
						mask[i * pitch + j] = Color32.op_Implicit(val3);
					}
				}
			}
		}

		private static void Level(float[] h, int pitch, Vector3 center, float scale, Vector3 worldPos, float radius, bool square, float[] baseH, float[] levelOnly, bool player)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			int num = pitch - 1;
			Vector3 val = worldPos - center;
			int num2 = (num + 1) / 2;
			int num3 = Mathf.FloorToInt(val.x / scale + 0.5f + (float)num2);
			int num4 = Mathf.FloorToInt(val.z / scale + 0.5f + (float)num2);
			float num5 = (float)((double)radius / (double)scale);
			int num6 = Mathf.CeilToInt(num5);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num3, (float)num4);
			for (int i = num4 - num6; i <= num4 + num6; i++)
			{
				for (int j = num3 - num6; j <= num3 + num6; j++)
				{
					if ((square || !(Vector2.Distance(val2, new Vector2((float)j, (float)i)) > num5)) && j >= 0 && i >= 0 && j < pitch && i < pitch)
					{
						float num7 = val.y;
						if (player)
						{
							float num8 = baseH[i * pitch + j];
							num7 = (levelOnly[i * pitch + j] = Mathf.Clamp(num7, (float)((double)num8 - 8.0), (float)((double)num8 + 8.0)));
						}
						h[i * pitch + j] = num7;
					}
				}
			}
		}

		private static void Smooth(float[] h, int pitch, Vector3 center, float scale, Vector3 worldPos, float radius, float[] levelOnly, float power, bool player)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			int num = pitch - 1;
			Vector3 val = worldPos - center;
			int num2 = num / 2;
			int num3 = Mathf.FloorToInt(val.x / scale + 0.5f) + num2;
			int num4 = Mathf.FloorToInt(val.z / scale + 0.5f) + num2;
			float num5 = (float)(double)(worldPos.y - center.y);
			float num6 = radius / scale;
			int num7 = Mathf.CeilToInt(num6);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num3, (float)num4);
			for (int i = num4 - num7; i <= num4 + num7; i++)
			{
				for (int j = num3 - num7; j <= num3 + num7; j++)
				{
					float num8 = Vector2.Distance(val2, new Vector2((float)j, (float)i));
					if (!(num8 > num6) && j >= 0 && i >= 0 && j < pitch && i < pitch)
					{
						float num9 = num8 / num6;
						num9 = ((power != 3f) ? Mathf.Pow(num9, power) : ((float)((double)num9 * (double)num9 * (double)num9)));
						float num10 = DUtils.Lerp(h[i * pitch + j], num5, (float)(1.0 - (double)num9));
						if (player)
						{
							float num11 = levelOnly[i * pitch + j];
							num10 = Mathf.Clamp(num10, (float)((double)num11 - 1.0), (float)((double)num11 + 1.0));
						}
						h[i * pitch + j] = num10;
					}
				}
			}
		}

		private byte[] LiveTerrainData(Vector2s id, out uint revision)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = LocalTerrainData(id, out revision);
			if (array != null || !_remote)
			{
				return array;
			}
			if (_remoteTerrain.TryGetValue(id, out (byte[], uint) value))
			{
				revision = value.Item2;
				return value.Item1;
			}
			return null;
		}

		private byte[] LocalTerrainData(Vector2s id, out uint revision)
		{
			//IL_0079: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			revision = 0u;
			if (_compilerPrefab == 0)
			{
				ZoneSystem instance = ZoneSystem.instance;
				Heightmap val = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_zonePrefab != (Object)null) ? instance.m_zonePrefab.GetComponentInChildren<Heightmap>() : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val.m_terrainCompilerPrefab != (Object)null)
				{
					_compilerPrefab = StringExtensionMethods.GetStableHashCode(((Object)val.m_terrainCompilerPrefab).name);
				}
			}
			if (ZDOMan.instance == null || _compilerPrefab == 0)
			{
				return null;
			}
			TerrainComp val2 = TerrainComp.FindTerrainCompiler(ZoneSystem.GetZonePos(id));
			object obj;
			if (!((Object)(object)val2 != (Object)null))
			{
				obj = null;
			}
			else
			{
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				obj = ((component != null) ? component.GetZDO() : null);
			}
			ZDO val3 = (ZDO)obj;
			if (val3 != null && ZoneSystem.GetZone(val3.GetPosition()) == id)
			{
				revision = val3.DataRevision;
				return val3.GetByteArray(ZDOVars.s_TCData, (byte[])null);
			}
			ZDO val4 = CompilerZdo(id);
			if (val4 == null)
			{
				return null;
			}
			revision = val4.DataRevision;
			return val4.GetByteArray(ZDOVars.s_TCData, (byte[])null);
		}

		private ZDO CompilerZdo(Vector2s id)
		{
			//IL_0028: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO>[] array = ((ZDOMan.instance != null) ? _bySector.Invoke(ZDOMan.instance) : null);
			if (array == null || _compilerPrefab == 0)
			{
				return null;
			}
			uint sector = ZoneSystem.SectorToIndex(id).Sector;
			if (sector == 0 || sector >= array.Length)
			{
				return null;
			}
			List<ZDO> list = array[sector];
			if (list == null)
			{
				return null;
			}
			for (int i = 0; i < list.Count; i++)
			{
				ZDO val = list[i];
				if (val != null && val.GetPrefab() == _compilerPrefab && ZoneSystem.GetZone(val.GetPosition()) == id)
				{
					return val;
				}
			}
			return null;
		}

		private float OwnHeight(int wx, int wz)
		{
			//IL_0009: 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)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_015f: 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_0069: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00cd: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			Vector2s zone = ZoneSystem.GetZone(new Vector3((float)wx, 0f, (float)wz));
			Vector3 zonePos = ZoneSystem.GetZonePos(zone);
			int num = 32;
			int num2 = 65;
			int num3 = Mathf.Clamp(wx - ((int)zonePos.x - num), 0, num2 - 1);
			int num4 = Mathf.Clamp(wz - ((int)zonePos.z - num), 0, num2 - 1);
			if (_ownTarget.HasValue)
			{
				if (zone.x == _ownTarget.Value.x && zone.y == _ownTarget.Value.y && _ownTargetData != null)
				{
					return _ownTargetData.Heights[num4 * num2 + num3];
				}
				if (zone.x != _ownTarget.Value.x || zone.y != _ownTarget.Value.y)
				{
					if (_ownZones.TryGetValue(zone, out var value))
					{
						return value.Heights[num4 * num2 + num3];
					}
					if (!_nbHm.TryGetValue(zone, out var value2))
					{
						value2 = Heightmap.FindHeightmap(zonePos);
						if ((Object)(object)value2 != (Object)null && value2.IsDistantLod)
						{
							value2 = null;
						}
						_nbHm[zone] = value2;
					}
					float result = default(float);
					if ((Object)(object)value2 != (Object)null && value2.GetWorldHeight(new Vector3((float)wx, 0f, (float)wz), ref result))
					{
						return result;
					}
				}
			}
			return OwnZoneData(zone).Heights[num4 * num2 + num3];
		}

		private void StoreOwnZone(Vector2s id, OwnZone oz)
		{
			//IL_0006: 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_0014: 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_0047: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!_ownZones.ContainsKey(id))
			{
				_ownOrder.Enqueue(id);
			}
			_ownZones[id] = oz;
			int num = _ownOrder.Count;
			while (_ownZones.Count > 400 && num > 0)
			{
				Vector2s val = _ownOrder.Dequeue();
				if (_ownZones.ContainsKey(val))
				{
					if (_zones.ContainsKey(val) || ((Vector2s)(ref val)).Equals(id))
					{
						_ownOrder.Enqueue(val);
					}
					else
					{
						_ownZones.Remove(val);
						GroundClears++;
					}
				}
				num--;
			}
			if (_ownOrder.Count <= 1600)
			{
				return;
			}
			int count = _ownOrder.Count;
			for (int i = 0; i < count; i++)
			{
				Vector2s val2 = _ownOrder.Dequeue();
				if (_ownZones.ContainsKey(val2))
				{
					_ownOrder.Enqueue(val2);
				}
			}
		}

		private void PruneGroundJobs()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			_pruneBuf.Clear();
			foreach (KeyValuePair<Vector2s, GroundJob> groundJob in _groundJobs)
			{
				if (groundJob.Value.Done && unscaledTime - groundJob.Value.Started > 30f)
				{
					_pruneBuf.Add(groundJob.Key);
				}
			}
			foreach (Vector2s item in _pruneBuf)
			{
				_groundJobs.Remove(item);
			}
		}

		private OwnZone OwnZoneReady(Vector2s id)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			uint revision;
			byte[] tc = LiveTerrainData(id, out revision);
			bool flag = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.IsZoneLoaded(id);
			if (_ownZones.TryGetValue(id, out var value) && value.Revision == revision && (value.Complete || !flag))
			{
				return value;
			}
			if (_groundJobs.TryGetValue(id, out var value2))
			{
				if (!value2.Done)
				{
					return null;
				}
				_groundJobs.Remove(id);
				if (value2.Result == null)
				{
					return OwnZoneData(id);
				}
				if (value2.Rev == revision && (value2.Loaded || !flag))
				{
					StoreOwnZone(id, value2.Result);
					return value2.Result;
				}
			}
			Vector3 center = ZoneSystem.GetZonePos(id);
			int width = 64;
			List<ModSnap> mods = SnapModifiers(center, (float)width * 0.5f);
			string file = ((tc == null) ? TerrainFile(id) : null);
			HeightmapBuilder builder = HeightmapBuilder.instance;
			WorldGenerator gen = WorldGenerator.instance;
			value2 = new GroundJob
			{
				Rev = revision,
				Loaded = flag,
				Started = Time.unscaledTime
			};
			_groundJobs[id] = value2;
			GroundJob j = value2;
			ThreadPool.QueueUserWorkItem(delegate
			{
				//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)
				long start = PackedMesh.ThreadNow();
				try
				{
					int modifiers;
					bool edits;
					Color32[] paint;
					Color32[] colors;
					float[] heights = ComputeGroundCore(id, center, width, 1f, mods, tc, file, builder, gen, out modifiers, out edits, out paint, out colors);
					j.Result = new OwnZone
					{
						Heights = heights,
						Paint = paint,
						Colors = colors,
						Revision = j.Rev,
						Complete = j.Loaded
					};
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)$"Own ground {id.x},{id.y} on a worker: {ex.Message}");
				}
				PackedMesh.ThreadDone(1, start);
				j.Done = true;
				GroundJobDone = true;
			});
			return null;
		}

		private bool GroundPrepared(Vector2s id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_003e: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			bool result = OwnZoneReady(id) != null;
			Vector2s val = default(Vector2s);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					if (j == 0 && i == 0)
					{
						continue;
					}
					((Vector2s)(ref val))..ctor(id.x + j, id.y + i);
					if (!_ownZones.ContainsKey(val))
					{
						Heightmap val2 = Heightmap.FindHeightmap(ZoneSystem.GetZonePos(val));
						if ((!((Object)(object)val2 != (Object)null) || val2.IsDistantLod) && OwnZoneReady(val) == null)
						{
							result = false;
						}
					}
				}
			}
			return result;
		}

		private OwnZone OwnZoneData(Vector2s id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to inval