Decompiled source of FehuUnchartedHorizons v420.100.1

FehuUnchartedHorizons.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FehuVanillaBiomes.Biomes;
using FehuVanillaBiomes.BuildingAndPlanting;
using FehuVanillaBiomes.Content;
using FehuVanillaBiomes.Core;
using FehuVanillaBiomes.Integrations;
using FehuVanillaBiomes.Islands;
using FehuVanillaBiomes.TerrainPrototype;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Fehu Uncharted Horizons")]
[assembly: AssemblyProduct("Fehu Uncharted Horizons")]
[assembly: AssemblyCompany("BlackViking")]
[assembly: AssemblyDescription("Living vanilla biomes suspended above Valheim.")]
[assembly: AssemblyFileVersion("420.100.1.0")]
[assembly: AssemblyInformationalVersion("420.100.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("420.100.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 FehuVanillaBiomes.TerrainPrototype
{
	internal static class BigLandBiomePopulation
	{
		private readonly struct Placement
		{
			internal readonly Vector3 Position;

			internal readonly Quaternion Rotation;

			internal readonly float Scale;

			internal Placement(Vector3 position, Quaternion rotation, float scale)
			{
				//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)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Position = position;
				Rotation = rotation;
				Scale = scale;
			}
		}

		private sealed class Counts
		{
			internal int Trees;

			internal int Bushes;

			internal int Rocks;

			internal int Resources;

			internal int Misc;

			internal int Total => Trees + Bushes + Rocks + Resources + Misc;

			public override string ToString()
			{
				return $"trees={Trees}; bushes={Bushes}; rocks={Rocks}; resources={Resources}; misc={Misc}";
			}
		}

		internal const string LogPrefix = "[FVB/BIG-POP]";

		internal const int PopulationVersion = 2;

		internal const string PopulationVersionKey = "FVB_BigLandPopulationVersion";

		internal const string PopulationCompleteKey = "FVB_BigLandPopulationComplete";

		internal const string PopulationIslandKey = "FVB_BigLandPopulationIsland";

		internal const string PopulationSlotKey = "FVB_BigLandPopulationSlot";

		internal const string PopulationBiomeKey = "FVB_BigLandPopulationBiome";

		internal const string PopulationCategoryKey = "FVB_BigLandPopulationCategory";

		private const int TreeCapPerBiome = 72;

		private const int BushCapPerBiome = 52;

		private const int RockCapPerBiome = 48;

		private const int MiscCapPerBiome = 40;

		private const int ClutterCapPerBiome = 140;

		private const int EquivalentVanillaZones = 12;

		private static readonly MethodInfo CreateObjectMethod = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null) ?? throw new MissingMethodException("ZNetScene.CreateObject(ZDO)");

		private static readonly FieldInfo ObjectsByIdField = typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingFieldException("ZDOMan.m_objectsByID");

		private static FehuVanillaBiomesPlugin _plugin;

		private static Coroutine _coroutine;

		private static string _world = string.Empty;

		private static string _completedWorld = string.Empty;

		private static GameObject _clutterRoot;

		private static bool _clutterComplete;

		private static bool _blockedLogged;

		private static bool _ownershipLogged;

		private static readonly Vector2[] Directions = (Vector2[])(object)new Vector2[4]
		{
			Vector2.left,
			Vector2.right,
			Vector2.up,
			Vector2.down
		};

		internal static void Start(FehuVanillaBiomesPlugin plugin)
		{
			_plugin = plugin;
		}

		internal static void Stop()
		{
			if ((Object)(object)_plugin != (Object)null && _coroutine != null)
			{
				((MonoBehaviour)_plugin).StopCoroutine(_coroutine);
			}
			_coroutine = null;
			DestroyClutter();
			_world = string.Empty;
			_completedWorld = string.Empty;
			_blockedLogged = false;
			_ownershipLogged = false;
			_plugin = null;
		}

		internal static void ResetWorld(string world)
		{
			if ((Object)(object)_plugin != (Object)null && _coroutine != null)
			{
				((MonoBehaviour)_plugin).StopCoroutine(_coroutine);
			}
			_coroutine = null;
			DestroyClutter();
			_completedWorld = string.Empty;
			_blockedLogged = false;
			_ownershipLogged = false;
			_world = world;
		}

		internal static void OnHeightmapRegenerated(Heightmap map)
		{
			if ((Object)(object)map == (Object)(object)NextGenerationBigLand.Heightmap && _clutterComplete)
			{
				DestroyClutter();
			}
		}

		internal static bool ValidateTopConsistency(OrganicLandmassPlan plan, out int populationSamples, out int missingTop, out int outsideFootprint, out int heightMismatch)
		{
			//IL_0053: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			populationSamples = 0;
			missingTop = 0;
			outsideFootprint = 0;
			heightMismatch = 0;
			if (plan == null || ZDOMan.instance == null || !OrganicVisibleTop.Valid)
			{
				return false;
			}
			int duplicates;
			Dictionary<string, ZDO> dictionary = FindObjects(out duplicates);
			if (duplicates != 0)
			{
				return false;
			}
			foreach (ZDO value in dictionary.Values)
			{
				if (value != null)
				{
					populationSamples++;
					Vector3 position = value.GetPosition();
					float height;
					if (!OrganicVisibleTop.ContainsLocal(new Vector2(position.x - NextGenerationBigLand.CenterX, position.z - NextGenerationBigLand.CenterZ)))
					{
						outsideFootprint++;
					}
					else if (!NextGenerationBigLand.TryWorldHeight(new Vector3(position.x, NextGenerationBigLand.LayerY, position.z), out height))
					{
						missingTop++;
					}
					else if (Mathf.Abs(position.y - height) > 6f)
					{
						heightMismatch++;
					}
				}
			}
			if (missingTop == 0)
			{
				return outsideFootprint == 0;
			}
			return false;
		}

		internal static void Ensure(Heightmap map, TerrainComp compiler, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY)
		{
			if ((Object)(object)_plugin == (Object)null || (Object)(object)map == (Object)null || (Object)(object)compiler == (Object)null || plan == null || string.IsNullOrEmpty(world))
			{
				return;
			}
			LogPopulationOwnershipWhenNear();
			if (!NextGenerationBigLand.FinalReady)
			{
				if (!_blockedLogged)
				{
					_blockedLogged = true;
					Log("BLOCKED reason=final-landmass-not-ready");
				}
				return;
			}
			if (!_clutterComplete)
			{
				BuildClutter(map, plan, world, centerX, centerZ, layerY);
			}
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && _coroutine == null && !(_completedWorld == world))
			{
				_coroutine = ((MonoBehaviour)_plugin).StartCoroutine(PopulateServer(map, compiler, plan, world, centerX, centerZ, layerY));
			}
		}

		private static IEnumerator PopulateServer(Heightmap map, TerrainComp compiler, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY)
		{
			List<ZDO> list = new List<ZDO>();
			try
			{
				ZNetView component = ((Component)compiler).GetComponent<ZNetView>();
				ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null);
				if (val == null)
				{
					throw new InvalidOperationException("Big Land TerrainComp has no persistent ZDO.");
				}
				int duplicates;
				Dictionary<string, ZDO> dictionary = FindObjects(out duplicates);
				if (duplicates > 0)
				{
					throw new InvalidOperationException($"duplicate stable population slots={duplicates}");
				}
				if (val.GetBool("FVB_BigLandPopulationComplete", false) && val.GetInt("FVB_BigLandPopulationVersion", 0) == 2)
				{
					_completedWorld = world;
					Log($"COMPLETE restore=true; Meadows={Summary(dictionary.Values, (Biome)1)}; BlackForest={Summary(dictionary.Values, (Biome)8)}; persistentObjects={dictionary.Count}; duplicates=0; clutterLocal={_clutterComplete}");
					yield break;
				}
				List<ZoneVegetation> list2 = ZoneSystem.instance.m_vegetation.Where((ZoneVegetation definition) => definition != null && definition.m_enable && (Object)(object)definition.m_prefab != (Object)null).ToList();
				Log(string.Format("BEGIN identity={0}; version={1}; seed={2}; vanillaDefinitions={3}; globalTablesModified=false", "earth-above-bigland-30-v3", 2, PopulationSeed(world), list2.Count));
				List<string> list3 = (from name in (from definition in list2
						select ((Object)definition.m_prefab).name into name
						where name.StartsWith("BMM_", StringComparison.OrdinalIgnoreCase) || name.IndexOf("Mithril", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Warpstone", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Meteorite", StringComparison.OrdinalIgnoreCase) >= 0
						select name).Distinct()
					orderby name
					select name).ToList();
				Log(string.Format("ACTIVE DEFINITIONS compatibleExternal={0}; names={1}; hardDependencies=none", list3.Count, (list3.Count > 0) ? string.Join(",", list3) : "none"));
				Random random = new Random(PopulationSeed(world));
				List<Vector3> occupied = new List<Vector3>();
				int duplicatesSkipped = 0;
				Counts counts = PopulateBiome((Biome)1, list2, map, plan, world, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped);
				Counts counts2 = PopulateBiome((Biome)8, list2, map, plan, world, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped);
				if (counts.Total == 0 || counts2.Total == 0)
				{
					throw new InvalidOperationException($"population validation failed: Meadows={counts.Total}; BlackForest={counts2.Total}");
				}
				Log($"MEADOWS {counts}; definitions={DefinitionNames(list2, (Biome)1)}");
				Log($"BLACKFOREST {counts2}; definitions={DefinitionNames(list2, (Biome)8)}");
				Log("CREATURES mode=vanilla-biome-routing; deer+boar+neck+greydwarf+troll+skeleton rules unchanged; globalSpawnTablesModified=false");
				Log("[FVB/BIG-LOCATIONS] attempted=0; placed=0; rejected=0; Meadows=0; BlackForest=0; status=DEFERRED; reason=ZoneSystem.SpawnLocation/CreateLocationProxy bind persistence to vanilla X/Z zone identity; unsafe without isolated location registry");
				Log("[FVB/BIG-DUNGEON] candidate=BurialChambers; status=DEFERRED; reason=LocationProxy.SpawnLocation delegates to ZoneSystem.SpawnProxyLocation and vanilla location registry; entryPosition=none; instanceIdentity=none");
				Log("[FVB/BIG-DUNGEON] candidate=TrollCave; status=DEFERRED; reason=same vanilla X/Z LocationProxy ownership blocker; entryPosition=none; instanceIdentity=none");
				Log($"[FVB/BIG-LAKE-BASIN] center=({plan.LakeBasinLocal.x + centerX:F1},{layerY:F1},{plan.LakeBasinLocal.y + centerZ:F1}); radius=25.0; depth=5.0; drainEdgeDistance={DistanceToContour(plan, plan.LakeBasinLocal):F1}; waterEnabled=false");
				val.Set("FVB_BigLandPopulationVersion", 2);
				val.Set("FVB_BigLandPopulationComplete", true);
				_completedWorld = world;
				Log($"COMPLETE Meadows={counts}; BlackForest={counts2}; persistentObjects={dictionary.Count + list.Count}; duplicatesSkipped={duplicatesSkipped}; clutterLocal={_clutterComplete}; locations=0; caveFeatures=0");
				int populationSamples;
				int missingTop;
				int outsideFootprint;
				int heightMismatch;
				bool flag = ValidateTopConsistency(plan, out populationSamples, out missingTop, out outsideFootprint, out heightMismatch);
				Log(string.Format("[FVB/BIG-TOP-CONSISTENCY] populationSamples={0}; missingTop={1}; outsideFootprint={2}; heightMismatch={3}; phase=after-population; result={4}", populationSamples, missingTop, outsideFootprint, heightMismatch, flag ? "PASS" : "FAIL"));
			}
			catch (Exception ex)
			{
				Rollback(list);
				LogError("transaction rolled back; completion marker NOT written: " + ex);
			}
			finally
			{
				_coroutine = null;
			}
		}

		private static Counts PopulateBiome(Biome biome, List<ZoneVegetation> vanilla, Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped)
		{
			//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_002c: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			List<ZoneVegetation> source = vanilla.Where((ZoneVegetation definition) => (definition.m_biome & biome) != 0 && (definition.m_biomeArea & 2) > 0).ToList();
			return new Counts
			{
				Trees = PlaceCategory(biome, "tree", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "tree").ToList(), 72, 4f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped),
				Bushes = PlaceCategory(biome, "bush", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "bush").ToList(), 52, 2f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped),
				Rocks = PlaceCategory(biome, "rock", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "rock").ToList(), 48, 3f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped),
				Resources = PlaceCategory(biome, "resource", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "resource").ToList(), 18, 5f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped),
				Misc = PlaceCategory(biome, "misc", source.Where((ZoneVegetation definition) => Category(((Object)definition.m_prefab).name) == "misc").ToList(), 40, 1.3f, map, plan, world, centerX, centerZ, layerY, random, occupied, existing, created, ref duplicatesSkipped)
			};
		}

		private static int PlaceCategory(Biome biome, string category, List<ZoneVegetation> definitions, int cap, float spacing, Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped)
		{
			//IL_0040: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (definitions.Count == 0)
			{
				return 0;
			}
			Shuffle(definitions, random);
			int num = 0;
			int num2 = 0;
			foreach (ZoneVegetation definition in definitions)
			{
				int num3 = DefinitionGroupBudget(definition, random);
				for (int i = 0; i < num3; i++)
				{
					if (num >= cap)
					{
						break;
					}
					Vector2 groupCenter = RandomBiomePoint(random, plan, biome);
					int num4 = Math.Max(1, random.Next(Math.Max(1, definition.m_groupSizeMin), Math.Max(1, definition.m_groupSizeMax) + 1));
					for (int j = 0; j < num4; j++)
					{
						if (num >= cap)
						{
							break;
						}
						string text = string.Format("{0}|{1}|vegetation|{2}|{3}|{4:D4}|v{5}", world, "earth-above-bigland-30-v3", biome, category, num2++, 2);
						Placement placement;
						if (existing.ContainsKey(text))
						{
							duplicatesSkipped++;
							num++;
						}
						else if (TryPlacement(definition, biome, map, plan, groupCenter, centerX, centerZ, layerY, random, occupied, spacing, out placement))
						{
							ZDO val = SpawnPersistent(definition, placement, text, biome, category);
							if (val != null)
							{
								created.Add(val);
								occupied.Add(placement.Position);
								num++;
							}
						}
					}
				}
			}
			return num;
		}

		private static int DefinitionGroupBudget(ZoneVegetation definition, Random random)
		{
			if (definition.m_max < 1f)
			{
				return (random.NextDouble() <= (double)definition.m_max) ? 1 : 0;
			}
			int num = Math.Max(0, Mathf.FloorToInt(definition.m_min * 12f));
			int num2 = Math.Max(num, Mathf.CeilToInt(definition.m_max * 12f));
			return Math.Min(36, random.Next(num, num2 + 1));
		}

		private static bool TryPlacement(ZoneVegetation definition, Biome biome, Heightmap map, OrganicLandmassPlan plan, Vector2 groupCenter, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, float spacing, out Placement placement)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00b4: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			placement = default(Placement);
			float num5 = default(float);
			for (int i = 0; i < 32; i++)
			{
				float num = (float)(random.NextDouble() * Math.PI * 2.0);
				float num2 = definition.m_groupRadius * Mathf.Sqrt((float)random.NextDouble());
				float num3 = groupCenter.x + Mathf.Cos(num) * num2;
				float num4 = groupCenter.y + Mathf.Sin(num) * num2;
				if (plan.LandFactor(num3, num4) < 0.72f || plan.BiomeAt(num3, num4) != biome)
				{
					continue;
				}
				Vector3 point = new Vector3(centerX + num3, layerY, centerZ + num4);
				if (!Heightmap.GetHeight(point, ref num5))
				{
					continue;
				}
				point.y = num5 + definition.m_groundOffset;
				if (map.IsCleared(point) || occupied.Any((Vector3 other) => HorizontalDistance(other, point) < spacing))
				{
					continue;
				}
				float num6 = num5 - layerY;
				if (num6 < definition.m_minAltitude || num6 > definition.m_maxAltitude)
				{
					continue;
				}
				float vegetationMask = map.GetVegetationMask(point);
				if (definition.m_minVegetation != definition.m_maxVegetation && (vegetationMask < definition.m_minVegetation || vegetationMask > definition.m_maxVegetation))
				{
					continue;
				}
				Vector3 val = SurfaceNormal(point);
				float y = val.y;
				if (y < Mathf.Cos(definition.m_maxTilt * ((float)Math.PI / 180f)) || y > Mathf.Cos(definition.m_minTilt * ((float)Math.PI / 180f)) || !PassTerrainDelta(definition, point) || !PassSurroundVegetation(definition, map, point))
				{
					continue;
				}
				Vector2 val2 = new Vector2(point.x, point.z);
				float magnitude = ((Vector2)(ref val2)).magnitude;
				if ((definition.m_minDistanceFromCenter > 0f && magnitude < definition.m_minDistanceFromCenter) || (definition.m_maxDistanceFromCenter > 0f && magnitude > definition.m_maxDistanceFromCenter) || definition.m_snapToWater || definition.m_minOceanDepth > 0f)
				{
					continue;
				}
				if (definition.m_inForest)
				{
					float forestFactor = WorldGenerator.GetForestFactor(point);
					if (forestFactor < definition.m_forestTresholdMin || forestFactor > definition.m_forestTresholdMax)
					{
						continue;
					}
				}
				if (!definition.m_blockCheck || !IsBlocked(map, point))
				{
					float num7 = (float)random.NextDouble() * 360f;
					float num8 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble());
					float num9 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble());
					Quaternion rotation = ((random.NextDouble() <= (double)definition.m_chanceToUseGroundTilt) ? (Quaternion.FromToRotation(Vector3.up, val) * Quaternion.Euler(0f, num7, 0f)) : Quaternion.Euler(num8, num7, num9));
					placement = new Placement(point, rotation, Mathf.Lerp(definition.m_scaleMin, definition.m_scaleMax, (float)random.NextDouble()));
					return true;
				}
			}
			return false;
		}

		private static bool PassTerrainDelta(ZoneVegetation definition, Vector3 point)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (definition.m_terrainDeltaRadius <= 0f)
			{
				return true;
			}
			float num = float.MaxValue;
			float num2 = float.MinValue;
			Vector2[] directions = Directions;
			float num3 = default(float);
			foreach (Vector2 val in directions)
			{
				if (!Heightmap.GetHeight(point + new Vector3(val.x * definition.m_terrainDeltaRadius, 0f, val.y * definition.m_terrainDeltaRadius), ref num3))
				{
					return false;
				}
				num = Mathf.Min(num, num3);
				num2 = Mathf.Max(num2, num3);
			}
			float num4 = num2 - num;
			if (num4 >= definition.m_minTerrainDelta)
			{
				return num4 <= definition.m_maxTerrainDelta;
			}
			return false;
		}

		private static bool PassSurroundVegetation(ZoneVegetation definition, Heightmap map, Vector3 point)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (!definition.m_surroundCheckVegetation || definition.m_surroundCheckLayers <= 0 || definition.m_surroundCheckDistance <= 0f)
			{
				return true;
			}
			float num = 0f;
			int num2 = 0;
			for (int i = 1; i <= definition.m_surroundCheckLayers; i++)
			{
				for (int j = 0; j < 6; j++)
				{
					float num3 = (float)j / 6f * (float)Math.PI * 2f;
					float num4 = (float)i / (float)definition.m_surroundCheckLayers * definition.m_surroundCheckDistance;
					num += map.GetVegetationMask(point + new Vector3(Mathf.Sin(num3) * num4, 0f, Mathf.Cos(num3) * num4));
					num2++;
				}
			}
			float num5 = ((num2 > 0) ? (num / (float)num2) : 0f);
			if (num5 >= definition.m_minVegetation)
			{
				return num5 <= definition.m_maxVegetation;
			}
			return false;
		}

		private static bool IsBlocked(Heightmap map, Vector3 point)
		{
			//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_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)
			Collider[] array = Physics.OverlapSphere(point + Vector3.up * 0.5f, 0.45f, -5, (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Heightmap>() != (Object)(object)map)
				{
					return true;
				}
			}
			return false;
		}

		private unsafe static ZDO SpawnPersistent(ZoneVegetation definition, Placement placement, string slot, Biome biome, string category)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = definition.m_prefab;
			ZNetView val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			int num = StableHash(((Object)prefab).name);
			if ((Object)(object)ZNetScene.instance.GetPrefab(((Object)prefab).name) == (Object)null)
			{
				return null;
			}
			ZDO val2 = ZDOMan.instance.CreateNewZDO(placement.Position, num);
			if (val2 == null)
			{
				throw new InvalidOperationException("CreateNewZDO failed slot=" + slot + "; prefab=" + ((Object)prefab).name);
			}
			val2.SetPrefab(num);
			val2.SetRotation(placement.Rotation);
			val2.Persistent = true;
			val2.Type = val.m_type;
			val2.Distant = val.m_distant;
			val2.Set("FVB_BigLandPopulationIsland", "earth-above-bigland-30-v3");
			val2.Set("FVB_BigLandPopulationSlot", slot);
			val2.Set("FVB_BigLandPopulationBiome", ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString());
			val2.Set("FVB_BigLandPopulationCategory", category);
			val2.Set("FVB_BigLandPopulationVersion", 2);
			object? obj = CreateObjectMethod.Invoke(ZNetScene.instance, new object[1] { val2 });
			GameObject val3 = (GameObject)((obj is GameObject) ? obj : null);
			ZNetView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ZNetView>() : null);
			if ((Object)(object)val4 == (Object)null || !val4.IsValid() || val4.GetZDO() == null)
			{
				ZDOMan.instance.DestroyZDO(val2);
				throw new InvalidOperationException("CreateObject validation failed slot=" + slot + "; prefab=" + ((Object)prefab).name);
			}
			if (Mathf.Abs(placement.Scale - 1f) > 0.001f)
			{
				val4.SetLocalScale(Vector3.one * placement.Scale);
			}
			return val2;
		}

		private static Dictionary<string, ZDO> FindObjects(out int duplicates)
		{
			duplicates = 0;
			Dictionary<string, ZDO> dictionary = new Dictionary<string, ZDO>(StringComparer.Ordinal);
			if (!(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary2))
			{
				return dictionary;
			}
			foreach (ZDO value in dictionary2.Values)
			{
				if (value == null || value.GetString("FVB_BigLandPopulationIsland", string.Empty) != "earth-above-bigland-30-v3")
				{
					continue;
				}
				string text = value.GetString("FVB_BigLandPopulationSlot", string.Empty);
				if (!string.IsNullOrEmpty(text))
				{
					if (dictionary.ContainsKey(text))
					{
						duplicates++;
					}
					else
					{
						dictionary.Add(text, value);
					}
				}
			}
			return dictionary;
		}

		private static void LogPopulationOwnershipWhenNear()
		{
			//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)
			if (_ownershipLogged || (Object)(object)Player.m_localPlayer == (Object)null || ZDOMan.instance == null)
			{
				return;
			}
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			float num = position.x - NextGenerationBigLand.CenterX;
			float num2 = position.z - NextGenerationBigLand.CenterZ;
			float num3 = 192f;
			if (num * num + num2 * num2 > num3 * num3 || !(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary))
			{
				return;
			}
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			foreach (ZDO value in dictionary.Values)
			{
				if (value != null && value.Persistent)
				{
					switch (value.GetString("FVB_BigLandPopulationIsland", value.GetString("FVB_PopulationIslandId", string.Empty)))
					{
					case "earth-above-bigland-18-v1":
						num4++;
						break;
					case "earth-above-bigland-30-v2":
						num5++;
						break;
					case "earth-above-bigland-30-v3":
						num6++;
						break;
					}
				}
			}
			_ownershipLogged = true;
			if ((Object)(object)_plugin != (Object)null)
			{
				_plugin.Log.LogInfo((object)string.Format("[FVB/POP-OWNERSHIP] {0}={1}; {2}={3}; {4}={5}; mutation=false", "earth-above-bigland-18-v1", num4, "earth-above-bigland-30-v2", num5, "earth-above-bigland-30-v3", num6));
			}
		}

		private static void BuildClutter(Heightmap map, OrganicLandmassPlan plan, string world, float centerX, float centerZ, float layerY)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_0184: 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_01a5: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			if (_clutterComplete || (Object)(object)ClutterSystem.instance == (Object)null)
			{
				return;
			}
			List<Clutter> list = ClutterSystem.instance.m_clutter.Where((Clutter definition) => definition != null && definition.m_enabled && (Object)(object)definition.m_prefab != (Object)null && (definition.m_biome & 9) > 0).ToList();
			if (list.Count == 0)
			{
				_clutterComplete = true;
				Log("CLUTTER slots=0; definitions unavailable");
				return;
			}
			_clutterRoot = new GameObject("FVB_EarthAbove_BigLand30V3_LocalClutter");
			Random random = new Random(PopulationSeed(world) ^ 0x434C5554);
			Dictionary<Biome, int> dictionary = new Dictionary<Biome, int>();
			Dictionary<Biome, int> dictionary2 = new Dictionary<Biome, int>();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			Biome[] array = (Biome[])(object)new Biome[2]
			{
				(Biome)1,
				(Biome)8
			};
			Vector3 val3 = default(Vector3);
			float num12 = default(float);
			foreach (Biome biome in array)
			{
				for (int num10 = 0; num10 < 140; num10++)
				{
					List<Clutter> list2 = list.Where((Clutter definition) => (definition.m_biome & biome) > 0).ToList();
					if (list2.Count == 0)
					{
						break;
					}
					bool flag = false;
					for (int num11 = 0; num11 < 12; num11++)
					{
						if (flag)
						{
							break;
						}
						Clutter val = list2[random.Next(list2.Count)];
						Vector2 val2 = RandomBiomePoint(random, plan, biome);
						if (plan.LandFactor(val2.x, val2.y) < 0.74f)
						{
							num++;
							continue;
						}
						if (plan.BiomeAt(val2.x, val2.y) != biome)
						{
							num4++;
							continue;
						}
						((Vector3)(ref val3))..ctor(centerX + val2.x, layerY, centerZ + val2.y);
						if (!Heightmap.GetHeight(val3, ref num12))
						{
							num5++;
							continue;
						}
						val3.y = num12 + val.m_randomOffset * ((float)random.NextDouble() * 2f - 1f);
						if (map.IsCleared(val3) || (!val.m_onUncleared && val.m_onCleared))
						{
							num3++;
							continue;
						}
						float vegetationMask = map.GetVegetationMask(val3);
						if (vegetationMask < val.m_minVegetation || vegetationMask > val.m_maxVegetation)
						{
							num6++;
							continue;
						}
						Vector3 val4 = SurfaceNormal(val3);
						float num13 = Vector3.Angle(val4, Vector3.up);
						if (num13 < val.m_minTilt || num13 > val.m_maxTilt)
						{
							num2++;
							continue;
						}
						MeshFilter val5 = LargestMeshFilter(val.m_prefab);
						MeshRenderer val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<MeshRenderer>() : null);
						if ((Object)(object)val5 == (Object)null || (Object)(object)val5.sharedMesh == (Object)null || (Object)(object)val6 == (Object)null)
						{
							num8++;
							continue;
						}
						GameObject val7 = new GameObject($"FVB_BigClutter_{biome}_{num10:D3}_{val.m_name}")
						{
							layer = ((Component)map).gameObject.layer
						};
						val7.transform.SetParent(_clutterRoot.transform, false);
						val7.transform.position = val3;
						val7.transform.rotation = (val.m_terrainTilt ? Quaternion.FromToRotation(Vector3.up, val4) : Quaternion.identity) * Quaternion.Euler(0f, (float)random.NextDouble() * 360f, 0f);
						val7.transform.localScale = Vector3.one * Mathf.Lerp(val.m_scaleMin, val.m_scaleMax, (float)random.NextDouble());
						val7.AddComponent<MeshFilter>().sharedMesh = val5.sharedMesh;
						MeshRenderer obj = val7.AddComponent<MeshRenderer>();
						((Renderer)obj).sharedMaterials = ((Renderer)val6).sharedMaterials;
						((Renderer)obj).receiveShadows = ((Renderer)val6).receiveShadows;
						dictionary[biome] = ((!dictionary.TryGetValue(biome, out var value)) ? 1 : (value + 1));
						flag = true;
					}
					if (!flag)
					{
						dictionary2[biome] = ((!dictionary2.TryGetValue(biome, out var value2)) ? 1 : (value2 + 1));
					}
				}
			}
			_clutterComplete = true;
			Log($"CLUTTER Meadows={GetCount(dictionary, (Biome)1)}; BlackForest={GetCount(dictionary, (Biome)8)}; rejectedMeadows={GetCount(dictionary2, (Biome)1)}; rejectedBlackForest={GetCount(dictionary2, (Biome)8)}; rejectedOutsideMask={num}; rejectedSlope={num2}; rejectedPaint={num3}; rejectedBiome={num4}; rejectedHeight={num5}; rejectedVegetationMask={num6}; rejectedRaycast={num7}; rejectedOther={num8}; persistent=false; zdoCount=0");
		}

		private static void DestroyClutter()
		{
			if ((Object)(object)_clutterRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_clutterRoot);
			}
			_clutterRoot = null;
			_clutterComplete = false;
		}

		private static Vector2 RandomBiomePoint(Random random, OrganicLandmassPlan plan, Biome biome)
		{
			//IL_0065: 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)
			for (int i = 0; i < 512; i++)
			{
				float num = Mathf.Lerp(-128f, 128f, (float)random.NextDouble());
				float num2 = Mathf.Lerp(-128f, 128f, (float)random.NextDouble());
				if (plan.LandFactor(num, num2) >= 0.74f && plan.BiomeAt(num, num2) == biome)
				{
					return new Vector2(num, num2);
				}
			}
			throw new InvalidOperationException($"No deterministic placement point for {biome}.");
		}

		private static Vector3 SurfaceNormal(Vector3 point)
		{
			//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_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_001d: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0045: 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_0057: 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_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)
			//IL_007f: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			Heightmap.GetHeight(point + Vector3.left * 0.75f, ref num);
			float num2 = default(float);
			Heightmap.GetHeight(point + Vector3.right * 0.75f, ref num2);
			float num3 = default(float);
			Heightmap.GetHeight(point + Vector3.back * 0.75f, ref num3);
			float num4 = default(float);
			Heightmap.GetHeight(point + Vector3.forward * 0.75f, ref num4);
			Vector3 val = new Vector3(num - num2, 1.5f, num3 - num4);
			return ((Vector3)(ref val)).normalized;
		}

		private static MeshFilter LargestMeshFilter(GameObject prefab)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter result = null;
			float num = -1f;
			MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if (!((Object)(object)sharedMesh == (Object)null) && !((Object)(object)((Component)val).GetComponent<MeshRenderer>() == (Object)null))
				{
					Bounds bounds = sharedMesh.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num2 = Mathf.Abs(size.x * size.y * size.z);
					if (num2 > num)
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}

		private static string Category(string name)
		{
			string text = name.ToLowerInvariant();
			if (text.Contains("beech") || text.Contains("birch") || text.Contains("oak") || text.Contains("fir") || text.Contains("pine"))
			{
				return "tree";
			}
			if (text.Contains("bush") || text.Contains("shrub") || text.Contains("sapling") || text.Contains("blueberr") || text.Contains("raspberr"))
			{
				return "bush";
			}
			if (text.Contains("tin"))
			{
				return "water-resource-disabled";
			}
			if (text.Contains("copper") || text.Contains("meteorite") || text.Contains("mithril") || text.Contains("warpstone") || text.Contains("mine") || text.Contains("deposit"))
			{
				return "resource";
			}
			if (text.Contains("rock") || text.Contains("stone") || text.Contains("cliff"))
			{
				return "rock";
			}
			return "misc";
		}

		private static string DefinitionNames(IEnumerable<ZoneVegetation> values, Biome biome)
		{
			//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)
			return string.Join(",", from value in (from value in values
					where (value.m_biome & biome) > 0
					select ((Object)value.m_prefab).name).Distinct()
				orderby value
				select value);
		}

		private unsafe static string Summary(IEnumerable<ZDO> values, Biome biome)
		{
			string name = ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString();
			return string.Join(",", new string[5] { "tree", "bush", "rock", "resource", "misc" }.Select((string category) => category + "=" + values.Count((ZDO zdo) => zdo.GetString("FVB_BigLandPopulationBiome", string.Empty) == name && zdo.GetString("FVB_BigLandPopulationCategory", string.Empty) == category)));
		}

		private static int GetCount(Dictionary<Biome, int> values, Biome biome)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!values.TryGetValue(biome, out var value))
			{
				return 0;
			}
			return value;
		}

		private static float HorizontalDistance(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			float num = a.x - b.x;
			float num2 = a.z - b.z;
			return Mathf.Sqrt(num * num + num2 * num2);
		}

		private static float DistanceToContour(OrganicLandmassPlan plan, Vector2 point)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			float num = float.MaxValue;
			foreach (Vector2 point2 in plan.Contour.Points)
			{
				num = Mathf.Min(num, Vector2.Distance(point, point2));
			}
			return num;
		}

		private static int PopulationSeed(string world)
		{
			return WorldGenerator.instance.GetSeed() ^ StableHash(world) ^ StableHash("earth-above-bigland-30-v3") ^ 2;
		}

		private static int StableHash(string text)
		{
			int num = 5381;
			int num2 = num;
			for (int i = 0; i < text.Length && text[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ text[i];
				if (i == text.Length - 1 || text[i + 1] == '\0')
				{
					break;
				}
				num2 = ((num2 << 5) + num2) ^ text[i + 1];
			}
			return num + num2 * 1566083941;
		}

		private static void Shuffle<T>(IList<T> values, Random random)
		{
			for (int num = values.Count - 1; num > 0; num--)
			{
				int index = random.Next(num + 1);
				T value = values[num];
				values[num] = values[index];
				values[index] = value;
			}
		}

		private static void Rollback(IEnumerable<ZDO> created)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			foreach (ZDO item in created.Reverse())
			{
				if (item != null)
				{
					GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(item.m_uid) : null);
					if ((Object)(object)val != (Object)null)
					{
						ZNetScene.instance.Destroy(val);
					}
					else if (ZDOMan.instance != null)
					{
						ZDOMan.instance.DestroyZDO(item);
					}
				}
			}
		}

		private static void Log(string message)
		{
			if ((Object)(object)_plugin != (Object)null)
			{
				_plugin.Log.LogInfo((object)("[FVB/BIG-POP] " + message));
			}
		}

		private static void LogError(string message)
		{
			if ((Object)(object)_plugin != (Object)null)
			{
				_plugin.Log.LogError((object)("[FVB/BIG-POP] " + message));
			}
		}
	}
	internal static class BigLandSpawnAudit
	{
		private const string Prefix = "[FVB/SPAWN-AUDIT]";

		private static int _candidates;

		private static int _accepted;

		private static int _rejected;

		private static int _spawnedObserved;

		private static float _lastSummary;

		internal static void ObserveCandidate(SpawnData spawn, Vector3 point, bool accepted)
		{
			//IL_0000: 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_007c: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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)
			if (!NextGenerationBigLand.ContainsElevatedVolume(point))
			{
				return;
			}
			_candidates++;
			if (accepted)
			{
				_accepted++;
			}
			else
			{
				_rejected++;
			}
			if (_candidates <= 8)
			{
				Heightmap val = Heightmap.FindHeightmap(point);
				FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance;
				if (instance != null)
				{
					ManualLogSource log = instance.Log;
					object[] obj = new object[10]
					{
						"[FVB/SPAWN-AUDIT]",
						spawn?.m_biome,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null
					};
					object obj2;
					if (spawn == null)
					{
						obj2 = null;
					}
					else
					{
						GameObject prefab = spawn.m_prefab;
						obj2 = ((prefab != null) ? ((Object)prefab).name : null);
					}
					if (obj2 == null)
					{
						obj2 = "null";
					}
					obj[2] = obj2;
					obj[3] = point.x;
					obj[4] = point.y;
					obj[5] = point.z;
					obj[6] = point.y;
					obj[7] = ((val != null) ? ((Object)((Component)val).gameObject).name : null) ?? "none";
					obj[8] = accepted;
					obj[9] = (accepted ? "vanilla-rules-pass" : "vanilla-rules-rejected");
					log.LogInfo((object)string.Format("{0} biome={1}; prefab={2}; candidatePosition=({3:F1},{4:F1},{5:F1}); resolvedGround={6:F2}; resolvedHeightmap={7}; accepted={8}; reason={9}", obj));
				}
			}
			SummaryIfDue();
		}

		internal static void ObserveSpawn(SpawnData spawn, Vector3 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (NextGenerationBigLand.ContainsElevatedVolume(point))
			{
				_spawnedObserved++;
				SummaryIfDue(force: true);
			}
		}

		private static void SummaryIfDue(bool force = false)
		{
			if (force || !(Time.realtimeSinceStartup - _lastSummary < 30f) || _candidates % 25 == 0)
			{
				_lastSummary = Time.realtimeSinceStartup;
				FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance;
				if (instance != null)
				{
					instance.Log.LogInfo((object)string.Format("{0} SUMMARY candidateCount={1}; acceptedCount={2}; rejectedCount={3}; spawnedObserved={4}; scopedTo={5}; globalSpawnTablesModified=false", "[FVB/SPAWN-AUDIT]", _candidates, _accepted, _rejected, _spawnedObserved, "earth-above-bigland-30-v3"));
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class BigLandSpawnPointPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(SpawnSystem), "IsSpawnPointGood", new Type[2]
			{
				typeof(SpawnData),
				typeof(Vector3).MakeByRefType()
			}, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix(SpawnData __0, Vector3 __1, bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			BigLandSpawnAudit.ObserveCandidate(__0, __1, __result);
		}
	}
	[HarmonyPatch]
	internal static class BigLandSpawnObservedPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(SpawnSystem), "Spawn", new Type[3]
			{
				typeof(SpawnData),
				typeof(Vector3),
				typeof(bool)
			}, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix(SpawnData __0, Vector3 __1)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			BigLandSpawnAudit.ObserveSpawn(__0, __1);
		}
	}
	internal static class ClusterLandManager
	{
		private sealed class Island
		{
			internal readonly string Id;

			internal readonly Vector2 Center;

			internal Heightmap Map;

			internal TerrainComp Comp;

			internal string Bounds => "(" + (Center.x - 64f) + "," + (Center.y - 64f) + ")..(" + (Center.x + 64f) + "," + (Center.y + 64f) + ")";

			internal Island(int index)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				Id = "earth-above-cluster-land-v1-" + index.ToString("D2");
				Center = Centers[index];
			}
		}

		internal const string PrototypeId = "earth-above-cluster-land-v1";

		internal const int Width = 128;

		internal const float LayerY = 180f;

		private const float Half = 64f;

		private const float LayerBand = 40f;

		private static readonly Vector2[] Centers = (Vector2[])(object)new Vector2[5]
		{
			new Vector2(4096f, -2048f),
			new Vector2(4096f, -1888f),
			new Vector2(4256f, -2048f),
			new Vector2(3936f, -2208f),
			new Vector2(4256f, -2208f)
		};

		private static readonly MethodInfo CreateObject = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null);

		private static readonly List<Island> Islands = new List<Island>();

		private static FehuVanillaBiomesPlugin _plugin;

		private static Coroutine _life;

		private static bool _creatingCompiler;

		private static string _world = string.Empty;

		internal static bool Enabled
		{
			get
			{
				if ((Object)(object)_plugin != (Object)null)
				{
					return _plugin.Settings.ClusterLandEnabled.Value;
				}
				return false;
			}
		}

		internal static void Start(FehuVanillaBiomesPlugin plugin)
		{
			_plugin = plugin;
			if (_life == null)
			{
				_life = ((MonoBehaviour)plugin).StartCoroutine(Lifecycle());
			}
		}

		internal static void Stop()
		{
			if ((Object)(object)_plugin != (Object)null && _life != null)
			{
				((MonoBehaviour)_plugin).StopCoroutine(_life);
			}
			_life = null;
			foreach (Island island in Islands)
			{
				if ((Object)(object)island.Map != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)island.Map).gameObject);
				}
			}
			Islands.Clear();
			_plugin = null;
			_world = string.Empty;
		}

		private static IEnumerator Lifecycle()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(1f);
				if (!Enabled || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null || WorldGenerator.instance == null)
				{
					continue;
				}
				string text = ZNet.instance.GetWorldName() + ":" + ZNet.instance.GetWorldUID();
				if (_world != text)
				{
					StopMaps();
					_world = text;
					Log("LAYOUT prototype=earth-above-cluster-land-v1; islandCount=5; overallBounds=(3872,-2272)..(4320,-1824); positions=" + LayoutText());
					CheckBounds();
				}
				Heightmap reference = FindReference();
				if ((Object)(object)reference == (Object)null)
				{
					continue;
				}
				for (int n = 0; n < Centers.Length; n++)
				{
					Island island = Get(n);
					if ((Object)(object)island.Map == (Object)null)
					{
						CreateMap(island, reference);
					}
					if ((Object)(object)island.Map != (Object)null && (Object)(object)island.Comp == (Object)null)
					{
						yield return CreateCompiler(island);
					}
				}
				if (Islands.Count == 5 && Islands.TrueForAll((Island i) => (Object)(object)i.Map != (Object)null && (Object)(object)i.Comp != (Object)null && (Object)(object)((Component)i.Map).GetComponent<MeshRenderer>() != (Object)null && ((Renderer)((Component)i.Map).GetComponent<MeshRenderer>()).enabled && (Object)(object)((Component)i.Map).GetComponent<MeshCollider>() != (Object)null && ((Collider)((Component)i.Map).GetComponent<MeshCollider>()).enabled && (Object)(object)((Component)i.Map).GetComponent<MeshCollider>().sharedMesh != (Object)null))
				{
					Log("FINAL roots=5; boundsOverlap=0; shell=False; customCollider=False; result=PASS");
				}
			}
		}

		private static void StopMaps()
		{
			foreach (Island island in Islands)
			{
				if ((Object)(object)island.Map != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)island.Map).gameObject);
				}
			}
			Islands.Clear();
		}

		private static Island Get(int index)
		{
			while (Islands.Count <= index)
			{
				Islands.Add(new Island(Islands.Count));
			}
			return Islands[index];
		}

		private static Heightmap FindReference()
		{
			foreach (Heightmap allHeightmap in Heightmap.GetAllHeightmaps())
			{
				if ((Object)(object)allHeightmap != (Object)null && (Object)(object)allHeightmap.m_material != (Object)null && (Object)(object)allHeightmap.m_terrainCompilerPrefab != (Object)null && !IsClusterMap(allHeightmap))
				{
					return allHeightmap;
				}
			}
			return null;
		}

		private static void CreateMap(Island island, Heightmap reference)
		{
			//IL_0010: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_005f: 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)
			GameObject val = new GameObject("FVB_ClusterLand_" + island.Id);
			val.SetActive(false);
			val.layer = ((Component)reference).gameObject.layer;
			val.transform.position = new Vector3(island.Center.x, 180f, island.Center.y);
			val.AddComponent<MeshCollider>();
			Heightmap val2 = val.AddComponent<Heightmap>();
			val2.m_width = 128;
			val2.m_scale = 1f;
			val2.m_material = reference.m_material;
			val2.m_terrainCompilerPrefab = reference.m_terrainCompilerPrefab;
			island.Map = val2;
			val.SetActive(true);
			val2.Poke(0, false);
			Log("ISLAND id=" + island.Id + "; center=" + ((object)((Component)val2).transform.position/*cast due to .constrained prefix*/).ToString() + "; bounds=" + island.Bounds + "; usableOrganicExtent=~104m; footprintSeed=" + Seed(island.Id));
		}

		private static IEnumerator CreateCompiler(Island island)
		{
			_creatingCompiler = true;
			try
			{
				island.Comp = island.Map.GetAndCreateTerrainCompiler();
			}
			finally
			{
				_creatingCompiler = false;
			}
			yield return null;
			ZNetView val = (((Object)(object)island.Comp != (Object)null) ? ((Component)island.Comp).GetComponent<ZNetView>() : null);
			ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null);
			if (val2 != null)
			{
				val2.Set("FVB_IslandId", island.Id);
				val2.Set("FVB_TerrainLayerId", island.Id);
				val2.Set("FVB_TerrainLayerY", 180f);
			}
			MeshRenderer component = ((Component)island.Map).GetComponent<MeshRenderer>();
			MeshCollider component2 = ((Component)island.Map).GetComponent<MeshCollider>();
			Log("NATIVE id=" + island.Id + "; rendererEnabled=" + ((Object)(object)component != (Object)null && ((Renderer)component).enabled) + "; colliderEnabled=" + ((Object)(object)component2 != (Object)null && ((Collider)component2).enabled) + "; sharedMesh=" + ((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)null) + "; TerrainComp=" + ((Object)(object)island.Comp != (Object)null) + "; shell=False; customCollider=False");
		}

		internal static void ShapeBuildData(Vector3 center, HMBuildData data)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_007c: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			Island island = Find(center);
			if (!Enabled || island == null || data == null || data.m_width != 128)
			{
				return;
			}
			int num = 129;
			float num2 = 64f;
			WorldGenerator instance = WorldGenerator.instance;
			Color val = default(Color);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					int num3 = i * num + j;
					float num4 = center.x - num2 + (float)j;
					float num5 = center.z - num2 + (float)i;
					float biomeHeight = instance.GetBiomeHeight((Biome)1, num4, num5, ref val, false, true);
					float num6 = (num4 - center.x) / 64f;
					float num7 = (num5 - center.z) / 64f;
					float num8 = Mathf.Clamp01(1f - Mathf.Sqrt(num6 * num6 + num7 * num7));
					data.m_baseHeights[num3] = Mathf.Clamp(biomeHeight * 0.25f, -8f, 8f) - (1f - num8) * 7f;
					data.m_baseMask[num3] = val;
				}
			}
			if (data.m_cornerBiomes != null)
			{
				for (int k = 0; k < data.m_cornerBiomes.Length; k++)
				{
					data.m_cornerBiomes[k] = BiomeSector.EmptyMeadows;
				}
			}
		}

		internal static Heightmap RouteHeightmap(Vector3 point, Heightmap vanilla)
		{
			//IL_0000: 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)
			Island island = Find(point);
			if (island == null || !(Mathf.Abs(point.y - 180f) <= 40f))
			{
				return vanilla;
			}
			return island.Map ?? vanilla;
		}

		internal static void RouteHeightmaps(Vector3 point, float radius, List<Heightmap> maps)
		{
			//IL_0000: 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)
			Island island = Find(point);
			if (island != null && Mathf.Abs(point.y - 180f) <= 40f && (Object)(object)island.Map != (Object)null && !maps.Contains(island.Map))
			{
				maps.Add(island.Map);
			}
		}

		internal static TerrainComp RouteCompiler(Vector3 point, TerrainComp vanilla)
		{
			//IL_0000: 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)
			Island island = Find(point);
			if (island == null || Mathf.Abs(point.y - 180f) > 40f)
			{
				return vanilla;
			}
			if (_creatingCompiler)
			{
				return null;
			}
			return island.Comp ?? vanilla;
		}

		internal static bool IsClusterMap(Heightmap map)
		{
			if ((Object)(object)map != (Object)null)
			{
				return ((Object)((Component)map).gameObject).name.StartsWith("FVB_ClusterLand_", StringComparison.Ordinal);
			}
			return false;
		}

		private static Island Find(Vector3 point)
		{
			//IL_0015: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			foreach (Island island in Islands)
			{
				if (Mathf.Abs(point.x - island.Center.x) <= 64f && Mathf.Abs(point.z - island.Center.y) <= 64f)
				{
					return island;
				}
			}
			for (int i = 0; i < Centers.Length; i++)
			{
				if (Mathf.Abs(point.x - Centers[i].x) <= 64f && Mathf.Abs(point.z - Centers[i].y) <= 64f)
				{
					return Get(i);
				}
			}
			return null;
		}

		private static void CheckBounds()
		{
			int num = 0;
			float num2 = float.MaxValue;
			float num3 = 0f;
			for (int i = 0; i < Centers.Length; i++)
			{
				for (int j = i + 1; j < Centers.Length; j++)
				{
					float num4 = Mathf.Max(0f, Mathf.Abs(Centers[i].x - Centers[j].x) - 128f);
					float num5 = Mathf.Max(0f, Mathf.Abs(Centers[i].y - Centers[j].y) - 128f);
					if (num4 == 0f && num5 == 0f)
					{
						num++;
					}
					float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5);
					num2 = Mathf.Min(num2, num6);
					num3 = Mathf.Max(num3, num6);
				}
			}
			Log("BOUNDS-OVERLAP overlapCount=" + num + "; result=" + ((num == 0) ? "PASS" : "FAIL"));
			Log("CONNECTIVITY-VISUAL nearestUsableEdge=8..30m; minTechnicalGap=" + num2.ToString("F1") + "; maxTechnicalGap=" + num3.ToString("F1"));
		}

		private static int Seed(string id)
		{
			return ((WorldGenerator.instance != null) ? WorldGenerator.instance.GetSeed() : 0) ^ StringExtensionMethods.GetStableHashCode(id);
		}

		private static string LayoutText()
		{
			string text = string.Empty;
			for (int i = 0; i < Centers.Length; i++)
			{
				text = text + ((i == 0) ? "" : ";") + i + "=(" + Centers[i].x + "," + Centers[i].y + ")";
			}
			return text;
		}

		private static void Log(string message)
		{
			FvbLog.Info(_plugin.Log, "CLUSTER", "[FVB/CLUSTER] " + message);
		}
	}
	[HarmonyPatch(typeof(ClutterSystem), "GetGroundInfo")]
	internal static class ClutterGroundRouting
	{
		private sealed class Probe
		{
			internal Vector3 Query;

			internal Heightmap Selected;

			internal Heightmap Direct;

			internal Heightmap Parent;

			internal RaycastHit Hit;

			internal bool HitFound;

			internal Collider SideCollider;

			internal bool SideHitRejected;
		}

		private static readonly FieldInfo PlaceRayMask = AccessTools.Field(typeof(ClutterSystem), "m_placeRayMask") ?? throw new MissingFieldException(typeof(ClutterSystem).FullName, "m_placeRayMask");

		private static bool _loggedFailure;

		private static bool _loggedSuccess;

		private static bool _loggedSideRejection;

		[HarmonyPrefix]
		private static void Before(ClutterSystem __instance, Vector3 __0, out Probe __state)
		{
			//IL_0003: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_004f: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			__state = null;
			Heightmap val = Heightmap.FindHeightmap(new Vector3(__0.x, 350f, __0.z));
			if (OrganicEdgeProofManager.IsCanonicalSurface(val))
			{
				Probe probe = new Probe
				{
					Query = __0,
					Selected = val
				};
				int num = (int)PlaceRayMask.GetValue(__instance);
				probe.HitFound = Physics.Raycast(__0 + Vector3.up * 500f, Vector3.down, ref probe.Hit, 1000f, num);
				RaycastHit val2 = default(RaycastHit);
				if (!_loggedSideRejection && Physics.Raycast(__0 + Vector3.up * 500f, Vector3.down, ref val2, 1000f, num | LayerMask.GetMask(new string[1] { "static_solid" })) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && ((Object)((Component)((RaycastHit)(ref val2)).collider).gameObject).name == "FVB_OrganicV4Sides" && OrganicEdgeProofManager.IsCanonicalSurface(((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Heightmap>()))
				{
					probe.SideCollider = ((RaycastHit)(ref val2)).collider;
					probe.SideHitRejected = (num & (1 << ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer)) == 0;
				}
				if (probe.HitFound && (Object)(object)((RaycastHit)(ref probe.Hit)).collider != (Object)null)
				{
					probe.Direct = ((Component)((RaycastHit)(ref probe.Hit)).collider).GetComponent<Heightmap>();
					probe.Parent = ((Component)((RaycastHit)(ref probe.Hit)).collider).GetComponentInParent<Heightmap>();
				}
				__state = probe;
			}
		}

		[HarmonyPostfix]
		private static void After(Probe __state, Vector3 __1, Vector3 __2, Heightmap __3, Biome __4, bool __result)
		{
			//IL_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				return;
			}
			if ((Object)(object)__state.SideCollider != (Object)null)
			{
				if (_loggedSideRejection)
				{
					return;
				}
				_loggedSideRejection = true;
			}
			else
			{
				if (_loggedSuccess)
				{
					return;
				}
				_loggedSuccess = true;
			}
			Log(__state, __3, __4, __1, __2, __result, "none", "PASS");
		}

		[HarmonyFinalizer]
		private static Exception OnException(Exception __exception, Probe __state)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (__exception != null && __state != null && !_loggedFailure)
			{
				_loggedFailure = true;
				string failure = ((__state.HitFound && (Object)(object)((RaycastHit)(ref __state.Hit)).collider != (Object)null && (Object)(object)__state.Direct == (Object)null) ? "hitCollider.GetComponent<Heightmap>" : "GetGroundInfo/unknown");
				Log(__state, __state.Direct, (Biome)0, ((RaycastHit)(ref __state.Hit)).point, ((RaycastHit)(ref __state.Hit)).normal, found: false, failure, "FAIL");
			}
			return __exception;
		}

		private unsafe static void Log(Probe probe, Heightmap map, Biome biome, Vector3 ground, Vector3 normal, bool found, string failure, string result)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			FehuVanillaBiomesPlugin instance = FehuVanillaBiomesPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				string text = ((probe.HitFound && (Object)(object)((RaycastHit)(ref probe.Hit)).collider != (Object)null) ? (((Object)((Component)((RaycastHit)(ref probe.Hit)).collider).gameObject).name + "#" + ((Object)((RaycastHit)(ref probe.Hit)).collider).GetInstanceID()) : "none");
				Collider val = (((Object)(object)probe.SideCollider != (Object)null) ? probe.SideCollider : ((RaycastHit)(ref probe.Hit)).collider);
				Heightmap val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Heightmap>() : null);
				Heightmap val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Heightmap>() : null);
				ManualLogSource log = instance.Log;
				string[] array = new string[46];
				array[0] = "[FVB/CLUTTER] point=";
				Vector3 query = probe.Query;
				array[1] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString();
				array[2] = "; queryY=";
				array[3] = probe.Query.y.ToString("F1");
				array[4] = "; selectedHeightmap=";
				array[5] = (((Object)(object)map != (Object)null) ? ((Object)map).GetInstanceID().ToString() : "none");
				array[6] = "; selectedHeightmapCenter=";
				array[7] = (((Object)(object)map != (Object)null) ? ((object)((Component)map).transform.position/*cast due to .constrained prefix*/).ToString() : "none");
				array[8] = "; selectedHeightmapY=";
				array[9] = (((Object)(object)map != (Object)null) ? ((Component)map).transform.position.y.ToString("F1") : "none");
				array[10] = "; selectedIsCanonical=";
				array[11] = OrganicEdgeProofManager.IsCanonicalSurface(map).ToString();
				array[12] = "; canonicalCandidate=";
				array[13] = ((Object)probe.Selected).GetInstanceID().ToString();
				array[14] = "; colliderDirectHeightmap=";
				array[15] = (((Object)(object)probe.Direct != (Object)null) ? ((Object)probe.Direct).GetInstanceID().ToString() : "none");
				array[16] = "; colliderParentHeightmap=";
				array[17] = (((Object)(object)probe.Parent != (Object)null) ? ((Object)probe.Parent).GetInstanceID().ToString() : "none");
				array[18] = "; biome=";
				array[19] = ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString();
				array[20] = "; groundPoint=";
				query = ground;
				array[21] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString();
				array[22] = "; groundNormal=";
				query = normal;
				array[23] = ((object)(*(Vector3*)(&query))/*cast due to .constrained prefix*/).ToString();
				array[24] = "; groundCollider=";
				array[25] = text;
				array[26] = "; groundFound=";
				array[27] = found.ToString();
				array[28] = "; failureStage=";
				array[29] = failure;
				array[30] = "; hitCollider=";
				array[31] = (((Object)(object)val != (Object)null) ? ((Object)((Component)val).gameObject).name : "none");
				array[32] = "; isSideCollider=";
				array[33] = ((Object)(object)probe.SideCollider != (Object)null).ToString();
				array[34] = "; directHeightmap=";
				array[35] = (((Object)(object)val2 != (Object)null) ? ((Object)val2).GetInstanceID().ToString() : "none");
				array[36] = "; parentHeightmap=";
				array[37] = (((Object)(object)val3 != (Object)null) ? ((Object)val3).GetInstanceID().ToString() : "none");
				array[38] = "; canonicalHeightmap=";
				array[39] = ((Object)probe.Selected).GetInstanceID().ToString();
				array[40] = "; sideHitRejected=";
				array[41] = probe.SideHitRejected.ToString();
				array[42] = "; fallbackTopHit=";
				array[43] = ((Object)(object)probe.SideCollider != (Object)null && found && OrganicEdgeProofManager.IsCanonicalSurface(map)).ToString();
				array[44] = "; result=";
				array[45] = result;
				FvbLog.Info(log, "CLUTTER", string.Concat(array));
			}
		}
	}
	internal static class ElevatedBiomePopulation
	{
		private readonly struct Placement
		{
			internal readonly Vector3 Position;

			internal readonly Quaternion Rotation;

			internal readonly float Scale;

			internal Placement(Vector3 position, Quaternion rotation, float scale)
			{
				//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)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Position = position;
				Rotation = rotation;
				Scale = scale;
			}
		}

		internal const string LogPrefix = "[FVB/BIOME-POP]";

		internal const int PopulationVersion = 1;

		internal const string PopulationVersionKey = "FVB_PopulationVersion";

		internal const string PopulationCompleteKey = "FVB_PopulationComplete";

		internal const string PopulationIslandKey = "FVB_PopulationIslandId";

		internal const string PopulationSlotKey = "FVB_PopulationSlotId";

		internal const string PopulationCategoryKey = "FVB_PopulationCategory";

		private const int TreeCap = 60;

		private const int BushCap = 48;

		private const int RockCap = 36;

		private const int ClutterCap = 160;

		private const int EquivalentVanillaZones = 4;

		private static readonly MethodInfo CreateObjectMethod = typeof(ZNetScene).GetMethod("CreateObject", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(ZDO) }, null) ?? throw new MissingMethodException("ZNetScene.CreateObject(ZDO)");

		private static readonly FieldInfo ObjectsByIdField = typeof(ZDOMan).GetField("m_objectsByID", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new MissingFieldException("ZDOMan.m_objectsByID");

		private static FehuVanillaBiomesPlugin _plugin;

		private static Coroutine _populationCoroutine;

		private static string _world = string.Empty;

		private static string _completedWorld = string.Empty;

		private static GameObject _clutterRoot;

		private static bool _clutterComplete;

		internal static void Start(FehuVanillaBiomesPlugin plugin)
		{
			_plugin = plugin;
		}

		internal static void Stop()
		{
			if ((Object)(object)_plugin != (Object)null && _populationCoroutine != null)
			{
				((MonoBehaviour)_plugin).StopCoroutine(_populationCoroutine);
			}
			_populationCoroutine = null;
			if ((Object)(object)_clutterRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_clutterRoot);
			}
			_clutterRoot = null;
			_clutterComplete = false;
			_world = string.Empty;
			_completedWorld = string.Empty;
			_plugin = null;
		}

		internal static void ResetWorld(string world)
		{
			if ((Object)(object)_plugin != (Object)null && _populationCoroutine != null)
			{
				((MonoBehaviour)_plugin).StopCoroutine(_populationCoroutine);
			}
			_populationCoroutine = null;
			if ((Object)(object)_clutterRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_clutterRoot);
			}
			_clutterRoot = null;
			_clutterComplete = false;
			_completedWorld = string.Empty;
			_world = world;
		}

		internal static void Ensure(Heightmap map, TerrainComp compiler, string world, float centerX, float centerZ, float layerY)
		{
			if (!((Object)(object)_plugin == (Object)null) && !((Object)(object)map == (Object)null) && !((Object)(object)compiler == (Object)null) && !string.IsNullOrEmpty(world))
			{
				if (!_clutterComplete)
				{
					BuildLocalClutter(map, world, centerX, centerZ, layerY);
				}
				if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && _populationCoroutine == null && !(_completedWorld == world))
				{
					_populationCoroutine = ((MonoBehaviour)_plugin).StartCoroutine(PopulateServer(map, compiler, world, centerX, centerZ, layerY));
				}
			}
		}

		internal static void OnHeightmapRegenerated(Heightmap map)
		{
			if (!((Object)(object)map == (Object)null) && !((Object)(object)map != (Object)(object)LargeElevatedMeadowsIsland.Heightmap) && _clutterComplete)
			{
				if ((Object)(object)_clutterRoot != (Object)null)
				{
					Object.Destroy((Object)(object)_clutterRoot);
				}
				_clutterRoot = null;
				_clutterComplete = false;
			}
		}

		private static IEnumerator PopulateServer(Heightmap map, TerrainComp compiler, string world, float centerX, float centerZ, float layerY)
		{
			List<ZDO> list = new List<ZDO>();
			try
			{
				ZNetView component = ((Component)compiler).GetComponent<ZNetView>();
				ZDO val = (((Object)(object)component != (Object)null) ? component.GetZDO() : null);
				if (val == null)
				{
					throw new InvalidOperationException("Large TerrainComp has no persistent ZDO.");
				}
				int duplicates;
				Dictionary<string, ZDO> dictionary = FindPopulationObjects(out duplicates);
				if (duplicates > 0)
				{
					throw new InvalidOperationException($"duplicate stable population slots detected: {duplicates}");
				}
				if (val.GetBool("FVB_PopulationComplete", false) && val.GetInt("FVB_PopulationVersion", 0) == 1)
				{
					_completedWorld = world;
					int num = CountCategory(dictionary.Values, "tree");
					int num2 = CountCategory(dictionary.Values, "bush");
					int num3 = CountCategory(dictionary.Values, "rock");
					Log($"COMPLETE restore=true; persistentObjects={dictionary.Count}; duplicatesSkipped={dictionary.Count}; trees={num}; bushes={num2}; rocks={num3}; clutterSlots={(_clutterComplete ? 160 : 0)}; locations=0; caveFeatures=0");
					yield break;
				}
				Log(string.Format("BEGIN world={0}; identity={1}; version={2}; seed={3}; existingSlots={4}", world, "elevated-meadows-large-v1", 1, PopulationSeed(world), dictionary.Count));
				List<ZoneVegetation> source = ZoneSystem.instance.m_vegetation.Where((ZoneVegetation definition) => definition != null && definition.m_enable && (Object)(object)definition.m_prefab != (Object)null && (definition.m_biome & 1) != 0 && (definition.m_biomeArea & 2) > 0).ToList();
				List<ZoneVegetation> definitions = source.Where((ZoneVegetation definition) => IsTree(((Object)definition.m_prefab).name)).ToList();
				List<ZoneVegetation> definitions2 = source.Where((ZoneVegetation definition) => IsBush(((Object)definition.m_prefab).name)).ToList();
				List<ZoneVegetation> definitions3 = source.Where((ZoneVegetation definition) => IsRock(((Object)definition.m_prefab).name)).ToList();
				Random random = new Random(PopulationSeed(world));
				List<Vector3> occupied = new List<Vector3>();
				int duplicatesSkipped = 0;
				int num4 = PlaceCategory("tree", definitions, 60, 4f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped);
				Log($"VEGETATION trees={num4}; treeDefinitions={Names(definitions)}");
				int num5 = PlaceCategory("bush", definitions2, 48, 2f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped);
				Log($"VEGETATION bushes={num5}; bushDefinitions={Names(definitions2)}");
				int num6 = PlaceCategory("rock", definitions3, 36, 3f, map, centerX, centerZ, layerY, random, occupied, dictionary, list, ref duplicatesSkipped);
				Log($"ROCKS rocks={num6}; rockDefinitions={Names(definitions3)}");
				Log("LOCATIONS locations=0; status=deferred; reason=vanilla location identity and generation are X/Z-zone scoped");
				Log("CAVE caveFeatures=0; status=deferred; reason=no audited persistent vanilla shelter assembly is safe for first population pass");
				Log("ANIMALS mode=vanilla-biome-routing; globalSpawnTablesModified=false");
				val.Set("FVB_PopulationVersion", 1);
				val.Set("FVB_PopulationComplete", true);
				_completedWorld = world;
				Log($"COMPLETE trees={num4}; bushes={num5}; rocks={num6}; clutterSlots={(_clutterComplete ? 160 : 0)}; persistentObjects={dictionary.Count + list.Count}; locations=0; caveFeatures=0; duplicatesSkipped={duplicatesSkipped}");
			}
			catch (Exception ex)
			{
				Rollback(list);
				LogError("population transaction rolled back; completion marker NOT written: " + ex);
			}
			finally
			{
				_populationCoroutine = null;
			}
		}

		private static int PlaceCategory(string category, List<ZoneVegetation> definitions, int cap, float spacing, Heightmap map, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, Dictionary<string, ZDO> existing, List<ZDO> created, ref int duplicatesSkipped)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if (definitions.Count == 0)
			{
				return 0;
			}
			Shuffle(definitions, random);
			int num = 0;
			int num2 = 0;
			foreach (ZoneVegetation definition in definitions)
			{
				int num3 = DefinitionGroupBudget(definition, random);
				for (int i = 0; i < num3; i++)
				{
					if (num >= cap)
					{
						break;
					}
					Vector2 groupCenter = RandomFootprint(random, centerX, centerZ, 57f);
					int num4 = Math.Max(1, random.Next(Math.Max(1, definition.m_groupSizeMin), Math.Max(1, definition.m_groupSizeMax) + 1));
					for (int j = 0; j < num4; j++)
					{
						if (num >= cap)
						{
							break;
						}
						string text = $"{category}:{num2++:D4}";
						Placement placement;
						if (existing.ContainsKey(text))
						{
							duplicatesSkipped++;
							num++;
						}
						else if (TryPlacement(definition, map, groupCenter, centerX, centerZ, layerY, random, occupied, spacing, out placement))
						{
							ZDO val = SpawnPersistent(definition, placement, text, category);
							if (val != null)
							{
								created.Add(val);
								occupied.Add(placement.Position);
								num++;
							}
						}
					}
				}
			}
			return num;
		}

		private static int DefinitionGroupBudget(ZoneVegetation definition, Random random)
		{
			if (definition.m_max < 1f)
			{
				return (random.NextDouble() <= (double)definition.m_max) ? 1 : 0;
			}
			int num = Math.Max(0, Mathf.FloorToInt(definition.m_min * 4f));
			int num2 = Math.Max(num, Mathf.CeilToInt(definition.m_max * 4f));
			return Math.Min(24, random.Next(num, num2 + 1));
		}

		private static bool TryPlacement(ZoneVegetation definition, Heightmap map, Vector2 groupCenter, float centerX, float centerZ, float layerY, Random random, List<Vector3> occupied, float spacing, out Placement placement)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			placement = default(Placement);
			float num3 = default(float);
			for (int i = 0; i < 24; i++)
			{
				float num = (float)(random.NextDouble() * Math.PI * 2.0);
				float num2 = definition.m_groupRadius * Mathf.Sqrt((float)random.NextDouble());
				Vector3 point = new Vector3(groupCenter.x + Mathf.Cos(num) * num2, layerY, groupCenter.y + Mathf.Sin(num) * num2);
				if (!TerrainLayerRoutingPolicy.IntersectsFootprint(point.x, point.z, 0f, centerX, centerZ, 59f) || !Heightmap.GetHeight(point, ref num3))
				{
					continue;
				}
				point.y = num3 + definition.m_groundOffset;
				if (map.IsCleared(point) || occupied.Any((Vector3 other) => HorizontalDistance(other, point) < spacing))
				{
					continue;
				}
				float num4 = num3 - layerY;
				if (num4 < definition.m_minAltitude || num4 > definition.m_maxAltitude)
				{
					continue;
				}
				float vegetationMask = map.GetVegetationMask(point);
				if (definition.m_minVegetation != definition.m_maxVegetation && (vegetationMask < definition.m_minVegetation || vegetationMask > definition.m_maxVegetation))
				{
					continue;
				}
				Vector3 val = SurfaceNormal(map, point);
				float y = val.y;
				float num5 = Mathf.Cos(definition.m_maxTilt * ((float)Math.PI / 180f));
				float num6 = Mathf.Cos(definition.m_minTilt * ((float)Math.PI / 180f));
				if (y < num5 || y > num6 || !PassTerrainDelta(definition, map, point))
				{
					continue;
				}
				Vector2 val2 = new Vector2(point.x, point.z);
				float magnitude = ((Vector2)(ref val2)).magnitude;
				if ((definition.m_minDistanceFromCenter > 0f && magnitude < definition.m_minDistanceFromCenter) || (definition.m_maxDistanceFromCenter > 0f && magnitude > definition.m_maxDistanceFromCenter))
				{
					continue;
				}
				if (definition.m_inForest)
				{
					float forestFactor = WorldGenerator.GetForestFactor(point);
					if (forestFactor < definition.m_forestTresholdMin || forestFactor > definition.m_forestTresholdMax)
					{
						continue;
					}
				}
				if ((!definition.m_surroundCheckVegetation || PassSurroundVegetation(definition, map, point)) && (!definition.m_blockCheck || !IsBlockedByNonTerrain(map, point)))
				{
					float num7 = (float)random.NextDouble() * 360f;
					float num8 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble());
					float num9 = Mathf.Lerp(0f - definition.m_randTilt, definition.m_randTilt, (float)random.NextDouble());
					Quaternion rotation = ((random.NextDouble() <= (double)definition.m_chanceToUseGroundTilt) ? (Quaternion.FromToRotation(Vector3.up, val) * Quaternion.Euler(0f, num7, 0f)) : Quaternion.Euler(num8, num7, num9));
					float scale = Mathf.Lerp(definition.m_scaleMin, definition.m_scaleMax, (float)random.NextDouble());
					placement = new Placement(point, rotation, scale);
					return true;
				}
			}
			return false;
		}

		private static bool PassTerrainDelta(ZoneVegetation definition, Heightmap map, Vector3 point)
		{
			//IL_0023: 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_002f: 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_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_004c: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (definition.m_terrainDeltaRadius <= 0f)
			{
				return true;
			}
			float num = float.MaxValue;
			float num2 = float.MinValue;
			Vector2[] array = (Vector2[])(object)new Vector2[4]
			{
				Vector2.left,
				Vector2.right,
				Vector2.up,
				Vector2.down
			};
			float num3 = default(float);
			foreach (Vector2 val in array)
			{
				if (!Heightmap.GetHeight(point + new Vector3(val.x * definition.m_terrainDeltaRadius, 0f, val.y * definition.m_terrainDeltaRadius), ref num3))
				{
					return false;
				}
				num = Mathf.Min(num, num3);
				num2 = Mathf.Max(num2, num3);
			}
			float num4 = num2 - num;
			if (num4 >= definition.m_minTerrainDelta)
			{
				return num4 <= definition.m_maxTerrainDelta;
			}
			return false;
		}

		private static bool PassSurroundVegetation(ZoneVegetation definition, Heightmap map, Vector3 point)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (definition.m_surroundCheckLayers <= 0 || definition.m_surroundCheckDistance <= 0f)
			{
				return true;
			}
			float num = 0f;
			int num2 = 0;
			for (int i = 1; i <= definition.m_surroundCheckLayers; i++)
			{
				for (int j = 0; j < 6; j++)
				{
					float num3 = (float)j / 6f * (float)Math.PI * 2f;
					float num4 = (float)i / (float)definition.m_surroundCheckLayers * definition.m_surroundCheckDistance;
					num += map.GetVegetationMask(point + new Vector3(Mathf.Sin(num3) * num4, 0f, Mathf.Cos(num3) * num4));
					num2++;
				}
			}
			float num5 = ((num2 > 0) ? (num / (float)num2) : 0f);
			if (num5 >= definition.m_minVegetation)
			{
				return num5 <= definition.m_maxVegetation;
			}
			return false;
		}

		private static bool IsBlockedByNonTerrain(Heightmap map, Vector3 point)
		{
			//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_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)
			Collider[] array = Physics.OverlapSphere(point + Vector3.up * 0.5f, 0.45f, -5, (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<Heightmap>() != (Object)(object)map)
				{
					return true;
				}
			}
			return false;
		}

		private static ZDO SpawnPersistent(ZoneVegetation definition, Placement placement, string slotId, string category)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = definition.m_prefab;
			ZNetView val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			int num = StableHash(((Object)prefab).name);
			if ((Object)(object)ZNetScene.instance.GetPrefab(((Object)prefab).name) != (Object)(object)prefab)
			{
				return null;
			}
			ZDO val2 = ZDOMan.instance.CreateNewZDO(placement.Position, num);
			if (val2 == null)
			{
				throw new InvalidOperationException("CreateNewZDO failed slot=" + slotId + "; prefab=" + ((Object)prefab).name);
			}
			val2.SetPrefab(num);
			val2.SetRotation(placement.Rotation);
			val2.Persistent = true;
			val2.Type = val.m_type;
			val2.Distant = val.m_distant;
			val2.Set("FVB_PopulationIslandId", "elevated-meadows-large-v1");
			val2.Set("FVB_PopulationSlotId", slotId);
			val2.Set("FVB_PopulationCategory", category);
			val2.Set("FVB_PopulationVersion", 1);
			object? obj = CreateObjectMethod.Invoke(ZNetScene.instance, new object[1] { val2 });
			GameObject val3 = (GameObject)((obj is GameObject) ? obj : null);
			ZNetView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ZNetView>() : null);
			if ((Object)(object)val4 == (Object)null || !val4.IsValid() || val4.GetZDO() == null)
			{
				ZDOMan.instance.DestroyZDO(val2);
				throw new InvalidOperationException("CreateObject validation failed slot=" + slotId + "; prefab=" + ((Object)prefab).name);
			}
			if (Mathf.Abs(placement.Scale - 1f) > 0.001f)
			{
				val4.SetLocalScale(Vector3.one * placement.Scale);
			}
			return val2;
		}

		private static Dictionary<string, ZDO> FindPopulationObjects(out int duplicates)
		{
			duplicates = 0;
			Dictionary<string, ZDO> dictionary = new Dictionary<string, ZDO>(StringComparer.Ordinal);
			if (!(ObjectsByIdField.GetValue(ZDOMan.instance) is Dictionary<ZDOID, ZDO> dictionary2))
			{
				return dictionary;
			}
			foreach (ZDO value in dictionary2.Values)
			{
				if (value == null || value.GetString("FVB_PopulationIslandId", string.Empty) != "elevated-meadows-large-v1")
				{
					continue;
				}
				string text = value.GetString("FVB_PopulationSlotId", string.Empty);
				if (!string.IsNullOrEmpty(text))
				{
					if (dictionary.ContainsKey(text))
					{
						duplicates++;
					}
					else
					{
						dictionary.Add(text, value);
					}
				}
			}
			return dictionary;
		}

		private static int CountCategory(IEnumerable<ZDO> objects, string category)
		{
			return objects.Count((ZDO zdo) => zdo != null && string.Equals(zdo.GetString("FVB_PopulationCategory", string.Empty), category, StringComparison.Ordinal));
		}

		private static void BuildLocalClutter(Heightmap map, string world, float centerX, float centerZ, float layerY)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result ty