Decompiled source of OHN0HoeLeveler v1.3.0

BepInEx/plugins/OHN0HoeLeveler/OHN0HoeLeveler.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("OHN0HoeLeveler")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OHN0HoeLeveler")]
[assembly: AssemblyTitle("OHN0HoeLeveler")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace OHN0HoeLeveler
{
	[BepInPlugin("ohn0.valheim.hoeleveler", "OHN0 Hoe Leveler", "1.3.0")]
	public sealed class HoeLevelerPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Menu), "Start")]
		private static class MenuStartPatch
		{
			private static void Postfix(Menu __instance)
			{
				EnsureEscMenuButton(__instance);
			}
		}

		[HarmonyPatch(typeof(Menu), "Show")]
		private static class MenuShowPatch
		{
			private static void Postfix(Menu __instance)
			{
				EnsureEscMenuButton(__instance);
			}
		}

		[HarmonyPatch(typeof(Menu), "Update")]
		private static class MenuUpdatePatch
		{
			private static void Postfix()
			{
				RefreshEscButtonLabel();
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		private static class PlayerPlacementGhostPatch
		{
			private static void Postfix(Player __instance)
			{
				Instance?.UpdateVanillaIndicatorScale(__instance);
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OpenFromEscMenu;
		}

		public const string PluginGuid = "ohn0.valheim.hoeleveler";

		public const string PluginName = "OHN0 Hoe Leveler";

		public const string PluginVersion = "1.3.0";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> LevelRadius;

		internal static ConfigEntry<float> OperationSpacing;

		internal static ConfigEntry<int> MaxExtraOperations;

		internal static ConfigEntry<bool> CircularFootprint;

		internal static ConfigEntry<string> LevelOperationNameContains;

		internal static ConfigEntry<bool> RequirePureLevelOperation;

		internal static ConfigEntry<bool> ShowHudMessage;

		internal static ConfigEntry<bool> ScaleVanillaIndicator;

		internal static ConfigEntry<bool> VerboseLogging;

		internal static ManualLogSource Log;

		internal static HoeLevelerPlugin Instance;

		private static Button LevelerButton;

		private static GameObject LevelerButtonObject;

		private static readonly FieldInfo ButtonOnClickField = typeof(Button).GetField("m_OnClick", BindingFlags.Instance | BindingFlags.NonPublic);

		private Harmony _harmony;

		private Rect _windowRect = new Rect(150f, 90f, 560f, 455f);

		private Vector2 _windowScroll;

		private bool _showWindow;

		private string _status = "Open from the ESC menu.";

		private GUIStyle _wrapLabel;

		private GUIStyle _headerLabel;

		private GUIStyle _mutedLabel;

		private GUIStyle _windowStyle;

		private GUIStyle _buttonStyle;

		private GUIStyle _closeButtonStyle;

		private GUIStyle _panelStyle;

		private GameObject _scaledMarker;

		private Vector3 _scaledMarkerOriginalScale = Vector3.one;

		private GameObject _scaledGhost;

		private Vector3 _scaledGhostOriginalScale = Vector3.one;

		private Texture2D _windowTexture;

		private Texture2D _panelTexture;

		private Texture2D _buttonTexture;

		private Texture2D _buttonHoverTexture;

		private Texture2D _buttonActiveTexture;

		private static readonly Color ParchmentText = new Color(0.93f, 0.86f, 0.68f, 1f);

		private static readonly Color MutedText = new Color(0.73f, 0.67f, 0.52f, 1f);

		private static readonly Color AmberText = new Color(1f, 0.62f, 0.22f, 1f);

		private static readonly Color DarkIron = new Color(0.045f, 0.055f, 0.045f, 0.98f);

		private static readonly Color DarkWood = new Color(0.12f, 0.09f, 0.055f, 0.96f);

		private static readonly Color ButtonWood = new Color(0.22f, 0.16f, 0.095f, 1f);

		private static readonly Color ButtonWoodHover = new Color(0.34f, 0.24f, 0.12f, 1f);

		private static readonly Color ButtonWoodActive = new Color(0.46f, 0.29f, 0.11f, 1f);

		private void Awake()
		{
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", false, "Enable wide hoe leveling.");
			LevelRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Leveling", "Level radius", 8f, "Outer radius in meters for the leveled footprint. Leveling uses the ground height where the local player is standing.");
			OperationSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Leveling", "Operation spacing", 0f, "Distance in meters between replayed vanilla level operations. Set to 0 to auto-pick from the vanilla hoe radius.");
			MaxExtraOperations = ((BaseUnityPlugin)this).Config.Bind<int>("Leveling", "Max extra operations", 64, "Safety cap for extra vanilla level operations sent per hoe use.");
			CircularFootprint = ((BaseUnityPlugin)this).Config.Bind<bool>("Leveling", "Circular footprint", true, "Use a circular footprint. Disable for a square grid.");
			LevelOperationNameContains = ((BaseUnityPlugin)this).Config.Bind<string>("Detection", "Level operation name contains", "level,flatten", "Comma-separated prefab-name fragments that identify the hoe level-ground operation.");
			RequirePureLevelOperation = ((BaseUnityPlugin)this).Config.Bind<bool>("Detection", "Require pure level operation", true, "Only widen terrain ops that level ground without also raising or smoothing.");
			ShowHudMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "Show HUD message", false, "Show a small in-game message with the number of extra level operations used.");
			ScaleVanillaIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Feedback", "Scale vanilla indicator", true, "Scale Valheim's normal hoe placement indicator to the configured level radius while edited leveling is enabled.");
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose logging", false, "Log each widened hoe level operation.");
			_harmony = new Harmony("ohn0.valheim.hoeleveler");
			_harmony.PatchAll();
			Log.LogInfo((object)string.Format("{0} {1} loaded. Level radius={2:0.##}m, max extra operations={3}.", "OHN0 Hoe Leveler", "1.3.0", LevelRadius.Value, MaxExtraOperations.Value));
		}

		private void Update()
		{
			if (_showWindow && ((Object)(object)Menu.instance == (Object)null || !Menu.IsVisible()))
			{
				_showWindow = false;
			}
			if (_showWindow)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
			RefreshEscButtonLabel();
		}

		private void OnGUI()
		{
			//IL_0087: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_003b: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!_showWindow)
			{
				return;
			}
			EnsureStyles();
			GUISkin skin = GUI.skin;
			Color color = GUI.color;
			Color contentColor = GUI.contentColor;
			Color backgroundColor = GUI.backgroundColor;
			try
			{
				GUI.color = Color.white;
				GUI.contentColor = ParchmentText;
				GUI.backgroundColor = Color.white;
				GUI.depth = -21;
				_windowRect = GUILayout.Window(((Object)this).GetInstanceID(), _windowRect, new WindowFunction(DrawWindow), "OHN0 HOE LEVELER", _windowStyle, Array.Empty<GUILayoutOption>());
			}
			finally
			{
				GUI.skin = skin;
				GUI.color = color;
				GUI.contentColor = contentColor;
				GUI.backgroundColor = backgroundColor;
			}
		}

		private void DrawWindow(int id)
		{
			//IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("OHN0 Hoe Leveler", _headerLabel, Array.Empty<GUILayoutOption>());
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("Close", _closeButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(90f),
					GUILayout.Height(28f)
				}))
				{
					_showWindow = false;
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(6f);
				GUILayout.BeginVertical(_panelStyle, Array.Empty<GUILayoutOption>());
				_windowScroll = GUILayout.BeginScrollView(_windowScroll, Array.Empty<GUILayoutOption>());
				DrawSettingsControls();
				GUILayout.EndScrollView();
				GUILayout.EndVertical();
				GUILayout.Space(8f);
				GUILayout.Label(_status, _mutedLabel, Array.Empty<GUILayoutOption>());
			}
			catch (Exception ex)
			{
				_status = "Hoe menu error: " + ex.GetBaseException().Message;
				Log.LogError((object)ex);
				GUILayout.Label(_status, _wrapLabel, Array.Empty<GUILayoutOption>());
			}
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void DrawSettingsControls()
		{
			bool value = Enabled.Value;
			float value2 = LevelRadius.Value;
			int value3 = MaxExtraOperations.Value;
			bool value4 = CircularFootprint.Value;
			float currentStandingHeight = HoeLevelerApi.CurrentStandingHeight;
			GUILayout.Label("Target Height", _headerLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Edited leveling uses the ground height where your local player is standing.", _wrapLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Label("When enabled, Valheim's normal hoe placement indicator is scaled to the selected radius.", _wrapLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Label(float.IsNaN(currentStandingHeight) ? "Current standing height: load into a world with your character active." : $"Current standing height: {currentStandingHeight:0.00}", _mutedLabel, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(value ? "Disable Edited Leveling" : "Enable Edited Leveling", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(220f),
				GUILayout.Height(30f)
			}))
			{
				Enabled.Value = !value;
				((BaseUnityPlugin)this).Config.Save();
				value = Enabled.Value;
				_status = (value ? "Edited hoe leveling is on." : "Edited hoe leveling is off.");
			}
			GUILayout.Label(value ? "Edited leveling is on." : "Edited leveling is off.", value ? _headerLabel : _mutedLabel, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			GUILayout.Label("Level Radius", _headerLabel, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"{value2:0.0} m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(72f) });
			if (GUILayout.Button("-1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) }))
			{
				SetRadius(value2 - 1f);
				value2 = LevelRadius.Value;
			}
			float num = Mathf.Round(GUILayout.HorizontalSlider(value2, 1f, 30f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(260f) }) * 10f) / 10f;
			if (Mathf.Abs(num - value2) >= 0.1f)
			{
				SetRadius(num);
				value2 = LevelRadius.Value;
			}
			if (GUILayout.Button("+1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) }))
			{
				SetRadius(value2 + 1f);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("6m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
			{
				SetRadius(6f);
			}
			if (GUILayout.Button("8m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
			{
				SetRadius(8f);
			}
			if (GUILayout.Button("12m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
			{
				SetRadius(12f);
			}
			if (GUILayout.Button("16m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
			{
				SetRadius(16f);
			}
			if (GUILayout.Button("24m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
			{
				SetRadius(24f);
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			GUILayout.Label("Coverage", _headerLabel, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(value4 ? "Footprint: Circular" : "Footprint: Square", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(190f),
				GUILayout.Height(28f)
			}))
			{
				CircularFootprint.Value = !value4;
				((BaseUnityPlugin)this).Config.Save();
				_status = (CircularFootprint.Value ? "Hoe leveling footprint set to circular." : "Hoe leveling footprint set to square.");
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Extra passes {value3}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) });
			int num2 = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)value3, 8f, 160f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(260f) }) / 4f) * 4;
			if (num2 != value3)
			{
				MaxExtraOperations.Value = Mathf.Clamp(num2, 0, 256);
				((BaseUnityPlugin)this).Config.Save();
				_status = $"Hoe extra-pass cap set to {MaxExtraOperations.Value}.";
			}
			GUILayout.EndHorizontal();
		}

		private void SetRadius(float radius)
		{
			LevelRadius.Value = Mathf.Clamp(radius, 1f, 50f);
			((BaseUnityPlugin)this).Config.Save();
			_status = $"Hoe level radius set to {LevelRadius.Value:0.0}m.";
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)LevelerButtonObject != (Object)null)
			{
				Object.Destroy((Object)(object)LevelerButtonObject);
				LevelerButtonObject = null;
				LevelerButton = null;
			}
			RestoreScaledIndicators();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void EnsureStyles()
		{
			//IL_000a: 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_002a: 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_004a: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//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_00d4: 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_00e3: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			//IL_025d: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Expected O, but got Unknown
			//IL_02b5: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Expected O, but got Unknown
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Expected O, but got Unknown
			//IL_0389: Expected O, but got Unknown
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Expected O, but got Unknown
			if (_wrapLabel == null)
			{
				_windowTexture = CreateTexture(DarkIron);
				_panelTexture = CreateTexture(DarkWood);
				_buttonTexture = CreateTexture(ButtonWood);
				_buttonHoverTexture = CreateTexture(ButtonWoodHover);
				_buttonActiveTexture = CreateTexture(ButtonWoodActive);
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					fontSize = 14
				};
				val.normal.textColor = ParchmentText;
				val.hover.textColor = ParchmentText;
				val.active.textColor = ParchmentText;
				val.focused.textColor = ParchmentText;
				_wrapLabel = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontStyle = (FontStyle)1,
					wordWrap = true,
					fontSize = 15
				};
				val2.normal.textColor = AmberText;
				val2.hover.textColor = AmberText;
				val2.active.textColor = AmberText;
				val2.focused.textColor = AmberText;
				_headerLabel = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					fontSize = 13
				};
				val3.normal.textColor = MutedText;
				val3.hover.textColor = MutedText;
				val3.active.textColor = MutedText;
				val3.focused.textColor = MutedText;
				_mutedLabel = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.window);
				val4.normal.background = _windowTexture;
				val4.normal.textColor = AmberText;
				val4.hover.background = _windowTexture;
				val4.hover.textColor = AmberText;
				val4.focused.background = _windowTexture;
				val4.focused.textColor = AmberText;
				val4.active.background = _windowTexture;
				val4.active.textColor = AmberText;
				val4.fontSize = 14;
				val4.fontStyle = (FontStyle)1;
				val4.alignment = (TextAnchor)1;
				val4.padding = new RectOffset(12, 12, 28, 12);
				val4.margin = new RectOffset(6, 6, 6, 6);
				_windowStyle = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.box);
				val5.normal.background = _panelTexture;
				val5.normal.textColor = ParchmentText;
				val5.padding = new RectOffset(10, 10, 10, 10);
				val5.margin = new RectOffset(2, 2, 2, 2);
				_panelStyle = val5;
				GUIStyle val6 = new GUIStyle(GUI.skin.button);
				val6.normal.background = _buttonTexture;
				val6.normal.textColor = ParchmentText;
				val6.hover.background = _buttonHoverTexture;
				val6.hover.textColor = Color.white;
				val6.active.background = _buttonActiveTexture;
				val6.active.textColor = Color.white;
				val6.focused.background = _buttonHoverTexture;
				val6.focused.textColor = Color.white;
				val6.alignment = (TextAnchor)4;
				val6.fontSize = 13;
				val6.fontStyle = (FontStyle)1;
				val6.wordWrap = false;
				val6.padding = new RectOffset(8, 8, 5, 5);
				val6.margin = new RectOffset(2, 2, 2, 2);
				_buttonStyle = val6;
				_closeButtonStyle = new GUIStyle(_buttonStyle);
			}
		}

		private static Texture2D CreateTexture(Color color)
		{
			//IL_0004: 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_0011: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private static void OpenFromEscMenu()
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance._showWindow = true;
				Instance._status = "Opened from the ESC menu.";
			}
		}

		private static void EnsureEscMenuButton(Menu menu)
		{
			//IL_010e: 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_0119: Expected O, but got Unknown
			if ((Object)(object)menu == (Object)null || (Object)(object)Instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)LevelerButton != (Object)null && (Object)(object)LevelerButtonObject != (Object)null)
			{
				RefreshEscButtonLabel();
				return;
			}
			Button val = (((Object)(object)menu.m_settingsButton != (Object)null) ? menu.m_settingsButton : (((Object)(object)menu.m_logoutButton != (Object)null) ? menu.m_logoutButton : menu.m_continueButton));
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null) && !((Object)(object)((Component)val).transform.parent == (Object)null))
			{
				LevelerButtonObject = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
				((Object)LevelerButtonObject).name = "OHN0HoeLevelerButton";
				LevelerButton = LevelerButtonObject.GetComponent<Button>();
				if ((Object)(object)LevelerButton == (Object)null)
				{
					LevelerButton = LevelerButtonObject.AddComponent<Button>();
				}
				ReplaceButtonClickEvent(LevelerButton);
				ButtonClickedEvent onClick = LevelerButton.onClick;
				object obj = <>O.<0>__OpenFromEscMenu;
				if (obj == null)
				{
					UnityAction val2 = OpenFromEscMenu;
					<>O.<0>__OpenFromEscMenu = val2;
					obj = (object)val2;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
				((Selectable)LevelerButton).interactable = true;
				RefreshEscButtonLabel();
				if ((Object)(object)menu.m_settingsButton != (Object)null)
				{
					LevelerButtonObject.transform.SetSiblingIndex(((Component)menu.m_settingsButton).transform.GetSiblingIndex());
				}
				LevelerButtonObject.SetActive(((Component)val).gameObject.activeSelf);
				if ((Object)(object)menu.menuEntriesParent != (Object)null)
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(menu.menuEntriesParent);
				}
			}
		}

		private static void ReplaceButtonClickEvent(Button button)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if (!((Object)(object)button == (Object)null))
			{
				ButtonClickedEvent value = new ButtonClickedEvent();
				if (ButtonOnClickField != null)
				{
					ButtonOnClickField.SetValue(button, value);
				}
				else
				{
					((UnityEventBase)button.onClick).RemoveAllListeners();
				}
			}
		}

		private static void RefreshEscButtonLabel()
		{
			if (!((Object)(object)LevelerButtonObject == (Object)null))
			{
				TMP_Text componentInChildren = LevelerButtonObject.GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.text = "OHN0 Hoe Leveler";
				}
				Text componentInChildren2 = LevelerButtonObject.GetComponentInChildren<Text>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren2.text = "OHN0 Hoe Leveler";
				}
			}
		}

		internal void UpdateVanillaIndicatorScale(Player player)
		{
			if (!Enabled.Value || !ScaleVanillaIndicator.Value || (Object)(object)player == (Object)null)
			{
				RestoreScaledIndicators();
				return;
			}
			TerrainOp selectedTerrainOp = GetSelectedTerrainOp(player);
			if ((Object)(object)selectedTerrainOp == (Object)null || !TerrainOpAwakePatch.IsWideLevelCandidate(selectedTerrainOp, selectedTerrainOp.m_settings))
			{
				RestoreScaledIndicators();
				return;
			}
			float num = Mathf.Max(0.1f, selectedTerrainOp.GetRadius());
			float scaleFactor = Mathf.Max(1f, LevelRadius.Value / num);
			GameObject placementMarker = PlacementGhostAccess.GetPlacementMarker(player);
			GameObject placementGhost = PlacementGhostAccess.GetPlacementGhost(player);
			ScaleMarker(placementMarker, scaleFactor);
			ScaleGhostIfSafe(placementGhost, scaleFactor);
		}

		private static TerrainOp GetSelectedTerrainOp(Player player)
		{
			PieceTable val = (((Object)(object)player != (Object)null) ? player.GetBuildTool() : null);
			GameObject val2 = (((Object)(object)val != (Object)null) ? val.GetSelectedPrefab() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.GetComponent<TerrainOp>();
		}

		private void ScaleMarker(GameObject marker, float scaleFactor)
		{
			//IL_0043: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)marker == (Object)null)
			{
				RestoreMarkerScale();
				return;
			}
			if ((Object)(object)_scaledMarker != (Object)(object)marker)
			{
				RestoreMarkerScale();
				_scaledMarker = marker;
				_scaledMarkerOriginalScale = marker.transform.localScale;
			}
			marker.transform.localScale = _scaledMarkerOriginalScale * scaleFactor;
		}

		private void ScaleGhostIfSafe(GameObject ghost, float scaleFactor)
		{
			//IL_005b: 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_004a: 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)
			if ((Object)(object)ghost == (Object)null || (Object)(object)ghost.GetComponent<TerrainOp>() == (Object)null || ghost.GetComponentsInChildren<Collider>(true).Length != 0)
			{
				RestoreGhostScale();
				return;
			}
			if ((Object)(object)_scaledGhost != (Object)(object)ghost)
			{
				RestoreGhostScale();
				_scaledGhost = ghost;
				_scaledGhostOriginalScale = ghost.transform.localScale;
			}
			ghost.transform.localScale = _scaledGhostOriginalScale * scaleFactor;
		}

		private void RestoreScaledIndicators()
		{
			RestoreMarkerScale();
			RestoreGhostScale();
		}

		private void RestoreMarkerScale()
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_scaledMarker != (Object)null)
			{
				_scaledMarker.transform.localScale = _scaledMarkerOriginalScale;
			}
			_scaledMarker = null;
			_scaledMarkerOriginalScale = Vector3.one;
		}

		private void RestoreGhostScale()
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_scaledGhost != (Object)null)
			{
				_scaledGhost.transform.localScale = _scaledGhostOriginalScale;
			}
			_scaledGhost = null;
			_scaledGhostOriginalScale = Vector3.one;
		}
	}
	internal static class PlacementGhostAccess
	{
		private static readonly FieldRef<Player, GameObject> PlacementGhostRef = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

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

		public static GameObject GetPlacementGhost(Player player)
		{
			if (!((Object)(object)player != (Object)null))
			{
				return null;
			}
			return PlacementGhostRef.Invoke(player);
		}

		public static GameObject GetPlacementMarker(Player player)
		{
			if (!((Object)(object)player != (Object)null))
			{
				return null;
			}
			return PlacementMarkerRef.Invoke(player);
		}
	}
	public static class HoeLevelerApi
	{
		public static bool IsLoaded => (Object)(object)HoeLevelerPlugin.Instance != (Object)null;

		public static bool Enabled
		{
			get
			{
				return HoeLevelerPlugin.Enabled?.Value ?? false;
			}
			set
			{
				if (HoeLevelerPlugin.Enabled != null)
				{
					HoeLevelerPlugin.Enabled.Value = value;
					Save();
				}
			}
		}

		public static float LevelRadius
		{
			get
			{
				return HoeLevelerPlugin.LevelRadius?.Value ?? 8f;
			}
			set
			{
				if (HoeLevelerPlugin.LevelRadius != null)
				{
					HoeLevelerPlugin.LevelRadius.Value = Mathf.Clamp(value, 1f, 50f);
					Save();
				}
			}
		}

		public static int MaxExtraOperations
		{
			get
			{
				return HoeLevelerPlugin.MaxExtraOperations?.Value ?? 64;
			}
			set
			{
				if (HoeLevelerPlugin.MaxExtraOperations != null)
				{
					HoeLevelerPlugin.MaxExtraOperations.Value = Mathf.Clamp(value, 0, 256);
					Save();
				}
			}
		}

		public static bool CircularFootprint
		{
			get
			{
				return HoeLevelerPlugin.CircularFootprint?.Value ?? true;
			}
			set
			{
				if (HoeLevelerPlugin.CircularFootprint != null)
				{
					HoeLevelerPlugin.CircularFootprint.Value = value;
					Save();
				}
			}
		}

		public static float CurrentStandingHeight
		{
			get
			{
				if (!TerrainOpAwakePatch.TryGetStandingLevelHeight(out var height))
				{
					return float.NaN;
				}
				return height;
			}
		}

		public static string TargetHeightMode => "Player standing ground height";

		private static void Save()
		{
			HoeLevelerPlugin instance = HoeLevelerPlugin.Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Config.Save();
			}
		}
	}
	[HarmonyPatch(typeof(TerrainOp), "Awake")]
	internal static class TerrainOpAwakePatch
	{
		private static bool _replaying;

		private static void Prefix(TerrainOp __instance)
		{
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			if (_replaying || (Object)(object)__instance == (Object)null || !HoeLevelerPlugin.Enabled.Value || TerrainOp.m_forceDisableTerrainOps)
			{
				return;
			}
			Settings settings = __instance.m_settings;
			if (!IsWideLevelCandidate(__instance, settings) || !TryGetStandingLevelHeight(out var height))
			{
				return;
			}
			float num = Mathf.Max(0.1f, __instance.GetRadius());
			float num2 = Mathf.Max(num, HoeLevelerPlugin.LevelRadius.Value);
			float num3 = Mathf.Max(0f, num2 - num);
			if (num3 < 0.1f)
			{
				return;
			}
			float num4 = HoeLevelerPlugin.OperationSpacing.Value;
			if (num4 <= 0f)
			{
				num4 = Mathf.Clamp(num * 0.8f, 0.75f, 2.5f);
			}
			num4 = Mathf.Clamp(num4, 0.5f, num2);
			List<Vector3> list = BuildOffsets(num3, num4, HoeLevelerPlugin.CircularFootprint.Value, Mathf.Max(0, HoeLevelerPlugin.MaxExtraOperations.Value));
			if (list.Count == 0)
			{
				return;
			}
			Vector3 position = ((Component)__instance).transform.position;
			position.y = height;
			string prefabName = GetPrefabName(__instance);
			int num5 = 0;
			try
			{
				_replaying = true;
				foreach (Vector3 item in list)
				{
					Vector3 val = position + item;
					val.y = height;
					((Component)__instance).transform.position = val;
					List<Heightmap> list2 = new List<Heightmap>();
					Heightmap.FindHeightmap(val, num, list2);
					foreach (Heightmap item2 in list2)
					{
						TerrainComp val2 = (((Object)(object)item2 != (Object)null) ? item2.GetAndCreateTerrainCompiler() : null);
						if (!((Object)(object)val2 == (Object)null))
						{
							val2.ApplyOperation(__instance);
							num5++;
						}
					}
				}
			}
			catch (Exception arg)
			{
				HoeLevelerPlugin.Log.LogWarning((object)$"Wide hoe leveling failed for '{prefabName}': {arg}");
			}
			finally
			{
				((Component)__instance).transform.position = position;
				_replaying = false;
			}
			if (num5 > 0)
			{
				if (HoeLevelerPlugin.VerboseLogging.Value)
				{
					HoeLevelerPlugin.Log.LogInfo((object)$"Widened '{prefabName}' with {num5} extra terrain-comp operation(s). Vanilla center operation will still run.");
				}
				if (HoeLevelerPlugin.ShowHudMessage.Value && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					((Character)Player.m_localPlayer).Message((MessageType)1, $"Wide level: {num5 + 1} passes", 0, (Sprite)null, false);
				}
			}
		}

		internal static bool TryGetStandingLevelHeight(out float height)
		{
			//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_0041: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				height = 0f;
				return false;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(position, ref height))
			{
				return true;
			}
			if (Heightmap.GetHeight(position, ref height))
			{
				return true;
			}
			height = position.y;
			return true;
		}

		internal static bool IsWideLevelCandidate(TerrainOp op, Settings settings)
		{
			if (settings == null || !settings.m_level)
			{
				return false;
			}
			if (HoeLevelerPlugin.RequirePureLevelOperation.Value && (settings.m_raise || settings.m_smooth))
			{
				return false;
			}
			string name = GetPrefabName(op);
			string[] array = (from token in (HoeLevelerPlugin.LevelOperationNameContains.Value ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select token.Trim() into token
				where token.Length > 0
				select token).ToArray();
			if (array.Length == 0)
			{
				return true;
			}
			return array.Any((string token) => name.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0);
		}

		private static List<Vector3> BuildOffsets(float centerRadius, float spacing, bool circular, int maxExtraOperations)
		{
			if (maxExtraOperations <= 0)
			{
				return new List<Vector3>();
			}
			List<Vector3> list;
			do
			{
				list = BuildOffsetsUncapped(centerRadius, spacing, circular);
				if (list.Count <= maxExtraOperations)
				{
					break;
				}
				spacing *= 1.2f;
			}
			while (spacing <= centerRadius * 2f && centerRadius > 0f);
			return list.OrderBy((Vector3 offset) => ((Vector3)(ref offset)).sqrMagnitude).Take(maxExtraOperations).ToList();
		}

		private static List<Vector3> BuildOffsetsUncapped(float centerRadius, float spacing, bool circular)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			int num = Mathf.CeilToInt(centerRadius / spacing);
			float num2 = centerRadius * centerRadius;
			for (int i = -num; i <= num; i++)
			{
				for (int j = -num; j <= num; j++)
				{
					if (j != 0 || i != 0)
					{
						float num3 = (float)j * spacing;
						float num4 = (float)i * spacing;
						float num5 = num3 * num3 + num4 * num4;
						if ((!circular || !(num5 > num2)) && (circular || (!(Mathf.Abs(num3) > centerRadius) && !(Mathf.Abs(num4) > centerRadius))))
						{
							list.Add(new Vector3(num3, 0f, num4));
						}
					}
				}
			}
			return list;
		}

		private static string GetPrefabName(TerrainOp op)
		{
			if ((Object)(object)op == (Object)null || (Object)(object)((Component)op).gameObject == (Object)null)
			{
				return "";
			}
			try
			{
				return Utils.GetPrefabName(((Object)((Component)op).gameObject).name);
			}
			catch
			{
				return ((Object)((Component)op).gameObject).name.Replace("(Clone)", "").Trim();
			}
		}
	}
}