Decompiled source of PlantBiomeHeeler v1.0.0

PlantBiomeHeeler.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using PlantBiomeHeeler.Configuration;
using PlantBiomeHeeler.Core.Input;
using PlantBiomeHeeler.Core.State;
using PlantBiomeHeeler.Core.UI;
using PlantBiomeHeeler.Core.Visuals;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DreamWraith (https://github.com/dreamwraith)")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 DreamWraith")]
[assembly: AssemblyDescription("Shows where plants can grow: a terrain overlay of the biome plants actually use, with a HUD readout of the target and standing biome.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+84b89c736dbe16b5041b674c084793d52765dd8c")]
[assembly: AssemblyProduct("PlantBiomeHeeler")]
[assembly: AssemblyTitle("PlantBiomeHeeler")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dreamwraith/Valheim-PlantBiomeHeeler")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PlantBiomeHeeler
{
	[BepInPlugin("dreamwraith.PlantBiomeHeeler", "PlantBiomeHeeler", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "dreamwraith.PlantBiomeHeeler";

		public const string ModName = "PlantBiomeHeeler";

		public const string ModVersion = "1.0.0";

		private Harmony? _harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Initialize(((BaseUnityPlugin)this).Config);
			new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
			if (!GUIManager.IsHeadless())
			{
				ModInputManager.Initialize();
				_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "dreamwraith.PlantBiomeHeeler");
				LogInfo("PlantBiomeHeeler v1.0.0 initialized.");
			}
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			BiomeOverlayRenderer.Cleanup();
			BiomeHudManager.Cleanup();
		}

		internal static void LogInfo(string message)
		{
			if (ModConfig.IsInfoLogging)
			{
				Log.LogInfo((object)message);
			}
		}

		internal static void LogDebug(string message)
		{
			if (ModConfig.IsDebugLogging)
			{
				Log.LogInfo((object)("[DEBUG] " + message));
			}
		}
	}
	internal static class VersionInfo
	{
		public const string Version = "1.0.0";
	}
}
namespace PlantBiomeHeeler.Patches
{
	[HarmonyPatch(typeof(Heightmap))]
	internal static class HeightmapPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("RebuildCollisionMesh")]
		private static void RebuildCollisionMeshPostfix(Heightmap __instance)
		{
			BiomeOverlayRenderer.MarkTerrainDirty(__instance);
		}
	}
	[HarmonyPatch(typeof(Hud))]
	internal static class HudPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(Hud __instance)
		{
			BiomeHudManager.AttachToHud(__instance);
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetLocalPlayer")]
		private static void SetLocalPlayerPostfix(Player __instance)
		{
			BiomeOverlayRenderer.EnsureRenderer(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdatePostfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				OverlayVisibility.Update(__instance);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnDestroy")]
		private static void OnDestroyPrefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				OverlayVisibility.Reset();
			}
		}
	}
}
namespace PlantBiomeHeeler.Core.Visuals
{
	internal sealed class BiomeContourBuilder
	{
		private record struct CellCorner(int UnitX, int UnitZ, Biome Biome)
		{
			[CompilerGenerated]
			public readonly void Deconstruct(out int UnitX, out int UnitZ, out Biome Biome)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected I4, but got Unknown
				UnitX = this.UnitX;
				UnitZ = this.UnitZ;
				Biome = (Biome)(int)this.Biome;
			}
		}

		private const int LatticeMargin = 2;

		private const int MaximumSubdivisionDepth = 3;

		private const int UnitsPerCell = 128;

		private const float UnitSize = 1f / 128f;

		private const int CrossingResolutionUnits = 2;

		private readonly PlantBiomeSampler _sampler;

		private readonly BiomeOverlayMeshBuilder _meshBuilder;

		private readonly BorderStripBuilder _borderStrips;

		private readonly Vector2[] _ringPoints = (Vector2[])(object)new Vector2[8];

		private readonly Biome[] _ringBiomes = (Biome[])(object)new Biome[8];

		private readonly bool[] _ringIsCrossing = new bool[8];

		private readonly Vector2[] _polygonPoints = (Vector2[])(object)new Vector2[8];

		private readonly Biome[] _cornerBiomes = (Biome[])(object)new Biome[4];

		private int _ringCount;

		private Biome[] _nodeBiomes = Array.Empty<Biome>();

		private OverlayBuildSpec _spec;

		private int _latticeSize;

		private int _latticeOriginX;

		private int _latticeOriginZ;

		private float _cellOriginX;

		private float _cellOriginZ;

		public BiomeContourBuilder(PlantBiomeSampler sampler, BiomeOverlayMeshBuilder meshBuilder, BorderStripBuilder borderStrips)
		{
			_sampler = sampler;
			_meshBuilder = meshBuilder;
			_borderStrips = borderStrips;
		}

		public void Build(in OverlayBuildSpec spec)
		{
			_spec = spec;
			PrepareLattice();
			ClassifyNodes();
			EmitCells();
		}

		private float NodeX(int column)
		{
			return (float)(_latticeOriginX + column) + 0.5f;
		}

		private float NodeZ(int row)
		{
			return (float)(_latticeOriginZ + row) + 0.5f;
		}

		private void PrepareLattice()
		{
			int num = Mathf.CeilToInt(_spec.Radius) + 2;
			_latticeOriginX = _spec.FocusCellX - num;
			_latticeOriginZ = _spec.FocusCellZ - num;
			_latticeSize = 2 * num + 1;
			int num2 = _latticeSize * _latticeSize;
			if (_nodeBiomes.Length < num2)
			{
				_nodeBiomes = (Biome[])(object)new Biome[num2];
			}
			Array.Clear(_nodeBiomes, 0, num2);
			_meshBuilder.PrepareNodeVertices(num2);
		}

		private void ClassifyNodes()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected I4, but got Unknown
			Vector2 focusCenter = _spec.FocusCenter;
			float num = _spec.Radius + 1.5f;
			float num2 = num * num;
			int num3 = _latticeSize - 1;
			foreach (Heightmap heightmap in _sampler.Heightmaps)
			{
				Vector3 position = ((Component)heightmap).transform.position;
				float num4 = (float)heightmap.m_width * heightmap.m_scale * 0.5f;
				int num5 = Mathf.Max(0, Mathf.CeilToInt(position.x - num4 - (float)_latticeOriginX - 0.5f));
				int num6 = Mathf.Min(num3, Mathf.FloorToInt(position.x + num4 - (float)_latticeOriginX - 0.5f));
				int num7 = Mathf.Max(0, Mathf.CeilToInt(position.z - num4 - (float)_latticeOriginZ - 0.5f));
				int num8 = Mathf.Min(num3, Mathf.FloorToInt(position.z + num4 - (float)_latticeOriginZ - 0.5f));
				for (int i = num7; i <= num8; i++)
				{
					float num9 = NodeZ(i);
					float num10 = num9 - focusCenter.y;
					for (int j = num5; j <= num6; j++)
					{
						float num11 = NodeX(j);
						float num12 = num11 - focusCenter.x;
						if (!(num12 * num12 + num10 * num10 > num2))
						{
							_nodeBiomes[i * _latticeSize + j] = (Biome)(int)heightmap.GetBiome(new Vector3(num11, 0f, num9), 0.02f, false);
						}
					}
				}
			}
		}

		private void EmitCells()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			Vector2 focusCenter = _spec.FocusCenter;
			float num = _spec.Radius * _spec.Radius;
			int num2 = _latticeSize - 1;
			for (int i = 0; i < num2; i++)
			{
				float num3 = NodeZ(i) + 0.5f - focusCenter.y;
				for (int j = 0; j < num2; j++)
				{
					float num4 = NodeX(j) + 0.5f - focusCenter.x;
					if (num4 * num4 + num3 * num3 > num)
					{
						continue;
					}
					int num5 = i * _latticeSize + j;
					int num6 = num5 + 1;
					int num7 = num5 + _latticeSize;
					int num8 = num7 + 1;
					Biome val = _nodeBiomes[num5];
					Biome val2 = _nodeBiomes[num6];
					Biome val3 = _nodeBiomes[num8];
					Biome val4 = _nodeBiomes[num7];
					if ((int)val != 0 && (int)val2 != 0 && (int)val3 != 0 && (int)val4 != 0)
					{
						if (val == val2 && val == val3 && val == val4)
						{
							_meshBuilder.AddUniformQuad(num5, _latticeSize, new Vector2(NodeX(j), NodeZ(i)), val);
							continue;
						}
						_cellOriginX = NodeX(j);
						_cellOriginZ = NodeZ(i);
						ProcessCell(0, 0, 128, val, val2, val3, val4, 0);
					}
				}
			}
		}

		private Vector2 CellPoint(int unitX, int unitZ)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(_cellOriginX + (float)unitX * (1f / 128f), _cellOriginZ + (float)unitZ * (1f / 128f));
		}

		private Biome ClassifyCellPoint(int unitX, int unitZ)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return _sampler.Classify(CellPoint(unitX, unitZ));
		}

		private void ProcessCell(int westUnit, int southUnit, int sizeUnits, Biome southWest, Biome southEast, Biome northEast, Biome northWest, int depth)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_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)
			if (southWest == southEast && southWest == northEast && southWest == northWest)
			{
				_meshBuilder.AddFillQuad(CellPoint(westUnit, southUnit), CellPoint(westUnit + sizeUnits, southUnit + sizeUnits), southWest);
				return;
			}
			if (CountDistinct(southWest, southEast, northEast, northWest) == 2)
			{
				EmitTwoBiomeCell(westUnit, southUnit, sizeUnits, southWest, southEast, northEast, northWest);
				return;
			}
			if (depth >= 3)
			{
				var (primary, secondary) = GetTwoMostCommonBiomes(southWest, southEast, northEast, northWest);
				EmitTwoBiomeCell(westUnit, southUnit, sizeUnits, FoldIntoPair(southWest, primary, secondary), FoldIntoPair(southEast, primary, secondary), FoldIntoPair(northEast, primary, secondary), FoldIntoPair(northWest, primary, secondary));
				return;
			}
			int num = sizeUnits / 2;
			int num2 = westUnit + num;
			int num3 = southUnit + num;
			int unitX = westUnit + sizeUnits;
			int unitZ = southUnit + sizeUnits;
			Biome val = ClassifyCellPoint(num2, southUnit);
			Biome val2 = ClassifyCellPoint(unitX, num3);
			Biome val3 = ClassifyCellPoint(num2, unitZ);
			Biome val4 = ClassifyCellPoint(westUnit, num3);
			Biome val5 = ClassifyCellPoint(num2, num3);
			ProcessCell(westUnit, southUnit, num, southWest, val, val5, val4, depth + 1);
			ProcessCell(num2, southUnit, num, val, southEast, val2, val5, depth + 1);
			ProcessCell(num2, num3, num, val5, val2, northEast, val3, depth + 1);
			ProcessCell(westUnit, num3, num, val4, val5, val3, northWest, depth + 1);
		}

		private void EmitTwoBiomeCell(int westUnit, int southUnit, int sizeUnits, Biome southWest, Biome southEast, Biome northEast, Biome northWest)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			int unitX = westUnit + sizeUnits;
			int unitZ = southUnit + sizeUnits;
			CellCorner cellCorner = new CellCorner(westUnit, southUnit, southWest);
			CellCorner cellCorner2 = new CellCorner(unitX, southUnit, southEast);
			CellCorner cellCorner3 = new CellCorner(unitX, unitZ, northEast);
			CellCorner cellCorner4 = new CellCorner(westUnit, unitZ, northWest);
			_ringCount = 0;
			AddRingCorner(cellCorner);
			AddRingCrossing(cellCorner, cellCorner2);
			AddRingCorner(cellCorner2);
			AddRingCrossing(cellCorner2, cellCorner3);
			AddRingCorner(cellCorner3);
			AddRingCrossing(cellCorner3, cellCorner4);
			AddRingCorner(cellCorner4);
			AddRingCrossing(cellCorner4, cellCorner);
			int num = -1;
			int num2 = -1;
			int num3 = 0;
			for (int i = 0; i < _ringCount; i++)
			{
				if (_ringIsCrossing[i])
				{
					num3++;
					if (num < 0)
					{
						num = i;
					}
					else if (num2 < 0)
					{
						num2 = i;
					}
				}
			}
			if (num3 == 2)
			{
				EmitSplitCell(num, num2);
				return;
			}
			Biome secondBiome = ((southEast != southWest) ? southEast : northEast);
			EmitSaddleCell(westUnit + sizeUnits / 2, southUnit + sizeUnits / 2, southWest, secondBiome);
		}

		private void AddRingCorner(CellCorner corner)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected I4, but got Unknown
			_ringPoints[_ringCount] = CellPoint(corner.UnitX, corner.UnitZ);
			_ringBiomes[_ringCount] = (Biome)(int)corner.Biome;
			_ringIsCrossing[_ringCount] = false;
			_ringCount++;
		}

		private void AddRingCrossing(CellCorner firstCorner, CellCorner secondCorner)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (firstCorner.Biome != secondCorner.Biome)
			{
				_ringPoints[_ringCount] = FindCrossing(firstCorner, secondCorner);
				_ringBiomes[_ringCount] = (Biome)0;
				_ringIsCrossing[_ringCount] = true;
				_ringCount++;
			}
		}

		private Vector2 FindCrossing(CellCorner firstCorner, CellCorner secondCorner)
		{
			//IL_008c: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			bool num = firstCorner.UnitX + firstCorner.UnitZ < secondCorner.UnitX + secondCorner.UnitZ;
			CellCorner cellCorner = (num ? firstCorner : secondCorner);
			CellCorner cellCorner2 = (num ? secondCorner : firstCorner);
			int num2 = ((cellCorner2.UnitX > cellCorner.UnitX) ? 1 : 0);
			int num3 = 1 - num2;
			int num4 = 0;
			int num5 = cellCorner2.UnitX - cellCorner.UnitX + (cellCorner2.UnitZ - cellCorner.UnitZ);
			while (num5 - num4 > 2)
			{
				int num6 = (num4 + num5) / 2;
				if (ClassifyCellPoint(cellCorner.UnitX + num2 * num6, cellCorner.UnitZ + num3 * num6) == cellCorner.Biome)
				{
					num4 = num6;
				}
				else
				{
					num5 = num6;
				}
			}
			int num7 = (num4 + num5) / 2;
			return CellPoint(cellCorner.UnitX + num2 * num7, cellCorner.UnitZ + num3 * num7);
		}

		private void EmitSplitCell(int firstCrossing, int secondCrossing)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Biome val = _ringBiomes[firstCrossing + 1];
			Biome val2 = _ringBiomes[(secondCrossing + 1) % _ringCount];
			EmitRingPolygon(firstCrossing, secondCrossing, val);
			EmitRingPolygon(secondCrossing, firstCrossing, val2);
			_borderStrips.AddSegment(_ringPoints[firstCrossing], _ringPoints[secondCrossing], val, _ringPoints[firstCrossing + 1], val2);
		}

		private void EmitSaddleCell(int centerUnitX, int centerUnitZ, Biome firstBiome, Biome secondBiome)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between I4 and Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			Biome val = ClassifyCellPoint(centerUnitX, centerUnitZ);
			if (val != firstBiome && val != secondBiome)
			{
				val = firstBiome;
			}
			int num = 0;
			for (int i = 0; i < _ringCount; i++)
			{
				if (_ringIsCrossing[i] || (int)_ringBiomes[i] == (int)val)
				{
					_polygonPoints[num] = _ringPoints[i];
					num++;
					continue;
				}
				Vector2 val2 = _ringPoints[(i + _ringCount - 1) % _ringCount];
				Vector2 val3 = _ringPoints[(i + 1) % _ringCount];
				Vector2 val4 = _ringPoints[i];
				Biome val5 = _ringBiomes[i];
				_meshBuilder.AddFillTriangle(val2, val4, val3, val5);
				_borderStrips.AddSegment(val2, val3, val5, val4, val);
			}
			_meshBuilder.AddFillPolygon(_polygonPoints, num, val);
		}

		private void EmitRingPolygon(int startIndex, int endIndex, Biome biome)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = startIndex;
			while (true)
			{
				_polygonPoints[num] = _ringPoints[num2];
				num++;
				if (num2 == endIndex)
				{
					break;
				}
				num2 = (num2 + 1) % _ringCount;
			}
			_meshBuilder.AddFillPolygon(_polygonPoints, num, biome);
		}

		private (Biome Primary, Biome Secondary) GetTwoMostCommonBiomes(Biome southWest, Biome southEast, Biome northEast, Biome northWest)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected I4, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected I4, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			_cornerBiomes[0] = (Biome)(int)southWest;
			_cornerBiomes[1] = (Biome)(int)southEast;
			_cornerBiomes[2] = (Biome)(int)northEast;
			_cornerBiomes[3] = (Biome)(int)northWest;
			Biome val = FindMostCommonCornerBiome((Biome)0);
			return (Primary: val, Secondary: FindMostCommonCornerBiome(val));
		}

		private Biome FindMostCommonCornerBiome(Biome excludedBiome)
		{
			//IL_0001: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between I4 and Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			Biome result = (Biome)0;
			int num = 0;
			for (int i = 0; i < _cornerBiomes.Length; i++)
			{
				Biome val = _cornerBiomes[i];
				if (val == excludedBiome)
				{
					continue;
				}
				int num2 = 0;
				for (int j = 0; j < _cornerBiomes.Length; j++)
				{
					if ((int)_cornerBiomes[j] == (int)val)
					{
						num2++;
					}
				}
				if (num2 > num)
				{
					result = val;
					num = num2;
				}
			}
			return result;
		}

		private static Biome FoldIntoPair(Biome biome, Biome primary, Biome secondary)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (biome != secondary)
			{
				return primary;
			}
			return secondary;
		}

		private static int CountDistinct(Biome first, Biome second, Biome third, Biome fourth)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = 1;
			if (second != first)
			{
				num++;
			}
			if (third != first && third != second)
			{
				num++;
			}
			if (fourth != first && fourth != second && fourth != third)
			{
				num++;
			}
			return num;
		}
	}
	internal sealed class BiomeOverlayMeshBuilder
	{
		private readonly PlantBiomeSampler _sampler = new PlantBiomeSampler();

		private readonly OverlayVertexFactory _vertexFactory;

		private readonly BiomeContourBuilder _contourBuilder;

		private readonly BorderStripBuilder _borderStrips = new BorderStripBuilder();

		private readonly OverlayMeshBuffers _fillBuffers = new OverlayMeshBuffers(16384);

		private readonly OverlayMeshBuffers _hatchBuffers = new OverlayMeshBuffers(16384);

		private readonly OverlayMeshBuffers _borderBuffers = new OverlayMeshBuffers(4096);

		private int[] _nodeVertices = Array.Empty<int>();

		private int[] _nodeVertexStamps = Array.Empty<int>();

		private int _stamp;

		private bool _hasHatchLines;

		public bool HasFillGeometry => _fillBuffers.HasGeometry;

		public bool HasHatchGeometry => _hatchBuffers.HasGeometry;

		public bool HasBorderGeometry => _borderBuffers.HasGeometry;

		public BiomeOverlayMeshBuilder()
		{
			_vertexFactory = new OverlayVertexFactory(new TerrainHeightSampler(_sampler));
			_contourBuilder = new BiomeContourBuilder(_sampler, this, _borderStrips);
		}

		public void Rebuild(Mesh fillMesh, Mesh hatchMesh, Mesh borderMesh, in OverlayBuildSpec spec)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			_hasHatchLines = spec.EnableHatchLines;
			_fillBuffers.Clear();
			_hatchBuffers.Clear();
			_borderBuffers.Clear();
			_borderStrips.Clear();
			_sampler.Prepare(spec.FocusCenter, spec.Radius);
			_vertexFactory.Prepare(in spec);
			_contourBuilder.Build(in spec);
			_borderStrips.Emit(_borderBuffers, _vertexFactory, spec.BorderWidth);
			_sampler.Clear();
			_fillBuffers.ApplyTo(fillMesh);
			_hatchBuffers.ApplyTo(hatchMesh);
			_borderBuffers.ApplyTo(borderMesh);
		}

		public void PrepareNodeVertices(int nodeCount)
		{
			if (_nodeVertexStamps.Length < nodeCount)
			{
				_nodeVertices = new int[nodeCount];
				_nodeVertexStamps = new int[nodeCount];
				_stamp = 0;
			}
			if (_stamp == int.MaxValue)
			{
				Array.Clear(_nodeVertexStamps, 0, _nodeVertexStamps.Length);
				_stamp = 0;
			}
			_stamp++;
		}

		public void AddUniformQuad(int southWestNode, int rowStride, Vector2 southWestPoint, Biome biome)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			int num = southWestNode + rowStride;
			AddFillQuadIndices(GetNodeVertex(southWestNode, southWestPoint, biome), GetNodeVertex(southWestNode + 1, southWestPoint + new Vector2(1f, 0f), biome), GetNodeVertex(num + 1, southWestPoint + new Vector2(1f, 1f), biome), GetNodeVertex(num, southWestPoint + new Vector2(0f, 1f), biome));
		}

		public void AddFillPolygon(Vector2[] points, int pointCount, Biome biome)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			int num = AddFillVertex(points[0], biome);
			for (int i = 1; i < pointCount; i++)
			{
				AddFillVertex(points[i], biome);
			}
			for (int j = 1; j < pointCount - 1; j++)
			{
				AddFillTriangleIndices(num, num + j, num + j + 1);
			}
		}

		public void AddFillTriangle(Vector2 firstPoint, Vector2 secondPoint, Vector2 thirdPoint, Biome biome)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			AddFillTriangleIndices(AddFillVertex(firstPoint, biome), AddFillVertex(secondPoint, biome), AddFillVertex(thirdPoint, biome));
		}

		public void AddFillQuad(Vector2 southWestPoint, Vector2 northEastPoint, Biome biome)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			AddFillQuadIndices(AddFillVertex(southWestPoint, biome), AddFillVertex(new Vector2(northEastPoint.x, southWestPoint.y), biome), AddFillVertex(northEastPoint, biome), AddFillVertex(new Vector2(southWestPoint.x, northEastPoint.y), biome));
		}

		private int GetNodeVertex(int nodeIndex, Vector2 point, Biome biome)
		{
			//IL_001a: 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)
			if (_nodeVertexStamps[nodeIndex] == _stamp)
			{
				return _nodeVertices[nodeIndex];
			}
			int num = AddFillVertex(point, biome);
			_nodeVertexStamps[nodeIndex] = _stamp;
			_nodeVertices[nodeIndex] = num;
			return num;
		}

		private int AddFillVertex(Vector2 point, Biome biome)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = _vertexFactory.GetPosition(point);
			if (_hasHatchLines)
			{
				_hatchBuffers.AddVertex(position, _vertexFactory.GetBorderColor(biome, point), _vertexFactory.GetHatchUv(point));
			}
			return _fillBuffers.AddVertex(position, _vertexFactory.GetFillColor(biome, point));
		}

		private void AddFillTriangleIndices(int first, int second, int third)
		{
			_fillBuffers.AddTriangle(first, second, third);
			if (_hasHatchLines)
			{
				_hatchBuffers.AddTriangle(first, second, third);
			}
		}

		private void AddFillQuadIndices(int first, int second, int third, int fourth)
		{
			AddFillTriangleIndices(first, second, third);
			AddFillTriangleIndices(first, third, fourth);
		}
	}
	public sealed class BiomeOverlayRenderer : MonoBehaviour
	{
		private const int FillRenderQueue = 3100;

		private const int HatchRenderQueue = 3101;

		private const int BorderRenderQueue = 3102;

		private const string OverlayShaderName = "Sprites/Default";

		private static BiomeOverlayRenderer? _instance;

		private readonly BiomeOverlayMeshBuilder _meshBuilder = new BiomeOverlayMeshBuilder();

		private Mesh? _fillMesh;

		private Mesh? _hatchMesh;

		private Mesh? _borderMesh;

		private Material _fillMaterial;

		private Material _hatchMaterial;

		private Material _borderMaterial;

		private Texture2D _hatchTexture;

		private float _hatchLineFraction = -1f;

		private OverlayBuildSpec _builtSpec;

		private bool _hasValidMesh;

		private bool _isTerrainDirty;

		private void Awake()
		{
			_instance = this;
			Shader shader = Shader.Find("Sprites/Default");
			_fillMaterial = CreateMaterial(shader, 3100);
			_hatchMaterial = CreateMaterial(shader, 3101);
			_borderMaterial = CreateMaterial(shader, 3102);
			_hatchTexture = OverlayHatchTexture.Create();
			_hatchMaterial.mainTexture = (Texture)(object)_hatchTexture;
			ModConfig.SettingChanged += OnConfigSettingChanged;
		}

		private void LateUpdate()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			if (!OverlayVisibility.IsOverlayActive)
			{
				_hasValidMesh = false;
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			OverlayBuildSpec buildSpec = new OverlayBuildSpec(Mathf.FloorToInt(position.x), Mathf.FloorToInt(position.z), ModConfig.OverlayRadius.Value, ModConfig.OverlayHeight.Value, ModConfig.InteriorOpacity.Value, ModConfig.BorderOpacity.Value, ModConfig.BorderWidth.Value, ZoneSystem.instance.m_waterLevel, ModConfig.EnableHatchLines.Value, ModConfig.HatchLineSpacing.Value, ModConfig.HatchLineWidth.Value);
			if (!_hasValidMesh || _isTerrainDirty || buildSpec != _builtSpec)
			{
				RebuildMeshes(in buildSpec);
			}
			if (_meshBuilder.HasFillGeometry)
			{
				Graphics.DrawMesh(_fillMesh, Matrix4x4.identity, _fillMaterial, 0);
			}
			if (_meshBuilder.HasHatchGeometry)
			{
				Graphics.DrawMesh(_hatchMesh, Matrix4x4.identity, _hatchMaterial, 0);
			}
			if (_meshBuilder.HasBorderGeometry)
			{
				Graphics.DrawMesh(_borderMesh, Matrix4x4.identity, _borderMaterial, 0);
			}
		}

		private void OnDestroy()
		{
			ModConfig.SettingChanged -= OnConfigSettingChanged;
			DestroyResource<Mesh>(ref _fillMesh);
			DestroyResource<Mesh>(ref _hatchMesh);
			DestroyResource<Mesh>(ref _borderMesh);
			Object.Destroy((Object)(object)_fillMaterial);
			Object.Destroy((Object)(object)_hatchMaterial);
			Object.Destroy((Object)(object)_borderMaterial);
			Object.Destroy((Object)(object)_hatchTexture);
			if (_instance == this)
			{
				_instance = null;
			}
		}

		public static void EnsureRenderer(Player player)
		{
			BiomeOverlayRenderer biomeOverlayRenderer = default(BiomeOverlayRenderer);
			if (!((Component)player).TryGetComponent<BiomeOverlayRenderer>(ref biomeOverlayRenderer))
			{
				((Component)player).gameObject.AddComponent<BiomeOverlayRenderer>();
			}
		}

		public static void Cleanup()
		{
			if (Object.op_Implicit((Object)(object)_instance))
			{
				Object.Destroy((Object)(object)_instance);
			}
		}

		public static void MarkTerrainDirty(Heightmap heightmap)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_instance) && _instance._hasValidMesh && !heightmap.IsDistantLod)
			{
				OverlayBuildSpec builtSpec = _instance._builtSpec;
				if (PlantBiomeSampler.IsWithinReach(((Component)heightmap).transform.position, builtSpec.FocusCenter, builtSpec.Radius))
				{
					_instance._isTerrainDirty = true;
				}
			}
		}

		private void OnConfigSettingChanged(object sender, SettingChangedEventArgs eventArgs)
		{
			_hasValidMesh = false;
		}

		private void RebuildMeshes(in OverlayBuildSpec buildSpec)
		{
			if (!Object.op_Implicit((Object)(object)_fillMesh))
			{
				_fillMesh = CreateMesh("PlantBiomeHeeler_OverlayFill");
			}
			if (!Object.op_Implicit((Object)(object)_hatchMesh))
			{
				_hatchMesh = CreateMesh("PlantBiomeHeeler_OverlayHatch");
			}
			if (!Object.op_Implicit((Object)(object)_borderMesh))
			{
				_borderMesh = CreateMesh("PlantBiomeHeeler_OverlayBorder");
			}
			float num = Mathf.Clamp01(buildSpec.HatchLineWidth / buildSpec.HatchLineSpacing);
			if (num != _hatchLineFraction)
			{
				OverlayHatchTexture.Fill(_hatchTexture, num);
				_hatchLineFraction = num;
			}
			long timestamp = Stopwatch.GetTimestamp();
			_meshBuilder.Rebuild(_fillMesh, _hatchMesh, _borderMesh, in buildSpec);
			if (ModConfig.IsDebugLogging)
			{
				double num2 = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency;
				Plugin.LogDebug($"Overlay rebuilt in {num2:F2} ms at radius {buildSpec.Radius:F0} m.");
			}
			_builtSpec = buildSpec;
			_hasValidMesh = true;
			_isTerrainDirty = false;
		}

		private static Mesh CreateMesh(string meshName)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = meshName,
				indexFormat = (IndexFormat)1,
				hideFlags = (HideFlags)61
			};
			val.MarkDynamic();
			return val;
		}

		private static Material CreateMaterial(Shader shader, int renderQueue)
		{
			//IL_0001: 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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			return new Material(shader)
			{
				color = Color.white,
				renderQueue = renderQueue,
				hideFlags = (HideFlags)61
			};
		}

		private static void DestroyResource<T>(ref T? resource) where T : Object
		{
			if (Object.op_Implicit((Object)(object)resource))
			{
				Object.Destroy((Object)(object)resource);
			}
			resource = default(T);
		}
	}
	internal sealed class BorderStripBuilder
	{
		private record struct BorderSegment(Vector2 Start, Vector2 End, Biome LeftBiome, Biome RightBiome)
		{
			[CompilerGenerated]
			public readonly void Deconstruct(out Vector2 Start, out Vector2 End, out Biome LeftBiome, out Biome RightBiome)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Expected I4, but got Unknown
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected I4, but got Unknown
				Start = this.Start;
				End = this.End;
				LeftBiome = (Biome)(int)this.LeftBiome;
				RightBiome = (Biome)(int)this.RightBiome;
			}
		}

		private record struct EndpointLinks(int FirstSegment, int SecondSegment, int Count);

		private const float MinimumMiterDot = 0.35f;

		private const float MinimumSegmentLengthSquared = 1E-08f;

		private readonly List<BorderSegment> _segments = new List<BorderSegment>(1024);

		private readonly Dictionary<Vector2, EndpointLinks> _links = new Dictionary<Vector2, EndpointLinks>(2048);

		private readonly List<Vector2> _chainPoints = new List<Vector2>(256);

		private bool[] _isSegmentUsed = Array.Empty<bool>();

		public void Clear()
		{
			_segments.Clear();
			_links.Clear();
		}

		public void AddSegment(Vector2 start, Vector2 end, Biome firstBiome, Vector2 pointOnFirstSide, Biome secondBiome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0041: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = end - start;
			if (!(((Vector2)(ref val)).sqrMagnitude < 1E-08f))
			{
				BorderSegment item = ((Vector2.Dot(new Vector2(0f - val.y, val.x), pointOnFirstSide - start) > 0f) ? new BorderSegment(start, end, firstBiome, secondBiome) : new BorderSegment(start, end, secondBiome, firstBiome));
				int count = _segments.Count;
				_segments.Add(item);
				AddLink(start, count);
				AddLink(end, count);
			}
		}

		public void Emit(OverlayMeshBuffers buffers, OverlayVertexFactory vertexFactory, float borderWidth)
		{
			//IL_0065: 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)
			int count = _segments.Count;
			if (_isSegmentUsed.Length < count)
			{
				_isSegmentUsed = new bool[Mathf.NextPowerOfTwo(count)];
			}
			Array.Clear(_isSegmentUsed, 0, count);
			for (int i = 0; i < count; i++)
			{
				if (!_isSegmentUsed[i])
				{
					var (headIndex, head) = FindChainHead(i);
					CollectChain(headIndex, head);
					EmitChain(buffers, vertexFactory, borderWidth, head.LeftBiome, head.RightBiome);
				}
			}
		}

		private void AddLink(Vector2 point, int segmentIndex)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!_links.TryGetValue(point, out var value))
			{
				_links[point] = new EndpointLinks(segmentIndex, -1, 1);
				return;
			}
			_links[point] = ((value.Count == 1) ? value with
			{
				SecondSegment = segmentIndex,
				Count = 2
			} : value with
			{
				Count = value.Count + 1
			});
		}

		private bool TryGetOtherSegment(Vector2 point, int fromSegment, out int otherSegment)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (_links.TryGetValue(point, out var value) && value.Count == 2)
			{
				otherSegment = ((value.FirstSegment == fromSegment) ? value.SecondSegment : value.FirstSegment);
				return true;
			}
			otherSegment = -1;
			return false;
		}

		private (int Index, BorderSegment Segment) FindChainHead(int seedIndex)
		{
			//IL_0016: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			int num = seedIndex;
			BorderSegment item = _segments[seedIndex];
			for (int i = 0; i < _segments.Count; i++)
			{
				if (!TryGetOtherSegment(item.Start, num, out var otherSegment))
				{
					break;
				}
				if (otherSegment == seedIndex)
				{
					break;
				}
				if (_isSegmentUsed[otherSegment])
				{
					break;
				}
				BorderSegment borderSegment = OrientToEndAt(_segments[otherSegment], item.Start);
				if (borderSegment.LeftBiome != item.LeftBiome || borderSegment.RightBiome != item.RightBiome)
				{
					break;
				}
				num = otherSegment;
				item = borderSegment;
			}
			return (Index: num, Segment: item);
		}

		private void CollectChain(int headIndex, BorderSegment head)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			_chainPoints.Clear();
			_chainPoints.Add(head.Start);
			_chainPoints.Add(head.End);
			_isSegmentUsed[headIndex] = true;
			int fromSegment = headIndex;
			BorderSegment borderSegment = head;
			int otherSegment;
			while (TryGetOtherSegment(borderSegment.End, fromSegment, out otherSegment) && !_isSegmentUsed[otherSegment])
			{
				BorderSegment borderSegment2 = OrientToStartAt(_segments[otherSegment], borderSegment.End);
				if (borderSegment2.LeftBiome == borderSegment.LeftBiome && borderSegment2.RightBiome == borderSegment.RightBiome)
				{
					_chainPoints.Add(borderSegment2.End);
					_isSegmentUsed[otherSegment] = true;
					fromSegment = otherSegment;
					borderSegment = borderSegment2;
					continue;
				}
				break;
			}
		}

		private void EmitChain(OverlayMeshBuffers buffers, OverlayVertexFactory vertexFactory, float borderWidth, Biome leftBiome, Biome rightBiome)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			int count = _chainPoints.Count;
			int num;
			if (count > 3)
			{
				Vector2 val = _chainPoints[0];
				num = (((Vector2)(ref val)).Equals(_chainPoints[count - 1]) ? 1 : 0);
			}
			else
			{
				num = 0;
			}
			bool isClosed = (byte)num != 0;
			int first = -1;
			int second = -1;
			int first2 = -1;
			int second2 = -1;
			for (int i = 0; i < count; i++)
			{
				Vector2 val2 = _chainPoints[i];
				Vector2 val3 = GetMiterNormal(i, isClosed) * borderWidth;
				Vector2 point = val2 + val3;
				Vector2 point2 = val2 - val3;
				Vector3 position = vertexFactory.GetPosition(val2);
				int num2 = buffers.AddVertex(position, vertexFactory.GetBorderColor(leftBiome, val2));
				int num3 = buffers.AddVertex(vertexFactory.GetPosition(point), vertexFactory.GetBorderColor(leftBiome, point));
				int num4 = buffers.AddVertex(position, vertexFactory.GetBorderColor(rightBiome, val2));
				int num5 = buffers.AddVertex(vertexFactory.GetPosition(point2), vertexFactory.GetBorderColor(rightBiome, point2));
				if (i > 0)
				{
					buffers.AddQuad(first, second, num3, num2);
					buffers.AddQuad(first2, second2, num5, num4);
				}
				first = num2;
				second = num3;
				first2 = num4;
				second2 = num5;
			}
		}

		private Vector2 GetMiterNormal(int pointIndex, bool isClosed)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			int num = _chainPoints.Count - 1;
			if (!isClosed && pointIndex == 0)
			{
				return GetLeftNormal(_chainPoints[1] - _chainPoints[0]);
			}
			if (!isClosed && pointIndex == num)
			{
				return GetLeftNormal(_chainPoints[num] - _chainPoints[num - 1]);
			}
			Vector2 val = _chainPoints[pointIndex];
			Vector2 val2 = ((pointIndex == 0) ? _chainPoints[num - 1] : _chainPoints[pointIndex - 1]);
			Vector2 leftNormal = GetLeftNormal(((pointIndex == num) ? _chainPoints[1] : _chainPoints[pointIndex + 1]) - val);
			Vector2 val3 = GetLeftNormal(val - val2) + leftNormal;
			if (((Vector2)(ref val3)).sqrMagnitude < 1E-06f)
			{
				return leftNormal;
			}
			Vector2 normalized = ((Vector2)(ref val3)).normalized;
			float num2 = Mathf.Max(Vector2.Dot(normalized, leftNormal), 0.35f);
			return normalized / num2;
		}

		private static Vector2 GetLeftNormal(Vector2 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(0f - direction.y, direction.x);
			return ((Vector2)(ref val)).normalized;
		}

		private static BorderSegment OrientToStartAt(BorderSegment segment, Vector2 point)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 start = segment.Start;
			if (!((Vector2)(ref start)).Equals(point))
			{
				return Reverse(segment);
			}
			return segment;
		}

		private static BorderSegment OrientToEndAt(BorderSegment segment, Vector2 point)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 end = segment.End;
			if (!((Vector2)(ref end)).Equals(point))
			{
				return Reverse(segment);
			}
			return segment;
		}

		private static BorderSegment Reverse(BorderSegment segment)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return new BorderSegment(segment.End, segment.Start, segment.RightBiome, segment.LeftBiome);
		}
	}
	internal record struct OverlayBuildSpec(int FocusCellX, int FocusCellZ, float Radius, float HeightOffset, float InteriorOpacity, float BorderOpacity, float BorderWidth, float WaterLevel, bool EnableHatchLines, float HatchLineSpacing, float HatchLineWidth)
	{
		public Vector2 FocusCenter => new Vector2((float)FocusCellX + 0.5f, (float)FocusCellZ + 0.5f);
	}
	internal static class OverlayHatchTexture
	{
		private const int TextureWidth = 256;

		private static readonly Color32[] Pixels = (Color32[])(object)new Color32[256];

		public static Texture2D Create()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return new Texture2D(256, 1, (TextureFormat)4, true)
			{
				name = "PlantBiomeHeeler_HatchLines",
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)2,
				anisoLevel = 8,
				hideFlags = (HideFlags)61
			};
		}

		public static void Fill(Texture2D texture, float lineFraction)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			float num = lineFraction * 256f;
			for (int i = 0; i < 256; i++)
			{
				float num2 = Mathf.Clamp01(num - (float)i);
				Pixels[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num2 * 255f));
			}
			texture.SetPixels32(Pixels);
			texture.Apply(true);
		}
	}
	internal sealed class OverlayMeshBuffers
	{
		private readonly List<Vector3> _vertices;

		private readonly List<Color32> _colors;

		private readonly List<Vector2> _uvs;

		private readonly List<int> _indices;

		public bool HasGeometry => _indices.Count > 0;

		public OverlayMeshBuffers(int vertexCapacity)
		{
			_vertices = new List<Vector3>(vertexCapacity);
			_colors = new List<Color32>(vertexCapacity);
			_uvs = new List<Vector2>();
			_indices = new List<int>(vertexCapacity * 2);
		}

		public void Clear()
		{
			_vertices.Clear();
			_colors.Clear();
			_uvs.Clear();
			_indices.Clear();
		}

		public int AddVertex(Vector3 position, Color32 color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			_vertices.Add(position);
			_colors.Add(color);
			return _vertices.Count - 1;
		}

		public int AddVertex(Vector3 position, Color32 color, Vector2 uv)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			_uvs.Add(uv);
			return AddVertex(position, color);
		}

		public void AddTriangle(int first, int second, int third)
		{
			_indices.Add(first);
			_indices.Add(second);
			_indices.Add(third);
		}

		public void AddQuad(int first, int second, int third, int fourth)
		{
			AddTriangle(first, second, third);
			AddTriangle(first, third, fourth);
		}

		public void ApplyTo(Mesh mesh)
		{
			mesh.Clear();
			if (_vertices.Count != 0)
			{
				mesh.SetVertices(_vertices);
				mesh.SetColors(_colors);
				if (_uvs.Count > 0)
				{
					mesh.SetUVs(0, _uvs);
				}
				mesh.SetIndices(_indices, (MeshTopology)0, 0, true, 0);
			}
		}
	}
	internal sealed class OverlayVertexFactory
	{
		private const float InnerFadeFraction = 0.65f;

		private readonly TerrainHeightSampler _heightSampler;

		private readonly Color32[] _fillColors = (Color32[])(object)new Color32[10];

		private readonly Color32[] _borderColors = (Color32[])(object)new Color32[10];

		private Vector2 _focus;

		private float _radius;

		private float _radiusSquared;

		private float _innerRadius;

		private float _innerRadiusSquared;

		private float _heightOffset;

		private float _waterLevel;

		private float _hatchOrigin;

		private float _hatchFrequency;

		public OverlayVertexFactory(TerrainHeightSampler heightSampler)
		{
			_heightSampler = heightSampler;
		}

		public void Prepare(in OverlayBuildSpec spec)
		{
			//IL_000a: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Invalid comparison between Unknown and I4
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			_focus = spec.FocusCenter;
			_radius = spec.Radius;
			_radiusSquared = spec.Radius * spec.Radius;
			_innerRadius = spec.Radius * 0.65f;
			_innerRadiusSquared = _innerRadius * _innerRadius;
			_heightOffset = spec.HeightOffset;
			_waterLevel = spec.WaterLevel;
			float num = spec.HatchLineSpacing * Mathf.Sqrt(2f);
			_hatchFrequency = 1f / num;
			_hatchOrigin = Mathf.Round((_focus.x + _focus.y) / num) * num;
			BiomeIndex val = (BiomeIndex)1;
			while ((int)val < 10)
			{
				Color biomeColor = ModConfig.GetBiomeColor(BiomeHelpers.ToBiome(val));
				Color linear = ((Color)(ref biomeColor)).linear;
				Color val2 = linear;
				val2.a = spec.BorderOpacity;
				linear.a *= spec.InteriorOpacity;
				_fillColors[val] = Color32.op_Implicit(linear);
				_borderColors[val] = Color32.op_Implicit(val2);
				val = (BiomeIndex)(byte)(val + 1);
			}
		}

		public Vector3 GetPosition(Vector2 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(point.x, _heightSampler.SampleSurfaceHeight(point, _waterLevel) + _heightOffset, point.y);
		}

		public Color32 GetFillColor(Biome biome, Vector2 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ApplyRadialFade(_fillColors[BiomeHelpers.ToIndex(biome)], point);
		}

		public Color32 GetBorderColor(Biome biome, Vector2 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return ApplyRadialFade(_borderColors[BiomeHelpers.ToIndex(biome)], point);
		}

		public Vector2 GetHatchUv(Vector2 point)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2((point.x + point.y - _hatchOrigin) * _hatchFrequency, 0f);
		}

		private Color32 ApplyRadialFade(Color32 color, Vector2 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			float num = point.x - _focus.x;
			float num2 = point.y - _focus.y;
			float num3 = num * num + num2 * num2;
			if (num3 <= _innerRadiusSquared)
			{
				return color;
			}
			if (num3 >= _radiusSquared)
			{
				color.a = 0;
				return color;
			}
			float num4 = (_radius - Mathf.Sqrt(num3)) / (_radius - _innerRadius);
			float num5 = num4 * num4 * (3f - 2f * num4);
			color.a = (byte)((float)(int)color.a * num5);
			return color;
		}
	}
	internal sealed class PlantBiomeSampler
	{
		private const float ZoneHalfDiagonal = 45.26f;

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

		public Dictionary<Vector2s, Heightmap>.ValueCollection Heightmaps => _heightmapsByZone.Values;

		public static bool IsWithinReach(Vector3 heightmapCenter, Vector2 focus, float radius)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			float num = radius + 45.26f;
			float num2 = heightmapCenter.x - focus.x;
			float num3 = heightmapCenter.z - focus.y;
			return num2 * num2 + num3 * num3 <= num * num;
		}

		public void Prepare(Vector2 focus, float radius)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			_heightmapsByZone.Clear();
			List<Heightmap> allHeightmaps = Heightmap.GetAllHeightmaps();
			for (int i = 0; i < allHeightmaps.Count; i++)
			{
				Heightmap val = allHeightmaps[i];
				Vector3 position = ((Component)val).transform.position;
				if (IsWithinReach(position, focus, radius))
				{
					_heightmapsByZone[ZoneSystem.GetZone(position)] = val;
				}
			}
		}

		public void Clear()
		{
			_heightmapsByZone.Clear();
		}

		public bool TryGetHeightmap(Vector2 point, out Heightmap heightmap)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			return _heightmapsByZone.TryGetValue(ZoneSystem.GetZone(new Vector3(point.x, 0f, point.y)), out heightmap);
		}

		public Biome Classify(Vector2 point)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetHeightmap(point, out Heightmap heightmap))
			{
				return (Biome)0;
			}
			return heightmap.GetBiome(new Vector3(point.x, 0f, point.y), 0.02f, false);
		}
	}
	internal sealed class TerrainHeightSampler
	{
		private readonly PlantBiomeSampler _biomeSampler;

		public TerrainHeightSampler(PlantBiomeSampler biomeSampler)
		{
			_biomeSampler = biomeSampler;
		}

		public float SampleSurfaceHeight(Vector2 point, float waterLevel)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (!_biomeSampler.TryGetHeightmap(point, out Heightmap heightmap))
			{
				return waterLevel;
			}
			int width = heightmap.m_width;
			int num = width + 1;
			float scale = heightmap.m_scale;
			float num2 = (float)width * scale * 0.5f;
			Vector3 position = ((Component)heightmap).transform.position;
			float num3 = Mathf.Clamp((point.x - position.x + num2) / scale, 0f, (float)width);
			float num4 = Mathf.Clamp((point.y - position.z + num2) / scale, 0f, (float)width);
			int num5 = Mathf.Min((int)num3, width - 1);
			int num6 = Mathf.Min((int)num4, width - 1);
			float num7 = num3 - (float)num5;
			float num8 = num4 - (float)num6;
			List<float> heights = heightmap.m_heights;
			int num9 = num6 * num + num5;
			int num10 = num9 + num;
			float num11 = Mathf.LerpUnclamped(heights[num9], heights[num9 + 1], num7);
			float num12 = Mathf.LerpUnclamped(heights[num10], heights[num10 + 1], num7);
			return Mathf.Max(position.y + Mathf.LerpUnclamped(num11, num12, num8), waterLevel);
		}
	}
}
namespace PlantBiomeHeeler.Core.UI
{
	public sealed class BiomeHudManager : MonoBehaviour
	{
		private static BiomeHudManager? _instance;

		private BiomeHudPanel _panel;

		private WaitForSeconds _cachedWait;

		private void Awake()
		{
			_instance = this;
			ModConfig.SettingChanged += OnConfigSettingChanged;
		}

		private void OnDestroy()
		{
			ModConfig.SettingChanged -= OnConfigSettingChanged;
			_panel.Destroy();
			if (_instance == this)
			{
				_instance = null;
			}
		}

		public static void AttachToHud(Hud hud)
		{
			BiomeHudManager biomeHudManager = default(BiomeHudManager);
			if (!((Component)hud).TryGetComponent<BiomeHudManager>(ref biomeHudManager))
			{
				((Component)hud).gameObject.AddComponent<BiomeHudManager>().Initialize(hud);
			}
		}

		public static void Cleanup()
		{
			if (Object.op_Implicit((Object)(object)_instance))
			{
				Object.Destroy((Object)(object)_instance);
			}
		}

		private void Initialize(Hud hud)
		{
			_panel = new BiomeHudPanel(hud.m_rootObject.transform);
			ApplySettings();
			((MonoBehaviour)this).StartCoroutine(PollLoop());
		}

		private IEnumerator PollLoop()
		{
			while (true)
			{
				yield return _cachedWait;
				Refresh();
			}
		}

		private void Refresh()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !OverlayVisibility.IsHudVisible)
			{
				_panel.SetActive(active: false);
				return;
			}
			Biome standingBiome = Heightmap.FindBiome(((Component)localPlayer).transform.position);
			Vector3 targetPoint;
			Biome targetBiome = (Biome)(TryGetTargetPoint(localPlayer, out targetPoint) ? ((int)Heightmap.FindBiome(targetPoint)) : 0);
			_panel.SetBiomes(targetBiome, standingBiome);
			_panel.SetActive(active: true);
		}

		private static bool TryGetTargetPoint(Player player, out Vector3 targetPoint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			GameObject placementGhost = player.m_placementGhost;
			if (Object.op_Implicit((Object)(object)placementGhost) && placementGhost.activeSelf)
			{
				targetPoint = placementGhost.transform.position;
				return true;
			}
			Transform transform = ((Component)Utils.GetMainCamera()).transform;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(transform.position, transform.forward, ref val, ModConfig.TargetRayDistance.Value, ZoneSystem.instance.m_terrainRayMask))
			{
				targetPoint = ((RaycastHit)(ref val)).point;
				return true;
			}
			targetPoint = Vector3.zero;
			return false;
		}

		private void OnConfigSettingChanged(object sender, SettingChangedEventArgs eventArgs)
		{
			ApplySettings();
		}

		private void ApplySettings()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			_cachedWait = new WaitForSeconds(ModConfig.HudUpdateInterval.Value);
			_panel.ApplySettings();
		}
	}
	internal sealed class BiomeHudPanel
	{
		private const string NoBiomeText = "-";

		private const string TitleText = "Plant Biome";

		private const float TitleFontScale = 0.75f;

		private const string TargetPrefix = "Target: ";

		private const string StandingPrefix = "Standing: ";

		private readonly GameObject _root;

		private readonly RectTransform _rootRect;

		private readonly Image _background;

		private readonly TextMeshProUGUI _titleLabel;

		private readonly TextMeshProUGUI _targetLabel;

		private readonly TextMeshProUGUI _standingLabel;

		private readonly string?[] _biomeTextCache = new string[10];

		private Biome _shownTargetBiome;

		private Biome _shownStandingBiome;

		private bool _hasText;

		public BiomeHudPanel(Transform parentTransform)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			_root = new GameObject("PlantBiomeHeeler_BiomeHud", new Type[1] { typeof(RectTransform) });
			_root.transform.SetParent(parentTransform, false);
			_rootRect = (RectTransform)_root.transform;
			_rootRect.anchorMin = new Vector2(0f, 1f);
			_rootRect.anchorMax = new Vector2(0f, 1f);
			_rootRect.pivot = new Vector2(0f, 1f);
			_background = _root.AddComponent<Image>();
			((Graphic)_background).raycastTarget = false;
			VerticalLayoutGroup obj = _root.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((LayoutGroup)obj).padding = new RectOffset(10, 10, 6, 6);
			ContentSizeFitter obj2 = _root.AddComponent<ContentSizeFitter>();
			obj2.horizontalFit = (FitMode)2;
			obj2.verticalFit = (FitMode)2;
			_titleLabel = CreateLabel((Transform)(object)_rootRect, "TitleLabel");
			((TMP_Text)_titleLabel).fontStyle = (FontStyles)1;
			((TMP_Text)_titleLabel).text = "Plant Biome";
			_targetLabel = CreateLabel((Transform)(object)_rootRect, "TargetLabel");
			_standingLabel = CreateLabel((Transform)(object)_rootRect, "StandingLabel");
		}

		public void ApplySettings()
		{
			//IL_001a: 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_002e: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			_rootRect.anchoredPosition = new Vector2(ModConfig.HudOffsetX.Value, ModConfig.HudOffsetY.Value);
			Color value = ModConfig.HudBackgroundColor.Value;
			((Graphic)_background).color = value;
			((Behaviour)_background).enabled = value.a > 0.001f;
			float num = ModConfig.HudFontSize.Value;
			((TMP_Text)_titleLabel).fontSize = num * 0.75f;
			((TMP_Text)_targetLabel).fontSize = num;
			((TMP_Text)_standingLabel).fontSize = num;
			for (int i = 0; i < _biomeTextCache.Length; i++)
			{
				_biomeTextCache[i] = null;
			}
			_hasText = false;
		}

		public void SetBiomes(Biome targetBiome, Biome standingBiome)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			SetRow(_targetLabel, "Target: ", targetBiome, ref _shownTargetBiome);
			SetRow(_standingLabel, "Standing: ", standingBiome, ref _shownStandingBiome);
			_hasText = true;
		}

		public void SetActive(bool active)
		{
			if (_root.activeSelf != active)
			{
				_root.SetActive(active);
			}
		}

		public void Destroy()
		{
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
			}
		}

		private void SetRow(TextMeshProUGUI label, string prefix, Biome biome, ref Biome shownBiome)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if (!_hasText || (int)biome != (int)shownBiome)
			{
				shownBiome = (Biome)(int)biome;
				((TMP_Text)label).text = prefix + GetBiomeText(biome);
			}
		}

		private string GetBiomeText(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((int)biome == 0)
			{
				return "-";
			}
			int num = BiomeHelpers.ToIndex(biome);
			string text = _biomeTextCache[num];
			if (text != null)
			{
				return text;
			}
			string text2 = Localization.instance.Localize(BiomeSector.GetBiomeName(biome));
			string text3 = ColorUtility.ToHtmlStringRGB(ModConfig.GetBiomeColor(biome));
			string text4 = "<color=#" + text3 + ">" + text2 + "</color>";
			_biomeTextCache[num] = text4;
			return text4;
		}

		private static TextMeshProUGUI CreateLabel(Transform parentTransform, string objectName)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName, new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			val.transform.SetParent(parentTransform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)UnifiedPopup.instance) && Object.op_Implicit((Object)(object)UnifiedPopup.instance.bodyText))
			{
				((TMP_Text)val2).font = ((TMP_Text)UnifiedPopup.instance.bodyText).font;
				((TMP_Text)val2).fontSharedMaterial = ((TMP_Text)UnifiedPopup.instance.bodyText).fontSharedMaterial;
			}
			else
			{
				((TMP_Text)val2).font = GUIManager.Instance.TMP_AveriaSansLibre;
			}
			((Graphic)val2).color = Color.white;
			((TMP_Text)val2).richText = true;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).enableAutoSizing = false;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)257;
			val.SetActive(true);
			return val2;
		}
	}
}
namespace PlantBiomeHeeler.Core.State
{
	public static class OverlayVisibility
	{
		private const string CultivatorPieceTableName = "_CultivatorPieceTable";

		private static bool _isVisible;

		private static bool _isAutoShown;

		private static bool _wasCultivatorEquipped;

		private static int _cachedPieceTableId;

		private static bool _cachedIsCultivator;

		public static bool IsOverlayActive
		{
			get
			{
				if (_isVisible && ModConfig.EnableMod.Value)
				{
					return ModConfig.EnableOverlay.Value;
				}
				return false;
			}
		}

		public static bool IsHudVisible
		{
			get
			{
				bool flag = ModConfig.EnableMod.Value;
				if (flag)
				{
					flag = ModConfig.HudMode.Value switch
					{
						HudDisplayMode.Always => true, 
						HudDisplayMode.WithOverlay => IsOverlayActive, 
						_ => false, 
					};
				}
				return flag;
			}
		}

		public static void Update(Player player)
		{
			bool flag = IsCultivatorEquipped(player);
			if (flag != _wasCultivatorEquipped)
			{
				_wasCultivatorEquipped = flag;
				if (flag)
				{
					OnCultivatorEquipped();
				}
				else
				{
					OnCultivatorUnequipped();
				}
			}
			if (ZInput.GetButtonDown(ModInputManager.ToggleOverlayButton.Name))
			{
				_isVisible = !_isVisible;
				_isAutoShown = false;
			}
		}

		public static void Reset()
		{
			_isVisible = false;
			_isAutoShown = false;
			_wasCultivatorEquipped = false;
		}

		private static void OnCultivatorEquipped()
		{
			if (ModConfig.ShowOverlayWithCultivator.Value && !_isVisible)
			{
				_isVisible = true;
				_isAutoShown = true;
			}
		}

		private static void OnCultivatorUnequipped()
		{
			if (_isAutoShown)
			{
				_isVisible = false;
				_isAutoShown = false;
			}
		}

		private static bool IsCultivatorEquipped(Player player)
		{
			PieceTable buildPieces = player.m_buildPieces;
			if (!Object.op_Implicit((Object)(object)buildPieces))
			{
				return false;
			}
			int instanceID = ((Object)buildPieces).GetInstanceID();
			if (instanceID != _cachedPieceTableId)
			{
				_cachedPieceTableId = instanceID;
				_cachedIsCultivator = string.Equals(((Object)buildPieces).name, "_CultivatorPieceTable", StringComparison.Ordinal);
			}
			return _cachedIsCultivator;
		}
	}
}
namespace PlantBiomeHeeler.Core.Input
{
	public static class ModInputManager
	{
		public static ButtonConfig ToggleOverlayButton { get; private set; }

		public static void Initialize()
		{
			//IL_0000: 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_0010: 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_0022: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			ToggleOverlayButton = new ButtonConfig
			{
				Name = "ToggleOverlay",
				ShortcutConfig = ModConfig.ToggleOverlayKey,
				ActiveInGUI = false,
				ActiveInCustomGUI = false,
				BlockOtherInputs = false,
				HintToken = null
			};
			InputManager.Instance.AddButton("dreamwraith.PlantBiomeHeeler", ToggleOverlayButton);
		}
	}
}
namespace PlantBiomeHeeler.Configuration
{
	public enum HudDisplayMode
	{
		Always,
		WithOverlay,
		Disabled
	}
	public enum ModLogLevel
	{
		None,
		Info,
		Debug
	}
	public static class ModConfig
	{
		private const string GeneralSection = "General";

		private const string OverlaySection = "Overlay";

		private const string BiomeColorsSection = "Biome Colors";

		private const string HudSection = "HUD";

		private const string KeybindingsSection = "Keybindings";

		private static ConfigFile _configFile;

		public static ConfigEntry<bool> EnableMod { get; private set; }

		public static ConfigEntry<bool> EnableOverlay { get; private set; }

		public static ConfigEntry<bool> ShowOverlayWithCultivator { get; private set; }

		public static ConfigEntry<HudDisplayMode> HudMode { get; private set; }

		public static ConfigEntry<ModLogLevel> LoggingLevel { get; private set; }

		public static ConfigEntry<float> OverlayRadius { get; private set; }

		public static ConfigEntry<float> OverlayHeight { get; private set; }

		public static ConfigEntry<float> InteriorOpacity { get; private set; }

		public static ConfigEntry<float> BorderOpacity { get; private set; }

		public static ConfigEntry<float> BorderWidth { get; private set; }

		public static ConfigEntry<bool> EnableHatchLines { get; private set; }

		public static ConfigEntry<flo