Decompiled source of Alchemy Machine Recipes v1.1.0

plugins/PotionCraftAlchemyMachineRecipes.dll

Decompiled 5 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using DarkScreenSystem;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PotionCraft;
using PotionCraft.Core;
using PotionCraft.Core.SerializableDictionary;
using PotionCraft.LocalizationSystem;
using PotionCraft.ManagersSystem;
using PotionCraft.ManagersSystem.Game;
using PotionCraft.ManagersSystem.Player;
using PotionCraft.ManagersSystem.Potion;
using PotionCraft.ManagersSystem.SaveLoad;
using PotionCraft.ManagersSystem.TMP;
using PotionCraft.NotificationSystem;
using PotionCraft.ObjectBased;
using PotionCraft.ObjectBased.AlchemyMachine;
using PotionCraft.ObjectBased.AlchemyMachineProduct;
using PotionCraft.ObjectBased.InteractiveItem;
using PotionCraft.ObjectBased.Potion;
using PotionCraft.ObjectBased.UIElements;
using PotionCraft.ObjectBased.UIElements.Books;
using PotionCraft.ObjectBased.UIElements.Books.GoalsBook;
using PotionCraft.ObjectBased.UIElements.Books.RecipeBook;
using PotionCraft.ObjectBased.UIElements.ConfirmationWindow;
using PotionCraft.ObjectBased.UIElements.FinishLegendarySubstanceMenu;
using PotionCraft.ObjectBased.UIElements.PotionCraftPanel;
using PotionCraft.ObjectBased.UIElements.Tooltip;
using PotionCraft.SaveFileSystem;
using PotionCraft.SaveLoadSystem;
using PotionCraft.ScriptableObjects;
using PotionCraft.ScriptableObjects.AlchemyMachineProducts;
using PotionCraft.ScriptableObjects.Potion;
using PotionCraft.Settings;
using PotionCraft.SoundSystem;
using PotionCraft.SoundSystem.SoundPresets;
using PotionCraft.TMPAtlasGenerationSystem;
using PotionCraft.Utils;
using PotionCraftAlchemyMachineRecipes.Scripts.Services;
using PotionCraftAlchemyMachineRecipes.Scripts.Storage;
using UnityEngine;
using UnityEngine.Events;

[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("PotionCraftAlchemyMachineRecipes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PotionCraftAlchemyMachineRecipes")]
[assembly: AssemblyTitle("PotionCraftAlchemyMachineRecipes")]
[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 PotionCraftAlchemyMachineRecipes
{
	[BepInPlugin("com.fahlgorithm.potioncraftalchemymachinerecipies", "PotionCraftAlchemyMachineRecipes", "1.1.0.0")]
	[BepInProcess("Potion Craft.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static ManualLogSource PluginLogger { get; private set; }

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

		public const string PLUGIN_NAME = "PotionCraftAlchemyMachineRecipes";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace PotionCraftAlchemyMachineRecipes.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.Message + "\r\n" + ex.StackTrace + "\r\n" + ex.InnerException?.Message;
			Plugin.PluginLogger.LogError((object)text);
		}
	}
	[HarmonyPatch(typeof(Icon), "GetByName")]
	public class Icon_GetByName
	{
		private static bool Prefix(ref Icon __result, string iconName)
		{
			return RecipeUIService.FixPotionIconException(ref __result, iconName);
		}
	}
	[HarmonyPatch(typeof(FinishLegendarySubstanceWindow), "UpdateSaveProductRecipeButton")]
	public class UpdateSaveProductRecipeButtonPatch
	{
		private static void Postfix(SaveProductRecipeButton ___saveProductRecipeButton)
		{
			Ex.RunSafe(delegate
			{
				RecipeUIService.UpdateSaveProductRecipeButton(___saveProductRecipeButton);
			});
		}
	}
	[HarmonyPatch(typeof(SaveProductRecipeButton), "OnButtonReleasedPointerInside")]
	public class ActuallySaveProductRecipeButtonPatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => RecipeService.ActuallySaveProductRecipeButton());
		}
	}
	[HarmonyPatch(typeof(AlchemyMachineObject), "WipeSlots")]
	public class StorePotionsBeforeWipePatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => RecipeService.StorePotionsBeforeWipe());
		}
	}
	[HarmonyPatch(typeof(Potion), "Clone")]
	public class StoreRecipeMarksFromRecipeBrewPatch
	{
		private static void Postfix(ref Potion __result, Potion __instance)
		{
			RunSafe(__result, __instance);
		}

		private static void RunSafe(Potion __result, Potion __instance)
		{
			Ex.RunSafe(delegate
			{
				RecipeService.CopyImportantInfoToPotionInstance(__result, __instance);
			});
		}
	}
	[HarmonyPatch(typeof(Potion), "GetTooltipContent")]
	public class FixLegendaryRecipeTooltipContentPatch
	{
		private static bool Prefix(Potion __instance, ref TooltipContent __result, int itemCount, bool anyModifierHeld)
		{
			return RecipeUIService.FixLegendaryRecipeTooltipContent(__instance, ref __result, itemCount, anyModifierHeld);
		}
	}
	[HarmonyPatch(typeof(RecipeBook), "UpdateBookmarkIcon")]
	public class FixLegendaryRecipeBookmarkIconPatch
	{
		private static bool Prefix(RecipeBook __instance, int index)
		{
			return Ex.RunSafe(() => RecipeUIService.FixLegendaryRecipeBookmarkIcon(__instance, index));
		}
	}
	[HarmonyPatch(typeof(PotionCraftPanel), "MakePotion")]
	public class SetCurrentlyMakingPotionPatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => RecipeService.SetCurrentlyMakingPotion(currentlyMakingPotion: true));
		}
	}
	[HarmonyPatch(typeof(PotionCraftPanel), "MakePotion")]
	public class UnsetCurrentlyMakingPotionPatch
	{
		private static void Postfix()
		{
			Ex.RunSafe(() => RecipeService.SetCurrentlyMakingPotion(currentlyMakingPotion: false));
		}
	}
	[HarmonyPatch(typeof(SaveRecipeButton), "GenerateRecipe")]
	public class SetCurrentlyGeneratingRecipePatch
	{
		private static bool Prefix()
		{
			return Ex.RunSafe(() => RecipeService.SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: true));
		}
	}
	[HarmonyPatch(typeof(SaveRecipeButton), "GenerateRecipe")]
	public class UnsetCurrentlyGeneratingRecipePatch
	{
		private static void Postfix()
		{
			Ex.RunSafe(() => RecipeService.SetCurrentlyGeneratingRecipe(currentlyGeneratingRecipe: false));
		}
	}
	[HarmonyPatch(typeof(PotionManager), "GeneratePotionFromCurrentPotion")]
	public class StoreRecipeMarksFromPotionBrewPatch
	{
		private static void Postfix(ref Potion __result, PotionManager __instance)
		{
			RunSafe(__result);
		}

		private static void RunSafe(Potion __result)
		{
			Ex.RunSafe(delegate
			{
				RecipeService.StoreRecipeMarksFromPotionBrew(__result);
			});
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdatePage")]
	public class HidePotionCustomizationPatch
	{
		private static void Postfix(RecipeBookLeftPageContent __instance, GameObject ___potionSlotBackground)
		{
			Ex.RunSafe(delegate
			{
				RecipeUIService.HidePotionCustomization(__instance, ___potionSlotBackground);
			});
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdateIngredientsList")]
	public class AddLegendaryIngredientToListPatch
	{
		private static bool Prefix(RecipeBookLeftPageContent __instance)
		{
			return Ex.RunSafe(() => RecipeService.AddLegendaryIngredientToList(__instance));
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdateIngredientsList")]
	public class RemoveLegendaryIngredientFromListPatch
	{
		private static void Postfix(RecipeBookLeftPageContent __instance)
		{
			Ex.RunSafe(delegate
			{
				RecipeService.RemoveLegendaryIngredientFromList(__instance);
			});
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdateIngredientsList")]
	public class ChangeAtlasNameForProductPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return RecipeUIService.UpdateIngredientList(instructions);
		}
	}
	[HarmonyPatch(typeof(RecipeBookContinuePotionBrewingButton), "UpdateVisual")]
	public class DisableContinueFromHereButtonPatch
	{
		private static void Postfix(RecipeBookContinuePotionBrewingButton __instance, RecipeBookRightPageContent ___rightPageContent)
		{
			Ex.RunSafe(delegate
			{
				RecipeUIService.DisableContinueFromHereButton(__instance, ___rightPageContent);
			});
		}
	}
	[HarmonyPatch(typeof(RecipeBook), "GetAvailableResultPotionsCount")]
	public class ChangeBrewPotionButtonCountPatch
	{
		private static void Postfix(ref int __result, Potion currentPotion)
		{
			RecipeUIService.ChangeBrewPotionButtonCount(ref __result, currentPotion);
		}
	}
	[HarmonyPatch(typeof(RecipeBookBrewPotionButton), "BrewPotion")]
	public class BrewPotionPatch
	{
		private static bool Prefix(RecipeBookBrewPotionButton __instance, RecipeBookRightPageContent ___rightPageContent)
		{
			return Ex.RunSafe(() => AlchemyMachineProductService.BrewPotion(__instance, ___rightPageContent), () => OnError(___rightPageContent));
		}

		private static bool OnError(RecipeBookRightPageContent rightPageContent)
		{
			try
			{
				if ((Object)(object)rightPageContent.pageContentPotion == (Object)null)
				{
					return true;
				}
				if (!RecipeService.IsLegendaryRecipe(rightPageContent.pageContentPotion))
				{
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				Ex.LogException(ex);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdateEffects")]
	public class HidePotionCustomizationEffectTextPrefixPatch
	{
		private static bool Prefix(Potion ___pageContentPotion)
		{
			return Ex.RunSafe(() => RecipeService.RemoveRecipePotionEffects(___pageContentPotion));
		}
	}
	[HarmonyPatch(typeof(RecipeBookLeftPageContent), "UpdateEffects")]
	public class HidePotionCustomizationEffectTextPostfixPatch
	{
		private static void Postfix(Potion ___pageContentPotion)
		{
			Ex.RunSafe(delegate
			{
				RecipeService.ReAddRecipePotionEffects(___pageContentPotion);
			});
		}
	}
	[HarmonyPatch(typeof(File), "CreateNewFromState")]
	public class RemoveAlchemyMachineRecipesFromSavedStatePatch
	{
		private static bool Prefix(SavePool savePool, SavedState savedState)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Ex.RunSafe(() => SaveLoadService.RemoveAlchemyMachineRecipesFromSavedState(savePool, savedState));
		}
	}
	[HarmonyPatch(typeof(SavedState), "ToJson")]
	public class InjectSavedRecipesPatch
	{
		private static void Postfix(ref string __result)
		{
			SaveLoadService.InjectSavedRecipes(ref __result);
		}
	}
	[HarmonyPatch(typeof(File), "Load")]
	public class RetrieveStateJsonStringPatch
	{
		private static bool Prefix(File __instance)
		{
			return Ex.RunSafe(() => SaveLoadService.RetrieveStateJsonString(__instance));
		}
	}
	[HarmonyPatch(typeof(SaveLoadManager), "LoadSelectedState")]
	public class RetreiveSavedAlchemyMachineRecipesFromSavedStatePatch
	{
		private static bool Prefix(Type type)
		{
			return Ex.RunSafe(() => SaveLoadService.RetreiveSavedAlchemyMachineRecipesFromSavedState(type));
		}
	}
	[HarmonyPatch(typeof(Potion), "GetSerializedInventorySlot")]
	public class SavePotionSerializedDataPatch
	{
		private static void Postfix(SerializedInventorySlot __result, Potion __instance)
		{
			Ex.RunSafe(delegate
			{
				SaveLoadService.SavePotionSerializedData(__result, __instance);
			});
		}
	}
	[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
			{
				SaveLoadService.LoadPotionSerializedData(__result, serializedObject);
			});
		}
	}
}
namespace PotionCraftAlchemyMachineRecipes.Scripts.Storage
{
	[Serializable]
	public class SavedRecipe
	{
		[SerializeField]
		public int Index;

		[SerializeField]
		public SerializedPotionRecipe Recipe;

		public SavedRecipe(int index, SerializedPotionRecipe recipe)
		{
			Index = index;
			Recipe = recipe;
		}
	}
	public static class StaticStorage
	{
		public const string AlchemyMachineRecipesJsonSaveName = "FahlgorithmAlchemyMachineRecipes";

		public static bool CurrentlyMakingPotion;

		public static bool CurrentlyGeneratingRecipe;

		public static List<InventoryItem> Ingredients;

		public static PotionEffect[] SavedPotionEffects;

		public static Sprite PotionBackgroundSprite;

		public static Color PotionBackgroundColor;

		public static Vector2 PotionBackgroundSize;

		public static bool PotionBackgroundIsActive;

		public static List<SavedRecipe> RecipesToSave;

		public static string StateJsonString;
	}
}
namespace PotionCraftAlchemyMachineRecipes.Scripts.Services
{
	public static class AlchemyMachineProductService
	{
		public static bool BrewPotion(RecipeBookBrewPotionButton instance, RecipeBookRightPageContent rightPageContent)
		{
			if ((Object)(object)rightPageContent.pageContentPotion == (Object)null)
			{
				return true;
			}
			if (!RecipeService.IsLegendaryRecipe(rightPageContent.pageContentPotion))
			{
				return true;
			}
			MakeProduct(instance, rightPageContent);
			return false;
		}

		private static void MakeProduct(RecipeBookBrewPotionButton instance, RecipeBookRightPageContent rightPageContent)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			int availableResultPotionsCount = RecipeBook.GetAvailableResultPotionsCount(((PageContent)rightPageContent).currentState, rightPageContent.pageContentPotion);
			if (availableResultPotionsCount == 0 || (Object)(object)rightPageContent.pageContentPotion == (Object)null)
			{
				return;
			}
			int? count = ((object)instance).GetType().GetMethod("GetPotionCountForBrew", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(instance, null) as int?;
			if (count.HasValue && count != 0)
			{
				if (count > 1 && count == availableResultPotionsCount)
				{
					DarkScreen.DeactivateAll((DarkScreenDeactivationType)2, ((Book)Managers.Potion.recipeBook).layer, false, (Func<DarkScreen, bool>)null);
					Key val = new Key("#max_potion_brewing_confirmation_title", new List<string> { count.ToString() }, false);
					ConfirmationWindow.Show((DarkScreenLayer)1, val, new Key("#max_potion_brewing_confirmation_description", (List<string>)null, false), Settings<GameManagerSettings>.Asset.confirmationWindowPosition, (Action)BrewProduct, (Action)null, (DarkScreenType)1, 0f, false);
				}
				else
				{
					BrewProduct();
				}
			}
			void BrewProduct()
			{
				Potion pageContentPotion = rightPageContent.pageContentPotion;
				string text = pageContentPotion.potionFromPanel.collectedPotionEffects.LastOrDefault();
				if (!string.IsNullOrEmpty(text))
				{
					AlchemyMachineProduct val2 = AlchemyMachineProduct.GetByName(text, false, false).Clone();
					if (pageContentPotion.isTitleCustom && !string.IsNullOrWhiteSpace(pageContentPotion.customTitle) && !pageContentPotion.customTitle.Equals(((Object)val2).name))
					{
						val2.customTitle = pageContentPotion.customTitle;
					}
					if (!string.IsNullOrWhiteSpace(pageContentPotion.customDescription))
					{
						val2.customDescription = pageContentPotion.customDescription;
					}
					RecipeBook.DecreaseIngredientsAmountOnPotionBrewing(rightPageContent.pageContentPotion, count.Value);
					DecreaseLegendaryIngredientsAmmountOnBrewing(rightPageContent, count.Value);
					((UnityEvent<bool>)(object)Managers.Player.inventory.onItemChanged).Invoke(false);
					LegendarySaltPile val3 = (LegendarySaltPile)(object)((val2 is LegendarySaltPile) ? val2 : null);
					if (val3 != null)
					{
						Managers.Player.inventory.AddItem((InventoryItem)(object)val3.convertToSaltOnPickup, val3.amountOfSalt, true, true);
					}
					else
					{
						Managers.Player.inventory.AddItem((InventoryItem)(object)val2, count.Value, true, true);
					}
					int potionCountForAlchemyMachineProduct = GetPotionCountForAlchemyMachineProduct(val2);
					Goal potionBrewedFromRecipeGoal = GoalsLoader.GetGoalByName("CreatePotionFromRecipeBook", true);
					Enumerable.Range(0, potionCountForAlchemyMachineProduct).ToList().ForEach(delegate
					{
						potionBrewedFromRecipeGoal.ProgressIncrement(1);
					});
					Goal goalByName = GoalsLoader.GetGoalByName("CreateLegendarySubstance" + text, false);
					if (goalByName != null)
					{
						goalByName.ProgressIncrement(1);
					}
					Sound.Play(Settings<SoundPresetInterface>.Asset.potionFinishing, 1f, 1f, false);
					PotionManager potion = Managers.Potion;
					potion.PotionsBrewed += count.Value * potionCountForAlchemyMachineProduct;
					AlchemyMachineObject alchemyMachine = Managers.Ingredient.alchemyMachine;
					alchemyMachine.LegendarySubstancesBrewedAmount += count.Value;
				}
			}
		}

		private static void DecreaseLegendaryIngredientsAmmountOnBrewing(RecipeBookRightPageContent rightPageContent, int countToRemove)
		{
			AlchemyMachineProduct requiredProductInstance = GetRequiredAlchemyMachineProduct(rightPageContent.pageContentPotion);
			if ((Object)(object)requiredProductInstance == (Object)null || RecipeService.GetAvailableProductCount(requiredProductInstance) < countToRemove)
			{
				return;
			}
			List<KeyValuePair<InventoryItem, int>> list = ((IEnumerable<KeyValuePair<InventoryItem, int>>)Managers.Player.inventory.items).Where((KeyValuePair<InventoryItem, int> i) => i.Key is AlchemyMachineProduct && ((Object)i.Key).name == ((Object)requiredProductInstance).name).ToList();
			while (countToRemove > 0 && list.Count != 0)
			{
				KeyValuePair<InventoryItem, int> keyValuePair = list.First();
				list.Remove(keyValuePair);
				int value = keyValuePair.Value;
				if (value <= countToRemove)
				{
					((SerializableDictionaryBase<InventoryItem, int, int>)(object)Managers.Player.inventory.items).Remove(keyValuePair);
				}
				else
				{
					InventoryItemInt items = Managers.Player.inventory.items;
					InventoryItem key = keyValuePair.Key;
					((SerializableDictionaryBase<InventoryItem, int, int>)(object)items)[key] = ((SerializableDictionaryBase<InventoryItem, int, int>)(object)items)[key] - countToRemove;
				}
				countToRemove -= Mathf.Min(countToRemove, value);
			}
		}

		public static AlchemyMachineProduct GetAlchemyMachineProduct(Potion recipe)
		{
			string text = recipe.potionFromPanel.collectedPotionEffects.LastOrDefault();
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			return AlchemyMachineProduct.GetByName(text, false, false);
		}

		public static AlchemyMachineProduct GetRequiredAlchemyMachineProduct(Potion recipe)
		{
			List<string> collectedPotionEffects = recipe.potionFromPanel.collectedPotionEffects;
			string text = collectedPotionEffects[collectedPotionEffects.Count - 2];
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			return AlchemyMachineProduct.GetByName(text, false, false);
		}

		public static int GetPotionCountForAlchemyMachineProduct(AlchemyMachineProduct product)
		{
			LegendaryRecipe legendaryRecipe = GetLegendaryRecipe(product);
			if ((Object)(object)legendaryRecipe == (Object)null)
			{
				return 5;
			}
			return (from s in Enum.GetValues(typeof(Slot)).OfType<Slot>().Except((IEnumerable<Slot>)(object)new Slot[2]
				{
					(Slot)7,
					(Slot)3
				})
					.ToList()
				where (Object)(object)legendaryRecipe.DesiredItemPerSlot(s) != (Object)null
				select s).Count();
		}

		public static LegendaryRecipe GetLegendaryRecipe(AlchemyMachineProduct product)
		{
			return Managers.SaveLoad.SelectedProgressState.unlockedLegendaryRecipes.Select((string r) => LegendaryRecipe.GetByName(r, false, true)).FirstOrDefault((Func<LegendaryRecipe, bool>)((LegendaryRecipe lr) => ((Object)lr.resultItem).name == ((Object)product).name));
		}
	}
	public class RecipeService
	{
		public static bool ActuallySaveProductRecipeButton()
		{
			Potion val = GenerateRecipe();
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			Managers.Potion.recipeBook.AddRecipe(val);
			Managers.Potion.potionCraftPanel.UpdateSaveRecipeButton(false);
			Managers.Ingredient.alchemyMachine.finishLegendarySubstanceWindow.UpdateSaveProductRecipeButton();
			return true;
		}

		private static Potion GenerateRecipe()
		{
			if (StaticStorage.Ingredients == null || !StaticStorage.Ingredients.Any())
			{
				Plugin.PluginLogger.LogInfo((object)"Error: No ingredients were stored");
				Notification.ShowText("Unable to save recipe", "Some data is missing because this product was created before loading the save.", (TextType)0);
				return null;
			}
			AlchemyMachineProductItem spawnedItem = Managers.Ingredient.alchemyMachine.alchemyMachineBox.resultItemSpawner.SpawnedItem;
			List<Potion> list = StaticStorage.Ingredients.Where((InventoryItem i) => i is Potion).OfType<Potion>().ToList();
			InventoryItem val = ((IEnumerable<InventoryItem>)StaticStorage.Ingredients).FirstOrDefault((Func<InventoryItem, bool>)((InventoryItem i) => i is LegendarySubstance));
			Potion val2 = list.First();
			PotionBase potionBase2 = val2.potionBase;
			Potion recipe = Object.Instantiate<Potion>(Settings<PotionManagerSettings>.Asset.defaultPotion);
			recipe.customTitle = ((ItemFromInventory)spawnedItem).inventoryItem.GetLocalizedTitle();
			recipe.isTitleCustom = true;
			recipe.potionBase = potionBase2;
			(from p in list
				select p.potionBase into p
				group p by ((Object)p).name into pg
				select pg.First()).ToList().ForEach(delegate(PotionBase potionBase)
			{
				PotionUsedComponent.GetComponent(recipe.usedComponents, (ScriptableObject)(object)potionBase);
			});
			list.ForEach(delegate(Potion potion)
			{
				if (potion.potionFromPanel.recipeMarks.Count == 0)
				{
					Potion val3 = ((IEnumerable<Potion>)Managers.Potion.recipeBook.savedRecipes).FirstOrDefault((Func<Potion, bool>)((Potion p) => RecipeMatchesPotion(potion, p)));
					if ((Object)(object)val3 != (Object)null)
					{
						recipe.potionFromPanel.recipeMarks.AddRange(val3.potionFromPanel.recipeMarks.Select((SerializedRecipeMark m) => m.Clone()));
					}
					else
					{
						recipe.potionFromPanel.recipeMarks.Add(SerializedRecipeMark.Generate((Type)0, ((Object)potionBase2).name));
					}
				}
				else
				{
					recipe.potionFromPanel.recipeMarks.AddRange(potion.potionFromPanel.recipeMarks.Select((SerializedRecipeMark m) => m.Clone()));
				}
				potion.usedComponents.ToList().ForEach(delegate(PotionUsedComponent ingredient)
				{
					if (!(ingredient.componentObject is PotionBase))
					{
						PotionUsedComponent component2 = PotionUsedComponent.GetComponent(recipe.usedComponents, ingredient.componentObject);
						if (ingredient.componentObject is InventoryItem)
						{
							component2.amount += ingredient.amount;
						}
					}
				});
			});
			recipe.usedComponents.ForEach(delegate(PotionUsedComponent component)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Expected O, but got Unknown
				recipe.potionFromPanel.potionUsedComponents.Add(new SerializedUsedComponent
				{
					componentName = ((Object)component.componentObject).name,
					componentAmount = component.amount,
					componentType = ((object)(ComponentType)(ref component.componentType)).ToString()
				});
			});
			recipe.coloredIcon = val2.coloredIcon;
			recipe.bottle = val2.bottle;
			recipe.sticker = val2.sticker;
			recipe.soundPreset = val2.soundPreset;
			recipe.stickerAngle = val2.stickerAngle;
			recipe.Effects = val2.Effects;
			recipe.potionFromPanel.serializedPath = val2.potionFromPanel.serializedPath;
			recipe.potionFromPanel.collectedPotionEffects = val2.potionFromPanel.collectedPotionEffects;
			recipe.potionFromPanel.potionSkinSettings = val2.potionFromPanel.potionSkinSettings;
			if (recipe.potionFromPanel.collectedPotionEffects.Count > 3)
			{
				recipe.potionFromPanel.collectedPotionEffects.RemoveRange(3, recipe.potionFromPanel.collectedPotionEffects.Count - 3);
			}
			recipe.potionFromPanel.collectedPotionEffects.Add((val != null) ? ((Object)val).name : null);
			recipe.potionFromPanel.collectedPotionEffects.Add(((Object)spawnedItem).name);
			PotionUsedComponent.ClearIndexes();
			return recipe;
		}

		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;
		}

		public static bool StorePotionsBeforeWipe()
		{
			AlchemyMachineObject val = Resources.FindObjectsOfTypeAll<AlchemyMachineObject>()?.FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: Could not find AlchemyMachineObject GameObject instance");
				return true;
			}
			StaticStorage.Ingredients = (from s in val.slots
				select s.ContainedInventoryItem into i
				where (Object)(object)i != (Object)null
				select i).ToList();
			return true;
		}

		public static bool IsLegendaryRecipe(Potion recipe)
		{
			return recipe.potionFromPanel.recipeMarks.Count((SerializedRecipeMark m) => (int)m.type == 0) > 1;
		}

		public static bool SetCurrentlyMakingPotion(bool currentlyMakingPotion)
		{
			StaticStorage.CurrentlyMakingPotion = currentlyMakingPotion;
			return true;
		}

		public static bool SetCurrentlyGeneratingRecipe(bool currentlyGeneratingRecipe)
		{
			StaticStorage.CurrentlyGeneratingRecipe = currentlyGeneratingRecipe;
			return true;
		}

		public static void StoreRecipeMarksFromPotionBrew(Potion copyTo)
		{
			if (StaticStorage.CurrentlyMakingPotion && !StaticStorage.CurrentlyGeneratingRecipe)
			{
				SerializedPotionFromPanel potionFromCurrentPotion = SerializedPotionFromPanel.GetPotionFromCurrentPotion();
				Potion currentPotion = Managers.Potion.potionCraftPanel.GetCurrentPotion();
				CopyImportantInfoToPotionInstance(copyTo, currentPotion, potionFromCurrentPotion);
			}
		}

		public static void CopyImportantInfoToPotionInstance(Potion copyTo, Potion copyFrom)
		{
			CopyImportantInfoToPotionInstance(copyTo, copyFrom, copyFrom.potionFromPanel);
		}

		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))
				{
					copyTo.potionFromPanel.collectedPotionEffects.Add(((Object)val).name);
					continue;
				}
				break;
			}
		}

		public static int GetAvailableProductCount(AlchemyMachineProduct requiredProductInstance)
		{
			return ((IEnumerable<KeyValuePair<InventoryItem, int>>)Managers.Player.inventory.items).Where((KeyValuePair<InventoryItem, int> i) => ((Object)i.Key).name == ((Object)requiredProductInstance).name).Sum((KeyValuePair<InventoryItem, int> i) => i.Value);
		}

		public static bool AddLegendaryIngredientToList(RecipeBookLeftPageContent instance)
		{
			if ((Object)(object)instance.pageContentPotion == (Object)null)
			{
				return true;
			}
			FixRecipeIfBroken(instance.pageContentPotion);
			if (!IsLegendaryRecipe(instance.pageContentPotion))
			{
				return true;
			}
			AlchemyMachineProduct requiredAlchemyMachineProduct = AlchemyMachineProductService.GetRequiredAlchemyMachineProduct(instance.pageContentPotion);
			if ((Object)(object)requiredAlchemyMachineProduct != (Object)null)
			{
				PotionUsedComponent component = PotionUsedComponent.GetComponent(instance.pageContentPotion.usedComponents, (ScriptableObject)(object)requiredAlchemyMachineProduct);
				component.amount++;
			}
			PotionUsedComponent.ClearIndexes();
			return true;
		}

		public static void RemoveLegendaryIngredientFromList(RecipeBookLeftPageContent instance)
		{
			if (!((Object)(object)instance.pageContentPotion == (Object)null))
			{
				FixRecipeIfBroken(instance.pageContentPotion);
				if (IsLegendaryRecipe(instance.pageContentPotion) && instance.pageContentPotion.usedComponents.Count != 0 && instance.pageContentPotion.usedComponents.Last().componentObject is AlchemyMachineProduct)
				{
					instance.pageContentPotion.usedComponents.RemoveAt(instance.pageContentPotion.usedComponents.Count - 1);
					PotionUsedComponent.ClearIndexes();
				}
			}
		}

		private static void FixRecipeIfBroken(Potion potion)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			PotionUsedComponent val = potion.usedComponents.FirstOrDefault();
			if (val == null || !(val.componentObject is PotionBase))
			{
				potion.usedComponents.Insert(0, new PotionUsedComponent
				{
					amount = 1,
					componentObject = (ScriptableObject)(object)(potion.potionBase ?? Managers.RecipeMap.currentMap.potionBase),
					componentType = (ComponentType)1
				});
				PotionUsedComponent.ClearIndexes();
			}
		}

		public static bool RemoveRecipePotionEffects(Potion currentPotion)
		{
			if ((Object)(object)currentPotion == (Object)null || !IsLegendaryRecipe(currentPotion))
			{
				return true;
			}
			StaticStorage.SavedPotionEffects = currentPotion.Effects;
			((object)currentPotion).GetType().GetField("effects", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(currentPotion, new PotionEffect[0]);
			return true;
		}

		public static void ReAddRecipePotionEffects(Potion currentPotion)
		{
			if (!((Object)(object)currentPotion == (Object)null) && IsLegendaryRecipe(currentPotion))
			{
				((object)currentPotion).GetType().GetField("effects", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(currentPotion, StaticStorage.SavedPotionEffects);
			}
		}
	}
	public class RecipeUIService
	{
		public static MethodInfo CrucibleAtlasNameMethod;

		public static void UpdateSaveProductRecipeButton(SaveProductRecipeButton saveProductRecipeButton)
		{
			if (!((Object)(object)saveProductRecipeButton == (Object)null))
			{
				((Button)saveProductRecipeButton).Locked = false;
			}
		}

		public static bool FixLegendaryRecipeTooltipContent(Potion instance, ref TooltipContent result, int itemCount, bool anyModifierHeld)
		{
			TooltipContent productTooltip = null;
			if (Ex.RunSafe(delegate
			{
				if (!RecipeService.IsLegendaryRecipe(instance))
				{
					return true;
				}
				AlchemyMachineProduct alchemyMachineProduct = AlchemyMachineProductService.GetAlchemyMachineProduct(instance);
				productTooltip = ((InventoryItem)alchemyMachineProduct).GetTooltipContent(itemCount, (ItemsPanel)null, anyModifierHeld);
				return false;
			}) || productTooltip == null)
			{
				return true;
			}
			result = productTooltip;
			return false;
		}

		public static bool FixLegendaryRecipeBookmarkIcon(RecipeBook instance, int index)
		{
			if (instance.savedRecipes.Count <= index)
			{
				return true;
			}
			Potion val = instance.savedRecipes[index];
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (!RecipeService.IsLegendaryRecipe(val))
			{
				return true;
			}
			AlchemyMachineProduct alchemyMachineProduct = AlchemyMachineProductService.GetAlchemyMachineProduct(val);
			if ((Object)(object)alchemyMachineProduct == (Object)null)
			{
				return true;
			}
			Sprite activeMarkerIcon = alchemyMachineProduct.GetActiveMarkerIcon();
			Sprite idleMarkerIcon = alchemyMachineProduct.GetIdleMarkerIcon();
			((Book)instance).bookmarkControllersGroupController.SetBookmarkContent(index, activeMarkerIcon, idleMarkerIcon, (Sprite)null, "");
			return false;
		}

		public static void HidePotionCustomization(RecipeBookLeftPageContent instance, GameObject potionSlotBackgroundGameObject)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			SpriteRenderer component = potionSlotBackgroundGameObject.GetComponent<SpriteRenderer>();
			if ((Object)(object)StaticStorage.PotionBackgroundSprite == (Object)null)
			{
				StaticStorage.PotionBackgroundSprite = component.sprite;
				StaticStorage.PotionBackgroundColor = component.color;
				StaticStorage.PotionBackgroundSize = component.size;
				StaticStorage.PotionBackgroundIsActive = potionSlotBackgroundGameObject.activeSelf;
			}
			if ((Object)(object)instance.pageContentPotion == (Object)null)
			{
				RestorePotionSlotBackground(component);
				return;
			}
			bool flag = RecipeService.IsLegendaryRecipe(instance.pageContentPotion);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeBottleButton).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeIconButton).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeStickerButton).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeColorButton1).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeColorButton2).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeColorButton3).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.customizeColorButton4).gameObject, !flag);
			ShowHide(((Component)instance.potionCustomizationPanel.resetAllCustomizationButton).gameObject, !flag);
			ShowHide(((Component)instance.GetPotionVisualObject()).gameObject, !flag);
			if (flag)
			{
				AlchemyMachineProduct alchemyMachineProduct = AlchemyMachineProductService.GetAlchemyMachineProduct(instance.pageContentPotion);
				if (!((Object)(object)alchemyMachineProduct == (Object)null))
				{
					Sprite recipeIcon = alchemyMachineProduct.GetRecipeIcon();
					component.color = new Color(1f, 1f, 1f, 1f);
					component.sprite = recipeIcon;
					component.color = new Color(component.color.r, component.color.g, component.color.b, 1f);
					component.size *= 1.5f;
					potionSlotBackgroundGameObject.SetActive(true);
					Inventory inventory = ((ItemsPanel)((Component)((Component)instance).transform.Find("PotionBottle").Find("InventoryPanel")).GetComponent<RecipeBookPanelInventoryPanel>()).Inventory;
					inventory.RemoveItem(((IEnumerable<KeyValuePair<InventoryItem, int>>)inventory.items).First().Key, 1, true, true);
					object? value = AccessTools.Field(((object)instance).GetType(), "placeholderForPotionTooltip").GetValue(instance);
					((RecipeBookPotionPlaceholderForTooltip)((value is RecipeBookPotionPlaceholderForTooltip) ? value : null)).isInteractable = false;
				}
			}
			else
			{
				RestorePotionSlotBackground(component);
			}
		}

		private static void RestorePotionSlotBackground(SpriteRenderer potionSlotBackground)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			potionSlotBackground.color = StaticStorage.PotionBackgroundColor;
			potionSlotBackground.sprite = StaticStorage.PotionBackgroundSprite;
			potionSlotBackground.color = StaticStorage.PotionBackgroundColor;
			potionSlotBackground.size = StaticStorage.PotionBackgroundSize;
			if (((Component)potionSlotBackground).gameObject.activeSelf != StaticStorage.PotionBackgroundIsActive)
			{
				((Component)potionSlotBackground).gameObject.SetActive(StaticStorage.PotionBackgroundIsActive);
			}
		}

		private static void ShowHide(GameObject gameObject, bool show)
		{
			gameObject.SetActive(show);
		}

		public static IEnumerable<CodeInstruction> UpdateIngredientList(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo getIconAtlasNameIfUsedComponentIsProduct = AccessTools.Method(typeof(RecipeUIService), "GetIconAtlasNameIfUsedComponentIsProduct", (Type[])null, (Type[])null);
			MethodInfo getAtlasSpriteNameIfUsedComponentIsProduct = AccessTools.Method(typeof(RecipeUIService), "GetAtlasSpriteNameIfUsedComponentIsProduct", (Type[])null, (Type[])null);
			MethodInfo getItemCountIfUsedComponentIsProduct = AccessTools.Method(typeof(RecipeUIService), "GetItemCountIfUsedComponentIsProduct", (Type[])null, (Type[])null);
			new List<CodeInstruction>();
			bool modifyingGetItemCount = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.operand is MethodInfo methodInfo && methodInfo == AccessTools.Method(typeof(Managers), "get_Player", (Type[])null, (Type[])null))
				{
					modifyingGetItemCount = true;
				}
				else if (modifyingGetItemCount)
				{
					if (!(instruction.opcode == OpCodes.Ldfld) || !(instruction.operand is FieldInfo fieldInfo) || !(fieldInfo == AccessTools.Field(typeof(PlayerManager), "inventory")))
					{
						if (instruction.opcode == OpCodes.Callvirt)
						{
							modifyingGetItemCount = false;
							yield return new CodeInstruction(OpCodes.Call, (object)getItemCountIfUsedComponentIsProduct);
						}
						else
						{
							yield return instruction;
						}
					}
				}
				else if (instruction.opcode == OpCodes.Ldloc_1)
				{
					yield return new CodeInstruction(OpCodes.Ldloc_S, (object)6);
					yield return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)getIconAtlasNameIfUsedComponentIsProduct);
				}
				else if (instruction.operand is MethodInfo methodInfo2 && methodInfo2 == AccessTools.Method(typeof(IngredientsAtlasGenerator), "GetAtlasSpriteName", (Type[])null, (Type[])null))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)getAtlasSpriteNameIfUsedComponentIsProduct);
				}
				else
				{
					yield return instruction;
				}
			}
		}

		private static int GetItemCountIfUsedComponentIsProduct(InventoryItem item)
		{
			AlchemyMachineProduct val = (AlchemyMachineProduct)(object)((item is AlchemyMachineProduct) ? item : null);
			if (val == null)
			{
				return Managers.Player.inventory.GetItemCount(item);
			}
			return RecipeService.GetAvailableProductCount(val);
		}

		public static string GetIconAtlasNameIfUsedComponentIsProduct(PotionUsedComponent usedComponent, string oldIngredientsAtlasName)
		{
			if (!(usedComponent.componentObject is AlchemyMachineProduct))
			{
				return oldIngredientsAtlasName;
			}
			? val = Plugin.PluginLogger;
			ScriptableObject componentObject = usedComponent.componentObject;
			((ManualLogSource)val).LogMessage((object)(((Object)((componentObject is AlchemyMachineProduct) ? componentObject : null)).name + " - "));
			return Settings<TMPManagerSettings>.Asset.IconsAtlasName;
		}

		public static string GetAtlasSpriteNameIfUsedComponentIsProduct(ScriptableObject componentObject)
		{
			if (!(componentObject is AlchemyMachineProduct))
			{
				return IngredientsAtlasGenerator.GetAtlasSpriteName(componentObject);
			}
			if (((Object)componentObject).name == "PhilosophersStone")
			{
				return "Philosopher'sStone";
			}
			return ((Object)componentObject).name;
		}

		public static void DisableContinueFromHereButton(RecipeBookContinuePotionBrewingButton instance, RecipeBookRightPageContent rightPageContent)
		{
			if (!((Object)(object)rightPageContent.pageContentPotion == (Object)null) && RecipeService.IsLegendaryRecipe(rightPageContent.pageContentPotion))
			{
				((Button)instance).Locked = true;
			}
		}

		public static void ChangeBrewPotionButtonCount(ref int result, Potion currentPotion)
		{
			try
			{
				if ((Object)(object)currentPotion == (Object)null || !RecipeService.IsLegendaryRecipe(currentPotion))
				{
					return;
				}
				AlchemyMachineProduct requiredAlchemyMachineProduct = AlchemyMachineProductService.GetRequiredAlchemyMachineProduct(currentPotion);
				if ((Object)(object)requiredAlchemyMachineProduct != (Object)null)
				{
					int availableProductCount = RecipeService.GetAvailableProductCount(requiredAlchemyMachineProduct);
					if (availableProductCount < result)
					{
						result = availableProductCount;
					}
				}
			}
			catch (Exception ex)
			{
				Ex.LogException(ex);
			}
		}

		public static bool FixPotionIconException(ref Icon result, string iconName)
		{
			Icon tempResult = null;
			bool result2 = Ex.RunSafe(delegate
			{
				if (string.IsNullOrEmpty(iconName))
				{
					tempResult = Icon.allIcons.FirstOrDefault();
					return false;
				}
				return true;
			});
			result = tempResult;
			return result2;
		}
	}
	public class SaveLoadService
	{
		public static bool RemoveAlchemyMachineRecipesFromSavedState(SavePool savePool, SavedState savedState)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)savePool != 0 && (int)savePool != -1)
			{
				ProgressState val = (ProgressState)(object)((savedState is ProgressState) ? savedState : null);
				if (val != null)
				{
					List<int> list = new List<int>();
					List<Potion> savedRecipes = Managers.Potion.recipeBook.savedRecipes;
					for (int i = 0; i < savedRecipes.Count; i++)
					{
						Potion val2 = savedRecipes[i];
						if ((Object)(object)val2 != (Object)null && RecipeService.IsLegendaryRecipe(val2))
						{
							list.Add(i);
						}
					}
					List<SavedRecipe> list2 = new List<SavedRecipe>();
					for (int j = 0; j < val.savedRecipes.Count; j++)
					{
						if (list.Contains(j))
						{
							list2.Add(new SavedRecipe(j, val.savedRecipes[j]));
							val.savedRecipes[j] = null;
						}
					}
					StaticStorage.RecipesToSave = list2;
					goto IL_00ca;
				}
			}
			StaticStorage.RecipesToSave = null;
			goto IL_00ca;
			IL_00ca:
			return true;
		}

		public static void InjectSavedRecipes(ref string result)
		{
			string modifiedResult = null;
			string savedStateJson = result;
			Ex.RunSafe(delegate
			{
				if (StaticStorage.RecipesToSave != null)
				{
					StringBuilder sbRecipes = new StringBuilder();
					sbRecipes.Append('[');
					bool firstRecipe = true;
					StaticStorage.RecipesToSave.ForEach(delegate(SavedRecipe recipe)
					{
						if (!firstRecipe)
						{
							sbRecipes.Append(',');
						}
						firstRecipe = false;
						sbRecipes.Append(JsonUtility.ToJson((object)recipe, false));
					});
					sbRecipes.Append(']');
					string value = string.Format(",\"{0}\":{1}", "FahlgorithmAlchemyMachineRecipes", sbRecipes);
					int startIndex = savedStateJson.LastIndexOf('}');
					modifiedResult = savedStateJson.Insert(startIndex, value);
					StaticStorage.RecipesToSave = null;
				}
			});
			if (!string.IsNullOrEmpty(modifiedResult))
			{
				result = modifiedResult;
			}
		}

		public static bool RetrieveStateJsonString(File instance)
		{
			StaticStorage.StateJsonString = instance.StateJsonString;
			return true;
		}

		public static bool RetreiveSavedAlchemyMachineRecipesFromSavedState(Type type)
		{
			if (type != typeof(ProgressState))
			{
				return true;
			}
			ProgressState selectedProgressState = Managers.SaveLoad.SelectedProgressState;
			string stateJsonString = StaticStorage.StateJsonString;
			StaticStorage.StateJsonString = null;
			if (string.IsNullOrEmpty(stateJsonString))
			{
				Plugin.PluginLogger.LogInfo((object)"Error: stateJsonString is empty. Cannot load alchemy machine recipes");
				return true;
			}
			int num = stateJsonString.IndexOf("FahlgorithmAlchemyMachineRecipes");
			if (num == -1)
			{
				Plugin.PluginLogger.LogInfo((object)"No existing alchemy machine recipes found during load");
				return true;
			}
			int num2 = stateJsonString.IndexOf('[', num);
			if (num2 == -1)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: alchemy machine recipes are not formed correctly. No alchemy machine recipes will be loaded (bad start index).");
				return true;
			}
			int endJsonIndex = GetEndJsonIndex(stateJsonString, num2, useBrackets: true);
			if (endJsonIndex >= stateJsonString.Length)
			{
				Plugin.PluginLogger.LogInfo((object)"Error: alchemy machine recipes are not formed correctly. No alchemy machine recipes will be loaded (bad end index).");
				return true;
			}
			string text = stateJsonString.Substring(num2, endJsonIndex - num2);
			if (text.Length <= 2)
			{
				Plugin.PluginLogger.LogInfo((object)"No existing alchemy machine recipes found during load");
				return true;
			}
			List<SavedRecipe> list = new List<SavedRecipe>();
			int num3 = 0;
			while (num3 == 0 || text[num3] == ',')
			{
				int num4 = num3 + 1;
				num3 = GetEndJsonIndex(text, num4, useBrackets: false);
				SavedRecipe savedRecipe = JsonUtility.FromJson<SavedRecipe>(text.Substring(num4, num3 - num4));
				if (savedRecipe == null)
				{
					Plugin.PluginLogger.LogInfo((object)"Error: alchemy machine recipes are not in sync with save file. Some alchemy machine recipes may have been loaded (failed to deserialize recipe).");
					break;
				}
				list.Add(savedRecipe);
			}
			foreach (SavedRecipe item in list)
			{
				if (selectedProgressState.savedRecipes.Count <= item.Index)
				{
					Plugin.PluginLogger.LogInfo((object)$"Error: alchemy machine recipes are not in sync with save file. Some alchemy machine recipes may have been loaded (index out of bounds: {item.Index}).");
					return true;
				}
				if (!string.IsNullOrEmpty(selectedProgressState.savedRecipes[item.Index].data))
				{
					Plugin.PluginLogger.LogInfo((object)$"Error: alchemy machine recipes are not in sync with save file. Some alchemy machine recipes may have been loaded (indexed recipe not null  {item.Index}).");
					return true;
				}
				Plugin.PluginLogger.LogInfo((object)$"Loaded recipe at index {item.Index}");
				selectedProgressState.savedRecipes[item.Index] = item.Recipe;
			}
			return true;
		}

		public 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);
			}
		}

		public 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;
		}
	}
}