Decompiled source of LetsBuild v0.7.7

plugins/LetsBuild.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DezzyCode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("DezzyCode")]
[assembly: AssemblyDescription("A creative builder's hammer, precision building, and grid planting.")]
[assembly: AssemblyFileVersion("0.7.7.0")]
[assembly: AssemblyInformationalVersion("0.7.7+0ae45d386b853d81f06bfff27042dd0020b0a2c9")]
[assembly: AssemblyProduct("Lets Build")]
[assembly: AssemblyTitle("LetsBuild")]
[assembly: AssemblyVersion("0.7.7.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LetsBuild
{
	internal static class AreaRepair
	{
		private static readonly MethodInfo HoveringPiece = AccessTools.Method(typeof(Player), "GetHoveringPiece", (Type[])null, (Type[])null);

		private static int _mask;

		private static bool _repairing;

		public static void Patch(Harmony harmony)
		{
			//IL_0080: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00b6: Expected O, but got Unknown
			//IL_00b6: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "Repair", new Type[2]
			{
				typeof(ItemData),
				typeof(Piece)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "CheckCanRemovePiece", (Type[])null, (Type[])null);
			if (methodInfo == null || HoveringPiece == null)
			{
				Log.Warning("Area repair is not available: the game has no Player.Repair or GetHoveringPiece as expected.");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AreaRepair), "StartRepair", (Type[])null), new HarmonyMethod(typeof(AreaRepair), "RepairAround", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(AreaRepair), "EndRepair", (Type[])null), (HarmonyMethod)null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(AreaRepair), "NoStationNeeded", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Log.Warning("Repairing still needs a crafting station: the game has no CheckCanRemovePiece as expected.");
			}
		}

		private static void StartRepair(Player __instance)
		{
			_repairing = Settings.AreaRepair.Value && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && PrecisionBuild.HoldsHammer(__instance);
		}

		private static void EndRepair()
		{
			_repairing = false;
		}

		private static bool NoStationNeeded(ref bool __result)
		{
			if (!_repairing)
			{
				return true;
			}
			__result = true;
			return false;
		}

		private static void RepairAround(Player __instance, ItemData toolItem)
		{
			//IL_0096: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.AreaRepair.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || toolItem == null || !((Character)__instance).InPlaceMode() || !PrecisionBuild.HoldsHammer(__instance))
			{
				return;
			}
			object? obj = HoveringPiece.Invoke(__instance, null);
			Piece val = (Piece)((obj is Piece) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (_mask == 0)
			{
				_mask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "vehicle" });
			}
			Vector3 position = ((Component)val).transform.position;
			HashSet<int> hashSet = new HashSet<int> { ((Object)((Component)val).gameObject).GetInstanceID() };
			List<(WearNTear, Piece, float)> list = new List<(WearNTear, Piece, float)>();
			Collider[] array = Physics.OverlapSphere(position, Settings.RepairRadius.Value, _mask);
			for (int i = 0; i < array.Length; i++)
			{
				WearNTear componentInParent = ((Component)array[i]).GetComponentInParent<WearNTear>();
				if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(((Object)((Component)componentInParent).gameObject).GetInstanceID()))
				{
					Piece component = ((Component)componentInParent).GetComponent<Piece>();
					ZNetView component2 = ((Component)componentInParent).GetComponent<ZNetView>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null) && component2.IsValid() && !(componentInParent.GetHealthPercentage() >= 1f))
					{
						list.Add((componentInParent, component, Vector3.Distance(position, ((Component)componentInParent).transform.position)));
					}
				}
			}
			list.Sort(((WearNTear wear, Piece piece, float distance) a, (WearNTear wear, Piece piece, float distance) b) => a.distance.CompareTo(b.distance));
			bool value = Settings.RepairCosts.Value;
			float buildStamina = PlayerAccess.GetBuildStamina(__instance);
			float attackEitr = toolItem.m_shared.m_attack.m_attackEitr;
			float num = toolItem.m_shared.m_useDurabilityDrain * Game.m_durabilityRate;
			int num2 = 0;
			foreach (var item2 in list)
			{
				WearNTear item = item2.Item1;
				if (!PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false))
				{
					continue;
				}
				if (value && (!((Character)__instance).HaveStamina(buildStamina) || !((Character)__instance).HaveEitr(attackEitr) || (toolItem.m_shared.m_useDurability && toolItem.m_durability <= 0f)))
				{
					break;
				}
				if (!item.Repair())
				{
					continue;
				}
				num2++;
				if (value)
				{
					((Character)__instance).UseStamina(buildStamina);
					((Character)__instance).UseEitr(attackEitr);
					if (toolItem.m_shared.m_useDurability)
					{
						toolItem.m_durability = Mathf.Max(0f, toolItem.m_durability - num);
					}
				}
			}
			if (num2 > 0)
			{
				((Character)__instance).Message((MessageType)1, "$lb_repaired_around: " + num2, 0, (Sprite)null, false);
			}
		}
	}
	[HarmonyPatch]
	internal static class BuildCamera
	{
		private const float Speed = 10f;

		private const float MaxPitch = 89f;

		private const float MaxReach = 64f;

		private static readonly FieldRef<Character, float> MaxAirAltitude = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude");

		private static bool _loose;

		private static bool _carry;

		private static Vector3 _position;

		private static float _yaw;

		private static float _pitch;

		private static Vector3 _start;

		private static readonly List<Renderer> Hidden = new List<Renderer>();

		private static readonly List<Collider> Disabled = new List<Collider>();

		private static bool _flightReading;

		public static void Tick(Player player)
		{
			if (_loose && ((Object)(object)player == (Object)null || ((Character)player).IsDead() || !CreativeMode.Holding || (_carry && !CreativeMode.IsAdmin())))
			{
				Fix(player);
			}
			else
			{
				if ((Object)(object)player == (Object)null || !CreativeMode.Holding)
				{
					return;
				}
				if (Keys.Down(Settings.CameraKey) && Listening(player))
				{
					if (_loose)
					{
						Fix(player);
					}
					else
					{
						Loosen(player);
					}
				}
				if (_loose && Listening(player) && !Hud.IsPieceSelectionVisible() && !Hud.InRadial())
				{
					Fly(Time.unscaledDeltaTime);
				}
			}
		}

		private static bool Listening(Player player)
		{
			return Keys.GameHasInput(player);
		}

		private static void Loosen(Player player)
		{
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null);
			if (!((Object)(object)val == (Object)null))
			{
				_position = val.position;
				Quaternion rotation = val.rotation;
				Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
				_yaw = eulerAngles.y;
				_pitch = Mathf.Clamp(Mathf.DeltaAngle(0f, eulerAngles.x), -89f, 89f);
				_start = ((Component)player).transform.position;
				_carry = CreativeMode.IsAdmin();
				if (_carry)
				{
					Hide(player);
				}
				_loose = true;
				((Character)player).Message((MessageType)1, "$lb_camera_loose", 0, (Sprite)null, false);
			}
		}

		private static void Fix(Player player)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			_loose = false;
			if ((Object)(object)player == (Object)null)
			{
				Hidden.Clear();
				Disabled.Clear();
				return;
			}
			if (_carry)
			{
				Show();
				if (!player.InDebugFlyMode())
				{
					Teleport(player, _start);
					MaxAirAltitude.Invoke((Character)(object)player) = _start.y;
				}
			}
			_carry = false;
			((Character)player).Message((MessageType)1, "$lb_camera_fixed", 0, (Sprite)null, false);
		}

		private static void Fly(float dt)
		{
			//IL_0000: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_006a: 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_0070: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens;
			if (PlayerController.m_invertMouse)
			{
				val.y = 0f - val.y;
			}
			_yaw += val.x;
			_pitch = Mathf.Clamp(_pitch - val.y, -89f, 89f);
			Quaternion val2 = Quaternion.Euler(_pitch, _yaw, 0f);
			Vector3 val3 = Vector3.zero;
			if (ZInput.GetButton("Forward"))
			{
				val3 += val2 * Vector3.forward;
			}
			if (ZInput.GetButton("Backward"))
			{
				val3 += val2 * Vector3.back;
			}
			if (ZInput.GetButton("Left"))
			{
				val3 += val2 * Vector3.left;
			}
			if (ZInput.GetButton("Right"))
			{
				val3 += val2 * Vector3.right;
			}
			if (ZInput.GetButton("Jump"))
			{
				val3 += Vector3.up;
			}
			if (ZInput.GetButton("Crouch"))
			{
				val3 += Vector3.down;
			}
			if (((Vector3)(ref val3)).sqrMagnitude > 1f)
			{
				((Vector3)(ref val3)).Normalize();
			}
			_position += val3 * (10f * dt);
		}

		private static void Hide(Player player)
		{
			Hidden.Clear();
			Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (val.enabled)
				{
					val.enabled = false;
					Hidden.Add(val);
				}
			}
			Disabled.Clear();
			Collider[] componentsInChildren2 = ((Component)player).GetComponentsInChildren<Collider>();
			foreach (Collider val2 in componentsInChildren2)
			{
				if (val2.enabled && !val2.isTrigger)
				{
					val2.enabled = false;
					Disabled.Add(val2);
				}
			}
		}

		private static void Show()
		{
			foreach (Renderer item in Hidden)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.enabled = true;
				}
			}
			foreach (Collider item2 in Disabled)
			{
				if ((Object)(object)item2 != (Object)null)
				{
					item2.enabled = true;
				}
			}
			Hidden.Clear();
			Disabled.Clear();
		}

		private static void Carry(Player player)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)((Character)player).m_eye == (Object)null))
			{
				Vector3 val = ((Character)player).m_eye.position - ((Component)player).transform.position;
				Teleport(player, _position - val);
				MaxAirAltitude.Invoke((Character)(object)player) = ((Component)player).transform.position.y;
			}
		}

		private static void Leash(Player player)
		{
			//IL_0021: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_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)
			Vector3 val = (((Object)(object)((Character)player).m_eye != (Object)null) ? ((Character)player).m_eye.position : ((Component)player).transform.position);
			Vector3 val2 = _position - val;
			if (((Vector3)(ref val2)).sqrMagnitude > 4096f)
			{
				_position = val + ((Vector3)(ref val2)).normalized * 64f;
			}
		}

		private static void Teleport(Player player, Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			((Component)player).transform.position = position;
			Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.position = position;
				component.linearVelocity = Vector3.zero;
				component.useGravity = false;
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		[HarmonyPostfix]
		private static void Place(GameCamera __instance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (_loose)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null && !_carry)
				{
					Leash(localPlayer);
				}
				((Component)__instance).transform.position = _position;
				((Component)__instance).transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
				if ((Object)(object)localPlayer != (Object)null && _carry)
				{
					Carry(localPlayer);
				}
			}
		}

		[HarmonyPatch(typeof(Character), "UpdateDebugFly")]
		[HarmonyPrefix]
		private static void FlightReads(Character __instance)
		{
			_flightReading = _loose && (Object)(object)__instance == (Object)(object)Player.m_localPlayer;
		}

		[HarmonyPatch(typeof(Character), "UpdateDebugFly")]
		[HarmonyFinalizer]
		private static void FlightDone()
		{
			_flightReading = false;
		}

		[HarmonyPatch(typeof(Player), "TakeInput")]
		[HarmonyPrefix]
		private static bool FlightInput(ref bool __result)
		{
			if (!_flightReading)
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(PlayerController), "TakeInput")]
		[HarmonyPrefix]
		private static bool CharacterInput(ref bool __result)
		{
			if (!_loose)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	internal static class CreativeHammer
	{
		public const string PrefabName = "LetsBuild_Hammer";

		public const string NameToken = "$lb_hammer";

		private const string IconFile = "hammer.png";

		private static Recipe _recipe;

		public static void Register()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Create;
			Settings.Craftable.SettingChanged += delegate
			{
				ApplyCraftable();
			};
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				ApplyCraftable();
			};
		}

		private static void ApplyCraftable()
		{
			if ((Object)(object)_recipe != (Object)null)
			{
				_recipe.m_enabled = Settings.Craftable.Value;
			}
		}

		public static bool IsHammer(ItemData item)
		{
			if (item?.m_shared != null)
			{
				return item.m_shared.m_name == "$lb_hammer";
			}
			return false;
		}

		private static void Create()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//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_0076: 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_0085: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= Create;
			ItemConfig val = new ItemConfig();
			val.Enabled = Settings.Craftable.Value;
			val.Name = "$lb_hammer";
			val.Description = "$lb_hammer_desc";
			val.CraftingStation = CraftingStations.Workbench;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = "Wood",
					Amount = 1,
					Recover = true
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("LetsBuild_Hammer", "Hammer", val2);
			if ((Object)(object)val3.ItemPrefab == (Object)null)
			{
				Log.Warning("Could not clone the vanilla hammer; the builder's hammer is unavailable.");
				return;
			}
			SharedData shared = val3.ItemDrop.m_itemData.m_shared;
			shared.m_name = "$lb_hammer";
			shared.m_description = "$lb_hammer_desc";
			shared.m_useDurability = false;
			Sprite val4 = LoadIcon();
			if ((Object)(object)val4 != (Object)null)
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { val4 };
			}
			ItemManager.Instance.AddItem(val3);
			CustomRecipe recipe = val3.Recipe;
			_recipe = ((recipe != null) ? recipe.Recipe : null);
			ApplyCraftable();
			Log.Info("Builder's hammer registered; " + (Settings.Craftable.Value ? "craftable at the workbench." : "not craftable now, spawn it with \"spawn LetsBuild_Hammer\".") + (((Object)(object)_recipe == (Object)null) ? " (No recipe could be made.)" : ""));
		}

		private static Sprite LoadIcon()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = ((directoryName != null) ? Path.Combine(directoryName, "hammer.png") : null);
			if (text == null || !File.Exists(text))
			{
				Log.Warning("hammer.png is not next to the DLL; the hammer keeps the vanilla icon.");
				return null;
			}
			MethodInfo methodInfo = AccessTools.Method("UnityEngine.ImageConversion:LoadImage", new Type[2]
			{
				typeof(Texture2D),
				typeof(byte[])
			}, (Type[])null);
			if (methodInfo == null)
			{
				Log.Warning("Cannot decode hammer.png; the hammer keeps the vanilla icon.");
				return null;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!(bool)methodInfo.Invoke(null, new object[2]
			{
				val,
				File.ReadAllBytes(text)
			}))
			{
				Object.Destroy((Object)(object)val);
				Log.Warning("hammer.png could not be decoded; the hammer keeps the vanilla icon.");
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
	[HarmonyPatch]
	internal static class CreativeMode
	{
		private static bool _active;

		private static bool _hadCheats;

		private static bool _hadDebug;

		private static bool _hadFly;

		private static bool _hadFreeBuild;

		private static bool _flyOffPending;

		private static bool _silent;

		private static bool _toldAdminOnly;

		private static bool _holding;

		public static bool Active => _active;

		public static bool Holding => _holding;

		public static void Register()
		{
			SynchronizationManager.OnAdminStatusChanged += AdminChanged;
		}

		private static void AdminChanged()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && _holding)
			{
				if (!IsAdmin())
				{
					Leave(localPlayer);
				}
				else if (Settings.CreativeActive.Value)
				{
					Enter(localPlayer);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		[HarmonyPostfix]
		private static void Equipped(Humanoid __instance, ItemData item, bool __result)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (__result && IsOurs(__instance, item))
			{
				_holding = true;
				if (Settings.CreativeActive.Value)
				{
					Enter((Player)__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		[HarmonyPostfix]
		private static void Unequipped(Humanoid __instance, ItemData item)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			if (IsOurs(__instance, item))
			{
				_holding = false;
				Leave((Player)__instance);
			}
		}

		[HarmonyPatch(typeof(Player), "OnDestroy")]
		[HarmonyPrefix]
		private static void PlayerGone(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				_holding = false;
				if (_active)
				{
					_active = false;
					_flyOffPending = false;
					Terminal.m_cheat = _hadCheats;
					Player.m_debugMode = _hadDebug;
					Log.Info("Creative mode off; the world closed while the hammer was held.");
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Message")]
		[HarmonyPrefix]
		private static bool Quiet()
		{
			return !_silent;
		}

		private static bool IsOurs(Humanoid humanoid, ItemData item)
		{
			if ((Object)(object)humanoid == (Object)(object)Player.m_localPlayer)
			{
				return CreativeHammer.IsHammer(item);
			}
			return false;
		}

		private static void Enter(Player player)
		{
			if (_active)
			{
				return;
			}
			if (!IsAdmin())
			{
				if (!_toldAdminOnly)
				{
					_toldAdminOnly = true;
					((Character)player).Message((MessageType)2, "$lb_admin_only", 0, (Sprite)null, false);
				}
				return;
			}
			_hadCheats = Terminal.m_cheat;
			_hadDebug = Player.m_debugMode;
			_hadFly = player.InDebugFlyMode();
			_hadFreeBuild = player.NoCostCheat();
			_flyOffPending = false;
			_active = true;
			Terminal.m_cheat = true;
			Player.m_debugMode = true;
			Silently(delegate
			{
				player.SetNoPlacementCost(true);
				if (!_hadFly && Settings.Fly.Value)
				{
					player.ToggleDebugFly();
				}
			});
			((Character)player).Message((MessageType)1, "$lb_creative_on", 0, (Sprite)null, false);
			Log.Info("Creative mode on (was: cheats " + _hadCheats + ", debug " + _hadDebug + ", fly " + _hadFly + ", free build " + _hadFreeBuild + ").");
		}

		private static void Leave(Player player)
		{
			if (!_active)
			{
				return;
			}
			_active = false;
			Terminal.m_cheat = _hadCheats;
			Player.m_debugMode = _hadDebug;
			Silently(delegate
			{
				player.SetNoPlacementCost(_hadFreeBuild);
			});
			if (player.InDebugFlyMode() == _hadFly)
			{
				((Character)player).Message((MessageType)1, "$lb_creative_off", 0, (Sprite)null, false);
				Log.Info("Creative mode off.");
			}
			else if (((Character)player).IsOnGround())
			{
				Silently(delegate
				{
					player.ToggleDebugFly();
				});
				((Character)player).Message((MessageType)1, "$lb_creative_off", 0, (Sprite)null, false);
				Log.Info("Creative mode off.");
			}
			else
			{
				_flyOffPending = true;
				((Character)player).Message((MessageType)1, "$lb_fly_until_landed", 0, (Sprite)null, false);
				Log.Info("Creative mode off; flight stays until you land.");
			}
		}

		public static void Tick(Player player)
		{
			if ((Object)(object)player != (Object)null && _holding && Keys.GameHasInput(player) && Keys.Down(Settings.CreativeKey))
			{
				Settings.CreativeActive.Value = !Settings.CreativeActive.Value;
				if (Settings.CreativeActive.Value)
				{
					Enter(player);
				}
				else
				{
					Leave(player);
				}
			}
			if (!_flyOffPending || (Object)(object)player == (Object)null)
			{
				return;
			}
			if (_active)
			{
				_flyOffPending = false;
			}
			else
			{
				if (!((Character)player).IsOnGround())
				{
					return;
				}
				_flyOffPending = false;
				if (player.InDebugFlyMode() != _hadFly)
				{
					Silently(delegate
					{
						player.ToggleDebugFly();
					});
					((Character)player).Message((MessageType)1, "$lb_creative_off", 0, (Sprite)null, false);
					Log.Info("Landed; flight off.");
				}
			}
		}

		private static void Silently(Action action)
		{
			_silent = true;
			try
			{
				action();
			}
			finally
			{
				_silent = false;
			}
		}

		public static bool IsAdmin()
		{
			if (!((Object)(object)ZNet.instance == (Object)null))
			{
				return SynchronizationManager.Instance.PlayerIsAdmin;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class HammerKeeper
	{
		private const string Key = "LetsBuild.Hammers";

		[HarmonyPatch(typeof(Player), "Save")]
		[HarmonyPrefix]
		private static void Remember(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				int num = Count(((Humanoid)__instance).GetInventory());
				if (num > 0)
				{
					__instance.m_customData["LetsBuild.Hammers"] = num.ToString(CultureInfo.InvariantCulture);
				}
				else
				{
					__instance.m_customData.Remove("LetsBuild.Hammers");
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		[HarmonyPostfix]
		private static void Restore(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !__instance.m_customData.TryGetValue("LetsBuild.Hammers", out var value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			int num = result - Count(inventory);
			if (num <= 0)
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("LetsBuild_Hammer") : null);
			if ((Object)(object)val == (Object)null)
			{
				Log.Warning("A builder's hammer is missing from the inventory, but the item is not registered.");
				return;
			}
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				if (!inventory.AddItem(val, 1))
				{
					break;
				}
				num2++;
			}
			if (num2 > 0)
			{
				Log.Info("Restored " + num2 + " builder's hammer(s) lost while the mod was not loaded.");
				((Character)__instance).Message((MessageType)2, "$lb_hammer_restored", 0, (Sprite)null, false);
			}
			if (num2 < num)
			{
				((Character)__instance).Message((MessageType)2, "$lb_hammer_no_room", 0, (Sprite)null, false);
			}
		}

		private static int Count(Inventory inventory)
		{
			int num = 0;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (CreativeHammer.IsHammer(allItem))
				{
					num += allItem.m_stack;
				}
			}
			return num;
		}
	}
	[HarmonyPatch]
	internal static class HintPanel
	{
		private sealed class Line
		{
			public string Text;

			public string[] Keys;

			public bool Combination;
		}

		private sealed class Row
		{
			public GameObject Root;

			public TMP_Text Label;

			public readonly List<GameObject> Parts = new List<GameObject>();

			public string Shape;
		}

		private struct State
		{
			public bool Visible;

			public int Mode;

			public int Planned;

			public string Reason;

			public bool Holding;

			public bool Admin;

			public bool Active;

			public int ConfigVersion;

			public int Language;
		}

		private const float LineSpacing = 4f;

		private const float PartSpacing = 6f;

		private static RectTransform _panel;

		private static RectTransform _root;

		private static GameObject _bar;

		private static Image _edge;

		private static int _alignedWidth;

		private static int _alignedHeight;

		private static Image _picture;

		private static GameObject _labelTemplate;

		private static GameObject _keyTemplate;

		private static readonly List<Row> Rows = new List<Row>();

		private static readonly List<Line> Lines = new List<Line>();

		private static State _state;

		private static bool _hasState;

		private static bool _unfilled;

		private static int _language;

		private static bool _listening;

		[HarmonyPatch(typeof(KeyHints), "Start")]
		[HarmonyPostfix]
		private static void Build(KeyHints __instance)
		{
			try
			{
				Create(__instance);
			}
			catch (Exception ex)
			{
				_panel = null;
				Log.Warning("Key hints could not be built from the game's hint bar: " + ex.Message);
			}
		}

		private static void Create(KeyHints vanilla)
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: 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_02c5: Unknown result type (might be due to invalid IL or missing references)
			Rows.Clear();
			_hasState = false;
			GameObject buildHints = vanilla.m_buildHints;
			UIInputHint val = (((Object)(object)buildHints != (Object)null) ? buildHints.GetComponent<UIInputHint>() : null);
			Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)val.m_mouseKeyboardHint != (Object)null) ? val.m_mouseKeyboardHint.transform : null);
			Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.Find("Place") : null);
			Transform val4 = (((Object)(object)val3 != (Object)null) ? val3.Find("Text") : null);
			Transform val5 = (((Object)(object)val3 != (Object)null) ? val3.Find("key_bkg") : null);
			if ((Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val5.Find("Key") == (Object)null)
			{
				Log.Warning("The game's build hints are not built as expected; key hints are off.");
				return;
			}
			Transform val6 = LastEntry(val2);
			Transform val7 = (((Object)(object)val6 != (Object)null) ? LastVisible(val6) : buildHints.transform);
			Canvas componentInParent = buildHints.GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				Log.Warning("The game's build hints have no canvas; key hints are off.");
				return;
			}
			_root = (RectTransform)((Component)componentInParent.rootCanvas).transform;
			_bar = buildHints;
			GameObject val8 = new GameObject("LetsBuild_KeyHints", new Type[1] { typeof(RectTransform) });
			_panel = (RectTransform)val8.transform;
			((Transform)_panel).SetParent((Transform)(object)_root, false);
			Vector3 lossyScale = buildHints.transform.lossyScale;
			Vector3 lossyScale2 = ((Transform)_root).lossyScale;
			((Transform)_panel).localScale = new Vector3(Mathf.Approximately(lossyScale2.x, 0f) ? 1f : (lossyScale.x / lossyScale2.x), Mathf.Approximately(lossyScale2.y, 0f) ? 1f : (lossyScale.y / lossyScale2.y), 1f);
			_panel.anchorMin = new Vector2(1f, 0.5f);
			_panel.anchorMax = new Vector2(1f, 0.5f);
			_panel.pivot = new Vector2(1f, 0.5f);
			_panel.anchoredPosition = Vector2.zero;
			Log.Info("Key hints line up with \"" + (((Object)(object)val6 != (Object)null) ? (((Object)val6).name + "/") : "") + ((Object)val7).name + "\".");
			_edge = ((Component)val7).GetComponent<Image>();
			_picture = _edge;
			VerticalLayoutGroup obj = val8.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)5;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			ContentSizeFitter obj2 = val8.AddComponent<ContentSizeFitter>();
			obj2.horizontalFit = (FitMode)2;
			obj2.verticalFit = (FitMode)2;
			_labelTemplate = Template(((Component)val4).gameObject, "label");
			_keyTemplate = Template(((Component)val5).gameObject, "key");
			val8.SetActive(false);
		}

		private static Transform LastVisible(Transform entry)
		{
			for (int num = entry.childCount - 1; num >= 0; num--)
			{
				Transform child = entry.GetChild(num);
				if (((Component)child).gameObject.activeSelf && child is RectTransform && (Object)(object)((Component)child).GetComponent<Graphic>() != (Object)null)
				{
					return child;
				}
			}
			return entry;
		}

		private static Transform LastEntry(Transform keyboard)
		{
			for (int num = keyboard.childCount - 1; num >= 0; num--)
			{
				Transform child = keyboard.GetChild(num);
				if (((Component)child).gameObject.activeSelf && child is RectTransform)
				{
					return child;
				}
			}
			return null;
		}

		private static GameObject Template(GameObject source, string name)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//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_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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0088: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(source, (Transform)(object)_panel, false);
			((Object)val).name = "template_" + name;
			Localize[] componentsInChildren = val.GetComponentsInChildren<Localize>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			RectTransform val2 = (RectTransform)source.transform;
			RectTransform val3 = (RectTransform)val.transform;
			Rect rect = val2.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			val3.anchorMin = new Vector2(0.5f, 0.5f);
			val3.anchorMax = new Vector2(0.5f, 0.5f);
			val3.pivot = new Vector2(0.5f, 0.5f);
			val3.sizeDelta = size;
			val.SetActive(false);
			return val;
		}

		public static void Tick()
		{
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			if (Screen.width != _alignedWidth || Screen.height != _alignedHeight)
			{
				_alignedWidth = Screen.width;
				_alignedHeight = Screen.height;
				_picture = _edge;
			}
			AlignToPicture();
			if (Changed())
			{
				Collect();
				_unfilled = true;
			}
			bool flag = Lines.Count > 0 && (Object)(object)_bar != (Object)null && _bar.activeInHierarchy;
			if (((Component)_panel).gameObject.activeSelf != flag)
			{
				((Component)_panel).gameObject.SetActive(flag);
			}
			if (!flag || !_unfilled)
			{
				return;
			}
			_unfilled = false;
			while (Rows.Count < Lines.Count)
			{
				Rows.Add(NewRow());
			}
			bool flag2 = false;
			for (int i = 0; i < Rows.Count; i++)
			{
				Row row = Rows[i];
				bool flag3 = i < Lines.Count;
				if (row.Root.activeSelf != flag3)
				{
					row.Root.SetActive(flag3);
					flag2 = true;
				}
				if (flag3 && Fill(row, Lines[i]))
				{
					flag2 = true;
				}
			}
			if (flag2)
			{
				LayoutRebuilder.ForceRebuildLayoutImmediate(_panel);
			}
		}

		private static void AlignToPicture()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: 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_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: 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_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_picture == (Object)null || (Object)(object)_panel == (Object)null)
			{
				return;
			}
			Rect rect = ((Graphic)_picture).rectTransform.rect;
			if (((Rect)(ref rect)).width <= 0f || ((Rect)(ref rect)).height <= 0f)
			{
				return;
			}
			Image picture = _picture;
			_picture = null;
			float num = ((Rect)(ref rect)).xMin;
			float num2 = ((Rect)(ref rect)).width;
			Sprite val = (((Object)(object)picture.overrideSprite != (Object)null) ? picture.overrideSprite : picture.sprite);
			Rect rect2;
			if ((Object)(object)val != (Object)null && picture.preserveAspect)
			{
				rect2 = val.rect;
				if (((Rect)(ref rect2)).height > 0f)
				{
					rect2 = val.rect;
					float width = ((Rect)(ref rect2)).width;
					rect2 = val.rect;
					float num3 = width / ((Rect)(ref rect2)).height;
					float num4 = ((Rect)(ref rect)).height * num3;
					if (num4 < ((Rect)(ref rect)).width)
					{
						num = ((Rect)(ref rect)).xMin + (((Rect)(ref rect)).width - num4) * ((Graphic)picture).rectTransform.pivot.x;
						num2 = num4;
					}
				}
			}
			float num5 = 0f;
			if ((Object)(object)val != (Object)null)
			{
				rect2 = val.rect;
				if (((Rect)(ref rect2)).width > 0f)
				{
					float num6 = float.MinValue;
					Vector2[] array;
					try
					{
						array = val.vertices;
					}
					catch (Exception)
					{
						array = (Vector2[])(object)new Vector2[0];
					}
					Vector2[] array2 = array;
					foreach (Vector2 val2 in array2)
					{
						num6 = Mathf.Max(num6, val2.x);
					}
					if (num6 > float.MinValue)
					{
						float num7 = num6 * val.pixelsPerUnit + val.pivot.x;
						rect2 = val.rect;
						num5 = Mathf.Clamp01(1f - num7 / ((Rect)(ref rect2)).width);
					}
				}
			}
			float num8 = num + num2 * (1f - num5);
			Vector3 val3 = ((Transform)((Graphic)picture).rectTransform).TransformPoint(new Vector3(num8, ((Rect)(ref rect)).center.y, 0f));
			float x = ((Transform)_root).InverseTransformPoint(val3).x;
			rect2 = _root.rect;
			float num9 = Mathf.Min(0f, x - ((Rect)(ref rect2)).xMax);
			_panel.anchoredPosition = new Vector2(num9, 0f);
			string[] obj = new string[13]
			{
				"Key hints aligned to the drawn mouse: rect ",
				((Rect)(ref rect)).width.ToString("0.#"),
				" x ",
				((Rect)(ref rect)).height.ToString("0.#"),
				", preserve aspect ",
				picture.preserveAspect.ToString(),
				", sprite ",
				null,
				null,
				null,
				null,
				null,
				null
			};
			object obj2;
			if (!((Object)(object)val != (Object)null))
			{
				obj2 = "none";
			}
			else
			{
				rect2 = val.rect;
				string text = ((Rect)(ref rect2)).width.ToString();
				rect2 = val.rect;
				obj2 = text + " x " + ((Rect)(ref rect2)).height;
			}
			obj[7] = (string)obj2;
			obj[8] = ", right margin in sprite ";
			obj[9] = (num5 * 100f).ToString("0");
			obj[10] = " %, offset from the right ";
			obj[11] = num9.ToString("0.#");
			obj[12] = ".";
			Log.Info(string.Concat(obj));
		}

		private static Row NewRow()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			GameObject val = new GameObject("line", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)_panel, false);
			HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)5;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			ContentSizeFitter obj2 = val.AddComponent<ContentSizeFitter>();
			obj2.horizontalFit = (FitMode)2;
			obj2.verticalFit = (FitMode)2;
			return new Row
			{
				Root = val,
				Label = NewLabel(val.transform)
			};
		}

		private static TMP_Text NewLabel(Transform parent)
		{
			GameObject val = Object.Instantiate<GameObject>(_labelTemplate, parent, false);
			((Object)val).name = "text";
			val.SetActive(true);
			ContentSizeFitter[] components = val.GetComponents<ContentSizeFitter>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			TMP_Text component = val.GetComponent<TMP_Text>();
			component.textWrappingMode = (TextWrappingModes)0;
			return component;
		}

		private static bool SetText(TMP_Text label, string text)
		{
			//IL_0019: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (label.text == text)
			{
				return false;
			}
			label.text = text;
			Vector2 preferredValues = label.GetPreferredValues(text);
			label.rectTransform.sizeDelta = new Vector2(Mathf.Ceil(preferredValues.x), Mathf.Max(label.rectTransform.sizeDelta.y, preferredValues.y));
			return true;
		}

		private static bool Fill(Row row, Line line)
		{
			bool result = SetText(row.Label, line.Text);
			string text = (line.Combination ? "+" : "|") + string.Join("\u0001", line.Keys);
			if (text == row.Shape)
			{
				return result;
			}
			row.Shape = text;
			foreach (GameObject part in row.Parts)
			{
				part.SetActive(false);
				Object.Destroy((Object)(object)part);
			}
			row.Parts.Clear();
			for (int i = 0; i < line.Keys.Length; i++)
			{
				if (i > 0 && line.Combination)
				{
					TMP_Text val = NewLabel(row.Root.transform);
					val.text = "";
					SetText(val, "+");
					row.Parts.Add(((Component)val).gameObject);
				}
				GameObject val2 = Object.Instantiate<GameObject>(_keyTemplate, row.Root.transform, false);
				((Object)val2).name = "key";
				val2.SetActive(true);
				((Component)val2.transform.Find("Key")).GetComponent<TMP_Text>().text = line.Keys[i];
				row.Parts.Add(val2);
			}
			return true;
		}

		private static bool Changed()
		{
			if (!_listening)
			{
				_listening = true;
				Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, (Action)delegate
				{
					_language++;
				});
			}
			Player localPlayer = Player.m_localPlayer;
			bool flag = Settings.ShowKeyHints.Value && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && ((Character)localPlayer).InPlaceMode() && !Hud.IsPieceSelectionVisible() && Keys.GameHasInput(localPlayer);
			int num = 0;
			if (flag)
			{
				Piece val = PlayerAccess.SelectedPiece(localPlayer);
				if ((Object)(object)val != (Object)null && PlantGrid.IsPlantPiece(val))
				{
					num = ((Settings.PlantingEnabled.Value && !PlantGrid.Climbs(val)) ? 1 : 0);
				}
				else if (Settings.PrecisionEnabled.Value && PrecisionBuild.HoldsHammer(localPlayer))
				{
					num = 2;
				}
			}
			State state = new State
			{
				Visible = flag,
				Mode = num,
				Planned = ((num == 1) ? PlantGrid.PlannedCount : 0),
				Reason = ((num == 1) ? PlantGrid.MainReason : null),
				Holding = CreativeMode.Holding,
				Admin = CreativeMode.IsAdmin(),
				Active = CreativeMode.Active,
				ConfigVersion = Settings.Version,
				Language = _language
			};
			if (_hasState && state.Visible == _state.Visible && state.Mode == _state.Mode && state.Planned == _state.Planned && state.Reason == _state.Reason && state.Holding == _state.Holding && state.Admin == _state.Admin && state.Active == _state.Active && state.ConfigVersion == _state.ConfigVersion && state.Language == _state.Language)
			{
				return false;
			}
			_state = state;
			_hasState = true;
			return true;
		}

		private static void Collect()
		{
			Lines.Clear();
			Player localPlayer = Player.m_localPlayer;
			if (!Settings.ShowKeyHints.Value || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !((Character)localPlayer).InPlaceMode() || Hud.IsPieceSelectionVisible() || !Keys.GameHasInput(localPlayer))
			{
				return;
			}
			Piece val = PlayerAccess.SelectedPiece(localPlayer);
			if ((Object)(object)val != (Object)null && PlantGrid.IsPlantPiece(val))
			{
				if (Settings.PlantingEnabled.Value && !PlantGrid.Climbs(val))
				{
					PlantLines();
				}
			}
			else if (Settings.PrecisionEnabled.Value && PrecisionBuild.HoldsHammer(localPlayer))
			{
				PrecisionLines();
			}
			if (CreativeMode.Holding)
			{
				if (CreativeMode.IsAdmin())
				{
					Add("$lb_creative: " + Texts.OnOff(CreativeMode.Active), Settings.CreativeKey);
				}
				Add("$lb_camera_toggle", Settings.CameraKey);
			}
		}

		private static void PlantLines()
		{
			int num = Mathf.Max(1, PlantGrid.PlannedCount);
			Either("$lb_rows: " + Settings.Rows.Value, Settings.MoreRowsKey, Settings.FewerRowsKey);
			Either("$lb_columns: " + Settings.Columns.Value + "  (" + num + " $lb_plants)", Settings.MoreColumnsKey, Settings.FewerColumnsKey);
			Add("$lb_plant_snap: " + Texts.OnOff(Settings.SnapToPlants.Value), Settings.GridKey);
			if (Settings.BulkHarvest.Value)
			{
				List<string> list = new List<string>(Parts(Settings.BulkHarvestModifier)) { Texts.T("$KEY_Use") };
				Lines.Add(new Line
				{
					Text = Texts.T("$lb_bulk_harvest"),
					Keys = list.ToArray(),
					Combination = true
				});
			}
			if (!string.IsNullOrEmpty(PlantGrid.MainReason))
			{
				Lines.Add(new Line
				{
					Text = "<color=#ff7a6a>" + Texts.T(PlantGrid.MainReason) + "</color>",
					Keys = new string[0]
				});
			}
		}

		private static void PrecisionLines()
		{
			bool value = Settings.GridActive.Value;
			Add("$lb_grid: " + Texts.OnOff(value), Settings.GridKey);
			if (value)
			{
				Add("$lb_grid_size: " + PrecisionBuild.Metres(Settings.GridSize.Value), Settings.GridSizeKey);
				Add("$lb_rotation_step: " + PrecisionBuild.Degrees(Settings.RotationStep.Value), Settings.RotationKey);
				Add("$lb_snap_target: " + Texts.T(Settings.SnapToCellCenters.Value ? "$lb_snap_centres" : "$lb_snap_corners"), Settings.SnapTargetKey);
			}
		}

		private static void Add(string text, ConfigEntry<KeyboardShortcut> entry)
		{
			Lines.Add(new Line
			{
				Text = Texts.T(text),
				Keys = Parts(entry),
				Combination = true
			});
		}

		private static void Either(string text, ConfigEntry<KeyboardShortcut> first, ConfigEntry<KeyboardShortcut> second)
		{
			List<string> list = new List<string>();
			list.Add(string.Join(" + ", Parts(first)));
			list.Add(string.Join(" + ", Parts(second)));
			Lines.Add(new Line
			{
				Text = Texts.T(text),
				Keys = list.ToArray(),
				Combination = false
			});
		}

		private static string[] Parts(ConfigEntry<KeyboardShortcut> entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			KeyboardShortcut value = entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return new string[1] { "-" };
			}
			List<string> list = new List<string>();
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				list.Add(KeyName(modifier));
			}
			list.Add(KeyName(((KeyboardShortcut)(ref value)).MainKey));
			return list.ToArray();
		}

		private unsafe static string KeyName(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected I4, but got Unknown
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0036: 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_005a: Expected I4, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_005a: 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_0072: Expected I4, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Invalid comparison between Unknown and I4
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Invalid comparison between Unknown and I4
			if ((int)key <= 32)
			{
				if ((int)key == 13)
				{
					return Texts.T("$button_return");
				}
				if ((int)key == 32)
				{
					return Texts.T("$button_space");
				}
			}
			else
			{
				switch (key - 273)
				{
				case 0:
					return Texts.T("$lb_key_up");
				case 1:
					return Texts.T("$lb_key_down");
				case 3:
					return Texts.T("$lb_key_left");
				case 2:
					return Texts.T("$lb_key_right");
				}
				switch (key - 303)
				{
				case 1:
					return Texts.T("$button_lshift");
				case 0:
					return Texts.T("$button_rshift");
				case 5:
					return Texts.T("$button_lalt");
				case 4:
					return Texts.T("$button_ralt");
				case 3:
					return Texts.T("$button_lctrl");
				case 2:
					return Texts.T("$button_rctrl");
				}
				switch (key - 323)
				{
				case 0:
					return Texts.T("$button_mouse0");
				case 1:
					return Texts.T("$button_mouse1");
				case 2:
					return Texts.T("$button_mouse2");
				}
			}
			if ((int)key >= 97 && (int)key <= 122)
			{
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
			return ZInput.KeyCodeToDisplayName(key);
		}
	}
	internal static class Keys
	{
		private static readonly Func<Player, bool> PlayerTakesInput = TakeInputDelegate();

		private static Func<Player, bool> TakeInputDelegate()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);
			if (!(methodInfo != null))
			{
				return null;
			}
			return AccessTools.MethodDelegate<Func<Player, bool>>(methodInfo, (object)null, true);
		}

		public static bool Down(ConfigEntry<KeyboardShortcut> entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return false;
			}
			return ModifiersHeld(value);
		}

		public static bool Held(ConfigEntry<KeyboardShortcut> entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return false;
			}
			return ModifiersHeld(value);
		}

		private static bool ModifiersHeld(KeyboardShortcut shortcut)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		public static bool GameHasInput(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (PlayerTakesInput != null)
			{
				return PlayerTakesInput(player);
			}
			return true;
		}
	}
	internal static class Log
	{
		private static ManualLogSource _source;

		public static void Init(ManualLogSource source)
		{
			_source = source;
		}

		public static void Info(string message)
		{
			ManualLogSource source = _source;
			if (source != null)
			{
				source.LogInfo((object)message);
			}
		}

		public static void Warning(string message)
		{
			ManualLogSource source = _source;
			if (source != null)
			{
				source.LogWarning((object)message);
			}
		}
	}
	[HarmonyPatch]
	internal static class Growth
	{
		private sealed class Spot
		{
			public bool Placed;

			public readonly List<Area> Areas = new List<Area>(1);

			public double PlantedAt = double.MinValue;

			public long NextPeriod;

			public double WetBefore;

			public long NowPeriod = long.MinValue;

			public bool NowWet;

			public int ForcedVersion = -1;

			public float RoofCheckedAt = float.NegativeInfinity;

			public bool Roofed;

			public int HiveVersion = -1;

			public int SettingsVersion = -1;

			public List<Component> Hives;
		}

		private sealed class Area
		{
			public BiomeSector Sector;

			public byte Edges;

			public bool Forced;

			public bool ForcedWet;
		}

		private readonly struct Period : IEquatable<Period>
		{
			private readonly BiomeSector _sector;

			private readonly byte _edges;

			private readonly long _index;

			public Period(BiomeSector sector, byte edges, long index)
			{
				_sector = sector;
				_edges = edges;
				_index = index;
			}

			public bool Equals(Period other)
			{
				if (_sector == other._sector && _edges == other._edges)
				{
					return _index == other._index;
				}
				return false;
			}

			public override bool Equals(object obj)
			{
				if (obj is Period other)
				{
					return Equals(other);
				}
				return false;
			}

			public override int GetHashCode()
			{
				int num = ((RuntimeHelpers.GetHashCode(_sector) * 397) ^ _edges) * 397;
				long index = _index;
				return num ^ index.GetHashCode();
			}
		}

		private sealed class HiveState
		{
			public float CheckedAt = float.NegativeInfinity;

			public bool Working;
		}

		private const float Recheck = 10f;

		private const int MaxPeriods = 4096;

		private const int MaxForecast = 1000;

		private static readonly Func<EnvMan, List<EnvEntry>, EnvSetup> SelectEnvironment = AccessTools.MethodDelegate<Func<EnvMan, List<EnvEntry>, EnvSetup>>(AccessTools.Method(typeof(EnvMan), "SelectWeightedEnvironment", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Plant, float> GrowTime = AccessTools.MethodDelegate<Func<Plant, float>>(AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Beehive, bool> RightBiome = AccessTools.MethodDelegate<Func<Beehive, bool>>(AccessTools.Method(typeof(Beehive), "CheckBiome", (Type[])null, (Type[])null), (object)null, true);

		private static readonly Func<Beehive, bool> FreeSpace = AccessTools.MethodDelegate<Func<Beehive, bool>>(AccessTools.Method(typeof(Beehive), "HaveFreeSpace", (Type[])null, (Type[])null), (object)null, true);

		private static readonly FieldRef<Beehive, ZNetView> HiveView = AccessTools.FieldRefAccess<Beehive, ZNetView>("m_nview");

		private static int _roofMask;

		private static readonly ConditionalWeakTable<Plant, Spot> Spots = new ConditionalWeakTable<Plant, Spot>();

		private const float RainReach = 16f;

		private static readonly Vector2[] AreaSamples = BuildSamples();

		private static readonly Dictionary<Period, bool> Weather = new Dictionary<Period, bool>();

		private static EnvMan _weatherOf;

		private static string _forcedName = "";

		private static bool _forcedWet;

		private static int _forcedVersion;

		private static bool _inRain;

		private static readonly List<Component> Hives = new List<Component>();

		private static int _hiveVersion;

		private static readonly Predicate<Component> Gone = (Component hive) => (Object)(object)hive == (Object)null;

		private static MethodInfo _boxGroup;

		private static MethodInfo _boxQueens;

		private static MethodInfo _boxWarm;

		private static bool _toldBoxFailed;

		private static readonly ConditionalWeakTable<Component, HiveState> HiveStates = new ConditionalWeakTable<Component, HiveState>();

		private static Vector2[] BuildSamples()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2> list = new List<Vector2> { Vector2.zero };
			float[] array = new float[2] { 8f, 16f };
			foreach (float num in array)
			{
				for (int j = 0; j < 8; j++)
				{
					float num2 = (float)j * (float)Math.PI / 4f;
					list.Add(new Vector2(Mathf.Cos(num2), Mathf.Sin(num2)) * num);
				}
			}
			return list.ToArray();
		}

		private static void ReadForced(EnvMan env)
		{
			string text = env.m_debugEnv ?? "";
			if (text == _forcedName)
			{
				return;
			}
			_forcedName = text;
			_forcedWet = false;
			foreach (EnvSetup environment in env.m_environments)
			{
				if (environment.m_name == text)
				{
					_forcedWet = environment.m_isWet;
					break;
				}
			}
			_forcedVersion++;
		}

		[HarmonyPatch(typeof(Plant), "TimeSincePlanted")]
		[HarmonyPostfix]
		private static void Rain(Plant __instance, ref double __result)
		{
			if (_inRain || !Settings.RainGrowth.Value || __result <= 0.0)
			{
				return;
			}
			_inRain = true;
			try
			{
				AddRain(__instance, ref __result);
			}
			finally
			{
				_inRain = false;
			}
		}

		private static void AddRain(Plant __instance, ref double __result)
		{
			float value = Settings.RainGrowthSpeed.Value;
			EnvMan instance = EnvMan.instance;
			if (value <= 1f || (Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			Spot orCreateValue = Spots.GetOrCreateValue(__instance);
			if (Place(__instance, orCreateValue))
			{
				ReadForced(instance);
				double timeSeconds = ZNet.instance.GetTimeSeconds();
				double num = WetSeconds(__instance, orCreateValue, instance, timeSeconds, timeSeconds - __result);
				if (num > 0.0 && !Roofed(__instance, orCreateValue))
				{
					__result += num * (double)(value - 1f);
				}
			}
		}

		public static bool RainingOn(Plant plant)
		{
			EnvMan instance = EnvMan.instance;
			if (!Settings.RainGrowth.Value || Settings.RainGrowthSpeed.Value <= 1f || (Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || instance.m_environmentDuration <= 0 || !Spots.TryGetValue(plant, out var value))
			{
				return false;
			}
			ReadForced(instance);
			long num = (long)ZNet.instance.GetTimeSeconds() / instance.m_environmentDuration;
			if (value.NowPeriod == num && value.ForcedVersion == _forcedVersion && value.NowWet)
			{
				return !value.Roofed;
			}
			return false;
		}

		public static double SecondsLeft(Plant plant, double since, double total)
		{
			double num = total - since;
			EnvMan instance = EnvMan.instance;
			float value = Settings.RainGrowthSpeed.Value;
			if (num <= 0.0 || !Settings.RainGrowth.Value || value <= 1f || (Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || instance.m_environmentDuration <= 0 || !Spots.TryGetValue(plant, out var value2) || !value2.Placed || Roofed(plant, value2))
			{
				return Math.Max(0.0, num);
			}
			ReadForced(instance);
			long environmentDuration = instance.m_environmentDuration;
			double timeSeconds = ZNet.instance.GetTimeSeconds();
			long num2 = (long)timeSeconds / environmentDuration;
			double num3 = 0.0;
			int num4 = 0;
			while (num4 < 1000)
			{
				double num5 = (double)(num2 + 1) * (double)environmentDuration - (timeSeconds + num3);
				double num6 = (Wet(instance, value2, num2) ? ((double)value) : 1.0);
				if (num <= num5 * num6)
				{
					return num3 + num / num6;
				}
				num -= num5 * num6;
				num3 += num5;
				num4++;
				num2++;
			}
			return num3 + num;
		}

		private static Area NewArea(BiomeSector sector, byte edges)
		{
			Area area = new Area
			{
				Sector = sector,
				Edges = edges
			};
			foreach (AltBiome altBiome in sector.AltBiomes)
			{
				if (altBiome == null || string.IsNullOrEmpty(altBiome.m_forceEnvironment))
				{
					continue;
				}
				area.Forced = true;
				foreach (EnvSetup environment in EnvMan.instance.m_environments)
				{
					if (environment.m_name == altBiome.m_forceEnvironment)
					{
						area.ForcedWet = environment.m_isWet;
						break;
					}
				}
				break;
			}
			return area;
		}

		private static bool Place(Plant plant, Spot spot)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (spot.Placed)
			{
				return true;
			}
			WorldGenerator instance = WorldGenerator.instance;
			AltBiomeWorldData val = ZNet.World?.m_biomeData;
			if (instance == null || (Object)(object)EnvMan.instance == (Object)null || val == null || !val.IsReady)
			{
				return false;
			}
			Vector3 position = ((Component)plant).transform.position;
			spot.Areas.Clear();
			Vector2[] areaSamples = AreaSamples;
			Vector3 val3 = default(Vector3);
			foreach (Vector2 val2 in areaSamples)
			{
				((Vector3)(ref val3))..ctor(position.x + val2.x, position.y, position.z + val2.y);
				BiomeSector biomeSector = instance.GetBiomeSector(val3, false);
				byte b = (byte)((WorldGenerator.IsAshlands(val3.x, val3.z) ? 1u : 0u) | (uint)(WorldGenerator.IsDeepnorth(val3.x, val3.y) ? 2 : 0));
				bool flag = false;
				foreach (Area area in spot.Areas)
				{
					if (area.Sector == biomeSector && area.Edges == b)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					spot.Areas.Add(NewArea(biomeSector, b));
				}
			}
			spot.Placed = true;
			return true;
		}

		private static double WetSeconds(Plant plant, Spot spot, EnvMan env, double now, double plantedAt)
		{
			long environmentDuration = env.m_environmentDuration;
			if (environmentDuration <= 0 || plantedAt < 0.0)
			{
				return 0.0;
			}
			long num = (long)now / environmentDuration;
			if (Math.Abs(plantedAt - spot.PlantedAt) > 1.0 || num < spot.NextPeriod || spot.ForcedVersion != _forcedVersion)
			{
				spot.ForcedVersion = _forcedVersion;
				spot.PlantedAt = plantedAt;
				spot.NextPeriod = (long)plantedAt / environmentDuration;
				spot.WetBefore = 0.0;
				spot.NowPeriod = long.MinValue;
			}
			if (spot.NextPeriod < num)
			{
				double num2 = plantedAt + (double)GrowTime(plant);
				long num3 = Math.Min(num, (long)num2 / environmentDuration + 1);
				while (spot.NextPeriod < num3)
				{
					long nextPeriod = spot.NextPeriod;
					if (Wet(env, spot, nextPeriod))
					{
						spot.WetBefore += (double)(nextPeriod + 1) * (double)environmentDuration - Math.Max((double)nextPeriod * (double)environmentDuration, plantedAt);
					}
					spot.NextPeriod++;
				}
			}
			double num4 = spot.WetBefore;
			if (spot.NextPeriod == num)
			{
				if (spot.NowPeriod != num)
				{
					spot.NowPeriod = num;
					spot.NowWet = Wet(env, spot, num);
				}
				if (spot.NowWet)
				{
					num4 += now - Math.Max((double)num * (double)environmentDuration, plantedAt);
				}
			}
			return num4;
		}

		private static bool Wet(EnvMan env, Spot spot, long period)
		{
			if (_forcedName.Length > 0)
			{
				return _forcedWet;
			}
			foreach (Area area in spot.Areas)
			{
				if (Wet(env, area, period))
				{
					return true;
				}
			}
			return false;
		}

		private static bool Wet(EnvMan env, Area area, long period)
		{
			if (area.Forced)
			{
				return area.ForcedWet;
			}
			if (env != _weatherOf || Weather.Count > 4096)
			{
				Weather.Clear();
				_weatherOf = env;
			}
			Period key = new Period(area.Sector, area.Edges, period);
			if (!Weather.TryGetValue(key, out var value))
			{
				value = Choose(env, area, period)?.m_isWet ?? false;
				Weather[key] = value;
			}
			return value;
		}

		private static EnvSetup Choose(EnvMan env, Area area, long period)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			State state = Random.state;
			Random.InitState((int)period);
			EnvSetup result = null;
			List<EnvEntry> availableEnvironments = env.GetAvailableEnvironments(area.Sector);
			if (availableEnvironments != null && availableEnvironments.Count > 0)
			{
				result = SelectEnvironment(env, availableEnvironments);
				foreach (EnvEntry item in availableEnvironments)
				{
					if (item.m_ashlandsOverride && (area.Edges & 1) != 0)
					{
						result = item.m_env;
					}
					if (item.m_deepnorthOverride && (area.Edges & 2) != 0)
					{
						result = item.m_env;
					}
				}
			}
			Random.state = state;
			return result;
		}

		private static bool Roofed(Plant plant, Spot spot)
		{
			//IL_0052: 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)
			float time = Time.time;
			if (time - spot.RoofCheckedAt >= 10f)
			{
				spot.RoofCheckedAt = time;
				if (_roofMask == 0)
				{
					_roofMask = LayerMask.GetMask(new string[3] { "Default", "static_solid", "piece" });
				}
				spot.Roofed = Physics.Raycast(((Component)plant).transform.position, Vector3.up, 100f, _roofMask);
			}
			return spot.Roofed;
		}

		[HarmonyPatch(typeof(Beehive), "Awake")]
		[HarmonyPostfix]
		private static void HiveBuilt(Beehive __instance)
		{
			ZNetView val = HiveView.Invoke(__instance);
			if ((Object)(object)val != (Object)null && val.GetZDO() != null)
			{
				Hives.Add((Component)(object)__instance);
				_hiveVersion++;
			}
		}

		public static void PatchBeeBoxes(Harmony harmony)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("BetrValheim.Bees.BeeBox");
			if (!(type == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, "Awake", (Type[])null, (Type[])null);
				_boxGroup = AccessTools.Method(type, "Group", (Type[])null, (Type[])null);
				_boxQueens = AccessTools.Method(type, "Queens", (Type[])null, (Type[])null);
				_boxWarm = AccessTools.Method(type, "Warm", (Type[])null, (Type[])null);
				if (methodInfo == null || _boxGroup == null || _boxQueens == null || _boxWarm == null)
				{
					_boxGroup = (_boxQueens = (_boxWarm = null));
					Log.Warning("BetrValheim's bee boxes could not be read; they do not speed up growth.");
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Growth), "BoxBuilt", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static void BoxBuilt(MonoBehaviour __instance)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.GetZDO() != null)
			{
				Hives.Add((Component)(object)__instance);
				_hiveVersion++;
			}
		}

		[HarmonyPatch(typeof(Plant), "GetGrowTime")]
		[HarmonyPostfix]
		private static void Bees(Plant __instance, ref float __result)
		{
			if (BeesAt(__instance))
			{
				__result /= Settings.BeeGrowthSpeed.Value;
			}
		}

		public static bool BeesAt(Plant plant)
		{
			if (!Settings.BeeGrowth.Value || Settings.BeeGrowthSpeed.Value <= 1f || Hives.Count == 0)
			{
				return false;
			}
			Spot orCreateValue = Spots.GetOrCreateValue(plant);
			if (orCreateValue.HiveVersion != _hiveVersion || orCreateValue.SettingsVersion != Settings.Version)
			{
				FindHives(plant, orCreateValue);
			}
			List<Component> hives = orCreateValue.Hives;
			if (hives == null)
			{
				return false;
			}
			for (int i = 0; i < hives.Count; i++)
			{
				Component val = hives[i];
				if ((Object)(object)val == (Object)null)
				{
					_hiveVersion++;
				}
				else if (Working(val))
				{
					return true;
				}
			}
			return false;
		}

		private static void FindHives(Plant plant, Spot spot)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0069: 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)
			if (Hives.RemoveAll(Gone) > 0)
			{
				_hiveVersion++;
			}
			spot.Hives?.Clear();
			float value = Settings.BeeRange.Value;
			float num = value * value;
			Vector3 position = ((Component)plant).transform.position;
			foreach (Component hive in Hives)
			{
				Vector3 val = hive.transform.position - position;
				if (((Vector3)(ref val)).sqrMagnitude <= num)
				{
					(spot.Hives ?? (spot.Hives = new List<Component>(1))).Add(hive);
				}
			}
			spot.HiveVersion = _hiveVersion;
			spot.SettingsVersion = Settings.Version;
		}

		private static bool Working(Component hive)
		{
			HiveState orCreateValue = HiveStates.GetOrCreateValue(hive);
			float time = Time.time;
			if (time - orCreateValue.CheckedAt >= 10f)
			{
				orCreateValue.CheckedAt = time;
				Beehive val = (Beehive)(object)((hive is Beehive) ? hive : null);
				orCreateValue.Working = ((val == null) ? BoxWorking(hive) : (RightBiome(val) && FreeSpace(val)));
			}
			return orCreateValue.Working;
		}

		private static bool BoxWorking(Component box)
		{
			if (_boxGroup == null)
			{
				return false;
			}
			try
			{
				object obj = _boxGroup.Invoke(box, null);
				return (int)_boxQueens.Invoke(null, new object[1] { obj }) > 0 && (bool)_boxWarm.Invoke(box, null);
			}
			catch (Exception ex)
			{
				if (!_toldBoxFailed)
				{
					_toldBoxFailed = true;
					Log.Warning("BetrValheim's bee box could not be asked whether its bees work: " + (ex.InnerException ?? ex).Message);
				}
				return false;
			}
		}
	}
	[HarmonyPatch]
	internal static class GrowthInfo
	{
		private static readonly MethodInfo SincePlanted = AccessTools.Method(typeof(Plant), "TimeSincePlanted", (Type[])null, (Type[])null);

		private static readonly MethodInfo GrowTime = AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null);

		private static readonly FieldRef<Pickable, ZNetView> PickableView = AccessTools.FieldRefAccess<Pickable, ZNetView>("m_nview");

		private static readonly FieldRef<Plant, ZNetView> PlantView = AccessTools.FieldRefAccess<Plant, ZNetView>("m_nview");

		[HarmonyPatch(typeof(Plant), "GetHoverText")]
		[HarmonyPostfix]
		private static void PlantText(Plant __instance, ref string __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.ShowGrowthInfo.Value || string.IsNullOrEmpty(__result) || (int)__instance.GetStatus() != 0 || SincePlanted == null || GrowTime == null)
			{
				return;
			}
			ZNetView val = PlantView.Invoke(__instance);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return;
			}
			double num = (double)SincePlanted.Invoke(__instance, null);
			float num2 = (float)GrowTime.Invoke(__instance, null);
			if (!(num2 <= 0f))
			{
				double num3 = Growth.SecondsLeft(__instance, num, num2);
				int num4 = Mathf.Clamp((int)(num / (double)num2 * 100.0), 0, 100);
				string text = ((num3 > 0.0) ? (num4 + " % " + Texts.T("$lb_grown") + ", " + Texts.T("$lb_ready_in") + " " + Duration(num3)) : ("100 % " + Texts.T("$lb_grown") + ", " + Texts.T("$lb_ready")));
				__result = __result + "\n<color=#c8c8c8>" + text + "</color>";
				string text2 = ((num3 > 0.0) ? Boost(__instance) : null);
				if (text2 != null)
				{
					__result = __result + "\n<color=#a8d8a0>" + text2 + "</color>";
				}
			}
		}

		[HarmonyPatch(typeof(Pickable), "GetHoverText")]
		[HarmonyPostfix]
		private static void PickableText(Pickable __instance, ref string __result)
		{
			if (!Settings.ShowGrowthInfo.Value || !__instance.GetPicked() || __instance.m_respawnTimeMinutes <= 0f)
			{
				return;
			}
			ZNetView val = PickableView.Invoke(__instance);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return;
			}
			long num = val.GetZDO().GetLong(ZDOVars.s_pickedTime, 0L);
			if (num > 1)
			{
				TimeSpan timeSpan = ZNet.instance.GetTime() - new DateTime(num);
				double num2 = (double)__instance.m_respawnTimeMinutes * 60.0 - timeSpan.TotalSeconds;
				if (!(num2 <= 0.0))
				{
					string text = Localization.instance.Localize(__instance.GetHoverName());
					__result = text + "\n<color=#c8c8c8>" + Texts.T("$lb_grows_back_in") + " " + Duration(num2) + "</color>";
				}
			}
		}

		private static string Boost(Plant plant)
		{
			bool flag = Growth.RainingOn(plant);
			bool flag2 = Growth.BeesAt(plant);
			if (!flag && !flag2)
			{
				return null;
			}
			float num = (flag ? Settings.RainGrowthSpeed.Value : 1f);
			float num2 = (flag2 ? Settings.BeeGrowthSpeed.Value : 1f);
			string text = Texts.T("$lb_growth") + " ×" + Texts.Number(num * num2) + " (";
			text = ((!(flag && flag2)) ? (text + Texts.T(flag ? "$lb_rain" : "$lb_bees")) : (text + Texts.T("$lb_rain") + " ×" + Texts.Number(num) + ", " + Texts.T("$lb_bees") + " ×" + Texts.Number(num2)));
			return text + ")";
		}

		private static string Duration(double seconds)
		{
			TimeSpan timeSpan = TimeSpan.FromSeconds(Math.Max(0.0, seconds));
			if (timeSpan.TotalHours >= 1.0)
			{
				return (int)timeSpan.TotalHours + " h " + timeSpan.Minutes.ToString("00") + " min";
			}
			if (timeSpan.TotalMinutes >= 1.0)
			{
				return (int)timeSpan.TotalMinutes + " min";
			}
			return timeSpan.Seconds + " s";
		}
	}
	[HarmonyPatch]
	internal static class Harvest
	{
		private static readonly MethodInfo HoneyLevel = AccessTools.Method(typeof(Beehive), "GetHoneyLevel", (Type[])null, (Type[])null);

		private static readonly Dictionary<string, Piece> SeedFor = new Dictionary<string, Piece>();

		private static ObjectDB _mappedFrom;

		private static bool _bulk;

		private static readonly object Yes = new object();

		private static readonly object No = new object();

		private static readonly ConditionalWeakTable<Pickable, object> Growing = new ConditionalWeakTable<Pickable, object>();

		public static void Tick(Player player)
		{
			if ((Object)(object)player != (Object)null && Keys.Down(Settings.ReplantKey) && Keys.GameHasInput(player))
			{
				Settings.ReplantOnHarvest.Value = !Settings.ReplantOnHarvest.Value;
				((Character)player).Message((MessageType)1, "$lb_replant: " + Texts.OnOff(Settings.ReplantOnHarvest.Value), 0, (Sprite)null, false);
			}
		}

		[HarmonyPatch(typeof(Pickable), "Interact")]
		[HarmonyPrefix]
		private static void BeforePick(Pickable __instance, out bool __state)
		{
			__state = Ripe(__instance);
		}

		[HarmonyPatch(typeof(Pickable), "Interact")]
		[HarmonyPostfix]
		private static void AfterPick(Pickable __instance, Humanoid character, bool repeat, bool __state)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!__state)
			{
				return;
			}
			Player val = (Player)(object)((character is Player) ? character : null);
			if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				if (Settings.ReplantOnHarvest.Value)
				{
					Replant(val, __instance);
				}
				if (!repeat && !_bulk)
				{
					Bulk(val, ((Component)__instance).transform.position, Utils.GetPrefabName(((Component)__instance).gameObject));
				}
			}
		}

		[HarmonyPatch(typeof(Beehive), "Interact")]
		[HarmonyPrefix]
		private static void BeforeHive(Beehive __instance, out bool __state)
		{
			__state = Honey(__instance) > 0;
		}

		[HarmonyPatch(typeof(Beehive), "Interact")]
		[HarmonyPostfix]
		private static void AfterHive(Beehive __instance, Humanoid character, bool repeat, bool __state)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (__state && !repeat && !_bulk)
			{
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
				{
					Bulk(val, ((Component)__instance).transform.position, Utils.GetPrefabName(((Component)__instance).gameObject));
				}
			}
		}

		private static bool Ripe(Pickable pickable)
		{
			if ((Object)(object)pickable != (Object)null && !pickable.GetPicked())
			{
				return pickable.GetEnabled == 1;
			}
			return false;
		}

		private static int Honey(Beehive hive)
		{
			if (!(HoneyLevel != null))
			{
				return 0;
			}
			return (int)HoneyLevel.Invoke(hive, null);
		}

		private static void Bulk(Player player, Vector3 centre, string kind)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.BulkHarvest.Value || !Keys.Held(Settings.BulkHarvestModifier))
			{
				return;
			}
			bool value = Settings.HarvestSameKindOnly.Value;
			HashSet<int> hashSet = new HashSet<int>();
			int num = 0;
			_bulk = true;
			try
			{
				Collider[] array = Physics.OverlapSphere(centre, Settings.HarvestRadius.Value, -1, (QueryTriggerInteraction)2);
				foreach (Collider val in array)
				{
					Pickable componentInParent = ((Component)val).GetComponentInParent<Pickable>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						if (hashSet.Add(((Object)((Component)componentInParent).gameObject).GetInstanceID()) && Ripe(componentInParent) && Harvestable(componentInParent) && (!value || Utils.GetPrefabName(((Component)componentInParent).gameObject) == kind))
						{
							componentInParent.Interact((Humanoid)(object)player, false, false);
							num++;
						}
						continue;
					}
					Beehive componentInParent2 = ((Component)val).GetComponentInParent<Beehive>();
					if ((Object)(object)componentInParent2 != (Object)null && hashSet.Add(((Object)((Component)componentInParent2).gameObject).GetInstanceID()) && Honey(componentInParent2) > 0 && (!value || Utils.GetPrefabName(((Component)componentInParent2).gameObject) == kind))
					{
						componentInParent2.Interact((Humanoid)(object)player, false, false);
						num++;
					}
				}
			}
			finally
			{
				_bulk = false;
			}
			if (num > 0)
			{
				Log.Info("Bulk harvest picked " + num + " more.");
			}
		}

		private static bool Harvestable(Pickable pickable)
		{
			if (!IsGrowing(pickable))
			{
				return pickable.m_harvestable;
			}
			return true;
		}

		public static bool IsGrowing(Pickable pickable)
		{
			if (Growing.TryGetValue(pickable, out var value))
			{
				return value == Yes;
			}
			string prefabName = Utils.GetPrefabName(((Component)pickable).gameObject);
			bool flag = SeedMap().ContainsKey(prefabName) || Plantables.IsWildPlant(prefabName);
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				Growing.Add(pickable, flag ? Yes : No);
			}
			return flag;
		}

		private static void Replant(Player player, Pickable pickable)
		{
			//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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (!SeedMap().TryGetValue(Utils.GetPrefabName(((Component)pickable).gameObject), out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)pickable).transform.position;
			if (Location.IsInsideNoBuildLocation(position) || !PrivateArea.CheckAccess(position, 0f, false, false))
			{
				return;
			}
			bool flag = player.NoCostCheat();
			if (flag || player.HaveRequirements(value, (RequirementMode)0))
			{
				bool flag2 = (((Humanoid)player).GetInventory().ItemCheated(value.m_resources, -1, true) || flag) && !PlayerProfile.s_bypassCheatChecks;
				if (!flag && !ZoneSystem.instance.GetGlobalKey(value.FreeBuildKey()))
				{
					player.ConsumeResources(value.m_resources, 0, -1, 1);
				}
				Quaternion val = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
				player.PlacePiece(value, position, val, false, flag2);
			}
		}

		private static Dictionary<string, Piece> SeedMap()
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance == (Object)(object)_mappedFrom)
			{
				return SeedFor;
			}
			SeedFor.Clear();
			_mappedFrom = instance;
			GameObject itemPrefab = instance.GetItemPrefab("Cultivator");
			PieceTable val = ((!((Object)(object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces);
			if ((Object)(object)val == (Object)null)
			{
				Log.Warning("Cultivator piece table not found; replanting is unavailable.");
				return SeedFor;
			}
			foreach (GameObject piece in val.m_pieces)
			{
				Plant val2 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Plant>() : null);
				Piece val3 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
				{
					continue;
				}
				GameObject[] grownPrefabs = val2.m_grownPrefabs;
				foreach (GameObject val4 in grownPrefabs)
				{
					if ((Object)(object)val4 != (Object)null && (Object)(object)val4.GetComponent<Pickable>() != (Object)null && !SeedFor.ContainsKey(((Object)val4).name))
					{
						SeedFor[((Object)val4).name] = val3;
					}
				}
			}
			return SeedFor;
		}
	}
	internal static class MeshCut
	{
		private sealed class Builder
		{
			private readonly Vector3[] _v;

			private readonly Vector3[] _n;

			private readonly Vector4[] _t;

			private readonly Color[] _c;

			private readonly Vector2[] _uv;

			private readonly Vector2[] _uv2;

			public readonly List<Vector3> V = new List<Vector3>();

			public readonly List<Vector3> N = new List<Vector3>();

			public readonly List<Vector4> T = new List<Vector4>();

			public readonly List<Color> C = new List<Color>();

			public readonly List<Vector2> UV = new List<Vector2>();

			public readonly List<Vector2> UV2 = new List<Vector2>();

			private readonly Dictionary<int, int> _kept = new Dictionary<int, int>();

			private readonly Dictionary<long, int> _cuts = new Dictionary<long, int>();

			public bool HasN => _n.Length == _v.Length;

			public bool HasT => _t.Length == _v.Length;

			public bool HasC => _c.Length == _v.Length;

			public bool HasUV => _uv.Length == _v.Length;

			public bool HasUV2 => _uv2.Length == _v.Length;

			public Builder(Mesh mesh)
			{
				_v = mesh.vertices;
				_n = mesh.normals;
				_t = mesh.tangents;
				_c = mesh.colors;
				_uv = mesh.uv;
				_uv2 = mesh.uv2;
			}

			public float Y(int i)
			{
				return _v[i].y;
			}

			public int Keep(int i)
			{
				//IL_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: 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_006c: 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_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				if (!_kept.TryGetValue(i, out var value))
				{
					value = Add(_v[i], HasN ? _n[i] : Vector3.up, HasT ? _t[i] : Vector4.zero, HasC ? _c[i] : Color.white, HasUV ? _uv[i] : Vector2.zero, HasUV2 ? _uv2[i] : Vector2.zero);
					_kept[i] = value;
				}
				return value;
			}

			public int Cut(int a, int b, float cut)
			{
				//IL_005b: 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_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: 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_00a2: 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)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: 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_00ea: 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_00fc: 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_0117: 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_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0156: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				long key = ((a < b) ? (((long)a << 32) | (uint)b) : (((long)b << 32) | (uint)a));
				if (!_cuts.TryGetValue(key, out var value))
				{
					float num = Mathf.InverseLerp(_v[a].y, _v[b].y, cut);
					Vector3 v = Vector3.Lerp(_v[a], _v[b], num);
					Vector3 n;
					if (!HasN)
					{
						n = Vector3.up;
					}
					else
					{
						Vector3 val = Vector3.Lerp(_n[a], _n[b], num);
						n = ((Vector3)(ref val)).normalized;
					}
					value = Add(v, n, HasT ? Vector4.Lerp(_t[a], _t[b], num) : Vector4.zero, HasC ? Color.Lerp(_c[a], _c[b], num) : Color.white, HasUV ? Vector2.Lerp(_uv[a], _uv[b], num) : Vector2.zero, HasUV2 ? Vector2.Lerp(_uv2[a], _uv2[b], num) : Vector2.zero);
					_cuts[key] = value;
				}
				return value;
			}

			public int Add(Vector3 v, Vector3 n, Vector4 t, Color c, Vector2 uv, Vector2 uv2)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				V.Add(v);
				N.Add(n);
				T.Add(t);
				C.Add(c);
				UV.Add(uv);
				UV2.Add(uv2);
				return V.Count - 1;
			}

			public int Lid(int i)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				return Add(V[i], Vector3.up, T[i], C[i], UV[i], UV2[i]);
			}
		}

		public static Mesh Below(Mesh source, float cut)
		{
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			Builder builder = new Builder(source);
			int subMeshCount = source.subMeshCount;
			List<int>[] array = new List<int>[subMeshCount];
			List<int> list = new List<int>(4);
			for (int i = 0; i < subMeshCo