Decompiled source of REPO Alchemy v1.0.3

REPOAlchemy.dll

Decompiled 2 days 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.Extensions;
using REPOLib.Modules;
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.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
	{
		public bool spawnAsValuable = true;

		public string prefabID;

		public Color color = Color.white;

		public PhotonView photon;

		public Sprite icon;

		public bool wasCrafted = false;

		private void Start()
		{
			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).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 Recipe(List<string> Ingredients, string Result, Sprite Icon, Color Col)
			{
				//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;
			}
		}

		[CompilerGenerated]
		private sealed class <Restock>d__66 : 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__66(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_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Expected O, but got Unknown
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.restocking = true;
					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.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>();

		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 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 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(TryRestock));
			}
			List<string> list = Tools.ingredients.Keys.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (StatsManager.instance.dictionaryOfDictionaries["ingredients"].ContainsKey(list[i]))
				{
					inventory.Add(list[i], Math.Min(StatsManager.instance.dictionaryOfDictionaries["ingredients"][list[i]], 2));
					StatsManager.instance.dictionaryOfDictionaries["ingredients"][list[i]] = inventory[list[i]];
				}
				if (SemiFunc.RunIsShop() || SemiFunc.RunIsArena() || Plugin.unlimitedIngredients.Value)
				{
					inventory[list[i]] = -1;
				}
			}
			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_009f: Unknown result type (might be due to invalid IL or missing references)
			List<PhysGrabObject> list = ObjectsInCart();
			List<string> list2 = new List<string>();
			foreach (PhysGrabObject item in list)
			{
				Ingredient component = ((Component)item).GetComponent<Ingredient>();
				if ((Object)(object)component != (Object)null)
				{
					list2.Add(component.ingredientID);
				}
			}
			activeRecipe = default(Recipe);
			foreach (Recipe recipe in recipes)
			{
				if (CheckIngredients(recipe.ingredients, list2))
				{
					SetColor(recipe.color);
					activeRecipe = recipe;
					break;
				}
			}
			UpdateIcon(activeRecipe);
		}

		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)
			{
				if (equippable.IsEquipped())
				{
					foreach (ObjectSource source in sources)
					{
						if ((Object)(object)source.obj != (Object)null)
						{
							AddIngredient(((Component)source.obj).GetComponent<Ingredient>().ingredientID);
							((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 = (inventoryPage + 1) % Math.Max((inventory.Count + sources.Count - 1) / sources.Count, 1);
				TryRestock();
			}
			oldState = component.toggleState;
		}

		private void UpdateIcon(Recipe recipe)
		{
			((Component)spriteRenderer).gameObject.SetActive(recipe.result != null);
			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_0175: 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 && (Object)(object)((Component)componentInParent).GetComponent<GrowScale>() == (Object)null)
				{
					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
			{
				inventory.Add(id, 1);
			}
			TryRestock();
		}

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

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

		private void CheckIngredients()
		{
			foreach (string item in inventory.Keys.ToList())
			{
				if (inventory[item] == 0)
				{
					inventory.Remove(item);
				}
			}
			inventoryPage = Math.Min(inventoryPage, (inventory.Count + sources.Count - 1) / sources.Count);
		}

		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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
				{
					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);
			val2.GetComponent<AlchemyItem>().spawnAsValuable = false;
			if (Object.op_Implicit((Object)(object)val2.GetComponent<ValuableObject>()))
			{
				val2.GetComponent<ValuableObject>().valuePreset = Plugin.craftedValue;
			}
		}

		public void TryRestock()
		{
			string id = default(string);
			for (int i = 0; i < sources.Count; i++)
			{
				if ((Object)(object)sources[i].obj == (Object)null && sources[i].prefabID != null && sources[i].prefabID != "")
				{
					DictionaryExtensions.TryGetKey<string, string>(Tools.ingredients, sources[i].prefabID, ref id);
					ReduceIngredient(id);
				}
			}
			CheckIngredients();
			for (int j = 0; j < sources.Count; j++)
			{
				int num = j + sources.Count * inventoryPage;
				if (inventory.Keys.Count > num)
				{
					string key = inventory.Keys.ToList()[num];
					sources[j].prefabID = Tools.ingredients[key];
				}
				else
				{
					sources[j].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__66))]
		private IEnumerator Restock()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Restock>d__66(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()
		{
			string key = default(string);
			for (int i = 0; i < sources.Count; i++)
			{
				int num = 0;
				if (sources[i].prefabID != null && sources[i].prefabID != "")
				{
					DictionaryExtensions.TryGetKey<string, string>(Tools.ingredients, sources[i].prefabID, ref key);
					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 wasStored = false;

		private void Start()
		{
			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;
				MonoBehaviour.print((object)(ingredientID + " count is now " + StatsManager.instance.dictionaryOfDictionaries["ingredients"][ingredientID]));
			}
		}

		public void UseIngredient()
		{
			if (wasStored && !SemiFunc.RunIsShop())
			{
				StatsManager.instance.dictionaryOfDictionaries["ingredients"][ingredientID]--;
				MonoBehaviour.print((object)(ingredientID + " count is now " + StatsManager.instance.dictionaryOfDictionaries["ingredients"][ingredientID]));
			}
		}
	}
	public class ObjectSource : MonoBehaviour
	{
		public bool spawnAsValuable = false;

		public string prefabID;

		public AlchemyItem obj;

		public float objectScale = 0.75f;

		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_00af: 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 * objectScale;
			if (SemiFunc.IsMultiplayer())
			{
				((Component)obj).GetComponent<PhotonView>().RPC("AddGrowerRPC", (RpcTarget)1, new object[2] { objectScale, 9999f });
			}
			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;
				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.AddIngredient();
				}
			}
		}
	}
	[HarmonyPatch(typeof(ValuableDirector), "SetupHost")]
	internal class ValuableDirectorPatch
	{
		private static void Postfix()
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			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;
			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 = Random.Range(0, Tools.spawnableIngredients.Count);
					string text = Tools.ingredients[Tools.spawnableIngredients[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;
		}
	}
	[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 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 cauldron \nDisabling this setting allows the cauldron to spawn in the shop");
		}

		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;
			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")
			};
			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 static List<string> spawnableIngredients = new List<string>();

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

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

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