Decompiled source of ComfyMassFarming v1.3.1

ComfyMassFarming.dll

Decompiled 7 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
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: AssemblyTitle("MassFarming")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MassFarming")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e1da477d-c14c-4355-be8f-c043e789791a")]
[assembly: AssemblyFileVersion("1.3.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.0")]
[module: UnverifiableCode]
namespace MassFarming;

[BepInPlugin("EardwulfDoesMods.Comfy.MassFarming", "Comfy.MassFarming", "1.3.1")]
public class MassFarming : BaseUnityPlugin
{
	[HarmonyPatch]
	public class MassPlant
	{
		private static FieldInfo m_noPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");

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

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

		private static MethodInfo _GetRightItemMethod = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null);

		private static Vector3 placedPosition;

		private static Quaternion placedRotation;

		private static Piece placedPiece;

		private static bool placeSuccessful = false;

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

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

		private static Piece _fakeResourcePiece;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		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_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_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)
			placeSuccessful = __result;
			if (__result)
			{
				GameObject val = (GameObject)m_placementGhostField.GetValue(__instance);
				placedPosition = val.transform.position;
				placedRotation = val.transform.rotation;
				placedPiece = piece;
			}
		}

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

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		public static void UpdatePlacementPostfix(Player __instance, bool takeInput, float dt)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			if (!placeSuccessful)
			{
				return;
			}
			Plant component = ((Component)placedPiece).gameObject.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Heightmap val = Heightmap.FindHeightmap(placedPosition);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			if (!PluginConfig.NoActionKeyNeeded.Value)
			{
				KeyboardShortcut value = PluginConfig.ControllerPickupHotkey.Value;
				if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					value = PluginConfig.MassActionHotkey.Value;
					if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
					{
						return;
					}
				}
			}
			foreach (Vector3 item in BuildPlantingGridPositions(placedPosition, component, placedRotation))
			{
				if ((placedPiece.m_cultivatedGroundOnly && !val.IsCultivated(item)) || placedPosition == item)
				{
					continue;
				}
				object? obj = _GetRightItemMethod.Invoke(__instance, Array.Empty<object>());
				ItemData val2 = (ItemData)((obj is ItemData) ? obj : null);
				bool flag = ((Character)__instance).HaveStamina((val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier()) * 1.7695f);
				ZLog.Log((object)($"Normal Per Plant Stamina: {val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier()}, Per Plant Stamina with CMF: {(val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier()) * 1.7695f}," + $" Additional Per Plant Stamina with CMF: {(val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier()) * 1.7695f - (val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier())}"));
				if (!flag)
				{
					Hud.instance.StaminaBarUppgradeFlash();
					break;
				}
				if (!(bool)m_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(placedPiece, (RequirementMode)0))
				{
					break;
				}
				if (HasGrowSpace(item, ((Component)placedPiece).gameObject))
				{
					GameObject val3 = Object.Instantiate<GameObject>(((Component)placedPiece).gameObject, item, placedRotation);
					Piece component2 = val3.GetComponent<Piece>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						component2.SetCreator(__instance.GetPlayerID());
					}
					placedPiece.m_placeEffect.Create(item, placedRotation, val3.transform, 1f, -1);
					Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f);
					__instance.ConsumeResources(placedPiece.m_resources, 0, -1);
					((Character)__instance).UseStamina((val2.m_shared.m_attack.m_attackStamina + ((Character)__instance).GetEquipmentBaseItemModifier()) * 1.7695f, false);
					val2.m_durability -= val2.m_shared.m_useDurabilityDrain;
					if (val2.m_durability <= 0f)
					{
						break;
					}
				}
			}
		}

		private static List<Vector3> BuildPlantingGridPositions(Vector3 originPos, Plant placedPlant, Quaternion rotation)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_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_003c: 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_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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00d8: 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_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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			float num = placedPlant.m_growRadius * 2f;
			List<Vector3> list = new List<Vector3>(PluginConfig.PlantGridWidth.Value * PluginConfig.PlantGridLength.Value);
			Vector3 val = rotation * Vector3.left * num;
			Vector3 val2 = rotation * Vector3.forward * num;
			Vector3 val3 = originPos;
			if (PluginConfig.GridAnchorLength.Value)
			{
				val3 -= val2 * (float)(PluginConfig.PlantGridLength.Value / 2);
			}
			if (PluginConfig.GridAnchorWidth.Value)
			{
				val3 -= val * (float)(PluginConfig.PlantGridWidth.Value / 2);
			}
			for (int i = 0; i < PluginConfig.PlantGridLength.Value; i++)
			{
				Vector3 val4 = val3;
				for (int j = 0; j < PluginConfig.PlantGridWidth.Value; j++)
				{
					val4.y = ZoneSystem.instance.GetGroundHeight(val4);
					list.Add(val4);
					val4 += val;
				}
				val3 += val2;
			}
			return list;
		}

		private static bool HasGrowSpace(Vector3 newPos, GameObject go)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Plant component = go.GetComponent<Plant>();
			if (component != null)
			{
				Collider[] array = Physics.OverlapSphere(newPos, component.m_growRadius, _plantSpaceMask);
				return array.Length == 0;
			}
			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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_016f: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_0248: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (GameObject)m_placementGhostField.GetValue(__instance);
			if (!Object.op_Implicit((Object)(object)val) || !val.activeSelf)
			{
				SetGhostsActive(active: false);
				return;
			}
			if (!PluginConfig.NoActionKeyNeeded.Value)
			{
				KeyboardShortcut value = PluginConfig.ControllerPickupHotkey.Value;
				if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					value = PluginConfig.MassActionHotkey.Value;
					if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
					{
						SetGhostsActive(active: false);
						return;
					}
				}
			}
			Plant component = val.GetComponent<Plant>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				SetGhostsActive(active: false);
				return;
			}
			if (!EnsureGhostsBuilt(__instance))
			{
				SetGhostsActive(active: false);
				return;
			}
			Requirement val2 = ((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));
			_fakeResourcePiece.m_resources[0].m_resItem = val2.m_resItem;
			_fakeResourcePiece.m_resources[0].m_amount = val2.m_amount;
			float num = __instance.GetStamina();
			object? obj = _GetRightItemMethod.Invoke(__instance, Array.Empty<object>());
			ItemData val3 = (ItemData)((obj is ItemData) ? obj : null);
			Heightmap val4 = Heightmap.FindHeightmap(val.transform.position);
			List<Vector3> list = BuildPlantingGridPositions(val.transform.position, component, val.transform.rotation);
			for (int i = 0; i < _placementGhosts.Length; i++)
			{
				Vector3 val5 = list[i];
				if (val.transform.position == val5)
				{
					_placementGhosts[i].SetActive(false);
					continue;
				}
				Requirement obj2 = _fakeResourcePiece.m_resources[0];
				obj2.m_amount += val2.m_amount;
				_placementGhosts[i].transform.position = val5;
				_placementGhosts[i].transform.rotation = val.transform.rotation;
				_placementGhosts[i].SetActive(true);
				bool invalidPlacementHeightlight = false;
				if (val.GetComponent<Piece>().m_cultivatedGroundOnly && !val4.IsCultivated(val5))
				{
					invalidPlacementHeightlight = true;
				}
				else if (!HasGrowSpace(val5, val.gameObject))
				{
					invalidPlacementHeightlight = true;
				}
				else if (num < val3.m_shared.m_attack.m_attackStamina * 1.7999f)
				{
					Hud.instance.StaminaBarUppgradeFlash();
					invalidPlacementHeightlight = true;
				}
				else if (!(bool)m_noPlacementCostField.GetValue(__instance) && !__instance.HaveRequirements(_fakeResourcePiece, (RequirementMode)0))
				{
					invalidPlacementHeightlight = true;
				}
				num -= val3.m_shared.m_attack.m_attackStamina * 1.7999f;
				_placementGhosts[i].GetComponent<Piece>().SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
		}

		private static bool EnsureGhostsBuilt(Player player)
		{
			int num = PluginConfig.PlantGridWidth.Value * PluginConfig.PlantGridLength.Value;
			if (!Object.op_Implicit((Object)(object)_placementGhosts[0]) || _placementGhosts.Length != num)
			{
				DestroyGhosts();
				if (_placementGhosts.Length != num)
				{
					_placementGhosts = (GameObject[])(object)new GameObject[num];
				}
				object? value = m_buildPiecesField.GetValue(player);
				PieceTable val = (PieceTable)((value is PieceTable) ? value : null);
				if (val != null)
				{
					GameObject selectedPrefab = val.GetSelectedPrefab();
					if (selectedPrefab != null)
					{
						if (selectedPrefab.GetComponent<Piece>().m_repairPiece)
						{
							return false;
						}
						for (int i = 0; i < _placementGhosts.Length; i++)
						{
							_placementGhosts[i] = SetupMyGhost(player, selectedPrefab);
						}
						goto IL_00e0;
					}
				}
				return false;
			}
			goto IL_00e0;
			IL_00e0:
			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 (val != null)
				{
					val.SetActive(active);
				}
			}
		}

		private static GameObject SetupMyGhost(Player player, GameObject prefab)
		{
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: 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;
			Joint[] componentsInChildren = val.GetComponentsInChildren<Joint>();
			foreach (Joint val2 in componentsInChildren)
			{
				Object.Destroy((Object)(object)val2);
			}
			Rigidbody[] componentsInChildren2 = val.GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val3 in componentsInChildren2)
			{
				Object.Destroy((Object)(object)val3);
			}
			int layer = LayerMask.NameToLayer("ghost");
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>();
			foreach (Transform val4 in componentsInChildren3)
			{
				((Component)val4).gameObject.layer = layer;
			}
			TerrainModifier[] componentsInChildren4 = val.GetComponentsInChildren<TerrainModifier>();
			foreach (TerrainModifier val5 in componentsInChildren4)
			{
				Object.Destroy((Object)(object)val5);
			}
			GuidePoint[] componentsInChildren5 = val.GetComponentsInChildren<GuidePoint>();
			foreach (GuidePoint val6 in componentsInChildren5)
			{
				Object.Destroy((Object)(object)val6);
			}
			Light[] componentsInChildren6 = val.GetComponentsInChildren<Light>();
			foreach (Light val7 in componentsInChildren6)
			{
				Object.Destroy((Object)(object)val7);
			}
			Transform val8 = val.transform.Find("_GhostOnly");
			if (Object.op_Implicit((Object)(object)val8))
			{
				((Component)val8).gameObject.SetActive(true);
			}
			MeshRenderer[] componentsInChildren7 = val.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val9 in componentsInChildren7)
			{
				if (!((Object)(object)((Renderer)val9).sharedMaterial == (Object)null))
				{
					Material[] sharedMaterials = ((Renderer)val9).sharedMaterials;
					for (int num2 = 0; num2 < sharedMaterials.Length; num2++)
					{
						Material val10 = new Material(sharedMaterials[num2]);
						val10.SetFloat("_RippleDistance", 0f);
						val10.SetFloat("_ValueNoise", 0f);
						sharedMaterials[num2] = val10;
					}
					((Renderer)val9).sharedMaterials = sharedMaterials;
					((Renderer)val9).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			return val;
		}

		static MassPlant()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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;
		}
	}

	public const string PluginGuid = "EardwulfDoesMods.Comfy.MassFarming";

	public const string PluginName = "Comfy.MassFarming";

	public const string PluginVersion = "1.3.1";

	private Harmony _harmony;

	public void Awake()
	{
		PluginConfig.BindConfig(((BaseUnityPlugin)this).Config);
		_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "EardwulfDoesMods.Comfy.MassFarming");
	}
}
public class PluginConfig
{
	public static ConfigEntry<KeyboardShortcut> MassActionHotkey { get; private set; }

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

	public static ConfigEntry<KeyboardShortcut> ControllerPickupHotkey { get; private set; }

	public static ConfigEntry<int> PlantGridWidth { get; private set; }

	public static ConfigEntry<int> PlantGridLength { get; private set; }

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

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

	public static void BindConfig(ConfigFile config)
	{
		//IL_0016: 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_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		MassActionHotkey = config.Bind<KeyboardShortcut>("Hotkeys", "MassActionHotkey", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Mass activation hotkey for multi-plant.");
		ControllerPickupHotkey = config.Bind<KeyboardShortcut>("Hotkeys", "ControllerPickupHotkey", new KeyboardShortcut((KeyCode)334, Array.Empty<KeyCode>()), "Mass activation hotkey for multi-pickup/multi-plant for controller.");
		NoActionKeyNeeded = config.Bind<bool>("Override Grid Plant", "NoActionKeyNeeded", false, "Enable or disable grid planting without an action key");
		PlantGridWidth = config.Bind<int>("Plant Grid", "Plant Grid Width", 3, new ConfigDescription("The width of mass planting grid.  Default value is 3.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>()));
		PlantGridLength = config.Bind<int>("Plant Grid", "Plant Grid Length", 3, new ConfigDescription("The lenght of the mass planting grid.  Default value is 3.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>()));
		GridAnchorWidth = config.Bind<bool>("PlantGrid", "GridAnchorWidth", true, "Planting grid anchor point (width). Default is 'enabled' so the grid will extend left and right from the crosshairs. Disable to set the anchor to the side of the grid. Disable both anchors to set to corner.");
		GridAnchorLength = config.Bind<bool>("PlantGrid", "GridAnchorLength", true, "Planting grid anchor point (length). Default is 'enabled' so the grid will extend forward and backward from the crosshairs. Disable to set the anchor to the side of the grid. Disable both anchors to set to corner.");
	}
}