Decompiled source of BotanistUseSoilPourers v1.0.1

BotanistUseSoilPourer_Mono.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BotanistUseSoilPourer;
using FishNet;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ScheduleOne;
using ScheduleOne.DevUtilities;
using ScheduleOne.Employees;
using ScheduleOne.EntityFramework;
using ScheduleOne.Equipping;
using ScheduleOne.ItemFramework;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.ObjectScripts;
using ScheduleOne.ObjectScripts.Soil;
using ScheduleOne.Tiles;
using ScheduleOne.Trash;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(BotanistUseSoilPourerMod), "Botanist Use Soil Pourer", "1.0.1", "Fortis", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BotanistUseSoilPourer_Mono")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BotanistUseSoilPourer_Mono")]
[assembly: AssemblyTitle("BotanistUseSoilPourer_Mono")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BotanistUseSoilPourer
{
	public class BotanistUseSoilPourerMod : MelonMod
	{
		[HarmonyPatch(typeof(PotActionBehaviour), "StartAction")]
		public static class PotActionBehaviourStartActionPatch
		{
			[HarmonyPostfix]
			private static void Postfix(PotActionBehaviour __instance)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Invalid comparison between Unknown and I4
				if ((object)IsAtPot != null)
				{
					if (__instance.AssignedPot != null && (int)__instance.CurrentActionType == 1 && !(bool)IsAtPot.Invoke(__instance, null))
					{
						SoilPourer potSoilPourer = GetPotSoilPourer(__instance.AssignedPot);
						if (potSoilPourer != null && !CheckPreventer.ContainsKey(__instance.AssignedPot))
						{
							Log("(PotActionBehaviourStartActionPatch/Postfix) Adding pot to check preventer", LogLevel.Debug);
							CheckPreventer.Add(__instance.AssignedPot, potSoilPourer);
						}
					}
				}
				else
				{
					Log("(PotActionBehaviourStartActionPatch/Postfix) IsAtPot is null", LogLevel.Warn);
				}
			}
		}

		[HarmonyPatch(typeof(PotActionBehaviour), "ActiveMinPass")]
		public static class PotActionBehviourActiveMinPassPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(PotActionBehaviour __instance)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				if ((int)__instance.CurrentActionType != 1)
				{
					return true;
				}
				if ((int)__instance.CurrentState == 0)
				{
					SoilPourer val = null;
					if (CheckPreventer.ContainsKey(__instance.AssignedPot))
					{
						val = CheckPreventer[__instance.AssignedPot];
					}
					if (val == null)
					{
						return true;
					}
					if (val.SoilID == string.Empty)
					{
						return true;
					}
					__instance.WalkToPot();
					return false;
				}
				return true;
			}

			[HarmonyPostfix]
			private static void Postfix(PotActionBehaviour __instance)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Invalid comparison between Unknown and I4
				if ((object)IsAtPot != null)
				{
					if ((int)__instance.CurrentActionType != 1)
					{
						return;
					}
					SoilPourer val = null;
					if (CheckPreventer.ContainsKey(__instance.AssignedPot))
					{
						val = CheckPreventer[__instance.AssignedPot];
					}
					if (val == null)
					{
						return;
					}
					if (val.SoilID == string.Empty)
					{
						if ((bool)IsAtPot.Invoke(__instance, null))
						{
							PourSoilIntoPourer(__instance, val);
							if (val.SoilID != string.Empty)
							{
								val.ActivateSound.Play();
								DispenseSoilQuick(val.SoilID, __instance.AssignedPot);
								val.SendSoil(string.Empty);
								val.SetSoilLevel(0f);
								EndBotanistTask(__instance);
							}
						}
					}
					else if ((bool)IsAtPot.Invoke(__instance, null))
					{
						Log("(PotActionBehaviourActiveMinPassPatch/Postfix) Activating soil pourer", LogLevel.Debug);
						val.ActivateSound.Play();
						DispenseSoilQuick(val.SoilID, __instance.AssignedPot);
						val.SendSoil(string.Empty);
						val.SetSoilLevel(0f);
						EndBotanistTask(__instance);
					}
				}
				else
				{
					Log("(PotActionBehaviourActiveMinPassPatch/Postfix) IsAtPot is null", LogLevel.Warn);
				}
			}
		}

		private enum LogLevel
		{
			Debug,
			Info,
			Warn,
			Error,
			Fatal
		}

		private static Configuration _config = null;

		private static readonly string ConfigDirectoryPath = Path.Combine(MelonEnvironment.UserDataDirectory, "BotanistUseSoilPourer");

		private static readonly string ConfigPath = Path.Combine(ConfigDirectoryPath, "configuration.json");

		private static Dictionary<Pot, SoilPourer> CheckPreventer = new Dictionary<Pot, SoilPourer>();

		private static MethodInfo IsAtPot = typeof(PotActionBehaviour).GetMethod("IsAtPot", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);

		private static MethodInfo StopPerformAction = typeof(PotActionBehaviour).GetMethod("StopPerformAction", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);

		private static MethodInfo CompleteAction = typeof(PotActionBehaviour).GetMethod("CompleteAction", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);

		public override void OnInitializeMelon()
		{
			Log("Initializing...", LogLevel.Info);
			LoadConfigFromFile();
			Log($"Enabled: {_config.enabled}", LogLevel.Info);
			if (_config.enabled)
			{
				if (_config.debug)
				{
					Log("Debug Mode Enabled", LogLevel.Debug);
				}
				Log("Initialized", LogLevel.Info);
			}
		}

		public override void OnDeinitializeMelon()
		{
			Log("(OnDeinitializeMelon) Mod unloaded", LogLevel.Info);
		}

		private static void DispenseSoilQuick(string id, Pot pot)
		{
			pot.SetSoilID(id);
			pot.SetSoilState((ESoilState)0);
			pot.AddSoil(pot.SoilCapacity);
			pot.SetSoilUses(Registry.GetItem<SoilDefinition>(id).Uses);
			if (InstanceFinder.IsServer)
			{
				pot.PushSoilDataToServer();
			}
		}

		private static void EndBotanistTask(PotActionBehaviour behaviour)
		{
			if ((object)StopPerformAction != null && (object)CompleteAction != null)
			{
				if (CheckPreventer.ContainsKey(behaviour.AssignedPot))
				{
					Log("(EndBotanistTask) Removing pot from check preventer", LogLevel.Debug);
					CheckPreventer.Remove(behaviour.AssignedPot);
				}
				StopPerformAction.Invoke(behaviour, null);
				CompleteAction.Invoke(behaviour, null);
				((Behaviour)behaviour).SendEnd();
				NPC npc = ((Behaviour)behaviour).Npc;
				Botanist val = (Botanist)(object)((npc is Botanist) ? npc : null);
				if (val != null)
				{
					((Employee)val).SetIdle(true);
				}
				else
				{
					Log("(EndBotanistTask) Botanist is null", LogLevel.Warn);
				}
			}
			else
			{
				Log($"(EndBotanistTask) StopPeformAction is null: {(object)StopPerformAction == null}, CompleteAction is null: {(object)CompleteAction == null}", LogLevel.Debug);
			}
		}

		private static void PourSoilIntoPourer(PotActionBehaviour behaviour, SoilPourer pourer)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (behaviour.AssignedPot == null)
			{
				Log("(PourSoilIntoPourer) PotActionBehaviour is null", LogLevel.Warn);
				return;
			}
			ItemInstance val = null;
			string[] soilIDS = GetSoilIDS();
			for (int i = 0; i < soilIDS.Length; i++)
			{
				val = ((Behaviour)behaviour).Npc.Inventory.GetFirstItem(soilIDS[i], (ItemFilter)null);
				if (val != null)
				{
					break;
				}
			}
			if (val == null)
			{
				Log("(PourSoilIntoPourer) Botanist does not have soil", LogLevel.Warn);
				return;
			}
			ItemDefinition definition = val.Definition;
			SoilDefinition val2 = (SoilDefinition)(object)((definition is SoilDefinition) ? definition : null);
			if (val2 == null)
			{
				Log("(PourSoilIntoPourer) SoilDefinition is null", LogLevel.Warn);
				return;
			}
			pourer.SendSoil(((ItemDefinition)val2).ID);
			? val3 = NetworkSingleton<TrashManager>.Instance;
			Equippable equippable = ((ItemDefinition)val2).Equippable;
			((TrashManager)val3).CreateTrashItem(((Equippable_Pourable)((equippable is Equippable_Soil) ? equippable : null)).PourablePrefab.TrashItem.ID, ((Component)behaviour).transform.position + Vector3.up * 0.5f, Random.rotation, default(Vector3), "", false);
			val.ChangeQuantity(-1);
		}

		private static string[] GetSoilIDS()
		{
			return new string[3] { "soil", "longlifesoil", "extralonglifesoil" };
		}

		private static SoilPourer? GetPotSoilPourer(Pot pot)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Expected O, but got Unknown
			//IL_02db: Expected O, but got Unknown
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Expected O, but got Unknown
			//IL_030e: Expected O, but got Unknown
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Expected O, but got Unknown
			Log("(GetSoilPourer) Fired", LogLevel.Debug);
			Coordinate val = new Coordinate(((GridItem)pot).OriginCoordinate);
			Log($"(GetPotSoilPourers) Assigned Pot Coords x: {val.x}, y: {val.y}", LogLevel.Debug);
			List<SoilPourer> list = new List<SoilPourer>();
			for (int i = 1; i < 4; i++)
			{
				Coordinate val2 = new Coordinate(val.x + i, val.y);
				Coordinate val3 = new Coordinate(val.x - i, val.y);
				Coordinate val4 = new Coordinate(val.x, val.y + i);
				Coordinate val5 = new Coordinate(val.x, val.y - i);
				Tile tile = ((GridItem)pot).OwnerGrid.GetTile(val2);
				Tile tile2 = ((GridItem)pot).OwnerGrid.GetTile(val3);
				Tile tile3 = ((GridItem)pot).OwnerGrid.GetTile(val4);
				Tile tile4 = ((GridItem)pot).OwnerGrid.GetTile(val5);
				Tile[] array = (Tile[])(object)new Tile[4] { tile, tile2, tile3, tile4 };
				for (int j = 0; j < array.Length; j++)
				{
					if (array[j] != null)
					{
						Log($"(GetPotSoilPourers) Checking tile at x: {array[j].x}, y: {array[j].y}", LogLevel.Debug);
						if (!TryGetSoilPourer(array[j], out SoilPourer pourer))
						{
							Log($"(GetPotSoilPourers) Tile at x: {array[j].x}, y: {array[j].y} contains no soil pourers", LogLevel.Debug);
							continue;
						}
						if (pourer == null)
						{
							Log($"(GetPotSoilPourers) Tile at x: {array[j].x}, y: {array[j].y} contains a soil pourer but soil pourer returned is null", LogLevel.Warn);
							continue;
						}
						Log($"(GetPotSoilPourers) Soil Pourer found at x: {array[j].x}, y: {array[j].y}", LogLevel.Debug);
						list.Add(pourer);
					}
				}
			}
			SoilPourer val6 = null;
			if (list.Count <= 0)
			{
				return val6;
			}
			Log($"(GetPotSoilPourers) pourersAroundPot Count: {list.Count}", LogLevel.Debug);
			for (int k = 0; k < list.Count; k++)
			{
				Coordinate val7 = new Coordinate(((GridItem)list[k]).OriginCoordinate);
				Log($"(GetPotSoilPourers) Checking if soil pourer at x: {val7.x}, y: {val7.y} pot is assigned pot", LogLevel.Debug);
				Coordinate val8 = new Coordinate(((GridItem)list[k]).OriginCoordinate) + Coordinate.RotateCoordinates(new Coordinate(0, 1), (float)((GridItem)list[k]).Rotation);
				Coordinate val9 = new Coordinate(((GridItem)list[k]).OriginCoordinate) + Coordinate.RotateCoordinates(new Coordinate(1, 1), (float)((GridItem)list[k]).Rotation);
				Tile tile5 = ((GridItem)list[k]).OwnerGrid.GetTile(val8);
				Tile tile6 = ((GridItem)list[k]).OwnerGrid.GetTile(val9);
				List<Pot> list2 = new List<Pot>();
				if ((Object)(object)tile5 != (Object)null && (Object)(object)tile6 != (Object)null)
				{
					Pot val10 = null;
					foreach (GridItem buildableOccupant in tile5.BuildableOccupants)
					{
						if (buildableOccupant is Pot)
						{
							val10 = (Pot)(object)((buildableOccupant is Pot) ? buildableOccupant : null);
							break;
						}
					}
					if ((Object)(object)val10 != (Object)null && tile6.BuildableOccupants.Contains((GridItem)(object)val10))
					{
						list2.Add(val10);
					}
				}
				if (list2.Count <= 0)
				{
					Log("(GetPotSoilPourers) Tile pots count is 0 or less", LogLevel.Debug);
					return val6;
				}
				Log($"(GetPotSoilPourers) Soil pourer pots count: {list2.Count}", LogLevel.Debug);
				for (int l = 0; l < list2.Count; l++)
				{
					Coordinate val11 = new Coordinate(((GridItem)list2[l]).OriginCoordinate);
					Log($"(GetPotSoilPourers) Checking soil pourer pot at x: {val11.x}, y: {val11.y} matches assigned pot at x: {val.x}, y {val.y}", LogLevel.Debug);
					if (val11.x == val.x && val11.y == val.y)
					{
						Log("(GetPotSoilPourers) Adding Soil pourer", LogLevel.Debug);
						val6 = list[k];
						break;
					}
				}
			}
			Log($"(GetPotSoilPourers) Soil pourer to be activated is null: {val6 == null}", LogLevel.Debug);
			return val6;
		}

		private static bool TryGetSoilPourer(Tile tile, out SoilPourer? pourer)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			pourer = null;
			foreach (GridItem buildableOccupant in tile.BuildableOccupants)
			{
				if (buildableOccupant == null || !(buildableOccupant is SoilPourer))
				{
					continue;
				}
				pourer = (SoilPourer)buildableOccupant;
				break;
			}
			return Object.op_Implicit((Object)(object)pourer);
		}

		private static void LoadConfigFromFile()
		{
			if (!Directory.Exists(ConfigDirectoryPath))
			{
				Directory.CreateDirectory(ConfigDirectoryPath);
			}
			if (!File.Exists(ConfigPath))
			{
				CreateNewConfigFile();
				return;
			}
			Configuration configuration = new Configuration
			{
				enabled = true,
				debug = false
			};
			string text = File.ReadAllText(ConfigPath);
			Configuration configuration2 = JsonConvert.DeserializeObject<Configuration>(text);
			if (configuration2 == null)
			{
				_config = configuration;
				return;
			}
			configuration.enabled = configuration2.enabled;
			configuration.debug = configuration2.debug;
			_config = configuration;
		}

		private static void CreateNewConfigFile()
		{
			Configuration configuration = new Configuration
			{
				enabled = true,
				debug = false
			};
			string contents = JsonConvert.SerializeObject((object)configuration, (Formatting)1);
			File.WriteAllText(ConfigPath, contents);
			_config = configuration;
		}

		private static void Log(string message, LogLevel level)
		{
			string logPrefix = GetLogPrefix(level);
			if (level != 0 || _config.debug)
			{
				MelonLogger.Msg(logPrefix + " " + message);
			}
		}

		private static string GetLogPrefix(LogLevel level)
		{
			return level switch
			{
				LogLevel.Debug => "[DEBUG]", 
				LogLevel.Info => "[INFO]", 
				LogLevel.Warn => "[WARN]", 
				LogLevel.Error => "[ERROR]", 
				LogLevel.Fatal => "[FATAL]", 
				_ => "[MISC]", 
			};
		}
	}
	internal class Configuration
	{
		[JsonProperty("enabled")]
		public bool enabled { get; set; }

		[JsonProperty("debug")]
		public bool debug { get; set; }
	}
}

BotanistUseSoilPourer.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using BotanistUseSoilPourer;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Employees;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.ObjectScripts.Soil;
using Il2CppScheduleOne.Tiles;
using Il2CppScheduleOne.Trash;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BotanistUseSoilPourerMod), "Botanist Use Soil Pourer", "1.0.1", "Fortis", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BotanistUseSoilPourer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BotanistUseSoilPourer")]
[assembly: AssemblyTitle("BotanistUseSoilPourer")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BotanistUseSoilPourer
{
	public class BotanistUseSoilPourerMod : MelonMod
	{
		[HarmonyPatch(typeof(PotActionBehaviour), "StartAction")]
		public static class PotActionBehaviourStartActionPatch
		{
			[HarmonyPostfix]
			private static void Postfix(PotActionBehaviour __instance)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Invalid comparison between Unknown and I4
				if (__instance.AssignedPot != null && (int)__instance.CurrentActionType == 1 && !__instance.IsAtPot())
				{
					SoilPourer potSoilPourer = GetPotSoilPourer(__instance.AssignedPot);
					if (potSoilPourer != null && !CheckPreventer.ContainsKey(__instance.AssignedPot))
					{
						Log("(PotActionBehaviourStartActionPatch/Postfix) Adding pot to check preventer", LogLevel.Debug);
						CheckPreventer.Add(__instance.AssignedPot, potSoilPourer);
					}
				}
			}
		}

		[HarmonyPatch(typeof(PotActionBehaviour), "ActiveMinPass")]
		public static class PotActionBehviourActiveMinPassPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(PotActionBehaviour __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if ((int)__instance.CurrentActionType != 1)
				{
					return true;
				}
				if ((int)__instance.CurrentState == 0)
				{
					SoilPourer val = null;
					if (CheckPreventer.ContainsKey(__instance.AssignedPot))
					{
						val = CheckPreventer[__instance.AssignedPot];
					}
					if (val == null)
					{
						return true;
					}
					if (val.SoilID == string.Empty)
					{
						return true;
					}
					__instance.WalkToPot();
					return false;
				}
				return true;
			}

			[HarmonyPostfix]
			private static void Postfix(PotActionBehaviour __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				if ((int)__instance.CurrentActionType != 1)
				{
					return;
				}
				SoilPourer val = null;
				if (CheckPreventer.ContainsKey(__instance.AssignedPot))
				{
					val = CheckPreventer[__instance.AssignedPot];
				}
				if (val == null)
				{
					return;
				}
				if (val.SoilID == string.Empty)
				{
					if (__instance.IsAtPot())
					{
						PourSoilIntoPourer(__instance, val);
						if (val.SoilID != string.Empty)
						{
							val.ActivateSound.Play();
							DispenseSoilQuick(val.SoilID, __instance.AssignedPot);
							val.SendSoil(string.Empty);
							val.SetSoilLevel(0f);
							EndBotanistTask(__instance);
						}
					}
				}
				else if (__instance.IsAtPot())
				{
					Log("(PotActionBehaviourActiveMinPassPatch/Postfix) Activating soil pourer", LogLevel.Debug);
					val.ActivateSound.Play();
					DispenseSoilQuick(val.SoilID, __instance.AssignedPot);
					val.SendSoil(string.Empty);
					val.SetSoilLevel(0f);
					EndBotanistTask(__instance);
				}
			}
		}

		private enum LogLevel
		{
			Debug,
			Info,
			Warn,
			Error,
			Fatal
		}

		private static Configuration _config = null;

		private static readonly string ConfigDirectoryPath = Path.Combine(MelonEnvironment.UserDataDirectory, "BotanistUseSoilPourer");

		private static readonly string ConfigPath = Path.Combine(ConfigDirectoryPath, "configuration.json");

		private static Dictionary<Pot, SoilPourer> CheckPreventer = new Dictionary<Pot, SoilPourer>();

		public override void OnInitializeMelon()
		{
			Log("Initializing...", LogLevel.Info);
			LoadConfigFromFile();
			Log($"Enabled: {_config.enabled}", LogLevel.Info);
			if (_config.enabled)
			{
				if (_config.debug)
				{
					Log("Debug Mode Enabled", LogLevel.Debug);
				}
				Log("Initialized", LogLevel.Info);
			}
		}

		public override void OnDeinitializeMelon()
		{
			Log("(OnDeinitializeMelon) Mod unloaded", LogLevel.Info);
		}

		private static void DispenseSoilQuick(string id, Pot pot)
		{
			pot.SetSoilID(id);
			pot.SetSoilState((ESoilState)0);
			pot.AddSoil(pot.SoilCapacity);
			pot.SetSoilUses(Registry.GetItem<SoilDefinition>(id).Uses);
			if (InstanceFinder.IsServer)
			{
				pot.PushSoilDataToServer();
			}
		}

		private static void EndBotanistTask(PotActionBehaviour behaviour)
		{
			if (CheckPreventer.ContainsKey(behaviour.AssignedPot))
			{
				Log("(EndBotanistTask) Removing pot from check preventer", LogLevel.Debug);
				CheckPreventer.Remove(behaviour.AssignedPot);
			}
			behaviour.StopPerformAction();
			behaviour.CompleteAction();
			((Behaviour)behaviour).SendEnd();
			((Employee)behaviour.botanist).SetIdle(true);
		}

		private static void PourSoilIntoPourer(PotActionBehaviour behaviour, SoilPourer pourer)
		{
			//IL_00b3: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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)
			if (behaviour.AssignedPot == null)
			{
				Log("(PourSoilIntoPourer) PotActionBehaviour is null", LogLevel.Warn);
				return;
			}
			ItemInstance val = null;
			string[] soilIDS = GetSoilIDS();
			for (int i = 0; i < soilIDS.Length; i++)
			{
				val = ((Behaviour)behaviour).Npc.Inventory.GetFirstItem(soilIDS[i], (ItemFilter)null);
				if (val != null)
				{
					break;
				}
			}
			if (val == null)
			{
				Log("(PourSoilIntoPourer) Botanist does not have soil", LogLevel.Warn);
				return;
			}
			((Il2CppObjectBase)val.Definition).TryCast<SoilDefinition>();
			SoilDefinition val2 = ((Il2CppObjectBase)val.Definition).TryCast<SoilDefinition>();
			if (val2 == null)
			{
				Log("(PourSoilIntoPourer) SoilDefinition is null", LogLevel.Warn);
				return;
			}
			pourer.SendSoil(((ItemDefinition)val2).ID);
			Equippable_Soil val3 = ((Il2CppObjectBase)((ItemDefinition)val2).Equippable).TryCast<Equippable_Soil>();
			if (val3 != null)
			{
				NetworkSingleton<TrashManager>.Instance.CreateTrashItem(((Equippable_Pourable)val3).PourablePrefab.TrashItem.ID, ((Component)behaviour).transform.position + Vector3.up * 0.5f, Random.rotation, default(Vector3), "", false);
			}
			val.ChangeQuantity(-1);
		}

		private static string[] GetSoilIDS()
		{
			return new string[3] { "soil", "longlifesoil", "extralonglifesoil" };
		}

		private static SoilPourer? GetPotSoilPourer(Pot pot)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Expected O, but got Unknown
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Expected O, but got Unknown
			//IL_03e7: Expected O, but got Unknown
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Expected O, but got Unknown
			//IL_041a: Expected O, but got Unknown
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Expected O, but got Unknown
			Log("(GetSoilPourer) Fired", LogLevel.Debug);
			Coordinate val = new Coordinate(((GridItem)pot).OriginCoordinate);
			Log($"(GetPotSoilPourers) Assigned Pot Coords x: {val.x}, y: {val.y}", LogLevel.Debug);
			List<SoilPourer> list = new List<SoilPourer>();
			for (int i = 1; i < 4; i++)
			{
				Coordinate val2 = new Coordinate(val.x + i, val.y);
				Coordinate val3 = new Coordinate(val.x - i, val.y);
				Coordinate val4 = new Coordinate(val.x, val.y + i);
				Coordinate val5 = new Coordinate(val.x, val.y - i);
				Tile tile = ((GridItem)pot).OwnerGrid.GetTile(val2);
				Tile tile2 = ((GridItem)pot).OwnerGrid.GetTile(val3);
				Tile tile3 = ((GridItem)pot).OwnerGrid.GetTile(val4);
				Tile tile4 = ((GridItem)pot).OwnerGrid.GetTile(val5);
				Tile[] array = (Tile[])(object)new Tile[4] { tile, tile2, tile3, tile4 };
				for (int j = 0; j < array.Length; j++)
				{
					if (array[j] == null)
					{
						Log($"(GetPotSoilPourers) Tile at index {j} is null, skipping", LogLevel.Debug);
						continue;
					}
					Log($"(GetPotSoilPourers) Checking tile at x: {array[j].x}, y: {array[j].y}", LogLevel.Debug);
					if (!TryGetSoilPourer(array[j], out SoilPourer pourer))
					{
						Log($"(GetPotSoilPourers) Tile at x: {array[j].x}, y: {array[j].y} contains no soil pourers", LogLevel.Debug);
					}
					else if (pourer == null)
					{
						Log($"(GetPotSoilPourers) Tile at x: {array[j].x}, y: {array[j].y} contains a soil pourer but soil pourer returned is null", LogLevel.Warn);
					}
					else
					{
						Log($"(GetPotSoilPourers) Soil Pourer found at x: {array[j].x}, y: {array[j].y}", LogLevel.Debug);
						list.Add(pourer);
					}
				}
			}
			SoilPourer val6 = null;
			if (list.Count <= 0)
			{
				return val6;
			}
			Log($"(GetPotSoilPourers) pourersAroundPot Count: {list.Count}", LogLevel.Debug);
			Pot val11 = default(Pot);
			for (int k = 0; k < list.Count; k++)
			{
				Coordinate val7 = new Coordinate(((GridItem)list[k]).OriginCoordinate);
				Log($"(GetPotSoilPourers) Checking if soil pourer at x: {val7.x}, y: {val7.y} pot is assigned pot", LogLevel.Debug);
				Coordinate val8 = new Coordinate(((GridItem)list[k]).OriginCoordinate) + Coordinate.RotateCoordinates(new Coordinate(0, 1), (float)((GridItem)list[k]).Rotation);
				Coordinate val9 = new Coordinate(((GridItem)list[k]).OriginCoordinate) + Coordinate.RotateCoordinates(new Coordinate(1, 1), (float)((GridItem)list[k]).Rotation);
				Tile tile5 = ((GridItem)list[k]).OwnerGrid.GetTile(val8);
				Tile tile6 = ((GridItem)list[k]).OwnerGrid.GetTile(val9);
				List<Pot> list2 = new List<Pot>();
				if ((Object)(object)tile5 != (Object)null && (Object)(object)tile6 != (Object)null)
				{
					Pot val10 = null;
					Enumerator<GridItem> enumerator = tile5.BuildableOccupants.GetEnumerator();
					while (enumerator.MoveNext())
					{
						if (((Component)enumerator.Current).TryGetComponent<Pot>(ref val11))
						{
							val10 = val11;
							break;
						}
					}
					if ((Object)(object)val10 != (Object)null && tile6.BuildableOccupants.Contains((GridItem)(object)val10))
					{
						list2.Add(val10);
					}
				}
				if (list2.Count <= 0)
				{
					Log("(GetPotSoilPourers) Tile pots count is 0 or less", LogLevel.Debug);
					return val6;
				}
				Log($"(GetPotSoilPourers) Soil pourer pots count: {list2.Count}", LogLevel.Debug);
				for (int l = 0; l < list2.Count; l++)
				{
					Coordinate val12 = new Coordinate(((GridItem)list2[l]).OriginCoordinate);
					Log($"(GetPotSoilPourers) Checking soil pourer pot at x: {val12.x}, y: {val12.y} matches assigned pot at x: {val.x}, y {val.y}", LogLevel.Debug);
					if (val12.x == val.x && val12.y == val.y)
					{
						Log("(GetPotSoilPourers) Adding Soil pourer", LogLevel.Debug);
						val6 = list[k];
						break;
					}
				}
			}
			Log($"(GetPotSoilPourers) Soil pourer to be activated is null: {val6 == null}", LogLevel.Debug);
			return val6;
		}

		private static bool TryGetSoilPourer(Tile tile, out SoilPourer? pourer)
		{
			pourer = null;
			Enumerator<GridItem> enumerator = tile.BuildableOccupants.GetEnumerator();
			SoilPourer val = default(SoilPourer);
			while (enumerator.MoveNext())
			{
				GridItem current = enumerator.Current;
				if (current != null && ((Component)current).TryGetComponent<SoilPourer>(ref val))
				{
					pourer = val;
					break;
				}
			}
			return Object.op_Implicit((Object)(object)pourer);
		}

		private static void LoadConfigFromFile()
		{
			if (!Directory.Exists(ConfigDirectoryPath))
			{
				Directory.CreateDirectory(ConfigDirectoryPath);
			}
			if (!File.Exists(ConfigPath))
			{
				CreateNewConfigFile();
				return;
			}
			Configuration configuration = new Configuration
			{
				enabled = true,
				debug = false
			};
			Configuration configuration2 = JsonSerializer.Deserialize<Configuration>(File.ReadAllText(ConfigPath));
			if (configuration2 == null)
			{
				_config = configuration;
				return;
			}
			configuration.enabled = configuration2.enabled;
			configuration.debug = configuration2.debug;
			_config = configuration;
		}

		private static void CreateNewConfigFile()
		{
			Configuration obj = new Configuration
			{
				enabled = true,
				debug = false
			};
			File.WriteAllText(contents: JsonSerializer.Serialize(obj, new JsonSerializerOptions
			{
				WriteIndented = true
			}), path: ConfigPath);
			_config = obj;
		}

		private static void Log(string message, LogLevel level)
		{
			string logPrefix = GetLogPrefix(level);
			if (level != 0 || _config.debug)
			{
				MelonLogger.Msg(logPrefix + " " + message);
			}
		}

		private static string GetLogPrefix(LogLevel level)
		{
			return level switch
			{
				LogLevel.Debug => "[DEBUG]", 
				LogLevel.Info => "[INFO]", 
				LogLevel.Warn => "[WARN]", 
				LogLevel.Error => "[ERROR]", 
				LogLevel.Fatal => "[FATAL]", 
				_ => "[MISC]", 
			};
		}
	}
	internal class Configuration
	{
		[JsonPropertyName("enabled")]
		public bool enabled { get; set; }

		[JsonPropertyName("debug")]
		public bool debug { get; set; }
	}
}