Decompiled source of REPO Alchemy v1.1.1

REPOAlchemy.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomDiscoverStateLib;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using REPOLib.Objects.Sdk;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("REPOAlchemy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("My first plugin")]
[assembly: AssemblyTitle("REPOAlchemy")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOAlchemy
{
	public class AlchemyItem : MonoBehaviour
	{
		[HideInInspector]
		public bool spawnAsValuable = true;

		[HideInInspector]
		public string prefabID;

		public Color color = Color.white;

		[HideInInspector]
		public PhotonView photon;

		public Sprite icon;

		[HideInInspector]
		public bool wasCrafted = false;

		public float potScale = 1f;

		[HideInInspector]
		public bool isOnSource = false;

		public bool itemPersistent = false;

		public bool itemPersisting = true;

		private void Start()
		{
			photon = ((Component)this).GetComponent<PhotonView>();
			if (wasCrafted && (Object)(object)((Component)this).GetComponent<ItemAttributes>() != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).GetComponent<ItemAttributes>());
			}
		}

		[PunRPC]
		public void SetWasCraftedRPC(bool val)
		{
			wasCrafted = val;
			if (wasCrafted && (Object)(object)((Component)this).GetComponent<ItemAttributes>() != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).GetComponent<ItemAttributes>());
			}
		}

		[PunRPC]
		public void AddGrowerRPC(float scale, float speed)
		{
			GrowScale growScale = ((Component)this).GetComponent<GrowScale>();
			if ((Object)(object)growScale == (Object)null)
			{
				growScale = ((Component)this).gameObject.AddComponent<GrowScale>();
			}
			growScale.targetScale = scale;
			growScale.speed = speed;
		}

		[PunRPC]
		public void SyncScaleRPC(Vector3 scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = scale;
		}
	}
	public class Cauldron : MonoBehaviour
	{
		public struct Recipe
		{
			public Color color;

			public List<string> ingredients;

			public string result;

			public Sprite icon;

			public bool isIngredient;

			public Recipe(List<string> Ingredients, string Result, Sprite Icon, Color Col, bool isIngredient)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				ingredients = Ingredients;
				result = Result;
				icon = Icon;
				color = Col;
				this.isIngredient = isIngredient;
			}
		}

		[CompilerGenerated]
		private sealed class <Restock>d__71 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Cauldron <>4__this;

			private List<ObjectSource>.Enumerator <>s__1;

			private ObjectSource <source>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Restock>d__71(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__1 = default(List<ObjectSource>.Enumerator);
				<source>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Expected O, but got Unknown
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.restocking = true;
					<>4__this.restockStacks++;
					if (SemiFunc.IsMultiplayer() && SemiFunc.IsMasterClient())
					{
						<>4__this.photon.RPC("RestockRPC", (RpcTarget)1, Array.Empty<object>());
					}
					<>4__this.PlayRestock();
					<>2__current = (object)new WaitForSeconds(0.35f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>s__1 = <>4__this.sources.GetEnumerator();
					try
					{
						while (<>s__1.MoveNext())
						{
							<source>5__2 = <>s__1.Current;
							<>4__this.RestockItem(<source>5__2);
							<source>5__2 = null;
						}
					}
					finally
					{
						((IDisposable)<>s__1).Dispose();
					}
					<>s__1 = default(List<ObjectSource>.Enumerator);
					<>4__this.CheckIndicators();
					<>2__current = (object)new WaitForSeconds(0.525f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>4__this.restockStacks--;
					if (<>4__this.restockStacks == 0)
					{
						<>4__this.restocking = false;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Cauldron instance;

		private Rigidbody rb;

		private PhysGrabObjectGrabArea handle;

		private Vector3 oldVel = Vector3.zero;

		private float shakeAmount = 0f;

		private float shakeDecay = 20f;

		private float shakeMax = 70f;

		private Animator animator;

		private bool restocking = false;

		private PhotonView photon;

		private Transform shakeIndicator;

		private SpriteRenderer spriteRenderer;

		private List<SpriteRenderer> indicators;

		private float lidOpenDuration = 0f;

		private List<string> sourceIDs = new List<string>();

		private ItemEquippable equippable;

		private int inventoryPage = 0;

		private Dictionary<string, int> inventory = new Dictionary<string, int>();

		private List<string> inventoryOrder = new List<string>();

		public AudioClip openSound;

		public AudioClip closeSound;

		public AudioClip restockSound;

		public List<AudioClip> shakeSounds;

		public static List<Recipe> recipes = new List<Recipe>();

		public List<ObjectSource> sources = new List<ObjectSource>();

		private List<AlchemyItem> itemsInPot = new List<AlchemyItem>();

		private Recipe activeRecipe;

		private bool lidOpen;

		private float checkCooldown = 0f;

		private bool oldEquipped = false;

		private bool oldState = false;

		private List<Ingredient> funneledIngredients = new List<Ingredient>();

		private float finishLightPower = 0f;

		private float shakeSoundCooldown = 0f;

		private int restockStacks = 0;

		private void Start()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			Transform val = ((Component)this).transform.Find("Model/Cauldron/Armature/Root/RackFlap/Racks");
			indicators = new List<SpriteRenderer>
			{
				((Component)val.Find("RackLeft/Indicator.000")).GetComponent<SpriteRenderer>(),
				((Component)val.Find("Indicator.001")).GetComponent<SpriteRenderer>(),
				((Component)val.Find("Indicator.002")).GetComponent<SpriteRenderer>(),
				((Component)val.Find("RackRight/Indicator.003")).GetComponent<SpriteRenderer>()
			};
			equippable = ((Component)this).GetComponent<ItemEquippable>();
			shakeIndicator = ((Component)this).transform.Find("Model/Cauldron/Armature/Root/ResultScreen/ShakeIcon");
			spriteRenderer = ((Component)((Component)this).transform.Find("Model/Cauldron/Armature/Root/ResultScreen/PotionSprite")).GetComponent<SpriteRenderer>();
			photon = ((Component)this).GetComponent<PhotonView>();
			animator = ((Component)((Component)this).transform.Find("Model/Cauldron")).GetComponent<Animator>();
			handle = ((Component)this).GetComponent<PhysGrabObjectGrabArea>();
			rb = ((Component)this).GetComponent<Rigidbody>();
			CheckIndicators();
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			foreach (ObjectSource source in sources)
			{
				source.objectUnlocked.AddListener(new UnityAction(OnIngredientGrab));
			}
			List<string> storeableIngredients = Tools.storeableIngredients;
			for (int i = 0; i < storeableIngredients.Count; i++)
			{
				if (StatsManager.instance.dictionaryOfDictionaries["ingredients"].ContainsKey(storeableIngredients[i]))
				{
					SetIngredient(storeableIngredients[i], Math.Min(StatsManager.instance.dictionaryOfDictionaries["ingredients"][storeableIngredients[i]], 2));
					StatsManager.instance.dictionaryOfDictionaries["ingredients"][storeableIngredients[i]] = inventory[storeableIngredients[i]];
				}
				if (SemiFunc.RunIsShop() || SemiFunc.RunIsArena() || Plugin.unlimitedIngredients.Value)
				{
					SetIngredient(storeableIngredients[i], -1);
				}
			}
			TryRestock();
		}

		private void OnIngredientGrab()
		{
			for (int i = 0; i < sources.Count; i++)
			{
				if ((Object)(object)sources[i].obj == (Object)null && sources[i].prefabID != null && sources[i].prefabID != "")
				{
					string id = Tools.TryGetKey(Tools.ingredients, sources[i].prefabID);
					ReduceIngredient(id);
				}
			}
			TryRestock();
		}

		private List<PhysGrabObject> ObjectsInCart()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)((Component)this).GetComponent<PhysGrabCart>().physGrabInCart).transform;
			Collider[] array = Physics.OverlapBox(transform.position, transform.localScale / 2f, transform.rotation);
			List<PhysGrabObject> list = new List<PhysGrabObject>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if (((Component)val).gameObject.layer == LayerMask.NameToLayer("PhysGrabObject"))
				{
					PhysGrabObject componentInParent = ((Component)val).GetComponentInParent<PhysGrabObject>();
					if (!Enumerable.Contains(list, componentInParent))
					{
						list.Add(componentInParent);
					}
				}
			}
			return list;
		}

		private Dictionary<string, int> IngredientDictionary(List<string> ingredients)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (string ingredient in ingredients)
			{
				if (dictionary.ContainsKey(ingredient))
				{
					dictionary[ingredient]++;
				}
				else
				{
					dictionary.Add(ingredient, 1);
				}
			}
			return dictionary;
		}

		private bool CheckIngredients(List<string> ingredients1, List<string> ingredients2)
		{
			if (ingredients1.Count != ingredients2.Count)
			{
				return false;
			}
			Dictionary<string, int> dictionary = IngredientDictionary(ingredients1);
			Dictionary<string, int> dictionary2 = IngredientDictionary(ingredients2);
			foreach (string key in dictionary.Keys)
			{
				if (!dictionary2.ContainsKey(key))
				{
					return false;
				}
				if (dictionary[key] != dictionary2[key])
				{
					return false;
				}
			}
			return true;
		}

		private void GetRecipe()
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			List<PhysGrabObject> list = ObjectsInCart();
			List<string> list2 = new List<string>();
			List<AlchemyItem> list3 = new List<AlchemyItem>(itemsInPot);
			itemsInPot.Clear();
			foreach (PhysGrabObject item in list)
			{
				Ingredient component = ((Component)item).GetComponent<Ingredient>();
				if ((Object)(object)component != (Object)null)
				{
					list2.Add(component.ingredientID);
				}
				AlchemyItem component2 = ((Component)item).GetComponent<AlchemyItem>();
				if ((Object)(object)component2 != (Object)null)
				{
					itemsInPot.Add(component2);
				}
			}
			activeRecipe = default(Recipe);
			foreach (Recipe recipe in recipes)
			{
				if (CheckIngredients(recipe.ingredients, list2))
				{
					SetColor(recipe.color);
					activeRecipe = recipe;
					break;
				}
			}
			UpdateIcon(activeRecipe);
			foreach (AlchemyItem item2 in list3)
			{
				if (!((Object)(object)item2 == (Object)null) && !itemsInPot.Contains(item2))
				{
					item2.AddGrowerRPC(1f, 3f);
					if (SemiFunc.IsMultiplayer())
					{
						item2.photon.RPC("AddGrowerRPC", (RpcTarget)1, new object[2] { 1f, 3f });
					}
				}
			}
			foreach (AlchemyItem item3 in itemsInPot)
			{
				if (!((Object)(object)item3 == (Object)null) && !list3.Contains(item3))
				{
					item3.AddGrowerRPC(item3.potScale, 3f);
					if (SemiFunc.IsMultiplayer())
					{
						item3.photon.RPC("AddGrowerRPC", (RpcTarget)1, new object[2] { item3.potScale, 3f });
					}
				}
			}
		}

		private void SetColor(Color color)
		{
			//IL_0016: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			((Component)((Component)this).transform.Find("ShakeParticles")).GetComponent<ParticleSystem>().startColor = color;
			((Component)((Component)this).transform.Find("FinishParticles")).GetComponent<ParticleSystem>().startColor = color;
			((Component)((Component)this).transform.Find("ShakeLight")).GetComponent<Light>().color = color;
			((Component)((Component)this).transform.Find("FinishLight")).GetComponent<Light>().color = color;
		}

		private void Open()
		{
			if (shakeAmount / shakeMax > 0.6f)
			{
				FinishEffect();
			}
			ShakeLoop(0f);
			animator.SetBool("Opened", true);
			((Component)this).GetComponent<AudioSource>().clip = openSound;
			((Component)this).GetComponent<AudioSource>().Play();
		}

		private void Close()
		{
			animator.SetBool("Opened", false);
			((Component)this).GetComponent<AudioSource>().clip = closeSound;
			((Component)this).GetComponent<AudioSource>().Play();
		}

		private void PlayRestock()
		{
			animator.SetTrigger("Restock");
			((Component)this).GetComponent<AudioSource>().clip = restockSound;
			((Component)this).GetComponent<AudioSource>().Play();
		}

		[PunRPC]
		private void SetOpenRPC(bool state)
		{
			if ((Object)(object)animator != (Object)null)
			{
				if (state)
				{
					Open();
				}
				else
				{
					Close();
				}
			}
			((Component)((Component)this).transform.Find("Cart Wall Collider Close")).gameObject.SetActive(!state);
			((Component)((Component)this).transform.Find("Cart Wall Collider Open")).gameObject.SetActive(state);
		}

		[PunRPC]
		private void RestockRPC()
		{
			if ((Object)(object)animator != (Object)null)
			{
				PlayRestock();
			}
		}

		private void FixedUpdate()
		{
			//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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (checkCooldown <= 0f)
			{
				checkCooldown = 0.5f;
				GetRecipe();
			}
			checkCooldown -= Time.fixedDeltaTime;
			UpdateLight();
			((Component)shakeIndicator).gameObject.SetActive(activeRecipe.result != null);
			if (activeRecipe.result != null)
			{
				Vector3 localPosition = shakeIndicator.localPosition;
				localPosition.x = (float)Math.Sin(Time.time * 30f) * 0.0002f;
				Quaternion localRotation = shakeIndicator.localRotation;
				shakeIndicator.SetLocalPositionAndRotation(localPosition, localRotation);
			}
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			UpdatePage();
			UpdateEquipped();
			bool flag = handle.listOfAllGrabbers.Any();
			bool flag2 = activeRecipe.result == null || !flag;
			if (flag2 != lidOpen)
			{
				lidOpen = flag2;
				if (flag2)
				{
					Open();
				}
				else
				{
					Close();
				}
				((Component)((Component)this).transform.Find("Cart Wall Collider Close")).gameObject.SetActive(!flag2);
				((Component)((Component)this).transform.Find("Cart Wall Collider Open")).gameObject.SetActive(flag2);
				if (SemiFunc.IsMultiplayer())
				{
					photon.RPC("SetOpenRPC", (RpcTarget)1, new object[1] { flag2 });
				}
			}
			foreach (ObjectSource source in sources)
			{
				if ((Object)(object)source.obj != (Object)null)
				{
					((Component)source.obj).GetComponent<Rigidbody>().detectCollisions = lidOpenDuration > 0.7f && !restocking;
				}
			}
			if (flag2)
			{
				lidOpenDuration += Time.fixedDeltaTime;
				UpdateFunnel();
			}
			else
			{
				lidOpenDuration = 0f;
			}
			UpdateShake(flag2, activeRecipe);
		}

		private void UpdateEquipped()
		{
			if (equippable.IsEquipped() == oldEquipped || restocking)
			{
				return;
			}
			if (equippable.IsEquipped())
			{
				foreach (ObjectSource source in sources)
				{
					if ((Object)(object)source.obj != (Object)null)
					{
						((Component)source.obj).GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
					}
				}
			}
			else
			{
				TryRestock();
			}
			oldEquipped = equippable.IsEquipped();
		}

		private void UpdatePage()
		{
			ItemToggle component = ((Component)this).GetComponent<ItemToggle>();
			if (component.toggleState != oldState)
			{
				oldState = component.toggleState;
				inventoryPage++;
				CheckPage();
				TryRestock();
			}
			oldState = component.toggleState;
		}

		private void CheckPage()
		{
			inventoryPage %= Math.Max((inventory.Count + sources.Count - 1) / sources.Count, 1);
		}

		private void UpdateIcon(Recipe recipe)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			((Component)spriteRenderer).gameObject.SetActive(recipe.result != null);
			((Component)shakeIndicator).GetComponent<SpriteRenderer>().color = (recipe.isIngredient ? new Color(0.65f, 0f, 1f) : new Color(1f, 0.55f, 0f));
			if (recipe.result != null)
			{
				spriteRenderer.sprite = recipe.icon;
			}
		}

		private void UpdateFunnel()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)this).transform.Find("InFunnel");
			Collider[] array = Physics.OverlapBox(val.position, val.localScale / 2f, val.rotation);
			Collider[] array2 = array;
			foreach (Collider val2 in array2)
			{
				if (((Component)val2).gameObject.layer != LayerMask.NameToLayer("PhysGrabObject"))
				{
					continue;
				}
				Ingredient componentInParent = ((Component)val2).GetComponentInParent<Ingredient>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.canStore && componentInParent.IsRegistered() && (Object)(object)((Component)componentInParent).GetComponent<GrowScale>() == (Object)null && !componentInParent.isOnSource)
				{
					GrowScale growScale = ((Component)componentInParent).gameObject.AddComponent<GrowScale>();
					growScale.targetScale = 0.1f;
					growScale.speed = 5f;
					if (SemiFunc.IsMultiplayer())
					{
						((Component)componentInParent).GetComponent<PhotonView>().RPC("AddGrowerRPC", (RpcTarget)1, new object[2] { 0.1f, 5f });
					}
					if (!funneledIngredients.Contains(componentInParent))
					{
						funneledIngredients.Add(componentInParent);
					}
				}
			}
			foreach (Ingredient funneledIngredient in funneledIngredients)
			{
				if ((Object)(object)funneledIngredient == (Object)null)
				{
					funneledIngredients.Remove(funneledIngredient);
					break;
				}
				if (((Component)funneledIngredient).transform.localScale.x == 0.1f)
				{
					funneledIngredient.AddIngredient();
					AddIngredient(funneledIngredient.ingredientID);
					((Component)funneledIngredient).GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
				}
			}
		}

		private void AddIngredient(string id)
		{
			if (inventory.ContainsKey(id))
			{
				if (inventory[id] >= 0)
				{
					inventory[id]++;
				}
			}
			else
			{
				inventoryOrder.Add(id);
				inventory.Add(id, 1);
			}
			TryRestock();
		}

		private void ReduceIngredient(string id)
		{
			if (inventory.ContainsKey(id))
			{
				inventory[id]--;
			}
			CheckIngredients();
		}

		private void SetIngredient(string id, int value)
		{
			if (inventory.ContainsKey(id))
			{
				inventory[id] = value;
				return;
			}
			inventoryOrder.Add(id);
			inventory.Add(id, value);
		}

		private void CheckIngredients()
		{
			foreach (string item in inventory.Keys.ToList())
			{
				if (inventory[item] == 0)
				{
					inventory.Remove(item);
					inventoryOrder.Remove(item);
				}
			}
			CheckPage();
		}

		private void ShakeLoop(float t)
		{
			ShakeLoopRPC(t);
			if (SemiFunc.IsMultiplayer())
			{
				photon.RPC("ShakeLoopRPC", (RpcTarget)1, new object[1] { t });
			}
		}

		[PunRPC]
		private void ShakeLoopRPC(float t)
		{
			AudioSource component = ((Component)((Component)this).transform.Find("ShakeLoop1")).GetComponent<AudioSource>();
			AudioSource component2 = ((Component)((Component)this).transform.Find("ShakeLoop2")).GetComponent<AudioSource>();
			Light component3 = ((Component)((Component)this).transform.Find("ShakeLight")).GetComponent<Light>();
			ParticleSystem component4 = ((Component)((Component)this).transform.Find("ShakeParticles")).GetComponent<ParticleSystem>();
			component4.loop = t > 0.6f;
			if (component4.loop)
			{
				component4.Play();
			}
			component.volume = Mathf.Clamp(t * 3f, 0f, 1f);
			component.pitch = 1f + t * 0.5f;
			component2.volume = Mathf.Clamp((t - 0.6f) * 5f, 0f, 1f);
			component2.pitch = 1f + t * 0.5f;
			component3.intensity = t * 2f;
		}

		private void ShakeSound()
		{
			ShakeSoundRPC();
			if (SemiFunc.IsMultiplayer())
			{
				photon.RPC("ShakeSoundRPC", (RpcTarget)1, Array.Empty<object>());
			}
		}

		[PunRPC]
		public void ShakeSoundRPC()
		{
			AudioSource component = ((Component)((Component)this).transform.Find("ShakeSound")).GetComponent<AudioSource>();
			component.PlayOneShot(shakeSounds[Random.RandomRangeInt(0, shakeSounds.Count)]);
		}

		private void FinishEffect()
		{
			FinishEffectRPC();
			if (SemiFunc.IsMultiplayer())
			{
				photon.RPC("FinishEffectRPC", (RpcTarget)1, Array.Empty<object>());
			}
		}

		[PunRPC]
		public void FinishEffectRPC()
		{
			((Component)((Component)this).transform.Find("FinishParticles")).GetComponent<ParticleSystem>().Play();
			finishLightPower = 1.5f;
		}

		private void UpdateLight()
		{
			finishLightPower = Mathf.Clamp(finishLightPower - Time.fixedDeltaTime, 0f, 1f);
			((Component)((Component)this).transform.Find("FinishLight")).GetComponent<Light>().intensity = finishLightPower * 2f;
		}

		private void UpdateShake(bool lidOpen, Recipe recipe)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = oldVel - rb.velocity;
			float magnitude = ((Vector3)(ref val)).magnitude;
			oldVel = rb.velocity;
			shakeAmount -= shakeDecay * Time.fixedDeltaTime;
			if (!lidOpen)
			{
				shakeAmount += magnitude;
				if (shakeAmount >= shakeMax)
				{
					Craft(recipe);
				}
				float num = magnitude / Time.fixedDeltaTime;
				if (num > 50f && shakeSoundCooldown <= 0f)
				{
					shakeSoundCooldown = 0.3f;
					ShakeSound();
				}
				shakeSoundCooldown -= Time.fixedDeltaTime;
				ShakeLoop(shakeAmount / shakeMax);
				shakeAmount = Mathf.Clamp(shakeAmount, 0f, shakeMax);
			}
		}

		private void FinishSound()
		{
			FinishSoundRPC();
			if (SemiFunc.IsMultiplayer())
			{
				photon.RPC("FinishSoundRPC", (RpcTarget)1, Array.Empty<object>());
			}
		}

		[PunRPC]
		public void FinishSoundRPC()
		{
			((Component)((Component)this).transform.Find("FinishSound")).GetComponent<AudioSource>().Play();
		}

		private void Craft(Recipe recipe)
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			FinishEffect();
			FinishSound();
			shakeAmount = 0f;
			foreach (PhysGrabObject item in ObjectsInCart())
			{
				Ingredient component = ((Component)item).GetComponent<Ingredient>();
				if ((Object)(object)component != (Object)null)
				{
					component.UseIngredient();
				}
				if ((Object)(object)((Component)item).GetComponent<EnemyRigidbody>() != (Object)null)
				{
					((Component)((Component)item).transform.parent).GetComponentInChildren<EnemyHealth>().Hurt(500, Vector3.up);
				}
				else if ((Object)(object)((Component)item).GetComponent<PlayerTumble>() == (Object)null && (Object)(object)((Component)item).GetComponent<PlayerDeathHead>() == (Object)null)
				{
					ItemAttributes component2 = ((Component)item).GetComponent<ItemAttributes>();
					if ((Object)(object)component2 != (Object)null && component.itemPersisting)
					{
						StatsManager.instance.ItemRemove(component2.item.itemAssetName);
					}
					item.DestroyPhysGrabObject();
				}
				if ((Object)(object)((Component)item).GetComponent<PlayerTumble>() != (Object)null)
				{
					((Component)item).GetComponent<PlayerTumble>().playerAvatar.playerHealth.Hurt(100, false, -1);
				}
			}
			Transform val = ((Component)this).transform.Find("ResultSpawn");
			GameObject val2 = NetworkPrefabs.SpawnNetworkPrefab(recipe.result, val.position, val.rotation, (byte)0, (object[])null);
			MonoBehaviour.print((object)("Crafted " + ((Object)val2).name));
			AlchemyItem component3 = val2.GetComponent<AlchemyItem>();
			val2.transform.localScale = Vector3.one * component3.potScale;
			if (SemiFunc.IsMultiplayer())
			{
				((Component)component3).GetComponent<PhotonView>().RPC("SyncScaleRPC", (RpcTarget)1, Array.Empty<object>());
			}
			ItemAttributes component4 = val2.GetComponent<ItemAttributes>();
			component3.itemPersisting = (Object)(object)component4 != (Object)null && component3.itemPersistent;
			if (component3.itemPersisting)
			{
				StatsManager.instance.ItemPurchase(component4.item.itemAssetName);
			}
			if (Object.op_Implicit((Object)(object)val2.GetComponent<ValuableObject>()))
			{
				val2.GetComponent<ValuableObject>().valuePreset = Plugin.craftedValue;
			}
		}

		public void TryRestock()
		{
			CheckIngredients();
			for (int i = 0; i < sources.Count; i++)
			{
				int num = i + sources.Count * inventoryPage;
				if (inventoryOrder.Count > num)
				{
					string key = inventoryOrder[num];
					sources[i].prefabID = Tools.ingredients[key];
				}
				else
				{
					sources[i].prefabID = null;
				}
			}
			CheckIndicators();
			if (CanRestock())
			{
				((MonoBehaviour)this).StartCoroutine(Restock());
			}
		}

		private bool CanRestock()
		{
			foreach (ObjectSource source in sources)
			{
				if (source.CanSpawn())
				{
					return true;
				}
			}
			return false;
		}

		[IteratorStateMachine(typeof(<Restock>d__71))]
		private IEnumerator Restock()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Restock>d__71(0)
			{
				<>4__this = this
			};
		}

		private void RestockItem(ObjectSource source)
		{
			if (source.prefabID == null && (Object)(object)source.obj != (Object)null)
			{
				((Component)source.obj).GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
			}
			AlchemyItem alchemyItem = source.SpawnObject();
			if (!((Object)(object)alchemyItem == (Object)null))
			{
				alchemyItem.wasCrafted = true;
				if (SemiFunc.IsMultiplayer())
				{
					((Component)alchemyItem).GetComponent<PhotonView>().RPC("SetWasCraftedRPC", (RpcTarget)1, new object[1] { true });
				}
			}
		}

		private void CheckIndicators()
		{
			for (int i = 0; i < sources.Count; i++)
			{
				int num = 0;
				if (sources[i].prefabID != null && sources[i].prefabID != "")
				{
					string key = Tools.TryGetKey(Tools.ingredients, sources[i].prefabID);
					num = inventory[key] - 1;
				}
				SetIndicatorRPC(i, num, Plugin.maxIngredientsTransferred.Value);
				if (SemiFunc.IsMasterClient())
				{
					photon.RPC("SetIndicatorRPC", (RpcTarget)1, new object[3]
					{
						i,
						num,
						Plugin.maxIngredientsTransferred.Value
					});
				}
			}
		}

		[PunRPC]
		public void SetIndicatorRPC(int indicator, int count, int max)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			SpriteRenderer val = indicators[indicator];
			((Component)val).gameObject.SetActive(count != 0);
			if (count > 0)
			{
				val.color = new Color(1f, 0.55f, 0f, 1f);
			}
			else if (count < 0)
			{
				val.color = new Color(0.95f, 0.23f, 1f, 1f);
			}
			if (count >= max)
			{
				val.color = new Color(0.8f, 0f, 0f, 1f);
			}
		}
	}
	public class GrowScale : MonoBehaviour
	{
		public float speed = 1f;

		public float targetScale = 1f;

		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			float x = ((Component)this).transform.localScale.x;
			x = Mathf.MoveTowards(x, targetScale, Time.deltaTime * speed);
			((Component)this).transform.localScale = Vector3.one * x;
			if (x == targetScale)
			{
				Object.Destroy((Object)(object)this);
			}
		}
	}
	public class Ingredient : AlchemyItem
	{
		public string ingredientID;

		public bool canStore = true;

		[HideInInspector]
		public bool wasStored = false;

		public bool storeOnExtract = true;

		public float storedScale = 0.75f;

		public bool ingredientHighlighting;

		private void Start()
		{
			photon = ((Component)this).GetComponent<PhotonView>();
			Dictionary<string, int> dictionary = StatsManager.instance.dictionaryOfDictionaries["ingredients"];
			if (!dictionary.ContainsKey(ingredientID))
			{
				dictionary.Add(ingredientID, 0);
			}
			if ((Object)(object)((Component)this).transform.parent != (Object)null)
			{
				ObjectSource component = ((Component)((Component)this).transform.parent).GetComponent<ObjectSource>();
				if ((Object)(object)component != (Object)null)
				{
					wasStored = true;
				}
			}
		}

		public void AddIngredient()
		{
			if (!wasStored)
			{
				StatsManager.instance.dictionaryOfDictionaries["ingredients"][ingredientID]++;
				wasStored = true;
			}
		}

		public void UseIngredient()
		{
			if (wasStored && !SemiFunc.RunIsShop())
			{
				StatsManager.instance.dictionaryOfDictionaries["ingredients"][ingredientID]--;
			}
		}

		public bool IsRegistered()
		{
			return Tools.ingredients.ContainsKey(ingredientID);
		}

		public static Ingredient ConvertToIngredient(AlchemyItem obj)
		{
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			bool flag = obj.spawnAsValuable;
			string text = obj.prefabID;
			Color val = obj.color;
			PhotonView val2 = obj.photon;
			Sprite val3 = obj.icon;
			float num = obj.potScale;
			bool flag2 = obj.itemPersistent;
			GameObject gameObject = ((Component)obj).gameObject;
			Object.Destroy((Object)(object)obj);
			Ingredient ingredient = gameObject.AddComponent<Ingredient>();
			ingredient.spawnAsValuable = flag;
			ingredient.prefabID = text;
			ingredient.color = val;
			ingredient.photon = val2;
			ingredient.icon = val3;
			ingredient.potScale = num;
			ingredient.itemPersistent = flag2;
			return ingredient;
		}
	}
	public class ObjectSource : MonoBehaviour
	{
		public bool spawnAsValuable = false;

		public string prefabID;

		public AlchemyItem obj;

		private float objectRemovedDuration = 0f;

		private bool objectRemoved = false;

		public UnityEvent objectUnlocked = new UnityEvent();

		public bool CanSpawn()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return false;
			}
			if ((Object)(object)obj != (Object)null && obj.prefabID == prefabID)
			{
				return false;
			}
			if ((prefabID == null || prefabID == "") && (Object)(object)obj == (Object)null)
			{
				return false;
			}
			return true;
		}

		public AlchemyItem SpawnObject()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSpawn())
			{
				return null;
			}
			if (prefabID == null)
			{
				return null;
			}
			if ((Object)(object)obj != (Object)null)
			{
				((Component)obj).GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
			}
			obj = NetworkPrefabs.SpawnNetworkPrefab(prefabID, ((Component)this).transform.position, ((Component)this).transform.rotation, (byte)0, (object[])null).GetComponent<AlchemyItem>();
			((Component)obj).transform.parent = ((Component)this).transform;
			((Component)obj).transform.localScale = Vector3.one * ((Component)obj).GetComponent<Ingredient>().storedScale;
			((Component)obj).GetComponent<AlchemyItem>().isOnSource = true;
			((Component)obj).GetComponent<ValuableObject>().valuePreset = Plugin.craftedValue;
			Rigidbody component = ((Component)obj).GetComponent<Rigidbody>();
			objectRemoved = false;
			objectRemovedDuration = 0f;
			ValuableObject component2 = ((Component)obj).GetComponent<ValuableObject>();
			NotValuableObject component3 = ((Component)obj).GetComponent<NotValuableObject>();
			return obj;
		}

		public void UnlockObject()
		{
			if (!((Object)(object)obj == (Object)null))
			{
				objectRemoved = true;
				((Component)obj).GetComponent<AlchemyItem>().isOnSource = false;
				Rigidbody component = ((Component)obj).GetComponent<Rigidbody>();
				((Component)obj).transform.parent = null;
				obj.AddGrowerRPC(1f, 1f);
				if (SemiFunc.IsMultiplayer())
				{
					((Component)obj).GetComponent<PhotonView>().RPC("AddGrowerRPC", (RpcTarget)1, new object[2] { 1f, 1f });
				}
				obj = null;
				objectUnlocked.Invoke();
			}
		}

		private void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (objectRemoved)
			{
				objectRemovedDuration += Time.deltaTime;
			}
			if ((Object)(object)obj != (Object)null)
			{
				if (SemiFunc.IsMasterClient())
				{
					((Component)obj).GetComponent<PhotonView>().RPC("SyncScaleRPC", (RpcTarget)1, new object[1] { ((Component)obj).transform.lossyScale });
				}
				Rigidbody component = ((Component)obj).GetComponent<Rigidbody>();
				if (!component.isKinematic)
				{
					component.velocity = Vector3.zero;
					component.angularVelocity = Vector3.zero;
				}
				((Component)obj).GetComponent<PhysGrabObject>().OverrideIndestructible(0.1f);
				((Component)obj).transform.rotation = ((Component)this).transform.rotation;
				((Component)obj).transform.position = ((Component)this).transform.position;
				if (((Component)obj).GetComponent<PhysGrabObject>().grabbed)
				{
					UnlockObject();
				}
			}
		}
	}
	[HarmonyPatch(typeof(StatsManager), "Start")]
	internal class StatsManagerPatchStart
	{
		private static void Prefix()
		{
			StatsManager.instance.dictionaryOfDictionaries.Add("ingredients", new Dictionary<string, int>());
		}
	}
	[HarmonyPatch(typeof(StatsManager), "RunStartStats")]
	internal class StatsManagerStartStatsPatch
	{
		private static void Postfix()
		{
			if (Plugin.startWithCauldron.Value)
			{
				StatsManager.instance.ItemPurchase(((Component)Cauldron.instance).GetComponent<ItemAttributes>().item.itemAssetName);
			}
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "DestroyTheFirstPhysObjectsInHaulList")]
	internal class ExtractionPointPatch
	{
		private static void Prefix()
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				Ingredient component = RoundDirector.instance.dollarHaulList[0].GetComponent<Ingredient>();
				if ((Object)(object)component != (Object)null && component.storeOnExtract)
				{
					component.AddIngredient();
				}
			}
		}
	}
	[HarmonyPatch(typeof(ValuableDirector), "SetupHost")]
	internal class ValuableDirectorPatch
	{
		private static void Postfix()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ingredientSpawnsMax.Value <= 0)
			{
				return;
			}
			List<ValuableVolume> list = Object.FindObjectsOfType<ValuableVolume>(false).ToList();
			list = list.FindAll((ValuableVolume x) => (int)x.VolumeType == 0);
			ListExtension.Shuffle<ValuableVolume>((IList<ValuableVolume>)list);
			if (list.Count == 0)
			{
				return;
			}
			if (Tools.spawnableIngredients.Count == 0)
			{
				MonoBehaviour.print((object)"No ingredients registered. Install a mod that adds ingredients.");
				return;
			}
			int num = Random.Range(Plugin.ingredientSpawnsMin.Value, Plugin.ingredientSpawnsMax.Value + 1);
			int num2 = 0;
			List<string> list2 = new List<string>(Tools.spawnableIngredients);
			ListExtension.Shuffle<string>((IList<string>)list2);
			MonoBehaviour.print((object)("Attempting to spawn " + num + " ingredients."));
			foreach (ValuableVolume item in list)
			{
				bool flag = true;
				Collider[] array = Physics.OverlapBox(((Component)item).transform.position, Vector3.one * 0.25f, Quaternion.identity);
				Collider[] array2 = array;
				foreach (Collider val in array2)
				{
					if ((Object)(object)((Component)val).GetComponentInParent<PhysGrabObject>() != (Object)null)
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					int index = ((num2 >= 3) ? Random.Range(0, Tools.spawnableIngredients.Count) : (num2 % list2.Count));
					string text = Tools.ingredients[list2[index]];
					GameObject val2 = NetworkPrefabs.SpawnNetworkPrefab(text, ((Component)item).transform.position, ((Component)item).transform.rotation, (byte)0, (object[])null);
					num2++;
				}
				if (num2 >= num)
				{
					MonoBehaviour.print((object)("Successfully spawned all " + num + " potion ingredients!"));
					return;
				}
			}
			MonoBehaviour.print((object)("Not enough space for all ingredients. Spawned " + num2 + " ingredients."));
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "Discover")]
	internal class IngredientDiscoverPatch
	{
		private static void Postfix(ValuableObject __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)__instance).GetComponent<Ingredient>() != (Object)null)
			{
				ValuableDiscover.instance.New(((Component)__instance).GetComponent<PhysGrabObject>(), Plugin.ingredientDiscoverState);
			}
		}
	}
	[HarmonyPatch(typeof(Map), "AddValuable")]
	internal class IngredientDiscoverMapPatch
	{
		private static bool Prefix(ValuableObject _valuable)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)((Component)_valuable).GetComponent<Ingredient>()))
			{
				MapCustom val = ((Component)_valuable).gameObject.AddComponent<MapCustom>();
				val.sprite = Plugin.mapIcon;
				val.color = new Color(0.21f, 0f, 1f);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Valuables), "RegisterInitialValuables")]
	internal class ValuableRegisterPatch
	{
		private static void Postfix()
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			List<Tools.QueuedIngredient> list = new List<Tools.QueuedIngredient>(Tools.queuedIngredients);
			foreach (Tools.QueuedIngredient item in list)
			{
				if (!item.isItem)
				{
					GameObject gameObject = ((Component)Valuables.GetValuableThatContainsName(item.name)).gameObject;
					Ingredient ingredient = gameObject.AddComponent<Ingredient>();
					ingredient.ingredientID = item.ingredientID;
					ingredient.canStore = item.canStore;
					ingredient.storeOnExtract = item.storeOnExtract && ingredient.canStore;
					ingredient.potScale = item.potScale;
					ingredient.storedScale = item.storedScale;
					Tools.RegisterIngredient(ingredient, item.canSpawn);
					Tools.queuedIngredients.Remove(item);
				}
			}
			List<Tools.QueuedRecipe> list2 = new List<Tools.QueuedRecipe>(Tools.queuedRecipes);
			foreach (Tools.QueuedRecipe item2 in list2)
			{
				if (!item2.isItem)
				{
					GameObject gameObject2 = ((Component)Valuables.GetValuableThatContainsName(item2.name)).gameObject;
					AlchemyItem alchemyItem = (((Object)(object)gameObject2.GetComponent<AlchemyItem>() != (Object)null) ? gameObject2.GetComponent<AlchemyItem>() : gameObject2.AddComponent<AlchemyItem>());
					alchemyItem.color = item2.color;
					alchemyItem.icon = item2.icon;
					alchemyItem.itemPersistent = item2.itemPersist;
					alchemyItem.potScale = item2.potScale;
					Tools.RegisterRecipe(item2.ingredients, alchemyItem);
					Tools.queuedRecipes.Remove(item2);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Items), "RegisterItems")]
	internal class ItemRegisterPatch
	{
		private static void Postfix()
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			List<Tools.QueuedIngredient> list = new List<Tools.QueuedIngredient>(Tools.queuedIngredients);
			foreach (Tools.QueuedIngredient item in list)
			{
				if (item.isItem)
				{
					GameObject prefab = Items.GetItemThatContainsName(item.name).prefab;
					Ingredient ingredient = prefab.AddComponent<Ingredient>();
					ingredient.ingredientID = item.ingredientID;
					ingredient.canStore = item.canStore;
					ingredient.storeOnExtract = item.storeOnExtract && ingredient.canStore;
					ingredient.potScale = item.potScale;
					ingredient.storedScale = item.storedScale;
					Tools.RegisterIngredient(ingredient, item.canSpawn);
					Tools.queuedIngredients.Remove(item);
				}
			}
			List<Tools.QueuedRecipe> list2 = new List<Tools.QueuedRecipe>(Tools.queuedRecipes);
			foreach (Tools.QueuedRecipe item2 in list2)
			{
				if (item2.isItem)
				{
					GameObject prefab2 = Items.GetItemThatContainsName(item2.name).prefab;
					AlchemyItem alchemyItem = (((Object)(object)prefab2.GetComponent<AlchemyItem>() != (Object)null) ? prefab2.GetComponent<AlchemyItem>() : prefab2.AddComponent<AlchemyItem>());
					alchemyItem.color = item2.color;
					alchemyItem.icon = item2.icon;
					alchemyItem.itemPersistent = item2.itemPersist;
					alchemyItem.potScale = item2.potScale;
					Tools.RegisterRecipe(item2.ingredients, alchemyItem);
					Tools.queuedRecipes.Remove(item2);
				}
			}
		}
	}
	[BepInPlugin("REPOAlchemy", "REPOAlchemy", "0.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("REPO.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static ConfigEntry<bool> unlimitedIngredients;

		public static ConfigEntry<int> ingredientSpawnsMax;

		public static ConfigEntry<int> ingredientSpawnsMin;

		public static ConfigEntry<int> maxIngredientsTransferred;

		public static ConfigEntry<bool> startWithCauldron;

		public static ConfigEntry<bool> purchaseableCauldron;

		public static ConfigEntry<int> cauldronMinPrice;

		public static ConfigEntry<int> cauldronMaxPrice;

		public static Value craftedValue;

		public static Sprite mapIcon;

		public static State ingredientDiscoverState;

		private Harmony harmony = new Harmony("REPOAlchemy");

		private AssetBundle assetBundle;

		private void Awake()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			SetUpConfigs();
			assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "repoalchemy"));
			ingredientDiscoverState = CustomDiscoverState.AddNewDiscoverGraphic(new Color(0.41f, 0.2f, 1f, 0.075f), new Color(0.41f, 0.2f, 1f, 0.75f));
			mapIcon = assetBundle.LoadAsset<Sprite>("Assets/Mods/REPOAlchemy/Map Icon Small.png");
			craftedValue = assetBundle.LoadAsset<Value>("Assets/Mods/REPOAlchemy/Cauldron/Value - Ingredient.asset");
			LoadCauldron();
			harmony.PatchAll();
			Logger.LogInfo((object)"Plugin REPOAlchemy is loaded!");
		}

		private void SetUpConfigs()
		{
			unlimitedIngredients = ((BaseUnityPlugin)this).Config.Bind<bool>("Ingredients", "Unlimited Ingredients (CHEAT)", false, "Should the POT provide unlimited ingredients");
			ingredientSpawnsMax = ((BaseUnityPlugin)this).Config.Bind<int>("Ingredients", "Ingredients Spawn Max", 4, "The maximum amount of ingredients to spawn per level");
			ingredientSpawnsMin = ((BaseUnityPlugin)this).Config.Bind<int>("Ingredients", "Ingredients Spawn Min", 1, "The minimum amount of ingredients to spawn per level");
			maxIngredientsTransferred = ((BaseUnityPlugin)this).Config.Bind<int>("Ingredients", "Max Ingredients Transferred", 2, "The maximum number of ingredients that can be transferred between levels");
			startWithCauldron = ((BaseUnityPlugin)this).Config.Bind<bool>("Cauldron", "Start With Cauldron", true, "Start each game with a P.O.T.");
			purchaseableCauldron = ((BaseUnityPlugin)this).Config.Bind<bool>("Cauldron", "Purchaseable Cauldron", true, "Should the P.O.T. be purchaseable\nOnly works if Start With Cauldron is false");
			cauldronMinPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Cauldron", "Cauldron Min Price", 3500, "Minimum price the P.O.T. should cost (before multipliers)\nDefault is identical to the Pocket C.A.R.T.");
			cauldronMaxPrice = ((BaseUnityPlugin)this).Config.Bind<int>("Cauldron", "Cauldron Max Price", 4500, "Maximum price the P.O.T. should cost (before multipliers)\nDefault is identical to the Pocket C.A.R.T.");
		}

		private void LoadCauldron()
		{
			GameObject val = assetBundle.LoadAsset<GameObject>("Assets/Mods/REPOAlchemy/Cauldron/Cauldron.prefab");
			Cauldron cauldron = val.AddComponent<Cauldron>();
			Item val2 = assetBundle.LoadAsset<Item>("Assets/Mods/REPOAlchemy/Cauldron/Cauldron.asset");
			val2.prefab = val;
			Cauldron.instance = cauldron;
			val.GetComponent<ItemAttributes>().item.value.valueMin = cauldronMinPrice.Value;
			val.GetComponent<ItemAttributes>().item.value.valueMax = cauldronMaxPrice.Value;
			Transform val3 = val.transform.Find("Model/Cauldron/Armature/Root/RackFlap/Racks");
			cauldron.sources.Add(((Component)val3.Find("RackLeft/RackSurfaceLeft/Slot.000")).gameObject.AddComponent<ObjectSource>());
			cauldron.sources.Add(((Component)val3.Find("RackSurfaceCenter/Slot.001")).gameObject.AddComponent<ObjectSource>());
			cauldron.sources.Add(((Component)val3.Find("RackSurfaceCenter/Slot.002")).gameObject.AddComponent<ObjectSource>());
			cauldron.sources.Add(((Component)val3.Find("RackRight/RackSurfaceRight/Slot.003")).gameObject.AddComponent<ObjectSource>());
			cauldron.openSound = assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Open1.ogg");
			cauldron.closeSound = assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Close1.ogg");
			cauldron.restockSound = assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Restock1.ogg");
			cauldron.shakeSounds = new List<AudioClip>
			{
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake1.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake2.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake3.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake4.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake5.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake6.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake7.ogg"),
				assetBundle.LoadAsset<AudioClip>("Assets/Mods/REPOAlchemy/Cauldron/Shake8.ogg")
			};
			if (purchaseableCauldron.Value || startWithCauldron.Value)
			{
				Items.RegisterItem(val2);
			}
			Logger.LogInfo((object)"Cauldron Loaded!");
		}
	}
	public class PluginInfo
	{
		public const string PLUGIN_GUID = "REPOAlchemy";

		public const string PLUGIN_NAME = "REPOAlchemy";

		public const string PLUGIN_VERSION = "0.0.0";
	}
	public class Tools
	{
		public struct QueuedIngredient
		{
			public string name;

			public string ingredientID;

			public bool canSpawn;

			public bool canStore;

			public bool storeOnExtract;

			public float potScale;

			public float storedScale;

			public bool isItem;
		}

		public struct QueuedRecipe
		{
			public string name;

			public Sprite icon;

			public Color color;

			public List<string> ingredients;

			public bool itemPersist;

			public float potScale;

			public bool isItem;
		}

		public static List<string> spawnableIngredients = new List<string>();

		public static Dictionary<string, string> ingredients = new Dictionary<string, string>();

		public static List<string> storeableIngredients = new List<string>();

		public static List<QueuedIngredient> queuedIngredients = new List<QueuedIngredient>();

		public static List<QueuedRecipe> queuedRecipes = new List<QueuedRecipe>();

		public static void RegisterIngredient(Ingredient ingredient, bool canSpawn = true)
		{
			NetworkPrefabs.RegisterNetworkPrefab(((Component)ingredient).gameObject);
			ingredients.Add(ingredient.ingredientID, ((Object)((Component)ingredient).gameObject).name);
			ingredient.prefabID = ((Object)((Component)ingredient).gameObject).name;
			if (canSpawn)
			{
				spawnableIngredients.Add(ingredient.ingredientID);
			}
			if (ingredient.canStore)
			{
				storeableIngredients.Add(ingredient.ingredientID);
			}
		}

		public static void RegisterIngredientByValuableName(string valuableName, string ingredientID, bool canSpawn = true, bool canStore = true, bool storeOnExtract = false, float potScale = 1f, float storedScale = 0.75f)
		{
			QueuedIngredient item = default(QueuedIngredient);
			item.name = valuableName;
			item.ingredientID = ingredientID;
			item.canSpawn = canSpawn;
			item.canStore = canStore;
			item.storeOnExtract = storeOnExtract;
			item.isItem = false;
			item.potScale = potScale;
			item.storedScale = storedScale;
			queuedIngredients.Add(item);
		}

		public static void RegisterIngredientByItemName(string itemName, string ingredientID, bool canSpawn = true, bool canStore = true, bool storeOnExtract = false, float potScale = 1f, float storedScale = 0.75f)
		{
			QueuedIngredient item = default(QueuedIngredient);
			item.name = itemName;
			item.ingredientID = ingredientID;
			item.canSpawn = canSpawn;
			item.canStore = canStore;
			item.storeOnExtract = storeOnExtract;
			item.isItem = true;
			item.potScale = potScale;
			item.storedScale = storedScale;
			queuedIngredients.Add(item);
		}

		public static void RegisterRecipe(List<string> ingredients, AlchemyItem result)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)((Component)result).gameObject).name;
			if (!NetworkPrefabs.HasNetworkPrefab(name))
			{
				NetworkPrefabs.RegisterNetworkPrefab(((Component)result).gameObject);
			}
			Cauldron.recipes.Add(new Cauldron.Recipe(ingredients, name, result.icon, result.color, (Object)(object)((Component)result).GetComponent<Ingredient>() != (Object)null));
		}

		public static void RegisterRecipeByItemName(string itemName, List<string> ingredients, Sprite icon, Color color, bool itemPersist = false, float potScale = 1f)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			QueuedRecipe item = default(QueuedRecipe);
			item.name = itemName;
			item.icon = icon;
			item.color = color;
			item.ingredients = ingredients;
			item.itemPersist = itemPersist;
			item.isItem = true;
			item.potScale = potScale;
			queuedRecipes.Add(item);
		}

		public static void RegisterRecipeByValuableName(string valuableName, List<string> ingredients, Sprite icon, Color color, bool itemPersist = false, float potScale = 1f)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			QueuedRecipe item = default(QueuedRecipe);
			item.name = valuableName;
			item.icon = icon;
			item.color = color;
			item.ingredients = ingredients;
			item.itemPersist = itemPersist;
			item.isItem = false;
			item.potScale = potScale;
			queuedRecipes.Add(item);
		}

		public static TKey? TryGetKey<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TValue value)
		{
			foreach (KeyValuePair<TKey, TValue> item in dictionary)
			{
				if (object.Equals(item.Value, value))
				{
					return item.Key;
				}
			}
			return default(TKey);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "REPOAlchemy";

		public const string PLUGIN_NAME = "My first plugin";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace REPOAlchemy.Development
{
	[CreateAssetMenu(menuName = "REPOAlchemy/Existing Item Ingredient", order = 2, fileName = "New Item Ingredient")]
	public class ExistingItemIngredientContent : Content
	{
		public string itemName = "Grenade Explosive";

		public string ingredientID;

		public bool canStore = false;

		public bool useIngredientSpawning = false;

		public bool storeOnExtract = false;

		public float potScale = 1f;

		public float storedScale = 0.75f;

		public override string Name => "Ingredient" + itemName;

		public override void Initialize(Mod mod)
		{
			Tools.RegisterIngredientByItemName(itemName, ingredientID, useIngredientSpawning, canStore, storeOnExtract, potScale, storedScale);
		}
	}
	[CreateAssetMenu(menuName = "REPOAlchemy/External Item Recipe", order = 5, fileName = "New Item Recipe")]
	public class ExistingItemRecipeContent : Content
	{
		public string itemName = "Grenade Explosive";

		public List<string> ingredients = new List<string>();

		public Color recipeColor = Color.magenta;

		public Sprite recipeIcon;

		public bool itemPersist = false;

		public float potScale = 1f;

		public override string Name => "Recipe" + itemName;

		public override void Initialize(Mod mod)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Tools.RegisterRecipeByItemName(itemName, ingredients, recipeIcon, recipeColor, itemPersist, potScale);
		}
	}
	[CreateAssetMenu(menuName = "REPOAlchemy/External Valuable Ingredient", order = 1, fileName = "New Valuable Ingredient")]
	public class ExistingValuableIngredientContent : Content
	{
		public string valuableName = "Diamond";

		public string ingredientID;

		public bool canStore = false;

		public bool useIngredientSpawning = false;

		public bool storeOnExtract = false;

		public float potScale = 1f;

		public float storedScale = 0.75f;

		public override string Name => "Ingredient" + valuableName;

		public override void Initialize(Mod mod)
		{
			Tools.RegisterIngredientByValuableName(valuableName, ingredientID, useIngredientSpawning, canStore, storeOnExtract, potScale, storedScale);
		}
	}
	[CreateAssetMenu(menuName = "REPOAlchemy/External Valuable Recipe", order = 4, fileName = "New Valuable Recipe")]
	public class ExistingValuableRecipeContent : Content
	{
		public string valuableName = "Diamond";

		public List<string> ingredients = new List<string>();

		public Color recipeColor = Color.magenta;

		public Sprite recipeIcon;

		public float potScale = 1f;

		public override string Name => "Recipe" + valuableName;

		public override void Initialize(Mod mod)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Tools.RegisterRecipeByValuableName(valuableName, ingredients, recipeIcon, recipeColor, itemPersist: false, potScale);
		}
	}
	[CreateAssetMenu(menuName = "REPOAlchemy/Ingredient", order = 0, fileName = "New Ingredient")]
	public class IngredientContent : Content
	{
		public Ingredient prefab;

		public bool useIngredientSpawning = true;

		public override string Name
		{
			get
			{
				Ingredient ingredient = prefab;
				return "Ingredient" + ((Object)ingredient).name;
			}
		}

		public override void Initialize(Mod mod)
		{
			Tools.RegisterIngredient(prefab, useIngredientSpawning);
		}
	}
	[CreateAssetMenu(menuName = "REPOAlchemy/Recipe", order = 3, fileName = "New Recipe")]
	public class RecipeContent : Content
	{
		public AlchemyItem resultPrefab;

		public List<string> ingredients = new List<string>();

		public override string Name
		{
			get
			{
				AlchemyItem alchemyItem = resultPrefab;
				return "Recipe" + ((Object)alchemyItem).name;
			}
		}

		public override void Initialize(Mod mod)
		{
			Tools.RegisterRecipe(ingredients, resultPrefab);
		}
	}
}