Decompiled source of Venture Farm Grid v0.1.2

Plugins/VentureValheim.FarmGrid.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VentureValheim.FarmGrid")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VentureValheim.FarmGrid")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9574D247-B4C6-45F8-92FC-A52DE6A636C0")]
[assembly: AssemblyFileVersion("0.1.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace VentureValheim.FarmGrid
{
	[BepInPlugin("com.orianaventure.mod.VentureFarmGrid", "VentureFarmGrid", "0.1.2")]
	public class FarmGridPlugin : BaseUnityPlugin
	{
		private const string ModName = "VentureFarmGrid";

		private const string ModVersion = "0.1.2";

		private const string Author = "com.orianaventure.mod";

		private const string ModGUID = "com.orianaventure.mod.VentureFarmGrid";

		private static string ConfigFileName = "com.orianaventure.mod.VentureFarmGrid.cfg";

		private static string ConfigFileFullPath;

		private readonly Harmony HarmonyInstance = new Harmony("com.orianaventure.mod.VentureFarmGrid");

		public static readonly ManualLogSource FarmGridLogger;

		private static ConfigEntry<int> CE_FarmGridFixedPartitions;

		private static ConfigEntry<float> CE_PlantSpacing;

		private static ConfigEntry<int> CE_FarmGridSections;

		private static ConfigEntry<float> CE_FarmGridYOffset;

		private static ConfigEntry<Color> CE_FarmGridColor;

		private static ConfigEntry<string> CE_CustomPlants;

		private DateTime _lastReloadTime;

		private const long RELOAD_DELAY = 10000000L;

		public static int GetFarmGridFixedPartitions()
		{
			return CE_FarmGridFixedPartitions.Value;
		}

		public static float GetExtraPlantSpacing()
		{
			return CE_PlantSpacing.Value;
		}

		public static int GetFarmGridSections()
		{
			return Math.Max(0, Math.Min(CE_FarmGridSections.Value, 10));
		}

		public static float GetFarmGridYOffset()
		{
			return CE_FarmGridYOffset.Value;
		}

		public static Color GetFarmGridColor()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CE_FarmGridColor.Value;
		}

		public static string GetCustomPlants()
		{
			return CE_CustomPlants.Value;
		}

		private void AddConfig<T>(string key, string section, string description, bool synced, T value, ref ConfigEntry<T> configEntry)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			string extendedDescription = GetExtendedDescription(description, synced);
			configEntry = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(extendedDescription, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public string GetExtendedDescription(string description, bool synchronizedSetting)
		{
			return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
		}

		public void Awake()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			AddConfig("FarmGridFixedPartitions", "General", "Fixed number partitions for initial snapping angles. Vanilla uses 16 for build pieces, 0 allows free rotation (int).", synced: false, 16, ref CE_FarmGridFixedPartitions);
			AddConfig("PlantSpacing", "General", "Extra spacing to add to all plants in addition to the plant's needed growth space (float).", synced: false, 0.01f, ref CE_PlantSpacing);
			AddConfig("FarmGridSections", "General", "Amount of grid squares to draw from the center (limited to 10 maximum) (int).", synced: false, 2, ref CE_FarmGridSections);
			AddConfig("FarmGridYOffset", "General", "Grid offset from the ground (float).", synced: false, 0.1f, ref CE_FarmGridYOffset);
			AddConfig("FarmGridColor", "General", "Color of the grid (Color).", synced: false, new Color(0.8f, 0.8f, 0.8f, 0.2f), ref CE_FarmGridColor);
			AddConfig("CustomPlants", "Advanced", "Additional non-Plant prefabs and default overrides (Example: RaspberryBush: 0.5, BlueberryBush: 0.5) (string in format: Prefab:float,Prefab:float).", synced: false, "", ref CE_CustomPlants);
			FarmGridLogger.LogInfo((object)"Snap. Crackle. Pop.");
			FarmGrid.SetupConfigurations();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			HarmonyInstance.PatchAll(executingAssembly);
			SetupWatcher();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			_lastReloadTime = DateTime.Now;
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			DateTime now = DateTime.Now;
			long num = now.Ticks - _lastReloadTime.Ticks;
			if (File.Exists(ConfigFileFullPath) && num >= 10000000)
			{
				try
				{
					FarmGridLogger.LogInfo((object)"Attempting to reload configuration...");
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch
				{
					FarmGridLogger.LogError((object)("There was an issue loading " + ConfigFileName));
					return;
				}
				_lastReloadTime = now;
				FarmGrid.SetupConfigurations();
			}
		}

		static FarmGridPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			FarmGridLogger = Logger.CreateLogSource("VentureFarmGrid");
			CE_FarmGridFixedPartitions = null;
			CE_PlantSpacing = null;
			CE_FarmGridSections = null;
			CE_FarmGridYOffset = null;
			CE_FarmGridColor = null;
			CE_CustomPlants = null;
		}
	}
	public class FarmGrid
	{
		private class PlantObject
		{
			public Vector3 position;

			public float growthSize;

			public PlantObject(Vector3 position, float growthSize)
			{
				//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)
				this.position = position;
				this.growthSize = growthSize;
			}
		}

		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		public static class Patch_Player_SetupPlacementGhost
		{
			private static void Postfix()
			{
				ResetCache();
				SetGhostPlant();
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		public static class Patch_Player_UpdatePlacementGhost
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				List<CodeInstruction> list = instructions.ToList();
				bool flag = false;
				int num = 0;
				MethodInfo methodInfo = AccessTools.Method(typeof(Player), "FindClosestSnapPoints", (Type[])null, (Type[])null);
				object obj = AccessTools.Method(typeof(FarmGrid), "GetFarmSnapPoints", (Type[])null, (Type[])null);
				for (int i = 0; i < list.Count; i++)
				{
					if (list[i].opcode == OpCodes.Brtrue)
					{
						num = i;
					}
					if (CodeInstructionExtensions.Calls(list[i], methodInfo))
					{
						list.InsertRange(num + 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
						{
							new CodeInstruction(OpCodes.Call, obj),
							new CodeInstruction(OpCodes.Brtrue, list[num].operand)
						});
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					FarmGridPlugin.FarmGridLogger.LogWarning((object)"FarmGrid: Failed to patch UpdatePlacementGhost");
				}
				return list;
			}
		}

		[HarmonyPatch(typeof(Player), "TryPlacePiece")]
		public static class Patch_Player_PlacePiece
		{
			private static bool Prefix(ref Player __instance, ref bool __result, Piece piece)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if (GetPlantObject(__instance.m_placementGhost.GetComponent<Collider>(), out PlantObject plantObject) && HasOverlappingPlants(plantObject.position, plantObject.growthSize))
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")]
		public static class Patch_Humanoid_SetupVisEquipment
		{
			private static void Postfix(ref Humanoid __instance)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Object)(object)Player.m_localPlayer == (Object)null || ((Humanoid)Player.m_localPlayer).m_rightItem == null || ((Humanoid)Player.m_localPlayer).m_rightItem.m_shared == null || ((Humanoid)Player.m_localPlayer).m_rightItem.m_shared.m_name != "$item_cultivator"))
				{
					HideFarmGrid();
					ResetCache();
				}
			}
		}

		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		public static class Patch_ZNetScene_Awake
		{
			private static void Postfix()
			{
				SetupPlantCache();
			}
		}

		private static Dictionary<string, float> customPlants = new Dictionary<string, float>();

		private static readonly Dictionary<string, float> vanillaPlantsDefaults = new Dictionary<string, float>
		{
			{ "BlueberryBush", 0.5f },
			{ "CloudberryBush", 0.5f },
			{ "RaspberryBush", 0.5f },
			{ "Pickable_Dandelion", 0.5f },
			{ "Pickable_Fiddlehead", 0.5f },
			{ "Pickable_Mushroom", 0.5f },
			{ "Pickable_Mushroom_blue", 0.5f },
			{ "Pickable_Mushroom_yellow", 0.5f },
			{ "Pickable_SmokePuff", 0.5f },
			{ "Pickable_Thistle", 0.5f }
		};

		private static Dictionary<string, float> plantsConfiguration = new Dictionary<string, float>();

		private static readonly string[] plantObjectMasks = new string[6] { "Default", "Default_small", "item", "piece", "piece_nonsolid", "static_solid" };

		private static int plantObjectMask = LayerMask.GetMask(plantObjectMasks);

		private static Vector3 plantSnapPoint = Vector3.zero;

		private static GameObject[] farmGrid = null;

		private static bool farmGridVisible = false;

		private static PlantObject plantGhost;

		private static Vector3 plantGhostPosition = Vector3.zero;

		private static Material lineMaterial;

		private static bool freeDraw = true;

		public static void SetupPlantCache()
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			plantsConfiguration.Clear();
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				Plant component = prefab.GetComponent<Plant>();
				if ((Object)(object)component == (Object)null || plantsConfiguration.ContainsKey(((Object)component).name))
				{
					continue;
				}
				plantsConfiguration.Add(((Object)component).name, component.m_growRadius);
				GameObject[] grownPrefabs = component.m_grownPrefabs;
				foreach (GameObject val in grownPrefabs)
				{
					if (!plantsConfiguration.ContainsKey(((Object)val).name))
					{
						plantsConfiguration.Add(((Object)val).name, component.m_growRadius);
					}
				}
			}
			foreach (KeyValuePair<string, float> vanillaPlantsDefault in vanillaPlantsDefaults)
			{
				if (!plantsConfiguration.ContainsKey(vanillaPlantsDefault.Key))
				{
					plantsConfiguration.Add(vanillaPlantsDefault.Key, vanillaPlantsDefault.Value);
				}
			}
		}

		public static void SetupConfigurations()
		{
			customPlants.Clear();
			string[] array = FarmGridPlugin.GetCustomPlants().Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new string[1] { ":" }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length == 2 && float.TryParse(array2[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					customPlants.Add(array2[0].Trim(), result);
				}
			}
			DestroyFarmGrid();
			ResetCache();
			SetGhostPlant();
		}

		private static bool HasCustomSize(string prefab, out float size)
		{
			string prefabName = Utils.GetPrefabName(prefab);
			size = 0f;
			if (customPlants.ContainsKey(prefabName))
			{
				size = customPlants[prefabName];
				return true;
			}
			if (plantsConfiguration.ContainsKey(prefabName))
			{
				size = plantsConfiguration[prefabName];
				return true;
			}
			return false;
		}

		private static float GetCollisionRadius(PlantObject plant)
		{
			return GetPlantSpacing(plant.growthSize) * (float)(FarmGridPlugin.GetFarmGridSections() + 1);
		}

		private static float GetPlantSpacing(float growthSize)
		{
			return growthSize * 2f + FarmGridPlugin.GetExtraPlantSpacing();
		}

		private static void DrawFarmGrid(Vector3 pos, Vector3 gridDir, float gridSize)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0050: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0068: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if (farmGrid == null || (Object)(object)farmGrid[0] == (Object)null)
			{
				InitFarmGrid();
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(gridDir.z, gridDir.y, 0f - gridDir.x);
			int farmGridSections = FarmGridPlugin.GetFarmGridSections();
			for (int i = -farmGridSections; i <= farmGridSections; i++)
			{
				GameObject grid = farmGrid[i + farmGridSections];
				Vector3 position = pos + gridDir * (float)i * gridSize;
				DrawSegments(farmGridSections, gridSize, grid, position, val);
				GameObject grid2 = farmGrid[i + farmGridSections + (farmGridSections * 2 + 1)];
				Vector3 position2 = pos + val * (float)i * gridSize;
				DrawSegments(farmGridSections, gridSize, grid2, position2, gridDir);
			}
			farmGridVisible = true;
		}

		private static void DrawSegments(int farmGridSections, float gridSize, GameObject grid, Vector3 position, Vector3 pivot)
		{
			//IL_0006: 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_0031: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			grid.transform.position = position;
			LineRenderer component = grid.GetComponent<LineRenderer>();
			component.widthMultiplier = 0.015f;
			((Renderer)component).enabled = true;
			float farmGridYOffset = FarmGridPlugin.GetFarmGridYOffset();
			for (int i = -farmGridSections; i <= farmGridSections; i++)
			{
				Vector3 val = position + pivot * (float)i * gridSize;
				float groundHeight = GetGroundHeight(val);
				val.y = groundHeight + farmGridYOffset;
				component.SetPosition(i + farmGridSections, val);
			}
		}

		private static float GetGroundHeight(Vector3 linePos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ZoneSystem.instance.GetGroundHeight(linePos);
		}

		public static void DestroyFarmGrid()
		{
			if (farmGrid == null)
			{
				return;
			}
			for (int i = 0; i < farmGrid.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)farmGrid[i]))
				{
					Object.Destroy((Object)(object)farmGrid[i]);
				}
			}
			farmGrid = null;
		}

		private static void InitFarmGrid()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)lineMaterial))
			{
				lineMaterial = Resources.FindObjectsOfTypeAll<Material>().First((Material k) => ((Object)k).name == "Default-Line");
			}
			int farmGridSections = FarmGridPlugin.GetFarmGridSections();
			Color farmGridColor = FarmGridPlugin.GetFarmGridColor();
			farmGrid = (GameObject[])(object)new GameObject[(farmGridSections * 2 + 1) * 2];
			for (int i = 0; i < farmGrid.Length; i++)
			{
				GameObject val = new GameObject();
				LineRenderer obj = val.AddComponent<LineRenderer>();
				((Renderer)obj).material = lineMaterial;
				obj.startColor = farmGridColor;
				obj.endColor = farmGridColor;
				obj.positionCount = farmGridSections * 2 + 1;
				farmGrid[i] = val;
			}
		}

		private static void HideFarmGrid()
		{
			if (farmGridVisible && farmGrid != null && (Object)(object)farmGrid[0] != (Object)null)
			{
				for (int i = 0; i < farmGrid.Length; i++)
				{
					((Renderer)farmGrid[i].GetComponent<LineRenderer>()).enabled = false;
				}
				farmGridVisible = false;
				freeDraw = true;
			}
		}

		private static void ResetCache()
		{
			//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)
			plantGhost = null;
			plantSnapPoint = Vector3.zero;
			freeDraw = true;
		}

		private static void SetGhostPlant()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)localPlayer.m_placementGhost == (Object)null) && GetPlantObject(localPlayer.m_placementGhost.GetComponentInChildren<Collider>(), out PlantObject plantObject))
			{
				plantGhost = plantObject;
				plantGhostPosition = plantGhost.position;
			}
		}

		private static bool GetFarmSnapPoints()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (plantGhost == null)
			{
				HideFarmGrid();
				ResetCache();
				return false;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				HideFarmGrid();
				ResetCache();
				return false;
			}
			GameObject placementGhost = Player.m_localPlayer.m_placementGhost;
			if ((Object)(object)placementGhost == (Object)null)
			{
				HideFarmGrid();
				ResetCache();
				return false;
			}
			Vector3 val = plantGhostPosition - placementGhost.transform.position;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (((!farmGridVisible || freeDraw) && sqrMagnitude < 0.0001f) || (farmGridVisible && !freeDraw && (double)sqrMagnitude < 0.02))
			{
				if (plantSnapPoint != Vector3.zero)
				{
					placementGhost.transform.position = plantSnapPoint;
				}
				return true;
			}
			plantSnapPoint = Vector3.zero;
			plantGhost.position = placementGhost.transform.position;
			plantGhostPosition = plantGhost.position;
			List<PlantObject> otherPlants = GetOtherPlants(plantGhost.position, GetCollisionRadius(plantGhost));
			if (otherPlants.Count < 1)
			{
				HideFarmGrid();
				return true;
			}
			if (otherPlants.Count == 1)
			{
				DrawFreeGrid(otherPlants[0]);
			}
			else if (otherPlants.Count > 1)
			{
				DrawFixedGrid(otherPlants);
			}
			return true;
		}

		private static void DrawFreeGrid(PlantObject otherPlant)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (!GetFixedGridDir(otherPlant, out var gridDir))
			{
				gridDir = plantGhost.position - otherPlant.position;
				gridDir.y = 0f;
				((Vector3)(ref gridDir)).Normalize();
			}
			freeDraw = true;
			float plantSpacing = GetPlantSpacing(Mathf.Max(plantGhost.growthSize, otherPlant.growthSize));
			plantSnapPoint = otherPlant.position + gridDir * plantSpacing;
			float groundHeight = GetGroundHeight(plantSnapPoint);
			plantSnapPoint.y = groundHeight;
			Player.m_localPlayer.m_placementGhost.transform.position = plantSnapPoint;
			DrawFarmGrid(plantSnapPoint, gridDir, plantSpacing);
		}

		private static void DrawFixedGrid(List<PlantObject> otherPlants)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			if (!GetGridDir(otherPlants, out Vector3 gridDir, out PlantObject chosen, out PlantObject _) || chosen == null)
			{
				DrawFreeGrid(otherPlants[0]);
				return;
			}
			freeDraw = false;
			float plantSpacing = GetPlantSpacing(Mathf.Max(plantGhost.growthSize, chosen.growthSize));
			List<Vector3> gridLocations = GetGridLocations(plantGhost.position, chosen.position, gridDir, plantSpacing);
			plantSnapPoint = gridLocations[0];
			for (int i = 0; i < gridLocations.Count; i++)
			{
				if (!HasOverlappingPlants(gridLocations[i], otherPlants, plantGhost.growthSize))
				{
					plantSnapPoint = gridLocations[i];
					break;
				}
			}
			float groundHeight = GetGroundHeight(plantSnapPoint);
			plantSnapPoint.y = groundHeight;
			Player.m_localPlayer.m_placementGhost.transform.position = plantSnapPoint;
			DrawFarmGrid(plantSnapPoint, gridDir, plantSpacing);
		}

		private static List<Vector3> GetGridLocations(Vector3 position, Vector3 otherPlantPosition, Vector3 gridDir, float gridSize)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0062: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(gridDir.z, gridDir.y, 0f - gridDir.x);
			for (int i = -2; i <= 2; i++)
			{
				for (int j = -2; j <= 2; j++)
				{
					if (i != 0 || j != 0)
					{
						Vector3 item = otherPlantPosition + gridDir * (float)i * gridSize + val * (float)j * gridSize;
						list.Add(item);
					}
				}
			}
			return list.OrderBy(delegate(Vector3 location)
			{
				//IL_0000: 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_0007: 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)
				Vector3 val2 = location - position;
				return ((Vector3)(ref val2)).sqrMagnitude;
			}).ToList();
		}

		private static bool GetFixedGridDir(PlantObject plant, out Vector3 gridDir)
		{
			//IL_0001: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			gridDir = default(Vector3);
			int farmGridFixedPartitions = FarmGridPlugin.GetFarmGridFixedPartitions();
			if (farmGridFixedPartitions != 0)
			{
				float num = (float)Math.PI * 2f / (float)farmGridFixedPartitions;
				Vector3 val = plantGhost.position - plant.position;
				float num2 = Mathf.Round(Mathf.Atan2(val.z, val.x) / num) * num;
				gridDir.y = 0f;
				gridDir.x = Mathf.Cos(num2);
				gridDir.z = Mathf.Sin(num2);
				gridDir = ((Vector3)(ref gridDir)).normalized;
				return true;
			}
			return false;
		}

		private static bool GetGridDir(List<PlantObject> plantList, out Vector3 gridDir, out PlantObject chosen1, out PlantObject chosen2)
		{
			//IL_00c7: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			chosen1 = plantList[0];
			chosen2 = null;
			for (int i = 0; i < 2; i++)
			{
				chosen1 = plantList[i];
				for (int j = 1; j < plantList.Count; j++)
				{
					gridDir = chosen1.position - plantList[j].position;
					gridDir.y = 0f;
					float plantSpacing = GetPlantSpacing(Mathf.Max(Mathf.Max(chosen1.growthSize, plantList[j].growthSize), plantGhost.growthSize));
					float num = ((Vector3)(ref gridDir)).magnitude - plantSpacing;
					if (num > -0.01f && num < 0.01f * plantSpacing)
					{
						chosen2 = plantList[j];
						gridDir = ((Vector3)(ref gridDir)).normalized;
						return true;
					}
				}
			}
			gridDir = Vector3.zero;
			chosen1 = null;
			chosen2 = null;
			return false;
		}

		private static List<PlantObject> GetOtherPlants(Vector3 position, float collisionRadius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			int count = Physics.OverlapSphereNonAlloc(position, collisionRadius, Piece.s_pieceColliders, plantObjectMask);
			List<Collider> list = Piece.s_pieceColliders.Take(count).OrderBy(delegate(Collider plant)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = ((Component)plant).transform.position - plantGhost.position;
				return ((Vector3)(ref val)).sqrMagnitude;
			}).ToList();
			List<PlantObject> list2 = new List<PlantObject>();
			for (int i = 0; i < list.Count; i++)
			{
				if (GetPlantObject(list[i], out PlantObject plantObject))
				{
					list2.Add(plantObject);
					if (list2.Count == 24)
					{
						break;
					}
				}
			}
			return list2;
		}

		private static bool HasOverlappingPlants(Vector3 pos, List<PlantObject> otherPlants, float collisionRadius)
		{
			//IL_0004: 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)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < otherPlants.Count; i++)
			{
				Vector3 val = pos - otherPlants[i].position;
				if (((Vector3)(ref val)).magnitude <= collisionRadius + otherPlants[i].growthSize)
				{
					return true;
				}
			}
			return false;
		}

		private static bool HasOverlappingPlants(Vector3 pos, float collisionRadius)
		{
			//IL_0000: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, collisionRadius, Piece.s_pieceColliders, plantObjectMask);
			for (int i = 0; i < num; i++)
			{
				if (GetPlantObject(Piece.s_pieceColliders[i], out PlantObject plantObject))
				{
					Vector3 val = pos - plantObject.position;
					if (((Vector3)(ref val)).magnitude <= collisionRadius + plantObject.growthSize)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool GetPlantObject(Collider collider, out PlantObject plantObject)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)collider != (Object)null && HasCustomSize(((Object)((Component)collider).transform.root).name, out var size))
			{
				plantObject = new PlantObject(((Component)collider).transform.position, size);
				return true;
			}
			plantObject = null;
			return false;
		}
	}
}