Decompiled source of CropUtils v2.1.0

Crop_Utils.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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 Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Crop_Utils")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod for helping with farming and gathering")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+c02fa2c332d8681524545b7b4b6250fec6530336")]
[assembly: AssemblyProduct("Crop_Utils")]
[assembly: AssemblyTitle("Crop_Utils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Crop_Utils
{
	[BepInPlugin("com.nopetrides.valheim.crop-utils", "Crop Utils", "2.1.0")]
	[BepInProcess("valheim.exe")]
	internal class CropUtils : BaseUnityPlugin
	{
		public static CropUtils Instance;

		public const string PluginGUID = "com.nopetrides.valheim.crop-utils";

		public const string PluginName = "Crop Utils";

		public const string PluginVersion = "2.1.0";

		public const string VALHEIM_EXE_NAME = "valheim.exe";

		internal const string LoggerName = "CropUtilsLog";

		private ConfigEntry<int> m_utilRange;

		private ConfigEntry<int> m_cropUtilDiscount;

		private ConfigEntry<bool> m_showVisualRangeIndicator;

		private ConfigEntry<KeyboardShortcut> m_increaseRangeControllerButton;

		private ConfigEntry<KeyboardShortcut> m_increaseRangeHotKey;

		private ConfigEntry<KeyboardShortcut> m_decreaseRangeControllerButton;

		private ConfigEntry<KeyboardShortcut> m_decreaseRangeHotKey;

		private ConfigEntry<KeyboardShortcut> m_utilControllerButton;

		private ConfigEntry<KeyboardShortcut> m_utilHotKey;

		private ConfigEntry<KeyboardShortcut> m_utilAltControllerButton;

		private ConfigEntry<KeyboardShortcut> m_utilAltHotKey;

		private ConfigEntry<bool> m_allowPlantAnything;

		private ConfigEntry<bool> m_alwaysUseCustomSpacing;

		private ConfigEntry<float> m_manualCropSpacing;

		private ConfigEntry<float> m_growRadiusSpacingMultiplier;

		private ConfigEntry<KeyboardShortcut> m_increaseSpacingHotKey;

		private ConfigEntry<KeyboardShortcut> m_decreaseSpacingHotKey;

		internal static ManualLogSource Log;

		public int UtilRange => m_utilRange.Value;

		public int Discount => m_cropUtilDiscount.Value;

		public bool ShowVisualRangeIndicator => m_showVisualRangeIndicator.Value;

		public KeyboardShortcut IncreaseRangeControllerButton => m_increaseRangeControllerButton.Value;

		public KeyboardShortcut IncreaseRangeHotKey => m_increaseRangeHotKey.Value;

		public KeyboardShortcut DecreaseRangeControllerButton => m_decreaseRangeControllerButton.Value;

		public KeyboardShortcut DecreaseRangeHotKey => m_decreaseRangeHotKey.Value;

		public KeyboardShortcut UtilControllerButton => m_utilControllerButton.Value;

		public KeyboardShortcut UtilHotKey => m_utilHotKey.Value;

		public KeyboardShortcut UtilAltControllerButton => m_utilAltControllerButton.Value;

		public KeyboardShortcut UtilAltHotKey => m_utilAltHotKey.Value;

		public bool AllowPlantAnything => m_allowPlantAnything.Value;

		public bool AlwaysUseCustomSpacing => m_alwaysUseCustomSpacing.Value;

		public float CustomSpacing => m_manualCropSpacing.Value;

		public float GrowRadiusSpacingMultiplier => m_growRadiusSpacingMultiplier.Value;

		public KeyboardShortcut IncreaseSpacingHotKey => m_increaseSpacingHotKey.Value;

		public KeyboardShortcut DecreaseSpacingHotKey => m_decreaseSpacingHotKey.Value;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Log = new ManualLogSource("CropUtilsLog");
			Logger.Sources.Add((ILogSource)(object)Log);
			Log.LogInfo((object)"CropUtils startup sequence");
			CreateConfigs();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Log.LogInfo((object)"CropUtils successfully patched in");
		}

		private void CreateConfigs()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0088: 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_00a2: Expected O, but got Unknown
			//IL_00c0: 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_00da: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Expected O, but got Unknown
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Expected O, but got Unknown
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Expected O, but got Unknown
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			m_utilRange = ((BaseUnityPlugin)this).Config.Bind<int>("Util Range", "UtilRangeConfig", 20, new ConfigDescription("The distance (in Unity Units) to perform operations out to. Larger numbers may hinder performance.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			m_showVisualRangeIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Util Range", "ShouldShowRangeIndicator", true, new ConfigDescription("Should the range be shown when holding down the util key", (AcceptableValueBase)null, Array.Empty<object>()));
			m_increaseRangeControllerButton = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Range", "Increase Range Key Gamepad", new KeyboardShortcut((KeyCode)337, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Gamepad button to increase the range of picking while holding the Utility Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_increaseRangeHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Increase Range Hot Key", new KeyboardShortcut((KeyCode)93, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to increase the range of picking while holding the Utility Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_decreaseRangeControllerButton = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Range", "Decrease Range Key Gamepad", new KeyboardShortcut((KeyCode)336, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Gamepad button to decrease the range of picking while holding the Utility Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_decreaseRangeHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Decrease Range Hot Key", new KeyboardShortcut((KeyCode)91, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to decrease the range of picking while holding the Utility Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_utilControllerButton = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Utility Key Gamepad", new KeyboardShortcut((KeyCode)335, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Button to enable farming utility helpers when planting or picking. Default behavior is pickup only this type and place in a line", (AcceptableValueBase)null, Array.Empty<object>()));
			m_utilHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Utility Hot Key", new KeyboardShortcut((KeyCode)308, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to enable farming utility helpers when planting or picking. Default behavior is pickup only this type and place in a line", (AcceptableValueBase)null, Array.Empty<object>()));
			m_utilAltControllerButton = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Ignore Type Key Gamepad", new KeyboardShortcut((KeyCode)334, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Button to enable farming utility helpers when planting or picking. Should pick any type of crop or use the radius placement for crops.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_utilAltHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Util Keys", "Utility Alternative Hot Key", new KeyboardShortcut((KeyCode)122, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to enable farming utility helpers when planting or picking. Should pick any type of crop or use the radius placement for crops.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_cropUtilDiscount = ((BaseUnityPlugin)this).Config.Bind<int>("Stamina & Tool Durability Discount", "StaminaDiscountConfig", 20, new ConfigDescription("Divides stamina and tool durability costs while using CropUtils (default: 20). Valheim does not currently treat this discount as a cheat for achievements. Achievement eligibility is controlled by Valheim and may change in future updates.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_allowPlantAnything = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod Compatibility Mode", "IgnorePlantTypeRestriction", false, new ConfigDescription("Should the tool respect default Valheim plantable types, or try to plant anything? Set to true if using another plantable mod. Compatibility is not guaranteed.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_alwaysUseCustomSpacing = ((BaseUnityPlugin)this).Config.Bind<bool>("Custom Crop Spacing", "CustomSpacingOnly", false, new ConfigDescription("Should the tool ignore crop growth radius and just use the custom spacing.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_manualCropSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Crop Spacing", "CustomCropSpacingDistance", 0.5f, new ConfigDescription("The distance (in Unity Units) to space plantables. Normal crops are 0.5, trees are 2.0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			m_growRadiusSpacingMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Custom Crop Spacing", "GrowRadiusSpacingMultiplier", 1f, new ConfigDescription("How far apart to space the pattern, as a multiple of the plant's grow radius. Valheim only needs slightly more than one radius between plants, so values under 2.0 pack tighter than older versions of this mod. If set too low for a given crop the grow space check rejects the tight positions, so you get fewer plants rather than unhealthy ones.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), Array.Empty<object>()));
			m_increaseSpacingHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Custom Crop Spacing", "Increase Spacing Hot Key", new KeyboardShortcut((KeyCode)61, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to increase the spacing between plants while using the cultivator.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_decreaseSpacingHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Custom Crop Spacing", "Decrease Spacing Hot Key", new KeyboardShortcut((KeyCode)45, (KeyCode[])(object)new KeyCode[0]), new ConfigDescription("Key to decrease the spacing between plants while using the cultivator.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public void ChangeRange(int rangeChange)
		{
			ConfigEntry<int> utilRange = m_utilRange;
			utilRange.Value += rangeChange;
			Log.LogInfo((object)$"Range is now {m_utilRange.Value}");
		}

		public void ChangeSpacing(float spacingChange)
		{
			ConfigEntry<float> manualCropSpacing = m_manualCropSpacing;
			manualCropSpacing.Value += spacingChange;
			Log.LogInfo((object)$"Spacing is now {m_manualCropSpacing.Value}");
		}
	}
	[HarmonyPatch]
	public static class PickCropsUtil
	{
		private static FieldInfo m_interactMaskField = AccessTools.Field(typeof(Player), "m_interactMask");

		private static MethodInfo m_extractMethod = AccessTools.Method(typeof(Beehive), "Extract", (Type[])null, (Type[])null);

		[HarmonyPatch(typeof(Player), "Interact")]
		public static void Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0038: 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)
			if (((Character)__instance).InAttack() || ((Character)__instance).InDodge() || hold)
			{
				return;
			}
			KeyboardShortcut val = CropUtils.Instance.UtilControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.UtilHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					return;
				}
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			PickableCheck(__instance, go, alt, componentInParent);
			BeehiveCheck(__instance, go, alt, componentInParent);
		}

		private static void PickableCheck(Player __instance, GameObject go, bool alt, Interactable ComponentInParent)
		{
			//IL_0024: 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_00b3: 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_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_00d1: Unknown result type (might be due to invalid IL or missing references)
			Pickable val = (Pickable)(object)((ComponentInParent is Pickable) ? ComponentInParent : null);
			if (val == null)
			{
				return;
			}
			int num = (int)m_interactMaskField.GetValue(__instance);
			Collider[] array = Physics.OverlapSphere(go.transform.position, (float)(CropUtils.Instance.UtilRange / 2), num);
			foreach (Collider val2 in array)
			{
				Pickable val3;
				if ((Object)(object)val2 == (Object)null)
				{
					val3 = null;
				}
				else
				{
					GameObject gameObject = ((Component)val2).gameObject;
					val3 = (((Object)(object)gameObject != (Object)null) ? gameObject.GetComponentInParent<Pickable>() : null);
				}
				if (!((Object)(object)val3 != (Object)null) || !((Object)(object)val3 != (Object)(object)val))
				{
					continue;
				}
				if (!(((Object)val3.m_itemPrefab).name == ((Object)val.m_itemPrefab).name))
				{
					KeyboardShortcut val4 = CropUtils.Instance.UtilControllerButton;
					if (!Input.GetKey(((KeyboardShortcut)(ref val4)).MainKey))
					{
						val4 = CropUtils.Instance.UtilHotKey;
						if (!Input.GetKey(((KeyboardShortcut)(ref val4)).MainKey))
						{
							continue;
						}
					}
				}
				val3.Interact((Humanoid)(object)__instance, false, alt);
			}
		}

		private static void BeehiveCheck(Player __instance, GameObject go, bool alt, Interactable ComponentInParent)
		{
			//IL_0024: 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)
			Beehive val = (Beehive)(object)((ComponentInParent is Beehive) ? ComponentInParent : null);
			if (val == null)
			{
				return;
			}
			int num = (int)m_interactMaskField.GetValue(__instance);
			Collider[] array = Physics.OverlapSphere(go.transform.position, (float)CropUtils.Instance.UtilRange, num);
			foreach (Collider val2 in array)
			{
				Beehive val3;
				if ((Object)(object)val2 == (Object)null)
				{
					val3 = null;
				}
				else
				{
					GameObject gameObject = ((Component)val2).gameObject;
					val3 = (((Object)(object)gameObject != (Object)null) ? gameObject.GetComponentInParent<Beehive>() : null);
				}
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val && PrivateArea.CheckAccess(((Component)val3).transform.position, 0f, true, false))
				{
					m_extractMethod.Invoke(val3, null);
				}
			}
		}
	}
	[HarmonyPatch]
	internal class PlantingUtil
	{
		private static int _plantSpaceMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid" });

		private static bool _placed = false;

		private static bool _originValid = true;

		private static bool _originSkipped = false;

		private static GameObject[] _placementGhosts = (GameObject[])(object)new GameObject[1];

		private static FieldInfo _placementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

		private static FieldInfo _buildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces");

		private static FieldInfo _noPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");

		private static Transform _placedPosition;

		private static Quaternion _placedRotation;

		private static Piece _placedPiece;

		private static List<Vector3> _lastPlantedPosition = null;

		private static Vector3 _lastPlayerGhostPosition;

		private static Coroutine _hexListCoroutine = null;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "TryPlacePiece")]
		public static void PlacePiecePostFix(Player __instance, ref bool __result, Piece piece)
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (_originSkipped)
			{
				_originSkipped = false;
				return;
			}
			_placed = __result;
			if (__result)
			{
				GameObject val = (GameObject)_placementGhostField.GetValue(__instance);
				_placedPosition = val.transform;
				_placedRotation = val.transform.rotation;
				_placedPiece = piece;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "TryPlacePiece")]
		public static bool PlacePiecePreFix(Player __instance, Piece piece, ref bool __result)
		{
			//IL_000c: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0025: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!_originValid)
			{
				KeyboardShortcut val = CropUtils.Instance.UtilControllerButton;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					val = CropUtils.Instance.UtilHotKey;
					if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
					{
						goto IL_0039;
					}
				}
				GameObject val2 = (GameObject)_placementGhostField.GetValue(__instance);
				if (!Object.op_Implicit((Object)(object)val2) || !val2.activeSelf)
				{
					return true;
				}
				_placedPosition = val2.transform;
				_placedRotation = val2.transform.rotation;
				_placedPiece = piece;
				_placed = true;
				_originSkipped = true;
				__result = false;
				return false;
			}
			goto IL_0039;
			IL_0039:
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static void UpdatePlacementPrefix(bool takeInput, float dt)
		{
			_placed = false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static void UpdatePlacementPostfix(Player __instance, bool takeInput, float dt)
		{
			if (_placed)
			{
				PlaceNextFrame(__instance);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		public static void PlacePieceRotationPrefix(Player __instance, out int __state)
		{
			__state = __instance.m_placeRotation;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		public static void PlacePieceRotationPostfix(Player __instance, int __state)
		{
			RestoreRotation(__instance, __state);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static void SetupPlacementGhostRotationPrefix(Player __instance, out int __state)
		{
			__state = __instance.m_placeRotation;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static void SetupPlacementGhostRotationPostfix(Player __instance, int __state)
		{
			RestoreRotation(__instance, __state);
		}

		private static void RestoreRotation(Player player, int rotation)
		{
			//IL_0005: 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_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_0026: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut val = CropUtils.Instance.UtilControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.UtilHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					return;
				}
			}
			player.m_placeRotation = rotation;
		}

		private static void PlaceNextFrame(Player __instance)
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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_00e0: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			float num = TryFindPlantGrowthRadius(((Component)_placedPiece).gameObject);
			if (num <= 0f)
			{
				return;
			}
			KeyboardShortcut val = CropUtils.Instance.UtilControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.UtilHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					return;
				}
			}
			List<Vector3> list = BuildPlantingPositions(_placedPosition, num);
			int num2 = 0;
			ItemData rightItem = ((Humanoid)__instance).GetRightItem();
			float num3 = rightItem.m_shared.m_attack.m_attackStamina / (float)CropUtils.Instance.Discount;
			float num4 = rightItem.m_shared.m_attack.m_attackStamina / (float)CropUtils.Instance.Discount;
			bool flag = ((Humanoid)__instance).m_inventory.ItemCheated(_placedPiece.m_resources, -1, true) || __instance.NoCostCheat();
			foreach (Vector3 item in list)
			{
				if (_placedPosition.position == item)
				{
					CropUtils.Log.LogError((object)"Did not plant: Position matches origin");
					continue;
				}
				Heightmap val2 = Heightmap.FindHeightmap(item);
				if ((Object)(object)val2 == (Object)null || (_placedPiece.m_cultivatedGroundOnly && !val2.IsCultivated(item)) || !CanGrowAt(((Component)_placedPiece).gameObject, item))
				{
					continue;
				}
				if (!((Character)__instance).HaveStamina(num3))
				{
					Hud.instance.StaminaBarEmptyFlash();
					break;
				}
				if (!(bool)_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(_placedPiece, (RequirementMode)0))
				{
					break;
				}
				if (!HasGrowSpace(item, num))
				{
					continue;
				}
				num2++;
				GameObject val3 = Object.Instantiate<GameObject>(((Component)_placedPiece).gameObject, item, _placedRotation);
				Piece component = val3.GetComponent<Piece>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.SetCreator(__instance.GetPlayerID(), ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID);
					component.SetInvalidPlacementHeightlight(false);
				}
				_placedPiece.m_placeEffect.Create(item, _placedRotation, val3.transform, 1f, -1, default(ZDOID));
				Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f, flag);
				try
				{
					__instance.ConsumeResources(_placedPiece.m_resources, 0, 1, 1);
				}
				catch (Exception ex)
				{
					CropUtils.Log.LogError((object)("[PlaceNextFrame] Player.ConsumeResources failed with " + ex.Message));
				}
				try
				{
					((Character)__instance).UseStamina(num3);
				}
				catch (Exception ex2)
				{
					CropUtils.Log.LogError((object)("[PlaceNextFrame] Player.UseStamina failed with " + ex2.Message));
				}
				if (rightItem.m_shared.m_useDurability)
				{
					rightItem.m_durability -= num4;
					if (rightItem.m_durability <= 0f)
					{
						break;
					}
				}
			}
			ClearAfterPlanting();
			CropUtils.Log.LogInfo((object)$"Finished planting {num2} new crops!");
		}

		private static void ClearAfterPlanting()
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			if (_hexListCoroutine != null)
			{
				((MonoBehaviour)CropUtils.Instance).StopCoroutine(_hexListCoroutine);
			}
			_lastPlayerGhostPosition = Vector3.zero;
			_placedRotation = default(Quaternion);
			_lastPlantedPosition = null;
			_placedPiece = null;
			DestroyGhosts();
			_placementGhosts = (GameObject[])(object)new GameObject[1];
			_placed = false;
		}

		private static List<Vector3> BuildPlantingPositions(Transform originPos, float plantGrowthRadius)
		{
			//IL_0005: 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_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_0026: 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_0085: 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_0068: 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)
			KeyboardShortcut val = CropUtils.Instance.UtilAltControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.UtilAltHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					_lastPlayerGhostPosition = originPos.position;
					_lastPlantedPosition = LinePlantPositions(originPos, plantGrowthRadius);
					UpdatePlayerGhostState(originPos, plantGrowthRadius);
					return _lastPlantedPosition;
				}
			}
			if (_lastPlantedPosition != null)
			{
				originPos.position = _lastPlayerGhostPosition;
				UpdatePlayerGhostState(originPos, plantGrowthRadius);
				return _lastPlantedPosition;
			}
			if (_hexListCoroutine != null)
			{
				((MonoBehaviour)CropUtils.Instance).StopCoroutine(_hexListCoroutine);
			}
			_lastPlayerGhostPosition = originPos.position;
			_lastPlantedPosition = HexPlantPositions(originPos, plantGrowthRadius);
			return _lastPlantedPosition;
		}

		private static void UpdatePlayerGhostState(Transform originGhost, float plantGrowthRadius)
		{
			//IL_0003: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			if (!HasGrowSpace(originGhost.position, plantGrowthRadius))
			{
				flag = true;
				((Component)originGhost).GetComponent<Piece>().SetInvalidPlacementHeightlight(flag);
			}
			if (flag)
			{
				return;
			}
			KeyboardShortcut val;
			if (!flag)
			{
				val = CropUtils.Instance.UtilAltControllerButton;
				if (Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					goto IL_0057;
				}
			}
			val = CropUtils.Instance.UtilAltHotKey;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				return;
			}
			goto IL_0057;
			IL_0057:
			if (((Component)originGhost).GetComponent<Piece>().m_cultivatedGroundOnly && !Heightmap.FindHeightmap(originGhost.position).IsCultivated(originGhost.position))
			{
				flag = true;
			}
			((Component)originGhost).GetComponent<Piece>().SetInvalidPlacementHeightlight(flag);
		}

		private static List<Vector3> HexPlantPositions(Transform originPos, float plantGrowthRadius)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			new Vector3(0f, 60f, 0f);
			int utilRange = CropUtils.Instance.UtilRange;
			List<Vector3> list = new List<Vector3>();
			float distanceBetween = PatternSpacing(plantGrowthRadius);
			_hexListCoroutine = ((MonoBehaviour)CropUtils.Instance).StartCoroutine(BuildHexList(originPos, utilRange, list, distanceBetween));
			return list;
		}

		private static IEnumerator BuildHexList(Transform originPos, int maxDistanceFromOrigin, List<Vector3> hexes, float distanceBetween)
		{
			Vector3 val = default(Vector3);
			for (int i = 1; i <= maxDistanceFromOrigin; i++)
			{
				int rows = i * 6;
				for (int j = 0; j < rows; j++)
				{
					float num = (float)j / (float)rows * 2f * MathF.PI;
					float num2 = Mathf.Cos(num);
					float num3 = Mathf.Sin(num);
					float num4 = num2 * distanceBetween * (float)i;
					float num5 = num3 * distanceBetween * (float)i;
					((Vector3)(ref val))..ctor(num4, 0f, num5);
					val += originPos.position;
					val.y = ZoneSystem.instance.GetGroundHeight(val);
					hexes.Add(val);
					yield return null;
				}
				yield return null;
			}
		}

		private static List<Vector3> LinePlantPositions(Transform originPos, float plantGrowthRadius)
		{
			//IL_0022: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_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)
			float num = PatternSpacing(plantGrowthRadius);
			int num2 = Mathf.CeilToInt((float)CropUtils.Instance.UtilRange / num);
			List<Vector3> list = new List<Vector3>(num2);
			Vector3 val = originPos.rotation * Vector3.forward * num;
			Vector3 val2 = val;
			val2 += originPos.position;
			for (int i = 0; i < num2; i++)
			{
				val2.y = ZoneSystem.instance.GetGroundHeight(val2);
				list.Add(val2);
				val2 += val;
			}
			return list;
		}

		private static bool HasGrowSpace(Vector3 newPos, float plantGrowthRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Physics.OverlapSphere(newPos, plantGrowthRadius, _plantSpaceMask).Length == 0;
		}

		private static bool CanAffordOnePlant(Player player, Piece piece)
		{
			if ((bool)_noPlacementCostField.GetValue(player))
			{
				return true;
			}
			Requirement val = ((IEnumerable<Requirement>)piece.m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement r) => Object.op_Implicit((Object)(object)r.m_resItem) && r.m_amount > 0));
			if (val == null || !Object.op_Implicit((Object)(object)val.m_resItem))
			{
				return true;
			}
			return ((Humanoid)player).m_inventory.CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) >= val.m_amount;
		}

		private static float PatternSpacing(float plantGrowthRadius)
		{
			return plantGrowthRadius * CropUtils.Instance.GrowRadiusSpacingMultiplier;
		}

		private static bool CanGrowAt(GameObject plantable, Vector3 position)
		{
			//IL_0011: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0049: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			Plant component = plantable.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			Heightmap val = Heightmap.FindHeightmap(position);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return true;
			}
			Biome biome = val.GetBiome(position, 0.02f, false);
			if ((biome & component.m_biome) == 0)
			{
				return false;
			}
			if (!component.m_tolerateHeat && (int)biome == 32 && !ShieldGenerator.IsInsideShield(position))
			{
				return false;
			}
			if (!component.m_tolerateCold && ((int)biome == 64 || (int)biome == 4) && !ShieldGenerator.IsInsideShield(position))
			{
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static void SetupPlacementGhostPostfix(Player __instance)
		{
			DestroyGhosts();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		public static void UpdatePlacementGhostPostfix(Player __instance, bool flashGuardStone)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0033: 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_003c: 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_0079: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00dc: 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_0103: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			_originValid = true;
			GameObject val = (GameObject)_placementGhostField.GetValue(__instance);
			if (!Object.op_Implicit((Object)(object)val) || !val.activeSelf)
			{
				SetGhostsActive(active: false);
				return;
			}
			KeyboardShortcut val2 = CropUtils.Instance.UtilControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val2)).MainKey))
			{
				val2 = CropUtils.Instance.UtilHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val2)).MainKey))
				{
					_lastPlantedPosition = null;
					SetGhostsActive(active: false);
					return;
				}
			}
			val2 = CropUtils.Instance.IncreaseSpacingHotKey;
			if (Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				CropUtils.Instance.ChangeSpacing(0.1f);
			}
			val2 = CropUtils.Instance.DecreaseSpacingHotKey;
			if (Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				CropUtils.Instance.ChangeSpacing(-0.1f);
			}
			float num = TryFindPlantGrowthRadius(val);
			if (num <= 0f)
			{
				return;
			}
			Vector3 position = val.transform.position;
			Piece component = val.GetComponent<Piece>();
			if (!CanGrowAt(val, position))
			{
				component.SetInvalidPlacementHeightlight(true);
				__instance.m_placementStatus = (PlacementStatus)8;
				_originValid = false;
			}
			else if (!HasGrowSpace(position, num) || !CanAffordOnePlant(__instance, component))
			{
				component.SetInvalidPlacementHeightlight(true);
				_originValid = false;
			}
			else
			{
				_originValid = true;
			}
			val2 = CropUtils.Instance.IncreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				val2 = CropUtils.Instance.IncreaseRangeHotKey;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
				{
					goto IL_0169;
				}
			}
			CropUtils.Instance.ChangeRange(1);
			goto IL_0169;
			IL_0169:
			val2 = CropUtils.Instance.DecreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				val2 = CropUtils.Instance.DecreaseRangeHotKey;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
				{
					goto IL_01a8;
				}
			}
			CropUtils.Instance.ChangeRange(-1);
			goto IL_01a8;
			IL_01a8:
			if (!DidGhostsBuild(__instance, num))
			{
				SetGhostsActive(active: false);
				return;
			}
			Requirement val3 = ((IEnumerable<Requirement>)val.GetComponent<Piece>().m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement r) => Object.op_Implicit((Object)(object)r.m_resItem) && r.m_amount > 0));
			bool flag = (bool)_noPlacementCostField.GetValue(__instance);
			int num2 = (Object.op_Implicit((Object)(object)val3.m_resItem) ? ((Humanoid)__instance).m_inventory.CountItems(val3.m_resItem.m_itemData.m_shared.m_name, -1, true) : 0);
			int num3 = (_originValid ? val3.m_amount : 0);
			float num4 = __instance.GetStamina();
			ItemData rightItem = ((Humanoid)__instance).GetRightItem();
			List<Vector3> list = BuildPlantingPositions(val.transform, num);
			for (int num5 = 0; num5 < _placementGhosts.Length && num5 < list.Count; num5++)
			{
				Vector3 val4 = list[num5];
				if (val.transform.position == val4)
				{
					_placementGhosts[num5].SetActive(false);
					continue;
				}
				_placementGhosts[num5].transform.position = val4;
				_placementGhosts[num5].transform.rotation = val.transform.rotation;
				_placementGhosts[num5].SetActive(true);
				bool invalidPlacementHeightlight = false;
				Heightmap val5 = Heightmap.FindHeightmap(val4);
				if (val.GetComponent<Piece>().m_cultivatedGroundOnly && !val5.IsCultivated(val4))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!CanGrowAt(val, val4))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!HasGrowSpace(val4, num))
				{
					invalidPlacementHeightlight = true;
				}
				else
				{
					float num6 = rightItem.m_shared.m_attack.m_attackStamina / (float)CropUtils.Instance.Discount;
					num3 += val3.m_amount;
					if (num4 < num6)
					{
						Hud.instance.StaminaBarEmptyFlash();
						invalidPlacementHeightlight = true;
					}
					else if (!flag && num3 > num2)
					{
						invalidPlacementHeightlight = true;
					}
					else
					{
						num4 -= num6;
					}
				}
				_placementGhosts[num5].GetComponent<Piece>().SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
		}

		private static bool DidGhostsBuild(Player player, float plantGrowthRadius)
		{
			//IL_001d: 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_0025: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.CeilToInt((float)CropUtils.Instance.UtilRange / PatternSpacing(plantGrowthRadius));
			KeyboardShortcut val = CropUtils.Instance.UtilAltControllerButton;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.UtilAltHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					goto IL_0062;
				}
			}
			num++;
			num = 3 * (int)Mathf.Pow((float)num, 2f) - 3 * num;
			goto IL_0062;
			IL_0062:
			if (num == 0)
			{
				CropUtils.Log.LogError((object)"Math is wrong, no ghosts to build!");
				return false;
			}
			if (!Object.op_Implicit((Object)(object)_placementGhosts[0]) || _placementGhosts.Length != num)
			{
				DestroyGhosts();
				if (_placementGhosts.Length != num)
				{
					_placementGhosts = (GameObject[])(object)new GameObject[num];
				}
				object? value = _buildPiecesField.GetValue(player);
				PieceTable val2 = (PieceTable)((value is PieceTable) ? value : null);
				if ((Object)(object)val2 != (Object)null)
				{
					GameObject selectedPrefab = val2.GetSelectedPrefab();
					if ((Object)(object)selectedPrefab != (Object)null)
					{
						if (selectedPrefab.GetComponent<Piece>().m_repairPiece)
						{
							return false;
						}
						for (int i = 0; i < _placementGhosts.Length; i++)
						{
							_placementGhosts[i] = SetupNewGhost(player, selectedPrefab);
						}
					}
				}
				return false;
			}
			return true;
		}

		private static void DestroyGhosts()
		{
			for (int i = 0; i < _placementGhosts.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)_placementGhosts[i]))
				{
					Object.Destroy((Object)(object)_placementGhosts[i]);
					_placementGhosts[i] = null;
				}
			}
		}

		private static void SetGhostsActive(bool active)
		{
			GameObject[] placementGhosts = _placementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
			}
		}

		private static GameObject SetupNewGhost(Player player, GameObject prefab)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			ZNetView.m_forceDisableInit = true;
			GameObject val = Object.Instantiate<GameObject>(prefab);
			ZNetView.m_forceDisableInit = false;
			((Object)val).name = ((Object)prefab).name;
			DestroyNonGhostComponents(val);
			Transform val2 = val.transform.Find("_GhostOnly");
			if (Object.op_Implicit((Object)(object)val2))
			{
				((Component)val2).gameObject.SetActive(true);
			}
			MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val3 in componentsInChildren)
			{
				if (!((Object)(object)((Renderer)val3).sharedMaterial == (Object)null))
				{
					Material[] sharedMaterials = ((Renderer)val3).sharedMaterials;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						Material val4 = new Material(sharedMaterials[j]);
						val4.SetFloat("_RippleDistance", 0f);
						val4.SetFloat("_ValueNoise", 0f);
						sharedMaterials[j] = val4;
					}
					((Renderer)val3).sharedMaterials = sharedMaterials;
					((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			return val;
		}

		private static void DestroyNonGhostComponents(GameObject gameObject)
		{
			Joint[] componentsInChildren = gameObject.GetComponentsInChildren<Joint>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = gameObject.GetComponentsInChildren<Rigidbody>();
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				Object.Destroy((Object)(object)componentsInChildren2[j]);
			}
			int layer = LayerMask.NameToLayer("ghost");
			Transform[] componentsInChildren3 = gameObject.GetComponentsInChildren<Transform>();
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				((Component)componentsInChildren3[k]).gameObject.layer = layer;
			}
			TerrainModifier[] componentsInChildren4 = gameObject.GetComponentsInChildren<TerrainModifier>();
			for (int l = 0; l < componentsInChildren4.Length; l++)
			{
				Object.Destroy((Object)(object)componentsInChildren4[l]);
			}
			GuidePoint[] componentsInChildren5 = gameObject.GetComponentsInChildren<GuidePoint>();
			for (int m = 0; m < componentsInChildren5.Length; m++)
			{
				Object.Destroy((Object)(object)componentsInChildren5[m]);
			}
			Light[] componentsInChildren6 = gameObject.GetComponentsInChildren<Light>();
			for (int n = 0; n < componentsInChildren6.Length; n++)
			{
				Object.Destroy((Object)(object)componentsInChildren6[n]);
			}
		}

		private static float TryFindPlantGrowthRadius(GameObject objectToGrow)
		{
			float customSpacing = CropUtils.Instance.CustomSpacing;
			if (CropUtils.Instance.AlwaysUseCustomSpacing)
			{
				return customSpacing;
			}
			Plant component = objectToGrow.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				if (CropUtils.Instance.AllowPlantAnything)
				{
					return customSpacing;
				}
				return -1f;
			}
			return component.m_growRadius;
		}
	}
	[HarmonyPatch]
	public static class InteractRangeUtil
	{
		public static GameObject m_rangeIndicator;

		[HarmonyPatch(typeof(Player), "FindHoverObject")]
		public static void Postfix(Player __instance, ref GameObject hover, ref GameObject hoverCreature)
		{
			//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_001f: 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_0035: 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_00cd: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_009a: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			bool active = false;
			KeyboardShortcut val;
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				val = CropUtils.Instance.UtilControllerButton;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					val = CropUtils.Instance.UtilHotKey;
					if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
					{
						goto IL_0142;
					}
				}
				if (CropUtils.Instance.ShowVisualRangeIndicator)
				{
					if ((Object)(object)m_rangeIndicator == (Object)null)
					{
						CreateDebugRenderer();
					}
					if ((Object)(object)hover != (Object)null)
					{
						Interactable componentInParent = hover.GetComponentInParent<Interactable>();
						if (componentInParent is Pickable || componentInParent is Beehive)
						{
							active = true;
							m_rangeIndicator.transform.position = hover.transform.position;
							m_rangeIndicator.transform.localScale = Vector3.one * (float)CropUtils.Instance.UtilRange;
						}
					}
				}
				val = CropUtils.Instance.IncreaseRangeControllerButton;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref val)).MainKey))
				{
					val = CropUtils.Instance.IncreaseRangeHotKey;
					if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
					{
						goto IL_0105;
					}
				}
				CropUtils.Instance.ChangeRange(1);
				goto IL_0105;
			}
			goto IL_0142;
			IL_0105:
			val = CropUtils.Instance.DecreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.DecreaseRangeHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					goto IL_0142;
				}
			}
			CropUtils.Instance.ChangeRange(-1);
			goto IL_0142;
			IL_0142:
			if ((Object)(object)m_rangeIndicator != (Object)null)
			{
				m_rangeIndicator.SetActive(active);
			}
		}

		private static void CreateDebugRenderer()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//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_0090: Unknown result type (might be due to invalid IL or missing references)
			m_rangeIndicator = GameObject.CreatePrimitive((PrimitiveType)0);
			((Collider)m_rangeIndicator.GetComponent<SphereCollider>()).enabled = false;
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(Shader));
			Shader val = null;
			Object[] array2 = array;
			foreach (Object val2 in array2)
			{
				if (val2 != (Object)null && val2.name == "UI/Unlit/Transparent")
				{
					val = (Shader)(object)((val2 is Shader) ? val2 : null);
					break;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				Material val3 = new Material(val);
				Color blue = Color.blue;
				blue.a = 0.05f;
				val3.color = blue;
				((Renderer)m_rangeIndicator.GetComponent<MeshRenderer>()).material = val3;
			}
		}
	}
	[HarmonyPatch]
	internal static class SafePlantSpacing
	{
		private struct PlantProfile
		{
			public float Radius;

			public float Footprint;
		}

		private static readonly FieldInfo BuildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces");

		private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

		private static readonly FieldInfo HexListCoroutineField = AccessTools.Field(typeof(PlantingUtil), "_hexListCoroutine");

		private const float SpacingEpsilon = 0.01f;

		private const float PatternMargin = 0.05f;

		private static float _manualSpacingAdjustment;

		private static float _lastBaseSpacing;

		private static float _lastSpacingFloor;

		private const float NeighbourScanFactor = 2f;

		private const int MaxGrowChainDepth = 6;

		private static readonly Dictionary<string, PlantProfile> ProfileCache = new Dictionary<string, PlantProfile>();

		private static readonly Collider[] NeighbourBuffer = (Collider[])(object)new Collider[128];

		private static readonly int GrowSpaceMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid" });

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlantingUtil), "PatternSpacing")]
		private static void PatternSpacingPostfix(float plantGrowthRadius, ref float __result)
		{
			float num = (_lastSpacingFloor = SpacingFloor(GetSelectedPlantPrefab(), plantGrowthRadius));
			_lastBaseSpacing = __result;
			__result = Mathf.Max(__result + _manualSpacingAdjustment, num);
		}

		private static float SpacingFloor(GameObject prefab, float fallbackRadius)
		{
			Plant val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<Plant>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return fallbackRadius;
			}
			PlantProfile plantProfile = ProfileFor(prefab, val);
			return plantProfile.Radius + plantProfile.Footprint + 0.01f + 0.05f;
		}

		private static bool HasMutualClearance(Vector3 position)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			GameObject selectedPlantPrefab = GetSelectedPlantPrefab();
			Plant val = (Object.op_Implicit((Object)(object)selectedPlantPrefab) ? selectedPlantPrefab.GetComponent<Plant>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return true;
			}
			PlantProfile plantProfile = ProfileFor(selectedPlantPrefab, val);
			float num = (plantProfile.Radius + plantProfile.Footprint) * 2f;
			int num2 = Physics.OverlapSphereNonAlloc(position, num, NeighbourBuffer, GrowSpaceMask);
			for (int i = 0; i < num2; i++)
			{
				Collider val2 = NeighbourBuffer[i];
				if (!Object.op_Implicit((Object)(object)val2))
				{
					continue;
				}
				Plant componentInParent = ((Component)val2).GetComponentInParent<Plant>();
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					PlantProfile plantProfile2 = ProfileFor(((Component)componentInParent).gameObject, componentInParent);
					float num3 = Mathf.Max(plantProfile2.Radius + plantProfile.Footprint, plantProfile.Radius + plantProfile2.Footprint) + 0.01f;
					Vector3 val3 = ((Component)componentInParent).transform.position - position;
					val3.y = 0f;
					if (((Vector3)(ref val3)).sqrMagnitude < num3 * num3)
					{
						return false;
					}
				}
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CropUtils), "ChangeSpacing")]
		private static bool ChangeSpacingPrefix(float spacingChange)
		{
			_manualSpacingAdjustment = Mathf.Max(_lastSpacingFloor - _lastBaseSpacing, _manualSpacingAdjustment + spacingChange);
			float num = Mathf.Max(_lastBaseSpacing + _manualSpacingAdjustment, _lastSpacingFloor);
			CropUtils.Log.LogInfo((object)$"Spacing is now {num:0.###}");
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlantingUtil), "HasGrowSpace")]
		private static void HasGrowSpacePrefix()
		{
			Physics.SyncTransforms();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlantingUtil), "HasGrowSpace")]
		private static void HasGrowSpacePostfix(Vector3 newPos, ref bool __result)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				__result = HasMutualClearance(newPos);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		private static void SetupPlacementGhostPrefix()
		{
			StopHexBuild();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		private static void UpdatePlacementGhostPostfix(Player __instance)
		{
			if (!(PlacementGhostField == null))
			{
				object? value = PlacementGhostField.GetValue(__instance);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if (!Object.op_Implicit((Object)(object)val) || !val.activeSelf)
				{
					StopHexBuild();
				}
			}
		}

		private static void StopHexBuild()
		{
			if (!(HexListCoroutineField == null) && Object.op_Implicit((Object)(object)CropUtils.Instance))
			{
				object? value = HexListCoroutineField.GetValue(null);
				Coroutine val = (Coroutine)((value is Coroutine) ? value : null);
				if (val != null)
				{
					((MonoBehaviour)CropUtils.Instance).StopCoroutine(val);
					HexListCoroutineField.SetValue(null, null);
				}
			}
		}

		private static GameObject GetSelectedPlantPrefab()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || BuildPiecesField == null)
			{
				return null;
			}
			object? value = BuildPiecesField.GetValue(localPlayer);
			PieceTable val = (PieceTable)((value is PieceTable) ? value : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetSelectedPrefab();
		}

		private static PlantProfile ProfileFor(GameObject root, Plant plant)
		{
			string text = CleanName(((Object)root).name);
			if (ProfileCache.TryGetValue(text, out var value))
			{
				return value;
			}
			PlantProfile plantProfile = Accumulate(root, plant, 1f, 0);
			ProfileCache[text] = plantProfile;
			CropUtils.Log.LogInfo((object)$"[CropUtils] {text} worst case radius {plantProfile.Radius:0.###}, footprint {plantProfile.Footprint:0.###}");
			return plantProfile;
		}

		private static PlantProfile Accumulate(GameObject root, Plant plant, float scale, int depth)
		{
			PlantProfile result = default(PlantProfile);
			result.Radius = (Object.op_Implicit((Object)(object)plant) ? Mathf.Max(plant.m_growRadius, plant.m_growRadiusVines) : 0f);
			result.Footprint = MeasureFootprint(root) * scale;
			if (!Object.op_Implicit((Object)(object)plant) || plant.m_grownPrefabs == null || depth >= 6)
			{
				return result;
			}
			float scale2 = scale * Mathf.Max(1f, plant.m_maxScale);
			GameObject[] grownPrefabs = plant.m_grownPrefabs;
			foreach (GameObject val in grownPrefabs)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					PlantProfile plantProfile = Accumulate(val, val.GetComponent<Plant>(), scale2, depth + 1);
					result.Radius = Mathf.Max(result.Radius, plantProfile.Radius);
					result.Footprint = Mathf.Max(result.Footprint, plantProfile.Footprint);
				}
			}
			return result;
		}

		private static string CleanName(string name)
		{
			int num = name.IndexOf("(Clone)");
			if (num < 0)
			{
				return name;
			}
			return name.Substring(0, num);
		}

		private static float MeasureFootprint(GameObject prefab)
		{
			//IL_005e: 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_0074: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00c0: 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_00d4: 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_00e2: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = prefab.transform;
			float num = 0f;
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			Vector3 val3 = default(Vector3);
			foreach (Collider val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)val) || !val.enabled || !IsGrowSpaceLayer(((Component)val).gameObject.layer) || !TryGetLocalBounds(val, out var bounds))
				{
					continue;
				}
				Matrix4x4 val2 = transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				Vector3 min = ((Bounds)(ref bounds)).min;
				Vector3 max = ((Bounds)(ref bounds)).max;
				for (int j = 0; j < 2; j++)
				{
					for (int k = 0; k < 2; k++)
					{
						for (int l = 0; l < 2; l++)
						{
							((Vector3)(ref val3))..ctor((j == 0) ? min.x : max.x, (k == 0) ? min.y : max.y, (l == 0) ? min.z : max.z);
							Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
							float num2 = val4.x * val4.x + val4.z * val4.z;
							num = Mathf.Max(num, num2);
						}
					}
				}
			}
			return Mathf.Sqrt(num);
		}

		private static bool IsGrowSpaceLayer(int layer)
		{
			return (GrowSpaceMask & (1 << layer)) != 0;
		}

		private static bool TryGetLocalBounds(Collider collider, out Bounds bounds)
		{
			//IL_000c: 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_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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0109: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cd: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
			if (val != null)
			{
				bounds = new Bounds(val.center, val.size);
				return true;
			}
			SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
			if (val2 != null)
			{
				bounds = new Bounds(val2.center, Vector3.one * val2.radius * 2f);
				return true;
			}
			CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
			if (val3 != null)
			{
				float radius = val3.radius;
				float num = Mathf.Max(val3.height * 0.5f, radius);
				Vector3 val4 = Vector3.one * radius;
				if (val3.direction == 0)
				{
					val4.x = num;
				}
				else if (val3.direction == 1)
				{
					val4.y = num;
				}
				else
				{
					val4.z = num;
				}
				bounds = new Bounds(val3.center, val4 * 2f);
				return true;
			}
			MeshCollider val5 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
			if (val5 != null && Object.op_Implicit((Object)(object)val5.sharedMesh))
			{
				bounds = val5.sharedMesh.bounds;
				return true;
			}
			bounds = default(Bounds);
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Crop_Utils";

		public const string PLUGIN_NAME = "Crop_Utils";

		public const string PLUGIN_VERSION = "2.1.0";
	}
}