Decompiled source of BigMixer v1.1.0

BigMixer_IL2CPP.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BigMixer;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.NPCs.CharacterClasses;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.Stations;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BigMixerMod), "Mixing Station Mk3", "1.1.0", "Ashton", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BigMixer_IL2CPP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BigMixer_IL2CPP")]
[assembly: AssemblyTitle("BigMixer_IL2CPP")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BigMixer
{
	public class BigMixerMod : MelonMod
	{
		public const string ItemId = "mixingstationmk3";

		public const string ItemName = "Mixing Station Mk3";

		public const int Capacity = 40;

		internal static Instance Log;

		internal static MelonPreferences_Entry<float> Price;

		internal static MelonPreferences_Entry<bool> DevDump;

		public override void OnInitializeMelon()
		{
			Log = ((MelonBase)this).LoggerInstance;
			MelonPreferences_Category obj = MelonPreferences.CreateCategory("MixingStationMk3", "Mixing Station Mk3");
			Price = obj.CreateEntry<float>("Price", 8000f, "Price", "Purchase price at Oscar's warehouse.", false, false, (ValueValidator)null, (string)null);
			DevDump = obj.CreateEntry<bool>("DevDump", false, "Dev dump", "Log the Mk2 prefab hierarchy and materials on load.", false, false, (ValueValidator)null, (string)null);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!(sceneName != "Main"))
			{
				Mk3Station.Clear();
				try
				{
					Mk3Factory.EnsureRegistered();
				}
				catch (Exception ex)
				{
					Log.Error("Failed to register Mixing Station Mk3: " + ex);
					return;
				}
				MelonCoroutines.Start(AddToOscarWhenReady());
			}
		}

		public override void OnUpdate()
		{
			Mk3Station.UpdateAll(Time.deltaTime);
		}

		private static IEnumerator AddToOscarWhenReady()
		{
			float timeout = Time.realtimeSinceStartup + 300f;
			while (Time.realtimeSinceStartup < timeout)
			{
				if ((!Singleton<LoadManager>.InstanceExists || !Singleton<LoadManager>.Instance.IsLoading) && OscarShop.TryAddListing())
				{
					yield break;
				}
				yield return (object)new WaitForSeconds(1f);
			}
			Log.Warning("Gave up waiting for Oscar's shop; Mk3 not listed this session.");
		}
	}
	internal static class Compat
	{
		public static T As<T>(Il2CppObjectBase obj) where T : Il2CppObjectBase
		{
			if (obj != null)
			{
				return obj.TryCast<T>();
			}
			return default(T);
		}

		public static Action Combine(Action a, Action b)
		{
			Delegate val = Delegate.Combine((Delegate)(object)a, (Delegate)(object)b);
			if (!(val == (Delegate)null))
			{
				return ((Il2CppObjectBase)val).Cast<Action>();
			}
			return null;
		}

		public static Action Remove(Action a, Action b)
		{
			Delegate val = Delegate.Remove((Delegate)(object)a, (Delegate)(object)b);
			if (!(val == (Delegate)null))
			{
				return ((Il2CppObjectBase)val).Cast<Action>();
			}
			return null;
		}

		public static Action Action(Action a)
		{
			return Action.op_Implicit(a);
		}

		public static List<ItemSlot> SlotList(params ItemSlot[] slots)
		{
			List<ItemSlot> val = new List<ItemSlot>();
			foreach (ItemSlot val2 in slots)
			{
				val.Add(val2);
			}
			return val;
		}

		public static void CreateListingUI(ShopInterface shop, ShopListing listing)
		{
			shop.CreateListingUI(listing);
		}

		public static void RefreshShownItems(ShopInterface shop)
		{
			shop.RefreshShownItems();
		}

		public static void StationContentsChanged(MixingStationInterface ui)
		{
			ui.StationContentsChanged();
		}

		public static MixingStationData GetData(MixingStationLoader loader, string mainPath)
		{
			return ((BuildableItemLoader)loader).GetData<MixingStationData>(mainPath);
		}
	}
	internal static class Mk3Factory
	{
		private static GameObject holder;

		private static MixingStationMk2 template;

		private static BuildableItemDefinition definition;

		public static BuildableItemDefinition Definition => definition;

		public static void EnsureRegistered()
		{
			if ((Object)(object)definition == (Object)null)
			{
				Build();
			}
			if ((Object)(object)Registry.GetItem("mixingstationmk3") == (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)definition);
			}
			NetworkObject component = ((Component)template).GetComponent<NetworkObject>();
			InstanceFinder.NetworkManager.SpawnablePrefabs.AddObject(component, true);
			BigMixerMod.Log.Msg("Mixing Station Mk3 registered (prefab id " + component.PrefabId + ").");
		}

		private static void Build()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			BuildableItemDefinition val = FindMk2Definition();
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Could not find the Mixing Station Mk2 definition.");
			}
			MixingStationMk2 val2 = Compat.As<MixingStationMk2>((Il2CppObjectBase)(object)val.BuiltItem);
			if (BigMixerMod.DevDump.Value)
			{
				MelonDump(((Component)val2).transform);
			}
			holder = new GameObject("BigMixer_Templates");
			holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)holder);
			GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, holder.transform);
			((Object)obj).name = "MixingStationMk3";
			template = obj.GetComponent<MixingStationMk2>();
			((MixingStation)template).MaxMixQuantity = 40;
			int num = ((MixingStation)val2).MixTimePerItem * ((MixingStation)val2).MaxMixQuantity / 40;
			((MixingStation)template).MixTimePerItem = Mathf.Max(1, num);
			if (!Mk3Model.Apply(template))
			{
				Mk3Style.Apply(template);
			}
			definition = Object.Instantiate<BuildableItemDefinition>(val);
			((Object)definition).name = "MixingStationMk3";
			((BaseItemDefinition)definition).ID = "mixingstationmk3";
			((BaseItemDefinition)definition).Name = "Mixing Station Mk3";
			((BaseItemDefinition)definition).Description = "Industrial-grade mixing station. Mixes up to " + 40 + " product with " + 40 + " ingredients in a single batch.";
			((StorableItemDefinition)definition).BasePurchasePrice = BigMixerMod.Price.Value;
			((StorableItemDefinition)definition).RequiresLevelToPurchase = false;
			definition.BuiltItem = (BuildableItem)(object)template;
			((Object)definition).hideFlags = (HideFlags)32;
			Sprite val3 = Mk3Icon.LoadEmbedded() ?? Mk3Icon.Render(((Component)template).transform, ((BaseItemDefinition)val).Icon);
			if ((Object)(object)val3 != (Object)null)
			{
				((BaseItemDefinition)definition).Icon = val3;
			}
			BigMixerMod.Log.Msg(string.Format("Built Mk3 from {0}: {1}x{1}, {2} min/item (Mk2 {3}x, {4} min/item).", ((BaseItemDefinition)val).ID, ((MixingStation)template).MaxMixQuantity, ((MixingStation)template).MixTimePerItem, ((MixingStation)val2).MaxMixQuantity, ((MixingStation)val2).MixTimePerItem));
		}

		private static BuildableItemDefinition FindMk2Definition()
		{
			List<ItemDefinition> allItems = Singleton<Registry>.Instance.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				BuildableItemDefinition val = Compat.As<BuildableItemDefinition>((Il2CppObjectBase)(object)allItems[i]);
				if ((Object)(object)val != (Object)null && (Object)(object)val.BuiltItem != (Object)null && (Object)(object)Compat.As<MixingStationMk2>((Il2CppObjectBase)(object)val.BuiltItem) != (Object)null && ((BaseItemDefinition)val).ID != "mixingstationmk3")
				{
					return val;
				}
			}
			return null;
		}

		private static void MelonDump(Transform root)
		{
			StringBuilder stringBuilder = new StringBuilder("Mk2 prefab dump:\n");
			DumpRecursive(root, 0, stringBuilder);
			BigMixerMod.Log.Msg(stringBuilder.ToString());
		}

		private static void DumpRecursive(Transform t, int depth, StringBuilder sb)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = sb.Append(' ', depth * 2).Append(((Object)t).name).Append(" pos=");
			Vector3 val = t.localPosition;
			StringBuilder stringBuilder2 = stringBuilder.Append(((Vector3)(ref val)).ToString("F3")).Append(" rot=");
			val = t.localEulerAngles;
			StringBuilder stringBuilder3 = stringBuilder2.Append(((Vector3)(ref val)).ToString("F0")).Append(" scl=");
			val = t.localScale;
			stringBuilder3.Append(((Vector3)(ref val)).ToString("F2"));
			if (!((Component)t).gameObject.activeSelf)
			{
				sb.Append(" [inactive]");
			}
			MeshFilter component = ((Component)t).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				StringBuilder stringBuilder4 = sb.Append(" mesh=").Append(((Object)component.sharedMesh).name).Append(" bounds=");
				Bounds bounds = component.sharedMesh.bounds;
				val = ((Bounds)(ref bounds)).size;
				stringBuilder4.Append(((Vector3)(ref val)).ToString("F3"));
			}
			Renderer component2 = ((Component)t).GetComponent<Renderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				foreach (Material item in (Il2CppArrayBase<Material>)(object)component2.sharedMaterials)
				{
					if (!((Object)(object)item == (Object)null))
					{
						sb.Append(" mat=").Append(((Object)item).name).Append('(')
							.Append(((Object)item.shader).name);
						if (item.HasProperty("_BaseColor"))
						{
							StringBuilder stringBuilder5 = sb.Append(' ');
							Color color = item.GetColor("_BaseColor");
							stringBuilder5.Append(((Color)(ref color)).ToString("F2"));
						}
						if (item.HasProperty("_BaseMap") && (Object)(object)item.GetTexture("_BaseMap") != (Object)null)
						{
							sb.Append(" tex=").Append(((Object)item.GetTexture("_BaseMap")).name);
						}
						sb.Append(')');
					}
				}
			}
			sb.Append('\n');
			for (int i = 0; i < t.childCount; i++)
			{
				DumpRecursive(t.GetChild(i), depth + 1, sb);
			}
		}
	}
	internal static class Mk3Icon
	{
		private const int Size = 512;

		private const string EmbeddedIcon = "BigMixer.mk3icon.rgba";

		private const int EmbeddedSize = 256;

		public static Sprite LoadEmbedded()
		{
			//IL_008b: 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_00ae: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			try
			{
				Stream manifestResourceStream = typeof(Mk3Icon).Assembly.GetManifestResourceStream("BigMixer.mk3icon.rgba");
				if (manifestResourceStream == null)
				{
					return null;
				}
				byte[] array;
				using (MemoryStream memoryStream = new MemoryStream())
				{
					manifestResourceStream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
				if (array.Length != 262144)
				{
					return null;
				}
				Color32[] array2 = (Color32[])(object)new Color32[65536];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = new Color32(array[i * 4], array[i * 4 + 1], array[i * 4 + 2], array[i * 4 + 3]);
				}
				Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false)
				{
					name = "MixingStationMk3 Icon",
					wrapMode = (TextureWrapMode)1
				};
				val.SetPixels32(Il2CppStructArray<Color32>.op_Implicit(array2));
				val.Apply(false, false);
				((Object)val).hideFlags = (HideFlags)32;
				Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj).name = "MixingStationMk3 Icon";
				((Object)obj).hideFlags = (HideFlags)32;
				return obj;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Warning("Embedded icon failed to load: " + ex.Message);
				return null;
			}
		}

		public static Sprite Render(Transform template, Sprite fallback)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			AmbientMode ambientMode = RenderSettings.ambientMode;
			Color ambientLight = RenderSettings.ambientLight;
			try
			{
				val = BuildVisualProxy(template);
				RenderSettings.ambientMode = (AmbientMode)3;
				RenderSettings.ambientLight = Color.white;
				RuntimePreviewGenerator.PreviewDirection = new Vector3(-0.55f, -0.42f, -1f);
				RuntimePreviewGenerator.Padding = 0.04f;
				RuntimePreviewGenerator.BackgroundColor = new Color(0f, 0f, 0f, 0f);
				RuntimePreviewGenerator.OrthographicMode = false;
				RuntimePreviewGenerator.MarkTextureNonReadable = false;
				Texture2D val2 = RuntimePreviewGenerator.GenerateModelPreview(val.transform, 512, 512, false, true);
				if ((Object)(object)val2 == (Object)null)
				{
					return fallback;
				}
				((Object)val2).name = "MixingStationMk3 Icon";
				Sprite obj = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj).name = "MixingStationMk3 Icon";
				Object.DontDestroyOnLoad((Object)(object)val2);
				return obj;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Warning("Icon render failed, using the Mk2 icon: " + ex.Message);
				return fallback;
			}
			finally
			{
				RenderSettings.ambientMode = ambientMode;
				RenderSettings.ambientLight = ambientLight;
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static GameObject BuildVisualProxy(Transform template)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00a8: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mk3IconProxy");
			val.transform.position = new Vector3(0f, -500f, 0f);
			foreach (MeshRenderer componentsInChild in ((Component)template).GetComponentsInChildren<MeshRenderer>(true))
			{
				if (!IsVisibleInTemplate(((Component)componentsInChild).transform, template))
				{
					continue;
				}
				MeshFilter component = ((Component)componentsInChild).GetComponent<MeshFilter>();
				TextMeshPro component2 = ((Component)componentsInChild).GetComponent<TextMeshPro>();
				if ((!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) || !((Object)(object)component2 == (Object)null))
				{
					GameObject val2 = new GameObject(((Object)componentsInChild).name);
					val2.transform.SetParent(val.transform, false);
					Matrix4x4 val3 = template.worldToLocalMatrix * ((Component)componentsInChild).transform.localToWorldMatrix;
					val2.transform.localPosition = ((Matrix4x4)(ref val3)).MultiplyPoint3x4(Vector3.zero);
					val2.transform.localRotation = Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref val3)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref val3)).GetColumn(1)));
					Transform transform = val2.transform;
					Vector4 column = ((Matrix4x4)(ref val3)).GetColumn(0);
					float magnitude = ((Vector4)(ref column)).magnitude;
					column = ((Matrix4x4)(ref val3)).GetColumn(1);
					float magnitude2 = ((Vector4)(ref column)).magnitude;
					column = ((Matrix4x4)(ref val3)).GetColumn(2);
					transform.localScale = new Vector3(magnitude, magnitude2, ((Vector4)(ref column)).magnitude);
					if ((Object)(object)component2 != (Object)null)
					{
						TextMeshPro obj = val2.AddComponent<TextMeshPro>();
						((TMP_Text)obj).font = ((TMP_Text)component2).font;
						((TMP_Text)obj).text = ((TMP_Text)component2).text;
						((TMP_Text)obj).fontStyle = ((TMP_Text)component2).fontStyle;
						((TMP_Text)obj).alignment = ((TMP_Text)component2).alignment;
						((Graphic)obj).color = ((Graphic)component2).color;
						((TMP_Text)obj).fontSize = ((TMP_Text)component2).fontSize;
						((TMP_Text)obj).rectTransform.sizeDelta = ((TMP_Text)component2).rectTransform.sizeDelta;
						((TMP_Text)obj).ForceMeshUpdate(false, false);
					}
					else
					{
						val2.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
						MeshRenderer obj2 = val2.AddComponent<MeshRenderer>();
						((Renderer)obj2).sharedMaterials = ((Renderer)componentsInChild).sharedMaterials;
						((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0;
					}
				}
			}
			return val;
		}

		private static bool IsVisibleInTemplate(Transform t, Transform template)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)template)
			{
				if (!((Component)val).gameObject.activeSelf)
				{
					return false;
				}
				val = val.parent;
			}
			Renderer component = ((Component)t).GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				return component.enabled;
			}
			return false;
		}
	}
	internal static class Mk3Model
	{
		private class Mat
		{
			public string Name;

			public Color Color;

			public float Metallic;

			public float Roughness;

			public Color Emissive;

			public int Flags;
		}

		private class Sub
		{
			public int Material;

			public Vector3[] Positions;

			public Vector3[] Normals;

			public int[] Indices;
		}

		private class Part
		{
			public string Name;

			public Vector3 Pivot;

			public List<Sub> Subs = new List<Sub>();
		}

		private struct Box
		{
			public string Name;

			public Vector3 Center;

			public Vector3 Size;
		}

		private struct Anchor
		{
			public Vector3 Point;

			public Vector3 Normal;
		}

		public const float Scale = 0.7f;

		public const string RootName = "Mk3Model";

		private const string Resource = "BigMixer.mk3model.bin";

		private static List<Mat> mats;

		private static List<Part> parts;

		private static List<Box> boxes;

		private static Dictionary<string, Anchor> anchors;

		private static Material[] built;

		internal static Material[][] LampMaterials;

		public static bool Apply(MixingStationMk2 station)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!Load())
				{
					return false;
				}
				Transform val = ((Component)station).transform.Find("Mixing Station/Mixing station");
				if ((Object)(object)val == (Object)null)
				{
					BigMixerMod.Log.Warning("Mk2 visuals not found; keeping the repainted Mk2 model.");
					return false;
				}
				HideOld(val, out var template, out var colliderLayer);
				BuildMaterials(template);
				GameObject val2 = new GameObject("Mk3Model");
				val2.layer = ((Component)val).gameObject.layer;
				val2.transform.SetParent(((Component)station).transform, false);
				val2.transform.localScale = Vector3.one * 0.7f;
				foreach (Part part in parts)
				{
					BuildPart(val2.transform, part);
				}
				BuildColliders(val2.transform, colliderLayer);
				MoveWorkingParts(station);
				BigMixerMod.Log.Msg("Mk3 custom model applied (" + parts.Count + " parts, base shader " + ((Object)template.shader).name + ").");
				return true;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Error("Custom Mk3 model failed, keeping the repainted Mk2 model: " + ex);
				return false;
			}
		}

		private static Vector3 ToStation(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return p * 0.7f;
		}

		private static void HideOld(Transform oldVisuals, out Material template, out int colliderLayer)
		{
			template = null;
			colliderLayer = ((Component)oldVisuals).gameObject.layer;
			foreach (Renderer componentsInChild in ((Component)oldVisuals).GetComponentsInChildren<Renderer>(true))
			{
				if ((Object)(object)template == (Object)null && (Object)(object)componentsInChild.sharedMaterial != (Object)null && componentsInChild.sharedMaterial.HasProperty("_BaseColor"))
				{
					template = componentsInChild.sharedMaterial;
				}
				componentsInChild.enabled = false;
			}
			bool flag = true;
			foreach (Collider componentsInChild2 in ((Component)oldVisuals).GetComponentsInChildren<Collider>(true))
			{
				if (!componentsInChild2.isTrigger)
				{
					if (flag)
					{
						colliderLayer = ((Component)componentsInChild2).gameObject.layer;
						flag = false;
					}
					componentsInChild2.enabled = false;
				}
			}
			if ((Object)(object)template == (Object)null)
			{
				throw new InvalidOperationException("no URP material on the Mk2 to base the Mk3 materials on");
			}
		}

		private static void BuildMaterials(Material template)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			if (built != null)
			{
				return;
			}
			built = (Material[])(object)new Material[mats.Count];
			for (int i = 0; i < mats.Count; i++)
			{
				built[i] = MakeMaterial(template, mats[i], mats[i].Color, mats[i].Emissive);
			}
			LampMaterials = new Material[3][];
			string[] lampMats = new string[3] { "green", "amber", "red" };
			int j;
			for (j = 0; j < 3; j++)
			{
				Mat mat = mats.Find((Mat x) => x.Name == lampMats[j]) ?? mats[0];
				Color color = mat.Color;
				LampMaterials[j] = (Material[])(object)new Material[2]
				{
					MakeMaterial(template, mat, color * 0.35f, Color.black),
					MakeMaterial(template, mat, color, color * 3f)
				};
			}
		}

		private static Material MakeMaterial(Material template, Mat m, Color linearColor, Color linearEmission)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(template);
			((Object)val).name = "Mk3 " + m.Name;
			((Object)val).hideFlags = (HideFlags)32;
			string[] array = new string[8] { "_BaseMap", "_MainTex", "_BumpMap", "_MetallicGlossMap", "_OcclusionMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
			}
			array = new string[5] { "_NORMALMAP", "_METALLICSPECGLOSSMAP", "_OCCLUSIONMAP", "_DETAIL_MULX2", "_PARALLAXMAP" };
			foreach (string text2 in array)
			{
				val.DisableKeyword(text2);
			}
			Color val2 = new Color(linearColor.r, linearColor.g, linearColor.b, m.Color.a);
			Color gamma = ((Color)(ref val2)).gamma;
			val.SetColor("_BaseColor", gamma);
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", gamma);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", m.Metallic);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", 1f - m.Roughness);
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", ((m.Flags & 2) != 0) ? 0f : 2f);
			}
			if (((Color)(ref linearEmission)).maxColorComponent > 0.001f && val.HasProperty("_EmissionColor"))
			{
				val.EnableKeyword("_EMISSION");
				val.SetColor("_EmissionColor", linearEmission);
				val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
			}
			else
			{
				val.DisableKeyword("_EMISSION");
				if (val.HasProperty("_EmissionColor"))
				{
					val.SetColor("_EmissionColor", Color.black);
				}
			}
			if ((m.Flags & 1) != 0)
			{
				if (val.HasProperty("_Surface"))
				{
					val.SetFloat("_Surface", 1f);
				}
				if (val.HasProperty("_Blend"))
				{
					val.SetFloat("_Blend", 0f);
				}
				val.SetInt("_SrcBlend", 5);
				val.SetInt("_DstBlend", 10);
				val.SetInt("_ZWrite", 0);
				val.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				val.SetOverrideTag("RenderType", "Transparent");
				val.renderQueue = 3000;
			}
			return val;
		}

		private static void BuildPart(Transform root, Part p)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			GameObject val = new GameObject(p.Name);
			val.layer = ((Component)root).gameObject.layer;
			val.transform.SetParent(root, false);
			val.transform.localPosition = p.Pivot;
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			foreach (Sub sub2 in p.Subs)
			{
				list.AddRange(sub2.Positions);
				list2.AddRange(sub2.Normals);
			}
			Mesh val2 = new Mesh();
			((Object)val2).name = "Mk3 " + p.Name;
			((Object)val2).hideFlags = (HideFlags)32;
			val2.indexFormat = (IndexFormat)(list.Count > 65000);
			val2.vertices = Il2CppStructArray<Vector3>.op_Implicit(list.ToArray());
			val2.normals = Il2CppStructArray<Vector3>.op_Implicit(list2.ToArray());
			val2.subMeshCount = p.Subs.Count;
			Material[] array = (Material[])(object)new Material[p.Subs.Count];
			int num = 0;
			for (int i = 0; i < p.Subs.Count; i++)
			{
				Sub sub = p.Subs[i];
				int[] array2 = new int[sub.Indices.Length];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = sub.Indices[j] + num;
				}
				val2.SetTriangles(Il2CppStructArray<int>.op_Implicit(array2), i);
				num += sub.Positions.Length;
				array[i] = built[sub.Material];
			}
			val2.RecalculateBounds();
			val.AddComponent<MeshFilter>().sharedMesh = val2;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = Il2CppReferenceArray<Material>.op_Implicit(array);
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)obj).receiveShadows = true;
		}

		private static void BuildColliders(Transform root, int layer)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Collision");
			val.layer = layer;
			val.transform.SetParent(root, false);
			foreach (Box box in boxes)
			{
				BoxCollider obj = val.AddComponent<BoxCollider>();
				obj.center = box.Center;
				obj.size = new Vector3(Mathf.Max(box.Size.x, 0.02f), Mathf.Max(box.Size.y, 0.02f), Mathf.Max(box.Size.z, 0.02f));
			}
		}

		private static void MoveWorkingParts(MixingStationMk2 station)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)station).transform;
			if ((Object)(object)((MixingStation)station).InputVisuals != (Object)null && anchors.TryGetValue("left_top", out var value))
			{
				CenterGridOn(transform, ((Component)((MixingStation)station).InputVisuals).transform, ToStation(value.Point) + Vector3.up * 0.005f);
			}
			if ((Object)(object)((MixingStation)station).OutputVisuals != (Object)null && anchors.TryGetValue("right_top", out value))
			{
				CenterGridOn(transform, ((Component)((MixingStation)station).OutputVisuals).transform, ToStation(value.Point) + Vector3.up * 0.005f);
			}
			if ((Object)(object)station.ScreenCanvas != (Object)null && anchors.TryGetValue("screen", out value))
			{
				Transform transform2 = ((Component)station.ScreenCanvas).transform;
				transform2.position = transform.TransformPoint(ToStation(value.Point) + value.Normal * 0.004f);
				transform2.rotation = transform.rotation * Quaternion.LookRotation(-value.Normal, Vector3.up);
				float num = 0.0003646409f;
				float num2 = (((Object)(object)transform2.parent != (Object)null) ? transform2.parent.lossyScale.x : 1f);
				transform2.localScale = Vector3.one * (num / num2);
			}
			Vector3 val = ToStation(anchors["bounds_min"].Point);
			Vector3 val2 = ToStation(anchors["bounds_max"].Point);
			Vector3 val3 = (val + val2) * 0.5f;
			Vector3 val4 = val2 - val;
			if ((Object)(object)((BuildableItem)station).BoundingCollider != (Object)null && (Object)(object)((Component)((BuildableItem)station).BoundingCollider).transform.parent == (Object)(object)transform)
			{
				((Component)((BuildableItem)station).BoundingCollider).transform.localPosition = Vector3.zero;
				((BuildableItem)station).BoundingCollider.center = val3;
				((BuildableItem)station).BoundingCollider.size = val4;
			}
			Transform val5 = transform.Find("Outline");
			if (!((Object)(object)val5 != (Object)null))
			{
				return;
			}
			for (int i = 0; i < val5.childCount; i++)
			{
				Transform child = val5.GetChild(i);
				if (i == 0)
				{
					child.localPosition = val3;
					child.localScale = val4;
				}
				else
				{
					((Component)child).gameObject.SetActive(false);
				}
			}
		}

		private static void CenterGridOn(Transform station, Transform grid, Vector3 target)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			if (grid.childCount != 0)
			{
				Bounds val = default(Bounds);
				((Bounds)(ref val))..ctor(station.InverseTransformPoint(grid.GetChild(0).position), Vector3.zero);
				for (int i = 1; i < grid.childCount; i++)
				{
					((Bounds)(ref val)).Encapsulate(station.InverseTransformPoint(grid.GetChild(i).position));
				}
				Vector3 val2 = target - new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y, ((Bounds)(ref val)).center.z);
				grid.position = station.TransformPoint(station.InverseTransformPoint(grid.position) + val2);
			}
		}

		private static bool Load()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if (parts != null)
			{
				return true;
			}
			Stream manifestResourceStream = typeof(Mk3Model).Assembly.GetManifestResourceStream("BigMixer.mk3model.bin");
			if (manifestResourceStream == null)
			{
				BigMixerMod.Log.Warning("Embedded Mk3 model missing; keeping the repainted Mk2 model.");
				return false;
			}
			using (BinaryReader binaryReader = new BinaryReader(manifestResourceStream))
			{
				if (new string(binaryReader.ReadChars(4)) != "MK3M" || binaryReader.ReadInt32() != 1)
				{
					throw new InvalidDataException("bad Mk3 model data");
				}
				List<Mat> list = new List<Mat>();
				for (int num = binaryReader.ReadInt32(); num > 0; num--)
				{
					list.Add(new Mat
					{
						Name = Str(binaryReader),
						Color = Col4(binaryReader),
						Metallic = binaryReader.ReadSingle(),
						Roughness = binaryReader.ReadSingle(),
						Emissive = Col3(binaryReader),
						Flags = binaryReader.ReadInt32()
					});
				}
				List<Part> list2 = new List<Part>();
				for (int num2 = binaryReader.ReadInt32(); num2 > 0; num2--)
				{
					Part part = new Part
					{
						Name = Str(binaryReader),
						Pivot = V3(binaryReader)
					};
					for (int num3 = binaryReader.ReadInt32(); num3 > 0; num3--)
					{
						Sub sub = new Sub
						{
							Material = binaryReader.ReadInt32()
						};
						int num4 = binaryReader.ReadInt32();
						sub.Positions = (Vector3[])(object)new Vector3[num4];
						sub.Normals = (Vector3[])(object)new Vector3[num4];
						for (int i = 0; i < num4; i++)
						{
							sub.Positions[i] = V3(binaryReader);
						}
						for (int j = 0; j < num4; j++)
						{
							sub.Normals[j] = V3(binaryReader);
						}
						sub.Indices = new int[binaryReader.ReadInt32()];
						for (int k = 0; k < sub.Indices.Length; k++)
						{
							sub.Indices[k] = binaryReader.ReadInt32();
						}
						part.Subs.Add(sub);
					}
					list2.Add(part);
				}
				List<Box> list3 = new List<Box>();
				for (int num5 = binaryReader.ReadInt32(); num5 > 0; num5--)
				{
					list3.Add(new Box
					{
						Name = Str(binaryReader),
						Center = V3(binaryReader),
						Size = V3(binaryReader)
					});
				}
				Dictionary<string, Anchor> dictionary = new Dictionary<string, Anchor>();
				for (int num6 = binaryReader.ReadInt32(); num6 > 0; num6--)
				{
					dictionary[Str(binaryReader)] = new Anchor
					{
						Point = V3(binaryReader),
						Normal = V3(binaryReader)
					};
				}
				mats = list;
				boxes = list3;
				anchors = dictionary;
				parts = list2;
			}
			return true;
		}

		private static string Str(BinaryReader r)
		{
			return Encoding.UTF8.GetString(r.ReadBytes(r.ReadInt32()));
		}

		private static Vector3 V3(BinaryReader r)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static Color Col4(BinaryReader r)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static Color Col3(BinaryReader r)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1f);
		}
	}
	public class Mk3Station
	{
		private static readonly Dictionary<int, Mk3Station> all = new Dictionary<int, Mk3Station>();

		public MixingStation Station;

		public ItemSlot ProductSlot2;

		public ItemSlot MixerSlot2;

		public ItemSlot OutputSlot2;

		private bool compacting;

		private Transform beater;

		private Renderer[] lamps;

		private int lampState = -1;

		public static Mk3Station Of(MixingStation station)
		{
			if ((Object)(object)station == (Object)null || !all.TryGetValue(((Object)station).GetInstanceID(), out var value))
			{
				return null;
			}
			return value;
		}

		public static Mk3Station FindByGuid(string guid)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			foreach (Mk3Station value in all.Values)
			{
				if ((Object)(object)value.Station != (Object)null && string.Equals(((object)((BuildableItem)value.Station).GUID/*cast due to .constrained prefix*/).ToString(), guid, StringComparison.OrdinalIgnoreCase))
				{
					return value;
				}
			}
			return null;
		}

		public static void Clear()
		{
			all.Clear();
		}

		public static void UpdateAll(float dt)
		{
			if (all.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, Mk3Station> item in all)
			{
				if ((Object)(object)item.Value.Station == (Object)null)
				{
					(list ?? (list = new List<int>())).Add(item.Key);
				}
				else
				{
					item.Value.Animate(dt);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item2 in list)
			{
				all.Remove(item2);
			}
		}

		private void FindModelParts()
		{
			Transform val = ((Component)Station).transform.Find("Mk3Model");
			if (!((Object)(object)val == (Object)null))
			{
				beater = val.Find("beater");
				lamps = (Renderer[])(object)new Renderer[3];
				for (int i = 0; i < 3; i++)
				{
					Transform val2 = val.Find("tower_lamp_" + i);
					lamps[i] = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Renderer>() : null);
				}
			}
		}

		private void Animate(float dt)
		{
			if (lamps != null)
			{
				bool num = Station.CurrentMixOperation != null && !Station.IsMixingDone;
				bool flag = Station.IsMixingDone || Station.OutputSlot.Quantity > 0;
				if (num && (Object)(object)beater != (Object)null)
				{
					beater.Rotate(0f, 540f * dt, 0f, (Space)1);
				}
				int num2 = (num ? 1 : (flag ? (((int)(Time.time * 2f) % 2 == 0) ? 2 : 0) : 0));
				if (num2 != lampState && Mk3Model.LampMaterials != null)
				{
					lampState = num2;
					SetLamp(0, num2 == 1);
					SetLamp(1, num2 == 2);
					SetLamp(2, on: false);
				}
			}
		}

		private void SetLamp(int i, bool on)
		{
			if ((Object)(object)lamps[i] != (Object)null)
			{
				lamps[i].sharedMaterial = Mk3Model.LampMaterials[i][on ? 1u : 0u];
			}
		}

		public static bool IsMk3Object(MixingStation station)
		{
			return ((Object)((Component)station).gameObject).name.StartsWith("MixingStationMk3", StringComparison.Ordinal);
		}

		public static void Create(MixingStation station)
		{
			Mk3Station mk3Station = new Mk3Station();
			all[((Object)station).GetInstanceID()] = mk3Station;
			mk3Station.Setup(station);
		}

		public ItemSlot SecondOf(ItemSlot first)
		{
			if (Same(first, Station.ProductSlot))
			{
				return ProductSlot2;
			}
			if (Same(first, Station.MixerSlot))
			{
				return MixerSlot2;
			}
			if (Same(first, Station.OutputSlot))
			{
				return OutputSlot2;
			}
			return null;
		}

		public static bool Same(ItemSlot a, ItemSlot b)
		{
			if (a != null && b != null)
			{
				return ((Il2CppObjectBase)a).Pointer == ((Il2CppObjectBase)b).Pointer;
			}
			return false;
		}

		private void Setup(MixingStation station)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			Station = station;
			ProductSlot2 = NewSlot((ItemFilter)new ItemFilter_UnpackagedProduct(), station.InputVisuals);
			MixerSlot2 = NewSlot((ItemFilter)new ItemFilter_MixingIngredient(), station.InputVisuals);
			OutputSlot2 = NewSlot(null, station.OutputVisuals);
			OutputSlot2.SetIsAddLocked(true);
			station.InputSlots.Add(ProductSlot2);
			station.InputSlots.Add(MixerSlot2);
			station.OutputSlots.Add(OutputSlot2);
			Hook(station.ProductSlot, ProductSlot2);
			Hook(station.MixerSlot, MixerSlot2);
			Hook(station.OutputSlot, OutputSlot2);
			FindModelParts();
		}

		private ItemSlot NewSlot(ItemFilter filter, StorageVisualizer visuals)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ItemSlot val = new ItemSlot(true);
			if (filter != null)
			{
				val.AddFilter(filter);
			}
			val.SetSlotOwner(Station.Cast());
			if ((Object)(object)visuals != (Object)null)
			{
				visuals.AddSlot(val, false);
			}
			val.onItemDataChanged = Compat.Combine(val.onItemDataChanged, Compat.Action(MarkChanged));
			return val;
		}

		private void MarkChanged()
		{
			((BuildableItem)Station).HasChanged = true;
		}

		private void Hook(ItemSlot first, ItemSlot second)
		{
			Action b = Compat.Action(delegate
			{
				Compact(first, second);
			});
			first.onItemDataChanged = Compat.Combine(first.onItemDataChanged, b);
			second.onItemDataChanged = Compat.Combine(second.onItemDataChanged, b);
		}

		private void Compact(ItemSlot first, ItemSlot second)
		{
			if (compacting || !InstanceFinder.IsServer || first.ItemInstance != null || second.ItemInstance == null || first.IsLocked || second.IsLocked)
			{
				return;
			}
			compacting = true;
			try
			{
				ItemInstance copy = second.ItemInstance.GetCopy(second.Quantity);
				second.ClearStoredInstance(false);
				first.SetStoredItem(copy, false);
			}
			finally
			{
				compacting = false;
			}
		}

		public int PairQuantity(ItemSlot first)
		{
			ItemSlot val = SecondOf(first);
			int num = first.Quantity;
			if (val != null && first.ItemInstance != null && val.ItemInstance != null && first.ItemInstance.CanStackWith(val.ItemInstance, false))
			{
				num += val.Quantity;
			}
			return num;
		}
	}
	internal static class StationExtensions
	{
		public static IItemSlotOwner Cast(this MixingStation station)
		{
			return ((Il2CppObjectBase)station).TryCast<IItemSlotOwner>();
		}
	}
	[HarmonyPatch(typeof(MixingStationMk2), "Awake")]
	internal static class Patch_Mk2Awake
	{
		private static void Postfix(MixingStationMk2 __instance)
		{
			if (!((BuildableItem)__instance).isGhost && Mk3Station.IsMk3Object((MixingStation)(object)__instance) && Mk3Station.Of((MixingStation)(object)__instance) == null)
			{
				Mk3Station.Create((MixingStation)(object)__instance);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "GetMixQuantity")]
	internal static class Patch_GetMixQuantity
	{
		private static void Postfix(MixingStation __instance, ref int __result)
		{
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			if (mk3Station != null && !((Object)(object)__instance.GetProduct() == (Object)null) && !((Object)(object)__instance.GetMixer() == (Object)null))
			{
				__result = Mathf.Min(Mathf.Min(mk3Station.PairQuantity(__instance.ProductSlot), mk3Station.PairQuantity(__instance.MixerSlot)), __instance.MaxMixQuantity);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "CanStartMix")]
	internal static class Patch_CanStartMix
	{
		private static void Postfix(MixingStation __instance, ref bool __result)
		{
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			if (mk3Station != null && mk3Station.OutputSlot2.Quantity > 0)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(ItemSlot), "ChangeQuantity")]
	internal static class Patch_ChangeQuantity
	{
		private static void Prefix(ItemSlot __instance, ref int change, bool _internal)
		{
			if (change >= 0 || -change <= __instance.Quantity)
			{
				return;
			}
			MixingStation val = Compat.As<MixingStation>((Il2CppObjectBase)(object)__instance.SlotOwner);
			Mk3Station mk3Station = Mk3Station.Of(val);
			if (mk3Station != null && (Mk3Station.Same(__instance, val.ProductSlot) || Mk3Station.Same(__instance, val.MixerSlot)))
			{
				ItemSlot val2 = mk3Station.SecondOf(__instance);
				int num = -change - __instance.Quantity;
				if (val2.ItemInstance != null && __instance.ItemInstance != null && __instance.ItemInstance.CanStackWith(val2.ItemInstance, false) && val2.Quantity >= num)
				{
					val2.ChangeQuantity(-num, _internal);
					change = -__instance.Quantity;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "RpcLogic___TryCreateOutputItems_2166136261")]
	internal static class Patch_TryCreateOutputItems
	{
		private static bool Prefix(MixingStation __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			MixOperation currentMixOperation = __instance.CurrentMixOperation;
			if (mk3Station == null || currentMixOperation == null)
			{
				return true;
			}
			ProductDefinition val = default(ProductDefinition);
			if (!currentMixOperation.IsOutputKnown(ref val))
			{
				return false;
			}
			int num = currentMixOperation.Quantity;
			string text = null;
			ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[2] { __instance.OutputSlot, mk3Station.OutputSlot2 };
			foreach (ItemSlot val2 in array)
			{
				if (num <= 0)
				{
					break;
				}
				int num2 = Mathf.Min(num, ((BaseItemDefinition)val).StackLimit);
				QualityItemInstance val3 = Compat.As<QualityItemInstance>((Il2CppObjectBase)(object)((ItemDefinition)val).GetDefaultInstance(num2));
				val3.SetQuality(currentMixOperation.ProductQuality);
				val2.AddItem((ItemInstance)(object)val3, false);
				text = ((BaseItemInstance)val3).ID;
				num -= num2;
			}
			if (num > 0)
			{
				BigMixerMod.Log.Warning("Mk3 output overflow: " + num + " item(s) didn't fit.");
			}
			if ((Object)(object)NetworkSingleton<ProductManager>.Instance.GetRecipe(currentMixOperation.ProductID, currentMixOperation.IngredientID) == (Object)null)
			{
				NetworkSingleton<ProductManager>.Instance.SendMixRecipe(currentMixOperation.ProductID, currentMixOperation.IngredientID, text);
			}
			__instance.SetMixOperation((NetworkConnection)null, (MixOperation)null, 0);
			return false;
		}
	}
	[HarmonyPatch(typeof(MixingStation), "GetBaseData")]
	internal static class Patch_GetBaseData
	{
		private static void Postfix(MixingStation __instance, BuildableItemData __result)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			MixingStationData val = Compat.As<MixingStationData>((Il2CppObjectBase)(object)__result);
			if (mk3Station != null && val != null)
			{
				val.ProductContents = new ItemSet(Compat.SlotList(__instance.ProductSlot, mk3Station.ProductSlot2));
				val.MixerContents = new ItemSet(Compat.SlotList(__instance.MixerSlot, mk3Station.MixerSlot2));
				val.OutputContents = new ItemSet(Compat.SlotList(__instance.OutputSlot, mk3Station.OutputSlot2));
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationLoader), "Load", new Type[] { typeof(DynamicSaveData) })]
	internal static class Patch_LoadDynamic
	{
		private static void Postfix(DynamicSaveData data)
		{
			MixingStationData d = default(MixingStationData);
			if (data.TryExtractBaseData<MixingStationData>(ref d))
			{
				Mk3Load.LoadSeconds(d);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationLoader), "Load", new Type[] { typeof(string) })]
	internal static class Patch_LoadPath
	{
		private static void Postfix(MixingStationLoader __instance, string mainPath)
		{
			MixingStationData data = Compat.GetData(__instance, mainPath);
			if (data != null)
			{
				Mk3Load.LoadSeconds(data);
			}
		}
	}
	internal static class Mk3Load
	{
		public static void LoadSeconds(MixingStationData d)
		{
			Mk3Station mk3Station = Mk3Station.FindByGuid(((BuildableItemData)d).GUID);
			if (mk3Station != null)
			{
				if (d.ProductContents != null)
				{
					d.ProductContents.LoadTo(mk3Station.ProductSlot2, 1);
				}
				if (d.MixerContents != null)
				{
					d.MixerContents.LoadTo(mk3Station.MixerSlot2, 1);
				}
				if (d.OutputContents != null)
				{
					d.OutputContents.LoadTo(mk3Station.OutputSlot2, 1);
				}
			}
		}
	}
	internal static class Mk3Style
	{
		private static readonly Color Paint = new Color(0.55f, 0.08f, 0.08f);

		private static readonly Color BadgeColor = new Color(0.95f, 0.78f, 0.25f);

		public static void Apply(MixingStationMk2 station)
		{
			Repaint(((Component)station).gameObject);
			AddBadge(station);
		}

		private static void Repaint(GameObject root)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00e3: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, Material> dictionary = new Dictionary<int, Material>();
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Paint, ref num, ref num2, ref num3);
			float num4 = default(float);
			float num5 = default(float);
			float num6 = default(float);
			foreach (Renderer componentsInChild in root.GetComponentsInChildren<Renderer>(true))
			{
				if ((Object)(object)Compat.As<ParticleSystemRenderer>((Il2CppObjectBase)(object)componentsInChild) != (Object)null || (Object)(object)((Component)componentsInChild).GetComponent<TMP_Text>() != (Object)null)
				{
					continue;
				}
				Il2CppReferenceArray<Material> sharedMaterials = componentsInChild.sharedMaterials;
				bool flag = false;
				for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; i++)
				{
					Material val = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[i];
					if ((Object)(object)val == (Object)null || !val.HasProperty("_BaseColor"))
					{
						continue;
					}
					Color color = val.GetColor("_BaseColor");
					Color.RGBToHSV(color, ref num4, ref num5, ref num6);
					if (num5 < 0.25f || num6 < 0.12f)
					{
						continue;
					}
					if (!dictionary.TryGetValue(((Object)val).GetInstanceID(), out var value))
					{
						value = new Material(val);
						((Object)value).name = ((Object)val).name + " (Mk3)";
						Color val2 = Color.HSVToRGB(num, Mathf.Max(num5, num2), Mathf.Min(num6, num3 + 0.15f));
						val2.a = color.a;
						value.SetColor("_BaseColor", val2);
						if (value.HasProperty("_Color"))
						{
							value.SetColor("_Color", val2);
						}
						dictionary[((Object)val).GetInstanceID()] = value;
					}
					((Il2CppArrayBase<Material>)(object)sharedMaterials)[i] = value;
					flag = true;
				}
				if (flag)
				{
					componentsInChild.sharedMaterials = sharedMaterials;
				}
			}
			BigMixerMod.Log.Msg("Mk3 repaint: " + dictionary.Count + " material(s) recoloured.");
		}

		private static void AddBadge(MixingStationMk2 station)
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)station).transform;
			Bounds val = LocalBounds(transform);
			GameObject val2 = new GameObject("Mk3Badge")
			{
				layer = ((Component)station).gameObject.layer
			};
			val2.transform.SetParent(transform, false);
			val2.transform.localPosition = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).center.y + ((Bounds)(ref val)).extents.y * 0.55f, ((Bounds)(ref val)).min.z - 0.004f);
			val2.transform.localRotation = Quaternion.identity;
			TextMeshPro val3 = val2.AddComponent<TextMeshPro>();
			if ((Object)(object)station.QuantityLabel != (Object)null && (Object)(object)((TMP_Text)station.QuantityLabel).font != (Object)null)
			{
				((TMP_Text)val3).font = ((TMP_Text)station.QuantityLabel).font;
			}
			((TMP_Text)val3).text = "MK3";
			((TMP_Text)val3).fontStyle = (FontStyles)1;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
			((Graphic)val3).color = BadgeColor;
			((TMP_Text)val3).enableAutoSizing = false;
			((TMP_Text)val3).fontSize = 1.2f;
			((TMP_Text)val3).rectTransform.sizeDelta = new Vector2(((Bounds)(ref val)).size.x * 0.8f, 0.2f);
		}

		internal static Bounds LocalBounds(Transform root)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds result = default(Bounds);
			foreach (MeshFilter componentsInChild in ((Component)root).GetComponentsInChildren<MeshFilter>(true))
			{
				if ((Object)(object)componentsInChild.sharedMesh == (Object)null || (Object)(object)((Component)componentsInChild).GetComponent<MeshRenderer>() == (Object)null)
				{
					continue;
				}
				Bounds bounds = componentsInChild.sharedMesh.bounds;
				Matrix4x4 val = root.worldToLocalMatrix * ((Component)componentsInChild).transform.localToWorldMatrix;
				for (int i = 0; i < 8; i++)
				{
					Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1))));
					Vector3 val3 = ((Matrix4x4)(ref val)).MultiplyPoint3x4(val2);
					if (!flag)
					{
						result = new Bounds(val3, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val3);
					}
				}
			}
			return result;
		}
	}
	internal static class Mk3Ui
	{
		private const float Gap = 10f;

		private static MixingStationInterface ui;

		private static ItemSlotUI product2;

		private static ItemSlotUI ingredient2;

		private static ItemSlotUI output2;

		private static Mk3Station current;

		private static Action contentsChanged;

		private static bool dumped;

		public static void Opened(MixingStationInterface face, MixingStation station)
		{
			EnsureClones(face);
			current = Mk3Station.Of(station);
			bool flag = current != null;
			((Component)product2).gameObject.SetActive(flag);
			((Component)ingredient2).gameObject.SetActive(flag);
			((Component)output2).gameObject.SetActive(false);
			if (flag)
			{
				if (BigMixerMod.DevDump.Value && !dumped)
				{
					dumped = true;
					DumpUi(((Component)face).transform);
				}
				product2.AssignSlot(current.ProductSlot2);
				ingredient2.AssignSlot(current.MixerSlot2);
				output2.AssignSlot(current.OutputSlot2);
				Subscribe(on: true);
				UpdateOutput(face);
			}
		}

		public static void Closed()
		{
			if (current != null)
			{
				Subscribe(on: false);
				product2.ClearSlot();
				ingredient2.ClearSlot();
				output2.ClearSlot();
				current = null;
			}
		}

		public static void UpdateOutput(MixingStationInterface face)
		{
			if (!((Object)(object)output2 == (Object)null))
			{
				((Component)output2).gameObject.SetActive(current != null && ((Component)face.OutputSlotUI).gameObject.activeSelf);
			}
		}

		private static void Subscribe(bool on)
		{
			ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[3] { current.ProductSlot2, current.MixerSlot2, current.OutputSlot2 };
			foreach (ItemSlot val in array)
			{
				val.onItemDataChanged = (on ? Compat.Combine(val.onItemDataChanged, contentsChanged) : Compat.Remove(val.onItemDataChanged, contentsChanged));
			}
		}

		private static void EnsureClones(MixingStationInterface face)
		{
			if (!((Object)(object)ui == (Object)(object)face) || !((Object)(object)product2 != (Object)null))
			{
				ui = face;
				product2 = CloneBelow(face.ProductSlotUI, "ProductSlot2");
				ingredient2 = CloneBelow(face.IngredientSlotUI, "IngredientSlot2");
				output2 = CloneBelow(face.OutputSlotUI, "OutputSlot2");
				contentsChanged = Compat.Action(delegate
				{
					Compat.StationContentsChanged(face);
				});
			}
		}

		private static ItemSlotUI CloneBelow(ItemSlotUI original, string name)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)original).GetComponent<RectTransform>();
			GameObject val = Object.Instantiate<GameObject>(((Component)original).gameObject, ((Transform)component).parent);
			((Object)val).name = name;
			val.GetComponent<ItemSlotUI>().ClearSlot();
			LayoutElement val2 = val.GetComponent<LayoutElement>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<LayoutElement>();
			}
			val2.ignoreLayout = true;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = component.anchorMin;
			component2.anchorMax = component.anchorMax;
			component2.pivot = component.pivot;
			component2.sizeDelta = component.sizeDelta;
			Vector2 anchoredPosition = component.anchoredPosition;
			Rect rect = component.rect;
			component2.anchoredPosition = anchoredPosition - new Vector2(0f, ((Rect)(ref rect)).height + 10f);
			val.SetActive(false);
			return val.GetComponent<ItemSlotUI>();
		}

		private static void DumpUi(Transform root)
		{
			StringBuilder stringBuilder = new StringBuilder("MixingStationInterface dump:\n");
			Dump(root, 0, stringBuilder);
			BigMixerMod.Log.Msg(stringBuilder.ToString());
		}

		private static void Dump(Transform t, int depth, StringBuilder sb)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (depth <= 7)
			{
				sb.Append(' ', depth * 2).Append(((Object)t).name);
				if (!((Component)t).gameObject.activeSelf)
				{
					sb.Append(" [off]");
				}
				RectTransform component = ((Component)t).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					StringBuilder stringBuilder = sb.Append(" pos=");
					Vector2 val = component.anchoredPosition;
					StringBuilder stringBuilder2 = stringBuilder.Append(((Vector2)(ref val)).ToString("F0")).Append(" size=");
					Rect rect = component.rect;
					val = ((Rect)(ref rect)).size;
					stringBuilder2.Append(((Vector2)(ref val)).ToString("F0"));
				}
				if ((Object)(object)((Component)t).GetComponent<LayoutGroup>() != (Object)null)
				{
					sb.Append(" [layout]");
				}
				sb.Append('\n');
				for (int i = 0; i < t.childCount; i++)
				{
					Dump(t.GetChild(i), depth + 1, sb);
				}
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "Open")]
	internal static class Patch_UiOpen
	{
		private static void Postfix(MixingStationInterface __instance, MixingStation station)
		{
			Mk3Ui.Opened(__instance, station);
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "Close")]
	internal static class Patch_UiClose
	{
		private static void Prefix()
		{
			Mk3Ui.Closed();
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "UpdateDisplayMode")]
	internal static class Patch_UiDisplayMode
	{
		private static void Postfix(MixingStationInterface __instance)
		{
			Mk3Ui.UpdateOutput(__instance);
		}
	}
	internal static class OscarShop
	{
		public static bool TryAddListing()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if ((Object)(object)Mk3Factory.Definition == (Object)null)
			{
				return false;
			}
			Oscar val = Object.FindObjectOfType<Oscar>();
			if ((Object)(object)val == (Object)null || (Object)(object)val.ShopInterface == (Object)null)
			{
				return false;
			}
			ShopInterface shopInterface = val.ShopInterface;
			if (shopInterface.GetListing("mixingstationmk3") != null)
			{
				return true;
			}
			ShopListing val2 = new ShopListing();
			val2.name = "Mixing Station Mk3";
			val2.Item = (StorableItemDefinition)(object)Mk3Factory.Definition;
			val2.CanBeDelivered = false;
			shopInterface.Listings.Add(val2);
			Compat.CreateListingUI(shopInterface, val2);
			val2.Initialize(shopInterface);
			Compat.RefreshShownItems(shopInterface);
			BigMixerMod.Log.Msg("Added Mixing Station Mk3 to " + shopInterface.ShopName + " for $" + val2.Price + ".");
			return true;
		}
	}
}

BigMixer_MONO.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BigMixer;
using FishNet;
using FishNet.Connection;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using ScheduleOne;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.EntityFramework;
using ScheduleOne.ItemFramework;
using ScheduleOne.NPCs.CharacterClasses;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.Product;
using ScheduleOne.Storage;
using ScheduleOne.UI;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.Stations;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(BigMixerMod), "Mixing Station Mk3", "1.1.0", "Ashton", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BigMixer
{
	public class BigMixerMod : MelonMod
	{
		public const string ItemId = "mixingstationmk3";

		public const string ItemName = "Mixing Station Mk3";

		public const int Capacity = 40;

		internal static Instance Log;

		internal static MelonPreferences_Entry<float> Price;

		internal static MelonPreferences_Entry<bool> DevDump;

		public override void OnInitializeMelon()
		{
			Log = ((MelonBase)this).LoggerInstance;
			MelonPreferences_Category obj = MelonPreferences.CreateCategory("MixingStationMk3", "Mixing Station Mk3");
			Price = obj.CreateEntry<float>("Price", 8000f, "Price", "Purchase price at Oscar's warehouse.", false, false, (ValueValidator)null, (string)null);
			DevDump = obj.CreateEntry<bool>("DevDump", false, "Dev dump", "Log the Mk2 prefab hierarchy and materials on load.", false, false, (ValueValidator)null, (string)null);
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!(sceneName != "Main"))
			{
				Mk3Station.Clear();
				try
				{
					Mk3Factory.EnsureRegistered();
				}
				catch (Exception ex)
				{
					Log.Error("Failed to register Mixing Station Mk3: " + ex);
					return;
				}
				MelonCoroutines.Start(AddToOscarWhenReady());
			}
		}

		public override void OnUpdate()
		{
			Mk3Station.UpdateAll(Time.deltaTime);
		}

		private static IEnumerator AddToOscarWhenReady()
		{
			float timeout = Time.realtimeSinceStartup + 300f;
			while (Time.realtimeSinceStartup < timeout)
			{
				if ((!Singleton<LoadManager>.InstanceExists || !Singleton<LoadManager>.Instance.IsLoading) && OscarShop.TryAddListing())
				{
					yield break;
				}
				yield return (object)new WaitForSeconds(1f);
			}
			Log.Warning("Gave up waiting for Oscar's shop; Mk3 not listed this session.");
		}
	}
	internal static class Compat
	{
		public static T As<T>(object obj) where T : class
		{
			return obj as T;
		}

		public static Action Combine(Action a, Action b)
		{
			return (Action)Delegate.Combine(a, b);
		}

		public static Action Remove(Action a, Action b)
		{
			return (Action)Delegate.Remove(a, b);
		}

		public static Action Action(Action a)
		{
			return a;
		}

		public static List<ItemSlot> SlotList(params ItemSlot[] slots)
		{
			return new List<ItemSlot>(slots);
		}

		public static void CreateListingUI(ShopInterface shop, ShopListing listing)
		{
			AccessTools.Method(typeof(ShopInterface), "CreateListingUI", (Type[])null, (Type[])null).Invoke(shop, new object[1] { listing });
		}

		public static void RefreshShownItems(ShopInterface shop)
		{
			AccessTools.Method(typeof(ShopInterface), "RefreshShownItems", (Type[])null, (Type[])null).Invoke(shop, null);
		}

		public static void StationContentsChanged(MixingStationInterface ui)
		{
			AccessTools.Method(typeof(MixingStationInterface), "StationContentsChanged", (Type[])null, (Type[])null).Invoke(ui, null);
		}

		public static MixingStationData GetData(MixingStationLoader loader, string mainPath)
		{
			object? obj = AccessTools.Method(typeof(MixingStationLoader), "GetData", (Type[])null, (Type[])null).MakeGenericMethod(typeof(MixingStationData)).Invoke(loader, new object[1] { mainPath });
			return (MixingStationData)((obj is MixingStationData) ? obj : null);
		}
	}
	internal static class Mk3Factory
	{
		private static GameObject holder;

		private static MixingStationMk2 template;

		private static BuildableItemDefinition definition;

		public static BuildableItemDefinition Definition => definition;

		public static void EnsureRegistered()
		{
			if ((Object)(object)definition == (Object)null)
			{
				Build();
			}
			if ((Object)(object)Registry.GetItem("mixingstationmk3") == (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)definition);
			}
			NetworkObject component = ((Component)template).GetComponent<NetworkObject>();
			InstanceFinder.NetworkManager.SpawnablePrefabs.AddObject(component, true);
			BigMixerMod.Log.Msg("Mixing Station Mk3 registered (prefab id " + component.PrefabId + ").");
		}

		private static void Build()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			BuildableItemDefinition val = FindMk2Definition();
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Could not find the Mixing Station Mk2 definition.");
			}
			MixingStationMk2 val2 = Compat.As<MixingStationMk2>(val.BuiltItem);
			if (BigMixerMod.DevDump.Value)
			{
				MelonDump(((Component)val2).transform);
			}
			holder = new GameObject("BigMixer_Templates");
			holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)holder);
			GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, holder.transform);
			((Object)obj).name = "MixingStationMk3";
			template = obj.GetComponent<MixingStationMk2>();
			((MixingStation)template).MaxMixQuantity = 40;
			int num = ((MixingStation)val2).MixTimePerItem * ((MixingStation)val2).MaxMixQuantity / 40;
			((MixingStation)template).MixTimePerItem = Mathf.Max(1, num);
			if (!Mk3Model.Apply(template))
			{
				Mk3Style.Apply(template);
			}
			definition = Object.Instantiate<BuildableItemDefinition>(val);
			((Object)definition).name = "MixingStationMk3";
			((BaseItemDefinition)definition).ID = "mixingstationmk3";
			((BaseItemDefinition)definition).Name = "Mixing Station Mk3";
			((BaseItemDefinition)definition).Description = "Industrial-grade mixing station. Mixes up to " + 40 + " product with " + 40 + " ingredients in a single batch.";
			((StorableItemDefinition)definition).BasePurchasePrice = BigMixerMod.Price.Value;
			((StorableItemDefinition)definition).RequiresLevelToPurchase = false;
			definition.BuiltItem = (BuildableItem)(object)template;
			((Object)definition).hideFlags = (HideFlags)32;
			Sprite val3 = Mk3Icon.LoadEmbedded() ?? Mk3Icon.Render(((Component)template).transform, ((BaseItemDefinition)val).Icon);
			if ((Object)(object)val3 != (Object)null)
			{
				((BaseItemDefinition)definition).Icon = val3;
			}
			BigMixerMod.Log.Msg(string.Format("Built Mk3 from {0}: {1}x{1}, {2} min/item (Mk2 {3}x, {4} min/item).", ((BaseItemDefinition)val).ID, ((MixingStation)template).MaxMixQuantity, ((MixingStation)template).MixTimePerItem, ((MixingStation)val2).MaxMixQuantity, ((MixingStation)val2).MixTimePerItem));
		}

		private static BuildableItemDefinition FindMk2Definition()
		{
			List<ItemDefinition> allItems = Singleton<Registry>.Instance.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				BuildableItemDefinition val = Compat.As<BuildableItemDefinition>(allItems[i]);
				if ((Object)(object)val != (Object)null && (Object)(object)val.BuiltItem != (Object)null && (Object)(object)Compat.As<MixingStationMk2>(val.BuiltItem) != (Object)null && ((BaseItemDefinition)val).ID != "mixingstationmk3")
				{
					return val;
				}
			}
			return null;
		}

		private static void MelonDump(Transform root)
		{
			StringBuilder stringBuilder = new StringBuilder("Mk2 prefab dump:\n");
			DumpRecursive(root, 0, stringBuilder);
			BigMixerMod.Log.Msg(stringBuilder.ToString());
		}

		private static void DumpRecursive(Transform t, int depth, StringBuilder sb)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = sb.Append(' ', depth * 2).Append(((Object)t).name).Append(" pos=");
			Vector3 val = t.localPosition;
			StringBuilder stringBuilder2 = stringBuilder.Append(((Vector3)(ref val)).ToString("F3")).Append(" rot=");
			val = t.localEulerAngles;
			StringBuilder stringBuilder3 = stringBuilder2.Append(((Vector3)(ref val)).ToString("F0")).Append(" scl=");
			val = t.localScale;
			stringBuilder3.Append(((Vector3)(ref val)).ToString("F2"));
			if (!((Component)t).gameObject.activeSelf)
			{
				sb.Append(" [inactive]");
			}
			MeshFilter component = ((Component)t).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				StringBuilder stringBuilder4 = sb.Append(" mesh=").Append(((Object)component.sharedMesh).name).Append(" bounds=");
				Bounds bounds = component.sharedMesh.bounds;
				val = ((Bounds)(ref bounds)).size;
				stringBuilder4.Append(((Vector3)(ref val)).ToString("F3"));
			}
			Renderer component2 = ((Component)t).GetComponent<Renderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				Material[] sharedMaterials = component2.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						sb.Append(" mat=").Append(((Object)val2).name).Append('(')
							.Append(((Object)val2.shader).name);
						if (val2.HasProperty("_BaseColor"))
						{
							StringBuilder stringBuilder5 = sb.Append(' ');
							Color color = val2.GetColor("_BaseColor");
							stringBuilder5.Append(((Color)(ref color)).ToString("F2"));
						}
						if (val2.HasProperty("_BaseMap") && (Object)(object)val2.GetTexture("_BaseMap") != (Object)null)
						{
							sb.Append(" tex=").Append(((Object)val2.GetTexture("_BaseMap")).name);
						}
						sb.Append(')');
					}
				}
			}
			sb.Append('\n');
			for (int j = 0; j < t.childCount; j++)
			{
				DumpRecursive(t.GetChild(j), depth + 1, sb);
			}
		}
	}
	internal static class Mk3Icon
	{
		private const int Size = 512;

		private const string EmbeddedIcon = "BigMixer.mk3icon.rgba";

		private const int EmbeddedSize = 256;

		public static Sprite LoadEmbedded()
		{
			//IL_008b: 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_00ae: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			try
			{
				Stream manifestResourceStream = typeof(Mk3Icon).Assembly.GetManifestResourceStream("BigMixer.mk3icon.rgba");
				if (manifestResourceStream == null)
				{
					return null;
				}
				byte[] array;
				using (MemoryStream memoryStream = new MemoryStream())
				{
					manifestResourceStream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
				if (array.Length != 262144)
				{
					return null;
				}
				Color32[] array2 = (Color32[])(object)new Color32[65536];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = new Color32(array[i * 4], array[i * 4 + 1], array[i * 4 + 2], array[i * 4 + 3]);
				}
				Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false)
				{
					name = "MixingStationMk3 Icon",
					wrapMode = (TextureWrapMode)1
				};
				val.SetPixels32(array2);
				val.Apply(false, false);
				((Object)val).hideFlags = (HideFlags)32;
				Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj).name = "MixingStationMk3 Icon";
				((Object)obj).hideFlags = (HideFlags)32;
				return obj;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Warning("Embedded icon failed to load: " + ex.Message);
				return null;
			}
		}

		public static Sprite Render(Transform template, Sprite fallback)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			AmbientMode ambientMode = RenderSettings.ambientMode;
			Color ambientLight = RenderSettings.ambientLight;
			try
			{
				val = BuildVisualProxy(template);
				RenderSettings.ambientMode = (AmbientMode)3;
				RenderSettings.ambientLight = Color.white;
				RuntimePreviewGenerator.PreviewDirection = new Vector3(-0.55f, -0.42f, -1f);
				RuntimePreviewGenerator.Padding = 0.04f;
				RuntimePreviewGenerator.BackgroundColor = new Color(0f, 0f, 0f, 0f);
				RuntimePreviewGenerator.OrthographicMode = false;
				RuntimePreviewGenerator.MarkTextureNonReadable = false;
				Texture2D val2 = RuntimePreviewGenerator.GenerateModelPreview(val.transform, 512, 512, false, true);
				if ((Object)(object)val2 == (Object)null)
				{
					return fallback;
				}
				((Object)val2).name = "MixingStationMk3 Icon";
				Sprite obj = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj).name = "MixingStationMk3 Icon";
				Object.DontDestroyOnLoad((Object)(object)val2);
				return obj;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Warning("Icon render failed, using the Mk2 icon: " + ex.Message);
				return fallback;
			}
			finally
			{
				RenderSettings.ambientMode = ambientMode;
				RenderSettings.ambientLight = ambientLight;
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static GameObject BuildVisualProxy(Transform template)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mk3IconProxy");
			val.transform.position = new Vector3(0f, -500f, 0f);
			MeshRenderer[] componentsInChildren = ((Component)template).GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val2 in componentsInChildren)
			{
				if (!IsVisibleInTemplate(((Component)val2).transform, template))
				{
					continue;
				}
				MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
				TextMeshPro component2 = ((Component)val2).GetComponent<TextMeshPro>();
				if ((!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) || !((Object)(object)component2 == (Object)null))
				{
					GameObject val3 = new GameObject(((Object)val2).name);
					val3.transform.SetParent(val.transform, false);
					Matrix4x4 val4 = template.worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix;
					val3.transform.localPosition = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(Vector3.zero);
					val3.transform.localRotation = Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(1)));
					Transform transform = val3.transform;
					Vector4 column = ((Matrix4x4)(ref val4)).GetColumn(0);
					float magnitude = ((Vector4)(ref column)).magnitude;
					column = ((Matrix4x4)(ref val4)).GetColumn(1);
					float magnitude2 = ((Vector4)(ref column)).magnitude;
					column = ((Matrix4x4)(ref val4)).GetColumn(2);
					transform.localScale = new Vector3(magnitude, magnitude2, ((Vector4)(ref column)).magnitude);
					if ((Object)(object)component2 != (Object)null)
					{
						TextMeshPro obj = val3.AddComponent<TextMeshPro>();
						((TMP_Text)obj).font = ((TMP_Text)component2).font;
						((TMP_Text)obj).text = ((TMP_Text)component2).text;
						((TMP_Text)obj).fontStyle = ((TMP_Text)component2).fontStyle;
						((TMP_Text)obj).alignment = ((TMP_Text)component2).alignment;
						((Graphic)obj).color = ((Graphic)component2).color;
						((TMP_Text)obj).fontSize = ((TMP_Text)component2).fontSize;
						((TMP_Text)obj).rectTransform.sizeDelta = ((TMP_Text)component2).rectTransform.sizeDelta;
						((TMP_Text)obj).ForceMeshUpdate(false, false);
					}
					else
					{
						val3.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
						MeshRenderer obj2 = val3.AddComponent<MeshRenderer>();
						((Renderer)obj2).sharedMaterials = ((Renderer)val2).sharedMaterials;
						((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0;
					}
				}
			}
			return val;
		}

		private static bool IsVisibleInTemplate(Transform t, Transform template)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)template)
			{
				if (!((Component)val).gameObject.activeSelf)
				{
					return false;
				}
				val = val.parent;
			}
			Renderer component = ((Component)t).GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				return component.enabled;
			}
			return false;
		}
	}
	internal static class Mk3Model
	{
		private class Mat
		{
			public string Name;

			public Color Color;

			public float Metallic;

			public float Roughness;

			public Color Emissive;

			public int Flags;
		}

		private class Sub
		{
			public int Material;

			public Vector3[] Positions;

			public Vector3[] Normals;

			public int[] Indices;
		}

		private class Part
		{
			public string Name;

			public Vector3 Pivot;

			public List<Sub> Subs = new List<Sub>();
		}

		private struct Box
		{
			public string Name;

			public Vector3 Center;

			public Vector3 Size;
		}

		private struct Anchor
		{
			public Vector3 Point;

			public Vector3 Normal;
		}

		public const float Scale = 0.7f;

		public const string RootName = "Mk3Model";

		private const string Resource = "BigMixer.mk3model.bin";

		private static List<Mat> mats;

		private static List<Part> parts;

		private static List<Box> boxes;

		private static Dictionary<string, Anchor> anchors;

		private static Material[] built;

		internal static Material[][] LampMaterials;

		public static bool Apply(MixingStationMk2 station)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!Load())
				{
					return false;
				}
				Transform val = ((Component)station).transform.Find("Mixing Station/Mixing station");
				if ((Object)(object)val == (Object)null)
				{
					BigMixerMod.Log.Warning("Mk2 visuals not found; keeping the repainted Mk2 model.");
					return false;
				}
				HideOld(val, out var template, out var colliderLayer);
				BuildMaterials(template);
				GameObject val2 = new GameObject("Mk3Model");
				val2.layer = ((Component)val).gameObject.layer;
				val2.transform.SetParent(((Component)station).transform, false);
				val2.transform.localScale = Vector3.one * 0.7f;
				foreach (Part part in parts)
				{
					BuildPart(val2.transform, part);
				}
				BuildColliders(val2.transform, colliderLayer);
				MoveWorkingParts(station);
				BigMixerMod.Log.Msg("Mk3 custom model applied (" + parts.Count + " parts, base shader " + ((Object)template.shader).name + ").");
				return true;
			}
			catch (Exception ex)
			{
				BigMixerMod.Log.Error("Custom Mk3 model failed, keeping the repainted Mk2 model: " + ex);
				return false;
			}
		}

		private static Vector3 ToStation(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return p * 0.7f;
		}

		private static void HideOld(Transform oldVisuals, out Material template, out int colliderLayer)
		{
			template = null;
			colliderLayer = ((Component)oldVisuals).gameObject.layer;
			Renderer[] componentsInChildren = ((Component)oldVisuals).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)template == (Object)null && (Object)(object)val.sharedMaterial != (Object)null && val.sharedMaterial.HasProperty("_BaseColor"))
				{
					template = val.sharedMaterial;
				}
				val.enabled = false;
			}
			bool flag = true;
			Collider[] componentsInChildren2 = ((Component)oldVisuals).GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if (!val2.isTrigger)
				{
					if (flag)
					{
						colliderLayer = ((Component)val2).gameObject.layer;
						flag = false;
					}
					val2.enabled = false;
				}
			}
			if ((Object)(object)template == (Object)null)
			{
				throw new InvalidOperationException("no URP material on the Mk2 to base the Mk3 materials on");
			}
		}

		private static void BuildMaterials(Material template)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			if (built != null)
			{
				return;
			}
			built = (Material[])(object)new Material[mats.Count];
			for (int i = 0; i < mats.Count; i++)
			{
				built[i] = MakeMaterial(template, mats[i], mats[i].Color, mats[i].Emissive);
			}
			LampMaterials = new Material[3][];
			string[] lampMats = new string[3] { "green", "amber", "red" };
			int j;
			for (j = 0; j < 3; j++)
			{
				Mat mat = mats.Find((Mat x) => x.Name == lampMats[j]) ?? mats[0];
				Color color = mat.Color;
				LampMaterials[j] = (Material[])(object)new Material[2]
				{
					MakeMaterial(template, mat, color * 0.35f, Color.black),
					MakeMaterial(template, mat, color, color * 3f)
				};
			}
		}

		private static Material MakeMaterial(Material template, Mat m, Color linearColor, Color linearEmission)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(template);
			((Object)val).name = "Mk3 " + m.Name;
			((Object)val).hideFlags = (HideFlags)32;
			string[] array = new string[8] { "_BaseMap", "_MainTex", "_BumpMap", "_MetallicGlossMap", "_OcclusionMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
			}
			array = new string[5] { "_NORMALMAP", "_METALLICSPECGLOSSMAP", "_OCCLUSIONMAP", "_DETAIL_MULX2", "_PARALLAXMAP" };
			foreach (string text2 in array)
			{
				val.DisableKeyword(text2);
			}
			Color val2 = new Color(linearColor.r, linearColor.g, linearColor.b, m.Color.a);
			Color gamma = ((Color)(ref val2)).gamma;
			val.SetColor("_BaseColor", gamma);
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", gamma);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", m.Metallic);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", 1f - m.Roughness);
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", ((m.Flags & 2) != 0) ? 0f : 2f);
			}
			if (((Color)(ref linearEmission)).maxColorComponent > 0.001f && val.HasProperty("_EmissionColor"))
			{
				val.EnableKeyword("_EMISSION");
				val.SetColor("_EmissionColor", linearEmission);
				val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
			}
			else
			{
				val.DisableKeyword("_EMISSION");
				if (val.HasProperty("_EmissionColor"))
				{
					val.SetColor("_EmissionColor", Color.black);
				}
			}
			if ((m.Flags & 1) != 0)
			{
				if (val.HasProperty("_Surface"))
				{
					val.SetFloat("_Surface", 1f);
				}
				if (val.HasProperty("_Blend"))
				{
					val.SetFloat("_Blend", 0f);
				}
				val.SetInt("_SrcBlend", 5);
				val.SetInt("_DstBlend", 10);
				val.SetInt("_ZWrite", 0);
				val.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				val.SetOverrideTag("RenderType", "Transparent");
				val.renderQueue = 3000;
			}
			return val;
		}

		private static void BuildPart(Transform root, Part p)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			GameObject val = new GameObject(p.Name);
			val.layer = ((Component)root).gameObject.layer;
			val.transform.SetParent(root, false);
			val.transform.localPosition = p.Pivot;
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			foreach (Sub sub2 in p.Subs)
			{
				list.AddRange(sub2.Positions);
				list2.AddRange(sub2.Normals);
			}
			Mesh val2 = new Mesh();
			((Object)val2).name = "Mk3 " + p.Name;
			((Object)val2).hideFlags = (HideFlags)32;
			val2.indexFormat = (IndexFormat)(list.Count > 65000);
			val2.vertices = list.ToArray();
			val2.normals = list2.ToArray();
			val2.subMeshCount = p.Subs.Count;
			Material[] array = (Material[])(object)new Material[p.Subs.Count];
			int num = 0;
			for (int i = 0; i < p.Subs.Count; i++)
			{
				Sub sub = p.Subs[i];
				int[] array2 = new int[sub.Indices.Length];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = sub.Indices[j] + num;
				}
				val2.SetTriangles(array2, i);
				num += sub.Positions.Length;
				array[i] = built[sub.Material];
			}
			val2.RecalculateBounds();
			val.AddComponent<MeshFilter>().sharedMesh = val2;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = array;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)obj).receiveShadows = true;
		}

		private static void BuildColliders(Transform root, int layer)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Collision");
			val.layer = layer;
			val.transform.SetParent(root, false);
			foreach (Box box in boxes)
			{
				BoxCollider obj = val.AddComponent<BoxCollider>();
				obj.center = box.Center;
				obj.size = new Vector3(Mathf.Max(box.Size.x, 0.02f), Mathf.Max(box.Size.y, 0.02f), Mathf.Max(box.Size.z, 0.02f));
			}
		}

		private static void MoveWorkingParts(MixingStationMk2 station)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)station).transform;
			if ((Object)(object)((MixingStation)station).InputVisuals != (Object)null && anchors.TryGetValue("left_top", out var value))
			{
				CenterGridOn(transform, ((Component)((MixingStation)station).InputVisuals).transform, ToStation(value.Point) + Vector3.up * 0.005f);
			}
			if ((Object)(object)((MixingStation)station).OutputVisuals != (Object)null && anchors.TryGetValue("right_top", out value))
			{
				CenterGridOn(transform, ((Component)((MixingStation)station).OutputVisuals).transform, ToStation(value.Point) + Vector3.up * 0.005f);
			}
			if ((Object)(object)station.ScreenCanvas != (Object)null && anchors.TryGetValue("screen", out value))
			{
				Transform transform2 = ((Component)station.ScreenCanvas).transform;
				transform2.position = transform.TransformPoint(ToStation(value.Point) + value.Normal * 0.004f);
				transform2.rotation = transform.rotation * Quaternion.LookRotation(-value.Normal, Vector3.up);
				float num = 0.0003646409f;
				float num2 = (((Object)(object)transform2.parent != (Object)null) ? transform2.parent.lossyScale.x : 1f);
				transform2.localScale = Vector3.one * (num / num2);
			}
			Vector3 val = ToStation(anchors["bounds_min"].Point);
			Vector3 val2 = ToStation(anchors["bounds_max"].Point);
			Vector3 val3 = (val + val2) * 0.5f;
			Vector3 val4 = val2 - val;
			if ((Object)(object)((BuildableItem)station).BoundingCollider != (Object)null && (Object)(object)((Component)((BuildableItem)station).BoundingCollider).transform.parent == (Object)(object)transform)
			{
				((Component)((BuildableItem)station).BoundingCollider).transform.localPosition = Vector3.zero;
				((BuildableItem)station).BoundingCollider.center = val3;
				((BuildableItem)station).BoundingCollider.size = val4;
			}
			Transform val5 = transform.Find("Outline");
			if (!((Object)(object)val5 != (Object)null))
			{
				return;
			}
			for (int i = 0; i < val5.childCount; i++)
			{
				Transform child = val5.GetChild(i);
				if (i == 0)
				{
					child.localPosition = val3;
					child.localScale = val4;
				}
				else
				{
					((Component)child).gameObject.SetActive(false);
				}
			}
		}

		private static void CenterGridOn(Transform station, Transform grid, Vector3 target)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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)
			if (grid.childCount != 0)
			{
				Bounds val = default(Bounds);
				((Bounds)(ref val))..ctor(station.InverseTransformPoint(grid.GetChild(0).position), Vector3.zero);
				for (int i = 1; i < grid.childCount; i++)
				{
					((Bounds)(ref val)).Encapsulate(station.InverseTransformPoint(grid.GetChild(i).position));
				}
				Vector3 val2 = target - new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y, ((Bounds)(ref val)).center.z);
				grid.position = station.TransformPoint(station.InverseTransformPoint(grid.position) + val2);
			}
		}

		private static bool Load()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if (parts != null)
			{
				return true;
			}
			Stream manifestResourceStream = typeof(Mk3Model).Assembly.GetManifestResourceStream("BigMixer.mk3model.bin");
			if (manifestResourceStream == null)
			{
				BigMixerMod.Log.Warning("Embedded Mk3 model missing; keeping the repainted Mk2 model.");
				return false;
			}
			using (BinaryReader binaryReader = new BinaryReader(manifestResourceStream))
			{
				if (new string(binaryReader.ReadChars(4)) != "MK3M" || binaryReader.ReadInt32() != 1)
				{
					throw new InvalidDataException("bad Mk3 model data");
				}
				List<Mat> list = new List<Mat>();
				for (int num = binaryReader.ReadInt32(); num > 0; num--)
				{
					list.Add(new Mat
					{
						Name = Str(binaryReader),
						Color = Col4(binaryReader),
						Metallic = binaryReader.ReadSingle(),
						Roughness = binaryReader.ReadSingle(),
						Emissive = Col3(binaryReader),
						Flags = binaryReader.ReadInt32()
					});
				}
				List<Part> list2 = new List<Part>();
				for (int num2 = binaryReader.ReadInt32(); num2 > 0; num2--)
				{
					Part part = new Part
					{
						Name = Str(binaryReader),
						Pivot = V3(binaryReader)
					};
					for (int num3 = binaryReader.ReadInt32(); num3 > 0; num3--)
					{
						Sub sub = new Sub
						{
							Material = binaryReader.ReadInt32()
						};
						int num4 = binaryReader.ReadInt32();
						sub.Positions = (Vector3[])(object)new Vector3[num4];
						sub.Normals = (Vector3[])(object)new Vector3[num4];
						for (int i = 0; i < num4; i++)
						{
							sub.Positions[i] = V3(binaryReader);
						}
						for (int j = 0; j < num4; j++)
						{
							sub.Normals[j] = V3(binaryReader);
						}
						sub.Indices = new int[binaryReader.ReadInt32()];
						for (int k = 0; k < sub.Indices.Length; k++)
						{
							sub.Indices[k] = binaryReader.ReadInt32();
						}
						part.Subs.Add(sub);
					}
					list2.Add(part);
				}
				List<Box> list3 = new List<Box>();
				for (int num5 = binaryReader.ReadInt32(); num5 > 0; num5--)
				{
					list3.Add(new Box
					{
						Name = Str(binaryReader),
						Center = V3(binaryReader),
						Size = V3(binaryReader)
					});
				}
				Dictionary<string, Anchor> dictionary = new Dictionary<string, Anchor>();
				for (int num6 = binaryReader.ReadInt32(); num6 > 0; num6--)
				{
					dictionary[Str(binaryReader)] = new Anchor
					{
						Point = V3(binaryReader),
						Normal = V3(binaryReader)
					};
				}
				mats = list;
				boxes = list3;
				anchors = dictionary;
				parts = list2;
			}
			return true;
		}

		private static string Str(BinaryReader r)
		{
			return Encoding.UTF8.GetString(r.ReadBytes(r.ReadInt32()));
		}

		private static Vector3 V3(BinaryReader r)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static Color Col4(BinaryReader r)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static Color Col3(BinaryReader r)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return new Color(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1f);
		}
	}
	public class Mk3Station
	{
		private static readonly Dictionary<int, Mk3Station> all = new Dictionary<int, Mk3Station>();

		public MixingStation Station;

		public ItemSlot ProductSlot2;

		public ItemSlot MixerSlot2;

		public ItemSlot OutputSlot2;

		private bool compacting;

		private Transform beater;

		private Renderer[] lamps;

		private int lampState = -1;

		public static Mk3Station Of(MixingStation station)
		{
			if ((Object)(object)station == (Object)null || !all.TryGetValue(((Object)station).GetInstanceID(), out var value))
			{
				return null;
			}
			return value;
		}

		public static Mk3Station FindByGuid(string guid)
		{
			foreach (Mk3Station value in all.Values)
			{
				if ((Object)(object)value.Station != (Object)null && string.Equals(((BuildableItem)value.Station).GUID.ToString(), guid, StringComparison.OrdinalIgnoreCase))
				{
					return value;
				}
			}
			return null;
		}

		public static void Clear()
		{
			all.Clear();
		}

		public static void UpdateAll(float dt)
		{
			if (all.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, Mk3Station> item in all)
			{
				if ((Object)(object)item.Value.Station == (Object)null)
				{
					(list ?? (list = new List<int>())).Add(item.Key);
				}
				else
				{
					item.Value.Animate(dt);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item2 in list)
			{
				all.Remove(item2);
			}
		}

		private void FindModelParts()
		{
			Transform val = ((Component)Station).transform.Find("Mk3Model");
			if (!((Object)(object)val == (Object)null))
			{
				beater = val.Find("beater");
				lamps = (Renderer[])(object)new Renderer[3];
				for (int i = 0; i < 3; i++)
				{
					Transform val2 = val.Find("tower_lamp_" + i);
					lamps[i] = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Renderer>() : null);
				}
			}
		}

		private void Animate(float dt)
		{
			if (lamps != null)
			{
				bool num = Station.CurrentMixOperation != null && !Station.IsMixingDone;
				bool flag = Station.IsMixingDone || Station.OutputSlot.Quantity > 0;
				if (num && (Object)(object)beater != (Object)null)
				{
					beater.Rotate(0f, 540f * dt, 0f, (Space)1);
				}
				int num2 = (num ? 1 : (flag ? (((int)(Time.time * 2f) % 2 == 0) ? 2 : 0) : 0));
				if (num2 != lampState && Mk3Model.LampMaterials != null)
				{
					lampState = num2;
					SetLamp(0, num2 == 1);
					SetLamp(1, num2 == 2);
					SetLamp(2, on: false);
				}
			}
		}

		private void SetLamp(int i, bool on)
		{
			if ((Object)(object)lamps[i] != (Object)null)
			{
				lamps[i].sharedMaterial = Mk3Model.LampMaterials[i][on ? 1u : 0u];
			}
		}

		public static bool IsMk3Object(MixingStation station)
		{
			return ((Object)((Component)station).gameObject).name.StartsWith("MixingStationMk3", StringComparison.Ordinal);
		}

		public static void Create(MixingStation station)
		{
			Mk3Station mk3Station = new Mk3Station();
			all[((Object)station).GetInstanceID()] = mk3Station;
			mk3Station.Setup(station);
		}

		public ItemSlot SecondOf(ItemSlot first)
		{
			if (Same(first, Station.ProductSlot))
			{
				return ProductSlot2;
			}
			if (Same(first, Station.MixerSlot))
			{
				return MixerSlot2;
			}
			if (Same(first, Station.OutputSlot))
			{
				return OutputSlot2;
			}
			return null;
		}

		public static bool Same(ItemSlot a, ItemSlot b)
		{
			return a == b;
		}

		private void Setup(MixingStation station)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			Station = station;
			ProductSlot2 = NewSlot((ItemFilter)new ItemFilter_UnpackagedProduct(), station.InputVisuals);
			MixerSlot2 = NewSlot((ItemFilter)new ItemFilter_MixingIngredient(), station.InputVisuals);
			OutputSlot2 = NewSlot(null, station.OutputVisuals);
			OutputSlot2.SetIsAddLocked(true);
			station.InputSlots.Add(ProductSlot2);
			station.InputSlots.Add(MixerSlot2);
			station.OutputSlots.Add(OutputSlot2);
			Hook(station.ProductSlot, ProductSlot2);
			Hook(station.MixerSlot, MixerSlot2);
			Hook(station.OutputSlot, OutputSlot2);
			FindModelParts();
		}

		private ItemSlot NewSlot(ItemFilter filter, StorageVisualizer visuals)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ItemSlot val = new ItemSlot(true);
			if (filter != null)
			{
				val.AddFilter(filter);
			}
			val.SetSlotOwner(Station.Cast());
			if ((Object)(object)visuals != (Object)null)
			{
				visuals.AddSlot(val, false);
			}
			val.onItemDataChanged = Compat.Combine(val.onItemDataChanged, Compat.Action(MarkChanged));
			return val;
		}

		private void MarkChanged()
		{
			((BuildableItem)Station).HasChanged = true;
		}

		private void Hook(ItemSlot first, ItemSlot second)
		{
			Action b = Compat.Action(delegate
			{
				Compact(first, second);
			});
			first.onItemDataChanged = Compat.Combine(first.onItemDataChanged, b);
			second.onItemDataChanged = Compat.Combine(second.onItemDataChanged, b);
		}

		private void Compact(ItemSlot first, ItemSlot second)
		{
			if (compacting || !InstanceFinder.IsServer || first.ItemInstance != null || second.ItemInstance == null || first.IsLocked || second.IsLocked)
			{
				return;
			}
			compacting = true;
			try
			{
				ItemInstance copy = second.ItemInstance.GetCopy(second.Quantity);
				second.ClearStoredInstance(false);
				first.SetStoredItem(copy, false);
			}
			finally
			{
				compacting = false;
			}
		}

		public int PairQuantity(ItemSlot first)
		{
			ItemSlot val = SecondOf(first);
			int num = first.Quantity;
			if (val != null && first.ItemInstance != null && val.ItemInstance != null && first.ItemInstance.CanStackWith(val.ItemInstance, false))
			{
				num += val.Quantity;
			}
			return num;
		}
	}
	internal static class StationExtensions
	{
		public static IItemSlotOwner Cast(this MixingStation station)
		{
			return (IItemSlotOwner)(object)station;
		}
	}
	[HarmonyPatch(typeof(MixingStationMk2), "Awake")]
	internal static class Patch_Mk2Awake
	{
		private static void Postfix(MixingStationMk2 __instance)
		{
			if (!((BuildableItem)__instance).isGhost && Mk3Station.IsMk3Object((MixingStation)(object)__instance) && Mk3Station.Of((MixingStation)(object)__instance) == null)
			{
				Mk3Station.Create((MixingStation)(object)__instance);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "GetMixQuantity")]
	internal static class Patch_GetMixQuantity
	{
		private static void Postfix(MixingStation __instance, ref int __result)
		{
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			if (mk3Station != null && !((Object)(object)__instance.GetProduct() == (Object)null) && !((Object)(object)__instance.GetMixer() == (Object)null))
			{
				__result = Mathf.Min(Mathf.Min(mk3Station.PairQuantity(__instance.ProductSlot), mk3Station.PairQuantity(__instance.MixerSlot)), __instance.MaxMixQuantity);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "CanStartMix")]
	internal static class Patch_CanStartMix
	{
		private static void Postfix(MixingStation __instance, ref bool __result)
		{
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			if (mk3Station != null && mk3Station.OutputSlot2.Quantity > 0)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(ItemSlot), "ChangeQuantity")]
	internal static class Patch_ChangeQuantity
	{
		private static void Prefix(ItemSlot __instance, ref int change, bool _internal)
		{
			if (change >= 0 || -change <= __instance.Quantity)
			{
				return;
			}
			MixingStation val = Compat.As<MixingStation>(__instance.SlotOwner);
			Mk3Station mk3Station = Mk3Station.Of(val);
			if (mk3Station != null && (Mk3Station.Same(__instance, val.ProductSlot) || Mk3Station.Same(__instance, val.MixerSlot)))
			{
				ItemSlot val2 = mk3Station.SecondOf(__instance);
				int num = -change - __instance.Quantity;
				if (val2.ItemInstance != null && __instance.ItemInstance != null && __instance.ItemInstance.CanStackWith(val2.ItemInstance, false) && val2.Quantity >= num)
				{
					val2.ChangeQuantity(-num, _internal);
					change = -__instance.Quantity;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "RpcLogic___TryCreateOutputItems_2166136261")]
	internal static class Patch_TryCreateOutputItems
	{
		private static bool Prefix(MixingStation __instance)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			MixOperation currentMixOperation = __instance.CurrentMixOperation;
			if (mk3Station == null || currentMixOperation == null)
			{
				return true;
			}
			ProductDefinition val = default(ProductDefinition);
			if (!currentMixOperation.IsOutputKnown(ref val))
			{
				return false;
			}
			int num = currentMixOperation.Quantity;
			string text = null;
			ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[2] { __instance.OutputSlot, mk3Station.OutputSlot2 };
			foreach (ItemSlot val2 in array)
			{
				if (num <= 0)
				{
					break;
				}
				int num2 = Mathf.Min(num, ((BaseItemDefinition)val).StackLimit);
				QualityItemInstance val3 = Compat.As<QualityItemInstance>(((ItemDefinition)val).GetDefaultInstance(num2));
				val3.SetQuality(currentMixOperation.ProductQuality);
				val2.AddItem((ItemInstance)(object)val3, false);
				text = ((BaseItemInstance)val3).ID;
				num -= num2;
			}
			if (num > 0)
			{
				BigMixerMod.Log.Warning("Mk3 output overflow: " + num + " item(s) didn't fit.");
			}
			if ((Object)(object)NetworkSingleton<ProductManager>.Instance.GetRecipe(currentMixOperation.ProductID, currentMixOperation.IngredientID) == (Object)null)
			{
				NetworkSingleton<ProductManager>.Instance.SendMixRecipe(currentMixOperation.ProductID, currentMixOperation.IngredientID, text);
			}
			__instance.SetMixOperation((NetworkConnection)null, (MixOperation)null, 0);
			return false;
		}
	}
	[HarmonyPatch(typeof(MixingStation), "GetBaseData")]
	internal static class Patch_GetBaseData
	{
		private static void Postfix(MixingStation __instance, BuildableItemData __result)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			Mk3Station mk3Station = Mk3Station.Of(__instance);
			MixingStationData val = Compat.As<MixingStationData>(__result);
			if (mk3Station != null && val != null)
			{
				val.ProductContents = new ItemSet(Compat.SlotList(__instance.ProductSlot, mk3Station.ProductSlot2));
				val.MixerContents = new ItemSet(Compat.SlotList(__instance.MixerSlot, mk3Station.MixerSlot2));
				val.OutputContents = new ItemSet(Compat.SlotList(__instance.OutputSlot, mk3Station.OutputSlot2));
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationLoader), "Load", new Type[] { typeof(DynamicSaveData) })]
	internal static class Patch_LoadDynamic
	{
		private static void Postfix(DynamicSaveData data)
		{
			MixingStationData d = default(MixingStationData);
			if (data.TryExtractBaseData<MixingStationData>(ref d))
			{
				Mk3Load.LoadSeconds(d);
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationLoader), "Load", new Type[] { typeof(string) })]
	internal static class Patch_LoadPath
	{
		private static void Postfix(MixingStationLoader __instance, string mainPath)
		{
			MixingStationData data = Compat.GetData(__instance, mainPath);
			if (data != null)
			{
				Mk3Load.LoadSeconds(data);
			}
		}
	}
	internal static class Mk3Load
	{
		public static void LoadSeconds(MixingStationData d)
		{
			Mk3Station mk3Station = Mk3Station.FindByGuid(((BuildableItemData)d).GUID);
			if (mk3Station != null)
			{
				if (d.ProductContents != null)
				{
					d.ProductContents.LoadTo(mk3Station.ProductSlot2, 1);
				}
				if (d.MixerContents != null)
				{
					d.MixerContents.LoadTo(mk3Station.MixerSlot2, 1);
				}
				if (d.OutputContents != null)
				{
					d.OutputContents.LoadTo(mk3Station.OutputSlot2, 1);
				}
			}
		}
	}
	internal static class Mk3Style
	{
		private static readonly Color Paint = new Color(0.55f, 0.08f, 0.08f);

		private static readonly Color BadgeColor = new Color(0.95f, 0.78f, 0.25f);

		public static void Apply(MixingStationMk2 station)
		{
			Repaint(((Component)station).gameObject);
			AddBadge(station);
		}

		private static void Repaint(GameObject root)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, Material> dictionary = new Dictionary<int, Material>();
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Paint, ref num, ref num2, ref num3);
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			float num4 = default(float);
			float num5 = default(float);
			float num6 = default(float);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)Compat.As<ParticleSystemRenderer>(val) != (Object)null || (Object)(object)((Component)val).GetComponent<TMP_Text>() != (Object)null)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				bool flag = false;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if ((Object)(object)val2 == (Object)null || !val2.HasProperty("_BaseColor"))
					{
						continue;
					}
					Color color = val2.GetColor("_BaseColor");
					Color.RGBToHSV(color, ref num4, ref num5, ref num6);
					if (num5 < 0.25f || num6 < 0.12f)
					{
						continue;
					}
					if (!dictionary.TryGetValue(((Object)val2).GetInstanceID(), out var value))
					{
						value = new Material(val2);
						((Object)value).name = ((Object)val2).name + " (Mk3)";
						Color val3 = Color.HSVToRGB(num, Mathf.Max(num5, num2), Mathf.Min(num6, num3 + 0.15f));
						val3.a = color.a;
						value.SetColor("_BaseColor", val3);
						if (value.HasProperty("_Color"))
						{
							value.SetColor("_Color", val3);
						}
						dictionary[((Object)val2).GetInstanceID()] = value;
					}
					sharedMaterials[j] = value;
					flag = true;
				}
				if (flag)
				{
					val.sharedMaterials = sharedMaterials;
				}
			}
			BigMixerMod.Log.Msg("Mk3 repaint: " + dictionary.Count + " material(s) recoloured.");
		}

		private static void AddBadge(MixingStationMk2 station)
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)station).transform;
			Bounds val = LocalBounds(transform);
			GameObject val2 = new GameObject("Mk3Badge")
			{
				layer = ((Component)station).gameObject.layer
			};
			val2.transform.SetParent(transform, false);
			val2.transform.localPosition = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).center.y + ((Bounds)(ref val)).extents.y * 0.55f, ((Bounds)(ref val)).min.z - 0.004f);
			val2.transform.localRotation = Quaternion.identity;
			TextMeshPro val3 = val2.AddComponent<TextMeshPro>();
			if ((Object)(object)station.QuantityLabel != (Object)null && (Object)(object)((TMP_Text)station.QuantityLabel).font != (Object)null)
			{
				((TMP_Text)val3).font = ((TMP_Text)station.QuantityLabel).font;
			}
			((TMP_Text)val3).text = "MK3";
			((TMP_Text)val3).fontStyle = (FontStyles)1;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
			((Graphic)val3).color = BadgeColor;
			((TMP_Text)val3).enableAutoSizing = false;
			((TMP_Text)val3).fontSize = 1.2f;
			((TMP_Text)val3).rectTransform.sizeDelta = new Vector2(((Bounds)(ref val)).size.x * 0.8f, 0.2f);
		}

		internal static Bounds LocalBounds(Transform root)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds result = default(Bounds);
			MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null || (Object)(object)((Component)val).GetComponent<MeshRenderer>() == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				Matrix4x4 val2 = root.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val4, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val4);
					}
				}
			}
			return result;
		}
	}
	internal static class Mk3Ui
	{
		private const float Gap = 10f;

		private static MixingStationInterface ui;

		private static ItemSlotUI product2;

		private static ItemSlotUI ingredient2;

		private static ItemSlotUI output2;

		private static Mk3Station current;

		private static Action contentsChanged;

		private static bool dumped;

		public static void Opened(MixingStationInterface face, MixingStation station)
		{
			EnsureClones(face);
			current = Mk3Station.Of(station);
			bool flag = current != null;
			((Component)product2).gameObject.SetActive(flag);
			((Component)ingredient2).gameObject.SetActive(flag);
			((Component)output2).gameObject.SetActive(false);
			if (flag)
			{
				if (BigMixerMod.DevDump.Value && !dumped)
				{
					dumped = true;
					DumpUi(((Component)face).transform);
				}
				product2.AssignSlot(current.ProductSlot2);
				ingredient2.AssignSlot(current.MixerSlot2);
				output2.AssignSlot(current.OutputSlot2);
				Subscribe(on: true);
				UpdateOutput(face);
			}
		}

		public static void Closed()
		{
			if (current != null)
			{
				Subscribe(on: false);
				product2.ClearSlot();
				ingredient2.ClearSlot();
				output2.ClearSlot();
				current = null;
			}
		}

		public static void UpdateOutput(MixingStationInterface face)
		{
			if (!((Object)(object)output2 == (Object)null))
			{
				((Component)output2).gameObject.SetActive(current != null && ((Component)face.OutputSlotUI).gameObject.activeSelf);
			}
		}

		private static void Subscribe(bool on)
		{
			ItemSlot[] array = (ItemSlot[])(object)new ItemSlot[3] { current.ProductSlot2, current.MixerSlot2, current.OutputSlot2 };
			foreach (ItemSlot val in array)
			{
				val.onItemDataChanged = (on ? Compat.Combine(val.onItemDataChanged, contentsChanged) : Compat.Remove(val.onItemDataChanged, contentsChanged));
			}
		}

		private static void EnsureClones(MixingStationInterface face)
		{
			if (!((Object)(object)ui == (Object)(object)face) || !((Object)(object)product2 != (Object)null))
			{
				ui = face;
				product2 = CloneBelow(face.ProductSlotUI, "ProductSlot2");
				ingredient2 = CloneBelow(face.IngredientSlotUI, "IngredientSlot2");
				output2 = CloneBelow(face.OutputSlotUI, "OutputSlot2");
				contentsChanged = Compat.Action(delegate
				{
					Compat.StationContentsChanged(face);
				});
			}
		}

		private static ItemSlotUI CloneBelow(ItemSlotUI original, string name)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)original).GetComponent<RectTransform>();
			GameObject val = Object.Instantiate<GameObject>(((Component)original).gameObject, ((Transform)component).parent);
			((Object)val).name = name;
			val.GetComponent<ItemSlotUI>().ClearSlot();
			LayoutElement val2 = val.GetComponent<LayoutElement>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<LayoutElement>();
			}
			val2.ignoreLayout = true;
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = component.anchorMin;
			component2.anchorMax = component.anchorMax;
			component2.pivot = component.pivot;
			component2.sizeDelta = component.sizeDelta;
			Vector2 anchoredPosition = component.anchoredPosition;
			Rect rect = component.rect;
			component2.anchoredPosition = anchoredPosition - new Vector2(0f, ((Rect)(ref rect)).height + 10f);
			val.SetActive(false);
			return val.GetComponent<ItemSlotUI>();
		}

		private static void DumpUi(Transform root)
		{
			StringBuilder stringBuilder = new StringBuilder("MixingStationInterface dump:\n");
			Dump(root, 0, stringBuilder);
			BigMixerMod.Log.Msg(stringBuilder.ToString());
		}

		private static void Dump(Transform t, int depth, StringBuilder sb)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (depth <= 7)
			{
				sb.Append(' ', depth * 2).Append(((Object)t).name);
				if (!((Component)t).gameObject.activeSelf)
				{
					sb.Append(" [off]");
				}
				RectTransform component = ((Component)t).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					StringBuilder stringBuilder = sb.Append(" pos=");
					Vector2 val = component.anchoredPosition;
					StringBuilder stringBuilder2 = stringBuilder.Append(((Vector2)(ref val)).ToString("F0")).Append(" size=");
					Rect rect = component.rect;
					val = ((Rect)(ref rect)).size;
					stringBuilder2.Append(((Vector2)(ref val)).ToString("F0"));
				}
				if ((Object)(object)((Component)t).GetComponent<LayoutGroup>() != (Object)null)
				{
					sb.Append(" [layout]");
				}
				sb.Append('\n');
				for (int i = 0; i < t.childCount; i++)
				{
					Dump(t.GetChild(i), depth + 1, sb);
				}
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "Open")]
	internal static class Patch_UiOpen
	{
		private static void Postfix(MixingStationInterface __instance, MixingStation station)
		{
			Mk3Ui.Opened(__instance, station);
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "Close")]
	internal static class Patch_UiClose
	{
		private static void Prefix()
		{
			Mk3Ui.Closed();
		}
	}
	[HarmonyPatch(typeof(MixingStationInterface), "UpdateDisplayMode")]
	internal static class Patch_UiDisplayMode
	{
		private static void Postfix(MixingStationInterface __instance)
		{
			Mk3Ui.UpdateOutput(__instance);
		}
	}
	internal static class OscarShop
	{
		public static bool TryAddListing()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if ((Object)(object)Mk3Factory.Definition == (Object)null)
			{
				return false;
			}
			Oscar val = Object.FindObjectOfType<Oscar>();
			if ((Object)(object)val == (Object)null || (Object)(object)val.ShopInterface == (Object)null)
			{
				return false;
			}
			ShopInterface shopInterface = val.ShopInterface;
			if (shopInterface.GetListing("mixingstationmk3") != null)
			{
				return true;
			}
			ShopListing val2 = new ShopListing();
			val2.name = "Mixing Station Mk3";
			val2.Item = (StorableItemDefinition)(object)Mk3Factory.Definition;
			val2.CanBeDelivered = false;
			shopInterface.Listings.Add(val2);
			Compat.CreateListingUI(shopInterface, val2);
			val2.Initialize(shopInterface);
			Compat.RefreshShownItems(shopInterface);
			BigMixerMod.Log.Msg("Added Mixing Station Mk3 to " + shopInterface.ShopName + " for $" + val2.Price + ".");
			return true;
		}
	}
}