Decompiled source of DadsQoL v1.1.0

DadsQoL.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using DadsQoL.MassFarming;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DadsQoL")]
[assembly: AssemblyDescription("Configurable Valheim quality-of-life features")]
[assembly: AssemblyCompany("Dad_Is_Bored")]
[assembly: AssemblyProduct("DadsQoL")]
[assembly: AssemblyCopyright("Copyright 2026 Dad_Is_Bored")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 DadsQoL
{
	[BepInPlugin("com.dadisbored.dadsqol", "DadsQoL", "1.1.0")]
	[BepInProcess("valheim.exe")]
	public sealed class DadsQoLPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dadisbored.dadsqol";

		public const string PluginName = "DadsQoL";

		public const string PluginVersion = "1.1.0";

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<bool> CarryWeightEnabled;

		internal static ConfigEntry<float> CarryWeight;

		internal static ConfigEntry<bool> PickupRadiusEnabled;

		internal static ConfigEntry<float> PickupRadius;

		internal static ConfigEntry<bool> EquipmentInWaterEnabled;

		internal static ConfigEntry<bool> MassFarmingEnabled;

		internal static ConfigEntry<KeyboardShortcut> MassFarmingKeyboardShortcut;

		internal static ConfigEntry<KeyboardShortcut> MassFarmingControllerShortcut;

		internal static ConfigEntry<float> MassHarvestRadius;

		internal static ConfigEntry<int> PlantGridWidth;

		internal static ConfigEntry<int> PlantGridLength;

		internal static ConfigEntry<bool> IgnorePlantingStamina;

		internal static ConfigEntry<bool> IgnorePlantingDurability;

		internal static ConfigEntry<bool> CenterPlantingGridWidth;

		internal static ConfigEntry<bool> CenterPlantingGridLength;

		private Harmony? _harmony;

		internal static bool MassFarmingActive => FeatureEnabled(MassFarmingEnabled);

		private void Awake()
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Expected O, but got Unknown
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Enable or disable every DadsQoL feature.");
			CarryWeightEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Carry Weight", "Enabled", true, "Enable the configured base carry weight.");
			CarryWeight = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Carry Weight", "Base Carry Weight", 5000f, "Base carry weight before food, equipment, status-effect, and world modifiers. Vanilla is 300.");
			PickupRadiusEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Pickup Radius", "Enabled", true, "Enable the configured automatic pickup radius.");
			PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Pickup Radius", "Radius", 6f, "Automatic pickup radius in meters. Vanilla is 2.");
			EquipmentInWaterEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Equipment In Water", "Enabled", true, "Allow tools, weapons, shields, bows, and other hand equipment to remain usable while swimming.");
			MassFarmingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Enabled", true, "Enable mass harvesting and grid planting.");
			MassFarmingKeyboardShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("5 - Mass Farming", "Keyboard Shortcut", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Hold while harvesting or planting to use mass farming.");
			MassFarmingControllerShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("5 - Mass Farming", "Controller Shortcut", new KeyboardShortcut((KeyCode)334, Array.Empty<KeyCode>()), "Hold while harvesting or planting to use mass farming with a controller.");
			MassHarvestRadius = ((BaseUnityPlugin)this).Config.Bind<float>("5 - Mass Farming", "Harvest Radius", 5f, "Radius in meters for harvesting matching pickables and extracting nearby beehives.");
			PlantGridWidth = ((BaseUnityPlugin)this).Config.Bind<int>("5 - Mass Farming", "Plant Grid Width", 5, "Number of plants across the grid.");
			PlantGridLength = ((BaseUnityPlugin)this).Config.Bind<int>("5 - Mass Farming", "Plant Grid Length", 5, "Number of plants along the grid.");
			IgnorePlantingStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Ignore Planting Stamina", false, "Do not consume stamina for the additional plants.");
			IgnorePlantingDurability = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Ignore Planting Durability", false, "Do not consume cultivator durability for the additional plants.");
			CenterPlantingGridWidth = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Center Grid Width", true, "Center the grid across the first plant instead of extending to one side.");
			CenterPlantingGridLength = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Mass Farming", "Center Grid Length", true, "Center the grid along the first plant instead of extending forward.");
			ModEnabled.SettingChanged += OnPickupSettingChanged;
			PickupRadiusEnabled.SettingChanged += OnPickupSettingChanged;
			PickupRadius.SettingChanged += OnPickupSettingChanged;
			_harmony = new Harmony("com.dadisbored.dadsqol");
			_harmony.PatchAll(typeof(DadsQoLPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsQoL 1.1.0 loaded.");
		}

		private static void OnPickupSettingChanged(object sender, EventArgs eventArgs)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				PlayerAwakePatch.Apply(Player.m_localPlayer);
			}
		}

		private void OnDestroy()
		{
			MassPlantingState.DestroyGhosts();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static bool FeatureEnabled(ConfigEntry<bool> feature)
		{
			if (ModEnabled.Value)
			{
				return feature.Value;
			}
			return false;
		}

		internal static bool MassFarmingShortcutHeld()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!ShortcutHeld(MassFarmingKeyboardShortcut.Value))
			{
				return ShortcutHeld(MassFarmingControllerShortcut.Value);
			}
			return true;
		}

		private static bool ShortcutHeld(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class PlayerAwakePatch
	{
		private sealed class OriginalRange
		{
			internal float Value;
		}

		private static readonly ConditionalWeakTable<Player, OriginalRange> OriginalRanges = new ConditionalWeakTable<Player, OriginalRange>();

		private static void Prefix(Player __instance)
		{
			OriginalRanges.GetValue(__instance, (Player player) => new OriginalRange
			{
				Value = player.m_autoPickupRange
			});
		}

		private static void Postfix(Player __instance)
		{
			Apply(__instance);
		}

		internal static void Apply(Player player)
		{
			OriginalRange value = OriginalRanges.GetValue(player, (Player current) => new OriginalRange
			{
				Value = current.m_autoPickupRange
			});
			player.m_autoPickupRange = (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.PickupRadiusEnabled) ? Math.Max(0f, DadsQoLPlugin.PickupRadius.Value) : value.Value);
		}
	}
	[HarmonyPatch(typeof(Player), "GetMaxCarryWeight")]
	internal static class CarryWeightPatch
	{
		private static void Prefix(Player __instance, out float __state)
		{
			__state = __instance.m_maxCarryWeight;
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.CarryWeightEnabled))
			{
				__instance.m_maxCarryWeight = Math.Max(0f, DadsQoLPlugin.CarryWeight.Value);
			}
		}

		private static void Postfix(Player __instance, float __state)
		{
			__instance.m_maxCarryWeight = __state;
		}
	}
	[HarmonyPatch]
	internal static class EquipmentInWaterPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(Humanoid), "UpdateEquipment", new Type[1] { typeof(float) }, (Type[])null);
			yield return AccessTools.Method(typeof(Humanoid), "EquipItem", new Type[2]
			{
				typeof(ItemData),
				typeof(bool)
			}, (Type[])null);
		}

		private static void Prefix(Humanoid __instance, ref float ___m_swimTimer, out float __state)
		{
			__state = ___m_swimTimer;
			if (DadsQoLPlugin.FeatureEnabled(DadsQoLPlugin.EquipmentInWaterEnabled) && ((Character)__instance).IsPlayer() && ___m_swimTimer < 0.5f)
			{
				___m_swimTimer = 0.5f;
			}
		}

		private static void Postfix(ref float ___m_swimTimer, float __state)
		{
			___m_swimTimer = __state;
		}
	}
}
namespace DadsQoL.MassFarming
{
	[HarmonyPatch(typeof(Player), "Interact")]
	internal static class MassHarvest
	{
		private static readonly FieldInfo InteractMaskField = AccessTools.Field(typeof(Player), "m_interactMask");

		private static bool _processingMassInteraction;

		private static void Prefix(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			if (!DadsQoLPlugin.MassFarmingActive || _processingMassInteraction || hold || ((Character)__instance).InAttack() || ((Character)__instance).InDodge() || !DadsQoLPlugin.MassFarmingShortcutHeld())
			{
				return;
			}
			Interactable componentInParent = go.GetComponentInParent<Interactable>();
			float num = Mathf.Max(0f, DadsQoLPlugin.MassHarvestRadius.Value);
			int num2 = (int)InteractMaskField.GetValue(__instance);
			Collider[] array = Physics.OverlapSphere(go.transform.position, num, num2);
			_processingMassInteraction = true;
			try
			{
				Pickable val = (Pickable)(object)((componentInParent is Pickable) ? componentInParent : null);
				Collider[] array2;
				if (val != null)
				{
					string text = (((Object)(object)val.m_itemPrefab != (Object)null) ? ((Object)val.m_itemPrefab).name : string.Empty);
					array2 = array;
					foreach (Collider val2 in array2)
					{
						Pickable val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject.GetComponentInParent<Pickable>() : null);
						if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val && (Object)(object)val3.m_itemPrefab != (Object)null && ((Object)val3.m_itemPrefab).name == text)
						{
							val3.Interact((Humanoid)(object)__instance, false, alt);
						}
					}
					return;
				}
				Beehive val4 = (Beehive)(object)((componentInParent is Beehive) ? componentInParent : null);
				if (val4 == null)
				{
					return;
				}
				array2 = array;
				foreach (Collider val5 in array2)
				{
					Beehive val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).gameObject.GetComponentInParent<Beehive>() : null);
					if ((Object)(object)val6 != (Object)null && (Object)(object)val6 != (Object)(object)val4 && PrivateArea.CheckAccess(((Component)val6).transform.position, 0f, true, false))
					{
						val6.Extract();
					}
				}
			}
			finally
			{
				_processingMassInteraction = false;
			}
		}
	}
	internal static class MassPlantingState
	{
		private static readonly FieldInfo NoPlacementCostField = AccessTools.Field(typeof(Player), "m_noPlacementCost");

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

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

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

		internal static Vector3 PlacedPosition;

		internal static Quaternion PlacedRotation;

		internal static Piece PlacedPiece = null;

		internal static bool PlaceSuccessful;

		internal static int? SavedRotation;

		internal static GameObject[] PlacementGhosts = (GameObject[])(object)new GameObject[1];

		internal static Piece FakeResourcePiece = null;

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

		internal static bool Active
		{
			get
			{
				if (DadsQoLPlugin.MassFarmingActive)
				{
					return DadsQoLPlugin.MassFarmingShortcutHeld();
				}
				return false;
			}
		}

		internal static bool NoPlacementCost(Player player)
		{
			return (bool)NoPlacementCostField.GetValue(player);
		}

		internal static GameObject? PlacementGhost(Player player)
		{
			object? value = PlacementGhostField.GetValue(player);
			return (GameObject?)((value is GameObject) ? value : null);
		}

		internal static PieceTable? BuildPieces(Player player)
		{
			object? value = BuildPiecesField.GetValue(player);
			return (PieceTable?)((value is PieceTable) ? value : null);
		}

		internal static ItemData? RightItem(Player player)
		{
			object? obj = GetRightItemMethod.Invoke(player, Array.Empty<object>());
			return (ItemData?)((obj is ItemData) ? obj : null);
		}

		internal static IEnumerable<Vector3> BuildGridPositions(Vector3 origin, Plant plant, Quaternion rotation)
		{
			//IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			int width = Math.Max(1, DadsQoLPlugin.PlantGridWidth.Value);
			int length = Math.Max(1, DadsQoLPlugin.PlantGridLength.Value);
			float num = plant.m_growRadius * 2f;
			Vector3 across = rotation * Vector3.left * num;
			Vector3 forward = rotation * Vector3.forward * num;
			Vector3 gridOrigin = origin;
			if (DadsQoLPlugin.CenterPlantingGridLength.Value)
			{
				gridOrigin -= forward * (float)(length / 2);
			}
			if (DadsQoLPlugin.CenterPlantingGridWidth.Value)
			{
				gridOrigin -= across * (float)(width / 2);
			}
			for (int x = 0; x < length; x++)
			{
				Vector3 position = gridOrigin;
				for (int z = 0; z < width; z++)
				{
					position.y = ZoneSystem.instance.GetGroundHeight(position);
					yield return position;
					position += across;
				}
				gridOrigin += forward;
			}
		}

		internal static bool HasGrowSpace(Vector3 position, GameObject prefab)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Plant component = prefab.GetComponent<Plant>();
			if (!((Object)(object)component == (Object)null))
			{
				return Physics.OverlapSphere(position, component.m_growRadius, PlantSpaceMask).Length == 0;
			}
			return true;
		}

		internal static bool EnsureGhostsBuilt(Player player)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			int num = Math.Max(1, DadsQoLPlugin.PlantGridWidth.Value) * Math.Max(1, DadsQoLPlugin.PlantGridLength.Value);
			if (PlacementGhosts.Length != num || (Object)(object)PlacementGhosts[0] == (Object)null)
			{
				DestroyGhosts();
				PlacementGhosts = (GameObject[])(object)new GameObject[num];
				PieceTable val = BuildPieces(player);
				GameObject val2 = (((Object)(object)val != (Object)null) ? val.GetSelectedPrefab() : null);
				if ((Object)(object)val2 == (Object)null || val2.GetComponent<Piece>().m_repairPiece)
				{
					return false;
				}
				for (int i = 0; i < PlacementGhosts.Length; i++)
				{
					PlacementGhosts[i] = CreateGhost(val2);
				}
			}
			if ((Object)(object)FakeResourcePiece == (Object)null)
			{
				FakeResourcePiece = PlacementGhosts[0].GetComponent<Piece>();
				FakeResourcePiece.m_dlc = string.Empty;
				FakeResourcePiece.m_resources = (Requirement[])(object)new Requirement[1]
				{
					new Requirement()
				};
			}
			return true;
		}

		internal static void DestroyGhosts()
		{
			GameObject[] placementGhosts = PlacementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			FakeResourcePiece = null;
		}

		internal static void SetGhostsActive(bool active)
		{
			GameObject[] placementGhosts = PlacementGhosts;
			foreach (GameObject val in placementGhosts)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
			}
		}

		private static GameObject CreateGhost(GameObject prefab)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			ZNetView.m_forceDisableInit = true;
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(prefab);
			}
			finally
			{
				ZNetView.m_forceDisableInit = false;
			}
			((Object)val).name = ((Object)prefab).name;
			Joint[] componentsInChildren = val.GetComponentsInChildren<Joint>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = val.GetComponentsInChildren<Rigidbody>();
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren2[i]);
			}
			int layer = LayerMask.NameToLayer("ghost");
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Component)componentsInChildren3[i]).gameObject.layer = layer;
			}
			TerrainModifier[] componentsInChildren4 = val.GetComponentsInChildren<TerrainModifier>();
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren4[i]);
			}
			GuidePoint[] componentsInChildren5 = val.GetComponentsInChildren<GuidePoint>();
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren5[i]);
			}
			Light[] componentsInChildren6 = val.GetComponentsInChildren<Light>();
			for (int i = 0; i < componentsInChildren6.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren6[i]);
			}
			Transform val2 = val.transform.Find("_GhostOnly");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(true);
			}
			MeshRenderer[] componentsInChildren7 = val.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val3 in componentsInChildren7)
			{
				if (!((Object)(object)((Renderer)val3).sharedMaterial == (Object)null))
				{
					Material[] sharedMaterials = ((Renderer)val3).sharedMaterials;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						Material val4 = new Material(sharedMaterials[j]);
						val4.SetFloat("_RippleDistance", 0f);
						val4.SetFloat("_ValueNoise", 0f);
						sharedMaterials[j] = val4;
					}
					((Renderer)val3).sharedMaterials = sharedMaterials;
					((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(Player), "TryPlacePiece")]
	internal static class TryPlacePiecePatch
	{
		private static void Prefix(int ___m_placeRotation)
		{
			if (MassPlantingState.Active && !MassPlantingState.SavedRotation.HasValue)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
		}

		private static void Postfix(Player __instance, bool __result, Piece piece, ref int ___m_placeRotation)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			MassPlantingState.PlaceSuccessful = __result;
			GameObject val = MassPlantingState.PlacementGhost(__instance);
			if (__result && (Object)(object)val != (Object)null)
			{
				MassPlantingState.PlacedPosition = val.transform.position;
				MassPlantingState.PlacedRotation = val.transform.rotation;
				MassPlantingState.PlacedPiece = piece;
			}
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	internal static class UpdatePlacementPatch
	{
		private static void Prefix(ref int ___m_placeRotation)
		{
			MassPlantingState.PlaceSuccessful = false;
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
		}

		private static void Postfix(Player __instance, int ___m_placeRotation)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_016a: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			if (MassPlantingState.Active)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
			if (!MassPlantingState.PlaceSuccessful || !MassPlantingState.Active)
			{
				return;
			}
			Plant component = ((Component)MassPlantingState.PlacedPiece).gameObject.GetComponent<Plant>();
			Heightmap val = Heightmap.FindHeightmap(MassPlantingState.PlacedPosition);
			if ((Object)(object)component == (Object)null || (Object)(object)val == (Object)null)
			{
				return;
			}
			PieceTable val2 = MassPlantingState.BuildPieces(__instance);
			foreach (Vector3 item in MassPlantingState.BuildGridPositions(MassPlantingState.PlacedPosition, component, MassPlantingState.PlacedRotation))
			{
				if (MassPlantingState.PlacedPosition == item || (MassPlantingState.PlacedPiece.m_cultivatedGroundOnly && !val.IsCultivated(item)) || !MassPlantingState.HasGrowSpace(item, ((Component)MassPlantingState.PlacedPiece).gameObject))
				{
					continue;
				}
				ItemData val3 = MassPlantingState.RightItem(__instance);
				if (val3 == null)
				{
					break;
				}
				if (!DadsQoLPlugin.IgnorePlantingStamina.Value && !((Character)__instance).HaveStamina(val3.m_shared.m_attack.m_attackStamina))
				{
					Hud.instance.StaminaBarUppgradeFlash();
					break;
				}
				if (!MassPlantingState.NoPlacementCost(__instance) && !__instance.HaveRequirements(MassPlantingState.PlacedPiece, (RequirementMode)0))
				{
					break;
				}
				GameObject val4 = Object.Instantiate<GameObject>(((Component)MassPlantingState.PlacedPiece).gameObject, item, MassPlantingState.PlacedRotation);
				Piece component2 = val4.GetComponent<Piece>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.SetCreator(__instance.GetPlayerID(), ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID);
				}
				MassPlantingState.PlacedPiece.m_placeEffect.Create(item, MassPlantingState.PlacedRotation, val4.transform, 1f, -1, default(ZDOID));
				Game.instance.IncrementPlayerStat((PlayerStatType)2, 1f, false);
				__instance.ConsumeResources(MassPlantingState.PlacedPiece.m_resources, 0, -1, 1);
				if (!DadsQoLPlugin.IgnorePlantingStamina.Value)
				{
					((Character)__instance).UseStamina(val3.m_shared.m_attack.m_attackStamina);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					((Character)__instance).RaiseSkill(val2.m_skill, 1f);
				}
				if (!DadsQoLPlugin.IgnorePlantingDurability.Value && val3.m_shared.m_useDurability)
				{
					val3.m_durability -= val3.m_shared.m_useDurabilityDrain;
					if (val3.m_durability <= 0f)
					{
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
	internal static class SetupPlacementGhostPatch
	{
		private static void Prefix(int ___m_placeRotation)
		{
			if (MassPlantingState.Active && !MassPlantingState.SavedRotation.HasValue)
			{
				MassPlantingState.SavedRotation = ___m_placeRotation;
			}
		}

		private static void Postfix(ref int ___m_placeRotation)
		{
			if (MassPlantingState.Active && MassPlantingState.SavedRotation.HasValue)
			{
				___m_placeRotation = MassPlantingState.SavedRotation.Value;
			}
			MassPlantingState.DestroyGhosts();
		}
	}
	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	internal static class UpdatePlacementGhostPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_0126: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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)
			GameObject val = MassPlantingState.PlacementGhost(__instance);
			if (!DadsQoLPlugin.MassFarmingActive || !DadsQoLPlugin.MassFarmingShortcutHeld() || (Object)(object)val == (Object)null || !val.activeSelf)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			Plant component = val.GetComponent<Plant>();
			if ((Object)(object)component == (Object)null || !MassPlantingState.EnsureGhostsBuilt(__instance))
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			Piece component2 = val.GetComponent<Piece>();
			Requirement val2 = ((IEnumerable<Requirement>)component2.m_resources).FirstOrDefault((Func<Requirement, bool>)((Requirement resource) => (Object)(object)resource.m_resItem != (Object)null && resource.m_amount > 0));
			if (val2 == null)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			MassPlantingState.FakeResourcePiece.m_resources[0].m_resItem = val2.m_resItem;
			MassPlantingState.FakeResourcePiece.m_resources[0].m_amount = 0;
			ItemData val3 = MassPlantingState.RightItem(__instance);
			Heightmap val4 = Heightmap.FindHeightmap(val.transform.position);
			if (val3 == null || (Object)(object)val4 == (Object)null)
			{
				MassPlantingState.SetGhostsActive(active: false);
				return;
			}
			float num = __instance.GetStamina();
			List<Vector3> list = MassPlantingState.BuildGridPositions(val.transform.position, component, val.transform.rotation).ToList();
			for (int num2 = 0; num2 < MassPlantingState.PlacementGhosts.Length; num2++)
			{
				GameObject val5 = MassPlantingState.PlacementGhosts[num2];
				Vector3 val6 = list[num2];
				if (val.transform.position == val6)
				{
					val5.SetActive(false);
					continue;
				}
				Requirement obj = MassPlantingState.FakeResourcePiece.m_resources[0];
				obj.m_amount += val2.m_amount;
				val5.transform.position = val6;
				val5.transform.rotation = val.transform.rotation;
				val5.SetActive(true);
				bool invalidPlacementHeightlight = (component2.m_cultivatedGroundOnly && !val4.IsCultivated(val6)) || !MassPlantingState.HasGrowSpace(val6, val) || (!DadsQoLPlugin.IgnorePlantingStamina.Value && num < val3.m_shared.m_attack.m_attackStamina) || (!MassPlantingState.NoPlacementCost(__instance) && !__instance.HaveRequirements(MassPlantingState.FakeResourcePiece, (RequirementMode)0));
				num -= val3.m_shared.m_attack.m_attackStamina;
				val5.GetComponent<Piece>().SetInvalidPlacementHeightlight(invalidPlacementHeightlight);
			}
		}
	}
}