Decompiled source of Pour Back In v1.1.0

plugins/PotionCraftPourBackIn.dll

Decompiled 5 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using IngredientVisualEffectSystem;
using Microsoft.CodeAnalysis;
using PotionCraft;
using PotionCraft.Assemblies.GamepadNavigation;
using PotionCraft.Assemblies.GamepadNavigation.Conditions;
using PotionCraft.Core;
using PotionCraft.Core.SerializableDictionary;
using PotionCraft.LocalizationSystem;
using PotionCraft.ManagersSystem;
using PotionCraft.ManagersSystem.Input.ControlProviders;
using PotionCraft.ManagersSystem.Player;
using PotionCraft.ManagersSystem.Potion;
using PotionCraft.ManagersSystem.Room;
using PotionCraft.NotificationSystem;
using PotionCraft.ObjectBased;
using PotionCraft.ObjectBased.AlchemyMachine;
using PotionCraft.ObjectBased.Cauldron;
using PotionCraft.ObjectBased.InteractiveItem;
using PotionCraft.ObjectBased.InteractiveItem.InventoryObject;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers.Presets;
using PotionCraft.ObjectBased.InteractiveItem.Vacuuming;
using PotionCraft.ObjectBased.Mortar;
using PotionCraft.ObjectBased.Potion;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.PotionEffectMapItem;
using PotionCraft.ObjectBased.ScalesSystem;
using PotionCraft.ObjectBased.Stack;
using PotionCraft.ObjectBased.Stack.StackItem;
using PotionCraft.ObjectBased.UIElements;
using PotionCraft.ObjectBased.UIElements.Books;
using PotionCraft.ObjectBased.UIElements.Books.RecipeBook;
using PotionCraft.ObjectBased.UIElements.PotionCraftPanel;
using PotionCraft.ObjectBased.UIElements.Tooltip;
using PotionCraft.SaveLoadSystem;
using PotionCraft.ScriptableObjects;
using PotionCraft.ScriptableObjects.Ingredient;
using PotionCraft.ScriptableObjects.Potion;
using PotionCraft.Settings;
using PotionCraft.SoundSystem;
using PotionCraft.SoundSystem.SoundPresets;
using PotionCraftPourBackIn.Scripts.Services;
using PotionCraftPourBackIn.Scripts.Storage;
using PotionCraftPourBackIn.Scripts.UIElements;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PotionCraftPourBackIn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Recipe Waypoint Mod for Potion Craft")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PotionCraftPourBackIn")]
[assembly: AssemblyTitle("PotionCraftPourBackIn")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PotionCraftPourBackIn
{
	[BepInPlugin("com.fahlgorithm.potioncraftpourbackin", "PotionCraftPourBackIn", "1.1.0.0")]
	[BepInProcess("Potion Craft.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.fahlgorithm.potioncraftpourbackin";

		public static ManualLogSource PluginLogger { get; private set; }

		private void Awake()
		{
			PluginLogger = ((BaseUnityPlugin)this).Logger;
			PluginLogger.LogInfo((object)"Plugin com.fahlgorithm.potioncraftpourbackin is loaded!");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.fahlgorithm.potioncraftpourbackin");
			PluginLogger.LogInfo((object)"Plugin com.fahlgorithm.potioncraftpourbackin: Patch Succeeded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PotionCraftPourBackIn";

		public const string PLUGIN_NAME = "PotionCraftPourBackIn";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace PotionCraftPourBackIn.Scripts
{
	public static class Ex
	{
		public static bool RunSafe(Func<bool> action, Func<bool> errorAction = null)
		{
			try
			{
				return action();
			}
			catch (Exception ex)
			{
				LogException(ex);
			}
			return errorAction?.Invoke() ?? true;
		}

		public static void RunSafe(Action action, Action errorAction = null)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				LogException(ex);
				errorAction?.Invoke();
			}
		}

		public static void LogException(Exception ex)
		{
			string text = $"{ex.GetType()}: {ex.Message}\r\n{ex.StackTrace}\r\n{ex.InnerException?.Message}";
			Plugin.PluginLogger.LogError((object)text);
		}
	}
}
namespace PotionCraftPourBackIn.Scripts.UIElements
{
	public class PotionStackItem : StackItem
	{
		public PotionItem potionItem;

		public override Bounds? GetHoveringColliderBounds()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return ((MovableItem)potionItem).mainCollider.bounds;
		}

		public override void SetPhysicsToDefault()
		{
			((Component)potionItem).gameObject.layer = 0;
		}

		public override void SetThisItemLayersToNormal()
		{
			((Component)potionItem).gameObject.layer = 14;
		}

		public override void IgnoreCollision(Collider2D target, bool ignore = true)
		{
			if (!((Object)(object)((Component)target).GetComponentInParent<ThrowVacuuming>() != (Object)(object)Managers.Ingredient.cauldron.throwVacuuming) && (ignore || !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted()))
			{
				((InteractiveItem)potionItem).IgnoreCollision(target, ignore);
			}
		}
	}
}
namespace PotionCraftPourBackIn.Scripts.Storage
{
	public static class StaticStorage
	{
		public static bool CurrentlyMakingPotion;

		public static bool CurrentlyGeneratingRecipe;

		public static List<PotionUsedComponent> PouredInUsedComponents;

		public static List<PotionEffect> PouredInEffects;

		public static List<Potion> PotionItemsNotifiedFor = new List<Potion>();

		public static float LastNotifiedTime;

		public static Potion CurrentPotionCraftPanelPotion;

		public static bool DummyEffectAddedToEnableFinishPotionGrab;
	}
}
namespace PotionCraftPourBackIn.Scripts.Services
{
	public static class EquipmentInteractionService
	{
		public static bool DisallowMortarPotionCollisions(Collider2D other, ThrowVacuuming throwVacuuming)
		{
			PotionStackItem componentInChildren = ((Component)other).GetComponentInChildren<PotionStackItem>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return true;
			}
			if (((StackItem)componentInChildren).IsVacuumingNow)
			{
				return false;
			}
			if ((Object)(object)throwVacuuming == (Object)(object)Managers.Ingredient.cauldron.throwVacuuming)
			{
				return true;
			}
			return false;
		}

		public static bool DisallowMortarGraphicStateSwitch(GraphicStateMachine instance, Collider2D other)
		{
			if (!(instance.stackItem is PotionStackItem))
			{
				return true;
			}
			if (Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
			{
				return false;
			}
			return !(((Component)other).GetComponentInParent<InteractiveItem>() is Mortar);
		}

		public static bool SetupSlotCauldronSlotConditionToAllowPotion(Slot instance)
		{
			if ((Object)(object)((Component)instance).GetComponentInParent<Cauldron>() == (Object)null)
			{
				return true;
			}
			if (((Object)((Component)((Component)instance).transform.parent).gameObject).name != "Cauldron")
			{
				return true;
			}
			if (instance.conditions.Contains((Condition)30))
			{
				return true;
			}
			if (!instance.conditions.Contains((Condition)10))
			{
				return true;
			}
			instance.conditions = instance.conditions.Concat((IEnumerable<Condition>)(object)new Condition[1] { (Condition)30 }).ToArray();
			return true;
		}
	}
	public static class PotionDataService
	{
		public static bool PotionHasSerializedData(Potion potion)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!(potion.potionFromPanel.serializedPath.indicatorTargetPosition != Vector2.zero))
			{
				return (potion.potionFromPanel?.serializedPath?.fixedPathPoints?.Any()).GetValueOrDefault();
			}
			return true;
		}

		public static bool IsPotionStackItemEffect(StackVisualEffects instance)
		{
			return ((ItemFromInventory)(instance?.stackScript?)).inventoryItem is Potion;
		}

		public static void CopyImportantInfoToPotionInstance(Potion copyTo, Potion copyFromPotion, SerializedPotionFromPanel copyFrom)
		{
			List<SerializedRecipeMark> recipeMarks = copyTo.potionFromPanel.recipeMarks;
			recipeMarks.Clear();
			copyFrom.recipeMarks.ForEach(delegate(SerializedRecipeMark m)
			{
				recipeMarks.Add(m.Clone());
			});
			copyTo.potionFromPanel.collectedPotionEffects.Clear();
			PotionEffect[] array = ((copyFromPotion != null) ? copyFromPotion.Effects : null) ?? Managers.Potion.collectedPotionEffects;
			foreach (PotionEffect val in array)
			{
				if ((ComparableScriptableObject<PotionEffect>)(object)val == (ComparableScriptableObject<PotionEffect>)null)
				{
					break;
				}
				copyTo.potionFromPanel.collectedPotionEffects.Add(((Object)val).name);
			}
			copyTo.potionFromPanel.serializedPath = copyFrom.serializedPath;
			List<PotionUsedComponent> usedComponents = copyTo.usedComponents;
			if (usedComponents != null && !usedComponents.Any())
			{
				if (copyTo.usedComponents == null)
				{
					copyTo.usedComponents = new List<PotionUsedComponent>();
				}
				copyTo.usedComponents = Managers.Potion.usedComponents.Select((PotionUsedComponent component) => component.Clone()).ToList();
			}
			if (!copyFrom.potionUsedComponents.Any())
			{
				copyTo.usedComponents.ForEach(delegate(PotionUsedComponent component)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0021: 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_0049: Expected O, but got Unknown
					copyFrom.potionUsedComponents.Add(new SerializedUsedComponent
					{
						componentName = ((Object)component.componentObject).name,
						componentAmount = component.amount,
						componentType = ((object)(ComponentType)(ref component.componentType)).ToString()
					});
				});
			}
			copyTo.potionFromPanel.potionUsedComponents = copyFrom.potionUsedComponents;
			copyTo.potionFromPanel.potionSkinSettings = copyFrom.potionSkinSettings;
		}
	}
	public static class PotionItemStackService
	{
		public static void SetupPotionItemForPouringIn(PotionItem potionItem)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			InventoryItem inventoryItem = ((ItemFromInventory)potionItem).inventoryItem;
			Potion potion = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
			if (PotionDataService.PotionHasSerializedData(potion) || RecipeService.GetRecipeForPotion(potion) != null)
			{
				StackVisualEffects obj = ((Component)potionItem).gameObject.AddComponent<StackVisualEffects>();
				Stack val = ((Component)potionItem).gameObject.AddComponent<Stack>();
				typeof(MovableItem).GetField("thisRigidbody", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, ((ItemFromInventory)potionItem).GetRigidbody());
				PotionStackItem potionStackItem = ((Component)potionItem).gameObject.AddComponent<PotionStackItem>();
				potionStackItem.potionItem = potionItem;
				typeof(StackItem).GetField("thisRigidbody", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(potionStackItem, ((ItemFromInventory)potionItem).GetRigidbody());
				((Component)potionStackItem).transform.parent = ((Component)potionItem).transform;
				val.itemsFromThisStack = new List<StackItem> { (StackItem)(object)potionStackItem };
				SoundController val2 = (SoundController)FormatterServices.GetUninitializedObject(typeof(SoundController));
				InitPotionStackSoundController(val2, (ItemFromInventory)(object)val, (ItemFromInventoryPreset)(object)((Potion)((ItemFromInventory)potionItem).inventoryItem).soundPreset);
				typeof(ItemFromInventory).GetField("_soundController", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, val2);
				((StackItem)potionStackItem).Initialize(val);
				obj.stackScript = val;
				((ItemFromInventory)val).inventoryItem = ((ItemFromInventory)potionItem).inventoryItem;
				((StackItem)potionStackItem).spriteRenderers = (SpriteRenderer[])(object)new SpriteRenderer[0];
				((StackItem)potionStackItem).graphicStateMachine = ((Component)potionItem).gameObject.AddComponent<GraphicStateMachine>();
				((StackItem)potionStackItem).graphicStateMachine.Init((StackItem)(object)potionStackItem);
			}
		}

		private static void InitPotionStackSoundController(SoundController instance, ItemFromInventory itemFromInventory, ItemFromInventoryPreset preset)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			Ingredient val = ((SerializableDictionaryBase<InventoryItem, int, int>)(object)Managers.Player.inventory.items).Keys.ToList().OfType<Ingredient>().FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				val = Ingredient.allIngredients.FirstOrDefault();
				if ((Object)(object)val?.soundPreset == (Object)null)
				{
					Plugin.PluginLogger.LogError((object)"Failed to setup sound controller for potion because there were no ingredients in the player inventory.");
					return;
				}
			}
			SoundPresetIngredient val2 = Object.Instantiate<SoundPresetIngredient>(val.soundPreset);
			((HitRubPreset)val2).hit = ((HitRubPreset)preset).hit;
			typeof(SoundController).GetField("stack", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, itemFromInventory);
			typeof(SoundController).GetField("soundPresetIngredient", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, val2);
			typeof(SoundController).GetField("rubGrindLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(val2.rubGrindLoop));
			typeof(ItemFromInventoryController).GetField("itemFromInventory", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, itemFromInventory);
			typeof(ItemFromInventoryController).GetField("preset", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, preset);
			typeof(ItemFromInventoryController).GetField("rubLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(((HitRubPreset)preset).rubLoop));
			typeof(ItemFromInventoryController).GetField("newCollisions", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<Vector2>());
			typeof(ItemFromInventoryController).GetField("collidedWith", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new Dictionary<int, GameObject>());
			typeof(ItemFromInventoryController).GetField("collidedWithToRemove", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new Dictionary<int, Tuple<float, GameObject>>());
		}

		public static void NotifyForPreModPotion(PotionItem instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((int)Managers.Room.currentRoom == 1 || (int)Managers.Room.targetRoom == 1)
			{
				Potion val = (Potion)((ItemFromInventory)instance).inventoryItem;
				if (!PotionDataService.PotionHasSerializedData(val) && RecipeService.GetRecipeForPotion(val) == null && (Object)(object)val != (Object)(object)StaticStorage.CurrentPotionCraftPanelPotion && !StaticStorage.PotionItemsNotifiedFor.Contains(val) && !(Time.unscaledTime - StaticStorage.LastNotifiedTime < 5f))
				{
					StaticStorage.LastNotifiedTime = Time.unscaledTime;
					StaticStorage.PotionItemsNotifiedFor.Add(val);
					Plugin.PluginLogger.LogInfo((object)"Grabbed potion does not have recipe data. This is likely a pre-mod potion with no corresponding recipe.");
					Notification.ShowText("This potion is missing critical markings", "You wouldn't know where to start if you poured it back in the cauldron", (TextType)0);
				}
			}
		}
	}
	public static class RecipeService
	{
		public static SerializedPotionFromPanel GetRecipeForPotion(Potion potion)
		{
			return ((IEnumerable<Potion>)Managers.Potion.recipeBook.savedRecipes).FirstOrDefault((Func<Potion, bool>)((Potion recipe) => RecipeMatchesPotion(potion, recipe)))?.potionFromPanel;
		}

		private static bool RecipeMatchesPotion(Potion potion, Potion recipe)
		{
			if ((Object)(object)recipe == (Object)null)
			{
				return false;
			}
			if (!((InventoryItem)recipe).GetLocalizedTitle().Equals(((InventoryItem)potion).GetLocalizedTitle()))
			{
				return false;
			}
			if (recipe.Effects.Count() != potion.Effects.Count())
			{
				return false;
			}
			if (!SequencesMatch(recipe.Effects.Select((PotionEffect e) => ((Object)e).name).ToList(), potion.Effects.Select((PotionEffect e) => ((Object)e).name).ToList()))
			{
				return false;
			}
			if (recipe.usedComponents.Count() != potion.usedComponents.Count())
			{
				return false;
			}
			var seq = recipe.usedComponents.Select((PotionUsedComponent e) => new
			{
				((Object)e.componentObject).name,
				e.amount
			}).ToList();
			var seq2 = potion.usedComponents.Select((PotionUsedComponent e) => new
			{
				((Object)e.componentObject).name,
				e.amount
			}).ToList();
			if (!SequencesMatch(seq, seq2))
			{
				return false;
			}
			return true;
		}

		private static bool SequencesMatch<T>(IList<T> seq1, IList<T> seq2)
		{
			if (seq1.Count != seq2.Count)
			{
				return false;
			}
			for (int i = 0; i < seq1.Count; i++)
			{
				if (!seq1[i].Equals(seq2[i]))
				{
					return false;
				}
			}
			return true;
		}
	}
}
namespace PotionCraftPourBackIn.Scripts.Patches
{
	[HarmonyPatch(typeof(EnterZone), "OnTriggerStay2D")]
	public class AcceptPotionCollisionEnterZonePatch
	{
		private static bool Prefix(Collider2D other, ThrowVacuuming ___throwVacuuming)
		{
			return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarPotionCollisions(other, ___throwVacuuming));
		}
	}
	[HarmonyPatch(typeof(GraphicStateMachine), "OnTriggerExit2D")]
	public class DisallowMortarGraphicStateSwitchExitPatch
	{
		private static bool Prefix(GraphicStateMachine __instance, Collider2D other)
		{
			return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarGraphicStateSwitch(__instance, other));
		}
	}
	[HarmonyPatch(typeof(GraphicStateMachine), "OnTriggerEnter2D")]
	public class DisallowMortarGraphicStateSwitchPatch
	{
		private static bool Prefix(GraphicStateMachine __instance, Collider2D other)
		{
			return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarGraphicStateSwitch(__instance, other));
		}
	}
	[HarmonyPatch(typeof(AlchemyMachineSlot), "CanBeInteractedNow")]
	public class OverrideAlchemyMachineSlotCanBeInteractedPatch
	{
		private static void Postfix(ref bool __result)
		{
			OverrideAlchemyMachineSlotCanBeInteracted(ref __result);
		}

		private static void OverrideAlchemyMachineSlotCanBeInteracted(ref bool result)
		{
			if (!result)
			{
				return;
			}
			bool newResult = true;
			Ex.RunSafe(delegate
			{
				InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
				PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
				if (val != null)
				{
					InventoryItem inventoryItem = ((ItemFromInventory)val).inventoryItem;
					Potion val2 = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
					if (val2.Effects.Length == 0 || (ComparableScriptableObject<PotionEffect>)(object)val2.Effects[0] == (ComparableScriptableObject<PotionEffect>)null)
					{
						newResult = false;
					}
				}
			});
			if (!newResult)
			{
				result = false;
			}
		}
	}
	public class OverrideCauldronCanBeInteractedPatch
	{
		[HarmonyPatch(typeof(Cauldron), "CanBeInteractedNow")]
		public class Cauldron_CanBeInteractedNow
		{
			private static void Postfix(ref bool __result, Cauldron __instance)
			{
				OverrideCauldronCanBeInteracted(ref __result, __instance);
			}
		}

		[HarmonyPatch(typeof(SlotSelector), "SelectNextSlotByStick")]
		public class SlotSelector_SelectNextSlotByStick
		{
			private static bool Prefix()
			{
				SetIsSelectingSlotByStick(isSelectingSlotByStick: true);
				return true;
			}

			private static void Postfix()
			{
				SetIsSelectingSlotByStick(isSelectingSlotByStick: false);
			}
		}

		private static bool IsSelectingSlotByStick;

		private static void OverrideCauldronCanBeInteracted(ref bool result, Cauldron instance)
		{
			if (result)
			{
				return;
			}
			bool newResult = false;
			Ex.RunSafe(delegate
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
				PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
				if (val != null && !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted() && (PotionDataService.PotionHasSerializedData((Potion)((ItemFromInventory)val).inventoryItem) || RecipeService.GetRecipeForPotion((Potion)((ItemFromInventory)val).inventoryItem) != null) && (IsSelectingSlotByStick || IsPotionItemWithinCauldronBounds(instance, val)))
				{
					ControlsProvider controlsProvider = Managers.Input.controlsProvider;
					newResult = instance.СanTakeIngredients && ((Object)(object)((ItemFromInventory)val).GetRigidbody() == (Object)null || InteractiveItem.CanBeInteractedByVelocity(((ItemFromInventory)val).GetRigidbody().velocity) || (controlsProvider is Gamepad && !Gamepad.MustFreeModeBeEnabled()));
				}
			});
			if (newResult)
			{
				result = true;
			}
		}

		private static bool IsPotionItemWithinCauldronBounds(Cauldron instance, PotionItem potionItem)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0030: 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_006f: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = instance.waterZoneCollider.bounds;
			if (((Component)potionItem).transform.position.x <= ((Bounds)(ref bounds)).min.x || ((Component)potionItem).transform.position.x >= ((Bounds)(ref bounds)).max.x)
			{
				return false;
			}
			CauldronPhysicsCollider componentInChildren = ((Component)instance).GetComponentInChildren<CauldronPhysicsCollider>();
			PolygonCollider2D val = ((componentInChildren != null) ? ((Component)componentInChildren).GetComponent<PolygonCollider2D>() : null);
			if ((Object)(object)val != (Object)null)
			{
				float y = ((Component)potionItem).transform.position.y;
				Bounds bounds2 = ((Collider2D)val).bounds;
				float num = y - ((Bounds)(ref bounds2)).min.y;
				bounds2 = ((Collider2D)val).bounds;
				float num2 = num / ((Bounds)(ref bounds2)).size.y;
				if (num2 < 0.5f)
				{
					return false;
				}
				if (num2 >= 0.7f)
				{
					num2 = 1f;
				}
				else if (num2 > 0.5f)
				{
					num2 += 0.2f;
				}
				float num3 = 0.7f * (1f - num2) * ((Bounds)(ref bounds)).size.x;
				if (((Component)potionItem).transform.position.x <= ((Bounds)(ref bounds)).min.x + num3 || ((Component)potionItem).transform.position.x >= ((Bounds)(ref bounds)).max.x - num3)
				{
					return false;
				}
			}
			return true;
		}

		private static void SetIsSelectingSlotByStick(bool isSelectingSlotByStick)
		{
			IsSelectingSlotByStick = isSelectingSlotByStick;
		}
	}
	[HarmonyPatch(typeof(EnterZone), "OnTriggerExit2D")]
	public class OverrideEnterZoneOnTriggerExit2DPatch
	{
		private static bool Prefix(Collider2D other, ThrowVacuuming ___throwVacuuming)
		{
			return Ex.RunSafe(() => EquipmentInteractionService.DisallowMortarPotionCollisions(other, ___throwVacuuming));
		}
	}
	[HarmonyPatch(typeof(PotionItem), "VacuumItem")]
	public class OverridePotionItemVaccumItemPatch
	{
		private static bool Prefix(PotionItem __instance, bool isPrimaryGrab, bool forceMassModifier, bool forceAltModifier)
		{
			return Ex.RunSafe(() => OverridePotionItemVaccumItem(__instance, isPrimaryGrab, forceMassModifier, forceAltModifier));
		}

		private static bool OverridePotionItemVaccumItem(PotionItem instance, bool isPrimaryGrab, bool forceMassModifier, bool forceAltModifier)
		{
			if (!isPrimaryGrab)
			{
				return true;
			}
			((ItemFromInventory)((Component)instance).gameObject.GetComponent<Stack>()).VacuumItem(isPrimaryGrab, forceMassModifier, forceAltModifier);
			return false;
		}
	}
	[HarmonyPatch(typeof(Stack), "OnCollisionEnter2D")]
	public class OverrideStackOnCollisionEnter2DPatch
	{
		private static bool Prefix(Stack __instance)
		{
			return Ex.RunSafe(() => OverrideStackOnCollisionEnter2D(__instance));
		}

		private static bool OverrideStackOnCollisionEnter2D(Stack instance)
		{
			if (instance.itemsFromThisStack.FirstOrDefault() is PotionStackItem)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PotionItem), "CanBeInteractedNow")]
	public class PreventPotionInteractionWhileVacuumPatch
	{
		private static void Postfix(ref bool __result, PotionItem __instance)
		{
			PreventPotionInteractionWhileVacuum(ref __result, __instance);
		}

		private static void PreventPotionInteractionWhileVacuum(ref bool result, PotionItem instance)
		{
			if (!result)
			{
				return;
			}
			bool newResult = true;
			Ex.RunSafe(delegate
			{
				Stack component = ((Component)instance).GetComponent<Stack>();
				if (!((Object)(object)component == (Object)null))
				{
					newResult = (Object)(object)component.vacuumingTo == (Object)null && ((Component)instance).GetComponent<SortingGroup>().sortingLayerID != 16;
				}
			});
			if (!newResult)
			{
				result = false;
			}
		}
	}
	[HarmonyPatch(typeof(WaterZone), "OnTriggerStay2D")]
	public class RejectPotionCollisionWhenBrewingPatch
	{
		private static bool Prefix(Collider2D other)
		{
			return Ex.RunSafe(() => RejectPotionCollisionWhenBrewing(other));
		}

		private static bool RejectPotionCollisionWhenBrewing(Collider2D other)
		{
			if ((Object)(object)((Component)other).GetComponentInParent<PotionItem>() == (Object)null)
			{
				return true;
			}
			if (Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GraphicStateMachine), "SetCurrentGraphicState")]
	public class RemovePotionHighlightWhenEnteringCauldronPatch
	{
		private static void Postfix(GraphicStateMachine __instance)
		{
			Ex.RunSafe(delegate
			{
				RemovePotionHighlightWhenEnteringCauldron(__instance);
			});
		}

		private static void RemovePotionHighlightWhenEnteringCauldron(GraphicStateMachine instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			StackItem stackItem = instance.stackItem;
			string sortingLayerName = ((InteractiveItem)stackItem).sortingGroup.sortingLayerName;
			SpriteSortingLayers val = (SpriteSortingLayers)16;
			if (sortingLayerName == ((object)(SpriteSortingLayers)(ref val)).ToString())
			{
				IHoverable iHoverableScript = ((InteractiveItem)stackItem.stackScript).iHoverableScript;
				PotionItem val2 = (PotionItem)(object)((iHoverableScript is PotionItem) ? iHoverableScript : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetHovered(false);
				}
			}
		}
	}
	public class SetupSlotCauldronSlotConditionToAllowPotion
	{
		[HarmonyPatch(typeof(Slot), "SetupConditions")]
		public class Slot_SetupConditions
		{
			private static bool Prefix(Slot __instance)
			{
				return Ex.RunSafe(() => EquipmentInteractionService.SetupSlotCauldronSlotConditionToAllowPotion(__instance));
			}
		}
	}
	[HarmonyPatch(typeof(ExperienceSubManager))]
	public class AddModifiedExperienceForPouredBackInPotionsPatch
	{
		private static MethodInfo TargetMethod()
		{
			return typeof(ExperienceSubManager).GetMethod("AddExperience", new Type[2]
			{
				typeof(Potion),
				typeof(int)
			});
		}

		private static bool Prefix(Potion potion, int count)
		{
			return Ex.RunSafe(() => AddModifiedExperienceForPouredBackInPotions(potion, count));
		}

		private static bool AddModifiedExperienceForPouredBackInPotions(Potion potion, int count)
		{
			if (StaticStorage.PouredInUsedComponents == null)
			{
				return true;
			}
			PlayerManagerSettings asset = Settings<PlayerManagerSettings>.Asset;
			float ingredientsExperience = 0f;
			(potion.usedComponents.Any() ? potion.usedComponents : Managers.Potion.usedComponents).Skip(StaticStorage.PouredInUsedComponents.Count).ToList().ForEach(delegate(PotionUsedComponent component)
			{
				//IL_0001: 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 ((int)component.componentType == 0)
				{
					ingredientsExperience += ((InventoryItem)component.componentObject).GetPrice() * (float)component.amount;
				}
			});
			ingredientsExperience *= asset.experiencePotionIngredientsMultiplier;
			new List<PotionEffect>();
			int num = 0;
			for (int i = 0; i < (StaticStorage.PouredInEffects?.Count ?? 0); i++)
			{
				if ((ComparableScriptableObject<PotionEffect>)(object)potion.Effects[num] == (ComparableScriptableObject<PotionEffect>)(object)StaticStorage.PouredInEffects[i])
				{
					num++;
				}
				else if (num > 0)
				{
					break;
				}
			}
			List<PotionEffect> list = potion.Effects.Skip(num).ToList();
			float num2 = (list.Any() ? ((float)potion.GetPotionReview(list.ToArray()).cost * asset.experiencePotionEffectsMultiplier) : 0f);
			Managers.Player.AddExperience((ingredientsExperience + num2) * (float)count);
			StaticStorage.PouredInUsedComponents = null;
			StaticStorage.PouredInEffects = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(PotionManager), "GeneratePotionFromCurrentPotion")]
	public class CopyImportantInfoToPotionInstancePotionManagerPatch
	{
		[HarmonyAfter(new string[] { "com.fahlgorithm.potioncraftalchemymachinerecipies" })]
		private static void Postfix(Potion __result)
		{
			Ex.RunSafe(delegate
			{
				CopyImportantInfoToPotionInstance(__result);
			});
		}

		private static void CopyImportantInfoToPotionInstance(Potion copyTo)
		{
			if (!StaticStorage.CurrentlyMakingPotion || StaticStorage.CurrentlyGeneratingRecipe)
			{
				return;
			}
			SerializedPotionFromPanel potionFromCurrentPotion = SerializedPotionFromPanel.GetPotionFromCurrentPotion();
			Potion currentPotion = Managers.Potion.potionCraftPanel.GetCurrentPotion();
			PotionItem val = null;
			if ((Object)(object)currentPotion == (Object)null)
			{
				InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
				PotionItem val2 = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
				if (val2 != null)
				{
					((ItemFromInventory)val2).inventoryItem = (InventoryItem)(object)copyTo;
					val = val2;
				}
			}
			PotionDataService.CopyImportantInfoToPotionInstance(copyTo, currentPotion, potionFromCurrentPotion);
			if ((Object)(object)val != (Object)null)
			{
				PotionItemStackService.SetupPotionItemForPouringIn(val);
				((ItemFromInventory)val).OnGrabPrimary();
			}
		}
	}
	[HarmonyPatch(typeof(Potion), "Clone")]
	public class CopyImportantInfoToPotionInstancePotionPatch
	{
		private static void Postfix(Potion __result, Potion __instance)
		{
			Ex.RunSafe(delegate
			{
				CopyImportantInfoToPotionInstance(__result, __instance);
			});
		}

		private static void CopyImportantInfoToPotionInstance(Potion copyTo, Potion copyFrom)
		{
			PotionDataService.CopyImportantInfoToPotionInstance(copyTo, copyFrom, copyFrom.potionFromPanel);
		}
	}
	[HarmonyPatch(typeof(StackVisualEffects))]
	public class HidePotionStackExplosionEffectsPatch
	{
		private static MethodInfo TargetMethod()
		{
			return typeof(StackVisualEffects).GetMethod("SpawnEffectsExplosion", new Type[3]
			{
				typeof(IngredientVisualEffect),
				typeof(Vector3),
				typeof(SpriteSortingLayers)
			});
		}

		private static bool Prefix(StackVisualEffects __instance)
		{
			return Ex.RunSafe(() => !PotionDataService.IsPotionStackItemEffect(__instance));
		}
	}
	[HarmonyPatch(typeof(StackVisualEffects), "SpawnEffectsUpdate")]
	public class HidePotionStackVisualEffectsPatch
	{
		private static bool Prefix(StackVisualEffects __instance)
		{
			return Ex.RunSafe(() => !PotionDataService.IsPotionStackItemEffect(__instance));
		}
	}
	[HarmonyPatch(typeof(PotionCraftPanel), "UpdatePotionInCraftPanel")]
	public class KeepTrackOfCurrentPotionCraftPanelPotionPatch
	{
		private static void Postfix()
		{
			Ex.RunSafe(delegate
			{
				KeepTrackOfCurrentPotionCraftPanelPotion();
			});
		}

		private static void KeepTrackOfCurrentPotionCraftPanelPotion()
		{
			StaticStorage.CurrentPotionCraftPanelPotion = Managers.Potion.potionCraftPanel.GetCurrentPotion();
		}
	}
	[HarmonyPatch(typeof(Potion))]
	public class LoadPotionSerializedDataPatch
	{
		private static MethodInfo TargetMethod()
		{
			return typeof(Potion).GetMethod("GetFromSerializedObject", new Type[1] { typeof(SerializedInventorySlot) });
		}

		private static void Postfix(Potion __result, SerializedInventorySlot serializedObject)
		{
			Ex.RunSafe(delegate
			{
				LoadPotionSerializedData(__result, serializedObject);
			});
		}

		private static void LoadPotionSerializedData(Potion result, SerializedInventorySlot serializedRecipe)
		{
			int num = serializedRecipe.data.IndexOf("potionFromPanel");
			if (num == -1)
			{
				return;
			}
			int num2 = serializedRecipe.data.IndexOf('{', num);
			if (num2 == -1)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed.");
				return;
			}
			int endJsonIndex = GetEndJsonIndex(serializedRecipe.data, num2, useBrackets: false);
			if (endJsonIndex >= serializedRecipe.data.Length)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed (bad end index).");
				return;
			}
			string text = serializedRecipe.data.Substring(num2, endJsonIndex - num2);
			if (text.Length <= 2)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: potionFromPanel data in serialized potion is malformed (empty object).");
			}
			else
			{
				result.potionFromPanel = JsonUtility.FromJson<SerializedPotionFromPanel>(text);
			}
		}

		private static int GetEndJsonIndex(string input, int startIndex, bool useBrackets)
		{
			int num = startIndex + 1;
			int num2 = 1;
			char value = (useBrackets ? '[' : '{');
			char value2 = (useBrackets ? ']' : '}');
			while (num2 > 0 && num < input.Length - 1)
			{
				int num3 = input.IndexOf(value, num);
				int num4 = input.IndexOf(value2, num);
				if (num3 == -1 && num4 == -1)
				{
					break;
				}
				if (num3 == -1)
				{
					num3 = int.MaxValue;
				}
				if (num4 == -1)
				{
					num4 = int.MaxValue;
				}
				if (num3 < num4)
				{
					num = num3 + 1;
					num2++;
				}
				else if (num4 < num3)
				{
					num = num4 + 1;
					num2--;
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(Stack), "AddIngredientPathToMapPath")]
	public class OverrideAddIngredientPathToMapPathPatch
	{
		private static bool Prefix(Stack __instance)
		{
			return Ex.RunSafe(() => OverrideAddIngredientPathToMapPath(__instance), () => OnError(__instance));
		}

		private static bool OnError(Stack stack)
		{
			try
			{
				if (stack.itemsFromThisStack.FirstOrDefault() is PotionStackItem)
				{
					return false;
				}
			}
			catch (Exception ex)
			{
				Ex.LogException(ex);
			}
			return true;
		}

		private static bool OverrideAddIngredientPathToMapPath(Stack instance)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			PotionStackItem potionStackItem = (instance.itemsFromThisStack.FirstOrDefault() as PotionStackItem) ?? (instance.vacuumedItemsFromThisStack.FirstOrDefault() as PotionStackItem);
			if ((Object)(object)potionStackItem == (Object)null)
			{
				return true;
			}
			ContinueBrewingFromPotion((Potion)((ItemFromInventory)potionStackItem.potionItem).inventoryItem);
			return false;
		}

		private static void ContinueBrewingFromPotion(Potion potion)
		{
			SerializedPotionFromPanel recipeForPotion = RecipeService.GetRecipeForPotion(potion);
			SerializedPotionFromPanel val = ((!PotionDataService.PotionHasSerializedData(potion)) ? recipeForPotion : potion.potionFromPanel);
			if (val == null)
			{
				Plugin.PluginLogger.LogInfo((object)"ERROR: Failed to find recipe for poured-in, pre-mod potion!");
				return;
			}
			PotionBase val2 = ((val.potionUsedComponents.Count == 0) ? Managers.RecipeMap.currentMap.potionBase : PotionBase.GetByName(val.potionUsedComponents[0].componentName, false, true));
			val.ApplyPotionToCurrentPotion(val2);
			StaticStorage.PouredInUsedComponents = potion.usedComponents.ToList();
			StaticStorage.PouredInEffects = potion.Effects.ToList();
			if (recipeForPotion != null)
			{
				Managers.Potion.potionCraftPanel.potionChangedAfterSavingRecipe = false;
				((Button)Managers.Potion.potionCraftPanel.saveRecipeButton).Locked = true;
			}
			PotionEffect[] collectedPotionEffects = Managers.Potion.collectedPotionEffects;
			foreach (PotionEffect val3 in collectedPotionEffects)
			{
				if ((ComparableScriptableObject<PotionEffect>)(object)val3 == (ComparableScriptableObject<PotionEffect>)null)
				{
					continue;
				}
				foreach (PotionEffectMapItem item in Managers.RecipeMap.currentMap.potionEffectsOnMap)
				{
					if ((ComparableScriptableObject<PotionEffect>)(object)item.Effect == (ComparableScriptableObject<PotionEffect>)(object)val3)
					{
						item.Status = (PotionEffectStatus)3;
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Potion), "GetSerializedInventorySlot")]
	public class SavePotionSerializedDataPatch
	{
		private static void Postfix(SerializedInventorySlot __result, Potion __instance)
		{
			Ex.RunSafe(delegate
			{
				SavePotionSerializedData(__result, __instance);
			});
		}

		private static void SavePotionSerializedData(SerializedInventorySlot result, Potion instance)
		{
			if (!result.data.Contains("potionFromPanel"))
			{
				string value = ",\"potionFromPanel\":" + JsonUtility.ToJson((object)instance.potionFromPanel);
				int startIndex = result.data.LastIndexOf('}');
				result.data = result.data.Insert(startIndex, value);
			}
		}
	}
	[HarmonyPatch(typeof(SaveRecipeButton), "GenerateRecipe")]
	public class SetCurrentlyGeneratingRecipePatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: true));
		}

		private static void Postfix()
		{
			Ex.RunSafe(() => SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: false));
		}

		private static bool SetCurrentlyGeneratingRecipe(bool currentlyGeneratingRecipe)
		{
			StaticStorage.CurrentlyGeneratingRecipe = currentlyGeneratingRecipe;
			return true;
		}
	}
	[HarmonyPatch(typeof(PotionCraftPanel), "MakePotion")]
	public class SetCurrentlyMakingPotionPatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => SetCurrentlyMakingPotion(currentlyMakingPotion: true));
		}

		private static void Postfix()
		{
			Ex.RunSafe(() => SetCurrentlyMakingPotion(currentlyMakingPotion: false));
		}

		private static bool SetCurrentlyMakingPotion(bool currentlyMakingPotion)
		{
			StaticStorage.CurrentlyMakingPotion = currentlyMakingPotion;
			return true;
		}
	}
	[HarmonyPatch(typeof(PotionItem), "OnGrabPrimary")]
	public class ForwardGrabPrimaryPatch
	{
		private static void Postfix(PotionItem __instance)
		{
			Ex.RunSafe(delegate
			{
				ForwardGrabPrimary(__instance);
			});
		}

		private static void ForwardGrabPrimary(PotionItem instance)
		{
			Stack component = ((Component)instance).GetComponent<Stack>();
			if ((Object)(object)component == (Object)null)
			{
				PotionItemStackService.NotifyForPreModPotion(instance);
				return;
			}
			((ItemFromInventory)component).OnGrabPrimary();
			MethodInfo method = typeof(ConditionValue).GetMethod("SetConditionValue", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(Condition),
				typeof(bool)
			}, new ParameterModifier[0]);
			if (!(method == null))
			{
				method.Invoke(null, new object[2]
				{
					(object)(Condition)30,
					true
				});
			}
		}
	}
	[HarmonyPatch(typeof(ItemFromInventory), "CustomOnReleasePrimaryCondition")]
	public class ForwardPotionItemOnReleasePrimaryPatch
	{
		private static void Postfix(ItemFromInventory __instance)
		{
			Ex.RunSafe(delegate
			{
				ForwardPotionItemOnReleasePrimary(__instance);
			});
		}

		private static void ForwardPotionItemOnReleasePrimary(ItemFromInventory instance)
		{
			if (instance is PotionItem)
			{
				Stack component = ((Component)instance).gameObject.GetComponent<Stack>();
				if (!((Object)(object)component == (Object)null) && !(Managers.Cursor.hoveredInteractiveItem is ScalesCupDisplay) && !(Managers.Cursor.hoveredInteractiveItem is AlchemyMachineSlot))
				{
					typeof(Stack).GetMethod("CustomOnReleasePrimaryCondition", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(component, null);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemFromInventory), "OnReleasePrimary")]
	public class ForwardReleasePrimaryPatch
	{
		private static void Postfix(ItemFromInventory __instance)
		{
			Ex.RunSafe(delegate
			{
				ForwardReleasePrimary(__instance);
			});
		}

		private static void ForwardReleasePrimary(ItemFromInventory instance)
		{
			if ((Object)(object)instance == (Object)null || instance.markedAsDestroyed)
			{
				return;
			}
			PotionItem val = (PotionItem)(object)((instance is PotionItem) ? instance : null);
			if (val != null)
			{
				Stack component = ((Component)val).GetComponent<Stack>();
				if (!((Object)(object)component == (Object)null) && !(Managers.Cursor.hoveredInteractiveItem is ScalesCupDisplay) && !(Managers.Cursor.hoveredInteractiveItem is AlchemyMachineSlot))
				{
					((ItemFromInventory)component).OnReleasePrimary();
				}
			}
		}
	}
	[HarmonyPatch(typeof(RoomManager), "GoTo")]
	public class NotifyForPreModPotionOnRoomChangePatch
	{
		private static void Postfix()
		{
			Ex.RunSafe(delegate
			{
				NotifyForPreModPotionOnRoomChange();
			});
		}

		private static void NotifyForPreModPotionOnRoomChange()
		{
			InteractiveItem grabbedInteractiveItem = Managers.Cursor.grabbedInteractiveItem;
			PotionItem val = (PotionItem)(object)((grabbedInteractiveItem is PotionItem) ? grabbedInteractiveItem : null);
			if (val != null)
			{
				PotionItemStackService.NotifyForPreModPotion(val);
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public class OverridePotionStackItemSoundControllerPatch
	{
		private static bool Prefix(SoundController __instance, StackItem stackItem)
		{
			return Ex.RunSafe(() => OverridePotionStackItemSoundController(__instance, stackItem), () => OnError(stackItem));
		}

		private static bool OnError(StackItem stackItem)
		{
			try
			{
				if (stackItem is PotionStackItem)
				{
					return false;
				}
			}
			catch (Exception ex)
			{
				Ex.LogException(ex);
			}
			return true;
		}

		private static bool OverridePotionStackItemSoundController(SoundController instance, StackItem stackItem)
		{
			//IL_00d9: 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_0134: Expected O, but got Unknown
			if (!(stackItem is PotionStackItem))
			{
				return true;
			}
			PotionItem potionItem = ((PotionStackItem)(object)stackItem).potionItem;
			typeof(SoundController).GetField("stackItem", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, stackItem);
			typeof(SoundController).GetField("newCollisions", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<Vector2>());
			typeof(SoundController).GetField("collidedWith", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, new List<GameObject>());
			Ingredient val = ((SerializableDictionaryBase<InventoryItem, int, int>)(object)Managers.Player.inventory.items).Keys.ToList().OfType<Ingredient>().FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				val = Ingredient.allIngredients.FirstOrDefault();
				if ((Object)(object)val == (Object)null)
				{
					Plugin.PluginLogger.LogError((object)"Failed to setup sound controller for potion because there were no ingredients in the player inventory.");
					return false;
				}
			}
			SoundPresetIngredient val2 = Object.Instantiate<SoundPresetIngredient>(val.soundPreset);
			SoundPresetPotion soundPreset = ((Potion)((ItemFromInventory)potionItem).inventoryItem).soundPreset;
			((HitRubPreset)val2).hit = ((HitRubPreset)soundPreset).hit;
			typeof(SoundController).GetField("preset", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, val2);
			typeof(SoundController).GetField("rubLoopEmitter", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(instance, (object?)new LoopEmitter(((HitRubPreset)val2).rubLoop));
			return false;
		}
	}
	[HarmonyPatch(typeof(SoundController), "OnGrind")]
	public class OverrideSoundControllerOnGrindPatch
	{
		private static bool Prefix(SoundController __instance)
		{
			return Ex.RunSafe(() => OverrideSoundControllerOnGrind(__instance));
		}

		private static bool OverrideSoundControllerOnGrind(SoundController instance)
		{
			return !(typeof(SoundController).GetField("stackItem", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance) is PotionStackItem);
		}
	}
	public class PreventCrashOnStackItemDestroy
	{
		[HarmonyPatch(typeof(StackItem), "RemoveItemFromStackAndReset")]
		public class StackItem_RemoveItemFromStackAndReset
		{
			private static bool Prefix(StackItem __instance)
			{
				return Ex.RunSafe(() => DoPreventCrashOnStackItemDestroy(__instance));
			}
		}

		private static bool DoPreventCrashOnStackItemDestroy(StackItem instance)
		{
			if (!(instance is PotionStackItem))
			{
				return true;
			}
			Stack stackScript = instance.stackScript;
			if (stackScript != null)
			{
				stackScript.RemoveItemFromStack(instance);
			}
			instance.soundController.ResetController();
			return false;
		}
	}
	[HarmonyPatch(typeof(Stack), "DisassembleStack")]
	public class PreventPotionStackDissassemblyPatch
	{
		private static bool Prefix(Stack __instance)
		{
			return Ex.RunSafe(() => PreventPotionStackDissassembly(__instance));
		}

		private static bool PreventPotionStackDissassembly(Stack instance)
		{
			return (Object)(object)((Component)instance).GetComponent<PotionItem>() == (Object)null;
		}
	}
	[HarmonyPatch(typeof(StackItem), "OnDestroy")]
	public class PreventStackItemOnDestroyExceptionPatch
	{
		private static bool Prefix(StackItem __instance)
		{
			return Ex.RunSafe(() => PreventStackItemOnDestroyException(__instance));
		}

		private static bool PreventStackItemOnDestroyException(StackItem instance)
		{
			if (!(instance is PotionStackItem))
			{
				return true;
			}
			Stack stackScript = instance.stackScript;
			if (stackScript != null)
			{
				stackScript.RemoveItemFromStack(instance);
			}
			SoundController soundController = instance.soundController;
			if (soundController != null)
			{
				soundController.ResetController();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PotionItem), "SpawnNewPotion")]
	public class SetupPotionItemForPouringInPatch
	{
		private static void Postfix(PotionItem __result)
		{
			Ex.RunSafe(delegate
			{
				PotionItemStackService.SetupPotionItemForPouringIn(__result);
			});
		}
	}
	[HarmonyPatch(typeof(RecipeBook), "OnLoad")]
	public class SetupPotionItemsForPouringInOnRecipeLoadPatch
	{
		private static void Postfix()
		{
			Ex.RunSafe(delegate
			{
				SetupPotionItemsForPouringInOnRecipeLoad();
			});
		}

		private static void SetupPotionItemsForPouringInOnRecipeLoad()
		{
			(from p in ((Component)Managers.Game.ItemContainer).GetComponentsInChildren<PotionItem>()
				where (Object)(object)((Component)p).GetComponent<Stack>() == (Object)null
				select p).ToList().ForEach(PotionItemStackService.SetupPotionItemForPouringIn);
		}
	}
	public static class UnfinishedPotionPatcher
	{
		[HarmonyPatch(typeof(PotionCraftPanel), "UpdatePotionInCraftPanel")]
		public class EnableFinishPotionButtonForUnfinishedPotionsPatch
		{
			private static void Postfix(PotionCraftPanel __instance)
			{
				Ex.RunSafe(delegate
				{
					EnableFinishPotionButtonForUnfinishedPotions(__instance);
				});
			}

			private static void EnableFinishPotionButtonForUnfinishedPotions(PotionCraftPanel instance)
			{
				if (instance.IsPotionBrewingStarted())
				{
					((Button)((ItemsPanel)instance.limitedInventoryPanel).buttons.First()).Locked = false;
					((Button)instance.potionFinishingButton).Locked = false;
				}
			}
		}

		[HarmonyPatch(typeof(PotionInventoryObject), "CanBeInteractedNow")]
		public class EnableGrabUnfinishedPotionToFinishPatch
		{
			private static bool Prefix(InventoryItem ___inventoryItem)
			{
				return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(___inventoryItem));
			}

			private static void Postfix(InventoryItem ___inventoryItem)
			{
				Ex.RunSafe(delegate
				{
					EnableGrabUnfinishedPotionToFinishPostfix(___inventoryItem);
				});
			}
		}

		[HarmonyPatch(typeof(RecipeBookPotionInventoryObject), "CanBeInteractedNow")]
		public class RecipeBookPotionInventoryObject_CanBeInteractedNow
		{
			private static bool Prefix(InventoryItem ___inventoryItem)
			{
				return Ex.RunSafe(() => EnableGrabUnfinishedPotionToFinishPrefix(___inventoryItem, requireBrewStart: false));
			}

			private static void Postfix(InventoryItem ___inventoryItem)
			{
				Ex.RunSafe(delegate
				{
					EnableGrabUnfinishedPotionToFinishPostfix(___inventoryItem, requireBrewStart: false);
				});
			}
		}

		private static bool EnableGrabUnfinishedPotionToFinishPrefix(InventoryItem inventoryItem, bool requireBrewStart = true)
		{
			Potion val = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
			if (val == null)
			{
				return true;
			}
			if (requireBrewStart && !Managers.Potion.potionCraftPanel.IsPotionBrewingStarted())
			{
				return true;
			}
			if (val.Effects.Any())
			{
				return true;
			}
			val.Effects = (PotionEffect[])(object)new PotionEffect[1] { PotionEffect.allPotionEffects.First() };
			StaticStorage.DummyEffectAddedToEnableFinishPotionGrab = true;
			return true;
		}

		private static void EnableGrabUnfinishedPotionToFinishPostfix(InventoryItem inventoryItem, bool requireBrewStart = true)
		{
			Potion val = (Potion)(object)((inventoryItem is Potion) ? inventoryItem : null);
			if (val != null && (!requireBrewStart || Managers.Potion.potionCraftPanel.IsPotionBrewingStarted()) && StaticStorage.DummyEffectAddedToEnableFinishPotionGrab)
			{
				val.Effects = (PotionEffect[])(object)new PotionEffect[0];
				StaticStorage.DummyEffectAddedToEnableFinishPotionGrab = false;
			}
		}
	}
}
namespace PotionCraftPourBackIn.Scripts.Patches.UnfinishedPotion
{
	public class AllowBrewingNoEffectPotionsFromRecipeBookPatch
	{
		[HarmonyPatch(typeof(RecipeBookPotionPlaceholderForTooltip), "GetTooltipContent")]
		public class RecipeBookPotionPlaceholderForTooltip_GetTooltipContent
		{
			private static void Postfix(ref TooltipContent __result, RecipeBookLeftPageContent ___leftPageContent)
			{
				OverrideRecipeBookPotionIconTooltip(ref __result, ___leftPageContent);
			}
		}

		[HarmonyPatch(typeof(RecipeBookPotionInventoryObject), "UpdateVisual")]
		public class RecipeBookPotionInventoryObject_UpdateVisual
		{
			private static void Postfix(RecipeBookPotionInventoryObject __instance)
			{
				Ex.RunSafe(delegate
				{
					AllowBrewingNoEffectPotionsFromRecipeBook(__instance);
				});
			}
		}

		private static void OverrideRecipeBookPotionIconTooltip(ref TooltipContent result, RecipeBookLeftPageContent leftPageContent)
		{
			if (result == null)
			{
				return;
			}
			TooltipContent newResult = result;
			string header = result.header;
			Ex.RunSafe(delegate
			{
				//IL_0007: 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_004d: 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_006a: Expected O, but got Unknown
				string text = new Key("#recipebook_brew_potion_no_effects", (List<string>)null, false).GetText();
				if (!(header != text))
				{
					if (RecipeBook.GetAvailableResultPotionsCount(((PageContent)leftPageContent).currentState, leftPageContent.pageContentPotion) != 0)
					{
						newResult = null;
					}
					else
					{
						string text2 = new Key("#recipebook_brew_potion_not_enough_ingredients", (List<string>)null, false).GetText();
						newResult = new TooltipContent
						{
							header = text2
						};
					}
				}
			});
			result = newResult;
		}

		private static void AllowBrewingNoEffectPotionsFromRecipeBook(RecipeBookPotionInventoryObject instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (((Button)instance).Locked)
			{
				ItemsPanel itemsPanel = ((InventoryObject)instance).itemsPanel;
				ItemsPanel obj = ((itemsPanel is RecipeBookPanelInventoryPanel) ? itemsPanel : null);
				State currentState = ((PageContent)((RecipeBookPanelInventoryPanel)obj).leftPageContent).currentState;
				Potion pageContentPotion = ((RecipeBookPanelInventoryPanel)obj).leftPageContent.pageContentPotion;
				if ((int)currentState != 0 && (pageContentPotion.Effects.Length == 0 || (ComparableScriptableObject<PotionEffect>)(object)pageContentPotion.Effects[0] == (ComparableScriptableObject<PotionEffect>)null) && RecipeBook.GetAvailableResultPotionsCount(currentState, pageContentPotion) != 0)
				{
					((Button)instance).Locked = false;
				}
			}
		}
	}
}