Decompiled source of DiverseBiomes v2.4.1

BepInEx/plugins/DiverseBiomes/DiverseBiomes.GalacticScale.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using GalacticScale;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DiverseBiomes.GalacticScale
{
	public sealed class Adapter : IEcologyAdapter
	{
		private static readonly Dictionary<GSTheme, ThemeEcology> profiles = new Dictionary<GSTheme, ThemeEcology>();

		public bool AppliesTo(PlanetData planet)
		{
			if (planet?.galaxy != null && !GS2.Vanilla)
			{
				return GS2.GetGSPlanet(planet) != null;
			}
			return false;
		}

		public GenerationPolicy LegacyPolicy()
		{
			if (GS2.Vanilla || GSSettings.ThemeLibrary == null || !((Dictionary<string, GSTheme>)(object)GSSettings.ThemeLibrary).ContainsKey("LivingWorlds.Generation.v1"))
			{
				return null;
			}
			return EcologyGeneration.DecodePolicy(((Dictionary<string, GSTheme>)(object)GSSettings.ThemeLibrary)["LivingWorlds.Generation.v1"].BriefIntroduction);
		}

		public ThemeEcology ThemeFor(PlanetData planet)
		{
			GSPlanet gSPlanet = GS2.GetGSPlanet(planet);
			GSTheme val = ((gSPlanet != null) ? gSPlanet.GsTheme : null);
			if (val == null)
			{
				return ProfiledCommunities.Mineral;
			}
			lock (profiles)
			{
				if (profiles.TryGetValue(val, out var value))
				{
					return value;
				}
				value = Resolve(val);
				string baseName = val.BaseName;
				for (int i = 0; i < 8; i++)
				{
					if (!(value.Key == "Mineral") && !(value.Key == "Organic"))
					{
						break;
					}
					if (string.IsNullOrEmpty(baseName))
					{
						break;
					}
					if (GSSettings.ThemeLibrary == null)
					{
						break;
					}
					if (!((Dictionary<string, GSTheme>)(object)GSSettings.ThemeLibrary).ContainsKey(baseName))
					{
						break;
					}
					GSTheme val2 = ((Dictionary<string, GSTheme>)(object)GSSettings.ThemeLibrary)[baseName];
					ThemeEcology val3 = Resolve(val2);
					if (val3.Key != "Mineral" || value.Key == "Mineral")
					{
						value = val3;
					}
					if (val2.BaseName == baseName)
					{
						break;
					}
					baseName = val2.BaseName;
				}
				if (profiles.Count > 256)
				{
					profiles.Clear();
				}
				profiles[val] = value;
				return value;
			}
		}

		private static ThemeEcology Resolve(GSTheme theme)
		{
			return ProfiledCommunities.Resolve(theme.Name, theme.BaseName, ProfiledCommunities.HasLivingModels((IEnumerable<int[]>)new int[6][] { theme.Vegetables0, theme.Vegetables1, theme.Vegetables2, theme.Vegetables3, theme.Vegetables4, theme.Vegetables5 }));
		}

		public void Attach(Harmony harmony)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			EcologyAdapters.RegisterVegetationGenerator(harmony, typeof(GS2PlanetAlgorithm));
			MethodInfo methodInfo = AccessTools.Method(typeof(VeinAlgorithms), "CalculateVectorsGS2", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new MissingMethodException("GS2 vein-vector generation is unavailable.");
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Adapter), "PreferOreTerrain", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void PreferOreTerrain(GSPlanet gsPlanet, List<GSVeinDescriptor> __result, bool sketchOnly)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_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)
			//IL_0092: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			PlanetData val = gsPlanet?.planetData;
			GenerationPolicy val2 = EcologyAdapters.PolicyFor(val);
			if (sketchOnly || __result == null || val?.data == null || val2 == null || val2.Revision < 4 || val2.OreStrength <= 0f)
			{
				return;
			}
			List<OreCluster> list = new List<OreCluster>(__result.Count);
			foreach (GSVeinDescriptor item in __result)
			{
				list.Add(new OreCluster
				{
					position = item.position,
					count = item.count,
					type = item.type
				});
			}
			EcologyGeneration.AdjustClusters(val, (IList<OreCluster>)list, val2.OreStrength, gsPlanet.veinSettings.VeinPadding, (Func<Vector3, float>)null, val2.Revision);
			for (int i = 0; i < list.Count; i++)
			{
				__result[i].position = list[i].position;
			}
		}
	}
}

BepInEx/plugins/DiverseBiomes/DiverseBiomes.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using crecheng.DSPModSave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("2.4.0.0")]
[assembly: InternalsVisibleTo("DiverseBiomes.Checks")]
[assembly: AssemblyVersion("2.4.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DiverseBiomes
{
	internal static class BirthVegetationProfile
	{
		internal static bool IsBirth(PlanetData planet)
		{
			if (planet != null && planet.id > 0 && planet.galaxy != null)
			{
				return planet.galaxy.birthPlanetId == planet.id;
			}
			return false;
		}

		internal static PlanetVegetationProfile Create(PlanetData planet, DistributionSettings settings)
		{
			return VegetationDistribution.CreateProfileWithBirthOverride(planet.seed, planet.id, settings, IsBirth(planet));
		}

		internal static bool SyncFactory(PlanetFactory factory)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			PlanetData val = ((factory != null) ? factory.planet : null);
			if (!IsBirth(val) || !GiantVegetationApplicator.WasProcessed(val) || val.data?.vegePool == null || factory.vegePool == null)
			{
				return false;
			}
			VegeData[] vegePool = val.data.vegePool;
			if (vegePool == factory.vegePool)
			{
				return true;
			}
			for (int i = 1; i < Math.Min(factory.vegeCursor, factory.vegePool.Length) && i < Math.Min(val.data.vegeCursor, vegePool.Length); i++)
			{
				VegeData val2 = factory.vegePool[i];
				VegeData val3 = vegePool[i];
				if (val2.id == i && val3.id == i && val2.protoId == val3.protoId)
				{
					Vector3 val4 = val2.pos - val3.pos;
					if (!(((Vector3)(ref val4)).sqrMagnitude > 0.0001f))
					{
						factory.vegePool[i].scl = val3.scl;
					}
				}
			}
			return true;
		}
	}
	internal static class BuildingOverlapGeometry
	{
		internal struct Shape
		{
			internal EColliderShape Kind;

			internal Vector3 Center;

			internal Vector3 Extent;

			internal Quaternion Rotation;

			internal float Radius;

			internal float Reach
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Invalid comparison between Unknown and I4
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Invalid comparison between Unknown and I4
					if ((int)Kind != 1)
					{
						if ((int)Kind != 3)
						{
							return ((Vector3)(ref Extent)).magnitude + Radius;
						}
						return ((Vector3)(ref Extent)).magnitude;
					}
					return Radius;
				}
			}

			internal Shape(EColliderShape kind, Vector3 center, Quaternion rotation, Vector3 extent, float radius)
			{
				//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)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Invalid comparison between Unknown and I4
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: 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)
				Kind = kind;
				Center = center;
				Rotation = rotation;
				Extent = (Vector3)(((int)kind == 2) ? extent : new Vector3(Math.Abs(extent.x), Math.Abs(extent.y), Math.Abs(extent.z)));
				Radius = Math.Max(0f, radius);
			}
		}

		internal static bool Supported(ColliderData collider)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			if ((int)((ColliderData)(ref collider)).shape != 1 && (int)((ColliderData)(ref collider)).shape != 2)
			{
				return (int)((ColliderData)(ref collider)).shape == 3;
			}
			return true;
		}

		internal static Shape At(ColliderData prototype, Vector3 location, Quaternion rotation, Vector3 scale)
		{
			//IL_0002: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Math.Abs(scale.x), Math.Abs(scale.y), Math.Abs(scale.z));
			return new Shape(((ColliderData)(ref prototype)).shape, location + rotation * Vector3.Scale(prototype.pos, scale), rotation * prototype.q, Vector3.Scale(prototype.ext, val), prototype.radius * VegetationColliderGeometry.Largest(scale));
		}

		internal static Shape Spanning(ColliderData prototype, Vector3 first, Quaternion firstRotation, Vector3 second, Quaternion secondRotation)
		{
			//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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_008e: 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_0097: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = second - first;
			if (((Vector3)(ref val)).sqrMagnitude < 1E-08f)
			{
				return At(prototype, first, firstRotation, Vector3.one);
			}
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = firstRotation * Vector3.up + secondRotation * Vector3.up;
			Vector3 val3 = Vector3.Cross(val2, normalized);
			if (((Vector3)(ref val3)).sqrMagnitude < 1E-08f)
			{
				val3 = Vector3.Cross((Math.Abs(normalized.y) < 0.9f) ? Vector3.up : Vector3.right, normalized);
			}
			val3 = ((Vector3)(ref val3)).normalized;
			Vector3 val4 = Vector3.Cross(normalized, val3);
			val2 = ((Vector3)(ref val4)).normalized;
			Quaternion rotation = Frame(val3, val2, normalized);
			Shape result = At(prototype, (first + second) * 0.5f, rotation, Vector3.one);
			result.Extent.z += ((Vector3)(ref val)).magnitude * 0.5f;
			return result;
		}

		private static Quaternion Frame(Vector3 x, Vector3 y, Vector3 z)
		{
			//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_006c: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			float num = x.x + y.y + z.z;
			if (num > 0f)
			{
				float num2 = (float)Math.Sqrt(1f + num) * 2f;
				return new Quaternion((y.z - z.y) / num2, (z.x - x.z) / num2, (x.y - y.x) / num2, num2 * 0.25f);
			}
			if (x.x > y.y && x.x > z.z)
			{
				float num3 = (float)Math.Sqrt(1f + x.x - y.y - z.z) * 2f;
				return new Quaternion(num3 * 0.25f, (y.x + x.y) / num3, (z.x + x.z) / num3, (y.z - z.y) / num3);
			}
			if (y.y > z.z)
			{
				float num4 = (float)Math.Sqrt(1f + y.y - x.x - z.z) * 2f;
				return new Quaternion((y.x + x.y) / num4, num4 * 0.25f, (z.y + y.z) / num4, (z.x - x.z) / num4);
			}
			float num5 = (float)Math.Sqrt(1f + z.z - x.x - y.y) * 2f;
			return new Quaternion((z.x + x.z) / num5, (z.y + y.z) / num5, num5 * 0.25f, (x.y - y.x) / num5);
		}

		internal static bool Overlaps(Shape first, Shape second)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00e1: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			float num = first.Reach + second.Reach;
			Vector3 val = first.Center - second.Center;
			if (((Vector3)(ref val)).sqrMagnitude >= num * num)
			{
				return false;
			}
			Vector3 direction = first.Center - second.Center;
			if (((Vector3)(ref direction)).sqrMagnitude < 1E-10f)
			{
				((Vector3)(ref direction))..ctor(1f, 0.37f, 0.19f);
			}
			Vector3[] array = (Vector3[])(object)new Vector3[4]
			{
				Difference(first, second, direction),
				default(Vector3),
				default(Vector3),
				default(Vector3)
			};
			int num2 = 1;
			Vector3 val2 = array[0];
			for (int i = 0; i < 40; i++)
			{
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude < 1E-08f)
				{
					return true;
				}
				Vector3 val3 = Difference(first, second, -val2);
				if (sqrMagnitude - Vector3.Dot(val2, val3) <= 1E-07f * Math.Max(1f, sqrMagnitude))
				{
					return false;
				}
				bool flag = false;
				for (int j = 0; j < num2; j++)
				{
					val = array[j] - val3;
					if (((Vector3)(ref val)).sqrMagnitude < 1E-12f)
					{
						flag = true;
					}
				}
				if (flag || num2 == 4)
				{
					return false;
				}
				array[num2++] = val3;
				float num3 = float.PositiveInfinity;
				int num4 = 0;
				Vector3 val4 = default(Vector3);
				for (int k = 1; k < 1 << num2; k++)
				{
					if (Project(array, num2, k, out var projection))
					{
						float sqrMagnitude2 = ((Vector3)(ref projection)).sqrMagnitude;
						if (sqrMagnitude2 < num3)
						{
							num3 = sqrMagnitude2;
							num4 = k;
							val4 = projection;
						}
					}
				}
				if (num4 == 0)
				{
					return false;
				}
				int num5 = 0;
				for (int l = 0; l < num2; l++)
				{
					if ((num4 & (1 << l)) != 0)
					{
						array[num5++] = array[l];
					}
				}
				num2 = num5;
				val2 = val4;
			}
			return false;
		}

		private static Vector3 Difference(Shape first, Shape second, Vector3 direction)
		{
			//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)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return Support(first, direction) - Support(second, -direction);
		}

		private static Vector3 Support(Shape shape, Vector3 direction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0011: 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_0051: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0064: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_015a: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			float magnitude = ((Vector3)(ref direction)).magnitude;
			if (magnitude < 1E-10f)
			{
				return shape.Center;
			}
			if ((int)shape.Kind == 1)
			{
				return shape.Center + direction * (Math.Max(0f, shape.Radius - 0.0005f) / magnitude);
			}
			if ((int)shape.Kind == 2)
			{
				Vector3 val = shape.Rotation * shape.Extent;
				return shape.Center + ((Vector3.Dot(val, direction) >= 0f) ? val : (-val)) + direction * (Math.Max(0f, shape.Radius - 0.0005f) / magnitude);
			}
			Quaternion rotation = shape.Rotation;
			float num = rotation.x * rotation.x + rotation.y * rotation.y + rotation.z * rotation.z + rotation.w * rotation.w;
			Vector3 val2 = (Quaternion)((num < 1E-12f) ? Quaternion.identity : new Quaternion((0f - rotation.x) / num, (0f - rotation.y) / num, (0f - rotation.z) / num, rotation.w / num)) * direction;
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(Signed(Math.Max(0f, shape.Extent.x - 0.0005f), val2.x), Signed(Math.Max(0f, shape.Extent.y - 0.0005f), val2.y), Signed(Math.Max(0f, shape.Extent.z - 0.0005f), val2.z));
			return shape.Center + shape.Rotation * val3;
		}

		private static float Signed(float size, float direction)
		{
			if (!(direction < 0f))
			{
				return size;
			}
			return 0f - size;
		}

		private static bool Project(Vector3[] points, int count, int mask, out Vector3 projection)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//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_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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b6: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00d8: 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_00e4: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: 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_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_02fe: Unknown result type (might be due to invalid IL or missing references)
			int num = -1;
			int num2 = -1;
			int num3 = -1;
			int num4 = -1;
			for (int i = 0; i < count; i++)
			{
				if ((mask & (1 << i)) != 0)
				{
					if (num < 0)
					{
						num = i;
					}
					else if (num2 < 0)
					{
						num2 = i;
					}
					else if (num3 < 0)
					{
						num3 = i;
					}
					else
					{
						num4 = i;
					}
				}
			}
			Vector3 val = (projection = points[num]);
			if (num2 < 0)
			{
				return true;
			}
			Vector3 val2 = points[num2] - val;
			Vector3 val3 = (Vector3)((num3 < 0) ? default(Vector3) : (points[num3] - val));
			Vector3 val4 = (Vector3)((num4 < 0) ? default(Vector3) : (points[num4] - val));
			double num5 = Vector3.Dot(val2, val2);
			double num6 = Vector3.Dot(val2, val3);
			double num7 = Vector3.Dot(val2, val4);
			double num8 = Vector3.Dot(val3, val3);
			double num9 = Vector3.Dot(val3, val4);
			double num10 = Vector3.Dot(val4, val4);
			double num11 = 0f - Vector3.Dot(val2, val);
			double num12 = 0f - Vector3.Dot(val3, val);
			double num13 = 0f - Vector3.Dot(val4, val);
			double num14 = 0.0;
			double num15 = 0.0;
			double num16;
			if (num3 < 0)
			{
				if (num5 < 1E-18)
				{
					return false;
				}
				num16 = num11 / num5;
			}
			else if (num4 < 0)
			{
				double num17 = num5 * num8 - num6 * num6;
				if (Math.Abs(num17) < 1E-12 * Math.Max(1.0, num5 * num8))
				{
					return false;
				}
				num16 = (num11 * num8 - num12 * num6) / num17;
				num14 = (num12 * num5 - num11 * num6) / num17;
			}
			else
			{
				double num18 = num5 * (num8 * num10 - num9 * num9) - num6 * (num6 * num10 - num9 * num7) + num7 * (num6 * num9 - num8 * num7);
				if (Math.Abs(num18) < 1E-12 * Math.Max(1.0, num5 * num8 * num10))
				{
					return false;
				}
				num16 = (num11 * (num8 * num10 - num9 * num9) - num6 * (num12 * num10 - num9 * num13) + num7 * (num12 * num9 - num8 * num13)) / num18;
				num14 = (num5 * (num12 * num10 - num9 * num13) - num11 * (num6 * num10 - num9 * num7) + num7 * (num6 * num13 - num12 * num7)) / num18;
				num15 = (num5 * (num8 * num13 - num12 * num9) - num6 * (num6 * num13 - num12 * num7) + num11 * (num6 * num9 - num8 * num7)) / num18;
			}
			if (num16 < 0.0 || num14 < 0.0 || num15 < 0.0 || num16 + num14 + num15 > 1.0)
			{
				return false;
			}
			projection = ((num4 >= 0) ? Vector3.zero : (val + val2 * (float)num16 + val3 * (float)num14));
			return true;
		}
	}
	internal static class ColliderHooks
	{
		internal static void Apply(Harmony harmony)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0112: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(ColliderData), "BindToObject", new Type[6]
			{
				typeof(int),
				typeof(int),
				typeof(EObjectType),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(Vector3)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(PlanetPhysics), "AddColliderData", new Type[1] { typeof(ColliderData) }, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(ColliderData) || methodInfo2 == null || methodInfo2.ReturnType != typeof(int))
			{
				throw new MissingMethodException("Vegetation collider registration API changed.");
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ColliderHooks), "UsePhysicalScale", (Type[])null), new HarmonyMethod(typeof(ColliderHooks), "BoundVegetation", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(ColliderHooks), "RegisterVegetation", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void BoundVegetation(ColliderData __instance, [HarmonyArgument(2)] EObjectType kind, [HarmonyArgument(5)] Vector3 scale, ref ColliderData __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)kind == 1 && ((ColliderData)(ref __result)).objId > 0)
			{
				VegetationColliderGeometry.CorrectScaledRadius(__instance, scale, ref __result);
			}
		}

		private static bool RegisterVegetation([HarmonyArgument(0)] ColliderData collider, ref int __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (!ModConfig.DisablePlayerVegetationCollision || (int)((ColliderData)(ref collider)).objType != 1)
			{
				return true;
			}
			__result = 0;
			return false;
		}

		private static void UsePhysicalScale([HarmonyArgument(2)] EObjectType kind, [HarmonyArgument(5)] ref Vector3 scale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)kind == 1)
			{
				float cap = Math.Max(1f, ModConfig.MaximumPlayerColliderScale);
				scale = new Vector3(Capped(scale.x, cap), Capped(scale.y, cap), Capped(scale.z, cap));
			}
		}

		private static float Capped(float value, float cap)
		{
			if (!(value < 0f))
			{
				return Math.Min(value, cap);
			}
			return 0f - Math.Min(0f - value, cap);
		}
	}
	public enum CommunityKind
	{
		RiparianForest,
		MeadowWoodland,
		HighlandScrub,
		PolarTundra,
		AridScrub,
		AncientGrove
	}
	public struct TerrainTraits
	{
		public float Elevation;

		public float Slope;

		public float Latitude;

		public float Patch;

		public float Moisture;

		public float Detail;

		public bool HasWater;

		public bool Cold;

		public bool Dry;
	}
	public struct CommunitySample
	{
		public CommunityKind Kind;

		public float Retention;

		public float SmallShare;

		public float MediumShare;

		public int Revision;

		public string BiomeName;

		public float TreeScale;

		public float GrassRetention;

		public float GrassLargeFactor;

		public float DecorationScale;

		public CommunitySample(CommunityKind kind, float retention, float small, float medium, int revision = 1)
		{
			Kind = kind;
			Retention = retention;
			SmallShare = small;
			MediumShare = medium;
			Revision = revision;
			BiomeName = null;
			TreeScale = 1f;
			GrassRetention = -1f;
			GrassLargeFactor = 1f;
			DecorationScale = 1f;
		}
	}
	public static class CommunityDesign
	{
		public static CommunitySample Choose(TerrainTraits t, bool refined = false)
		{
			if (refined)
			{
				return Refined(t);
			}
			if (t.Cold || t.Latitude > 0.8f)
			{
				return new CommunitySample(CommunityKind.PolarTundra, 0.26f + 0.25f * t.Patch, 0.82f, 0.16f);
			}
			if (t.Slope > 0.48f || t.Elevation > 4.2f)
			{
				return new CommunitySample(CommunityKind.HighlandScrub, 0.3f + 0.3f * t.Patch, 0.68f, 0.28f);
			}
			if (t.Dry && t.Moisture < 0.66f)
			{
				return new CommunitySample(CommunityKind.AridScrub, 0.24f + 0.3f * t.Patch, 0.74f, 0.23f);
			}
			if (t.HasWater && t.Elevation < 1.6f && t.Slope < 0.2f)
			{
				return new CommunitySample(CommunityKind.RiparianForest, 0.84f + 0.14f * t.Patch, 0.12f, 0.52f);
			}
			if (t.Patch > 0.62f && t.Moisture > 0.55f && t.Slope < 0.22f)
			{
				return new CommunitySample(CommunityKind.AncientGrove, 0.88f, 0.1f, 0.32f);
			}
			return new CommunitySample(CommunityKind.MeadowWoodland, 0.35f + 0.48f * t.Patch, 0.34f, 0.52f);
		}

		private static CommunitySample Refined(TerrainTraits t)
		{
			if (t.Cold || t.Latitude > 0.78f)
			{
				return new CommunitySample(CommunityKind.PolarTundra, 0.16f + 0.2f * t.Patch, 0.94f, 0.055f, 2);
			}
			if (t.Slope > 0.38f || t.Elevation > 5f)
			{
				return new CommunitySample(CommunityKind.HighlandScrub, 0.2f + 0.22f * t.Patch, 0.86f, 0.13f, 2);
			}
			if (t.Dry && t.Moisture < 0.7f)
			{
				return new CommunitySample(CommunityKind.AridScrub, 0.16f + 0.24f * t.Patch, 0.9f, 0.09f, 2);
			}
			if (t.HasWater && t.Elevation < 1.65f && t.Slope < 0.18f)
			{
				return new CommunitySample(CommunityKind.RiparianForest, 0.86f + 0.12f * t.Patch, 0.08f, 0.62f, 2);
			}
			if (t.Patch > 0.58f && t.Moisture > 0.48f && t.Slope < 0.18f)
			{
				return new CommunitySample(CommunityKind.AncientGrove, 0.94f, 0.04f, 0.2f, 2);
			}
			float num = Math.Max(0f, Math.Min(1f, (t.Patch - 0.28f) / 0.4f));
			num = num * num * (3f - 2f * num);
			return new CommunitySample(CommunityKind.MeadowWoodland, 0.22f + 0.48f * num, 0.54f, 0.42f, 2);
		}

		internal static float SizeMultiplier(PlanetVegetationProfile profile, CommunitySample sample, uint key)
		{
			float num = Unit(key ^ 0x7E119D23);
			float num2 = ((!(num < sample.SmallShare)) ? ((num < sample.SmallShare + sample.MediumShare) ? 1 : 2) : 0) switch
			{
				1 => profile.SecondPeak, 
				0 => profile.FirstPeak, 
				_ => profile.ThirdPeak, 
			};
			if (sample.Revision == 2)
			{
				float num3 = ((sample.Kind == CommunityKind.AncientGrove) ? 1.08f : ((sample.Kind == CommunityKind.PolarTundra) ? 0.88f : ((sample.Kind == CommunityKind.HighlandScrub || sample.Kind == CommunityKind.AridScrub) ? 0.92f : 1f)));
				num2 *= num3;
			}
			if (sample.Revision >= 3)
			{
				num2 *= sample.TreeScale;
			}
			return Math.Max(1f, Math.Min(7f, num2 * (0.94f + 0.12f * Unit(key ^ 0x184BD38F))));
		}

		public static float Unit(uint x)
		{
			x ^= x >> 16;
			x *= 2146121005;
			x ^= x >> 15;
			x *= 2221713035u;
			x ^= x >> 16;
			return (float)(x & 0xFFFFFF) / 16777216f;
		}

		public static float PatchNoise(Vector3 direction, int seed, float frequency)
		{
			//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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			double num = direction.x * frequency;
			double num2 = direction.y * frequency;
			double num3 = direction.z * frequency;
			int num4 = (int)Math.Floor(num);
			int num5 = (int)Math.Floor(num2);
			int num6 = (int)Math.Floor(num3);
			float t = Smooth((float)(num - (double)num4));
			float t2 = Smooth((float)(num2 - (double)num5));
			float t3 = Smooth((float)(num3 - (double)num6));
			float a = Lerp(Hash(num4, num5, num6, seed), Hash(num4 + 1, num5, num6, seed), t);
			float b = Lerp(Hash(num4, num5 + 1, num6, seed), Hash(num4 + 1, num5 + 1, num6, seed), t);
			float a2 = Lerp(Hash(num4, num5, num6 + 1, seed), Hash(num4 + 1, num5, num6 + 1, seed), t);
			return Lerp(b: Lerp(a2, Lerp(Hash(num4, num5 + 1, num6 + 1, seed), Hash(num4 + 1, num5 + 1, num6 + 1, seed), t), t2), a: Lerp(a, b, t2), t: t3);
		}

		private static float Hash(int x, int y, int z, int seed)
		{
			return Unit((uint)(seed ^ (x * 73856093) ^ (y * 19349663) ^ (z * 83492791)));
		}

		private static float Smooth(float x)
		{
			return x * x * (3f - 2f * x);
		}

		private static float Lerp(float a, float b, float t)
		{
			return a + (b - a) * t;
		}
	}
	public sealed class OreCluster
	{
		public Vector3 position;

		public int count;

		public EVeinType type;
	}
	public static class EcologyGeneration
	{
		public sealed class GenerationPolicy
		{
			public readonly bool Communities;

			public readonly float Density;

			public readonly float OreStrength;

			public readonly int Revision;

			public readonly float GrassShare;

			public readonly float GrassWidth;

			public readonly float GrassHeight;

			public GenerationPolicy(bool communities, float density, float oreStrength, int revision = 4, float grassShare = 0.08f, float grassWidth = 1.75f, float grassHeight = 1.45f)
			{
				Communities = communities;
				Density = density;
				OreStrength = oreStrength;
				Revision = revision;
				GrassShare = grassShare;
				GrassWidth = grassWidth;
				GrassHeight = grassHeight;
			}
		}

		public const string Marker = "LivingWorlds.Generation.v1";

		private static ConfigEntry<bool> communities;

		private static ConfigEntry<bool> oreTerrain;

		private static ConfigEntry<float> density;

		private static ConfigEntry<float> oreStrength;

		internal static int DesignRevision => SavedPolicy()?.Revision ?? 0;

		internal static GenerationPolicy GroundCoverPolicy => SavedPolicy();

		public static string EncodePolicy(GenerationPolicy policy)
		{
			string text = "LW" + policy.Revision + ";" + (policy.Communities ? "1" : "0") + ";" + policy.Density.ToString("R", CultureInfo.InvariantCulture) + ";" + policy.OreStrength.ToString("R", CultureInfo.InvariantCulture);
			if (policy.Revision >= 3)
			{
				text = text + ";" + policy.GrassShare.ToString("R", CultureInfo.InvariantCulture) + ";" + policy.GrassWidth.ToString("R", CultureInfo.InvariantCulture) + ";" + policy.GrassHeight.ToString("R", CultureInfo.InvariantCulture);
			}
			return text;
		}

		public static GenerationPolicy DecodePolicy(string text)
		{
			if (text == null || !text.StartsWith("LW", StringComparison.Ordinal))
			{
				return null;
			}
			string[] array = text.Split(new char[1] { ';' });
			int num = ((array[0] == "LW1") ? 1 : ((array[0] == "LW2") ? 2 : ((array[0] == "LW3") ? 3 : ((array[0] == "LW4") ? 4 : 0))));
			if (num == 0 || array.Length != ((num >= 3) ? 7 : 4) || (array[1] != "0" && array[1] != "1") || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || float.IsNaN(result) || float.IsInfinity(result) || result < 0.4f || result > 1.5f || float.IsNaN(result2) || float.IsInfinity(result2) || result2 < 0f || result2 > 0.5f)
			{
				throw new InvalidOperationException("Invalid saved DiverseBiomes generation policy; refusing to regenerate a different surface.");
			}
			float value = 0.08f;
			float value2 = 1.75f;
			float value3 = 1.45f;
			if (num >= 3 && (!ReadRange(array[4], 0f, 0.3f, out value) || !ReadRange(array[5], 1f, 2f, out value2) || !ReadRange(array[6], 1f, 1.6f, out value3)))
			{
				throw new InvalidOperationException("Invalid saved DiverseBiomes ground cover settings.");
			}
			return new GenerationPolicy(array[1] == "1", result, result2, num, value, value2, value3);
		}

		private static bool ReadRange(string text, float min, float max, out float value)
		{
			if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value) && !float.IsNaN(value) && !float.IsInfinity(value) && value >= min)
			{
				return value <= max;
			}
			return false;
		}

		private static GenerationPolicy SavedPolicy()
		{
			return WorldEcology.ActivePolicy;
		}

		internal static GenerationPolicy ConfiguredPolicy()
		{
			bool num = communities?.Value ?? true;
			float num2 = density?.Value ?? 1f;
			ConfigEntry<bool> obj = oreTerrain;
			return new GenerationPolicy(num, num2, (obj != null && !obj.Value) ? 0f : (oreStrength?.Value ?? 0.4f), 4, GroundCover.LargeShare, GroundCover.WidthLimit, GroundCover.HeightLimit);
		}

		public static void Configure(ConfigFile config)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			communities = config.Bind<bool>("Ecology / 生态", "Terrain communities / 地形群落", true, "Captured into each newly generated galaxy; saved settings keep plant IDs and deposits stable. / 新星区创建时固定设置,读档保留植物编号和矿点。");
			density = config.Bind<float>("Ecology / 生态", "Vegetation density / 植物密度", 1f, new ConfigDescription("Captured into each newly generated galaxy; saved settings keep plant IDs and deposits stable. / 新星区创建时固定设置,读档保留植物编号和矿点。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 1.5f), Array.Empty<object>()));
			oreTerrain = config.Bind<bool>("Ecology / 生态", "Ore terrain preference / 矿脉地形偏好", true, "Requires the optional Galactic Scale adapter. / 仅在 GS2 可选适配中生效。Captured into each newly generated galaxy; saved settings keep plant IDs and deposits stable. / 新星区创建时固定设置,读档保留植物编号和矿点。");
			oreStrength = config.Bind<float>("Ecology / 生态", "Ore preference strength / 矿脉偏好强度", 0.4f, new ConfigDescription("0 keeps original positions; 40% of clusters attempt terrain refinement by default, at most 12m on radius 300. / 默认四成矿团尝试地形微调,300 星最大 12 米。Captured into each newly generated galaxy; saved settings keep plant IDs and deposits stable. / 新星区创建时固定设置,读档保留植物编号和矿点。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
		}

		internal static GenerationPolicy SettingsFor(PlanetData planet)
		{
			return EcologyAdapters.PolicyFor(planet);
		}

		internal static bool UsesCommunities(PlanetData planet)
		{
			return SettingsFor(planet)?.Communities ?? false;
		}

		internal static ThemeEcology ThemeProfile(PlanetData planet)
		{
			IEcologyAdapter current = EcologyAdapters.Current;
			if (current == null || !current.AppliesTo(planet))
			{
				return ProfiledCommunities.ForVanilla(planet);
			}
			return EcologyAdapters.Current.ThemeFor(planet);
		}

		internal static int RevisionFor(PlanetData planet)
		{
			return SettingsFor(planet)?.Revision ?? 0;
		}

		internal static CommunitySample CommunityAt(PlanetData planet, Vector3 pos)
		{
			//IL_002b: 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)
			GenerationPolicy generationPolicy = SettingsFor(planet);
			if (generationPolicy != null && generationPolicy.Revision >= 3)
			{
				ThemeEcology profile = ThemeProfile(planet);
				return ProfiledCommunities.Choose(profile, SampleTerrain(planet, pos, null, profile));
			}
			return CommunityDesign.Choose(SampleTerrain(planet, pos), generationPolicy != null && generationPolicy.Revision >= 2);
		}

		internal static bool IsPlant(short protoId)
		{
			//IL_0020: 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_0033: Invalid comparison between Unknown and I4
			VegeProtoSet veges = LDB.veges;
			if (veges == null)
			{
				return false;
			}
			return (int)(((ProtoSet<VegeProto>)(object)veges).Select((int)protoId)?.Type).GetValueOrDefault() == 1;
		}

		internal static void Prune(PlanetRawData raw, List<int> removed)
		{
			if (removed == null || removed.Count == 0 || raw?.vegePool == null)
			{
				return;
			}
			foreach (int item in removed)
			{
				if (item > 0 && item < Math.Min(raw.vegeCursor, raw.vegePool.Length))
				{
					raw.vegePool[item].id = 0;
				}
			}
			if (raw.vegeIds == null)
			{
				return;
			}
			for (int i = 0; i < raw.vegeIds.Length; i++)
			{
				int num = raw.vegeIds[i];
				if (num > 0 && (num >= raw.vegePool.Length || raw.vegePool[num].id != num))
				{
					raw.vegeIds[i] = 0;
				}
			}
		}

		internal static TerrainTraits SampleTerrain(PlanetData planet, Vector3 pos, Func<Vector3, float> query = null, ThemeEcology profile = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0089: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Invalid comparison between Unknown and I4
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Invalid comparison between Unknown and I4
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Invalid comparison between Unknown and I4
			//IL_01a6: 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_020b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 normalized = ((Vector3)(ref pos)).normalized;
			float realRadius = planet.realRadius;
			Func<Vector3, float> func = query ?? new Func<Vector3, float>(planet.data.QueryHeight);
			float num = func(normalized);
			float num2 = 2.5f / realRadius;
			Vector3 val = Vector3.Cross(normalized, (Math.Abs(normalized.y) < 0.9f) ? Vector3.up : Vector3.right);
			Vector3 normalized2 = ((Vector3)(ref val)).normalized;
			val = Vector3.Cross(normalized, normalized2);
			Vector3 normalized3 = ((Vector3)(ref val)).normalized;
			val = normalized + normalized2 * num2;
			float num3 = func(((Vector3)(ref val)).normalized);
			val = normalized - normalized2 * num2;
			float num4 = num3 - func(((Vector3)(ref val)).normalized);
			val = normalized + normalized3 * num2;
			float num5 = func(((Vector3)(ref val)).normalized);
			val = normalized - normalized3 * num2;
			float num6 = num5 - func(((Vector3)(ref val)).normalized);
			return new TerrainTraits
			{
				Elevation = num - (realRadius + planet.waterHeight),
				Slope = (float)Math.Sqrt(num4 * num4 + num6 * num6) / 5f,
				Latitude = Math.Abs(normalized.y),
				HasWater = (planet.waterItemId != 0),
				Cold = ((int)planet.type == 4 || planet.temperatureBias < -1f),
				Dry = ((profile == null || !profile.Organic) && ((int)planet.type == 3 || (int)planet.type == 1 || planet.waterItemId == 0)),
				Patch = CommunityDesign.PatchNoise(normalized, planet.seed, Math.Max(3f, realRadius / 45f) * ((profile != null && profile.Organic) ? profile.PatchFrequency : 1f)),
				Moisture = CommunityDesign.PatchNoise(normalized, planet.seed ^ 0x4D6F6973, 3.5f),
				Detail = ((profile != null) ? CommunityDesign.PatchNoise(normalized, planet.seed ^ 0x65636F33, Math.Max(7f, realRadius / 17f)) : 0f)
			};
		}

		internal static bool PreparePlant(PlanetData planet, ref VegeData vegetation, uint key, PlanetVegetationProfile baseProfile, out float multiplier)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: 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_02d5: Unknown result type (might be due to invalid IL or missing references)
			bool flag = GroundCover.IsGrass(vegetation.protoId);
			if (vegetation.protoId >= 9999 || vegetation.protoId == 1044 || (!flag && !IsPlant(vegetation.protoId)))
			{
				multiplier = 1f;
				GenerationPolicy generationPolicy = SettingsFor(planet);
				if (generationPolicy != null && generationPolicy.Revision >= 4 && generationPolicy.Communities && !ThemeProfile(planet).Organic && ProfiledCommunities.IsDecoration(vegetation.protoId))
				{
					CommunitySample communitySample = CommunityAt(planet, vegetation.pos);
					multiplier = communitySample.DecorationScale;
					return CommunityDesign.Unit(key ^ 0xD729C865u) < Math.Min(1f, communitySample.Retention * generationPolicy.Density);
				}
				return true;
			}
			multiplier = (flag ? GroundCover.Sample(key) : VegetationDistribution.SampleMultiplier(baseProfile, key));
			GenerationPolicy generationPolicy2 = SettingsFor(planet);
			if (generationPolicy2 == null || !generationPolicy2.Communities)
			{
				return true;
			}
			GenerationPolicy generationPolicy3 = SettingsFor(planet);
			if (generationPolicy3.Revision >= 3)
			{
				if (!ThemeProfile(planet).Organic)
				{
					multiplier = 1f;
					if (!ProfiledCommunities.IsDecoration(vegetation.protoId))
					{
						return true;
					}
					CommunitySample communitySample2 = CommunityAt(planet, vegetation.pos);
					multiplier = communitySample2.DecorationScale;
					return CommunityDesign.Unit(key ^ 0xD729C865u) < Math.Min(1f, communitySample2.Retention * generationPolicy3.Density);
				}
				if (vegetation.protoId >= 9999 || (!IsPlant(vegetation.protoId) && !flag))
				{
					multiplier = 1f;
					return true;
				}
			}
			else if (!IsPlant(vegetation.protoId) && (!flag || generationPolicy3.Revision < 2))
			{
				return true;
			}
			CommunitySample sample = CommunityAt(planet, vegetation.pos);
			PlanetVegetationProfile profile = ((baseProfile.Mode == VegetationSizeMode.TriplePeak) ? baseProfile : VegetationDistribution.CreateProfileWithBirthOverride(planet.seed, planet.id, VegetationGenerationPatches.SettingsFor(planet), birth: true));
			multiplier = ((!flag) ? CommunityDesign.SizeMultiplier(profile, sample, key) : ((generationPolicy3.Revision >= 3) ? GroundCover.Sample(key, sample, generationPolicy3.GrassShare) : GroundCover.Sample(key)));
			float num = Math.Min(1f, sample.Retention * generationPolicy3.Density);
			if (generationPolicy3.Revision >= 3)
			{
				num = (flag ? Math.Min(1f, sample.GrassRetention * generationPolicy3.Density) : (num * ProfiledCommunities.SpeciesRetention(vegetation.protoId, sample)));
			}
			else if (flag && generationPolicy3.Revision >= 2)
			{
				float num2 = ((sample.Kind == CommunityKind.MeadowWoodland) ? 0.9f : ((sample.Kind == CommunityKind.RiparianForest) ? 0.68f : ((sample.Kind == CommunityKind.AncientGrove) ? 0.48f : ((sample.Kind == CommunityKind.HighlandScrub) ? 0.36f : 0.26f))));
				num = Math.Min(1f, num2 * generationPolicy3.Density);
			}
			Vector3 val = ((Vector3)(ref vegetation.pos)).normalized - ((Vector3)(ref planet.birthPoint)).normalized;
			float num3 = ((Vector3)(ref val)).magnitude * planet.realRadius;
			if (BirthVegetationProfile.IsBirth(planet) && num3 < 18f)
			{
				num *= 0.55f;
			}
			return CommunityDesign.Unit(key ^ 0xD729C865u) < num;
		}

		internal static float TreeMultiplier(PlanetData planet, VegeData vegetation, uint key, PlanetVegetationProfile profile)
		{
			PreparePlant(planet, ref vegetation, key, profile, out var multiplier);
			return multiplier;
		}

		public static int AdjustClusters(PlanetData planet, IList<OreCluster> clusters, float strength, float padding, Func<Vector3, float> height = null, int revision = 1)
		{
			//IL_0036: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected I4, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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_01e9: Invalid comparison between Unknown and I4
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: 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_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: 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_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			if (planet == null || clusters == null || strength <= 0f)
			{
				return 0;
			}
			strength = Math.Min(0.5f, strength);
			float realRadius = planet.realRadius;
			int num = 0;
			for (int i = 0; i < clusters.Count; i++)
			{
				OreCluster oreCluster = clusters[i];
				if (oreCluster.position == Vector3.zero)
				{
					continue;
				}
				Vector3 normalized = ((Vector3)(ref oreCluster.position)).normalized;
				Vector3 val;
				if (BirthVegetationProfile.IsBirth(planet))
				{
					if (i < 2)
					{
						continue;
					}
					val = normalized - ((Vector3)(ref planet.birthPoint)).normalized;
					if (((Vector3)(ref val)).magnitude * realRadius < 45f)
					{
						continue;
					}
				}
				uint num2 = (uint)(planet.seed ^ (i * -1640531527) ^ (oreCluster.type * -2048144789));
				if (CommunityDesign.Unit(num2) >= strength)
				{
					continue;
				}
				float num3 = OreScore(oreCluster.type, SampleTerrain(planet, normalized, height), revision);
				Vector3 val2 = normalized;
				val = Vector3.Cross(normalized, (Math.Abs(normalized.y) < 0.9f) ? Vector3.up : Vector3.right);
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				val = Vector3.Cross(normalized, normalized2);
				Vector3 normalized3 = ((Vector3)(ref val)).normalized;
				float num4 = ((revision >= 2) ? Math.Min(12f, realRadius * 0.04f) : Math.Min(8f, realRadius * 0.035f)) / realRadius;
				int num5 = ((revision >= 2) ? 12 : 6);
				for (int j = 0; j < num5; j++)
				{
					double num6 = Math.PI * 2.0 * ((double)j / 6.0 + (double)CommunityDesign.Unit(num2 ^ 0xA731B9EDu));
					float num7 = ((j >= 6) ? 0.55f : 1f);
					val = normalized + num4 * num7 * (normalized2 * (float)Math.Cos(num6) + normalized3 * (float)Math.Sin(num6));
					Vector3 normalized4 = ((Vector3)(ref val)).normalized;
					TerrainTraits terrain = SampleTerrain(planet, normalized4, height);
					float num8 = (((int)oreCluster.type == 7) ? 0.6f : 0.1f);
					if (terrain.Elevation < num8 || terrain.Slope > 0.65f)
					{
						continue;
					}
					float num9 = Math.Min(7f, 2.1f * (float)Math.Sqrt(Math.Max(1, oreCluster.count))) / realRadius;
					bool flag = true;
					Vector3[] array = (Vector3[])(object)new Vector3[4]
					{
						normalized2,
						-normalized2,
						normalized3,
						-normalized3
					};
					foreach (Vector3 val3 in array)
					{
						val = normalized4 + val3 * num9;
						if (SampleTerrain(planet, ((Vector3)(ref val)).normalized, height).Elevation < num8)
						{
							flag = false;
							break;
						}
					}
					if (!flag)
					{
						continue;
					}
					if (BirthVegetationProfile.IsBirth(planet))
					{
						val = normalized4 - ((Vector3)(ref planet.birthPoint)).normalized;
						if (((Vector3)(ref val)).magnitude * realRadius < 45f)
						{
							continue;
						}
					}
					float num10 = (float)Math.Pow(2.1f / realRadius, 2.0) * Math.Max(100f, padding * 196f);
					bool flag2 = false;
					for (int l = 0; l < clusters.Count; l++)
					{
						if (l != i && clusters[l].position != Vector3.zero)
						{
							val = normalized4 - ((Vector3)(ref clusters[l].position)).normalized;
							if (((Vector3)(ref val)).sqrMagnitude < num10)
							{
								flag2 = true;
								break;
							}
						}
					}
					if (!flag2)
					{
						float num11 = OreScore(oreCluster.type, terrain, revision);
						if (num11 > num3 + 0.01f)
						{
							num3 = num11;
							val2 = normalized4;
						}
					}
				}
				val = val2 - normalized;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-10f)
				{
					oreCluster.position = val2;
					num++;
				}
			}
			return num;
		}

		public static float OreScore(EVeinType type, TerrainTraits terrain, int revision = 1)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			if (revision >= 2)
			{
				float num = (((int)type == 7) ? 1.1f : (((int)type == 6) ? 1.8f : (((int)type == 5) ? 3f : (((int)type == 4) ? 4.5f : (((int)type == 3) ? 3.8f : 3.2f)))));
				float num2 = (((int)type == 7) ? 1f : 0.55f);
				return (0f - Math.Abs(terrain.Elevation - num)) * num2 - terrain.Slope * 3f;
			}
			if ((int)type == 7)
			{
				return 0f - Math.Abs(terrain.Elevation - 1.1f) - terrain.Slope * 3f;
			}
			if ((int)type == 6)
			{
				return (0f - Math.Abs(terrain.Elevation - 1.8f)) * 0.5f - terrain.Slope * 2f;
			}
			return Math.Min(terrain.Elevation, 5f) * 0.35f - terrain.Slope * 2f;
		}
	}
	internal static class ExistingVegetationMigration
	{
		internal static void Apply(Harmony harmony, DistributionSettings settings, ConfigFile config)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(PlanetModelingManager), "LoadingPlanetFactoryMain", new Type[1] { typeof(PlanetData) }, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(PlanetModelingManager), "currentFactingStage");
			if (methodInfo == null || fieldInfo?.FieldType != typeof(int))
			{
				throw new MissingMethodException("Planet factory loading stages changed.");
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ExistingVegetationMigration), "BeforeModels", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void BeforeModels(PlanetData planet, int ___currentFactingStage)
		{
			if (___currentFactingStage == 1 && planet?.factory?.vegePool != null)
			{
				PlanetFactory factory = planet.factory;
				if ((EcologyGeneration.RevisionFor(planet) == 0 || EcologyGeneration.RevisionFor(planet) >= 4) && GiantVegetationApplicator.WasProcessed(planet))
				{
					SyncMatchingPlants(factory.vegePool, factory.vegeCursor, planet.data.vegePool, planet.data.vegeCursor);
				}
				GroundCover.ClampFactory(factory);
			}
		}

		internal static int SyncMatchingPlants(VegeData[] saved, int savedCursor, VegeData[] reference, int referenceCursor)
		{
			//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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0051: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (saved == null || reference == null || saved == reference)
			{
				return 0;
			}
			int num = 0;
			int num2 = Math.Min(Math.Min(savedCursor, saved.Length), Math.Min(referenceCursor, reference.Length));
			for (int i = 1; i < num2; i++)
			{
				VegeData val = saved[i];
				VegeData val2 = reference[i];
				if (val.id == i && val2.id == i && val.protoId == val2.protoId && val.protoId < 9999)
				{
					Vector3 val3 = val.pos - val2.pos;
					if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0001f) && (GroundCover.IsGrass(val.protoId) || EcologyGeneration.IsPlant(val.protoId)))
					{
						saved[i].scl = val2.scl;
						num++;
					}
				}
			}
			return num;
		}
	}
	internal static class GiantVegetationApplicator
	{
		private sealed class Stamp
		{
			internal VegeData[] Pool;
		}

		private static readonly ConditionalWeakTable<PlanetData, Stamp> completed = new ConditionalWeakTable<PlanetData, Stamp>();

		private static readonly object gate = new object();

		internal static bool WasProcessed(PlanetData planet)
		{
			if (planet == null)
			{
				return false;
			}
			lock (gate)
			{
				Stamp value;
				return completed.TryGetValue(planet, out value) && value.Pool == planet.data?.vegePool;
			}
		}

		internal static int Apply(PlanetData planet, VegeData[] pool, int cursor, DistributionSettings settings)
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			if (planet == null || pool == null || settings == null)
			{
				return 0;
			}
			lock (gate)
			{
				if (completed.TryGetValue(planet, out var value) && value.Pool == pool)
				{
					return 0;
				}
				completed.Remove(planet);
				completed.Add(planet, new Stamp
				{
					Pool = pool
				});
			}
			if (EcologyGeneration.RevisionFor(planet) > 0 && EcologyGeneration.RevisionFor(planet) < 4)
			{
				return 0;
			}
			if (planet.radius + 0.5f < WorldEcology.MinimumGiantRadius(planet) || !VegetationDistribution.ShouldGenerateGiantVegetation(planet.seed, planet.id, settings))
			{
				return 0;
			}
			int giantVegetationCount = VegetationDistribution.GetGiantVegetationCount(planet.seed, planet.id, settings);
			if (giantVegetationCount <= 0)
			{
				return 0;
			}
			SortedDictionary<ulong, int> sortedDictionary = new SortedDictionary<ulong, int>();
			int num = Math.Min(cursor, pool.Length);
			for (int i = 1; i < num; i++)
			{
				VegeData val = pool[i];
				if (val.id != i || !EcologyGeneration.IsPlant(val.protoId) || GroundCover.IsGrass(val.protoId) || (EcologyGeneration.UsesCommunities(planet) && EcologyGeneration.CommunityAt(planet, val.pos).Kind != CommunityKind.AncientGrove))
				{
					continue;
				}
				ulong key = ((ulong)VegetationDistribution.GetGiantSelectionScore(VegetationDistribution.CreatePlantKey(planet.seed, planet.id, i, val.protoId, val.pos.x, val.pos.y, val.pos.z)) << 32) | (uint)i;
				sortedDictionary.Add(key, i);
				if (sortedDictionary.Count <= giantVegetationCount)
				{
					continue;
				}
				ulong key2 = 0uL;
				foreach (KeyValuePair<ulong, int> item in sortedDictionary)
				{
					key2 = item.Key;
				}
				sortedDictionary.Remove(key2);
			}
			PlanetVegetationProfile profile = BirthVegetationProfile.Create(planet, settings);
			foreach (int value2 in sortedDictionary.Values)
			{
				VegeData val2 = pool[value2];
				uint key3 = VegetationDistribution.CreatePlantKey(planet.seed, planet.id, value2, val2.protoId, val2.pos.x, val2.pos.y, val2.pos.z);
				float num2 = EcologyGeneration.TreeMultiplier(planet, val2, key3, profile);
				float num3 = VegetationDistribution.SampleGiantMultiplier(key3, settings);
				if (num2 > 0f)
				{
					ref Vector3 scl = ref pool[value2].scl;
					scl *= num3 / num2;
				}
			}
			return sortedDictionary.Count;
		}
	}
	internal static class GroundCover
	{
		private static ConfigEntry<float> largeShare;

		private static ConfigEntry<float> widthCap;

		private static ConfigEntry<float> heightCap;

		internal static float LargeShare => largeShare?.Value ?? 0.08f;

		internal static float WidthLimit => widthCap?.Value ?? 1.75f;

		internal static float HeightLimit => heightCap?.Value ?? 1.45f;

		internal static void Configure(ConfigFile config)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			largeShare = config.Bind<float>("Ground cover / 地被草", "Large grass share / 大草比例", 0.08f, new ConfigDescription("Base share; LW3 meadows increase it, dense understory decreases it, up to 30%. / 基准比例;草甸提高、密林下层降低,上限三成。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.3f), Array.Empty<object>()));
			widthCap = config.Bind<float>("Ground cover / 地被草", "Width limit / 宽度上限", 1.75f, new ConfigDescription("Relative to the prototype's original maximum; applies safely on loading existing factories too. / 相对原型正常尺寸上限,读旧档也限制,不累乘。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), Array.Empty<object>()));
			heightCap = config.Bind<float>("Ground cover / 地被草", "Height limit / 高度上限", 1.45f, new ConfigDescription("Keeps belts easier to see. / 降低草对传送带走向的遮挡。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1.6f), Array.Empty<object>()));
		}

		internal static bool IsGrass(short id)
		{
			if ((id < 61 || id > 63) && (id < 1001 || id > 1004) && (id < 1011 || id > 1013) && (id < 1021 || id > 1023) && (id < 1081 || id > 1086))
			{
				if (id >= 1091)
				{
					return id <= 1094;
				}
				return false;
			}
			return true;
		}

		internal static float Multiplier(uint key, float large = 0.04f)
		{
			float num = CommunityDesign.Unit(key ^ 0x318EAD27);
			float num2 = ((num < 1f - large - 0.22f) ? 1f : ((num < 1f - large) ? 1.18f : 1.48f));
			return Math.Max(1f, num2 * (0.96f + 0.08f * CommunityDesign.Unit(key ^ 0xE7869AF3u)));
		}

		internal static float Sample(uint key)
		{
			return Multiplier(key, largeShare?.Value ?? 0.04f);
		}

		internal static float Sample(uint key, CommunitySample sample, float basis)
		{
			float num = Math.Min(0.3f, Math.Max(0f, basis * sample.GrassLargeFactor));
			float num2 = CommunityDesign.Unit(key ^ 0x318EAD27);
			float num3 = ((num2 < 1f - num - 0.22f) ? 1f : ((num2 < 1f - num) ? 1.22f : 1.68f));
			return Math.Max(1f, num3 * (0.96f + 0.08f * CommunityDesign.Unit(key ^ 0xE7869AF3u)));
		}

		internal static Vector3 Limit(Vector3 scale, Vector4 range, float width = 1.6f, float height = 1.25f)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			float num = Math.Max(0.1f, 1f + range.y);
			float num2 = num * Math.Max(0.1f, 1f + range.w);
			float num3 = Math.Min(1f, Math.Min(num2 * width / Math.Max(0.0001f, Math.Max(Math.Abs(scale.x), Math.Abs(scale.z))), num * height / Math.Max(0.0001f, Math.Abs(scale.y))));
			return scale * num3;
		}

		internal static void Clamp(ref VegeData vegetation, EcologyGeneration.GenerationPolicy policy = null)
		{
			//IL_006a: 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_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 (IsGrass(vegetation.protoId))
			{
				VegeProto val = ((ProtoSet<VegeProto>)(object)LDB.veges)?.Select((int)vegetation.protoId);
				EcologyGeneration.GenerationPolicy generationPolicy = policy ?? EcologyGeneration.GroundCoverPolicy;
				float width = ((generationPolicy != null && generationPolicy.Revision >= 3) ? generationPolicy.GrassWidth : WidthLimit);
				float height = ((generationPolicy != null && generationPolicy.Revision >= 3) ? generationPolicy.GrassHeight : HeightLimit);
				if (val != null)
				{
					vegetation.scl = Limit(vegetation.scl, val.ScaleRange, width, height);
				}
			}
		}

		internal static void ClampFactory(PlanetFactory factory)
		{
			if (factory?.vegePool == null)
			{
				return;
			}
			for (int i = 1; i < Math.Min(factory.vegeCursor, factory.vegePool.Length); i++)
			{
				if (factory.vegePool[i].id == i)
				{
					Clamp(ref factory.vegePool[i], EcologyAdapters.PolicyFor(factory.planet));
				}
			}
		}

		internal static void SyncFactoryGrass(PlanetFactory factory)
		{
			PlanetData val = ((factory != null) ? factory.planet : null);
			if (val?.data?.vegePool != null && factory.vegePool != null && GiantVegetationApplicator.WasProcessed(val))
			{
				SyncMatchingGrass(factory.vegePool, factory.vegeCursor, val.data.vegePool, val.data.vegeCursor);
			}
		}

		internal static int SyncMatchingGrass(VegeData[] saved, int savedCursor, VegeData[] fresh, int freshCursor)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004e: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (saved == null || fresh == null || saved == fresh)
			{
				return 0;
			}
			int num = Math.Min(Math.Min(savedCursor, saved.Length), Math.Min(freshCursor, fresh.Length));
			int num2 = 0;
			for (int i = 1; i < num; i++)
			{
				VegeData val = saved[i];
				VegeData val2 = fresh[i];
				if (val.id == i && val2.id == i && val.protoId == val2.protoId && IsGrass(val.protoId))
				{
					Vector3 val3 = val.pos - val2.pos;
					if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0001f))
					{
						saved[i].scl = val2.scl;
						num2++;
					}
				}
			}
			return num2;
		}
	}
	internal static class LegacyConfiguration
	{
		private static ConfigFile legacy;

		private static bool checkedFile;

		internal static ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T fallback, ConfigDescription description)
		{
			//IL_0027: 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_0038: Expected O, but got Unknown
			if (!checkedFile)
			{
				checkedFile = true;
				string text = Path.Combine(Paths.ConfigPath, "Zincon.DSPVegetationScale.cfg");
				if (File.Exists(text))
				{
					legacy = new ConfigFile(text, false)
					{
						SaveOnConfigSet = false
					};
				}
			}
			return config.Bind<T>(section, key, (legacy == null) ? fallback : legacy.Bind<T>(section, key, fallback, (ConfigDescription)null).Value, description);
		}

		internal static ConfigEntry<T> Bind<T>(ConfigFile config, string section, string key, T fallback, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(config, section, key, fallback, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal static class ModConfig
	{
		internal static float GiantMinimumPlanetRadius { get; private set; }

		internal static float MaximumPlayerColliderScale { get; private set; }

		internal static float PlayerCollisionDamageMultiplier { get; private set; }

		internal static bool DisablePlayerVegetationCollision { get; private set; }

		internal static DistributionSettings Bind(ConfigFile config)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Expected O, but got Unknown
			string[] array = new string[3] { "1 - Super-large / 超大型", "2 - Large / 大型", "3 - Triple peak / 三峰型" };
			string[] array2 = new string[8] { "Peak multiplier minimum / 波峰倍数下限", "Peak multiplier maximum / 波峰倍数上限", "Small peak minimum / 小型峰下限", "Small peak maximum / 小型峰上限", "Medium peak minimum / 中型峰下限", "Medium peak maximum / 中型峰上限", "Large peak minimum / 大型峰下限", "Large peak maximum / 大型峰上限" };
			float[] array3 = new float[15]
			{
				1.75f, 2.5f, 1.25f, 1.75f, 1f, 1f, 1.25f, 1.75f, 2.375f, 3f,
				0.5f, 5f, 15f, 4f, 7.5f
			};
			for (int i = 0; i < 10; i++)
			{
				int num = ((i >= 2) ? ((i < 4) ? 1 : 2) : 0);
				int num2 = ((i < 4) ? (i % 2) : (i - 2));
				array3[i] = Float(config, array[num], array2[num2], array3[i], 1f, 7f, "Plant size peak. / 植物尺寸波峰。");
			}
			array3[10] = Float(config, "4 - Giant vegetation / 巨型植被", "Planet chance / 星球概率", 0.5f, 0f, 1f, "Chance of a giant grove. / 古木群出现概率。");
			array3[11] = LegacyConfiguration.Bind(config, "4 - Giant vegetation / 巨型植被", "Minimum count / 最少数量", 5, new ConfigDescription("Giant grove count range. / 古木数量范围。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())).Value;
			array3[12] = LegacyConfiguration.Bind(config, "4 - Giant vegetation / 巨型植被", "Maximum count / 最多数量", 15, new ConfigDescription("Giant grove count range. / 古木数量范围。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())).Value;
			array3[13] = Float(config, "4 - Giant vegetation / 巨型植被", "Minimum multiplier / 最小倍数", 4f, 1f, 15f, "Giant size range. / 古木尺寸范围。");
			array3[14] = Float(config, "4 - Giant vegetation / 巨型植被", "Maximum multiplier / 最大倍数", 7.5f, 1f, 15f, "Giant size range. / 古木尺寸范围。");
			GiantMinimumPlanetRadius = Float(config, "4 - Giant vegetation / 巨型植被", "Minimum planet radius for giants / 巨型植物最低行星半径", 400f, 0f, 510f, "Set zero to allow giant groves on every radius. / 设零取消古木最低星球半径限制。");
			DisablePlayerVegetationCollision = LegacyConfiguration.Bind(config, "4 - Player collision / 人物碰撞", "Disable physical collision / 关闭物理碰撞", fallback: false, "Let Icarus pass through vegetation. / 允许伊卡洛斯穿过植被。").Value;
			MaximumPlayerColliderScale = Float(config, "4 - Player collision / 人物碰撞", "Maximum collider scale / 碰撞体最大倍数", 1.5f, 1f, 7f, "Limit physical obstructions without shrinking visible plants. / 限制人物碰撞体,不缩小可见植物。");
			PlayerCollisionDamageMultiplier = Float(config, "4 - Player collision / 人物碰撞", "Vegetation damage multiplier / 植被伤害倍率", 0.1f, 0f, 1f, "Damage to plants from Icarus collisions. / 伊卡洛斯撞击植物的伤害比例。");
			return new DistributionSettings(array3);
		}

		private static float Float(ConfigFile file, string section, string key, float value, float lo, float hi, string explanation)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return LegacyConfiguration.Bind(file, section, key, value, new ConfigDescription(explanation, (AcceptableValueBase)(object)new AcceptableValueRange<float>(lo, hi), Array.Empty<object>())).Value;
		}
	}
	internal static class PlanetInfoUiPatches
	{
		private static DistributionSettings settings;

		private const int Marker = -73520;

		internal static void Apply(Harmony harmony, DistributionSettings values)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			settings = values;
			MethodInfo methodInfo = AccessTools.Method(typeof(UIPlanetDetail), "SetResCount", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo == null || AccessTools.Method(typeof(UIPlanetDetail), "GetEntry", (Type[])null, (Type[])null) == null)
			{
				throw new MissingMethodException("Planet detail entries changed.");
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PlanetInfoUiPatches), "Describe", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void Describe(UIPlanetDetail __instance, ref int count, UIResAmountEntry ___tipEntry)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			List<UIResAmountEntry> entries = __instance.entries;
			PlanetData planet = __instance.planet;
			if (entries == null || planet == null || (int)planet.type == 5)
			{
				return;
			}
			string[] array = new string[3] { "植物尺度 / Plant scale", "地表群落 / Communities", "古木上限 / Grove limit" };
			string[] array2 = new string[3]
			{
				GetVegetationScaleText(planet, settings),
				CommunityText(planet),
				GetGiantVegetationCount(planet, settings).ToString()
			};
			bool flag = (Object)(object)___tipEntry != (Object)null && entries.Remove(___tipEntry);
			int num = 0;
			int row;
			for (row = 0; row < array2.Length; row++)
			{
				UIResAmountEntry val = entries.Find((UIResAmountEntry item) => item.refId == -73520 - row);
				if ((Object)(object)val == (Object)null)
				{
					val = (UIResAmountEntry)AccessTools.Method(typeof(UIPlanetDetail), "GetEntry", (Type[])null, (Type[])null).Invoke(__instance, null);
					val.SetInfo(entries.Count, array[row], (Sprite)null, "", false, false, "");
					val.refId = -73520 - row;
					entries.Add(val);
					num++;
				}
				val.valueString = array2[row];
			}
			if (flag)
			{
				___tipEntry.SetIndex(entries.Count);
				entries.Add(___tipEntry);
			}
			count += num;
		}

		internal static string GetVegetationScaleText(PlanetData planet, DistributionSettings values)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (planet == null || (int)planet.type == 5)
			{
				return "—";
			}
			if (EcologyAdapters.PolicyFor(planet) == null)
			{
				return "原有地表 / Existing surf