Decompiled source of MEDVAC Healer Drone v1.8.4

MEDVAC.HealerDrone.dll

Decompiled 8 hours 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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MEDVAC Healer Drone")]
[assembly: AssemblyProduct("MEDVAC.HealerDrone")]
[assembly: AssemblyCopyright("MEDVAC")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 MEDVAC.HealerDrone
{
	internal static class Compat
	{
		private static bool _patched;

		private static float _lastForce;

		private static float _lastKick;

		internal static void PatchAll(Harmony harmony)
		{
			if (harmony != null && !_patched)
			{
				_patched = true;
				Plugin.Log.LogInfo((object)"Compat ready (no extra Harmony on More Shop Items / other mods).");
			}
		}

		private static void PatchAssembly(Harmony harmony, string asmHint, params string[] methodHints)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					string text = "";
					try
					{
						text = assembly.GetName().Name ?? "";
					}
					catch
					{
						continue;
					}
					if (text.IndexOf(asmHint, StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					Type[] types = assembly.GetTypes();
					for (int j = 0; j < types.Length; j++)
					{
						MethodInfo[] methods = types[j].GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (MethodInfo methodInfo in methods)
						{
							if (methodInfo.IsAbstract || methodInfo.ContainsGenericParameters)
							{
								continue;
							}
							bool flag = false;
							foreach (string value in methodHints)
							{
								if (methodInfo.Name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
								{
									flag = true;
									break;
								}
							}
							if (flag)
							{
								try
								{
									harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Compat), "AfterOtherMod", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
								}
								catch
								{
								}
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Compat " + asmHint + " skipped: " + ex.Message));
			}
		}

		private static void AfterOtherMod()
		{
			ShopRegistry.ClampShopCaps();
		}
	}
	internal static class MedkitTable
	{
		internal static readonly int[] Packs = new int[3] { 25, 50, 100 };

		internal static int WasteMax(int packHp)
		{
			if (packHp <= 25)
			{
				return 5;
			}
			if (packHp <= 50)
			{
				return 10;
			}
			return 15;
		}

		internal static bool CanSip(int tankHp, int tankMax, int packHp)
		{
			if (packHp <= 0 || tankMax <= 0)
			{
				return false;
			}
			int num = tankMax - tankHp;
			if (num <= 0)
			{
				return false;
			}
			return Mathf.Max(0, packHp - num) <= WasteMax(packHp);
		}

		internal static int Give(int tankHp, int tankMax, int packHp)
		{
			if (!CanSip(tankHp, tankMax, packHp))
			{
				return 0;
			}
			return Mathf.Min(tankMax - tankHp, packHp);
		}

		internal static void LogOnce()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("MEDVAC refill table (sip if overflow <= pack limit):");
			stringBuilder.AppendLine("pack 25 => max waste 5 | pack 50 => 10 | pack 100 => 15");
			Tier[] tiers = Plugin.Tiers;
			foreach (Tier tier in tiers)
			{
				int tankHp = tier.TankHp;
				stringBuilder.Append(tier.Name).Append(' ').Append(tankHp)
					.Append("HP:");
				int[] packs = Packs;
				foreach (int num in packs)
				{
					int num2 = num - WasteMax(num);
					if (num2 > tankHp)
					{
						stringBuilder.Append("  ").Append(num).Append("=never");
						continue;
					}
					int value = Mathf.Max(0, tankHp - num2);
					stringBuilder.Append("  ").Append(num).Append("HP@0-")
						.Append(value);
				}
				stringBuilder.AppendLine();
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}
	}
	internal static class MedvacIcon
	{
		private static Sprite _sprite;

		private static Texture2D _tex;

		internal static Sprite Sprite
		{
			get
			{
				if ((Object)(object)_sprite == (Object)null)
				{
					Build();
				}
				return _sprite;
			}
		}

		internal static Texture2D Texture
		{
			get
			{
				if ((Object)(object)_tex == (Object)null)
				{
					Build();
				}
				return _tex;
			}
		}

		private static void Build()
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			_tex = new Texture2D(2, 2, (TextureFormat)4, false);
			((Texture)_tex).filterMode = (FilterMode)1;
			((Texture)_tex).wrapMode = (TextureWrapMode)1;
			byte[] array = null;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MEDVAC.icon.png"))
			{
				if (stream != null)
				{
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
			}
			if (array != null && array.Length != 0)
			{
				ImageConversion.LoadImage(_tex, array, false);
			}
			((Object)_tex).name = "MEDVAC Icon";
			_sprite = Sprite.Create(_tex, new Rect(0f, 0f, (float)((Texture)_tex).width, (float)((Texture)_tex).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)_sprite).name = "MEDVAC Icon";
		}
	}
	internal static class MedvacNet
	{
		internal const byte ConvertEvent = 183;

		internal const byte TankEvent = 184;

		private static bool _hooked;

		internal static void Hook()
		{
			try
			{
				if (PhotonNetwork.NetworkingClient != null)
				{
					PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
					PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
					_hooked = true;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("MedvacNet hook: " + ex.Message));
			}
		}

		internal static bool IsMultiplayer()
		{
			try
			{
				return SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom;
			}
			catch
			{
				return PhotonNetwork.InRoom;
			}
		}

		internal static bool IsMaster()
		{
			try
			{
				if (!IsMultiplayer())
				{
					return true;
				}
				return PhotonNetwork.IsMasterClient;
			}
			catch
			{
				return true;
			}
		}

		internal static GameObject Spawn(Item item, Vector3 pos, Quaternion rot)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			GameObject val = null;
			if (IsMultiplayer() && IsMaster())
			{
				val = ShopRegistry.SpawnViaRepoLib(item, pos, rot);
				if ((Object)(object)val == (Object)null)
				{
					string[] array = new string[5]
					{
						ShopRegistry.VanillaPhotonId,
						"Items/Item Drone Feather",
						"Items/Item Drone Heal",
						"Items/Item Drone Battery",
						"Items/Item Drone Indestructible"
					};
					foreach (string text in array)
					{
						if (string.IsNullOrEmpty(text))
						{
							continue;
						}
						try
						{
							val = PhotonNetwork.InstantiateRoomObject(text, pos, rot, (byte)0, (object[])null);
							if ((Object)(object)val != (Object)null)
							{
								break;
							}
						}
						catch (Exception ex)
						{
							Plugin.Log.LogDebug((object)("Photon " + text + ": " + ex.Message));
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null && (!IsMultiplayer() || IsMaster()))
			{
				GameObject val2 = ShopRegistry.Alive(ShopRegistry.GetTemplate(item)) ?? ShopRegistry.Alive(ShopRegistry.VanillaPrefab);
				if ((Object)(object)val2 != (Object)null)
				{
					val = Object.Instantiate<GameObject>(val2, pos, rot);
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			val.SetActive(true);
			ShopRegistry.ConvertToHealer(val, item);
			BroadcastConvert(val, item);
			return val;
		}

		internal static void BroadcastConvert(GameObject go, Item item)
		{
			//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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go == (Object)null || (Object)(object)item == (Object)null || !IsMultiplayer() || !IsMaster())
			{
				return;
			}
			PhotonView val = go.GetComponent<PhotonView>() ?? go.GetComponentInChildren<PhotonView>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				object[] array = new object[3]
				{
					val.ViewID,
					item.itemName ?? "",
					((Object)item).name ?? ""
				};
				RaiseEventOptions val2 = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0,
					CachingOption = (EventCaching)4
				};
				PhotonNetwork.RaiseEvent((byte)183, (object)array, val2, SendOptions.SendReliable);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("BroadcastConvert: " + ex.Message));
			}
		}

		internal static void BroadcastTank(MedvacRuntime rt)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007f: Expected O, but got Unknown
			if ((Object)(object)rt == (Object)null || !IsMultiplayer() || !IsMaster())
			{
				return;
			}
			PhotonView val = ((Component)rt).GetComponent<PhotonView>() ?? ((Component)rt).GetComponentInChildren<PhotonView>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				PhotonNetwork.RaiseEvent((byte)184, (object)new object[3] { val.ViewID, rt.tankHp, rt.tankMax }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
			catch
			{
			}
		}

		private static void OnEvent(EventData e)
		{
			try
			{
				if (e.Code == 183)
				{
					if (e.CustomData is object[] array && array.Length >= 3)
					{
						int viewId = Convert.ToInt32(array[0]);
						string itemName = (array[1] as string) ?? "";
						string assetName = (array[2] as string) ?? "";
						if ((Object)(object)Plugin.Instance != (Object)null)
						{
							((MonoBehaviour)Plugin.Instance).StartCoroutine(ApplyConvert(viewId, itemName, assetName));
						}
					}
				}
				else
				{
					if (e.Code != 184 || !(e.CustomData is object[] array2) || array2.Length < 3)
					{
						return;
					}
					int num = Convert.ToInt32(array2[0]);
					int tankHp = Convert.ToInt32(array2[1]);
					int tankMax = Convert.ToInt32(array2[2]);
					PhotonView val = PhotonView.Find(num);
					if (!((Object)(object)val == (Object)null))
					{
						MedvacRuntime medvacRuntime = ((Component)val).GetComponent<MedvacRuntime>() ?? ((Component)val).GetComponentInChildren<MedvacRuntime>();
						if (!((Object)(object)medvacRuntime == (Object)null))
						{
							medvacRuntime.tankHp = tankHp;
							medvacRuntime.tankMax = tankMax;
							medvacRuntime.SyncBattery();
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("MedvacNet event: " + ex.Message));
			}
		}

		private static IEnumerator ApplyConvert(int viewId, string itemName, string assetName)
		{
			for (int i = 0; i < 60; i++)
			{
				PhotonView val = PhotonView.Find(viewId);
				if ((Object)(object)val != (Object)null)
				{
					Item val2 = ShopRegistry.FindMedvacItem(itemName, assetName);
					if ((Object)(object)val2 != (Object)null)
					{
						ShopRegistry.ConvertToHealer(((Component)val).gameObject, val2);
					}
					yield break;
				}
				yield return (object)new WaitForSeconds(0.1f);
			}
			Plugin.Log.LogWarning((object)("Client never saw PhotonView " + viewId + " for " + itemName));
		}
	}
	public class MedvacVisual : MonoBehaviour
	{
		private const float S = 0.24f;

		private Transform[] _rotors;

		private Light _plusLight;

		private Transform _bob;

		private float _t;

		private MeshRenderer[] _pips;

		private Material _pipOn;

		private Material _pipOff;

		private int _lastLit = -1;

		private void Start()
		{
			HideVanilla();
			Build();
			SetupGrabVolume();
		}

		private void Update()
		{
			float deltaTime = Time.deltaTime;
			_t += deltaTime;
			if (_rotors == null)
			{
				return;
			}
			float num = 720f * deltaTime;
			for (int i = 0; i < _rotors.Length; i++)
			{
				if (!((Object)(object)_rotors[i] == (Object)null))
				{
					_rotors[i].Rotate(0f, num * ((i % 2 == 0) ? 1f : (-1f)), 0f, (Space)1);
				}
			}
		}

		internal void RefreshPips()
		{
			UpdatePips();
		}

		private void UpdatePips()
		{
			if (_pips == null)
			{
				return;
			}
			MedvacRuntime medvacRuntime = ((Component)this).GetComponent<MedvacRuntime>() ?? ((Component)this).GetComponentInParent<MedvacRuntime>();
			int num = Mathf.Clamp(Mathf.CeilToInt((((Object)(object)medvacRuntime != (Object)null) ? medvacRuntime.Fill01 : 1f) * (float)_pips.Length - 0.001f), 0, _pips.Length);
			if (num == _lastLit)
			{
				return;
			}
			_lastLit = num;
			for (int i = 0; i < _pips.Length; i++)
			{
				if (!((Object)(object)_pips[i] == (Object)null))
				{
					((Renderer)_pips[i]).sharedMaterial = ((i < num) ? _pipOn : _pipOff);
				}
			}
		}

		private void SetupGrabVolume()
		{
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)this).transform.Find("MV_Grab");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			PhysGrabObject val2 = ((Component)this).GetComponent<PhysGrabObject>() ?? ((Component)this).GetComponentInParent<PhysGrabObject>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.grabDisableTimer = 0f;
			}
			ItemAttributes val3 = ((Component)this).GetComponent<ItemAttributes>() ?? ((Component)this).GetComponentInParent<ItemAttributes>();
			if ((Object)(object)val3 != (Object)null)
			{
				val3.disableUI = false;
			}
			int num = -1;
			PhysGrabObjectCollider[] componentsInChildren = ((Component)this).GetComponentsInChildren<PhysGrabObjectCollider>(true);
			PhysGrabObjectCollider[] array = componentsInChildren;
			foreach (PhysGrabObjectCollider val4 in array)
			{
				if (!((Object)(object)val4 == (Object)null) && !(((Object)((Component)val4).gameObject).name == "MV_Grab"))
				{
					num = ((Component)val4).gameObject.layer;
					Enlarge(((Component)val4).gameObject, ((Component)this).transform);
				}
			}
			if (num < 0)
			{
				Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Collider>(true);
				foreach (Collider val5 in componentsInChildren2)
				{
					if (!((Object)(object)val5 == (Object)null) && !((Object)((Component)val5).gameObject).name.StartsWith("MV_") && ((Component)val5).gameObject.layer != 0)
					{
						num = ((Component)val5).gameObject.layer;
						break;
					}
				}
			}
			if (num < 0 && (Object)(object)val2 != (Object)null)
			{
				num = ((Component)val2).gameObject.layer;
			}
			if (num < 0)
			{
				num = ((Component)this).gameObject.layer;
			}
			if (componentsInChildren.Length == 0 && (Object)(object)val2 != (Object)null)
			{
				GameObject gameObject = ((Component)val2).gameObject;
				gameObject.layer = num;
				BoxCollider val6 = gameObject.GetComponent<BoxCollider>();
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = gameObject.AddComponent<BoxCollider>();
				}
				val6.size = new Vector3(0.52f, 0.48f, 0.52f);
				val6.center = new Vector3(0f, 0.04f, 0f);
				((Collider)val6).isTrigger = false;
				((Collider)val6).enabled = true;
				PhysGrabObjectCollider val7 = gameObject.GetComponent<PhysGrabObjectCollider>();
				if ((Object)(object)val7 == (Object)null)
				{
					val7 = gameObject.AddComponent<PhysGrabObjectCollider>();
				}
				val7.colliderID = 1;
				AccessTools.Field(typeof(PhysGrabObjectCollider), "physGrabObject")?.SetValue(val7, val2);
				if (val2.colliders != null && !val2.colliders.Contains(gameObject.transform))
				{
					val2.colliders.Add(gameObject.transform);
				}
			}
			Plugin.Log.LogInfo((object)("Grab setup: layer=" + num + " markers=" + ((Component)this).GetComponentsInChildren<PhysGrabObjectCollider>(true).Length));
		}

		private static void Enlarge(GameObject host, Transform root)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_005c: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b9: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0.58f, 0.54f, 0.56f);
			Vector3 lossyScale = host.transform.lossyScale;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x / Mathf.Max(0.001f, Mathf.Abs(lossyScale.x)), val.y / Mathf.Max(0.001f, Mathf.Abs(lossyScale.y)), val.z / Mathf.Max(0.001f, Mathf.Abs(lossyScale.z)));
			Vector3 center = host.transform.InverseTransformPoint(root.TransformPoint(new Vector3(0f, 0.04f, 0f)));
			BoxCollider component = host.GetComponent<BoxCollider>();
			if ((Object)(object)component != (Object)null)
			{
				component.size = Vector3.Max(component.size, val2);
				component.center = center;
				((Collider)component).enabled = true;
				((Collider)component).isTrigger = false;
			}
			SphereCollider component2 = host.GetComponent<SphereCollider>();
			if ((Object)(object)component2 != (Object)null)
			{
				float num = 0.34f / Mathf.Max(0.001f, Mathf.Max(new float[3]
				{
					Mathf.Abs(lossyScale.x),
					Mathf.Abs(lossyScale.y),
					Mathf.Abs(lossyScale.z)
				}));
				component2.radius = Mathf.Max(component2.radius, num);
				component2.center = center;
				((Collider)component2).enabled = true;
				((Collider)component2).isTrigger = false;
			}
			CapsuleCollider component3 = host.GetComponent<CapsuleCollider>();
			if ((Object)(object)component3 != (Object)null)
			{
				float num2 = Mathf.Max(0.001f, Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.z)));
				component3.radius = Mathf.Max(component3.radius, 0.28f / num2);
				component3.height = Mathf.Max(component3.height, 0.54f / Mathf.Max(0.001f, Mathf.Abs(lossyScale.y)));
				component3.center = center;
				((Collider)component3).enabled = true;
			}
			if ((Object)(object)component == (Object)null && (Object)(object)component2 == (Object)null && (Object)(object)component3 == (Object)null)
			{
				BoxCollider obj = host.AddComponent<BoxCollider>();
				obj.size = val2;
				obj.center = center;
				((Collider)obj).isTrigger = false;
			}
		}

		private void HideVanilla()
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)((Component)val).transform).name.StartsWith("MV_"))
				{
					val.enabled = false;
				}
			}
		}

		private void Build()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Expected O, but got Unknown
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0707: Unknown result type (might be due to invalid IL or missing references)
			//IL_070c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0716: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_075b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07da: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_080f: Unknown result type (might be due to invalid IL or missing references)
			//IL_082e: Unknown result type (might be due to invalid IL or missing references)
			//IL_084f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0863: Unknown result type (might be due to invalid IL or missing references)
			//IL_0882: Unknown result type (might be due to invalid IL or missing references)
			//IL_0891: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_08de: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0916: Unknown result type (might be due to invalid IL or missing references)
			//IL_0928: Unknown result type (might be due to invalid IL or missing references)
			//IL_093c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0951: Unknown result type (might be due to invalid IL or missing references)
			//IL_0965: Unknown result type (might be due to invalid IL or missing references)
			//IL_0990: Unknown result type (might be due to invalid IL or missing references)
			//IL_09bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a04: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a09: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a13: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a36: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a45: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a69: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a6e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a78: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ab5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0adb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b77: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b8b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bcf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)this).transform.Find("MV_Root") != (Object)null)
			{
				return;
			}
			Transform transform = new GameObject("MV_Root").transform;
			transform.SetParent(((Component)this).transform, false);
			transform.localPosition = Vector3.zero;
			transform.localRotation = Quaternion.identity;
			transform.localScale = Vector3.one * 0.24f;
			_bob = new GameObject("MV_Bob").transform;
			_bob.SetParent(transform, false);
			Material mat = Mat(new Color(0.89f, 0.93f, 0.95f), 0f, 0.38f, 0.16f);
			Material val = Mat(new Color(0.23f, 0.66f, 0.64f), 0.25f, 0.32f, 0.28f);
			Material mat2 = Mat(new Color(0.11f, 0.14f, 0.16f), 0f, 0.4f, 0.4f);
			Material mat3 = Mat(new Color(0.78f, 1f, 0.88f), 1.15f, 0.22f, 0.05f);
			Material mat4 = Mat(new Color(1f, 0.45f, 0.45f), 0.9f, 0.3f, 0.08f);
			Material mat5 = Mat(new Color(0.78f, 1f, 0.97f), 1.2f, 0.2f, 0.05f);
			Material mat6 = Mat(new Color(0.1f, 0.11f, 0.13f), 0f, 0.48f, 0.25f);
			Material mat7 = Mat(new Color(0.04f, 0.05f, 0.07f), 0f, 0.12f, 0.85f);
			Material mat8 = (_pipOn = Mat(new Color(0.6f, 1f, 0.77f), 1.1f, 0.25f, 0.05f));
			_pipOff = Mat(new Color(0.12f, 0.18f, 0.14f), 0f, 0.4f, 0.1f);
			Material mat9 = Mat(new Color(1f, 0.84f, 0.42f), 0.9f, 0.25f, 0.05f);
			Prim((PrimitiveType)3, "MV_Body", _bob, Vector3.zero, new Vector3(1.64f, 1.54f, 1.46f), mat);
			Corner(val, _bob, 1.64f, 1.54f, 1.46f, 1, 1);
			Corner(val, _bob, 1.64f, 1.54f, 1.46f, 1, -1);
			Corner(val, _bob, 1.64f, 1.54f, 1.46f, -1, 1);
			Corner(val, _bob, 1.64f, 1.54f, 1.46f, -1, -1);
			int[] array = new int[2] { -1, 1 };
			float[] array2;
			foreach (int num in array)
			{
				array2 = new float[3] { -0.2f, 0f, 0.2f };
				foreach (float num2 in array2)
				{
					Prim((PrimitiveType)3, "MV_Vent", _bob, new Vector3((float)num * 0.83f, num2, 0.04f), new Vector3(0.03f, 0.055f, 0.4f), mat2);
				}
			}
			array = new int[2] { -1, 1 };
			foreach (int num3 in array)
			{
				int[] array3 = new int[2] { -1, 1 };
				foreach (int num4 in array3)
				{
					Prim((PrimitiveType)2, "MV_LED", _bob, new Vector3((float)num3 * 0.52f, -0.78f, (float)num4 * 0.42f), new Vector3(0.07f, 0.012f, 0.07f), mat5);
				}
			}
			Prim((PrimitiveType)3, "MV_Bay", _bob, new Vector3(0f, 0.02f, 0.75f), new Vector3(1.18f, 1.14f, 0.05f), mat2);
			Prim((PrimitiveType)3, "MV_PlusH", _bob, new Vector3(0f, 0.02f, 0.785f), new Vector3(0.78f, 0.22f, 0.05f), mat3);
			Prim((PrimitiveType)3, "MV_PlusV", _bob, new Vector3(0f, 0.02f, 0.785f), new Vector3(0.22f, 0.78f, 0.05f), mat3);
			Prim((PrimitiveType)3, "MV_RedPlusH", _bob, new Vector3(0.4f, 0.4f, 0.79f), new Vector3(0.2f, 0.055f, 0.03f), mat4);
			Prim((PrimitiveType)3, "MV_RedPlusV", _bob, new Vector3(0.4f, 0.4f, 0.79f), new Vector3(0.055f, 0.2f, 0.03f), mat4);
			Frame(mat5, _bob, 1.28f, 1.22f, 0.77000004f, 0.045f);
			Prim((PrimitiveType)3, "MV_Gasket", _bob, new Vector3(0f, 0.782f, 0f), new Vector3(1.5f, 0.03f, 1.32f), val);
			GameObject val2 = new GameObject("MV_PlusLight");
			val2.transform.SetParent(_bob, false);
			val2.transform.localPosition = new Vector3(0f, 0.05f, 0.93f);
			_plusLight = val2.AddComponent<Light>();
			_plusLight.type = (LightType)2;
			_plusLight.color = new Color(0.35f, 1f, 0.55f);
			_plusLight.range = 1.2f;
			_plusLight.intensity = 0.35f;
			_plusLight.shadows = (LightShadows)0;
			_plusLight.renderMode = (LightRenderMode)2;
			Prim((PrimitiveType)0, "MV_Dome", _bob, new Vector3(0f, 0.78999996f, 0.22f), Vector3.one * 0.31f, mat7).localScale = new Vector3(0.31f, 0.16f, 0.31f);
			Prim((PrimitiveType)0, "MV_Amber", _bob, new Vector3(-0.22f, 0.82f, 0.32f), Vector3.one * 0.055f, mat9);
			Prim((PrimitiveType)0, "MV_Cyan", _bob, new Vector3(0.22f, 0.82f, 0.3f), Vector3.one * 0.05f, mat5);
			_rotors = (Transform[])(object)new Transform[4];
			float[] array4 = new float[4] { 45f, 135f, 225f, 315f };
			for (int k = 0; k < 4; k++)
			{
				Transform transform2 = new GameObject("MV_Arm" + k).transform;
				transform2.SetParent(_bob, false);
				transform2.localRotation = Quaternion.Euler(0f, array4[k], 0f);
				((Component)Prim((PrimitiveType)2, "MV_Shoulder", transform2, new Vector3(0.78f, 0.52f, 0f), new Vector3(0.24f, 0.13f, 0.24f), mat)).transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
				((Component)Prim((PrimitiveType)2, "MV_Boom", transform2, new Vector3(1.19f, 0.52f, 0f), new Vector3(0.15f, 0.31f, 0.15f), mat)).transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
				((Component)Prim((PrimitiveType)2, "MV_Collar", transform2, new Vector3(1.14f, 0.52f, 0f), new Vector3(0.2f, 0.05f, 0.2f), val)).transform.localRotation = Quaternion.Euler(0f, 0f, 90f);
				Transform transform3 = new GameObject("MV_Motor").transform;
				transform3.SetParent(transform2, false);
				transform3.localPosition = new Vector3(1.5f, 0.78f, 0f);
				Prim((PrimitiveType)3, "MV_MotorBody", transform3, Vector3.zero, new Vector3(0.44f, 0.17f, 0.44f), mat);
				Transform transform4 = new GameObject("MV_Rotor").transform;
				transform4.SetParent(transform3, false);
				transform4.localPosition = new Vector3(0f, 0.22f, 0f);
				Prim((PrimitiveType)3, "MV_BladeA", transform4, Vector3.zero, new Vector3(1.5f, 0.016f, 0.1f), mat6);
				Prim((PrimitiveType)3, "MV_BladeB", transform4, Vector3.zero, new Vector3(0.1f, 0.016f, 1.5f), mat6);
				_rotors[k] = transform4;
			}
			Transform transform5 = new GameObject("MV_Gimbal").transform;
			transform5.SetParent(_bob, false);
			transform5.localPosition = new Vector3(0f, -0.96f, 0f);
			Prim((PrimitiveType)2, "MV_Neck", transform5, Vector3.zero, new Vector3(0.22f, 0.05f, 0.22f), val);
			Prim((PrimitiveType)0, "MV_Ball", transform5, new Vector3(0f, -0.16f, 0f), Vector3.one * 0.31f, mat);
			Prim((PrimitiveType)0, "MV_Lens", transform5, new Vector3(0f, -0.22f, 0.07f), Vector3.one * 0.18f, mat7);
			Prim((PrimitiveType)0, "MV_Lens2", transform5, new Vector3(0.055f, -0.2f, -0.055f), Vector3.one * 0.1f, mat7);
			Transform transform6 = new GameObject("MV_HUD").transform;
			transform6.SetParent(_bob, false);
			transform6.localPosition = new Vector3(0f, 0.86f, 0.74f);
			Prim((PrimitiveType)3, "MV_HudBack", transform6, Vector3.zero, new Vector3(1.24f, 0.17f, 0.05f), mat2);
			_pips = (MeshRenderer[])(object)new MeshRenderer[10];
			for (int l = 0; l < 10; l++)
			{
				_pips[l] = ((Component)Prim((PrimitiveType)3, "MV_Pip" + l, transform6, new Vector3(-0.52f + (float)l * 0.104f, 0f, 0.03f), new Vector3(0.086f, 0.11f, 0.02f), mat8)).GetComponent<MeshRenderer>();
			}
			Prim((PrimitiveType)3, "MV_Nub", transform6, new Vector3(0.66f, 0f, 0f), new Vector3(0.07f, 0.09f, 0.03f), mat2);
			array2 = new float[3] { -0.1f, 0f, 0.1f };
			foreach (float num5 in array2)
			{
				Prim((PrimitiveType)3, "MV_Pin", transform6, new Vector3(num5, -0.175f, 0f), new Vector3(0.028f, 0.1f, 0.02f), mat8);
			}
		}

		private static void Corner(Material teal, Transform parent, float bw, float bh, float bd, int sx, int sy)
		{
			//IL_0037: 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)
			Prim((PrimitiveType)3, "MV_Corner", parent, new Vector3((float)sx * (bw / 2f - 0.12f), (float)sy * (bh / 2f - 0.12f), bd / 2f + 0.01f), new Vector3(0.2f, 0.2f, 0.03f), teal);
		}

		private static void Frame(Material mat, Transform parent, float w, float h, float z, float t)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_006d: 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_0098: 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)
			Prim((PrimitiveType)3, "MV_FrmT", parent, new Vector3(0f, h / 2f, z), new Vector3(w, t, t), mat);
			Prim((PrimitiveType)3, "MV_FrmB", parent, new Vector3(0f, (0f - h) / 2f, z), new Vector3(w, t, t), mat);
			Prim((PrimitiveType)3, "MV_FrmL", parent, new Vector3((0f - w) / 2f, 0f, z), new Vector3(t, h, t), mat);
			Prim((PrimitiveType)3, "MV_FrmR", parent, new Vector3(w / 2f, 0f, z), new Vector3(t, h, t), mat);
		}

		private static Transform Prim(PrimitiveType type, string name, Transform parent, Vector3 localPos, Vector3 scale, Material mat)
		{
			//IL_0000: 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)
			GameObject val = GameObject.CreatePrimitive(type);
			((Object)val).name = name;
			Collider[] components = val.GetComponents<Collider>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.Destroy((Object)(object)components[i]);
			}
			val.transform.SetParent(parent, false);
			val.transform.localPosition = localPos;
			val.transform.localScale = scale;
			MeshRenderer component = val.GetComponent<MeshRenderer>();
			((Renderer)component).sharedMaterial = mat;
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
			((Renderer)component).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)component).reflectionProbeUsage = (ReflectionProbeUsage)0;
			return val.transform;
		}

		private static Material Mat(Color color, float emission, float smoothness, float metallic)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Color"));
			if (val.HasProperty("_BaseColor"))
			{
				val.SetColor("_BaseColor", color);
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", color);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", smoothness);
			}
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", smoothness);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", metallic);
			}
			if (emission > 0.01f)
			{
				Color val2 = color * emission;
				if (val.HasProperty("_EmissionColor"))
				{
					val.EnableKeyword("_EMISSION");
					val.SetColor("_EmissionColor", val2);
				}
			}
			return val;
		}
	}
	internal static class PrefabRefLivePatch
	{
	}
	[HarmonyPatch(typeof(StatsManager), "Awake")]
	internal static class StatsManagerAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(StatsManager __instance)
		{
			ShopRegistry.TryInject(__instance);
		}
	}
	[HarmonyPatch(typeof(StatsManager), "Start")]
	internal static class StatsManagerStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(StatsManager __instance)
		{
			ShopRegistry.TryInject(__instance);
		}
	}
	[HarmonyPatch(typeof(StatsManager), "LoadItemsFromFolder")]
	internal static class LoadItemsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(StatsManager __instance)
		{
			ShopRegistry.TryInject(__instance);
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	internal static class ChangeLevelPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			ShopRegistry.ResetShopWait();
			if ((Object)(object)StatsManager.instance != (Object)null)
			{
				ShopRegistry.TryInject(StatsManager.instance);
			}
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			if ((Object)(object)StatsManager.instance != (Object)null)
			{
				ShopRegistry.TryInject(StatsManager.instance);
			}
			ShopRegistry.RefreshRamCache();
		}
	}
	[HarmonyPatch(typeof(ShopManager), "ShopInitialize")]
	internal static class ShopInitializePatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			ShopRegistry.TryInject(StatsManager.instance);
		}

		[HarmonyPostfix]
		private static void Postfix(ShopManager __instance)
		{
			ShopRegistry.TryInject(StatsManager.instance);
			ShopRegistry.RefreshRamCache();
		}
	}
	[HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")]
	internal static class ShopCollectItemsPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ShopManager __instance)
		{
			ShopRegistry.AddToShop(__instance);
		}
	}
	[HarmonyPatch(typeof(PunManager), "ShopPopulateItemVolumes")]
	internal static class ShopPopulatePatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix()
		{
			ShopRegistry.TryInject(StatsManager.instance);
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			ShopRegistry.AddToShop(ShopManager.instance);
			ShopRegistry.SnapshotVolumes();
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(ShopRegistry.AfterVanillaShopPopulate());
			}
		}
	}
	[HarmonyPatch(typeof(ShopManager), "GetAllItemVolumesInScene")]
	internal static class ShopVolumesPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ShopManager __instance)
		{
			ShopRegistry.SnapshotFrom(__instance);
		}
	}
	[HarmonyPatch(typeof(PunManager), "SpawnShopItem")]
	internal static class SpawnShopItemPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(ItemVolume itemVolume, List<Item> itemList)
		{
			ShopRegistry.NoteVolume(itemVolume);
			itemList?.RemoveAll((Item it) => (Object)(object)it != (Object)null && Plugin.IsMedvacItem(it));
			if (itemList != null)
			{
				ShopRegistry.BindLivePrefabs(itemList);
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemVolume itemVolume)
		{
			if (!((Object)(object)itemVolume == (Object)null) && !((Object)(object)itemVolume.itemAttributes == (Object)null))
			{
				Item item = itemVolume.itemAttributes.item;
				if (!((Object)(object)item == (Object)null) && Plugin.IsMedvacItem(item))
				{
					ShopRegistry.ConvertToHealer(((Component)itemVolume.itemAttributes).gameObject, item);
					ShopRegistry.ApplyTierPrice(itemVolume.itemAttributes);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "SpawnItem")]
	internal static class PunSpawnItemPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(Item item, ItemVolume volume)
		{
			ShopRegistry.NoteVolume(volume);
			if (!((Object)(object)item == (Object)null) && Plugin.IsMedvacItem(item))
			{
				ShopRegistry.BindSpawned(item, volume);
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(ShopRegistry.ConvertVolumeNextFrame(item, volume));
				}
			}
		}
	}
	[HarmonyPatch(typeof(StatsManager), "ItemFetchName")]
	internal static class ItemFetchNameGuard
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemAttributes itemAttributes)
		{
			if ((Object)(object)itemAttributes == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)itemAttributes).GetComponent<MedvacRuntime>() != (Object)null)
			{
				return false;
			}
			if (Plugin.IsMedvacItem(itemAttributes.item))
			{
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		private static void Postfix(ItemAttributes itemAttributes)
		{
			if (!((Object)(object)itemAttributes == (Object)null) && (Object)(object)((Component)itemAttributes).GetComponent<MedvacRuntime>() != (Object)null)
			{
				ItemNamePatch.ForceName(itemAttributes);
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "SetItemName")]
	internal static class SetItemNameGuard
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemAttributes itemAttributes)
		{
			if (!((Object)(object)itemAttributes == (Object)null))
			{
				return (Object)(object)((Component)itemAttributes).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PunManager), "AddingItem")]
	internal static class PunAddingItemPatch
	{
		[HarmonyPostfix]
		private static void Postfix(string itemName, ItemAttributes itemAttributes)
		{
			if (!((Object)(object)itemAttributes == (Object)null))
			{
				Item val = itemAttributes.item;
				if ((Object)(object)val == (Object)null && (Object)(object)StatsManager.instance != (Object)null && StatsManager.instance.itemDictionary.TryGetValue(itemName, out var value))
				{
					val = value;
				}
				if (!((Object)(object)val == (Object)null) && Plugin.IsMedvacItem(val))
				{
					ShopRegistry.ConvertToHealer(((Component)itemAttributes).gameObject, val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PunManager), "TruckPopulateItemVolumes")]
	internal static class TruckPopulatePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(ShopRegistry.ConvertAllNextFrame());
			}
			else
			{
				ShopRegistry.ConvertAllMedvacInScene();
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "LateStart")]
	internal static class ItemAttributesLateStartPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && Plugin.IsMedvacItem(__instance.item))
			{
				ShopRegistry.ConvertToHealer(((Component)__instance).gameObject, __instance.item);
				ItemNamePatch.ForceName(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(ItemManager), "ItemsInitialize")]
	internal static class ItemManagerInitPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			ShopRegistry.TryInject(StatsManager.instance);
			ShopRegistry.RefreshRamCache();
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GetValue")]
	internal static class ItemValuePatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(ItemAttributes __instance)
		{
			ShopRegistry.BindValueRange(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			ShopRegistry.ApplyTierPrice(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GetValueRPC")]
	internal static class ItemValueRpcPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			ShopRegistry.ApplyTierPrice(__instance);
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "ShopUpdateCost")]
	internal static class ShopCostPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			ShopManager instance = ShopManager.instance;
			if ((Object)(object)instance == (Object)null || instance.shoppingList == null)
			{
				return;
			}
			foreach (ItemAttributes shopping in instance.shoppingList)
			{
				ShopRegistry.ApplyTierPrice(shopping, rollIfNeeded: false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			ShopManager instance = ShopManager.instance;
			if ((Object)(object)instance == (Object)null || instance.shoppingList == null)
			{
				return;
			}
			int num = 0;
			HashSet<string> hashSet = new HashSet<string>();
			foreach (ItemAttributes shopping in instance.shoppingList)
			{
				if ((Object)(object)shopping == (Object)null)
				{
					continue;
				}
				if ((Object)(object)((Component)shopping).GetComponent<MedvacRuntime>() == (Object)null && (Plugin.IsMedvacItem(shopping.item) || (shopping.itemName != null && shopping.itemName.IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) >= 0)))
				{
					ShopRegistry.ConvertToHealer(((Component)shopping).gameObject, shopping.item);
				}
				ShopRegistry.ApplyTierPrice(shopping, rollIfNeeded: false);
				if (Plugin.IsMedvacItem(shopping.item) || (shopping.itemName != null && shopping.itemName.IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) >= 0))
				{
					string text = (((Object)(object)shopping.item != (Object)null) ? ((Object)shopping.item).name : shopping.itemName);
					if (!hashSet.Add(text ?? "MEDVAC"))
					{
						continue;
					}
				}
				num += Mathf.Max(0, shopping.value);
			}
			instance.totalCost = num;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "Start")]
	internal static class ItemAttributesStartPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				GameObject gameObject = ((Component)__instance).gameObject;
				if (Plugin.IsMedvacItem(__instance.item) || (((Object)gameObject).name != null && ((Object)gameObject).name.IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) >= 0) || (Object)(object)gameObject.GetComponent<MedvacRuntime>() != (Object)null)
				{
					ShopRegistry.ConvertToHealer(gameObject, __instance.item);
					ItemNamePatch.ForceName(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "ShowInfo")]
	internal static class ItemNamePatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(ItemAttributes __instance)
		{
			ForceName(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			ForceName(__instance);
			if (Time.frameCount % 15 == 0)
			{
				RelabelWorld(__instance);
			}
		}

		internal static string Label(MedvacRuntime runtime)
		{
			if ((Object)(object)runtime == (Object)null)
			{
				return "MEDVAC";
			}
			string text = (((Object)(object)runtime.boundItem != (Object)null) ? runtime.boundItem.itemName : "MEDVAC");
			if (runtime.tankMax > 0)
			{
				return text + "  " + runtime.tankHp + "/" + runtime.tankMax + "HP";
			}
			return text;
		}

		internal static void ForceName(ItemAttributes attrs)
		{
			if ((Object)(object)attrs == (Object)null)
			{
				return;
			}
			MedvacRuntime medvacRuntime = ((Component)attrs).GetComponent<MedvacRuntime>() ?? ((Component)attrs).GetComponentInParent<MedvacRuntime>();
			if (!((Object)(object)medvacRuntime == (Object)null))
			{
				if ((Object)(object)medvacRuntime.boundItem != (Object)null)
				{
					attrs.item = medvacRuntime.boundItem;
				}
				attrs.instanceName = (attrs.promptName = (attrs.itemName = Label(medvacRuntime)));
				medvacRuntime.ApplyIdentity();
			}
		}

		internal static void RelabelWorld(ItemAttributes attrs)
		{
			MedvacRuntime medvacRuntime = (((Object)(object)attrs != (Object)null) ? ((Component)attrs).GetComponent<MedvacRuntime>() : null);
			if ((Object)(object)medvacRuntime == (Object)null)
			{
				return;
			}
			string text = Label(medvacRuntime);
			Type type = AccessTools.TypeByName("TMPro.TMP_Text") ?? AccessTools.TypeByName("TMPro.TextMeshProUGUI");
			if (type == null)
			{
				return;
			}
			PropertyInfo propertyInfo = AccessTools.Property(type, "text");
			if (propertyInfo == null)
			{
				return;
			}
			Object[] array;
			try
			{
				array = Object.FindObjectsOfType(type);
			}
			catch
			{
				return;
			}
			Object[] array2 = array;
			foreach (Object val in array2)
			{
				if (!(val == (Object)null))
				{
					string text2 = propertyInfo.GetValue(val) as string;
					if (!string.IsNullOrEmpty(text2) && (text2.IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) < 0 || text2.IndexOf("HP", StringComparison.OrdinalIgnoreCase) < 0) && (text2.IndexOf("RECHARGE", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("ZERO GRAVITY", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("INDESTRUCTIBLE", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("FEATHER", StringComparison.OrdinalIgnoreCase) >= 0 || (text2.IndexOf("DRONE", StringComparison.OrdinalIgnoreCase) >= 0 && text2.IndexOf("[E]", StringComparison.OrdinalIgnoreCase) >= 0)))
					{
						bool flag = text2.IndexOf("[E]", StringComparison.OrdinalIgnoreCase) >= 0;
						propertyInfo.SetValue(val, flag ? (text + " [E]") : text);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")]
	internal static class LocalizedNamePatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance, ref string __result)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null))
			{
				__result = ItemNamePatch.Label(((Component)__instance).GetComponent<MedvacRuntime>());
			}
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "ShowingInfo")]
	internal static class ItemShowingInfoPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(ItemAttributes __instance)
		{
			ItemNamePatch.ForceName(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			ItemNamePatch.ForceName(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "Update")]
	internal static class ItemAttributesUpdatePatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ItemAttributes __instance)
		{
			ItemNamePatch.ForceName(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemDroneHeal), "Update")]
	internal static class ItemDroneHealUpdateGuard
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDroneHeal __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "DrawBeamLine")]
	internal static class BlockMedvacBeam
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "StateBeamDeployed")]
	internal static class BlockMedvacBeamState
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "StateAttached")]
	internal static class BlockMedvacAttach
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "TargetFindPlayer")]
	internal static class BlockMedvacPlayerTarget
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance, ref bool __result)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "ActivateMagnet")]
	internal static class BlockMedvacMagnet
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemDrone), "FixedUpdate")]
	internal static class BlockMedvacVanillaFlight
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemDrone __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				return (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GenerateIcon")]
	internal static class MedvacIconPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemAttributes __instance, ref IEnumerator __result)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() == (Object)null)
			{
				return true;
			}
			__instance.icon = MedvacIcon.Sprite;
			__instance.hasIcon = true;
			__result = Empty();
			return false;
		}

		private static IEnumerator Empty()
		{
			yield break;
		}
	}
	[HarmonyPatch(typeof(ItemDroneHeal), "CustomTargetingCondition")]
	internal static class HealTouchPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemDroneHeal __instance, GameObject target, ref bool __result)
		{
			if (!((Object)(object)__instance == (Object)null) && (Object)(object)((Component)__instance).GetComponent<MedvacRuntime>() != (Object)null)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(ItemHealthPack), "UsedRPC")]
	internal static class MedkitRefillPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemHealthPack __instance)
		{
			return true;
		}
	}
	internal static class RamSpawnPatch
	{
		private static bool _applied;

		internal static void TryApply(Harmony harmony)
		{
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			if (_applied || harmony == null)
			{
				return;
			}
			try
			{
				Type type = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						type = assembly.GetType("RepoAdminMenu.Utils.ItemUtil");
						if (type == null)
						{
							Type[] types = assembly.GetTypes();
							foreach (Type type2 in types)
							{
								if (type2.Name == "ItemUtil" && type2.Namespace != null && type2.Namespace.IndexOf("RepoAdmin") >= 0)
								{
									type = type2;
									break;
								}
							}
						}
					}
					catch
					{
					}
					if (type != null)
					{
						break;
					}
				}
				if (type == null)
				{
					return;
				}
				MethodInfo methodInfo = null;
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (methodInfo2.Name.IndexOf("spawn", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						ParameterInfo[] parameters = methodInfo2.GetParameters();
						if (parameters.Length >= 1 && parameters[0].ParameterType.Name == "Item")
						{
							methodInfo = methodInfo2;
							break;
						}
					}
				}
				if (methodInfo == null)
				{
					List<string> list = new List<string>();
					methods = type.GetMethods();
					foreach (MethodInfo methodInfo3 in methods)
					{
						list.Add(methodInfo3.Name);
					}
					Plugin.Log.LogWarning((object)("R.A.M. ItemUtil found but no spawn method. Methods: " + string.Join(", ", list.ToArray())));
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(RamSpawnPatch), "Prefix", (Type[])null)
					{
						priority = 800
					}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_applied = true;
					Plugin.Log.LogInfo((object)("Hooked R.A.M. " + type.FullName + "." + methodInfo.Name));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("R.A.M. hook failed: " + ex));
			}
		}

		public static bool Prefix(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return true;
			}
			if (!Plugin.IsMedvacItem(item))
			{
				return true;
			}
			Plugin.Log.LogInfo((object)("R.A.M. spawn intercepted for " + ((Object)item).name));
			ShopRegistry.SpawnInWorld(item);
			return false;
		}
	}
	internal static class ShopRegistry
	{
		internal static readonly Dictionary<string, GameObject> Templates = new Dictionary<string, GameObject>();

		internal static GameObject VanillaPrefab;

		internal static PrefabRef VanillaPrefabRef;

		internal static string VanillaPhotonId = "Items/Item Drone Feather";

		internal static bool Injected;

		internal static readonly Dictionary<string, PrefabRef> Prefabs = new Dictionary<string, PrefabRef>();

		internal static readonly HashSet<string> RepoLibOnce = new HashSet<string>();

		private static bool _limitPatched;

		private static bool _leftPool;

		private static Item _poolLog;

		private static readonly List<ItemVolume> SeenVolumes = new List<ItemVolume>();

		private static bool _waitRunning;

		private static bool _placedThisVisit;

		internal static void TryInject(StatsManager sm)
		{
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.InjectShop.Value || (Object)(object)sm == (Object)null || sm.itemDictionary == null || sm.itemDictionary.Count == 0)
			{
				return;
			}
			Item val = FindDrone(sm);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No drone item in dictionary yet.");
				return;
			}
			GameObject val2 = ResolvePrefab(val);
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Drone prefab missing, cannot bind MEDVAC.");
				return;
			}
			VanillaPrefab = val2;
			VanillaPrefabRef = val.prefab;
			if (!string.IsNullOrEmpty(((Object)val).name))
			{
				VanillaPhotonId = "Items/" + ((Object)val).name;
			}
			Tier[] tiers = Plugin.Tiers;
			foreach (Tier tier in tiers)
			{
				string text = "Item Drone MEDVAC " + tier.Name;
				Item val3 = FindExisting(sm, text, tier.ItemName);
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = Object.Instantiate<Item>(val);
					((Object)val3).name = text;
					val3.itemName = tier.ItemName;
					val3.description = $"Healer drone {tier.TankHp} HP tank. Heals on hull contact. Activate to patrol. Refill with medkits.";
					val3.disabled = false;
					val3.itemType = (itemType)0;
					val3.maxAmount = 8;
					val3.maxAmountInShop = 1;
					val3.maxPurchase = false;
					val3.physicalItem = true;
					val3.itemSecretShopType = (itemSecretShopType)0;
					try
					{
						val3.emojiIcon = (emojiIcon)0;
					}
					catch
					{
						val3.emojiIcon = val.emojiIcon;
					}
					val3.itemVolume = (itemVolume)0;
					val3.prefab = val.prefab;
					Value val4 = ScriptableObject.CreateInstance<Value>();
					((Object)val4).name = "Value MEDVAC " + tier.Name;
					val4.valueMin = tier.PriceMin;
					val4.valueMax = tier.PriceMax;
					val3.value = val4;
					sm.itemDictionary[text] = val3;
					EnsureDict(sm.itemStatBattery, text, 100);
					EnsureDict(sm.itemsPurchased, text, 0);
					Plugin.Log.LogInfo((object)$"Registered {text} ({tier.TankHp} HP).");
				}
				BindHealerPrefab(val3, val2, tier);
				val3.maxAmount = 8;
				val3.maxAmountInShop = 1;
				val3.maxPurchase = false;
				val3.disabled = false;
				val3.itemType = (itemType)0;
				val3.itemVolume = (itemVolume)0;
				val3.itemSecretShopType = (itemSecretShopType)0;
			}
			Injected = true;
			ClampShopCaps(sm);
		}

		internal static void ClampShopCaps(StatsManager sm = null)
		{
			//IL_0123: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			sm = sm ?? StatsManager.instance;
			if ((Object)(object)sm == (Object)null || sm.itemDictionary == null)
			{
				return;
			}
			foreach (KeyValuePair<string, Item> item in sm.itemDictionary)
			{
				if (!((Object)(object)item.Value == (Object)null) && Plugin.IsMedvacItem(item.Value))
				{
					if (item.Value.maxAmountInShop != 1 || item.Value.maxAmount != 8)
					{
						Plugin.Log.LogInfo((object)("Shop cap " + item.Value.itemName + " " + item.Value.maxAmountInShop + "/" + item.Value.maxAmount + " -> 1/8"));
						item.Value.maxAmountInShop = 1;
						item.Value.maxAmount = 8;
					}
					item.Value.disabled = false;
					item.Value.maxPurchase = false;
					item.Value.itemType = (itemType)0;
					item.Value.itemVolume = (itemVolume)0;
					item.Value.itemSecretShopType = (itemSecretShopType)0;
				}
			}
		}

		internal static void ClampShopCapsNoArgs()
		{
			ClampShopCaps();
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(ClampSoon());
			}
		}

		private static IEnumerator ClampSoon()
		{
			yield return null;
			ClampShopCaps();
			yield return (object)new WaitForSeconds(0.15f);
			ClampShopCaps();
		}

		internal static void PatchNoItemSpawnLimit(Harmony harmony)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			if (harmony == null || _limitPatched)
			{
				return;
			}
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					string text = "";
					try
					{
						text = assembly.GetName().Name ?? "";
					}
					catch
					{
						continue;
					}
					if (text.IndexOf("NoItemSpawnLimit", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					Type[] types = assembly.GetTypes();
					foreach (Type type in types)
					{
						MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (MethodInfo methodInfo in methods)
						{
							if (methodInfo.IsAbstract || methodInfo.ContainsGenericParameters)
							{
								continue;
							}
							string name = methodInfo.Name;
							if (name.IndexOf("Apply", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Limit", StringComparison.OrdinalIgnoreCase) >= 0 || !(name != "Start") || !(name != "Awake"))
							{
								try
								{
									harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ShopRegistry), "ClampShopCapsNoArgs", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
									Plugin.Log.LogInfo((object)("Clamping MEDVAC shop cap after " + type.Name + "." + name));
								}
								catch
								{
								}
							}
						}
					}
					_limitPatched = true;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("NoItemSpawnLimit patch skipped: " + ex.Message));
			}
		}

		internal static void SpawnInWorld(Item item)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0039: 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_0053: 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_006e: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = SemiFunc.PlayerGetLocal() ?? PlayerAvatar.instance;
			Vector3 val2 = Vector3.up * 1.2f;
			Quaternion rot = Quaternion.identity;
			if ((Object)(object)val != (Object)null)
			{
				val2 = ((Component)val).transform.position + Vector3.up * 1.15f + ((Component)val).transform.forward * 1.2f;
				rot = ((Component)val).transform.rotation;
			}
			if (MedvacNet.IsMultiplayer() && !MedvacNet.IsMaster())
			{
				Plugin.Log.LogInfo((object)"Client asked host-side spawn; skip.");
			}
			else if ((Object)(object)MedvacNet.Spawn(item, val2, rot) == (Object)null)
			{
				Plugin.Log.LogError((object)"MEDVAC spawn failed: no networked drone prefab.");
			}
			else
			{
				Plugin.Log.LogInfo((object)$"Spawned healer {item.itemName} at {val2}");
			}
		}

		internal static void ConvertAllMedvacInScene()
		{
			ItemAttributes[] array = Object.FindObjectsOfType<ItemAttributes>();
			foreach (ItemAttributes val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.item == (Object)null) && Plugin.IsMedvacItem(val.item) && !((Object)(object)((Component)val).GetComponent<MedvacRuntime>() != (Object)null))
				{
					ConvertToHealer(((Component)val).gameObject, val.item);
				}
			}
		}

		internal static IEnumerator ConvertVolumeNextFrame(Item item, ItemVolume volume)
		{
			yield return null;
			BindSpawned(item, volume);
			yield return (object)new WaitForSeconds(0.35f);
			BindSpawned(item, volume);
			ConvertAllMedvacInScene();
		}

		internal static IEnumerator ConvertAllNextFrame()
		{
			yield return null;
			yield return (object)new WaitForSeconds(0.15f);
			ConvertAllMedvacInScene();
		}

		internal static void BindSpawned(Item item, ItemVolume volume)
		{
			if (!((Object)(object)item == (Object)null) && Plugin.IsMedvacItem(item))
			{
				if ((Object)(object)volume != (Object)null && (Object)(object)volume.itemAttributes != (Object)null)
				{
					ConvertToHealer(((Component)volume.itemAttributes).gameObject, item);
				}
				else
				{
					ConvertAllMedvacInScene();
				}
			}
		}

		internal static GameObject Alive(GameObject go)
		{
			if (!Object.op_Implicit((Object)(object)go))
			{
				return null;
			}
			return go;
		}

		private static GameObject ResolveAnyDronePrefab()
		{
			StatsManager instance = StatsManager.instance;
			if ((Object)(object)instance == (Object)null || instance.itemDictionary == null)
			{
				return null;
			}
			foreach (KeyValuePair<string, Item> item in instance.itemDictionary)
			{
				Item value = item.Value;
				if ((Object)(object)value == (Object)null || Plugin.IsMedvacItem(value))
				{
					continue;
				}
				try
				{
					GameObject val = ((value.prefab != null) ? ((PrefabRef<GameObject>)(object)value.prefab).Prefab : null);
					if (Object.op_Implicit((Object)(object)val))
					{
						return val;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		internal static void ConvertNearby(Item item)
		{
			//IL_0043: 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)
			PlayerAvatar val = SemiFunc.PlayerGetLocal() ?? PlayerAvatar.instance;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemDrone[] array = Object.FindObjectsOfType<ItemDrone>();
			ItemDrone val2 = null;
			float num = 4f;
			ItemDrone[] array2 = array;
			foreach (ItemDrone val3 in array2)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)val3).transform.position, ((Component)val).transform.position);
					if (num2 < num)
					{
						num = num2;
						val2 = val3;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null && ((Object)(object)((Component)val2).GetComponent<MedvacRuntime>() != (Object)null || (((Object)val2).name != null && ((Object)val2).name.IndexOf("MEDVAC") >= 0)))
			{
				ConvertToHealer(((Component)val2).gameObject, item);
			}
		}

		internal static void ConvertToHealer(GameObject go, Item item)
		{
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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)
			if (!((Object)(object)go == (Object)null) && !((Object)(object)item == (Object)null) && Plugin.IsMedvacItem(item))
			{
				StripForeignDroneLogic(go);
				ItemAttributes val = go.GetComponent<ItemAttributes>() ?? go.GetComponentInChildren<ItemAttributes>();
				if ((Object)(object)val != (Object)null)
				{
					val.item = item;
					val.itemName = (((Object)(object)item != (Object)null) ? item.itemName : val.itemName);
					val.icon = MedvacIcon.Sprite;
					val.hasIcon = true;
					ApplyTierPrice(val);
				}
				MedvacRuntime.PendingBind = item;
				MedvacRuntime medvacRuntime = go.GetComponent<MedvacRuntime>();
				if ((Object)(object)medvacRuntime == (Object)null)
				{
					medvacRuntime = go.AddComponent<MedvacRuntime>();
				}
				medvacRuntime.boundItem = item;
				medvacRuntime.ApplyIdentity();
				MedvacRuntime.PendingBind = null;
				ItemDroneHeal component = go.GetComponent<ItemDroneHeal>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
					Object.Destroy((Object)(object)component);
				}
				if ((Object)(object)go.GetComponent<MedvacVisual>() == (Object)null)
				{
					go.AddComponent<MedvacVisual>();
				}
				ItemDrone component2 = go.GetComponent<ItemDrone>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.targetPlayers = false;
					component2.targetValuables = false;
					component2.targetEnemies = false;
					component2.targetNonValuables = false;
					Color val2 = default(Color);
					((Color)(ref val2))..ctor(0.25f, 1f, 0.45f, 1f);
					AccessTools.Field(typeof(ItemDrone), "droneColor")?.SetValue(component2, val2);
					AccessTools.Field(typeof(ItemDrone), "beamColor")?.SetValue(component2, val2);
					AccessTools.Field(typeof(ItemDrone), "batteryColor")?.SetValue(component2, val2);
				}
			}
		}

		internal static void BindValueRange(ItemAttributes attrs)
		{
			if ((Object)(object)attrs == (Object)null)
			{
				return;
			}
			MedvacRuntime medvacRuntime = ((Component)attrs).GetComponent<MedvacRuntime>() ?? ((Component)attrs).GetComponentInParent<MedvacRuntime>();
			Item val = (((Object)(object)medvacRuntime != (Object)null) ? medvacRuntime.boundItem : attrs.item);
			if (!((Object)(object)val == (Object)null) && Plugin.IsMedvacItem(val))
			{
				Tier tier = Plugin.GetTier(val);
				attrs.itemValueMin = tier.PriceMin;
				attrs.itemValueMax = tier.PriceMax;
				if ((Object)(object)val.value != (Object)null)
				{
					val.value.valueMin = tier.PriceMin;
					val.value.valueMax = tier.PriceMax;
				}
			}
		}

		internal static int KMin(Tier tier)
		{
			return Mathf.Max(1, Mathf.RoundToInt(tier.PriceMin / 1000f));
		}

		internal static int KMax(Tier tier)
		{
			return Mathf.Max(KMin(tier), Mathf.RoundToInt(tier.PriceMax / 1000f));
		}

		internal static int RollTierPrice(Tier tier)
		{
			int num = KMin(tier);
			int num2 = KMax(tier);
			return Random.Range(num, num2 + 1);
		}

		internal static void ApplyTierPrice(ItemAttributes attrs, bool rollIfNeeded = true)
		{
			if ((Object)(object)attrs == (Object)null)
			{
				return;
			}
			MedvacRuntime medvacRuntime = ((Component)attrs).GetComponent<MedvacRuntime>() ?? ((Component)attrs).GetComponentInParent<MedvacRuntime>();
			Item val = (((Object)(object)medvacRuntime != (Object)null) ? medvacRuntime.boundItem : attrs.item);
			if (!((Object)(object)val == (Object)null) && Plugin.IsMedvacItem(val))
			{
				Tier tier = Plugin.GetTier(val);
				int num = KMin(tier);
				int num2 = KMax(tier);
				BindValueRange(attrs);
				int num3 = attrs.value;
				if (num3 >= num * 900)
				{
					num3 = Mathf.RoundToInt((float)num3 / 1000f);
				}
				if (num3 < num || num3 > num2)
				{
					num3 = (rollIfNeeded ? RollTierPrice(tier) : Mathf.Clamp((num3 <= 0) ? num : num3, num, num2));
				}
				attrs.value = Mathf.Clamp(num3, num, num2);
			}
		}

		internal static void InjectIntoSpawnList(ItemVolume vol, List<Item> list)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_004f: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vol == (Object)null || list == null || (Object)(object)StatsManager.instance == (Object)null)
			{
				return;
			}
			bool flag = (int)vol.itemVolume == 0 || (int)vol.itemVolume == 1;
			bool flag2 = false;
			foreach (Item item in list)
			{
				if ((Object)(object)item != (Object)null && (int)item.itemType == 0)
				{
					flag2 = true;
					break;
				}
			}
			if (!flag && !flag2)
			{
				return;
			}
			int num = 0;
			foreach (KeyValuePair<string, Item> item2 in StatsManager.instance.itemDictionary)
			{
				Item value = item2.Value;
				if (!((Object)(object)value == (Object)null) && Plugin.IsMedvacItem(value))
				{
					value.disabled = false;
					value.itemType = (itemType)0;
					value.itemVolume = (itemVolume)0;
					value.itemSecretShopType = (itemSecretShopType)0;
					if (value.maxAmountInShop < 1)
					{
						value.maxAmountInShop = 1;
					}
					if (!list.Contains(value))
					{
						list.Add(value);
						num++;
					}
				}
			}
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)("SpawnShopItem pool +" + num + " MEDVAC (list=" + list.Count + ", shelf=" + ((object)Unsafe.As<itemVolume, itemVolume>(ref vol.itemVolume)/*cast due to .constrained prefix*/).ToString() + ")"));
			}
		}

		internal static void AddToShop(ShopManager shop)
		{
			if (!((Object)(object)shop == (Object)null) && shop.potentialItems != null)
			{
				int num = shop.potentialItems.RemoveAll((Item it) => (Object)(object)it != (Object)null && Plugin.IsMedvacItem(it));
				if (num > 0 && !_leftPool)
				{
					_leftPool = true;
					Plugin.Log.LogInfo((object)("MEDVAC left shared shop roll (-" + num + "). Own shelf after other mods."));
				}
			}
		}

		internal static IEnumerator ForceShopStockDelayed()
		{
			yield return (object)new WaitForSeconds(0.8f);
			ForceShopStock();
			yield return (object)new WaitForSeconds(1.2f);
			ForceShopStock();
		}

		internal static void ForceShopStock()
		{
		}

		internal static bool HasMedvacInShop()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0054: 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)
			ItemAttributes[] array = Resources.FindObjectsOfTypeAll<ItemAttributes>();
			foreach (ItemAttributes val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (!((Scene)(ref scene)).IsValid() || IsTemplate((Component)(object)val) || ((Object)(object)((Component)val).transform != (Object)null && ((Component)val).transform.position.y < -500f))
				{
					continue;
				}
				scene = ((Component)val).gameObject.scene;
				if ((((Scene)(ref scene)).name ?? "").IndexOf("DontDestroyOnLoad", StringComparison.OrdinalIgnoreCase) < 0 && (int)((Object)val).hideFlags == 0)
				{
					if ((Object)(object)((Component)val).GetComponent<MedvacRuntime>() != (Object)null)
					{
						return true;
					}
					if (Plugin.IsMedvacItem(val.item))
					{
						return true;
					}
					if ((val.itemName ?? "").IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
			}
			foreach (ItemVolume item in CollectVolumes())
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.itemAttributes == (Object)null) && Plugin.IsMedvacItem(item.itemAttributes.item))
				{
					return true;
				}
			}
			return false;
		}

		internal static Item PickRandomMedvac()
		{
			if ((Object)(object)StatsManager.instance == (Object)null)
			{
				return null;
			}
			List<Item> list = new List<Item>();
			foreach (KeyValuePair<string, Item> item in StatsManager.instance.itemDictionary)
			{
				if (!((Object)(object)item.Value == (Object)null) && Plugin.IsMedvacItem(item.Value) && !list.Contains(item.Value))
				{
					list.Add(item.Value);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			return list[Random.Range(0, list.Count)];
		}

		internal static void NoteVolume(ItemVolume vol)
		{
			if (!((Object)(object)vol == (Object)null) && !SeenVolumes.Contains(vol))
			{
				SeenVolumes.Add(vol);
			}
		}

		private static bool IsUsableEmpty(ItemVolume vol)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)vol == (Object)null)
			{
				return false;
			}
			if ((Object)(object)vol.itemAttributes != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)vol).transform != (Object)null && ((Component)vol).transform.position.y < -500f)
			{
				return false;
			}
			return true;
		}

		private static ItemVolume MakeOwnShelf()
		{
			//IL_0039: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_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_004c: Unknown result type (might be due to invalid IL or missing references)
			ItemVolume val = null;
			foreach (ItemVolume item in CollectVolumes())
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).transform == (Object)null) && !(((Component)item).transform.position.y < -500f))
				{
					if ((int)item.itemVolume == 0)
					{
						val = item;
						break;
					}
					if ((Object)(object)val == (Object)null)
					{
						val = item;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent);
			((Object)val2).name = "Item Volume MEDVAC";
			val2.SetActive(true);
			val2.transform.position = ((Component)val).transform.position + ((Component)val).transform.right * 0.9f + Vector3.up * 0.02f;
			val2.transform.rotation = ((Component)val).transform.rotation;
			ItemAttributes[] componentsInChildren = val2.GetComponentsInChildren<ItemAttributes>(true);
			foreach (ItemAttributes val3 in componentsInChildren)
			{
				if (!((Object)(object)val3 == (Object)null) && !((Object)(object)((Component)val3).gameObject == (Object)(object)val2))
				{
					Object.Destroy((Object)(object)((Component)val3).gameObject);
				}
			}
			ItemVolume val4 = val2.GetComponent<ItemVolume>() ?? val2.GetComponentInChildren<ItemVolume>(true);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.itemAttributes = null;
				NoteVolume(val4);
			}
			ShopManager instance = ShopManager.instance;
			if ((Object)(object)instance != (Object)null && instance.itemVolumes != null && (Object)(object)val4 != (Object)null && !instance.itemVolumes.Contains(val4))
			{
				instance.itemVolumes.Add(val4);
			}
			Plugin.Log.LogInfo((object)("Added own MEDVAC shelf next to " + ((Object)val).name));
			return val4;
		}

		internal static void SnapshotVolumes()
		{
			SnapshotFrom(ShopManager.instance);
		}

		internal static void SnapshotFrom(ShopManager shop)
		{
			if ((Object)(object)shop == (Object)null)
			{
				return;
			}
			int count = SeenVolumes.Count;
			if (shop.itemVolumes != null)
			{
				foreach (ItemVolume itemVolume in shop.itemVolumes)
				{
					NoteVolume(itemVolume);
				}
			}
			if (shop.secretItemVolumes != null)
			{
				foreach (KeyValuePair<itemSecretShopType, List<ItemVolume>> secretItemVolume in shop.secretItemVolumes)
				{
					if (secretItemVolume.Value == null)
					{
						continue;
					}
					foreach (ItemVolume item in secretItemVolume.Value)
					{
						NoteVolume(item);
					}
				}
			}
			if (SeenVolumes.Count != count)
			{
				Plugin.Log.LogInfo((object)("Shelf volumes seen=" + SeenVolumes.Count));
			}
		}

		private static bool PlaceLoose(Item item)
		{
			return PlaceNextToShopItem(item);
		}

		private static bool PlaceNextToShopItem(Item item)
		{
			//IL_003e: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: 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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			ItemAttributes val = null;
			ItemAttributes[] array = Resources.FindObjectsOfTypeAll<ItemAttributes>();
			foreach (ItemAttributes val2 in array)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null)
				{
					continue;
				}
				Scene scene = ((Component)val2).gameObject.scene;
				if (!((Scene)(ref scene)).IsValid() || IsTemplate((Component)(object)val2) || (int)((Object)val2).hideFlags != 0 || ((Object)(object)((Component)val2).transform != (Object)null && ((Component)val2).transform.position.y < -200f))
				{
					continue;
				}
				scene = ((Component)val2).gameObject.scene;
				if ((((Scene)(ref scene)).name ?? "").IndexOf("DontDestroyOnLoad", StringComparison.OrdinalIgnoreCase) >= 0 || (Object)(object)((Component)val2).GetComponent<MedvacRuntime>() != (Object)null)
				{
					continue;
				}
				val = val2;
				try
				{
					if ((Object)(object)val2.item != (Object)null && (int)val2.item.itemType == 0)
					{
						break;
					}
				}
				catch
				{
				}
			}
			if ((Object)(object)(Alive(GetTemplate(item)) ?? Alive(VanillaPrefab)) == (Object)null && !MedvacNet.IsMultiplayer())
			{
				return false;
			}
			Vector3 pos;
			Quaternion rot;
			if ((Object)(object)val != (Object)null)
			{
				pos = ((Component)val).transform.position + ((Component)val).transform.right * 0.75f + Vector3.up * 0.04f;
				rot = ((Component)val).transform.rotation;
			}
			else
			{
				ShopManager instance = ShopManager.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return false;
				}
				pos = ((Component)instance).transform.position + Vector3.up * 1.15f + ((Component)instance).transform.forward * 1.4f;
				rot = Quaternion.identity;
			}
			GameObject val3 = MedvacNet.Spawn(item, pos, rot);
			if ((Object)(object)val3 == (Object)null)
			{
				return false;
			}
			ActivateShopInstance(val3);
			MarkShopStock(val3);
			Plugin.Log.LogInfo((object)("Shelf neighbor spawn " + item.itemName + (((Object)(object)val != (Object)null) ? (" next to " + ((Object)val).name) : " (no neighbor)")));
			_placedThisVisit = (Object)(object)val3.GetComponent<MedvacRuntime>() != (Object)null;
			return _placedThisVisit;
		}

		internal static bool ForceAtLeastOne()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ShopManager.instance == (Object)null)
			{
				return false;
			}
			try
			{
				if (SemiFunc.IsNotMasterClient())
				{
					return true;
				}
			}
			catch
			{
			}
			if (HasMedvacInShop())
			{
				return true;
			}
			Item val = PickRandomMedvac();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			val.disabled = false;
			val.itemType = (itemType)0;
			val.itemVolume = (itemVolume)0;
			val.itemSecretShopType = (itemSecretShopType)0;
			if (val.maxAmountInShop < 1)
			{
				val.maxAmountInShop = 1;
			}
			ItemVolume val2 = PickEmptyDroneVolume() ?? MakeOwnShelf();
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No shelf for MEDVAC, spawning in shop.");
				return PlaceLoose(val);
			}
			Plugin.Log.LogInfo((object)("Own shelf " + val.itemName + " -> " + ((Object)val2).name));
			PlaceOnShelf(val, val2);
			if (HasMedvacInShop() || ((Object)(object)val2.itemAttributes != (Object)null && Plugin.IsMedvacItem(val2.itemAttributes.item)))
			{
				_placedThisVisit = true;
				return true;
			}
			return false;
		}

		private static ItemVolume PickEmptyDroneVolume()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			List<ItemVolume> list = CollectVolumes();
			foreach (ItemVolume item in list)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.itemAttributes != (Object)null) && (int)item.itemVolume == 0)
				{
					return item;
				}
			}
			foreach (ItemVolume item2 in list)
			{
				if (!((Object)(object)item2 == (Object)null) && !((Object)(object)item2.itemAttributes != (Object)null))
				{
					return item2;
				}
			}
			return null;
		}

		private static ItemVolume PickShelf(List<ItemVolume> volumes, Item item)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			foreach (ItemVolume volume in volumes)
			{
				if (!((Object)(object)volume == (Object)null) && !((Object)(object)volume.itemAttributes != (Object)null) && (Object)(object)item != (Object)null && volume.itemVolume == item.itemVolume)
				{
					return volume;
				}
			}
			foreach (ItemVolume volume2 in volumes)
			{
				if (!((Object)(object)volume2 == (Object)null) && !((Object)(object)volume2.itemAttributes != (Object)null) && ((int)volume2.itemVolume == 1 || (int)volume2.itemVolume == 0))
				{
					return volume2;
				}
			}
			foreach (ItemVolume volume3 in volumes)
			{
				if (!((Object)(object)volume3 == (Object)null) && !((Object)(object)volume3.itemAttributes != (Object)null))
				{
					return volume3;
				}
			}
			return null;
		}

		private static void MarkShopStock(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				ItemAttributes val = go.GetComponent<ItemAttributes>() ?? go.GetComponentInChildren<ItemAttributes>();
				if ((Object)(object)val != (Object)null)
				{
					val.shopItem = true;
				}
				ItemDrone component = go.GetComponent<ItemDrone>();
				if ((Object)(object)component != (Object)null)
				{
					component.itemActivated = false;
					component.targetPlayers = false;
				}
				ItemToggle component2 = go.GetComponent<ItemToggle>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.toggleState = false;
				}
			}
		}

		private static void PlaceOnShelf(Item item, ItemVolume slot)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)item == (Object)null) && !((Object)(object)slot == (Object)null) && !((Object)(object)slot.itemAttributes != (Object)null))
			{
				Vector3 pos = ((Component)slot).transform.position + Vector3.up * 0.12f;
				GameObject val = MedvacNet.Spawn(item, pos, ((Component)slot).transform.rotation);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)("No live prefab for " + item.itemName));
					return;
				}
				ActivateShopInstance(val);
				MarkShopStock(val);
				slot.itemAttributes = val.GetComponent<ItemAttributes>() ?? val.GetComponentInChildren<ItemAttributes>();
				Plugin.Log.LogInfo((object)((((Object)(object)slot.itemAttributes != (Object)null) ? "Shop spawned " : "Shop FAILED ") + item.itemName + " on " + ((Object)slot).name));
			}
		}

		private static void ActivateShopInstance(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			go.SetActive(true);
			((Object)go).hideFlags = (HideFlags)0;
			Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = true;
				}
			}
			Rigidbody[] componentsInChildren2 = go.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.detectCollisions = true;
				}
			}
		}

		internal static void RefreshRamCache()
		{
			try
			{
				Type type = AccessTools.TypeByName("RepoAdminMenu.Utils.ItemUtil");
				if (!(type == null))
				{
					AccessTools.Method(type, "Init", (Type[])null, (Type[])null)?.Invoke(null, null);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("R.A.M. refresh skipped: " + ex.Message));
			}
		}

		private static void BindHealerPrefab(Item clone, GameObject sourcePrefab, Tier tier)
		{
			string name = ((Object)clone).name;
			if (Templates.TryGetValue(name, out var value) && Object.op_Implicit((Object)(object)value) && ((Object)value).name != null && ((Object)value).name.IndexOf("MEDVAC", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				BindLivePrefab(clone, value, Prefabs.TryGetValue(name, out var value2) ? value2 : clone.prefab);
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(sourcePrefab);
			((Object)val).name = name;
			ParkTemplate(val);
			Object.DontDestroyOnLoad((Object)(object)val);
			StripForeignDroneLogic(val);
			ItemAttributes val2 = val.GetComponent<ItemAttributes>() ?? val.GetComponentInChildren<ItemAttributes>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.item = clone;
				val2.itemName = clone.itemName;
			}
			ConvertToHealer(val, clone);
			Templates[name] = val;
			if (!string.IsNullOrEmpty(clone.itemName))
			{
				Templates[clone.itemName] = val;
			}
			PrefabRef prefabRef = RegisterRepoLibItemOnce(clone, val);
			BindLivePrefab(clone, val, prefabRef);
			Plugin.Log.LogInfo((object)("Live prefab bound for " + name));
		}

		internal static void BindLivePrefabs(List<Item> items)
		{
			if (items == null)
			{
				return;
			}
			foreach (Item item in items)
			{
				if (!((Object)(object)item == (Object)null) && Plugin.IsMedvacItem(item))
				{
					GameObject template = GetTemplate(item);
					if (!((Object)(o