Decompiled source of CropUtils v1.5.2

Crop_Utils.dll

Decompiled a month 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 UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("Crop_Utils")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod for helping with farming and gathering")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7f266a2be18eb9c698b4dcd4fb462ee2f6ffd2c6")]
[assembly: AssemblyProduct("Crop_Utils")]
[assembly: AssemblyTitle("Crop_Utils")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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", "1.5.2")]
	[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 = "1.5.2";

		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<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 KeyboardShortcut IncreaseSpacingHotKey => m_increaseSpacingHotKey.Value;

		public KeyboardShortcut DecreaseSpacingHotKey => m_decreaseSpacingHotKey.Value;

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_008a: 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_00a4: Expected O, but got Unknown
			//IL_00c2: 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_00dc: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0170: 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_018a: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Expected O, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Expected O, but got Unknown
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: 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 Utiity Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			m_increaseRangeHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Utils 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 Utiity 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 Utiity 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 pickingwhile holding the Utiity 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>("Utils 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", "Utlity 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("The divider for how much less stamina planting uses when using the util (stamina cost / 20) default", (AcceptableValueBase)null, Array.Empty<object>()));
			m_allowPlantAnything = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod Compatability 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. Compatability 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_increaseSpacingHotKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Custom Crop Spacing", "Increase Spacing Hot Key", new KeyboardShortcut((KeyCode)45, (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)61, (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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_002c: 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)
			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 Piece _fakeResourcePiece;

		private static bool _placed;

		private static GameObject[] _placementGhosts;

		private static FieldInfo _placementGhostField;

		private static FieldInfo _buildPiecesField;

		private static FieldInfo _noPlacementCostField;

		private static Transform _placedPosition;

		private static Quaternion _placedRotation;

		private static Piece _placedPiece;

		private static List<Vector3> _lastPlantedPosition;

		private static Vector3 _lastPlayerGhostPosition;

		private static Coroutine _hexListCoroutine;

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

		[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);
			}
		}

		private static void PlaceNextFrame(Player __instance)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: 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)
			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;
			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)))
				{
					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());
					component.SetInvalidPlacementHeightlight(false);
				}
				_placedPiece.m_placeEffect.Create(item, _placedRotation, val3.transform, 1f, -1);
				PlayerStats playerStats = Game.instance.GetPlayerProfile().m_playerStats;
				float num5 = playerStats[(PlayerStatType)2];
				playerStats[(PlayerStatType)2] = num5 + 1f;
				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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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;
			_placementGhosts = (GameObject[])(object)new GameObject[1];
			_placed = false;
		}

		private static List<Vector3> BuildPlantingPositions(Transform originPos, float plantGrowthRadius)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0024: 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_00a3: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			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_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_003f: 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_0084: 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_006a;
				}
			}
			val = CropUtils.Instance.UtilAltHotKey;
			if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
			{
				return;
			}
			goto IL_006a;
			IL_006a:
			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)
		{
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, 60f, 0f);
			int utilRange = CropUtils.Instance.UtilRange;
			List<Vector3> list = new List<Vector3>();
			float distanceBetween = plantGrowthRadius * 2f;
			_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)
		{
			for (int i = 1; i <= maxDistanceFromOrigin; i++)
			{
				int rows = i * 6;
				for (int j = 0; j < rows; j++)
				{
					float circumferenceProgress = (float)j / (float)rows;
					float currentRadian = circumferenceProgress * 2f * (float)Math.PI;
					float xNormalized = Mathf.Cos(currentRadian);
					float zNormalized = Mathf.Sin(currentRadian);
					float x = xNormalized * distanceBetween * (float)i;
					float z = zNormalized * distanceBetween * (float)i;
					Vector3 posInRow2 = new Vector3(x, 0f, z);
					posInRow2 += originPos.position;
					posInRow2.y = ZoneSystem.instance.GetGroundHeight(posInRow2);
					hexes.Add(posInRow2);
					yield return null;
				}
				yield return null;
			}
		}

		private static List<Vector3> LinePlantPositions(Transform originPos, float plantGrowthRadius)
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			float num = plantGrowthRadius * 2f;
			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_0001: Unknown result type (might be due to invalid IL or missing references)
			return Physics.OverlapSphere(newPos, plantGrowthRadius, _plantSpaceMask).Length == 0;
		}

		[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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			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;
			}
			val2 = CropUtils.Instance.IncreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				val2 = CropUtils.Instance.IncreaseRangeHotKey;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
				{
					goto IL_0151;
				}
			}
			CropUtils.Instance.ChangeRange(1);
			goto IL_0151;
			IL_019a:
			if (!DidGhostsBuild(__instance, num))
			{
				SetGhostsActive(active: false);
				return;
			}
			Piece component = val.GetComponent<Piece>();
			Requirement val3 = ((IEnumerable<Requirement>)component.m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement r) => Object.op_Implicit((Object)(object)r.m_resItem) && r.m_amount > 0));
			_fakeResourcePiece.m_resources[0].m_resItem = val3.m_resItem;
			_fakeResourcePiece.m_resources[0].m_amount = val3.m_amount;
			float num2 = __instance.GetStamina();
			ItemData rightItem = ((Humanoid)__instance).GetRightItem();
			List<Vector3> list = BuildPlantingPositions(val.transform, num);
			for (int i = 0; i < _placementGhosts.Length && i < list.Count; i++)
			{
				Vector3 val4 = list[i];
				if (val.transform.position == val4)
				{
					_placementGhosts[i].SetActive(false);
					continue;
				}
				Requirement obj = _fakeResourcePiece.m_resources[0];
				obj.m_amount += val3.m_amount;
				_placementGhosts[i].transform.position = val4;
				_placementGhosts[i].transform.rotation = val.transform.rotation;
				_placementGhosts[i].SetActive(true);
				bool invalidPlacementHeightlight = false;
				Heightmap val5 = Heightmap.FindHeightmap(val4);
				if (val.GetComponent<Piece>().m_cultivatedGroundOnly && !val5.IsCultivated(val4))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!HasGrowSpace(val4, num))
				{
					invalidPlacementHeightlight = true;
				}
				else if (num2 < rightItem.m_shared.m_attack.m_attackStamina / (float)CropUtils.Instance.Discount)
				{
					Hud.instance.StaminaBarEmptyFlash();
					invalidPlacementHeightlight = true;
				}
				else if (!(bool)_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(component, (RequirementMode)0))
				{
					invalidPlacementHeightlight = true;
				}
				num2 -= rightItem.m_shared.m_attack.m_attackStamina / (float)CropUtils.Instance.Discount;
				_placementGhosts[i].GetComponent<Piece>().SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
			return;
			IL_0151:
			val2 = CropUtils.Instance.DecreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
			{
				val2 = CropUtils.Instance.DecreaseRangeHotKey;
				if (!Input.GetKeyDown(((KeyboardShortcut)(ref val2)).MainKey))
				{
					goto IL_019a;
				}
			}
			CropUtils.Instance.ChangeRange(-1);
			goto IL_019a;
		}

		private static bool DidGhostsBuild(Player player, float plantGrowthRadius)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.CeilToInt((float)CropUtils.Instance.UtilRange / (plantGrowthRadius * 2f));
			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_006b;
				}
			}
			num++;
			num = 3 * (int)Mathf.Pow((float)num, 2f) - 3 * num;
			goto IL_006b;
			IL_006b:
			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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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;
		}

		static PlantingUtil()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			Piece val = new Piece();
			val.m_dlc = string.Empty;
			val.m_resources = (Requirement[])(object)new Requirement[1]
			{
				new Requirement()
			};
			_fakeResourcePiece = val;
			_placed = false;
			_placementGhosts = (GameObject[])(object)new GameObject[1];
			_placementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");
			_buildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces");
			_noPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");
			_lastPlantedPosition = null;
			_hexListCoroutine = null;
		}
	}
	[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_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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00eb: 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_0189;
					}
				}
				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_0140;
					}
				}
				CropUtils.Instance.ChangeRange(1);
				goto IL_0140;
			}
			goto IL_0189;
			IL_0140:
			val = CropUtils.Instance.DecreaseRangeControllerButton;
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref val)).MainKey))
			{
				val = CropUtils.Instance.DecreaseRangeHotKey;
				if (!Input.GetKey(((KeyboardShortcut)(ref val)).MainKey))
				{
					goto IL_0189;
				}
			}
			CropUtils.Instance.ChangeRange(-1);
			goto IL_0189;
			IL_0189:
			if ((Object)(object)m_rangeIndicator != (Object)null)
			{
				m_rangeIndicator.SetActive(active);
			}
		}

		private static void CreateDebugRenderer()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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;
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Crop_Utils";

		public const string PLUGIN_NAME = "Crop_Utils";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}