Decompiled source of PlantEasily v1.7.3

Advize_PlantEasily.dll

Decompiled 3 weeks 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 Advize_PlantEasily.Configuration;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Advize_PlantEasily")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Valheim Game Modification")]
[assembly: AssemblyCopyright("Copyright © Advize 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5eaff7d4-7661-4152-a841-ed19ba3b36f4")]
[assembly: AssemblyFileVersion("1.7.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.3.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
}
namespace Advize_PlantEasily
{
	[BepInPlugin("advize.PlantEasily", "PlantEasily", "1.7.3")]
	public class PlantEasily : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Player), "UpdateBuildGuiInput")]
		public class PlayerUpdateBuildGuiInput
		{
			public static void Prefix(Player __instance)
			{
				//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_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: 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_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: 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_01a4: 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_0219: Unknown result type (might be due to invalid IL or missing references)
				//IL_0249: Unknown result type (might be due to invalid IL or missing references)
				KeyboardShortcut val = config.EnableModKey;
				if (((KeyboardShortcut)(ref val)).IsDown())
				{
					config.ModActive = !config.ModActive;
					Dbgl($"modActive was {!config.ModActive} setting to {config.ModActive}", forceLog: false, (LogLevel)16);
					((Character)__instance).Message((MessageType)1, $"PlantEasily.ModActive: {config.ModActive}", 0, (Sprite)null);
					if (HoldingCultivator)
					{
						__instance.SetupPlacementGhost();
					}
				}
				val = config.EnableSnappingKey;
				if (((KeyboardShortcut)(ref val)).IsDown())
				{
					config.SnapActive = !config.SnapActive;
					Dbgl($"snapActive was {!config.SnapActive} setting to {config.SnapActive}", forceLog: false, (LogLevel)16);
					((Character)__instance).Message((MessageType)1, $"PlantEasily.SnapActive: {config.SnapActive}", 0, (Sprite)null);
				}
				val = config.ToggleAutoReplantKey;
				if (((KeyboardShortcut)(ref val)).IsDown())
				{
					config.ReplantOnHarvest = !config.ReplantOnHarvest;
					Dbgl($"replantOnHarvest was {!config.ReplantOnHarvest} setting to {config.ReplantOnHarvest}", forceLog: false, (LogLevel)16);
					((Character)__instance).Message((MessageType)1, $"PlantEasily.ReplantOnHarvest: {config.ReplantOnHarvest}", 0, (Sprite)null);
				}
				if (ZInput.GetKey(config.KeyboardModifierKey, true) || ZInput.GetKey(config.GamepadModifierKey, true))
				{
					if (ZInput.GetKeyDown(config.IncreaseXKey, false) || ZInput.GetButtonDown("JoyDPadRight"))
					{
						config.Columns++;
					}
					if (ZInput.GetKeyDown(config.IncreaseYKey, false) || ZInput.GetButtonDown("JoyDPadUp"))
					{
						config.Rows++;
					}
					if (ZInput.GetKeyDown(config.DecreaseXKey, false) || ZInput.GetButtonDown("JoyDPadLeft"))
					{
						config.Columns--;
					}
					if (ZInput.GetKeyDown(config.DecreaseYKey, false) || ZInput.GetButtonDown("JoyDPadDown"))
					{
						config.Rows--;
					}
				}
			}
		}

		[HarmonyPatch(typeof(HotkeyBar), "Update")]
		public class HotKeyBarUpdate
		{
			public static void Prefix(ref bool __runOriginal)
			{
				__runOriginal = !OverrideGamepadInput;
			}
		}

		[HarmonyPatch(typeof(Player), "StartGuardianPower")]
		public class PlayerStartGuardianPower
		{
			public static void Prefix(ref bool __runOriginal)
			{
				__runOriginal = !OverrideGamepadInput;
			}
		}

		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public class PlayerSetupPlacementGhost
		{
			public static int placementRotation;

			public static void Prefix()
			{
				if (config.ModActive && HoldingCultivator)
				{
					placementRotation = Player.m_localPlayer.m_placeRotation;
				}
			}

			public static void Postfix(GameObject ___m_placementGhost, ref int ___m_placeRotation)
			{
				DestroyGhosts();
				if (config.ModActive && Object.op_Implicit((Object)(object)___m_placementGhost) && HoldingCultivator && IsPlantOrPickable(___m_placementGhost))
				{
					___m_placeRotation = placementRotation;
					CreateGhosts(___m_placementGhost);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		public class PlayerUpdatePlacementGhost
		{
			private class SnapPosition
			{
				internal Vector3 rowDirection;

				internal Vector3 columnDirection;

				internal Vector3 position;

				internal SnapPosition(Vector3 rd, Vector3 cd, Vector3 p)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_000f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					rowDirection = rd;
					columnDirection = cd;
					position = p;
				}
			}

			private static bool FindSnapPoints(List<SnapPosition> snapPoints, Collider collider, Vector3 rowDirection, Vector3 columnDirection, Plant plant)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0044: 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_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: 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_008e: 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_00e1: 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_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				Vector3[] array = (Vector3[])(object)new Vector3[4]
				{
					((Component)collider).transform.position + rowDirection,
					((Component)collider).transform.position + columnDirection,
					((Component)collider).transform.position - rowDirection,
					((Component)collider).transform.position - columnDirection
				};
				foreach (Vector3 val in array)
				{
					bool flag = false;
					bool flag2 = false;
					if (PositionHasCollisions(val) || (Object.op_Implicit((Object)(object)plant) && !HasGrowSpace(plant, val)))
					{
						continue;
					}
					if (config.GridSnappingStyle == GridSnappingStyle.Intelligent)
					{
						if (config.Rows > 1 && PositionHasCollisions(val + rowDirection))
						{
							flag = true;
						}
						if (config.Columns > 1 && PositionHasCollisions(val + columnDirection))
						{
							flag2 = true;
						}
					}
					snapPoints.Add(new SnapPosition((!flag) ? rowDirection : (-rowDirection), (!flag2) ? columnDirection : (-columnDirection), val));
				}
				return snapPoints.Count > 0;
			}

			public static void Prefix(Player __instance, GameObject ___m_placementGhost)
			{
				if (config.ModActive && Object.op_Implicit((Object)(object)___m_placementGhost) && HoldingCultivator && IsPlantOrPickable(___m_placementGhost) && (ghostPlacementStatus.Count == 0 || (extraGhosts.Count == 0 && (config.Rows != 1 || config.Columns != 1))))
				{
					__instance.SetupPlacementGhost();
				}
			}

			public static void Postfix(Player __instance, ref GameObject ___m_placementGhost, ref int ___m_placementStatus)
			{
				//IL_0065: 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_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_007c: 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_008c: 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_0095: 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_00d3: 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_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: 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_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: 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_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03be: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_038a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0395: Unknown result type (might be due to invalid IL or missing references)
				//IL_039a: Unknown result type (might be due to invalid IL or missing references)
				//IL_039f: Unknown result type (might be due to invalid IL or missing references)
				//IL_033b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0340: Unknown result type (might be due to invalid IL or missing references)
				//IL_0341: Unknown result type (might be due to invalid IL or missing references)
				//IL_0348: Unknown result type (might be due to invalid IL or missing references)
				//IL_034a: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_035d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0362: Unknown result type (might be due to invalid IL or missing references)
				//IL_0366: Unknown result type (might be due to invalid IL or missing references)
				//IL_036b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02da: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f1: 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_0236: 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_024c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0251: Unknown result type (might be due to invalid IL or missing references)
				//IL_0253: Unknown result type (might be due to invalid IL or missing references)
				//IL_0258: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: 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_047c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0456: Unknown result type (might be due to invalid IL or missing references)
				//IL_045b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0460: Unknown result type (might be due to invalid IL or missing references)
				//IL_0465: Unknown result type (might be due to invalid IL or missing references)
				//IL_046a: Unknown result type (might be due to invalid IL or missing references)
				//IL_046f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0474: Unknown result type (might be due to invalid IL or missing references)
				//IL_0270: Unknown result type (might be due to invalid IL or missing references)
				//IL_026d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0481: Unknown result type (might be due to invalid IL or missing references)
				//IL_0483: Unknown result type (might be due to invalid IL or missing references)
				//IL_049d: Unknown result type (might be due to invalid IL or missing references)
				//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0271: 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_0279: Unknown result type (might be due to invalid IL or missing references)
				//IL_027e: Unknown result type (might be due to invalid IL or missing references)
				//IL_028f: Unknown result type (might be due to invalid IL or missing references)
				//IL_028c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0290: Unknown result type (might be due to invalid IL or missing references)
				//IL_0292: Unknown result type (might be due to invalid IL or missing references)
				//IL_0298: 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)
				//IL_02a7: 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)
				if (!config.ModActive || !Object.op_Implicit((Object)(object)___m_placementGhost) || !HoldingCultivator || !IsPlantOrPickable(___m_placementGhost))
				{
					return;
				}
				for (int i = 0; i < extraGhosts.Count; i++)
				{
					extraGhosts[i].SetActive(___m_placementGhost.activeSelf);
				}
				Vector3 basePosition = ___m_placementGhost.transform.position;
				Quaternion rotation;
				Quaternion val = (rotation = ___m_placementGhost.transform.rotation);
				if (config.StandardizeGridRotations)
				{
					Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
					eulerAngles.x = Mathf.Round(eulerAngles.x / 90f) * 90f;
					eulerAngles.y = Mathf.Round(eulerAngles.y / 90f) * 90f;
					eulerAngles.z = Mathf.Round(eulerAngles.z / 90f) * 90f;
					((Quaternion)(ref rotation)).eulerAngles = eulerAngles;
				}
				float pieceSpacing = GetPieceSpacing(___m_placementGhost);
				Vector3 val2 = (config.GloballyAlignGridDirections ? Vector3.forward : Utils.DirectionXZ(basePosition - ((Component)__instance).transform.position));
				Vector3 val3 = Vector3.Cross(Vector3.up, val2);
				bool flag = false;
				if (config.SnapActive)
				{
					List<SnapPosition> snapPoints = new List<SnapPosition>();
					Plant component = ___m_placementGhost.GetComponent<Plant>();
					Collider[] array = Physics.OverlapSphere(___m_placementGhost.transform.position, pieceSpacing, CollisionMask);
					int num = 0;
					Collider[] array2 = array;
					foreach (Collider val4 in array2)
					{
						if (!IsPlantOrPickable(((Component)((Component)val4).transform.root).gameObject))
						{
							continue;
						}
						num++;
						if (num > 8)
						{
							break;
						}
						Collider[] array3 = Physics.OverlapSphere(((Component)val4).transform.position, pieceSpacing, CollisionMask);
						int num2 = 0;
						Collider[] array4 = array3;
						foreach (Collider val5 in array4)
						{
							if (IsPlantOrPickable(((Component)((Component)val5).transform.root).gameObject) && !((Object)(object)((Component)val5).transform.root == (Object)(object)((Component)val4).transform.root))
							{
								num2++;
								if (num2 > 8)
								{
									break;
								}
								val2 = Utils.DirectionXZ(((Component)val5).transform.position - ((Component)val4).transform.position);
								val3 = Vector3.Cross(Vector3.up, val2);
								val2 = (config.StandardizeGridRotations ? rotation : val) * val2 * pieceSpacing;
								val3 = (config.StandardizeGridRotations ? rotation : val) * val3 * pieceSpacing;
								flag = FindSnapPoints(snapPoints, val4, val2, val3, component);
							}
						}
						if (!flag)
						{
							val2 = val * val2 * pieceSpacing;
							val3 = val * val3 * pieceSpacing;
							flag = FindSnapPoints(snapPoints, val4, val2, val3, component);
						}
					}
					if (flag)
					{
						SnapPosition snapPosition = snapPoints.OrderBy(delegate(SnapPosition o)
						{
							//IL_002a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0030: Unknown result type (might be due to invalid IL or missing references)
							//IL_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)
							float num6 = snapPoints.Min((SnapPosition m) => Utils.DistanceXZ(m.position, o.position));
							Vector3 val9 = o.position - basePosition;
							return num6 + ((Vector3)(ref val9)).magnitude;
						}).First();
						Vector3 val6 = (___m_placementGhost.transform.position = snapPosition.position);
						basePosition = val6;
						if (config.GridSnappingStyle == GridSnappingStyle.Intelligent)
						{
							val2 = snapPosition.rowDirection;
							val3 = snapPosition.columnDirection;
						}
					}
				}
				if (!flag)
				{
					if (config.SnapActive)
					{
						val2 = (config.GloballyAlignGridDirections ? Vector3.forward : Utils.DirectionXZ(basePosition - ((Component)__instance).transform.position));
						val3 = Vector3.Cross(Vector3.up, val2);
					}
					val2 = val * val2 * pieceSpacing;
					val3 = val * val3 * pieceSpacing;
				}
				Piece component2 = ___m_placementGhost.GetComponent<Piece>();
				int amount = component2.m_resources[0].m_amount;
				int num3 = 0;
				float y = default(float);
				for (int l = 0; l < config.Rows; l++)
				{
					for (int n = 0; n < config.Columns; n++)
					{
						num3 += amount;
						component2.m_resources[0].m_amount = num3;
						bool num4 = n == 0 && l == 0;
						int num5 = l * config.Columns + n;
						GameObject val7 = (num4 ? ___m_placementGhost : extraGhosts[num5 - 1]);
						Vector3 val8 = (num4 ? basePosition : (basePosition + val2 * (float)l + val3 * (float)n));
						Heightmap.GetHeight(val8, ref y);
						val8.y = y;
						val7.transform.position = val8;
						val7.transform.rotation = ___m_placementGhost.transform.rotation;
						Status placementStatus = Status.Healthy;
						if (!__instance.m_noPlacementCost && !__instance.HaveRequirements(component2, (RequirementMode)0))
						{
							placementStatus = Status.LackResources;
						}
						SetPlacementGhostStatus(val7, num5, CheckPlacementStatus(val7, placementStatus), ref ___m_placementStatus);
					}
				}
				component2.m_resources[0].m_amount = amount;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		public class PlayerPlacePiece
		{
			public static int placementRotation;

			public static bool Prefix(Player __instance, Piece piece, ref bool __result, ref bool __state)
			{
				if (!config.ModActive || !Object.op_Implicit((Object)(object)piece) || !HoldingCultivator || !IsPlantOrPickable(((Component)piece).gameObject))
				{
					return true;
				}
				__state = true;
				placementRotation = __instance.m_placeRotation;
				if (config.PreventInvalidPlanting)
				{
					int num = (int)CheckPlacementStatus(__instance.m_placementGhost);
					if (num > 1)
					{
						((Character)__instance).Message((MessageType)2, statusMessage[num], 0, (Sprite)null);
						return __state = (__result = false);
					}
				}
				if (config.PreventPartialPlanting)
				{
					foreach (Status item in ghostPlacementStatus)
					{
						if (item != 0 && (item != Status.LackResources || !__instance.m_noPlacementCost))
						{
							((Character)__instance).Message((MessageType)2, statusMessage[(int)item], 0, (Sprite)null);
							return __state = (__result = false);
						}
					}
				}
				return true;
			}

			public static void Postfix(Player __instance, Piece piece, bool __state)
			{
				if (!config.ModActive || !__state || !Object.op_Implicit((Object)(object)piece) || !HoldingCultivator || !IsPlantOrPickable(((Component)piece).gameObject))
				{
					return;
				}
				__instance.m_placeRotation = placementRotation;
				ItemData rightItem = ((Humanoid)__instance).GetRightItem();
				int num = extraGhosts.Count;
				for (int i = 0; i < extraGhosts.Count; i++)
				{
					if (ghostPlacementStatus[i + 1] != 0 && (ghostPlacementStatus[i + 1] != Status.LackResources || !__instance.m_noPlacementCost) && (config.PreventInvalidPlanting || ghostPlacementStatus[i + 1] <= Status.LackResources))
					{
						num--;
					}
					else
					{
						PlacePiece(__instance, extraGhosts[i], piece);
					}
				}
				num = ((!__instance.m_noPlacementCost) ? num : 0);
				for (int j = 0; j < num; j++)
				{
					__instance.ConsumeResources(piece.m_resources, 0, -1);
				}
				if (config.UseStamina)
				{
					((Character)__instance).UseStamina(rightItem.m_shared.m_attack.m_attackStamina * (float)num, true);
				}
				if (rightItem.m_shared.m_useDurability && config.UseDurability)
				{
					rightItem.m_durability -= rightItem.m_shared.m_useDurabilityDrain * (float)num;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Interact")]
		public class PlayerInteract
		{
			private static string GetPrefabName(Interactable i)
			{
				return ((object)i).ToString().Replace("(Clone) (Pickable)", "");
			}

			public static void Prefix(Player __instance, GameObject go, bool hold, bool alt)
			{
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				if (!config.ModActive || (!config.EnableBulkHarvest && !config.ReplantOnHarvest) || ((Character)__instance).InAttack() || ((Character)__instance).InDodge() || (hold && Time.time - __instance.m_lastHoverInteractTime < 0.2f))
				{
					return;
				}
				Interactable componentInParent = go.GetComponentInParent<Interactable>();
				if (componentInParent == null)
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)((componentInParent is Pickable) ? componentInParent : null)) && config.ReplantOnHarvest && pickablesToPlants.ContainsKey(GetPrefabName(componentInParent)))
				{
					instanceIDS.Add(((Object)(Pickable)componentInParent).GetInstanceID());
				}
				if (!config.EnableBulkHarvest || (!ZInput.GetKey(config.KeyboardHarvestModifierKey, false) && !ZInput.GetKey(config.GamepadModifierKey, false)) || (!Object.op_Implicit((Object)(object)((componentInParent is Pickable) ? componentInParent : null)) && !Object.op_Implicit((Object)(object)((componentInParent is Beehive) ? componentInParent : null))))
				{
					return;
				}
				foreach (Interactable item in FindResourcesInRadius(go))
				{
					if (config.ReplantOnHarvest && pickablesToPlants.ContainsKey(GetPrefabName(item)))
					{
						instanceIDS.Add(((Object)(Pickable)item).GetInstanceID());
					}
					item.Interact((Humanoid)(object)__instance, hold, alt);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
		public class InventoryGuiSetupRequirement
		{
			[HarmonyPriority(0)]
			public static void Postfix(Transform elementRoot, Requirement req)
			{
				if (extraGhosts.Count >= 1 && config.ShowCost)
				{
					TMP_Text component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>();
					int count = ghostPlacementStatus.Count;
					string text = ((config.CostDisplayStyle != 0) ? $"({req.m_amount * count})" : ((config.CostDisplayLocation == CostDisplayLocation.LeftSide) ? $"{count}x" : $"x{count}"));
					component.text = ((config.CostDisplayLocation == CostDisplayLocation.LeftSide) ? (text + component.text) : (component.text + text));
				}
			}
		}

		[HarmonyPatch(typeof(Pickable), "SetPicked")]
		public class PickableSetPicked
		{
			public static void Prefix(Pickable __instance, bool picked)
			{
				if (!config.ModActive || !config.ReplantOnHarvest || instanceIDS.Count == 0 || !picked)
				{
					return;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				if (instanceIDS.Contains(instanceID))
				{
					instanceIDS.Remove(instanceID);
					Player localPlayer = Player.m_localPlayer;
					Piece component = prefabRefs[pickablesToPlants[((Object)__instance).name.Replace("(Clone)", "")]].GetComponent<Piece>();
					if (localPlayer.HaveRequirements(component, (RequirementMode)0) || Player.m_localPlayer.m_noPlacementCost)
					{
						PlacePiece(localPlayer, ((Component)__instance).gameObject, component);
						localPlayer.ConsumeResources(component.m_resources, 0, -1);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class ObjectDBAwake
		{
			public static void Postfix()
			{
				InitPrefabRefs();
			}
		}

		private enum Status
		{
			Healthy,
			LackResources,
			NotCultivated,
			WrongBiome,
			NoSpace,
			NoSun,
			Invalid
		}

		public const string PluginID = "advize.PlantEasily";

		public const string PluginName = "PlantEasily";

		public const string Version = "1.7.3";

		private static readonly ManualLogSource PELogger = new ManualLogSource(" PlantEasily");

		private static ModConfig config;

		private static readonly Dictionary<string, GameObject> prefabRefs = new Dictionary<string, GameObject>();

		private static GameObject placementGhost;

		private static readonly List<GameObject> extraGhosts = new List<GameObject>();

		private static readonly List<Status> ghostPlacementStatus = new List<Status>();

		private static readonly List<int> instanceIDS = new List<int>();

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

		private static readonly Dictionary<int, string> statusMessage = new Dictionary<int, string>
		{
			{ 1, "$msg_missingrequirement" },
			{ 2, "$piece_plant_notcultivated" },
			{ 3, "$piece_plant_wrongbiome" },
			{ 4, "$piece_plant_nospace" },
			{ 5, "$piece_plant_nosun" },
			{ 6, "$msg_invalidplacement" }
		};

		private static readonly Dictionary<string, string> pickablesToPlants = new Dictionary<string, string>
		{
			{ "Pickable_SeedOnion", "sapling_seedonion" },
			{ "Pickable_Onion", "sapling_onion" },
			{ "Pickable_Turnip", "sapling_turnip" },
			{ "Pickable_Barley", "sapling_barley" },
			{ "Pickable_Mushroom_JotunPuffs", "sapling_jotunpuffs" },
			{ "Pickable_Carrot", "sapling_carrot" },
			{ "Pickable_SeedCarrot", "sapling_seedcarrot" },
			{ "Pickable_Flax", "sapling_flax" },
			{ "Pickable_Mushroom_Magecap", "sapling_magecap" },
			{ "Pickable_SeedTurnip", "sapling_seedturnip" }
		};

		private static bool HoldingCultivator
		{
			get
			{
				Player localPlayer = Player.m_localPlayer;
				return ((localPlayer == null) ? null : ((Humanoid)localPlayer).GetRightItem()?.m_shared.m_name) == "$item_cultivator";
			}
		}

		private static bool OverrideGamepadInput
		{
			get
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)placementGhost))
				{
					return ZInput.GetKey(config.GamepadModifierKey, false);
				}
				return false;
			}
		}

		public void Awake()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Logger.Sources.Add((ILogSource)(object)PELogger);
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				Dbgl("This mod is client-side only and is not needed on a dedicated server. Plugin patches will not be applied.", forceLog: true, (LogLevel)4);
				return;
			}
			config = new ModConfig(((BaseUnityPlugin)this).Config);
			new Harmony("advize.PlantEasily").PatchAll();
		}

		private static bool IsPlantOrPickable(GameObject go)
		{
			if (!Object.op_Implicit((Object)(object)go.GetComponent<Plant>()))
			{
				return Object.op_Implicit((Object)(object)go.GetComponent<Pickable>());
			}
			return true;
		}

		internal static void GridSizeChanged(object sender, EventArgs e)
		{
			DestroyGhosts();
		}

		private static void DestroyGhosts()
		{
			if (extraGhosts.Count > 0)
			{
				foreach (GameObject extraGhost in extraGhosts)
				{
					Object.Destroy((Object)(object)extraGhost);
				}
				extraGhosts.Clear();
			}
			ghostPlacementStatus.Clear();
		}

		private static void CreateGhosts(GameObject rootGhost)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < config.Rows; i++)
			{
				for (int j = 0; j < config.Columns; j++)
				{
					if (i == 0 && j == 0)
					{
						placementGhost = rootGhost;
						ghostPlacementStatus.Add(Status.Healthy);
						continue;
					}
					ZNetView.m_forceDisableInit = true;
					GameObject val = Object.Instantiate<GameObject>(rootGhost);
					ZNetView.m_forceDisableInit = false;
					((Object)val).name = ((Object)rootGhost).name;
					int layer = LayerMask.NameToLayer("ghost");
					Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>();
					for (int k = 0; k < componentsInChildren.Length; k++)
					{
						((Component)componentsInChildren[k]).gameObject.layer = layer;
					}
					val.transform.position = rootGhost.transform.position;
					val.transform.localScale = rootGhost.transform.localScale;
					extraGhosts.Add(val);
					ghostPlacementStatus.Add(Status.Healthy);
				}
			}
		}

		private static bool HasGrowSpace(Plant plant, Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Physics.OverlapSphere(position, plant.m_growRadius, Plant.m_spaceMask).Length == 0;
		}

		private static bool PositionHasCollisions(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			return Physics.CheckCapsule(position, position + Vector3.up / 2f, 0.0001f, CollisionMask);
		}

		private static float GetPieceSpacing(GameObject go)
		{
			float num = 0f;
			bool flag = false;
			Plant component = go.GetComponent<Plant>();
			if (Object.op_Implicit((Object)(object)component))
			{
				List<GameObject> list = new List<GameObject>();
				list.Add(go);
				list.AddRange(component.m_grownPrefabs);
				flag = list.Any((GameObject x) => Object.op_Implicit((Object)(object)x.GetComponent<TreeBase>()));
				if (config.MinimizeGridSpacing && !flag)
				{
					for (int i = 0; i < list.Count; i++)
					{
						CapsuleCollider[] componentsInChildren = list[i].GetComponentsInChildren<CapsuleCollider>();
						foreach (CapsuleCollider val in componentsInChildren)
						{
							num = Mathf.Max(num, val.radius);
						}
					}
				}
				num += (flag ? config.ExtraSaplingSpacing : config.ExtraCropSpacing);
			}
			return (flag ? (component.m_growRadius * 2.2f) : ((component?.m_growRadius * (config.MinimizeGridSpacing ? 1.1f : 2f)) ?? PickableSnapRadius(((Object)go).name))) + num;
		}

		private static float PickableSnapRadius(string name)
		{
			if (name.EndsWith("berryBush"))
			{
				return config.BerryBushSnapRadius;
			}
			if (name.StartsWith("Pickable_Mushroom"))
			{
				return config.MushroomSnapRadius;
			}
			if (name.Contains("Dandelion") || name.Contains("Thistle"))
			{
				return config.FlowerSnapRadius;
			}
			return config.PickableSnapRadius;
		}

		private static void SetPlacementGhostStatus(GameObject ghost, int index, Status placementStatus, ref int m_placementStatus)
		{
			ghost.GetComponent<Piece>().SetInvalidPlacementHeightlight(placementStatus != Status.Healthy);
			if (ghostPlacementStatus.Count > index)
			{
				ghostPlacementStatus[index] = placementStatus;
				if (index == 0 && placementStatus == Status.Healthy)
				{
					m_placementStatus = 0;
				}
			}
		}

		private static Status CheckPlacementStatus(GameObject ghost, Status placementStatus = Status.Healthy)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0036: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0067: 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_007c: 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)
			Piece component = ghost.GetComponent<Piece>();
			Plant component2 = ghost.GetComponent<Plant>();
			Vector3 position = ghost.transform.position;
			Heightmap val = Heightmap.FindHeightmap(position);
			bool num = component2?.m_needCultivatedGround ?? component.m_cultivatedGroundOnly;
			Biome val2 = component2?.m_biome ?? component.m_onlyInBiome;
			if (num && Object.op_Implicit((Object)(object)val) && !val.IsCultivated(position))
			{
				placementStatus = Status.NotCultivated;
			}
			if ((int)val2 != 0 && (Heightmap.FindBiome(position) & val2) == 0)
			{
				placementStatus = Status.WrongBiome;
			}
			if (Object.op_Implicit((Object)(object)component2) && !HasGrowSpace(component2, ghost.transform.position))
			{
				placementStatus = Status.NoSpace;
			}
			if (Object.op_Implicit((Object)(object)component2) && (bool)Traverse.Create((object)component2).Method("HaveRoof", Array.Empty<object>()).GetValue())
			{
				placementStatus = Status.NoSun;
			}
			if (!Object.op_Implicit((Object)(object)component2) && config.PreventOverlappingPlacements && PositionHasCollisions(position))
			{
				placementStatus = Status.NoSpace;
			}
			return placementStatus;
		}

		private static List<Interactable> FindResourcesInRadius(GameObject rootInteractable)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			List<Interactable> list = new List<Interactable>();
			Collider[] array = Physics.OverlapSphere(rootInteractable.transform.root.position, config.HarvestRadius, CollisionMask);
			foreach (Collider obj in array)
			{
				Pickable componentInParent = ((Component)obj).GetComponentInParent<Pickable>();
				Beehive componentInParent2 = ((Component)obj).GetComponentInParent<Beehive>();
				if (!Object.op_Implicit((Object)(object)componentInParent) && !Object.op_Implicit((Object)(object)componentInParent2))
				{
					continue;
				}
				GameObject val = ((componentInParent != null) ? ((Component)componentInParent).gameObject : null) ?? ((Component)componentInParent2).gameObject;
				if ((Object)(object)val.transform.root != (Object)(object)rootInteractable.transform.root && (config.HarvestStyle != 0 || !(((Object)val.transform.root).name != ((Object)rootInteractable.transform.root).name)) && (!Object.op_Implicit((Object)(object)componentInParent2) || componentInParent2.GetHoneyLevel() >= 1))
				{
					Interactable val2 = (Interactable)(object)componentInParent;
					Interactable item = (Interactable)(((object)val2) ?? ((object)componentInParent2));
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		private static void PlacePiece(Player player, GameObject go, Piece piece)
		{
			//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_003e: 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_0043: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = go.transform.position;
			Quaternion val = (config.RandomizeRotation ? Quaternion.Euler(0f, 22.5f * (float)Random.Range(0, 16), 0f) : go.transform.rotation);
			GameObject gameObject = ((Component)piece).gameObject;
			TerrainModifier.SetTriggerOnPlaced(true);
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, position, val);
			TerrainModifier.SetTriggerOnPlaced(false);
			val2.GetComponent<Piece>().SetCreator(player.GetPlayerID());
			piece.m_placeEffect.Create(position, val, val2.transform, 1f, -1);
			((Character)player).AddNoise(50f);
			Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f);
			Gogan.LogEvent("Game", "PlacedPiece", ((Object)gameObject).name, 0L);
		}

		private static void InitPrefabRefs()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			Dbgl("InitPrefabRefs", forceLog: false, (LogLevel)16);
			if (prefabRefs.Count > 0)
			{
				return;
			}
			foreach (string value in pickablesToPlants.Values)
			{
				prefabRefs.Add(value, null);
			}
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(GameObject));
			for (int i = 0; i < array.Length; i++)
			{
				GameObject val = (GameObject)array[i];
				if (prefabRefs.ContainsKey(((Object)val).name))
				{
					prefabRefs[((Object)val).name] = val;
					if (!prefabRefs.Any((KeyValuePair<string, GameObject> key) => !Object.op_Implicit((Object)(object)key.Value)))
					{
						Dbgl("Found all prefab references", forceLog: false, (LogLevel)16);
						break;
					}
				}
			}
		}

		internal static void Dbgl(string message, bool forceLog = false, LogLevel level = 16)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (!forceLog && !config.EnableDebugMessages)
			{
				return;
			}
			if ((int)level <= 8)
			{
				switch (level - 1)
				{
				case 1:
					PELogger.LogError((object)message);
					return;
				case 3:
					PELogger.LogWarning((object)message);
					return;
				case 0:
					PELogger.LogFatal((object)message);
					return;
				case 2:
					return;
				}
				if ((int)level == 8)
				{
					PELogger.LogMessage((object)message);
				}
			}
			else if ((int)level != 16)
			{
				if ((int)level == 32)
				{
					PELogger.LogDebug((object)message);
				}
			}
			else
			{
				PELogger.LogInfo((object)message);
			}
		}
	}
}
namespace Advize_PlantEasily.Configuration
{
	internal class ModConfig
	{
		internal class ConfigurationManagerAttributes
		{
			public string? Description;

			public int? Order;
		}

		private readonly ConfigFile Config;

		private readonly ConfigEntry<bool> enableDebugMessages;

		private readonly ConfigEntry<int> rows;

		private readonly ConfigEntry<int> columns;

		private readonly ConfigEntry<bool> modActive;

		private readonly ConfigEntry<bool> snapActive;

		private readonly ConfigEntry<bool> preventPartialPlanting;

		private readonly ConfigEntry<bool> preventInvalidPlanting;

		private readonly ConfigEntry<bool> randomizeRotation;

		private readonly ConfigEntry<bool> useStamina;

		private readonly ConfigEntry<bool> useDurability;

		private readonly ConfigEntry<float> extraCropSpacing;

		private readonly ConfigEntry<float> extraSaplingSpacing;

		private readonly ConfigEntry<GridSnappingStyle> gridSnappingStyle;

		private readonly ConfigEntry<bool> standardizeGridRotations;

		private readonly ConfigEntry<bool> minimizeGridSpacing;

		private readonly ConfigEntry<bool> globallyAlignGridDirections;

		private readonly ConfigEntry<float> pickableSnapRadius;

		private readonly ConfigEntry<float> berryBushSnapRadius;

		private readonly ConfigEntry<float> mushroomSnapRadius;

		private readonly ConfigEntry<float> flowerSnapRadius;

		private readonly ConfigEntry<bool> preventOverlappingPlacements;

		private readonly ConfigEntry<bool> enableBulkHarvest;

		private readonly ConfigEntry<HarvestStyle> harvestStyle;

		private readonly ConfigEntry<float> harvestRadius;

		private readonly ConfigEntry<bool> replantOnHarvest;

		private readonly ConfigEntry<KeyboardShortcut> enableModKey;

		private readonly ConfigEntry<KeyboardShortcut> enableSnappingKey;

		private readonly ConfigEntry<KeyboardShortcut> increaseXKey;

		private readonly ConfigEntry<KeyboardShortcut> increaseYKey;

		private readonly ConfigEntry<KeyboardShortcut> decreaseXKey;

		private readonly ConfigEntry<KeyboardShortcut> decreaseYKey;

		private readonly ConfigEntry<KeyboardShortcut> keyboardModifierKey;

		private readonly ConfigEntry<KeyboardShortcut> gamepadModifierKey;

		private readonly ConfigEntry<KeyboardShortcut> keyboardHarvestModifierKey;

		private readonly ConfigEntry<KeyboardShortcut> toggleAutoReplantKey;

		private readonly ConfigEntry<bool> showCost;

		private readonly ConfigEntry<CostDisplayStyle> costDisplayStyle;

		private readonly ConfigEntry<CostDisplayLocation> costDisplayLocation;

		internal bool EnableDebugMessages => enableDebugMessages.Value;

		internal int Rows
		{
			get
			{
				return Mathf.Max(rows.Value, 1);
			}
			set
			{
				((ConfigEntryBase)rows).BoxedValue = Mathf.Max(value, 1);
			}
		}

		internal int Columns
		{
			get
			{
				return Mathf.Max(columns.Value, 1);
			}
			set
			{
				((ConfigEntryBase)columns).BoxedValue = Mathf.Max(value, 1);
			}
		}

		internal bool ModActive
		{
			get
			{
				return modActive.Value;
			}
			set
			{
				((ConfigEntryBase)modActive).BoxedValue = value;
			}
		}

		internal bool SnapActive
		{
			get
			{
				return snapActive.Value;
			}
			set
			{
				((ConfigEntryBase)snapActive).BoxedValue = value;
			}
		}

		internal float PickableSnapRadius => pickableSnapRadius.Value;

		internal float BerryBushSnapRadius => berryBushSnapRadius.Value;

		internal float MushroomSnapRadius => mushroomSnapRadius.Value;

		internal float FlowerSnapRadius => flowerSnapRadius.Value;

		internal bool PreventOverlappingPlacements => preventOverlappingPlacements.Value;

		internal bool PreventPartialPlanting => preventPartialPlanting.Value;

		internal bool PreventInvalidPlanting => preventInvalidPlanting.Value;

		internal bool RandomizeRotation => randomizeRotation.Value;

		internal bool UseStamina => useStamina.Value;

		internal bool UseDurability => useDurability.Value;

		internal float ExtraCropSpacing => extraCropSpacing.Value;

		internal float ExtraSaplingSpacing => extraSaplingSpacing.Value;

		internal GridSnappingStyle GridSnappingStyle => gridSnappingStyle.Value;

		internal bool StandardizeGridRotations => standardizeGridRotations.Value;

		internal bool MinimizeGridSpacing => minimizeGridSpacing.Value;

		internal bool GloballyAlignGridDirections => globallyAlignGridDirections.Value;

		internal bool EnableBulkHarvest => enableBulkHarvest.Value;

		internal HarvestStyle HarvestStyle => harvestStyle.Value;

		internal float HarvestRadius => harvestRadius.Value;

		internal bool ReplantOnHarvest
		{
			get
			{
				return replantOnHarvest.Value;
			}
			set
			{
				((ConfigEntryBase)replantOnHarvest).BoxedValue = value;
			}
		}

		internal KeyboardShortcut EnableModKey => enableModKey.Value;

		internal KeyboardShortcut EnableSnappingKey => enableSnappingKey.Value;

		internal KeyCode IncreaseXKey
		{
			get
			{
				//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)
				KeyboardShortcut value = increaseXKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode IncreaseYKey
		{
			get
			{
				//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)
				KeyboardShortcut value = increaseYKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode DecreaseXKey
		{
			get
			{
				//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)
				KeyboardShortcut value = decreaseXKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode DecreaseYKey
		{
			get
			{
				//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)
				KeyboardShortcut value = decreaseYKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode KeyboardModifierKey
		{
			get
			{
				//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)
				KeyboardShortcut value = keyboardModifierKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode GamepadModifierKey
		{
			get
			{
				//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)
				KeyboardShortcut value = gamepadModifierKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyCode KeyboardHarvestModifierKey
		{
			get
			{
				//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)
				KeyboardShortcut value = keyboardHarvestModifierKey.Value;
				return ((KeyboardShortcut)(ref value)).MainKey;
			}
		}

		internal KeyboardShortcut ToggleAutoReplantKey => toggleAutoReplantKey.Value;

		internal bool ShowCost => showCost.Value;

		internal CostDisplayStyle CostDisplayStyle => costDisplayStyle.Value;

		internal CostDisplayLocation CostDisplayLocation => costDisplayLocation.Value;

		internal ModConfig(ConfigFile configFile)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Expected O, but got Unknown
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Expected O, but got Unknown
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Expected O, but got Unknown
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Expected O, but got Unknown
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0506: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Expected O, but got Unknown
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Expected O, but got Unknown
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Expected O, but got Unknown
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Expected O, but got Unknown
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0648: Expected O, but got Unknown
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Expected O, but got Unknown
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e4: Expected O, but got Unknown
			//IL_0700: Unknown result type (might be due to invalid IL or missing references)
			//IL_0724: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Expected O, but got Unknown
			//IL_0765: Unknown result type (might be due to invalid IL or missing references)
			//IL_076f: Expected O, but got Unknown
			Config = configFile;
			configFile.SaveOnConfigSet = false;
			enableDebugMessages = Config.Bind<bool>("General", "EnableDebugMessages", false, "Enable mod debug messages in console.");
			rows = Config.Bind<int>("General", "Rows", 2, new ConfigDescription("Number of rows for planting grid aka height.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 8
				}
			}));
			columns = Config.Bind<int>("General", "Columns", 2, new ConfigDescription("Number of columns for planting grid aka width.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7
				}
			}));
			modActive = Config.Bind<bool>("General", "ModActive", true, new ConfigDescription("Enables all mod features.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10
				}
			}));
			snapActive = Config.Bind<bool>("General", "SnapActive", true, new ConfigDescription("Enables grid snapping feature.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 9
				}
			}));
			preventPartialPlanting = Config.Bind<bool>("General", "PreventPartialPlanting", true, "Prevents placement of resources when any placement ghosts are invalid for any reason.");
			preventInvalidPlanting = Config.Bind<bool>("General", "PreventInvalidPlanting", true, "Prevents plants from being placed where they will be unable to grow.");
			randomizeRotation = Config.Bind<bool>("General", "RandomizeRotation", true, "Randomizes rotation of pieces once placed.");
			useStamina = Config.Bind<bool>("General", "UseStamina", true, "Consume stamina for every piece placed.");
			useDurability = Config.Bind<bool>("General", "UseDurability", true, "Decrease durability of cultivator for every piece placed.");
			extraCropSpacing = Config.Bind<float>("General", "ExtraCropSpacing", 0f, "Adds extra spacing between crops. Accepts negative values to decrease spacing (not recommended).");
			extraSaplingSpacing = Config.Bind<float>("General", "ExtraSaplingSpacing", 0f, "Adds extra spacing between saplings. Accepts negative values to decrease spacing (not recommended).");
			gridSnappingStyle = Config.Bind<GridSnappingStyle>("General", "GridSnappingStyle", GridSnappingStyle.Intelligent, "Determines grid snapping style. Intelligent will attempt to prevent a new grid from overlapping with an old one. Legacy will allow any orientation of new rows and columns.");
			standardizeGridRotations = Config.Bind<bool>("General", "StandardizeGridRotations", true, "When set to true, this setting will prevent the diagonal snapping of new grids to existing grids.");
			minimizeGridSpacing = Config.Bind<bool>("General", "MinimizeGridSpacing", false, "Allows for tighter grids, but with varying spacing used between diverse/distinct plants. ");
			globallyAlignGridDirections = Config.Bind<bool>("General", "GloballyAlignGridDirections", true, "When set to true, new grid placements will have their column and row directions align with the global grid.");
			pickableSnapRadius = Config.Bind<float>("Pickables", "PickableSnapRadius", 1f, "Determines default distance/spacing between pickable resources when planting.");
			berryBushSnapRadius = Config.Bind<float>("Pickables", "BerryBushSnapRadius", 1.5f, "Determines distance/spacing between berry bushes when planting.");
			mushroomSnapRadius = Config.Bind<float>("Pickables", "MushroomSnapRadius", 0.5f, "Determines distance/spacing between mushrooms when planting.");
			flowerSnapRadius = Config.Bind<float>("Pickables", "FlowerSnapRadius", 1f, "Determines distance/spacing between flowers when planting.");
			preventOverlappingPlacements = Config.Bind<bool>("Pickables", "PreventOverlappingPlacements", true, new ConfigDescription("Prevents placement of pickable resources on top of colliding obstructions.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5
				}
			}));
			enableBulkHarvest = Config.Bind<bool>("Harvesting", "EnableBulkHarvest", true, "Enables the ability to harvest multiple resources at once.");
			harvestStyle = Config.Bind<HarvestStyle>("Harvesting", "HarvestStyle", HarvestStyle.AllResources, "Determines bulk harvest style. LikeResources only harvests resources of the type you've interacted with. AllResources harvests all eligible resources.");
			harvestRadius = Config.Bind<float>("Harvesting", "HarvestRadius", 3f, "Determines radius used to search for resources when bulk harvesting.");
			replantOnHarvest = Config.Bind<bool>("Harvesting", "ReplantOnHarvest", false, new ConfigDescription("Enables automatic replanting of crops when harvested, provided you have the resources.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			enableModKey = Config.Bind<KeyboardShortcut>("Controls", "EnableModKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), new ConfigDescription("Key to toggle on/off all mod features. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to toggle on/off all mod features."
				}
			}));
			enableSnappingKey = Config.Bind<KeyboardShortcut>("Controls", "EnableSnappingKey", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), new ConfigDescription("Key to toggle on/off piece snapping functionality. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to toggle on/off piece snapping functionality."
				}
			}));
			increaseXKey = Config.Bind<KeyboardShortcut>("Controls", "IncreaseXKey", new KeyboardShortcut((KeyCode)275, Array.Empty<KeyCode>()), new ConfigDescription("Key to increase number of grid columns. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to increase number of grid columns."
				}
			}));
			increaseYKey = Config.Bind<KeyboardShortcut>("Controls", "IncreaseYKey", new KeyboardShortcut((KeyCode)273, Array.Empty<KeyCode>()), new ConfigDescription("Key to increase number of grid rows. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to increase number of grid rows."
				}
			}));
			decreaseXKey = Config.Bind<KeyboardShortcut>("Controls", "DecreaseXKey", new KeyboardShortcut((KeyCode)276, Array.Empty<KeyCode>()), new ConfigDescription("Key to decrease number of grid columns. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to decrease number of grid columns."
				}
			}));
			decreaseYKey = Config.Bind<KeyboardShortcut>("Controls", "DecreaseYKey", new KeyboardShortcut((KeyCode)274, Array.Empty<KeyCode>()), new ConfigDescription("Key to decrease number of grid rows. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to decrease number of grid rows."
				}
			}));
			keyboardModifierKey = Config.Bind<KeyboardShortcut>("Controls", "KeyboardModifierKey", new KeyboardShortcut((KeyCode)305, Array.Empty<KeyCode>()), new ConfigDescription("Modifier key when using keyboard controls. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Modifier key when using keyboard controls."
				}
			}));
			gamepadModifierKey = Config.Bind<KeyboardShortcut>("Controls", "GamepadModifierKey", new KeyboardShortcut((KeyCode)334, Array.Empty<KeyCode>()), new ConfigDescription("Modifier key when using gamepad controls. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Modifier key when using gamepad controls."
				}
			}));
			keyboardHarvestModifierKey = Config.Bind<KeyboardShortcut>("Controls", "KeyboardHarvestModifierKey", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), new ConfigDescription("Modifier key to enable bulk harvest when using keyboard controls. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Modifier key to enable bulk harvest when using keyboard controls."
				}
			}));
			toggleAutoReplantKey = Config.Bind<KeyboardShortcut>("Controls", "ToggleAutoReplantKey", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), new ConfigDescription("Key to toggle on/off the [Harvesting]ReplantOnHarvest setting. See https://docs.unity3d.com/ScriptReference/KeyCode.html", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Description = "Key to toggle on/off the [Harvesting]ReplantOnHarvest setting."
				}
			}));
			showCost = Config.Bind<bool>("UI", "ShowCost", true, new ConfigDescription("Update resource cost in build UI.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			costDisplayStyle = Config.Bind<CostDisplayStyle>("UI", "CostDisplayStyle", CostDisplayStyle.TotalCount, "Determines display style of the ShowCost setting. TotalCount shows total number of pieces to be placed. FullCost shows combined resoure cost of all pieces.");
			costDisplayLocation = Config.Bind<CostDisplayLocation>("UI", "CostDisplayLocation", CostDisplayLocation.RightSide, "Determines whether to prepend or append text to the resource cost in build UI. LeftSide or RightSide will prepend or append respectively.");
			configFile.Save();
			configFile.SaveOnConfigSet = true;
			rows.SettingChanged += PlantEasily.GridSizeChanged;
			columns.SettingChanged += PlantEasily.GridSizeChanged;
		}
	}
	internal enum GridSnappingStyle
	{
		Intelligent,
		Legacy
	}
	internal enum HarvestStyle
	{
		LikeResources,
		AllResources
	}
	internal enum CostDisplayStyle
	{
		TotalCount,
		FullCost
	}
	internal enum CostDisplayLocation
	{
		LeftSide,
		RightSide
	}
}