Decompiled source of New Horizons Treelines v4.6.35

DonegalHorizonLift.dll

Decompiled a day ago
using System;
using System.Collections;
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 UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("New Horizons Treelines")]
[assembly: AssemblyDescription("New Horizons Treelines visual-only distant forest and terrain renderer for Valheim.")]
[assembly: AssemblyCompany("Marc / Codex")]
[assembly: AssemblyProduct("New Horizons Treelines")]
[assembly: AssemblyFileVersion("4.6.31")]
[assembly: AssemblyInformationalVersion("4.6.31")]
[assembly: AssemblyVersion("4.6.31.0")]
namespace DonegalHorizonLift;

[BepInPlugin("marc.donegalhorizonlift", "New Horizons Treelines", "4.6.31")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class DonegalHorizonLiftPlugin : BaseUnityPlugin
{
	private delegate float GetBaseHeightDelegate(WorldGenerator generator, float worldX, float worldZ, bool menuTerrain);

	private enum QualityPreset
	{
		VeryLow,
		Low,
		Balanced,
		Medium,
		High,
		Ultra,
		Horizon,
		Custom
	}

	private enum TreeCardDensityPreset
	{
		VeryLow,
		Low,
		Balanced,
		Medium,
		High,
		Ultra,
		Extreme,
		Custom
	}

	private enum NativeTreelineMode
	{
		AutoDetect,
		ManualCalibrated,
		DefaultFallback
	}

	private enum WorldDataMode
	{
		Auto,
		BetterContinentsCustomMap,
		ProceduralWorld
	}

	private enum HazeControlMode
	{
		Disabled,
		Auto,
		YieldToExternal,
		ForceHorizonLiftFog
	}

	private enum WaterSurfaceMode
	{
		Auto,
		Override,
		DisableLowlandForest
	}

	private enum ForestPlacementKind
	{
		TreeCard,
		BiomeCard,
		CanopyCard,
		ProxyMass,
		FillCard
	}

	private enum CardBaseHeightMode
	{
		LowestSupportedGround,
		LowerMiddleSupportedGround,
		MedianSupportedGround
	}

	private enum GroundRejectReason
	{
		None,
		Water,
		Unsupported,
		HeightMismatch,
		Other,
		BelowWater,
		VisibleLandRatio,
		CoastlineEdge,
		UncertainSupport,
		FinalFloating
	}

	private enum StrictFinalRejectReason
	{
		None,
		Floating,
		Burial,
		OpenWater,
		UnsupportedRoot
	}

	private enum RootAnchorMode
	{
		BottomCenter
	}

	private enum ClearSkyWeatherTier
	{
		Clear,
		PartlyClear,
		Bad,
		SpecialBiome
	}

	private enum TrueColourDiagnosticTarget
	{
		Off,
		NativeTerrainMaterial,
		NativeFogOutput,
		NewHorizonsFarTerrain,
		NewHorizonsTerrainTint,
		NewHorizonsHaze,
		ForestTerrainTint,
		NewHorizonsTreeCardMaterials
	}

	private enum ClearSkiesOperatingMode
	{
		Disabled,
		NaturalWeatherOnly,
		NaturalWeatherAndOccasionalEvent,
		PermanentCinematicOverride
	}

	private enum ForestRing
	{
		Handoff,
		Near,
		Mid,
		Far,
		Horizon
	}

	private enum ViewFacingForestOverloadState
	{
		Normal,
		Soft,
		Hard
	}

	private struct RingPlaneCounts
	{
		public int Tree;

		public int Canopy;

		public int PrimaryTree;

		public int OptionalTree;
	}

	private struct AtlasVisibleBounds
	{
		public float MinU;

		public float MaxU;

		public float MinV;

		public float MaxV;

		public float WidthFraction;

		public float HeightFraction;

		public Vector2 Root;

		public static AtlasVisibleBounds Full => new AtlasVisibleBounds
		{
			MinU = 0f,
			MaxU = 1f,
			MinV = 0f,
			MaxV = 1f,
			WidthFraction = 1f,
			HeightFraction = 1f,
			Root = new Vector2(0.5f, 0f)
		};
	}

	private struct TreeRendererPropertyState
	{
		public Color Colour;
	}

	private sealed class ForestDeterminismRecord
	{
		public string Hash;

		public string GenerationSignature;

		public int CandidateTotal;

		public int CandidatesCompleted;

		public int[] StableCardRecords;
	}

	private readonly struct GroundCardSpatialRecord
	{
		public readonly float X;

		public readonly float Z;

		public readonly float BaseY;

		public readonly float Width;

		public readonly ForestPlacementKind Kind;

		public readonly Biome Biome;

		public readonly int GenerationEpoch;

		public GroundCardSpatialRecord(float x, float z, float baseY, float width, ForestPlacementKind kind, Biome biome, int generationEpoch)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			X = x;
			Z = z;
			BaseY = baseY;
			Width = width;
			Kind = kind;
			Biome = biome;
			GenerationEpoch = generationEpoch;
		}
	}

	private readonly struct AcceptedCoverageCardRecord
	{
		public readonly float X;

		public readonly float Z;

		public readonly Biome Biome;

		public readonly int GenerationEpoch;

		public AcceptedCoverageCardRecord(float x, float z, Biome biome, int generationEpoch)
		{
			//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)
			X = x;
			Z = z;
			Biome = biome;
			GenerationEpoch = generationEpoch;
		}
	}

	private readonly struct CoverageSectorKey : IEquatable<CoverageSectorKey>
	{
		public readonly int X;

		public readonly int Z;

		public readonly ForestRing Ring;

		public readonly int Epoch;

		public CoverageSectorKey(int x, int z, ForestRing ring, int epoch)
		{
			X = x;
			Z = z;
			Ring = ring;
			Epoch = epoch;
		}

		public bool Equals(CoverageSectorKey other)
		{
			if (X == other.X && Z == other.Z && Ring == other.Ring)
			{
				return Epoch == other.Epoch;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is CoverageSectorKey)
			{
				return Equals((CoverageSectorKey)obj);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (int)(((uint)(((X * 397) ^ Z) * 397) ^ (uint)Ring) * 397) ^ Epoch;
		}
	}

	private sealed class CoverageSectorJob
	{
		public CoverageSectorKey Key;

		public int CellCursor;

		public int CellCount;

		public int GridSide;

		public int UnresolvedGapCells;

		public bool Dirty;

		public bool Completed;

		public float QueuedRealtime;

		public float LastProgressRealtime;
	}

	private enum RootAnchorRejectReason
	{
		None,
		Water,
		Unsupported,
		DryRatio,
		FloatHeight,
		WaterChannel,
		MissingValidation,
		MismatchedValidation,
		StaleValidation
	}

	private sealed class PresetRuntimeProfile
	{
		public QualityPreset Preset;

		public string Name;

		public float ExtensionDistance;

		public bool UseWorldMaximum;

		public int MaximumForestTiles;

		public int GlobalTreeCardPlaneBudget;

		public int GlobalCanopyPlaneBudget;

		public int PanicTileCeiling;

		public int TilesBuiltPerFrame;

		public int MaximumMeshUploadsPerFrame;
	}

	private sealed class TreeCardDensityProfile
	{
		public TreeCardDensityPreset Preset;

		public float ClusterCellSize;

		public float DensityThreshold;

		public float DensityMultiplier;

		public int CandidateTotal;

		public int CandidateStep;

		public int MaximumClusters;

		public int MaximumTreePlanes;

		public float MeadowsCoverage;

		public float BlackForestCoverage;

		public float NearRetention;

		public float MidRetention;

		public float FarRetention;

		public float HorizonRetention;

		public float HandoffGap;

		public float NearGap;

		public float MidGap;

		public float FarGap;

		public float HorizonGap;

		public float GlobalDistributedDensity;

		public float BlackForestDistributedDensity;

		public float MeadowsDistributedDensity;

		public float MountainDistributedDensity;

		public float PlainsDistributedDensity;

		public float HardRejectSlope;
	}

	private sealed class ForestBuildContinuation
	{
		public ForestAddJob Job;

		public ForestRing Ring;

		public ForestBuildResult Result;

		public IEnumerator<int> Enumerator;

		public bool OptionalCoverageWasEnabled;

		public long GroundOwnerKey;

		public float StartedRealtime;

		public int CandidateIndex;

		public int CandidateTotal;

		public ViewFacingForestOverloadState GeometryOverloadState;

		public readonly List<ForestChunkBuffers> LeasedChunkBuffers = new List<ForestChunkBuffers>(32);
	}

	private sealed class ForestTileAssemblyResult
	{
		public ForestTile Tile;
	}

	private sealed class CoverageRepairJob
	{
		public float X;

		public float Z;

		public ForestRing Ring;

		public Biome Biome;

		public int AttemptsRemaining;

		public long QueueKey;

		public int StableRepairSeed;

		public int CoastalAttemptCursor;

		public bool CoastalSearchActive;

		public float QueuedRealtime;

		public bool DensityResolved;

		public float Density;
	}

	private sealed class CoverageRepairMeshBuffer
	{
		public readonly List<Vector3> Vertices = new List<Vector3>(256);

		public readonly List<Vector2> Uvs = new List<Vector2>(256);

		public readonly List<int> Triangles = new List<int>(384);

		public ForestTile Tile;

		public ForestChunk Chunk;

		public Mesh Mesh;
	}

	private enum ForestTileWorkState
	{
		None,
		Pending,
		Building,
		AwaitingUpload,
		Active,
		Cached,
		Retiring
	}

	private struct CalibrationSampleStats
	{
		public int Count;

		public float Min;

		public float Max;

		public float Median;

		public float P25;

		public float P75;

		public float MedianAbsoluteDeviation;

		public float DirectionalCoverageDegrees;
	}

	private interface IWorldDataProvider
	{
		string ProviderName { get; }

		bool IsReady { get; }

		float WorldRadius { get; }

		float ValidForestRange { get; }

		int StableSeed { get; }

		string WorldIdentity { get; }

		string HeightSource { get; }

		string BiomeSource { get; }

		string ForestSource { get; }

		string WaterSource { get; }

		string ExactSamplerStatus { get; }

		string TerrainOverlayStatus { get; }

		string CacheStatus { get; }

		bool UsesSharedTerrainTexture { get; }

		Texture2D SharedTerrainTexture { get; }

		bool TryInitialize(out string failureReason);

		bool TrySample(float worldX, float worldZ, out WorldSurfaceSample sample);

		Vector2 GetTerrainUv(float worldX, float worldZ);

		Color GetTerrainColor(float worldX, float worldZ, float distanceFromAnchor);

		void UpdateBackgroundWork(float budgetMs);

		void DeleteCache();

		void Dispose();
	}

	private struct WorldSurfaceSample
	{
		public bool Valid;

		public float GroundY;

		public Biome Biome;

		public float ForestDensity;

		public float SlopeDegrees;

		public bool IsWaterOrOcean;

		public string HeightSource;

		public string ForestSource;
	}

	private struct VisibleGroundSupportSample
	{
		public WorldSurfaceSample Surface;

		public float WaterHeight;

		public bool ExactSupport;

		public bool AboveVisibleWater;

		public bool WaterCovered;

		public bool OpenWater;

		public bool VisibleLand;
	}

	private struct PlacementValidationResult
	{
		public bool IsValid;

		public bool GroundLocked;

		public bool VisibleLandSupported;

		public float FinalBaseY;

		public ForestPlacementKind CardKind;

		public GroundRejectReason RejectReason;

		public Biome ValidatedBiome;

		public float ValidatedCenterX;

		public float ValidatedCenterZ;

		public float ValidatedWidth;

		public float ValidatedHeight;

		public float ValidatedDistance;

		public int ValidationEpoch;

		public long ValidationId;

		public bool RootAnchorValidated;

		public Vector3 RootAnchorWorldPosition;

		public float RootAnchorGroundY;

		public float RootAnchorWaterY;

		public float RootAnchorDrySampleRatio;

		public RootAnchorRejectReason RootAnchorRejectReason;

		public RootAnchorMode RootAnchorMode;

		public float RootAnchorAngle;

		public float RootPreLockBaseY;

		public float RootLockedBaseY;

		public int RootAnchorValidationEpoch;

		public long RootAnchorValidationId;

		public static PlacementValidationResult Valid(ForestPlacementKind kind, float finalBaseY)
		{
			return new PlacementValidationResult
			{
				IsValid = true,
				GroundLocked = true,
				VisibleLandSupported = true,
				FinalBaseY = finalBaseY,
				CardKind = kind,
				RejectReason = GroundRejectReason.None,
				RootAnchorValidated = false,
				RootAnchorRejectReason = RootAnchorRejectReason.MissingValidation
			};
		}

		public static PlacementValidationResult Invalid(ForestPlacementKind kind, GroundRejectReason reason)
		{
			return new PlacementValidationResult
			{
				IsValid = false,
				GroundLocked = false,
				VisibleLandSupported = false,
				FinalBaseY = 0f,
				CardKind = kind,
				RejectReason = reason,
				RootAnchorValidated = false,
				RootAnchorRejectReason = RootAnchorRejectReason.MissingValidation
			};
		}
	}

	private sealed class BetterContinentsCustomMapProvider : IWorldDataProvider
	{
		private readonly DonegalHorizonLiftPlugin _plugin;

		private WorldGenerator _worldGenerator;

		private GetBaseHeightDelegate _getBaseHeight;

		private Texture2D _heightMap;

		private Texture2D _colourMap;

		private Texture2D _forestMap;

		private Texture2D _overlayTexture;

		private Color32[] _colourPixels;

		private Color32[] _forestPixels;

		private BetterContinentsMapSettings _settings;

		private bool _ready;

		private float _waterLevel;

		private string _waterSource = "unresolved conservative";

		public string ProviderName => "BetterContinentsCustomMap";

		public bool IsReady => _ready;

		public float WorldRadius => _settings.TotalRadius;

		public float ValidForestRange => Mathf.Max(0f, _settings.WorldSize);

		public int StableSeed => StableStringSeed(WorldIdentity);

		public string WorldIdentity => "BC:" + _settings.TotalRadius.ToString("F0", CultureInfo.InvariantCulture) + ":" + _settings.ConfigHash;

		public string HeightSource => "private WorldGenerator.GetBaseHeight(float,float,bool) * 200";

		public string BiomeSource => "WorldGenerator.GetBiome(Vector3)";

		public string ForestSource => "forestmap.png";

		public string WaterSource => _waterSource;

		public string ExactSamplerStatus
		{
			get
			{
				if (_getBaseHeight == null)
				{
					return "failed";
				}
				return "linked";
			}
		}

		public string TerrainOverlayStatus
		{
			get
			{
				Texture2D sharedTerrainTexture = SharedTerrainTexture;
				string text = ((_plugin._useUntintedProviderTerrainColourMap != null && _plugin._useUntintedProviderTerrainColourMap.Value) ? "original colour map" : "forested overlay");
				if (!((Object)(object)sharedTerrainTexture != (Object)null))
				{
					return "missing";
				}
				return text + " / " + ((Texture)sharedTerrainTexture).width + "x" + ((Texture)sharedTerrainTexture).height;
			}
		}

		public string CacheStatus => "not used";

		public bool UsesSharedTerrainTexture => true;

		public Texture2D SharedTerrainTexture
		{
			get
			{
				if (_plugin._useUntintedProviderTerrainColourMap != null && _plugin._useUntintedProviderTerrainColourMap.Value && (Object)(object)_colourMap != (Object)null)
				{
					return _colourMap;
				}
				return _overlayTexture;
			}
		}

		public BetterContinentsCustomMapProvider(DonegalHorizonLiftPlugin plugin)
		{
			_plugin = plugin;
		}

		public bool TryInitialize(out string failureReason)
		{
			failureReason = "";
			if (!IsBetterContinentsPresent())
			{
				failureReason = "Better Continents plugin GUID is not present.";
				return false;
			}
			if (!_plugin._useBetterContinentsExactSampler.Value)
			{
				failureReason = "Use Better Continents Exact Sampler is false. Final Donegal mode refuses direct/simple height fallback.";
				return false;
			}
			if (!TryLoadSettings(out failureReason))
			{
				return false;
			}
			if (!TryLoadMaps(out failureReason))
			{
				return false;
			}
			if (!TryBindExactSampler(out failureReason))
			{
				return false;
			}
			ResolveWater();
			_overlayTexture = CreateForestedOverlayTexture();
			_ready = true;
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)"Better Continents base-height sampler linked.");
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)"Exact terrain-height mode active.");
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)("Better Continents mapping: worldSize=" + _settings.WorldSize.ToString("F0") + " edgeSize=" + _settings.EdgeSize.ToString("F0") + " totalRadius=" + _settings.TotalRadius.ToString("F0") + " totalSpan=" + _settings.TotalSize.ToString("F0") + ". UV = Clamp(world/totalSpan + 0.5), PNG rows top-down."));
			return true;
		}

		private static bool IsBetterContinentsPresent()
		{
			if (Chainloader.PluginInfos != null)
			{
				return Chainloader.PluginInfos.ContainsKey("BetterContinents");
			}
			return false;
		}

		private bool TryLoadSettings(out string failure)
		{
			failure = "";
			string text = ResolvePath(_plugin._betterContinentsConfigFile.Value, Paths.ConfigPath);
			if (!File.Exists(text))
			{
				failure = "Missing BetterContinents.cfg at " + text;
				return false;
			}
			Dictionary<string, string> values = ReadSimpleConfig(text);
			_settings = BetterContinentsMapSettings.CreateDefault(10500f);
			_settings.WorldSize = GetConfigFloat(values, "World Size", _settings.WorldSize);
			_settings.EdgeSize = GetConfigFloat(values, "Edge Size", _settings.EdgeSize);
			_settings.Recalculate();
			_settings.ConfigHash = FileHashShort(text);
			return true;
		}

		private bool TryLoadMaps(out string failure)
		{
			failure = "";
			string path = ResolvePath(_plugin._mapFolder.Value, Paths.PluginPath);
			string path2 = Path.Combine(path, _plugin._heightMapFile.Value);
			string path3 = Path.Combine(path, _plugin._colourMapFile.Value);
			string path4 = Path.Combine(path, _plugin._forestMapFile.Value);
			if (!File.Exists(path2) || !File.Exists(path3) || !File.Exists(path4))
			{
				failure = "Required Donegal custom-map PNGs missing. height=" + File.Exists(path2) + " colour=" + File.Exists(path3) + " forest=" + File.Exists(path4);
				return false;
			}
			_heightMap = LoadPng(path2, (FilterMode)0);
			_colourMap = LoadPng(path3, (FilterMode)1);
			_forestMap = LoadPng(path4, (FilterMode)1);
			if (((Texture)_heightMap).width != ((Texture)_heightMap).height || ((Texture)_heightMap).width < 512)
			{
				failure = "heightmap.png is not a readable square map.";
				return false;
			}
			_colourPixels = _colourMap.GetPixels32();
			_forestPixels = _forestMap.GetPixels32();
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)("Assets ready. Height " + ((Texture)_heightMap).width + "x" + ((Texture)_heightMap).height + "; colour " + ((Texture)_colourMap).width + "x" + ((Texture)_colourMap).height + "; forest " + ((Texture)_forestMap).width + "x" + ((Texture)_forestMap).height + "."));
			return true;
		}

		private bool TryBindExactSampler(out string failure)
		{
			failure = "";
			_worldGenerator = WorldGenerator.instance;
			if (_worldGenerator == null)
			{
				failure = "WorldGenerator.instance is not ready yet.";
				return false;
			}
			MethodInfo method = typeof(WorldGenerator).GetMethod("GetBaseHeight", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(bool)
			}, null);
			if (method == null)
			{
				failure = "Could not find private WorldGenerator.GetBaseHeight(float,float,bool).";
				return false;
			}
			_getBaseHeight = (GetBaseHeightDelegate)Delegate.CreateDelegate(typeof(GetBaseHeightDelegate), method);
			float num = SampleHeightOnly(0f, 0f);
			float num2 = SampleHeightOnly(0f, 4000f);
			float num3 = SampleHeightOnly(4000f, 0f);
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)("Better Continents base-height sampler linked. Building far terrain ring. Samples (metres): center=" + num.ToString("F1") + ", north=" + num2.ToString("F1") + ", east=" + num3.ToString("F1") + "."));
			return true;
		}

		public bool TrySample(float worldX, float worldZ, out WorldSurfaceSample sample)
		{
			//IL_008c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			sample = default(WorldSurfaceSample);
			if (!_ready || _worldGenerator == null || _getBaseHeight == null || worldX * worldX + worldZ * worldZ > _settings.TotalRadius * _settings.TotalRadius)
			{
				return false;
			}
			float num = SampleHeightOnly(worldX, worldZ);
			Biome biome = (Biome)0;
			try
			{
				biome = _worldGenerator.GetBiome(new Vector3(worldX, 0f, worldZ));
			}
			catch
			{
			}
			float num2 = SampleForestMap(worldX, worldZ);
			float slopeDegrees = CalculateSlope(worldX, worldZ, _plugin._slopeSampleRadius.Value);
			bool isWaterOrOcean = IsWater(biome, num, worldX, worldZ);
			sample.Valid = true;
			sample.GroundY = num;
			sample.Biome = biome;
			sample.ForestDensity = Mathf.Clamp01(num2);
			sample.SlopeDegrees = slopeDegrees;
			sample.IsWaterOrOcean = isWaterOrOcean;
			sample.HeightSource = HeightSource;
			sample.ForestSource = ForestSource;
			return true;
		}

		public Vector2 GetTerrainUv(float worldX, float worldZ)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			WorldToUvTopDown(worldX, worldZ, out var u, out var v);
			return new Vector2(u, 1f - v);
		}

		public Color GetTerrainColor(float worldX, float worldZ, float distanceFromAnchor)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_colourMap == (Object)null)
			{
				return Color.gray;
			}
			WorldToUvTopDown(worldX, worldZ, out var u, out var v);
			return SampleTextureColourTopDown(_colourPixels, ((Texture)_colourMap).width, ((Texture)_colourMap).height, u, v);
		}

		public void UpdateBackgroundWork(float budgetMs)
		{
		}

		public void DeleteCache()
		{
		}

		private float SampleHeightOnly(float worldX, float worldZ)
		{
			float num = _getBaseHeight(_worldGenerator, worldX, worldZ, menuTerrain: false);
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				num = 0f;
			}
			return num * 200f;
		}

		private float CalculateSlope(float x, float z, float r)
		{
			float num = SampleHeightOnly(x + r, z);
			float num2 = SampleHeightOnly(x - r, z);
			float num3 = SampleHeightOnly(x, z + r);
			float num4 = SampleHeightOnly(x, z - r);
			float num5 = (num - num2) / (2f * r);
			float num6 = (num3 - num4) / (2f * r);
			return Mathf.Atan(Mathf.Sqrt(num5 * num5 + num6 * num6)) * 57.29578f;
		}

		private bool IsWater(Biome biome, float ground, float x, float 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)
			if ((biome & 0x100) != 0)
			{
				return true;
			}
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Override)
			{
				return ground <= _plugin._waterSurfaceHeightOverride.Value + _plugin._waterClearance.Value;
			}
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Auto && (Object)(object)ZoneSystem.instance != (Object)null)
			{
				float waterLevel = ZoneSystem.instance.m_waterLevel;
				if (ground <= waterLevel + _plugin._waterClearance.Value)
				{
					return true;
				}
				if (ground <= waterLevel + _plugin._waterClearance.Value + 2f)
				{
					float value = _plugin._shoreSampleRadius.Value;
					if (!(SampleHeightOnly(x + value, z) <= waterLevel + _plugin._waterClearance.Value) && !(SampleHeightOnly(x - value, z) <= waterLevel + _plugin._waterClearance.Value) && !(SampleHeightOnly(x, z + value) <= waterLevel + _plugin._waterClearance.Value))
					{
						return SampleHeightOnly(x, z - value) <= waterLevel + _plugin._waterClearance.Value;
					}
					return true;
				}
			}
			return false;
		}

		private void ResolveWater()
		{
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Override)
			{
				_waterLevel = _plugin._waterSurfaceHeightOverride.Value;
				_waterSource = "override " + _waterLevel.ToString("F1", CultureInfo.InvariantCulture);
			}
			else if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Auto && (Object)(object)ZoneSystem.instance != (Object)null)
			{
				_waterLevel = ZoneSystem.instance.m_waterLevel;
				_waterSource = "ZoneSystem.instance.m_waterLevel " + _waterLevel.ToString("F1", CultureInfo.InvariantCulture);
			}
			else
			{
				_waterSource = "unresolved conservative";
			}
		}

		private Texture2D CreateForestedOverlayTexture()
		{
			//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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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)
			Color32[] pixels = _colourMap.GetPixels32();
			Color32[] array = (Color32[])(object)new Color32[pixels.Length];
			Color val = ParseColor(_plugin._forestTerrainTintColour.Value, new Color(0.14f, 0.23f, 0.17f, 1f));
			int width = ((Texture)_colourMap).width;
			int height = ((Texture)_colourMap).height;
			for (int i = 0; i < height; i++)
			{
				int num = height - 1 - i;
				float vTopDown = ((height > 1) ? ((float)num / (float)(height - 1)) : 0f);
				for (int j = 0; j < width; j++)
				{
					int num2 = i * width + j;
					float u = ((width > 1) ? ((float)j / (float)(width - 1)) : 0f);
					float num3 = Mathf.Clamp01(SamplePixels(_forestPixels, ((Texture)_forestMap).width, ((Texture)_forestMap).height, u, vTopDown) * _plugin.ForestDensityMultiplier());
					Color val2 = Color32.op_Implicit(pixels[num2]);
					float num4 = Mathf.Clamp01((num3 - _plugin.ForestDensityThreshold()) / Mathf.Max(0.01f, 1f - _plugin.ForestDensityThreshold()));
					Color val3 = Color.Lerp(val2, val, num4 * _plugin.ForestTerrainTintStrength());
					array[num2] = Color32.op_Implicit(val3);
				}
			}
			Texture2D val4 = new Texture2D(width, height, (TextureFormat)3, true, false);
			((Object)val4).name = "DonegalForestedHorizonTexture_Runtime";
			((Texture)val4).wrapMode = (TextureWrapMode)1;
			((Texture)val4).filterMode = (FilterMode)1;
			val4.SetPixels32(array);
			val4.Apply(true, false);
			return val4;
		}

		private float SampleForestMap(float worldX, float worldZ)
		{
			WorldToUvTopDown(worldX, worldZ, out var u, out var v);
			return SamplePixels(_forestPixels, ((Texture)_forestMap).width, ((Texture)_forestMap).height, u, v);
		}

		private void WorldToUvTopDown(float worldX, float worldZ, out float u, out float v)
		{
			float num = Mathf.Max(1f, _settings.TotalSize);
			u = Mathf.Clamp01(worldX / num + 0.5f);
			v = Mathf.Clamp01(worldZ / num + 0.5f);
		}

		public void Dispose()
		{
			if ((Object)(object)_heightMap != (Object)null)
			{
				Object.Destroy((Object)(object)_heightMap);
			}
			if ((Object)(object)_colourMap != (Object)null)
			{
				Object.Destroy((Object)(object)_colourMap);
			}
			if ((Object)(object)_forestMap != (Object)null)
			{
				Object.Destroy((Object)(object)_forestMap);
			}
			if ((Object)(object)_overlayTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayTexture);
			}
			_heightMap = null;
			_colourMap = null;
			_forestMap = null;
			_overlayTexture = null;
			_colourPixels = null;
			_forestPixels = null;
			_ready = false;
		}
	}

	private sealed class ProceduralWorldProvider : IWorldDataProvider
	{
		private readonly DonegalHorizonLiftPlugin _plugin;

		private WorldGenerator _worldGenerator;

		private GetBaseHeightDelegate _getBaseHeight;

		private bool _ready;

		private int _stableSeed;

		private string _worldIdentity = "procedural:pending";

		private string _worldName = "unknown";

		private string _waterSource = "unresolved conservative";

		private float _waterLevel;

		public string ProviderName => "ProceduralWorld";

		public bool IsReady => _ready;

		public float WorldRadius => _plugin._proceduralWorldRadius.Value;

		public float ValidForestRange => Mathf.Max(0f, WorldRadius - 500f);

		public int StableSeed => _stableSeed;

		public string WorldIdentity => _worldIdentity;

		public string HeightSource => "private WorldGenerator.GetBaseHeight(float,float,bool) * 200 (native procedural)";

		public string BiomeSource => "WorldGenerator.GetBiome(Vector3)";

		public string ForestSource => "deterministic biome-aware procedural density";

		public string WaterSource => _waterSource;

		public string ExactSamplerStatus
		{
			get
			{
				if (_getBaseHeight == null)
				{
					return "failed";
				}
				return "linked native procedural";
			}
		}

		public string TerrainOverlayStatus => "per-tile procedural biome colour";

		public string CacheStatus => "not used";

		public bool UsesSharedTerrainTexture => false;

		public Texture2D SharedTerrainTexture => null;

		public ProceduralWorldProvider(DonegalHorizonLiftPlugin plugin)
		{
			_plugin = plugin;
		}

		public bool TryInitialize(out string failureReason)
		{
			failureReason = "";
			if (!_plugin.IsGameplayWorldReady(out var reason))
			{
				failureReason = reason;
				return false;
			}
			_worldGenerator = WorldGenerator.instance;
			if (_worldGenerator == null)
			{
				failureReason = "WorldGenerator.instance is not ready yet.";
				return false;
			}
			MethodInfo method = typeof(WorldGenerator).GetMethod("GetBaseHeight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
			{
				typeof(float),
				typeof(float),
				typeof(bool)
			}, null);
			if (method == null || method.ReturnType != typeof(float))
			{
				failureReason = "Could not find WorldGenerator.GetBaseHeight(float,float,bool) required for safe native procedural far terrain.";
				return false;
			}
			try
			{
				_getBaseHeight = (GetBaseHeightDelegate)Delegate.CreateDelegate(typeof(GetBaseHeightDelegate), method);
			}
			catch (Exception ex)
			{
				failureReason = "Could not bind WorldGenerator.GetBaseHeight(float,float,bool): " + ex.Message;
				return false;
			}
			ResolveWorldIdentity();
			ResolveWater();
			_ready = true;
			float num = SampleHeightOnly(0f, 0f);
			float num2 = SampleHeightOnly(0f, 4000f);
			float num3 = SampleHeightOnly(4000f, 0f);
			((BaseUnityPlugin)_plugin).Logger.LogInfo((object)("ProceduralWorld sampler linked. World '" + _worldName + "', seed " + _stableSeed.ToString(CultureInfo.InvariantCulture) + ", radius " + WorldRadius.ToString("F0", CultureInfo.InvariantCulture) + "m. Samples (metres): center=" + num.ToString("F1", CultureInfo.InvariantCulture) + ", north=" + num2.ToString("F1", CultureInfo.InvariantCulture) + ", east=" + num3.ToString("F1", CultureInfo.InvariantCulture) + "."));
			return true;
		}

		public bool TrySample(float worldX, float worldZ, out WorldSurfaceSample sample)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009c: 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_004f: 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)
			sample = default(WorldSurfaceSample);
			if (!_ready || _worldGenerator == null || _getBaseHeight == null || worldX * worldX + worldZ * worldZ > WorldRadius * WorldRadius)
			{
				return false;
			}
			float num = SampleHeightOnly(worldX, worldZ);
			Biome biome = (Biome)0;
			try
			{
				biome = _worldGenerator.GetBiome(new Vector3(worldX, 0f, worldZ));
			}
			catch
			{
			}
			float num2 = CalculateSlope(worldX, worldZ, _plugin._slopeSampleRadius.Value);
			bool flag = IsWater(biome, num, worldX, worldZ);
			sample.Valid = true;
			sample.GroundY = num;
			sample.Biome = biome;
			sample.ForestDensity = SampleForestDensity(worldX, worldZ, biome, num2, flag);
			sample.SlopeDegrees = num2;
			sample.IsWaterOrOcean = flag;
			sample.HeightSource = HeightSource;
			sample.ForestSource = ForestSource;
			return true;
		}

		public Vector2 GetTerrainUv(float worldX, float worldZ)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(1f, WorldRadius * 2f);
			return new Vector2(Mathf.Clamp01(worldX / num + 0.5f), Mathf.Clamp01(worldZ / num + 0.5f));
		}

		public Color GetTerrainColor(float worldX, float worldZ, float distanceFromAnchor)
		{
			//IL_0001: 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_0014: 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_0040: 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)
			Biome biome = (Biome)0;
			try
			{
				biome = _worldGenerator.GetBiome(new Vector3(worldX, 0f, worldZ));
			}
			catch
			{
			}
			float ground = SampleHeightOnly(worldX, worldZ);
			float noise = ProceduralNoise(worldX, worldZ, 650f, 0.62f, 0.38f);
			return BiomeTerrainColour(biome, ground, noise);
		}

		public void UpdateBackgroundWork(float budgetMs)
		{
		}

		public void DeleteCache()
		{
		}

		private float SampleHeightOnly(float worldX, float worldZ)
		{
			float num = _getBaseHeight(_worldGenerator, worldX, worldZ, menuTerrain: false);
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				num = 0f;
			}
			return num * 200f;
		}

		private float CalculateSlope(float x, float z, float radius)
		{
			float num = Mathf.Max(0.5f, radius);
			float num2 = SampleHeightOnly(x + num, z);
			float num3 = SampleHeightOnly(x - num, z);
			float num4 = SampleHeightOnly(x, z + num);
			float num5 = SampleHeightOnly(x, z - num);
			float num6 = (num2 - num3) / (2f * num);
			float num7 = (num4 - num5) / (2f * num);
			return Mathf.Atan(Mathf.Sqrt(num6 * num6 + num7 * num7)) * 57.29578f;
		}

		private float SampleForestDensity(float worldX, float worldZ, Biome biome, float slope, bool water)
		{
			//IL_0004: 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_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (water || (biome & 0x100) != 0 || (biome & 0x20) != 0)
			{
				return 0f;
			}
			float num = (((biome & 8) != 0) ? 0.86f : (((biome & 1) != 0) ? 0.52f : (((biome & 2) != 0) ? 0.68f : (((biome & 0x200) != 0) ? 0.62f : (((biome & 0x40) != 0) ? 0.42f : (((biome & 4) != 0) ? 0.24f : (((biome & 0x10) == 0) ? 0.28f : 0.2f)))))));
			float num2 = ProceduralNoise(worldX, worldZ, 1000f, 0.68f, 0.32f);
			float num3 = ProceduralNoise(worldX + 937.4f, worldZ - 571.9f, 280f, 0.45f, 0.55f);
			float num4 = num * Mathf.Lerp(0.38f, 1.18f, num2) * Mathf.Lerp(0.75f, 1.15f, num3);
			float num5 = 1f - Mathf.Clamp01(Mathf.InverseLerp(_plugin._slopeRejectionThreshold.Value * 0.7f, _plugin._hardSlopeRejectionThreshold.Value, slope));
			return Mathf.Clamp01(num4 * num5);
		}

		private float ProceduralNoise(float worldX, float worldZ, float scale, float macroWeight, float detailWeight)
		{
			float num = (float)(_stableSeed & 0x7FFF) * 0.01337f;
			float num2 = (float)((_stableSeed >> 8) & 0x7FFF) * 0.01771f;
			float num3 = Mathf.PerlinNoise((worldX + num) / Mathf.Max(1f, scale), (worldZ + num2) / Mathf.Max(1f, scale));
			float num4 = Mathf.PerlinNoise((worldX - num2 * 3.1f) / Mathf.Max(1f, scale * 0.31f), (worldZ + num * 2.3f) / Mathf.Max(1f, scale * 0.31f));
			return Mathf.Clamp01(num3 * macroWeight + num4 * detailWeight);
		}

		private static Color BiomeTerrainColour(Biome biome, float ground, float noise)
		{
			//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_0029: 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_004f: 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_0145: 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_0078: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: 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_009f: 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_017d: 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_018e: 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_00c4: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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)
			Color val = default(Color);
			if ((biome & 0x100) != 0)
			{
				((Color)(ref val))..ctor(0.08f, 0.17f, 0.23f, 1f);
			}
			else if ((biome & 0x20) != 0)
			{
				((Color)(ref val))..ctor(0.24f, 0.13f, 0.1f, 1f);
			}
			else if ((biome & 0x200) != 0)
			{
				((Color)(ref val))..ctor(0.22f, 0.26f, 0.21f, 1f);
			}
			else if ((biome & 2) != 0)
			{
				((Color)(ref val))..ctor(0.18f, 0.25f, 0.16f, 1f);
			}
			else if ((biome & 8) != 0)
			{
				((Color)(ref val))..ctor(0.17f, 0.27f, 0.16f, 1f);
			}
			else if ((biome & 4) != 0)
			{
				((Color)(ref val))..ctor(0.46f, 0.47f, 0.45f, 1f);
			}
			else if ((biome & 0x40) != 0)
			{
				((Color)(ref val))..ctor(0.56f, 0.61f, 0.62f, 1f);
			}
			else if ((biome & 0x10) != 0)
			{
				((Color)(ref val))..ctor(0.44f, 0.42f, 0.2f, 1f);
			}
			else
			{
				((Color)(ref val))..ctor(0.34f, 0.42f, 0.22f, 1f);
			}
			if ((biome & 4) != 0 && ground > 70f)
			{
				float num = Mathf.Clamp01(Mathf.InverseLerp(70f, 130f, ground));
				val = Color.Lerp(val, new Color(0.78f, 0.8f, 0.79f, 1f), num * 0.7f);
			}
			float num2 = Mathf.Lerp(0.86f, 1.1f, noise);
			return new Color(Mathf.Clamp01(val.r * num2), Mathf.Clamp01(val.g * num2), Mathf.Clamp01(val.b * num2), 1f);
		}

		private bool IsWater(Biome biome, float ground, float x, float 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)
			if ((biome & 0x100) != 0)
			{
				return true;
			}
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Override)
			{
				return ground <= _plugin._waterSurfaceHeightOverride.Value + _plugin._waterClearance.Value;
			}
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Auto && (Object)(object)ZoneSystem.instance != (Object)null)
			{
				float waterLevel = ZoneSystem.instance.m_waterLevel;
				if (ground <= waterLevel + _plugin._waterClearance.Value)
				{
					return true;
				}
				if (ground <= waterLevel + _plugin._waterClearance.Value + 2f)
				{
					float value = _plugin._shoreSampleRadius.Value;
					if (!(SampleHeightOnly(x + value, z) <= waterLevel + _plugin._waterClearance.Value) && !(SampleHeightOnly(x - value, z) <= waterLevel + _plugin._waterClearance.Value) && !(SampleHeightOnly(x, z + value) <= waterLevel + _plugin._waterClearance.Value))
					{
						return SampleHeightOnly(x, z - value) <= waterLevel + _plugin._waterClearance.Value;
					}
					return true;
				}
			}
			return false;
		}

		private void ResolveWater()
		{
			if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Override)
			{
				_waterLevel = _plugin._waterSurfaceHeightOverride.Value;
				_waterSource = "override " + _waterLevel.ToString("F1", CultureInfo.InvariantCulture);
			}
			else if (_plugin._waterSurfaceMode.Value == WaterSurfaceMode.Auto && (Object)(object)ZoneSystem.instance != (Object)null)
			{
				_waterLevel = ZoneSystem.instance.m_waterLevel;
				_waterSource = "ZoneSystem.instance.m_waterLevel " + _waterLevel.ToString("F1", CultureInfo.InvariantCulture);
			}
			else
			{
				_waterSource = "unresolved conservative";
			}
		}

		private static object ReadStaticMember(Type type, params string[] names)
		{
			if (type == null)
			{
				return null;
			}
			for (int i = 0; i < names.Length; i++)
			{
				FieldInfo field = type.GetField(names[i], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field.GetValue(null);
				}
				PropertyInfo property = type.GetProperty(names[i], BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.GetIndexParameters().Length == 0)
				{
					return property.GetValue(null, null);
				}
			}
			return null;
		}

		private void ResolveWorldIdentity()
		{
			_stableSeed = 91009;
			_worldName = "unknown";
			try
			{
				Type type = typeof(WorldGenerator).Assembly.GetType("ZNet");
				if (type != null)
				{
					object obj = ReadStaticMember(type, "instance", "Instance");
					MethodInfo methodInfo = ((obj != null) ? type.GetMethod("GetWorld", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) : null);
					object obj2 = ((methodInfo != null) ? methodInfo.Invoke(obj, null) : null);
					if (obj2 != null)
					{
						if (TryReadIntMember(obj2, out var value, "m_seed", "Seed", "seed"))
						{
							_stableSeed = value;
						}
						if (TryReadStringMember(obj2, out var value2, "m_name", "Name", "name") && !string.IsNullOrEmpty(value2))
						{
							_worldName = value2;
						}
					}
				}
				if (_stableSeed == 91009 && TryReadIntMember(_worldGenerator, out var value3, "m_seed", "m_worldSeed", "Seed"))
				{
					_stableSeed = value3;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)_plugin).Logger.LogWarning((object)("ProceduralWorld could not read active world identity; using stable fallback seed. " + ex.Message));
			}
			_worldIdentity = "PROCEDURAL:" + _worldName + ":" + _stableSeed.ToString(CultureInfo.InvariantCulture) + ":" + Mathf.RoundToInt(WorldRadius).ToString(CultureInfo.InvariantCulture);
		}

		private static bool TryReadIntMember(object instance, out int value, params string[] names)
		{
			value = 0;
			if (instance == null)
			{
				return false;
			}
			Type type = instance.GetType();
			for (int i = 0; i < names.Length; i++)
			{
				FieldInfo field = type.GetField(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(int))
				{
					value = (int)field.GetValue(instance);
					return true;
				}
				PropertyInfo property = type.GetProperty(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(int) && property.GetIndexParameters().Length == 0)
				{
					value = (int)property.GetValue(instance, null);
					return true;
				}
			}
			return false;
		}

		private static bool TryReadStringMember(object instance, out string value, params string[] names)
		{
			value = "";
			if (instance == null)
			{
				return false;
			}
			Type type = instance.GetType();
			for (int i = 0; i < names.Length; i++)
			{
				FieldInfo field = type.GetField(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(string))
				{
					value = field.GetValue(instance) as string;
					return true;
				}
				PropertyInfo property = type.GetProperty(names[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(string) && property.GetIndexParameters().Length == 0)
				{
					value = property.GetValue(instance, null) as string;
					return true;
				}
			}
			return false;
		}

		public void Dispose()
		{
			_ready = false;
			_worldGenerator = null;
			_getBaseHeight = null;
		}
	}

	private sealed class TerrainTile
	{
		public readonly GameObject Root;

		public readonly MeshFilter Filter;

		public readonly MeshRenderer Renderer;

		public readonly Vector3 Center;

		public readonly float Size;

		public Mesh Mesh;

		public Material Material;

		public Texture2D Texture;

		public float[] HeightGrid;

		public int GridResolution;

		public TerrainTile(int x, int z, float size, Transform parent)
		{
			//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)
			Size = size;
			Center = new Vector3(((float)x + 0.5f) * size, 0f, ((float)z + 0.5f) * size);
			Root = CreateMeshObject("DonegalHorizonTerrainTile_" + x + "_" + z, parent, out Filter, out Renderer);
		}

		public void Destroy()
		{
			if ((Object)(object)Mesh != (Object)null)
			{
				Object.Destroy((Object)(object)Mesh);
			}
			if ((Object)(object)Material != (Object)null)
			{
				Object.Destroy((Object)(object)Material);
			}
			if ((Object)(object)Texture != (Object)null)
			{
				Object.Destroy((Object)(object)Texture);
			}
			if ((Object)(object)Root != (Object)null)
			{
				Object.Destroy((Object)(object)Root);
			}
		}
	}

	private sealed class ForestChunkBuffers
	{
		public int ChunkX;

		public int ChunkZ;

		public float ChunkSize;

		public int Shard;

		public bool Pooled;

		public readonly List<Vector3> MassVertices = new List<Vector3>(256);

		public readonly List<int> MassTriangles = new List<int>(384);

		public readonly List<Vector3> TreeVertices = new List<Vector3>(512);

		public readonly List<Vector2> TreeUvs = new List<Vector2>(512);

		public readonly List<int> TreeTriangles = new List<int>(768);

		public readonly List<Vector3> CanopyVertices = new List<Vector3>(256);

		public readonly List<Vector2> CanopyUvs = new List<Vector2>(256);

		public readonly List<int> CanopyTriangles = new List<int>(384);

		public readonly List<Vector3> MountainVertices = new List<Vector3>(256);

		public readonly List<Vector2> MountainUvs = new List<Vector2>(256);

		public readonly List<int> MountainTriangles = new List<int>(384);

		public readonly List<Vector3> SwampVertices = new List<Vector3>(256);

		public readonly List<Vector2> SwampUvs = new List<Vector2>(256);

		public readonly List<int> SwampTriangles = new List<int>(384);

		public int TreeBucketTreePlanes;

		public int CanopyBucketCanopyPlanes;

		public int MountainTreePlanes;

		public int MountainCanopyPlanes;

		public int SwampTreePlanes;

		public int SwampCanopyPlanes;

		public int DetailedLogicalCards;

		public int DetailedCrossedLogicalCards;

		public int DetailedSinglePlaneLogicalCards;

		public int DetailedTriangleCount => (TreeTriangles.Count + CanopyTriangles.Count + MountainTriangles.Count + SwampTriangles.Count) / 3;

		public int DetailedVertexCount => TreeVertices.Count + CanopyVertices.Count + MountainVertices.Count + SwampVertices.Count;

		public ForestChunkBuffers(int chunkX, int chunkZ, float chunkSize, int shard)
		{
			Prepare(chunkX, chunkZ, chunkSize, shard);
		}

		public void Prepare(int chunkX, int chunkZ, float chunkSize, int shard)
		{
			ChunkX = chunkX;
			ChunkZ = chunkZ;
			ChunkSize = chunkSize;
			Shard = shard;
			Pooled = false;
			TreeBucketTreePlanes = 0;
			CanopyBucketCanopyPlanes = 0;
			MountainTreePlanes = 0;
			MountainCanopyPlanes = 0;
			SwampTreePlanes = 0;
			SwampCanopyPlanes = 0;
			DetailedLogicalCards = 0;
			DetailedCrossedLogicalCards = 0;
			DetailedSinglePlaneLogicalCards = 0;
		}

		public void ClearForPool()
		{
			MassVertices.Clear();
			MassTriangles.Clear();
			TreeVertices.Clear();
			TreeUvs.Clear();
			TreeTriangles.Clear();
			CanopyVertices.Clear();
			CanopyUvs.Clear();
			CanopyTriangles.Clear();
			MountainVertices.Clear();
			MountainUvs.Clear();
			MountainTriangles.Clear();
			SwampVertices.Clear();
			SwampUvs.Clear();
			SwampTriangles.Clear();
			Pooled = true;
		}

		public void RecordLogicalTreeCard(bool singlePlane)
		{
			DetailedLogicalCards++;
			if (singlePlane)
			{
				DetailedSinglePlaneLogicalCards++;
			}
			else
			{
				DetailedCrossedLogicalCards++;
			}
		}

		public void RecordAtlasPlanes(List<Vector3> targetVertices, int count, bool canopy)
		{
			if (count <= 0)
			{
				return;
			}
			if (targetVertices == TreeVertices)
			{
				TreeBucketTreePlanes += count;
			}
			else if (targetVertices == CanopyVertices)
			{
				CanopyBucketCanopyPlanes += count;
			}
			else if (targetVertices == MountainVertices)
			{
				if (canopy)
				{
					MountainCanopyPlanes += count;
				}
				else
				{
					MountainTreePlanes += count;
				}
			}
			else if (targetVertices == SwampVertices)
			{
				if (canopy)
				{
					SwampCanopyPlanes += count;
				}
				else
				{
					SwampTreePlanes += count;
				}
			}
		}
	}

	private sealed class ForestChunkMeshSet
	{
		public int ChunkX;

		public int ChunkZ;

		public float ChunkSize;

		public int Shard;

		public Mesh MassMesh;

		public Mesh TreeCardMesh;

		public Mesh CanopyMesh;

		public Mesh MountainBiomeMesh;

		public Mesh SwampBiomeMesh;

		public int TreePlaneCount;

		public int CanopyPlaneCount;

		public int LogicalTreeCardCount;

		public int CrossedLogicalTreeCardCount;

		public int SinglePlaneLogicalTreeCardCount;
	}

	private sealed class ForestBuildResult
	{
		public List<ForestChunkMeshSet> Chunks;

		public int ClusterCount;

		public int TreeCardCount;

		public int CanopyCardCount;

		public float NearestDensity;

		public int CandidateTotal;

		public int CandidatesCompleted;

		public int[] StableCardRecords;

		public ViewFacingForestOverloadState GeometryOverloadState;
	}

	private sealed class ForestChunk
	{
		public readonly GameObject Root;

		public readonly MeshFilter MassFilter;

		public readonly MeshRenderer MassRenderer;

		public readonly MeshFilter TreeFilter;

		public readonly MeshRenderer TreeRenderer;

		public readonly MeshFilter CanopyFilter;

		public readonly MeshRenderer CanopyRenderer;

		public readonly MeshFilter MountainBiomeFilter;

		public readonly MeshRenderer MountainBiomeRenderer;

		public readonly MeshFilter SwampBiomeFilter;

		public readonly MeshRenderer SwampBiomeRenderer;

		public readonly Vector3 Center;

		public readonly float Size;

		public Mesh MassMesh;

		public Mesh TreeCardMesh;

		public Mesh CanopyMesh;

		public Mesh MountainBiomeMesh;

		public Mesh SwampBiomeMesh;

		public Bounds WorldBounds;

		public bool HasBounds;

		public int LogicalTreeCardCount;

		public int CrossedLogicalTreeCardCount;

		public int SinglePlaneLogicalTreeCardCount;

		public int DetailedRendererCount;

		public long DetailedVertexCount;

		public long DetailedTriangleCount;

		public bool Enabled;

		public readonly Vector3 CreatedWorldPosition;

		public readonly Vector3 LocalOrigin;

		public ForestChunk(int chunkX, int chunkZ, float size, Transform parent, int shard = 0)
		{
			//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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			Size = size;
			Center = new Vector3(((float)chunkX + 0.5f) * size, 0f, ((float)chunkZ + 0.5f) * size);
			Root = new GameObject("DonegalHorizonForestChunk_" + chunkX + "_" + chunkZ + "_s" + shard);
			Root.layer = 0;
			Root.transform.SetParent(parent, false);
			LocalOrigin = new Vector3((float)chunkX * size, 0f, (float)chunkZ * size);
			Root.transform.localPosition = LocalOrigin;
			Root.transform.localRotation = Quaternion.identity;
			Root.transform.localScale = Vector3.one;
			CreatedWorldPosition = Root.transform.position;
			GameObject val = CreateMeshObject("Mass", Root.transform, out MassFilter, out MassRenderer);
			GameObject val2 = CreateMeshObject("TreeCards", Root.transform, out TreeFilter, out TreeRenderer);
			GameObject val3 = CreateMeshObject("Canopy", Root.transform, out CanopyFilter, out CanopyRenderer);
			GameObject val4 = CreateMeshObject("MountainBiomeCards", Root.transform, out MountainBiomeFilter, out MountainBiomeRenderer);
			GameObject val5 = CreateMeshObject("SwampBiomeCards", Root.transform, out SwampBiomeFilter, out SwampBiomeRenderer);
			val.transform.localPosition = Vector3.zero;
			val2.transform.localPosition = Vector3.zero;
			val3.transform.localPosition = Vector3.zero;
			val4.transform.localPosition = Vector3.zero;
			val5.transform.localPosition = Vector3.zero;
		}

		public void RecalculateBounds()
		{
			//IL_0020: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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)
			HasBounds = false;
			DetailedRendererCount = 0;
			DetailedVertexCount = 0L;
			DetailedTriangleCount = 0L;
			Bounds combined = default(Bounds);
			if ((Object)(object)MassMesh != (Object)null)
			{
				Encapsulate(ref combined, ref HasBounds, ((Renderer)MassRenderer).bounds);
			}
			if ((Object)(object)TreeCardMesh != (Object)null)
			{
				Encapsulate(ref combined, ref HasBounds, ((Renderer)TreeRenderer).bounds);
				AccumulateDetailedMesh(TreeCardMesh);
			}
			if ((Object)(object)CanopyMesh != (Object)null)
			{
				Encapsulate(ref combined, ref HasBounds, ((Renderer)CanopyRenderer).bounds);
				AccumulateDetailedMesh(CanopyMesh);
			}
			if ((Object)(object)MountainBiomeMesh != (Object)null)
			{
				Encapsulate(ref combined, ref HasBounds, ((Renderer)MountainBiomeRenderer).bounds);
				AccumulateDetailedMesh(MountainBiomeMesh);
			}
			if ((Object)(object)SwampBiomeMesh != (Object)null)
			{
				Encapsulate(ref combined, ref HasBounds, ((Renderer)SwampBiomeRenderer).bounds);
				AccumulateDetailedMesh(SwampBiomeMesh);
			}
			WorldBounds = combined;
			if (!HasBounds)
			{
				WorldBounds = new Bounds(Center, new Vector3(Size, 1f, Size));
			}
		}

		private void AccumulateDetailedMesh(Mesh mesh)
		{
			if (!((Object)(object)mesh == (Object)null))
			{
				DetailedRendererCount++;
				DetailedVertexCount += mesh.vertexCount;
				if (mesh.subMeshCount > 0)
				{
					DetailedTriangleCount += (long)mesh.GetIndexCount(0) / 3L;
				}
			}
		}

		private static void Encapsulate(ref Bounds combined, ref bool has, Bounds bounds)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!has)
			{
				combined = bounds;
				has = true;
			}
			else
			{
				((Bounds)(ref combined)).Encapsulate(bounds);
			}
		}

		public void SetEnabled(bool enabled)
		{
			if ((Object)(object)MassRenderer != (Object)null)
			{
				((Renderer)MassRenderer).enabled = enabled && (Object)(object)MassMesh != (Object)null;
			}
			if ((Object)(object)TreeRenderer != (Object)null)
			{
				((Renderer)TreeRenderer).enabled = enabled && (Object)(object)TreeCardMesh != (Object)null;
			}
			if ((Object)(object)CanopyRenderer != (Object)null)
			{
				((Renderer)CanopyRenderer).enabled = enabled && (Object)(object)CanopyMesh != (Object)null;
			}
			if ((Object)(object)MountainBiomeRenderer != (Object)null)
			{
				((Renderer)MountainBiomeRenderer).enabled = enabled && (Object)(object)MountainBiomeMesh != (Object)null;
			}
			if ((Object)(object)SwampBiomeRenderer != (Object)null)
			{
				((Renderer)SwampBiomeRenderer).enabled = enabled && (Object)(object)SwampBiomeMesh != (Object)null;
			}
			Enabled = enabled;
		}

		public void Destroy()
		{
			if ((Object)(object)MassMesh != (Object)null)
			{
				Object.Destroy((Object)(object)MassMesh);
			}
			if ((Object)(object)TreeCardMesh != (Object)null)
			{
				Object.Destroy((Object)(object)TreeCardMesh);
			}
			if ((Object)(object)CanopyMesh != (Object)null)
			{
				Object.Destroy((Object)(object)CanopyMesh);
			}
			if ((Object)(object)MountainBiomeMesh != (Object)null)
			{
				Object.Destroy((Object)(object)MountainBiomeMesh);
			}
			if ((Object)(object)SwampBiomeMesh != (Object)null)
			{
				Object.Destroy((Object)(object)SwampBiomeMesh);
			}
			if ((Object)(object)Root != (Object)null)
			{
				Object.Destroy((Object)(object)Root);
			}
		}
	}

	private sealed class ForestTile
	{
		public readonly GameObject Root;

		public readonly Vector3 Center;

		public readonly float Size;

		public readonly int TileX;

		public readonly int TileZ;

		public readonly List<ForestChunk> Chunks = new List<ForestChunk>();

		public int ClusterCount;

		public int TreeCardCount;

		public int CanopyCardCount;

		public float NearestDensity;

		public bool PrimaryPassOnly;

		public bool IsCoverageRepair;

		public int CandidateTotal;

		public int CandidatesCompleted;

		public int[] StableCardRecords;

		public ViewFacingForestOverloadState GeometryOverloadState;

		public string GenerationSignatureBase;

		public bool WasBoundaryBandTile;

		public float BuiltHBucket;

		public float BuiltOBucket;

		public float LastUsedRealtime;

		public string ContentHash;

		public int EstimatedVertexCount;

		public ForestTile(int x, int z, float size, Transform parent)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Size = size;
			TileX = x;
			TileZ = z;
			Center = new Vector3(((float)x + 0.5f) * size, 0f, ((float)z + 0.5f) * size);
			Root = new GameObject("DonegalHorizonForestTile_" + x + "_" + z);
			Root.layer = 0;
			Root.transform.SetParent(parent, false);
		}

		public void SetEnabled(bool enabled)
		{
			for (int i = 0; i < Chunks.Count; i++)
			{
				Chunks[i].SetEnabled(enabled);
			}
		}

		public void ResetForReuse()
		{
			//IL_001a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Root == (Object)null)
			{
				return;
			}
			Root.transform.localPosition = Vector3.zero;
			Root.transform.localRotation = Quaternion.identity;
			Root.transform.localScale = Vector3.one;
			for (int i = 0; i < Chunks.Count; i++)
			{
				ForestChunk forestChunk = Chunks[i];
				if (forestChunk != null && !((Object)(object)forestChunk.Root == (Object)null))
				{
					forestChunk.Root.transform.localPosition = forestChunk.LocalOrigin;
					forestChunk.Root.transform.localRotation = Quaternion.identity;
					forestChunk.Root.transform.localScale = Vector3.one;
					for (int j = 0; j < forestChunk.Root.transform.childCount; j++)
					{
						Transform child = forestChunk.Root.transform.GetChild(j);
						child.localPosition = Vector3.zero;
						child.localRotation = Quaternion.identity;
						child.localScale = Vector3.one;
					}
					forestChunk.SetEnabled(enabled: false);
					forestChunk.RecalculateBounds();
				}
			}
		}

		public void Destroy()
		{
			for (int i = 0; i < Chunks.Count; i++)
			{
				Chunks[i].Destroy();
			}
			Chunks.Clear();
			if ((Object)(object)Root != (Object)null)
			{
				Object.Destroy((Object)(object)Root);
			}
		}
	}

	private sealed class TileRequest
	{
		public readonly int X;

		public readonly int Z;

		public readonly float Distance;

		public readonly long Key;

		public bool IsPrimaryCoverage;

		public bool IsResident;

		public TileRequest(int x, int z, float distance, long key, bool isPrimaryCoverage = false)
		{
			X = x;
			Z = z;
			Distance = distance;
			Key = key;
			IsPrimaryCoverage = isPrimaryCoverage;
		}

		public static int CompareDistance(TileRequest a, TileRequest b)
		{
			return a.Distance.CompareTo(b.Distance);
		}

		public static int CompareResidentThenDistance(TileRequest a, TileRequest b)
		{
			if (a.IsResident != b.IsResident)
			{
				if (!a.IsResident)
				{
					return 1;
				}
				return -1;
			}
			return a.Distance.CompareTo(b.Distance);
		}
	}

	private sealed class ForestAddJob
	{
		public readonly int X;

		public readonly int Z;

		public readonly long Key;

		public float Distance;

		public readonly int Epoch;

		public readonly float QueuedAtRealtime;

		public int RetryCount;

		public bool IsPrimaryCoverage;

		public bool IsReinforcement;

		public ForestAddJob(int x, int z, long key, float distance, int epoch, float queuedAtRealtime, bool isPrimaryCoverage = false)
		{
			X = x;
			Z = z;
			Key = key;
			Distance = distance;
			Epoch = epoch;
			QueuedAtRealtime = queuedAtRealtime;
			IsPrimaryCoverage = isPrimaryCoverage;
		}
	}

	private struct BetterContinentsMapSettings
	{
		public float WorldSize;

		public float EdgeSize;

		public float TotalRadius;

		public float TotalSize;

		public string ConfigHash;

		public static BetterContinentsMapSettings CreateDefault(float radius)
		{
			BetterContinentsMapSettings result = default(BetterContinentsMapSettings);
			result.WorldSize = radius - 500f;
			result.EdgeSize = 500f;
			result.Recalculate();
			result.ConfigHash = "unknown";
			return result;
		}

		public void Recalculate()
		{
			TotalRadius = Mathf.Max(1f, WorldSize + EdgeSize);
			TotalSize = TotalRadius * 2f;
		}
	}

	public const string PluginGuid = "marc.donegalhorizonlift";

	public const string PluginName = "New Horizons Treelines";

	public const string PluginVersion = "4.6.31";

	private const string BuildName = "Swamp Trees Default Off";

	private const string BuildId = "NHT-4.6.31-20260717-SWAMP-TREES-DEFAULT-OFF";

	private const float Small = 0.0001f;

	private const float TreeCardMeshBottomSink = 0.01f;

	private const float HeightScale = 200f;

	private const float StandardForestVisibilityChunkSize = 64f;

	private const int ForestCoverageSectorCount = 16;

	private const int TreeStartAlgorithmVersion = 5;

	private const int PresetContractVersion = 5;

	private const int HandoffFillAlgorithmVersion = 6;

	private const int GroundingAlgorithmVersion = 10;

	private const int FinalBiomeRoutingVersion = 3;

	private const int BudgetSchedulingVersion = 13;

	private const int ContinuousCoverageAlgorithmVersion = 10;

	private const int CoverageSectorAlgorithmVersion = 2;

	private const int MeshAssemblyAlgorithmVersion = 1;

	private const int AtlasGeometryAlgorithmVersion = 10;

	private const int AdaptivePerformanceAlgorithmVersion = 2;

	private const int DeterministicGenerationVersion = 5;

	private const int StreamingAlgorithmVersion = 6;

	private const int TreeCardDensityAlgorithmVersion = 1;

	private const int DistributedDensityAlgorithmVersion = 2;

	private const int RendererAlgorithmVersion = 3;

	private const int RendererLodVersion = 2;

	private const int ViewFacingOverloadGuardVersion = 1;

	private const int BlackForestScaleVersion = 4;

	private const int MountainScaleVersion = 2;

	private const int BlackForestVisibleWidthVersion = 2;

	private const int CanopyCapContractVersion = 1;

	private const int ForestMeshCacheSignatureVersion = 1;

	private const int CompletionSchedulerVersion = 1;

	private const int TerrainColourSignatureVersion = 1;

	private const int DiagnosticAlgorithmVersion = 4;

	private const int GroundingDiagnosticVersion = 1;

	private const float GoldenBlackForestSupportHeightMultiplier = 1.55f;

	private const float GoldenBlackForestSupportWidthMultiplier = 2f;

	private const float GoldenBlackForestSupportMinimumRatio = 0.42f;

	private const float GoldenBlackForestSupportMaximumRatio = 0.72f;

	private const float GoldenBlackForestSupportMaximumWidth = 18f;

	private const float GoldenMountainSupportHeightMultiplier = 1.35f;

	private const float GoldenMountainSupportWidthMultiplier = 1.2f;

	private const float GoldenMountainSupportMinimumRandomScale = 0.9f;

	private const float GoldenMountainSupportMaximumRandomScale = 1.3f;

	private const float GoldenMountainSupportMinimumRatio = 0.45f;

	private const float GoldenMountainSupportMaximumRatio = 0.78f;

	private const float GoldenMountainSupportMaximumQuadWidth = 22f;

	private const int MaximumDetailedCardsPerRendererChunk = 600;

	private const int MaximumSinglePlaneCardsPerRendererChunk = 900;

	private const int MaximumVerticesPerRendererChunk = 24000;

	private const int Safe16BitTriangleLimit = 20000;

	private const float CoverageRepairChunkSize = 64f;

	private const float DefaultMeadowsContinuousCoverage = 1f;

	private const float DefaultBlackForestContinuousCoverage = 1f;

	private const float DefaultSwampContinuousCoverage = 0.9f;

	private const float DefaultMountainContinuousCoverage = 0.9f;

	private const float DefaultPlainsContinuousCoverage = 0.2f;

	private const string DefaultProfileDir = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Valheim_Modded_BACKUP\\DonegalValheimYourThirsty\\Valheim\\profiles\\DonegalHorizons";

	private const int PresetMaximumTerrainTileCeiling = 800;

	private const int PresetMaximumForestTileCeiling = 2800;

	private static readonly PresetRuntimeProfile VeryLowRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.VeryLow, "VeryLow", 500f, useWorldMaximum: false, 220, 50000, 35000, 700, 2, 2);

	private static readonly PresetRuntimeProfile LowRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.Low, "Low", 1000f, useWorldMaximum: false, 320, 70000, 50000, 950, 2, 2);

	private static readonly PresetRuntimeProfile BalancedRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.Balanced, "Balanced", 2000f, useWorldMaximum: false, 500, 100000, 75000, 1400, 3, 3);

	private static readonly PresetRuntimeProfile MediumRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.Medium, "Medium", 4000f, useWorldMaximum: false, 800, 140000, 105000, 2100, 4, 3);

	private static readonly PresetRuntimeProfile HighRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.High, "High", 7000f, useWorldMaximum: false, 1400, 190000, 145000, 3000, 5, 4);

	private static readonly PresetRuntimeProfile UltraRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.Ultra, "Ultra", 10000f, useWorldMaximum: false, 2600, 260000, 195000, 4000, 6, 5);

	private static readonly PresetRuntimeProfile HorizonRuntimeProfile = CreatePresetRuntimeProfile(QualityPreset.Horizon, "Horizon", 0f, useWorldMaximum: true, 2800, 340000, 255000, 5000, 7, 6);

	private static readonly TreeCardDensityProfile GoldenHighDensityProfile = new TreeCardDensityProfile
	{
		Preset = TreeCardDensityPreset.High,
		ClusterCellSize = 18f,
		DensityThreshold = 0f,
		DensityMultiplier = 13.036f,
		CandidateTotal = 900,
		CandidateStep = 48,
		MaximumClusters = 6799,
		MaximumTreePlanes = 10945,
		MeadowsCoverage = 1f,
		BlackForestCoverage = 1f,
		NearRetention = 1f,
		MidRetention = 1f,
		FarRetention = 0.85f,
		HorizonRetention = 0.7f,
		HandoffGap = 18f,
		NearGap = 22f,
		MidGap = 30f,
		FarGap = 42f,
		HorizonGap = 60f,
		GlobalDistributedDensity = 1.65f,
		BlackForestDistributedDensity = 2f,
		MeadowsDistributedDensity = 1.3f,
		MountainDistributedDensity = 1.15f,
		PlainsDistributedDensity = 0.25f,
		HardRejectSlope = 52.366f
	};

	private ConfigEntry<bool> _enabled;

	private ConfigEntry<bool> _waitForGameplayWorld;

	private ConfigEntry<bool> _requireWaterSystemForProceduralWorld;

	private ConfigEntry<WorldDataMode> _worldDataMode;

	private ConfigEntry<float> _proceduralWorldRadius;

	private ConfigEntry<string> _mapFolder;

	private ConfigEntry<string> _betterContinentsConfigFile;

	private ConfigEntry<string> _renderLimitsConfigFile;

	private ConfigEntry<string> _heightMapFile;

	private ConfigEntry<string> _colourMapFile;

	private ConfigEntry<string> _forestMapFile;

	private ConfigEntry<string> _treeAtlasFile;

	private ConfigEntry<string> _canopyAtlasFile;

	private ConfigEntry<string> _mountainBiomeAtlasFile;

	private ConfigEntry<string> _swampBiomeAtlasFile;

	private ConfigEntry<bool> _requireRenderLimits;

	private ConfigEntry<bool> _allowManualEnvelopeWithoutRenderLimits;

	private ConfigEntry<float> _manualNearWorldExclusionRadius;

	private ConfigEntry<float> _minimumNearWorldExclusionRadius;

	private ConfigEntry<float> _nativeEnvelopePadding;

	private ConfigEntry<QualityPreset> _qualityPreset;

	private ConfigEntry<bool> _autoDetectNativeTreeViewDistance;

	private ConfigEntry<float> _nativeTreeViewDistanceFallback;

	private ConfigEntry<NativeTreelineMode> _nativeTreelineMode;

	private ConfigEntry<float> _nativeTreelineCalibratedRadius;

	private ConfigEntry<float> _nativeTreelineSeamOverlap;

	private ConfigEntry<bool> _enforceStrictCalibratedTreeline;

	private ConfigEntry<float> _nativeTreelineSeamFadeWidth;

	private ConfigEntry<float> _nativeTreelineSeamTolerance;

	private ConfigEntry<float> _nativeTreelineHandoffOffset;

	private ConfigEntry<float> _nativeTreelineBoundaryChunkSize;

	private ConfigEntry<float> _normalForestChunkSize;

	private ConfigEntry<float> _canopyHandoffOffset;

	private ConfigEntry<bool> _enableHandoffFill;

	private ConfigEntry<float> _handoffFillBandWidth;

	private ConfigEntry<float> _handoffFillMinimumCoverage;

	private ConfigEntry<float> _handoffFillCandidateSpacing;

	private ConfigEntry<float> _handoffFillMaximumGap;

	private ConfigEntry<bool> _handoffFillUsesBiomeDensity;

	private ConfigEntry<bool> _handoffFillRequiresValidForestLand;

	private ConfigEntry<bool> _enableContinuousForestCoverage;

	private ConfigEntry<float> _continuousMeadowsCoverage;

	private ConfigEntry<float> _continuousBlackForestCoverage;

	private ConfigEntry<float> _continuousSwampCoverage;

	private ConfigEntry<float> _continuousMountainCoverage;

	private ConfigEntry<float> _continuousPlainsCoverage;

	private ConfigEntry<float> _continuousMistlandsCoverage;

	private ConfigEntry<float> _continuousAshlandsCoverage;

	private ConfigEntry<float> _continuousDeepNorthCoverage;

	private ConfigEntry<float> _continuousNearGridRetention;

	private ConfigEntry<float> _continuousMidGridRetention;

	private ConfigEntry<float> _continuousFarGridRetention;

	private ConfigEntry<float> _continuousHorizonGridRetention;

	private ConfigEntry<float> _coverageHandoffMaximumGap;

	private ConfigEntry<float> _coverageNearMaximumGap;

	private ConfigEntry<float> _coverageMidMaximumGap;

	private ConfigEntry<float> _coverageFarMaximumGap;

	private ConfigEntry<float> _coverageHorizonMaximumGap;

	private ConfigEntry<float> _coverageRepairRecoveryRadius;

	private ConfigEntry<int> _coverageRepairMaxRetries;

	private ConfigEntry<int> _coverageRepairJobsPerFrame;

	private ConfigEntry<int> _coverageCellsPerResumableStep;

	private ConfigEntry<int> _maximumActiveCoverageAuditJobs;

	private ConfigEntry<int> _maximumCoverageRepairJobsAdmittedPerFrame;

	private ConfigEntry<int> _maximumCoverageRepairCardsCommittedPerFrame;

	private ConfigEntry<float> _maximumCoverageSectorStarvationSeconds;

	private ConfigEntry<float> _coastalDryLandSearchRadius;

	private ConfigEntry<int> _coastalSearchMaximumAttempts;

	private ConfigEntry<int> _coastalSearchAttemptsPerResumableStep;

	private ConfigEntry<int> _coastalSearchAngularSamples;

	private ConfigEntry<bool> _enableCoastalLandRecovery;

	private ConfigEntry<float> _coastalLandRecoveryRadius;

	private ConfigEntry<int> _coastalLandRecoveryAttempts;

	private ConfigEntry<int> _blackForestNearMinimumSubclusters;

	private ConfigEntry<int> _meadowsNearMinimumSubclusters;

	private ConfigEntry<bool> _allowDetailedTreeFoliageOverhangAtCoast;

	private ConfigEntry<float> _coastalDetailedTreeWaterSafetyWidth;

	private ConfigEntry<float> _coastalDetailedTreeNearWaterRejectRadius;

	private ConfigEntry<float> _coastalDetailedTreeMinimumAboveWater;

	private ConfigEntry<TreeCardDensityPreset> _treeCardDensityPreset;

	private ConfigEntry<bool> _preserveExistingManualTreeCardValues;

	private ConfigEntry<bool> _autoMatchTreeDensityToQualityPreset;

	private ConfigEntry<float> _globalDistributedTreeDensity;

	private ConfigEntry<float> _blackForestDistributedDensity;

	private ConfigEntry<float> _meadowsDistributedDensity;

	private ConfigEntry<float> _swampDistributedDensity;

	private ConfigEntry<float> _mountainDistributedDensity;

	private ConfigEntry<float> _plainsDistributedDensity;

	private ConfigEntry<float> _newHorizonsExtensionDistance;

	private ConfigEntry<bool> _forestContinuityEnabled;

	private ConfigEntry<bool> _enableFarTerrain;

	private ConfigEntry<float> _continuityStartDistance;

	private ConfigEntry<bool> _decoupleForestStartFromTerrainExclusion;

	private ConfigEntry<float> _minimumForestStartDistance;

	private ConfigEntry<float> _forestExclusionMarginScale;

	private ConfigEntry<float> _continuityEndDistance;

	private ConfigEntry<float> _treeCardEndDistance;

	private ConfigEntry<float> _canopyStartDistance;

	private ConfigEntry<float> _continuityTileSize;

	private ConfigEntry<float> _continuityRebuildDistance;

	private ConfigEntry<float> _nearCullHysteresis;

	private ConfigEntry<float> _clusterCellSize;

	private ConfigEntry<float> _forestDensityThreshold;

	private ConfigEntry<float> _forestDensityMultiplier;

	private ConfigEntry<float> _slopeRejectionThreshold;

	private ConfigEntry<float> _hardSlopeRejectionThreshold;

	private ConfigEntry<int> _maximumClustersPerTile;

	private ConfigEntry<int> _maxTreeCardPlanesPerTile;

	private ConfigEntry<int> _maxCanopyPlanesPerTile;

	private ConfigEntry<float> _slopeSampleRadius;

	private ConfigEntry<float> _innerTerrainDistance;

	private ConfigEntry<float> _farTerrainViewDistance;

	private ConfigEntry<float> _farTerrainTileSize;

	private ConfigEntry<int> _farTerrainMeshResolution;

	private ConfigEntry<float> _farForestStartDistance;

	private ConfigEntry<float> _farForestEndDistance;

	private ConfigEntry<float> _forestTerrainTintStrength;

	private ConfigEntry<string> _forestTerrainTintColour;

	private ConfigEntry<bool> _useBetterContinentsExactSampler;

	private ConfigEntry<float> _verticalOffset;

	private ConfigEntry<bool> _extendMainCameraFarClip;

	private ConfigEntry<float> _mainCameraFarClip;

	private ConfigEntry<int> _tilesBuiltPerFrame;

	private ConfigEntry<bool> _cullBehindCamera;

	private ConfigEntry<float> _behindCameraDot;

	private ConfigEntry<int> _maxTerrainTiles;

	private ConfigEntry<int> _maxForestTiles;

	private ConfigEntry<int> _panicTileCeiling;

	private ConfigEntry<int> _globalTreeCardPlaneBudget;

	private ConfigEntry<int> _globalCanopyPlaneBudget;

	private ConfigEntry<bool> _enableRingBudgetReservation;

	private ConfigEntry<float> _handoffMinimumTreeBudgetShare;

	private ConfigEntry<float> _nearMinimumTreeBudgetShare;

	private ConfigEntry<float> _midMinimumTreeBudgetShare;

	private ConfigEntry<float> _farMinimumTreeBudgetShare;

	private ConfigEntry<float> _horizonMinimumTreeBudgetShare;

	private ConfigEntry<float> _handoffMinimumCanopyBudgetShare;

	private ConfigEntry<float> _nearMinimumCanopyBudgetShare;

	private ConfigEntry<float> _midMinimumCanopyBudgetShare;

	private ConfigEntry<float> _farMinimumCanopyBudgetShare;

	private ConfigEntry<float> _horizonMinimumCanopyBudgetShare;

	private ConfigEntry<bool> _allowUnusedRingBudgetRedistribution;

	private ConfigEntry<float> _nearHandoffMinimumAlpha;

	private ConfigEntry<float> _midDistanceMinimumAlpha;

	private ConfigEntry<float> _farDistanceMinimumAlpha;

	private ConfigEntry<float> _horizonMinimumAlpha;

	private ConfigEntry<bool> _enableIncrementalForestStreaming;

	private ConfigEntry<float> _forestGenerationTimeBudgetMs;

	private ConfigEntry<int> _maxMeshUploadsPerFrame;

	private ConfigEntry<int> _maxChunkActivationsPerFrame;

	private ConfigEntry<float> _pauseGenerationAboveFrameTimeMs;

	private ConfigEntry<float> _slowFrameGenerationBudgetMs;

	private ConfigEntry<float> _streamingRecalculateDistance;

	private ConfigEntry<float> _sliderRebuildDebounceSeconds;

	private ConfigEntry<float> _forestRetirementTimeBudgetMs;

	private ConfigEntry<int> _maxChunkDestructionsPerFrame;

	private ConfigEntry<int> _maxForestJobRetries;

	private ConfigEntry<int> _maximumCandidateCellsPerTileBuild;

	private ConfigEntry<int> _candidateEvaluationsPerResumableStep;

	private ConfigEntry<bool> _enableAdaptiveForestGenerationBudget;

	private ConfigEntry<float> _normalForestGenerationCpuBudgetMs;

	private ConfigEntry<float> _stationaryForestGenerationCpuBudgetMs;

	private ConfigEntry<float> _movementPressureForestGenerationCpuBudgetMs;

	private ConfigEntry<float> _startupForestGenerationCpuBudgetMs;

	private ConfigEntry<float> _generationTargetFrameTimeMs;

	private ConfigEntry<float> _generationBudgetRecoveryDelaySeconds;

	private ConfigEntry<int> _terrainGroundSamplesPerResumableStep;

	private ConfigEntry<int> _footprintValidationsPerResumableStep;

	private ConfigEntry<int> _slopeValidationsPerResumableStep;

	private ConfigEntry<int> _cardsAppendedToMeshPerResumableStep;

	private ConfigEntry<int> _maximumSimultaneousMeshAssemblyJobs;

	private ConfigEntry<int> _maximumCompletedForestTileCommitsPerFrame;

	private ConfigEntry<float> _repairChunkRebuildCoalescingSeconds;

	private ConfigEntry<int> _maximumAdmittedForestGenerationJobs;

	private ConfigEntry<int> _hardCandidateEvaluationCeiling;

	private ConfigEntry<int> _maximumForestTileBuildsPerFrameSafetyCap;

	private ConfigEntry<bool> _enableStartupHitchGuard;

	private ConfigEntry<float> _startupInitialDelaySeconds;

	private ConfigEntry<float> _startupSafeModeSeconds;

	private ConfigEntry<int> _startupForestBuildIntervalFrames;

	private ConfigEntry<int> _startupTerrainBuildIntervalFrames;

	private ConfigEntry<bool> _runExpensiveDeterministicStartupSelfTest;

	private ConfigEntry<float> _coverageRepairTimeBudgetMs;

	private ConfigEntry<int> _coverageRepairHardJobsPerFrame;

	private ConfigEntry<int> _minimumActiveChunksBeforeCoverageRepair;

	private ConfigEntry<float> _minimumMovementSyncIntervalSeconds;

	private ConfigEntry<float> _fastMovementRebuildDistance;

	private ConfigEntry<float> _maximumMovementSyncsPerSecond;

	private ConfigEntry<bool> _enableForestObjectPooling;

	private ConfigEntry<int> _maxPooledForestChunks;

	private ConfigEntry<int> _maxPooledMeshes;

	private ConfigEntry<bool> _clearPoolsOnWorldChange;

	private ConfigEntry<bool> _enableForestMemoryCache;

	private ConfigEntry<float> _forestMemoryCacheLimitMb;

	private ConfigEntry<int> _maxCachedForestChunks;

	private ConfigEntry<float> _cacheRetentionDistance;

	private ConfigEntry<float> _forestPreloadDistance;

	private ConfigEntry<float> _forestChunkRetentionDistance;

	private ConfigEntry<bool> _forestFarChunkMergeEnabled;

	private ConfigEntry<float> _midForestChunkSize;

	private ConfigEntry<float> _forestFarChunkSize;

	private ConfigEntry<float> _forestFarChunkMergeStart;

	private ConfigEntry<bool> _forestVeryFarChunkMergeEnabled;

	private ConfigEntry<float> _forestVeryFarChunkSize;

	private ConfigEntry<float> _forestVeryFarChunkMergeStart;

	private ConfigEntry<float> _minimumTreeMaterialUpdateIntervalSeconds;

	private ConfigEntry<float> _minimumBrightnessChangeBeforeUpdate;

	private ConfigEntry<float> _visibilityUpdateIntervalSeconds;

	private ConfigEntry<bool> _enableFarSinglePlaneLod;

	private ConfigEntry<float> _farSinglePlaneLodStartDistance;

	private ConfigEntry<float> _horizonSinglePlaneLodStartDistance;

	private ConfigEntry<bool> _enableViewFacingForestOverloadGuard;

	private ConfigEntry<int> _visibleDetailedTriangleSoftLimit;

	private ConfigEntry<int> _visibleDetailedTriangleHardLimit;

	private ConfigEntry<int> _visibleTreeRendererSoftLimit;

	private ConfigEntry<int> _visibleTreeRendererHardLimit;

	private ConfigEntry<bool> _enableAdaptiveHighPresetGovernor;

	private ConfigEntry<float> _adaptiveTargetFrameTimeMs;

	private ConfigEntry<float> _adaptiveSoftFrameTimeMs;

	private ConfigEntry<float> _adaptiveHardFrameTimeMs;

	private ConfigEntry<int> _adaptiveFrameSmoothingSamples;

	private ConfigEntry<float> _adaptiveRecoveryDelaySeconds;

	private ConfigEntry<float> _adaptiveRecoveryRatePerSecond;

	private ConfigEntry<float> _adaptiveMinimumGenerationBudgetMs;

	private ConfigEntry<int> _adaptiveMinimumMeshUploadsPerFrame;

	private ConfigEntry<int> _adaptiveMinimumChunkActivationsPerFrame;

	private ConfigEntry<float> _adaptiveHardSpikeCooldownSeconds;

	private ConfigEntry<float> _adaptiveMaximumBuildOverrunCooldownSeconds;

	private ConfigEntry<float> _adaptiveReinforcementDeferPressure;

	private ConfigEntry<float> _bootstrapPrimaryGenerationBudgetMs;

	private ConfigEntry<int> _minimumPrimaryProgressStepsPerFrame;

	private ConfigEntry<float> _maximumPrimaryStarvationSeconds;

	private ConfigEntry<float> _maximumReinforcementStarvationSeconds;

	private ConfigEntry<int> _minimumReinforcementProgressStepsAfterStarvation;

	private ConfigEntry<float> _maximumCoverageStarvationSeconds;

	private ConfigEntry<int> _minimumCoverageProgressStepsAfterStarvation;

	private ConfigEntry<float> _maximumDesiredTileStarvationSeconds;

	private ConfigEntry<int> _bootstrapMeshUploadsPerFrame;

	private ConfigEntry<bool> _enablePredictiveStreamingPriority;

	private ConfigEntry<float> _predictiveMovementPriorityStrength;

	private ConfigEntry<float> _predictiveCameraPriorityStrength;

	private ConfigEntry<int> _adaptiveTerrainBuildIntervalFrames;

	private ConfigEntry<float> _terrainSlopeShadingStrength;

	private ConfigEntry<float> _terrainDistanceTintStrength;

	private ConfigEntry<bool> _enableHorizonClarity;

	private ConfigEntry<bool> _reduceHorizonHaze;

	private ConfigEntry<float> _horizonHazeStrength;

	private ConfigEntry<float> _terrainDistanceFadeStrength;

	private ConfigEntry<float> _forestDistanceFadeStrength;

	private ConfigEntry<float> _farTerrainContrast;

	private ConfigEntry<float> _farForestContrast;

	private ConfigEntry<float> _farForestDarkness;

	private ConfigEntry<float> _farTerrainDarkness;

	private ConfigEntry<float> _farTreeAlpha;

	private ConfigEntry<float> _farCanopyAlpha;

	private ConfigEntry<bool> _preserveWeatherFog;

	private ConfigEntry<float> _weatherFogInfluence;

	private ConfigEntry<float> _clearWeatherVisibilityBoost;

	private ConfigEntry<float> _mistWeatherVisibilityBoost;

	private ConfigEntry<float> _stormWeatherVisibilityBoost;

	private string _lastClarityWeather = "";

	private ConfigEntry<HazeControlMode> _hazeControlMode;

	private ConfigEntry<float> _clearWeatherHazeMultiplier;

	private ConfigEntry<float> _lightCloudHazeMultiplier;

	private ConfigEntry<float> _maximumHazeReduction;

	private ConfigEntry<float> _hazeBlendSpeed;

	private ConfigEntry<bool> _enableRealClearSkies;

	private ConfigEntry<float> _clearSkiesStrength;

	private ConfigEntry<ClearSkiesOperatingMode> _clearSkiesOperatingMode;

	private ConfigEntry<bool> _allowOccasionalCrystalClearWeather;

	private ConfigEntry<float> _crystalClearChancePerClearDay;

	private ConfigEntry<float> _crystalClearMinimumDurationMinutes;

	private ConfigEntry<float> _crystalClearMaximumDurationMinutes;

	private ConfigEntry<float> _crystalClearFogMultiplier;

	private ConfigEntry<float> _crystalClearHorizonHazeMultiplier;

	private ConfigEntry<float> _crystalClearCloudOpacityMultiplier;

	private ConfigEntry<float> _crystalClearDistanceTintMultiplier;

	private ConfigEntry<float> _clearWeatherFogMultiplier;

	private ConfigEntry<float> _clearWeatherHorizonHazeMultiplier;

	private ConfigEntry<float> _clearWeatherCloudOpacityMultiplier;

	private ConfigEntry<float> _clearWeatherDistanceTintMultiplier;

	private ConfigEntry<float> _clearSkiesTransitionSeconds;

	private ConfigEntry<bool> _preserveStormWeather;

	private ConfigEntry<bool> _preserveRainAndSnow;

	private ConfigEntry<bool> _preserveMistlandsMist;

	private ConfigEntry<bool> _preserveAshlandsAtmosphere;

	private ConfigEntry<bool> _preserveDeepNorthAtmosphere;

	private ConfigEntry<bool> _preserveBossWeather;

	private ConfigEntry<bool> _restoreOriginalWeatherValuesOnDisable;

	private bool _crystalClearEventActive;

	private float _crystalClearEventEndRealtime = -1f;

	private int _crystalClearScheduledForDay = int.MinValue;

	private float _crystalClearEventRemainingSecondsForDiagnostics;

	private ConfigEntry<WaterSurfaceMode> _waterSurfaceMode;

	private ConfigEntry<float> _waterSurfaceHeightOverride;

	private ConfigEntry<float> _waterClearance;

	private ConfigEntry<float> _shoreSampleRadius;

	private ConfigEntry<KeyCode> _reloadKey;

	private ConfigEntry<KeyCode> _alternateReloadKey;

	private ConfigEntry<bool> _enableCalibrationMode;

	private ConfigEntry<KeyCode> _calibrationToggleKey;

	private ConfigEntry<KeyCode> _calibrationIncrease1mKey;

	private ConfigEntry<KeyCode> _calibrationDecrease1mKey;

	private ConfigEntry<KeyCode> _calibrationIncrease5mKey;

	private ConfigEntry<KeyCode> _calibrationDecrease5mKey;

	private ConfigEntry<KeyCode> _calibrationIncrease25mKey;

	private ConfigEntry<KeyCode> _calibrationDecrease25mKey;

	private ConfigEntry<KeyCode> _calibrationSaveKey;

	private ConfigEntry<KeyCode> _calibrationResetKey;

	private ConfigEntry<KeyCode> _calibrationRecordSampleKey;

	private ConfigEntry<KeyCode> _calibrationClearSamplesKey;

	private ConfigEntry<float> _calibrationGuideLineWidth;

	private ConfigEntry<float> _calibrationGuideHeightOffset;

	private ConfigEntry<int> _calibrationGuidePointCountConfig;

	private ConfigEntry<bool> _showCalibrationVerticalMarkers;

	private ConfigEntry<float> _calibrationMarkerHeight;

	private ConfigEntry<bool> _calibrationGuideAlwaysVisible;

	private ConfigEntry<bool> _showCalibrationTestGuide;

	private ConfigEntry<float> _calibrationTestGuideRadius;

	private ConfigEntry<bool> _enableProxyForestMasses;

	private ConfigEntry<bool> _enableProxyMassesInSwamp;

	private ConfigEntry<float> _swampTreeCardStartDistance;

	private ConfigEntry<float> _swampTreeCardEndDistance;

	private ConfigEntry<float> _swampNearCardDensityMultiplier;

	private ConfigEntry<float> _swampMidCardDensityMultiplier;

	private long _closeSwampRejectedWater;

	private long _closeSwampRejectedRoot;

	private long _closeSwampEmitted;

	private Biome _lastValidationBiome;

	private long _swampNoFloatAttempts;

	private long _swampPassedDensity;

	private long _swampRejectedThreshold;

	private long _swampRejectedSlope;

	private long _swampRejectedWater;

	private long _swampRejectedVisibleLandRatio;

	private long _swampRejectedCoastline;

	private long _swampRejectedSupport;

	private long _swampRejectedRootAnchor;

	private long _swampRejectedRootDryRatio;

	private long _swampRejectedWaterChannel;

	private long _swampRejectedFinalFloating;

	private int _swampChunksBuilt;

	private int _swampRenderersCreated;

	private int _swampRenderersEnabled;

	private int _swampInnerCulled;

	private int _swampOuterCulled;

	private bool _staticPlacementOk = true;

	private int _debugPageIndex;

	private float _lastRebuildStartTime;

	private float _lastRebuildDurationSeconds;

	private bool _rebuildTimingPending;

	private long _proxyAttempts;

	private long _proxyAttemptsBlockedDisabled;

	private long _proxyAttemptsBlockedSwamp;

	private long _treeSampleRetriesUsed;

	private GroundRejectReason _lastNoFloatRejectReason;

	private ConfigEntry<bool> _enableHardcodedReloadFallbacks;

	private ConfigEntry<KeyCode> _debugKey;

	private ConfigEntry<bool> _showDebug;

	private ConfigEntry<bool> _forestProofDiagnostic;

	private ConfigEntry<bool> _debugDrawCardBases;

	private ConfigEntry<bool> _groundAuthoritativePlacement;

	private ConfigEntry<bool> _requireExactFootprintTerrainSupport;

	private ConfigEntry<bool> _rejectAnyFootprintSampleWater;

	private ConfigEntry<bool> _rejectAnyFootprintSampleUnsupported;

	private ConfigEntry<float> _maxFootprintHeightDifference;

	private ConfigEntry<float> _defaultMinimumLandAboveWater;

	private ConfigEntry<float> _plainsMinimumLandAboveWater;

	private ConfigEntry<float> _coastalMinimumLandAboveWater;

	private ConfigEntry<float> _swampMinimumLandAboveWater;

	private ConfigEntry<float> _nonSwampNearWaterRejectRadius;

	private ConfigEntry<float> _swampNearWaterRejectRadius;

	private ConfigEntry<float> _swampMaxCanopyCardWidth;

	private ConfigEntry<float> _swampMaxProxyCardWidth;

	private ConfigEntry<bool> _requireFinalSwampPositionRemainsSwamp;

	private ConfigEntry<float> _maxSwampInlandRetryDistance;

	private ConfigEntry<bool> _rejectSwampCardIfNoValidGround;

	private ConfigEntry<float> _swampFinalRootEmbedDepth;

	private ConfigEntry<float> _swampMaxFinalFloatingClearance;

	private ConfigEntry<bool> _debugSwampCardTypeColours;

	private ConfigEntry<bool> _enableCrossBiomeDuplicateRejection;

	private ConfigEntry<float> _duplicateHorizontalDistanceTolerance;

	private ConfigEntry<float> _duplicateBaseHeightDifferenceWarning;

	private ConfigEntry<float> _duplicateFootprintOverlapThreshold;

	private ConfigEntry<float> _maxFinalGroundFloatingError;

	private ConfigEntry<float> _maxFinalGroundBurialError;

	private ConfigEntry<float> _maxGroundHeightVarianceStandardCard;

	private ConfigEntry<float> _maxGroundHeightVarianceLargeCard;

	private ConfigEntry<bool> _enableStrictFinalHeightmapValidation;

	private ConfigEntry<float> _finalRootEmbedDepth;

	private ConfigEntry<float> _minimumRootSupportRatio;

	private ConfigEntry<float> _minimumFootprintSupportRatio;

	private ConfigEntry<float> _maximumUnsupportedSpan;

	private ConfigEntry<float> _maximumStandardGroundCardWidth;

	private ConfigEntry<float> _maximumSwampGroundCardWidth;

	private ConfigEntry<float> _maximumPlainsGroundCardWidth;

	private ConfigEntry<float> _treeCardVerticalAdjustment;

	private ConfigEntry<float> _mixedVerticalAdjustment;

	private ConfigEntry<float> _blackForestVerticalAdjustment;

	private ConfigEntry<float> _swampVerticalAdjustmentFinal;

	private ConfigEntry<float> _mountainVerticalAdjustmentFinal;

	private ConfigEntry<float> _plainsVerticalAdjustmentFinal;

	private ConfigEntry<float> _maximumProxyGroundMassWidth;

	private ConfigEntry<bool> _rejectGroundCardsOverOpenWater;

	private ConfigEntry<bool> _splitLargeCardsOnUnevenTerrain;

	private ConfigEntry<float> _meadowsDistantTreeDensity;

	private ConfigEntry<float> _blackForestDistantTreeDensity;

	private ConfigEntry<float> _swampDistantTreeDensity;

	private ConfigEntry<float> _mountainDistantTreeDensity;

	private ConfigEntry<float> _plainsDistantTreeDensity;

	private ConfigEntry<float> _mistlandsDistantTreeDensity;

	private ConfigEntry<float> _ashlandsDistantTreeDensity;

	private ConfigEntry<float> _deepNorthDistantTreeDensity;

	private ConfigEntry<float> _meadowsDistantCanopyDensity;

	private ConfigEntry<float> _blackForestDistantCanopyDensity;

	private ConfigEntry<float> _swampDistantCanopyDensity;

	private ConfigEntry<float> _mountainDistantCanopyDensity;

	private ConfigEntry<float> _plainsDistantCanopyDensity;

	private ConfigEntry<float> _mistlandsDistantCanopyDensity;

	private ConfigEntry<float> _daylightTreeBrightness;

	private ConfigEntry<float> _sunsetTreeBrightness;

	private ConfigEntry<float> _nightTreeBrightness;

	private ConfigEntry<float> _overcastTreeBrightness;

	private ConfigEntry<float> _stormTreeBrightness;

	private ConfigEntry<float> _minimumTreeLuminance;

	private ConfigEntry<bool> _naturalDaylightDarkening;

	private ConfigEntry<float> _biomeColourPreservation;

	private ConfigEntry<float> _weatherColourInfluence;

	private ConfigEntry<float> _lateAfternoonTreeBrightness;

	private ConfigEntry<float> _twilightTreeBrightness;

	private ConfigEntry<float> _moonlitNightTreeBrightness;

	private ConfigEntry<float> _lightingTransitionSeconds;

	private ConfigEntry<float> _midDistanceOriginalColourStrength;

	private ConfigEntry<float> _farDistanceOriginalColourStrength;

	private ConfigEntry<float> _farDistanceAtmosphericInfluence;

	private float _lastAmbientLuminanceForDiagnostics;

	private float _lastSunElevationForDiagnostics;

	private float _lastDaylightFactorForDiagnostics;

	private float _lastTreeBrightnessForDiagnostics = 1f;

	private float _smoothedTreeBrightness = 1f;

	private float _lastAppliedTreeBrightness = -1f;

	private bool _treeLightingBlendInitialized;

	private float _lastTreeLightingApplyRealtime = -1f;

	private ConfigEntry<bool> _preserveOriginalColourNearHandoff;

	private ConfigEntry<float> _nearHandoffColourBandWidth;

	private ConfigEntry<float> _nearHandoffDaylightOriginalColourStrength;

	private ConfigEntry<float> _nearHandoffWeatherColourInfluence;

	private ConfigEntry<float> _nearHandoffFogColourInfluence;

	private ConfigEntry<float> _nearHandoffMinimumDaylightBrightness;

	private ConfigEntry<float> _nearHandoffMaximumDaylightBrightness;

	private ConfigEntry<bool> _useNeutralAtlasNormals;

	private MaterialPropertyBlock _treeRendererPropertyBlock;

	private readonly Dictionary<int, TreeRendererPropertyState> _treeRendererPropertyStates = new Dictionary<int, TreeRendererPropertyState>();

	private long _treeMaterialUpdatePasses;

	private long _treeMaterialUpdatesSkippedByInterval;

	private long _treeMaterialUpdatesSkippedByBrightness;

	private long _treePropertyBlockWrites;

	private bool _treeRendererPropertiesDirty = true;

	private int _nearHandoffChunksTinted;

	private float _lastNearHandoffBrightnessForDiagnostics = 1f;

	private ConfigEntry<bool> _enableTrueColourDistantLand;

	private ConfigEntry<float> _clearWeatherOriginalTerrainColourStrength;

	private ConfigEntry<float> _clearWeatherAtmosphericColourStrength;

	private ConfigEntry<float> _clearWeatherMaximumTerrainDarkening;

	private ConfigEntry<float> _clearWeatherDistantSaturationStrength;

	private ConfigEntry<float> _radialTerrainColourTransitionWidth;

	private ConfigEntry<float> _trueColourBlendSeconds;

	private ConfigEntry<bool> _useFullResolutionProviderTerrainColour;

	private ConfigEntry<bool> _useUntintedProviderTerrainColourMap;

	private ConfigEntry<int> _fallbackTerrainColourTextureResolution;

	private ConfigEntry<bool> _preserveNativeTerrainLodSystemTrueColour;

	private ConfigEntry<bool> _preserveStormTerrainAtmosphere;

	private ConfigEntry<bool> _preserveNightTerrainDarkness;

	private ConfigEntry<bool> _preserveSunriseAndSunsetColourTrueColour;

	private ConfigEntry<bool> _preserveSpecialBiomeAtmosphereTerrain;

	private ConfigEntry<TrueColourDiagnosticTarget> _trueColourDiagnosticTarget;

	private ConfigEntry<bool> _enableSwampTreeCards;

	private ConfigEntry<float> _swampTreeDensityMultiplier;

	private ConfigEntry<float> _swampFootprintRadiusScale;

	private ConfigEntry<float> _swampMaxFootprintHeightDiff;

	private ConfigEntry<bool> _swampAllowShallowWetGround;

	private ConfigEntry<float> _swampMaxShallowWaterDepth;

	private ConfigEntry<float> _minimumSwampBiomeFootprintRatio;

	private ConfigEntry<float> _minimumSwampRootSupportRatio;

	private ConfigEntry<float> _minimumSwampFootprintSupportRatio;

	private ConfigEntry<float> _swampSinkIntoGround;

	private ConfigEntry<float> _swampTreeHeightMultiplier;

	private ConfigEntry<float> _swampTreeWidthMultiplier;

	private ConfigEntry<bool> _enableMountainTreeCards;

	private ConfigEntry<float> _mountainTreeDensityMultiplier;

	private ConfigEntry<float> _mountainMaximumSlope;

	private ConfigEntry<float> _mountainMinimumHeight;

	private ConfigEntry<float> _mountainFootprintRadiusScale;

	private ConfigEntry<float> _mountainMaxFootprintHeightDiff;

	private ConfigEntry<float> _mountainSinkIntoGround;

	private ConfigEntry<float> _mountainTreeHeightMultiplier;

	private ConfigEntry<float> _mountainTreeWidthMultiplier;

	private ConfigEntry<float> _mountainMinimumRandomScale;

	private ConfigEntry<float> _mountainMaximumRandomScale;

	private ConfigEntry<float> _mountainMinimumWidthToHeightRatio;

	private ConfigEntry<float> _mountainMaximumWidthToHeightRatio;

	private ConfigEntry<float> _mountainMinimumAutomaticWidthScale;

	private ConfigEntry<float> _maximumMountainGroundCardWidth;

	private ConfigEntry<float> _blackForestTreeHeightMultiplier;

	private ConfigEntry<float> _bla