Decompiled source of VoidCart v0.4.0

BepInEx/plugins/VoidCart/VoidCart.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace VoidCartMod;

internal static class GameAccess
{
	private static readonly FieldInfo cartVolume = Required(typeof(PhysGrabCart), "inCart");

	private static readonly FieldInfo cartHaul = Required(typeof(PhysGrabCart), "haulCurrent");

	private static readonly FieldInfo cartItems = Required(typeof(PhysGrabCart), "itemsInCart");

	private static readonly FieldInfo value = Required(typeof(ValuableObject), "dollarValueCurrent");

	private static readonly FieldInfo kinematic = Required(typeof(PhysGrabObject), "isKinematic");

	private static readonly FieldInfo detectorCart = Required(typeof(PhysGrabObjectImpactDetector), "currentCart");

	private static readonly FieldInfo indestructible = Required(typeof(PhysGrabObjectImpactDetector), "isIndestructible");

	private static readonly FieldInfo active = Required(typeof(PhysGrabObject), "isActive");

	private static readonly FieldInfo equipping = Required(typeof(ItemEquippable), "isEquipping");

	private static readonly FieldInfo unequipping = Required(typeof(ItemEquippable), "isUnequipping");

	private static readonly FieldInfo grenadeActive = Required(typeof(ItemGrenade), "isActive");

	private static readonly FieldInfo gunState = Required(typeof(ItemGun), "stateCurrent");

	private static readonly FieldInfo mineState = Required(typeof(ItemMine), "state");

	private static readonly object gunIdle = Enum.Parse(gunState.FieldType, "Idle");

	private static readonly object gunEmpty = Enum.Parse(gunState.FieldType, "OutOfAmmo");

	private static readonly object mineDisarmed = Enum.Parse(mineState.FieldType, "Disarmed");

	private static readonly MethodInfo resetMeleeMotion = AccessTools.Method(typeof(ItemMelee), "ResetForFreshUnequip", (Type[])null, (Type[])null);

	private static FieldInfo Required(Type type, string name)
	{
		FieldInfo fieldInfo = AccessTools.Field(type, name);
		if (fieldInfo == null)
		{
			throw new MissingFieldException(type.FullName, name);
		}
		return fieldInfo;
	}

	public static void Validate()
	{
		GC.KeepAlive(cartVolume);
		if (resetMeleeMotion == null)
		{
			throw new MissingMethodException(typeof(ItemMelee).FullName, "ResetForFreshUnequip");
		}
	}

	public static Transform CartVolume(PhysGrabCart cart)
	{
		object? obj = cartVolume.GetValue(cart);
		return (Transform)((obj is Transform) ? obj : null);
	}

	public static List<PhysGrabObject> PhysicalCartItems(PhysGrabCart cart)
	{
		return cartItems.GetValue(cart) as List<PhysGrabObject>;
	}

	public static void SetCartHaul(PhysGrabCart cart, int total)
	{
		cartHaul.SetValue(cart, total);
	}

	public static Vector3 CartCenter(PhysGrabCart cart)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		Transform val = CartVolume(cart);
		if (!Object.op_Implicit((Object)(object)val))
		{
			return ((Component)cart).transform.position + Vector3.up * 0.6f;
		}
		return val.position;
	}

	public static float Value(ValuableObject obj)
	{
		return (float)value.GetValue(obj);
	}

	public static bool IsKinematic(PhysGrabObject obj)
	{
		return (bool)kinematic.GetValue(obj);
	}

	public static bool SafeToStore(PhysGrabObject obj)
	{
		if (!(bool)active.GetValue(obj))
		{
			return false;
		}
		ItemEquippable component = ((Component)obj).GetComponent<ItemEquippable>();
		if (Object.op_Implicit((Object)(object)component) && (component.IsEquipped() || (bool)equipping.GetValue(component) || (bool)unequipping.GetValue(component)))
		{
			return false;
		}
		ItemGun[] componentsInChildren = ((Component)obj).GetComponentsInChildren<ItemGun>(true);
		foreach (ItemGun obj2 in componentsInChildren)
		{
			object objA = gunState.GetValue(obj2);
			if (!object.Equals(objA, gunIdle) && !object.Equals(objA, gunEmpty))
			{
				return false;
			}
		}
		ItemMelee[] componentsInChildren2 = ((Component)obj).GetComponentsInChildren<ItemMelee>(true);
		foreach (ItemMelee val in componentsInChildren2)
		{
			if (val.IsSwinging())
			{
				return false;
			}
		}
		ItemGrenade[] componentsInChildren3 = ((Component)obj).GetComponentsInChildren<ItemGrenade>(true);
		foreach (ItemGrenade val2 in componentsInChildren3)
		{
			ItemToggle component2 = ((Component)val2).GetComponent<ItemToggle>();
			if ((bool)grenadeActive.GetValue(val2) || (Object.op_Implicit((Object)(object)component2) && component2.toggleState))
			{
				return false;
			}
		}
		ItemMine[] componentsInChildren4 = ((Component)obj).GetComponentsInChildren<ItemMine>(true);
		foreach (ItemMine val3 in componentsInChildren4)
		{
			ItemToggle component3 = ((Component)val3).GetComponent<ItemToggle>();
			if (!object.Equals(mineState.GetValue(val3), mineDisarmed) || (Object.op_Implicit((Object)(object)component3) && component3.toggleState))
			{
				return false;
			}
		}
		return true;
	}

	public static void SetKinematic(PhysGrabObject obj, bool state)
	{
		kinematic.SetValue(obj, state);
	}

	public static void ResetWeaponMotion(PhysGrabObject obj)
	{
		ItemMelee[] componentsInChildren = ((Component)obj).GetComponentsInChildren<ItemMelee>(true);
		foreach (ItemMelee obj2 in componentsInChildren)
		{
			resetMeleeMotion.Invoke(obj2, null);
		}
	}

	public static void StoreImpactState(PhysGrabObject obj, PhysGrabCart cart, List<Action> restore)
	{
		PhysGrabObjectImpactDetector detector = ((Component)obj).GetComponent<PhysGrabObjectImpactDetector>();
		if (!Object.op_Implicit((Object)(object)detector))
		{
			return;
		}
		object oldCart = detectorCart.GetValue(detector);
		object oldIndestructible = indestructible.GetValue(detector);
		bool inCart = detector.inCart;
		bool sliding = detector.isSliding;
		restore.Add(delegate
		{
			if (Object.op_Implicit((Object)(object)detector))
			{
				detectorCart.SetValue(detector, oldCart);
				indestructible.SetValue(detector, oldIndestructible);
				detector.inCart = inCart;
				detector.isSliding = sliding;
			}
		});
		detectorCart.SetValue(detector, cart);
		indestructible.SetValue(detector, true);
		detector.inCart = true;
		detector.isSliding = false;
	}

	public static void CompactRoomCheck(RoomVolumeCheck check, List<Action> restore)
	{
		//IL_0014: 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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = check.CheckPosition;
		Vector3 size = check.currentSize;
		restore.Add(delegate
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)check))
			{
				check.CheckPosition = position;
				check.currentSize = size;
			}
		});
		check.currentSize = Vector3.one * 0.1f;
	}

	public static void CenterRoomCheck(RoomVolumeCheck check, Vector3 position)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		check.CheckPosition = Quaternion.Inverse(((Component)check).transform.rotation) * (position - ((Component)check).transform.position);
		check.currentSize = Vector3.one * 0.1f;
	}
}
[HarmonyPatch(typeof(PhysGrabCart), "Start")]
internal static class CartStartPatch
{
	private static void Postfix(PhysGrabCart __instance)
	{
		if (Object.op_Implicit((Object)(object)VoidCartPlugin.Instance))
		{
			VoidCartPlugin.Instance.RegisterCart(__instance);
		}
	}
}
[HarmonyPatch(typeof(PhysGrabCart), "ObjectsInCart")]
internal static class CartValuePatch
{
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		MethodInfo update = AccessTools.Method(typeof(ValueScreen), "UpdateValue", new Type[1] { typeof(int) }, (Type[])null);
		MethodInfo combined = AccessTools.Method(typeof(CartValuePatch), "UpdateCombinedValue", (Type[])null, (Type[])null);
		int replaced = 0;
		foreach (CodeInstruction instruction in instructions)
		{
			if (CodeInstructionExtensions.Calls(instruction, update))
			{
				CodeInstruction cartArgument = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
				cartArgument.labels.AddRange(instruction.labels);
				cartArgument.blocks.AddRange(instruction.blocks);
				yield return cartArgument;
				yield return new CodeInstruction(OpCodes.Call, (object)combined);
				replaced++;
			}
			else
			{
				yield return instruction;
			}
		}
		if (replaced != 1)
		{
			throw new InvalidOperationException("Unsupported cart value scan: expected one display update.");
		}
	}

	private static void UpdateCombinedValue(ValueScreen screen, int physicalValue, PhysGrabCart cart)
	{
		int num = (Object.op_Implicit((Object)(object)VoidCartPlugin.Instance) ? VoidCartPlugin.Instance.IncludeStoredValue(cart, physicalValue) : physicalValue);
		screen.UpdateValue(num);
	}
}
[HarmonyPatch(typeof(PhysGrabObject), "Update")]
internal static class StoredUpdatePatch
{
	private static bool Prefix(PhysGrabObject __instance)
	{
		if (Object.op_Implicit((Object)(object)VoidCartPlugin.Instance))
		{
			return !VoidCartPlugin.Instance.IsStored(__instance);
		}
		return true;
	}
}
[HarmonyPatch(typeof(PhysGrabObject), "FixedUpdate")]
internal static class StoredPhysicsPatch
{
	private static bool Prefix(PhysGrabObject __instance)
	{
		if (Object.op_Implicit((Object)(object)VoidCartPlugin.Instance))
		{
			return !VoidCartPlugin.Instance.IsStored(__instance);
		}
		return true;
	}
}
[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
internal static class LevelChangePatch
{
	private static void Prefix(bool ___restarting)
	{
		if (!___restarting && (SemiFunc.MenuLevel() || SemiFunc.IsMasterClientOrSingleplayer()) && Object.op_Implicit((Object)(object)VoidCartPlugin.Instance))
		{
			VoidCartPlugin.Instance.BeforeSceneChange();
		}
	}
}
[HarmonyPatch(typeof(SemiFunc), "OnSceneSwitch")]
internal static class SceneSwitchPatch
{
	private static void Prefix()
	{
		if (Object.op_Implicit((Object)(object)VoidCartPlugin.Instance))
		{
			VoidCartPlugin.Instance.BeforeSceneChange();
		}
	}
}
public enum StoredItemCategory
{
	Inventory,
	Weapons,
	Cosmetics
}
public sealed class StoredItem
{
	private readonly List<Action> restore = new List<Action>();

	private readonly Rigidbody[] bodies;

	private readonly Vector3[] bodyOffsets;

	private readonly Quaternion[] bodyRotations;

	private readonly Renderer[] renderers;

	private readonly bool[] rendererEnabled;

	private readonly RoomVolumeCheck[] roomChecks;

	private readonly bool previousKinematic;

	private bool restored;

	public PhysGrabObject Object { get; private set; }

	public PhysGrabCart Cart { get; private set; }

	public int Id { get; private set; }

	public string DisplayName { get; private set; }

	public bool IsCosmetic { get; private set; }

	public StoredItemCategory Category { get; private set; }

	public bool IsWeapon => Category == StoredItemCategory.Weapons;

	public float Value
	{
		get
		{
			if (!Object.op_Implicit((Object)(object)Object))
			{
				return 0f;
			}
			ValuableObject component = ((Component)Object).GetComponent<ValuableObject>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return Math.Max(0f, GameAccess.Value(component));
			}
			ItemValuableBox component2 = ((Component)Object).GetComponent<ItemValuableBox>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return 0f;
			}
			return component2.CurrentValue;
		}
	}

	public Vector3 HalfSize { get; private set; }

	public Vector3 BoundsOffset { get; private set; }

	public Vector3 LastPosition { get; private set; }

	public Quaternion OriginalRotation { get; private set; }

	public StoredItem(PhysGrabObject obj, PhysGrabCart cart, int id)
	{
		//IL_004b: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_073b: Unknown result type (might be due to invalid IL or missing references)
		//IL_073d: 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_0177: 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_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_03db: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
		Object = obj;
		Cart = cart;
		Id = id;
		OriginalRotation = ((Component)obj).transform.rotation;
		LastPosition = ((Component)obj).transform.position;
		Vector3 lastPosition = LastPosition;
		IsCosmetic = (Object)(object)((Component)obj).GetComponentInChildren<CosmeticWorldObject>(true) != (Object)null;
		ItemAttributes component = ((Component)obj).GetComponent<ItemAttributes>();
		Category = (IsCosmetic ? StoredItemCategory.Cosmetics : (IsWeaponObject(obj, component) ? StoredItemCategory.Weapons : StoredItemCategory.Inventory));
		DisplayName = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.item) && !string.IsNullOrEmpty(component.item.itemName)) ? component.item.itemName : ((Object)obj).name.Replace("(Clone)", "").Replace("Valuable ", "").Trim());
		if (IsCosmetic)
		{
			DisplayName = "Cosmetic capsule · " + DisplayName;
		}
		previousKinematic = GameAccess.IsKinematic(obj);
		Collider[] componentsInChildren = ((Component)obj).GetComponentsInChildren<Collider>(true);
		Bounds bounds = default(Bounds);
		((Bounds)(ref bounds))..ctor(((Component)obj).transform.position, Vector3.one * 0.2f);
		bool flag = true;
		Collider[] array = componentsInChildren;
		foreach (Collider val in array)
		{
			if (val.enabled && !val.isTrigger)
			{
				if (flag)
				{
					bounds = val.bounds;
					flag = false;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(val.bounds);
				}
			}
		}
		HalfSize = Vector3.Max(((Bounds)(ref bounds)).extents, Vector3.one * 0.1f);
		BoundsOffset = ((Bounds)(ref bounds)).center - ((Component)obj).transform.position;
		renderers = ((Component)obj).GetComponentsInChildren<Renderer>(true);
		rendererEnabled = renderers.Select((Renderer val8) => val8.enabled).ToArray();
		roomChecks = ((Component)obj).GetComponentsInChildren<RoomVolumeCheck>(true);
		bodies = ((Component)obj).GetComponentsInChildren<Rigidbody>(true);
		bodyOffsets = bodies.Select((Rigidbody val8) => val8.position - ((Component)obj).transform.position).ToArray();
		bodyRotations = bodies.Select((Rigidbody val8) => val8.rotation).ToArray();
		try
		{
			Collider[] array2 = componentsInChildren;
			foreach (Collider val2 in array2)
			{
				Collider c = val2;
				bool enabled = c.enabled;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)c))
					{
						c.enabled = enabled;
					}
				});
				c.enabled = false;
			}
			Rigidbody[] array3 = bodies;
			foreach (Rigidbody val3 in array3)
			{
				Rigidbody b = val3;
				bool kinematic = b.isKinematic;
				bool collisions = b.detectCollisions;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)b))
					{
						b.isKinematic = kinematic;
						b.detectCollisions = collisions;
					}
				});
				if (!b.isKinematic)
				{
					b.velocity = Vector3.zero;
					b.angularVelocity = Vector3.zero;
				}
				b.isKinematic = true;
				b.detectCollisions = false;
			}
			for (int num3 = 0; num3 < renderers.Length; num3++)
			{
				Renderer r = renderers[num3];
				bool enabled2 = rendererEnabled[num3];
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)r))
					{
						r.enabled = enabled2;
					}
				});
				r.enabled = false;
			}
			Behaviour[] componentsInChildren2 = ((Component)obj).GetComponentsInChildren<Behaviour>(true);
			foreach (Behaviour val4 in componentsInChildren2)
			{
				if (!(val4 is Light) && !(val4 is Animator) && !(val4 is Animation))
				{
					continue;
				}
				Behaviour b2 = val4;
				bool enabled3 = b2.enabled;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)b2))
					{
						b2.enabled = enabled3;
					}
				});
				b2.enabled = false;
			}
			GameAccess.StoreImpactState(obj, cart, restore);
			MonoBehaviour[] componentsInChildren3 = ((Component)obj).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val5 in componentsInChildren3)
			{
				if (val5 is PhysGrabObject || val5 is ValuableObject || val5 is RoomVolumeCheck || val5 is CosmeticWorldObject || val5 is ItemValuableBox || val5 is PhotonView || val5 is PhotonTransformView)
				{
					continue;
				}
				MonoBehaviour b3 = val5;
				bool enabled4 = ((Behaviour)b3).enabled;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)b3))
					{
						((Behaviour)b3).enabled = enabled4;
					}
				});
				((Behaviour)b3).enabled = false;
			}
			AudioSource[] componentsInChildren4 = ((Component)obj).GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val6 in componentsInChildren4)
			{
				AudioSource a = val6;
				bool playing = a.isPlaying;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)a) && playing)
					{
						a.UnPause();
					}
				});
				if (playing)
				{
					a.Pause();
				}
			}
			ParticleSystem[] componentsInChildren5 = ((Component)obj).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val7 in componentsInChildren5)
			{
				ParticleSystem p = val7;
				bool playing2 = p.isPlaying;
				restore.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)p) && playing2)
					{
						p.Play(false);
					}
				});
				if (playing2)
				{
					p.Pause(false);
				}
			}
			RoomVolumeCheck[] array4 = roomChecks;
			foreach (RoomVolumeCheck check in array4)
			{
				GameAccess.CompactRoomCheck(check, restore);
			}
			FollowCart();
			RefreshRooms();
		}
		catch
		{
			Restore(lastPosition, OriginalRotation);
			throw;
		}
	}

	private static bool IsWeaponObject(PhysGrabObject obj, ItemAttributes attributes)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected I4, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Invalid comparison between Unknown and I4
		if (Object.op_Implicit((Object)(object)attributes) && Object.op_Implicit((Object)(object)attributes.item))
		{
			itemType itemType = attributes.item.itemType;
			switch (itemType - 6)
			{
			default:
				if ((int)itemType != 15)
				{
					break;
				}
				goto case 0;
			case 0:
			case 1:
			case 3:
			case 5:
				return true;
			case 2:
			case 4:
				break;
			}
		}
		if (!Object.op_Implicit((Object)(object)((Component)obj).GetComponentInChildren<ItemGun>(true)) && !Object.op_Implicit((Object)(object)((Component)obj).GetComponentInChildren<ItemMelee>(true)) && !Object.op_Implicit((Object)(object)((Component)obj).GetComponentInChildren<ItemGrenade>(true)))
		{
			return Object.op_Implicit((Object)(object)((Component)obj).GetComponentInChildren<ItemMine>(true));
		}
		return true;
	}

	public void FollowCart()
	{
		//IL_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		if (restored || !Object.op_Implicit((Object)(object)Object) || !Object.op_Implicit((Object)(object)Cart))
		{
			return;
		}
		LastPosition = GameAccess.CartCenter(Cart);
		((Component)Object).transform.SetPositionAndRotation(LastPosition, OriginalRotation);
		for (int i = 0; i < bodies.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)bodies[i]))
			{
				bodies[i].isKinematic = true;
				bodies[i].position = LastPosition + bodyOffsets[i];
				bodies[i].rotation = bodyRotations[i];
			}
		}
		Object.midPoint = LastPosition;
		Object.centerPoint = LastPosition;
		GameAccess.SetKinematic(Object, state: true);
		Object.OverrideIndestructible(0.5f);
		Object.OverrideGrabDisable(0.5f);
		RoomVolumeCheck[] array = roomChecks;
		foreach (RoomVolumeCheck val in array)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				GameAccess.CenterRoomCheck(val, LastPosition);
			}
		}
	}

	public void RefreshRooms()
	{
		RoomVolumeCheck[] array = roomChecks;
		foreach (RoomVolumeCheck val in array)
		{
			if (Object.op_Implicit((Object)(object)val) && ((Behaviour)val).isActiveAndEnabled)
			{
				val.CheckSet();
			}
		}
	}

	public void ShowExtractionVisuals()
	{
		for (int i = 0; i < renderers.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)renderers[i]))
			{
				renderers[i].enabled = rendererEnabled[i];
			}
		}
	}

	public void Restore(Vector3 position, Quaternion rotation)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_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_00ba: 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_00c6: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		if (restored)
		{
			return;
		}
		restored = true;
		if (Object.op_Implicit((Object)(object)Object))
		{
			((Component)Object).transform.SetPositionAndRotation(position, rotation);
			Quaternion val = rotation * Quaternion.Inverse(OriginalRotation);
			for (int i = 0; i < bodies.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)bodies[i]))
				{
					bodies[i].position = position + val * bodyOffsets[i];
					bodies[i].rotation = val * bodyRotations[i];
				}
			}
			Object.midPoint = position;
			Object.centerPoint = position;
			GameAccess.SetKinematic(Object, previousKinematic);
			try
			{
				GameAccess.ResetWeaponMotion(Object);
			}
			catch (Exception ex)
			{
				VoidCartPlugin.LogWarning("Could not reset a withdrawn weapon's motion: " + ex.Message);
			}
		}
		for (int num = restore.Count - 1; num >= 0; num--)
		{
			try
			{
				restore[num]();
			}
			catch (Exception ex2)
			{
				VoidCartPlugin.LogWarning("Could not restore an item component: " + ex2.Message);
			}
		}
		restore.Clear();
		if (Object.op_Implicit((Object)(object)Object))
		{
			Object.OverrideIndestructible(1.5f);
			Object.OverrideBreakEffects(1.5f);
			Object.OverrideGrabDisable(0.2f);
			RefreshRooms();
		}
	}
}
internal static class VoidCartMesh
{
	private sealed class Builder
	{
		private readonly List<Vector3> vertices = new List<Vector3>(400);

		private readonly List<Vector2> uvs = new List<Vector2>(400);

		private readonly List<int>[] triangles;

		public Builder(int submeshCount)
		{
			triangles = new List<int>[submeshCount];
			for (int i = 0; i < submeshCount; i++)
			{
				triangles[i] = new List<int>(600);
			}
		}

		public void Wall(Vector3[] lower, Vector3[] upper, bool inward, int material, bool metalCorners)
		{
			//IL_0062: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			for (int i = 0; i < lower.Length; i++)
			{
				int num = (i + 1) % lower.Length;
				int material2 = ((metalCorners && i % 2 == 0) ? 1 : material);
				if (inward)
				{
					Quad(upper[num], lower[num], lower[i], upper[i], material2);
				}
				else
				{
					Quad(upper[i], lower[i], lower[num], upper[num], material2);
				}
			}
		}

		public void Annulus(Vector3[] outer, Vector3[] inner, int material)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < outer.Length; i++)
			{
				int num = (i + 1) % outer.Length;
				Quad(outer[i], outer[num], inner[num], inner[i], material);
			}
		}

		public void Cap(Vector3[] ring, bool upward, int material)
		{
			//IL_004f: 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_0063: 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_0035: 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)
			Vector3 a = default(Vector3);
			((Vector3)(ref a))..ctor(0f, ring[0].y, 0f);
			for (int i = 0; i < ring.Length; i++)
			{
				int num = (i + 1) % ring.Length;
				if (upward)
				{
					Triangle(a, ring[i], ring[num], material);
				}
				else
				{
					Triangle(a, ring[num], ring[i], material);
				}
			}
		}

		private void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, int material)
		{
			//IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			int count = vertices.Count;
			vertices.Add(a);
			vertices.Add(b);
			vertices.Add(c);
			vertices.Add(d);
			uvs.Add(new Vector2(0f, 1f));
			uvs.Add(new Vector2(0f, 0f));
			uvs.Add(new Vector2(1f, 0f));
			uvs.Add(new Vector2(1f, 1f));
			triangles[material].Add(count);
			triangles[material].Add(count + 1);
			triangles[material].Add(count + 2);
			triangles[material].Add(count);
			triangles[material].Add(count + 2);
			triangles[material].Add(count + 3);
		}

		private void Triangle(Vector3 a, Vector3 b, Vector3 c, int material)
		{
			//IL_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			int count = vertices.Count;
			vertices.Add(a);
			vertices.Add(b);
			vertices.Add(c);
			uvs.Add(new Vector2(a.x, a.z));
			uvs.Add(new Vector2(b.x, b.z));
			uvs.Add(new Vector2(c.x, c.z));
			triangles[material].Add(count);
			triangles[material].Add(count + 1);
			triangles[material].Add(count + 2);
		}

		public Mesh Finish(string name)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			Mesh val = new Mesh();
			((Object)val).name = name;
			val.vertices = vertices.ToArray();
			val.uv = uvs.ToArray();
			val.subMeshCount = triangles.Length;
			for (int i = 0; i < triangles.Length; i++)
			{
				val.SetTriangles(triangles[i].ToArray(), i);
			}
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}
	}

	public static Mesh CreateHull(float width, float depth, float height)
	{
		RequirePositive(width, "width");
		RequirePositive(depth, "depth");
		RequirePositive(height, "height");
		float num = Mathf.Min(width, depth);
		float num2 = num * 0.047f;
		float num3 = Mathf.Min(height * 0.12f, num * 0.065f);
		float num4 = Mathf.Min(num2 * 0.23f, num3 * 0.24f);
		float num5 = Mathf.Min(height * 0.12f, num * 0.065f);
		float num6 = Mathf.Min(height * 0.07f, num * 0.034f);
		float num7 = num * 0.026f;
		float num8 = num * 0.09f;
		Vector3[] array = Ring(width * 0.8f, depth * 0.8f, num8 * 0.8f, 0f - height);
		Vector3[] array2 = Ring(width * 0.82f, depth * 0.82f, num8 * 0.82f, 0f - height + num4);
		Vector3[] array3 = Ring(width * 0.83f, depth * 0.83f, num8 * 0.83f, 0f - height + num5);
		Vector3[] array4 = Ring(width - num4 * 2f, depth - num4 * 2f, num8, 0f - num3);
		Vector3[] array5 = Ring(width, depth, num8, 0f - num3);
		Vector3[] array6 = Ring(width, depth, num8, 0f - num4);
		Vector3[] array7 = Ring(width - num4 * 2f, depth - num4 * 2f, num8 - num4, 0f);
		Vector3[] array8 = Ring(width - num2 * 2f + num4 * 2f, depth - num2 * 2f + num4 * 2f, num8 * 0.7f, 0f);
		Vector3[] array9 = Ring(width - num2 * 2f, depth - num2 * 2f, num8 * 0.7f, 0f - num4);
		Vector3[] array10 = Ring(width - num2 * 2f, depth - num2 * 2f, num8 * 0.7f, 0f - num3);
		Vector3[] array11 = Ring(width * 0.8f - num7 * 2f, depth * 0.8f - num7 * 2f, num8 * 0.55f, 0f - height + num6);
		Builder builder = new Builder(2);
		builder.Wall(array, array2, inward: false, 1, metalCorners: false);
		builder.Wall(array2, array3, inward: false, 1, metalCorners: false);
		builder.Wall(array3, array4, inward: false, 0, metalCorners: true);
		builder.Wall(array4, array5, inward: false, 1, metalCorners: false);
		builder.Wall(array5, array6, inward: false, 1, metalCorners: false);
		builder.Wall(array6, array7, inward: false, 1, metalCorners: false);
		builder.Annulus(array7, array8, 1);
		builder.Wall(array9, array8, inward: true, 1, metalCorners: false);
		builder.Wall(array10, array9, inward: true, 1, metalCorners: false);
		builder.Wall(array11, array10, inward: true, 0, metalCorners: false);
		builder.Cap(array11, upward: true, 0);
		builder.Cap(array, upward: false, 0);
		return builder.Finish("Void Cart - beveled basket");
	}

	public static Mesh CreateAperture(float width, float depth, float y)
	{
		RequirePositive(width, "width");
		RequirePositive(depth, "depth");
		if (float.IsNaN(y) || float.IsInfinity(y))
		{
			throw new ArgumentOutOfRangeException("y");
		}
		Vector3[] ring = Ring(width, depth, Mathf.Min(width, depth) * 0.09f, y);
		Builder builder = new Builder(1);
		builder.Cap(ring, upward: true, 0);
		builder.Cap(ring, upward: false, 0);
		return builder.Finish("Void Cart - aperture");
	}

	private static void RequirePositive(float value, string argument)
	{
		if (value <= 0f || float.IsNaN(value) || float.IsInfinity(value))
		{
			throw new ArgumentOutOfRangeException(argument, "Mesh dimensions must be finite and positive.");
		}
	}

	private static Vector3[] Ring(float width, float depth, float cut, float y)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_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_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		float num = width * 0.5f;
		float num2 = depth * 0.5f;
		cut = Mathf.Min(cut, Mathf.Min(num, num2) * 0.45f);
		return (Vector3[])(object)new Vector3[8]
		{
			new Vector3(0f - num + cut, y, 0f - num2),
			new Vector3(0f - num, y, 0f - num2 + cut),
			new Vector3(0f - num, y, num2 - cut),
			new Vector3(0f - num + cut, y, num2),
			new Vector3(num - cut, y, num2),
			new Vector3(num, y, num2 - cut),
			new Vector3(num, y, 0f - num2 + cut),
			new Vector3(num - cut, y, 0f - num2)
		};
	}
}
internal sealed class VoidCartNetwork : IDisposable
{
	private sealed class PendingStore
	{
		public int CartId;

		public float Deadline;
	}

	private const byte EventCode = 176;

	private const string Marker = "caspi.voidcart/1";

	private const string PlayerKey = "caspi.voidcart";

	private const string EpochKey = "caspi.voidcart.epoch";

	private readonly VoidCartPlugin plugin;

	private readonly Dictionary<int, PendingStore> pending = new Dictionary<int, PendingStore>();

	private readonly Dictionary<int, float> requestTimes = new Dictionary<int, float>();

	private Room currentRoom;

	private string epoch = "";

	private float nextCheck;

	private bool synchronized;

	private int previousMaster;

	private bool transitioning;

	private bool awaitFreshEpoch;

	private string retiredEpoch = "";

	private readonly Dictionary<int, int> snapshot = new Dictionary<int, int>();

	private int snapshotId;

	private int expectedSnapshotItems;

	private int receivedChunks;

	private int nextSnapshotId;

	public bool Ready { get; private set; }

	internal VoidCartNetwork(VoidCartPlugin owner)
	{
		plugin = owner;
		PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
	}

	public void Tick()
	{
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Expected O, but got Unknown
		if (!SemiFunc.IsMultiplayer())
		{
			Ready = !transitioning;
			return;
		}
		if (PhotonNetwork.CurrentRoom != currentRoom)
		{
			if (currentRoom != null)
			{
				plugin.RestoreAll();
			}
			currentRoom = PhotonNetwork.CurrentRoom;
			epoch = "";
			retiredEpoch = "";
			awaitFreshEpoch = false;
			synchronized = false;
			pending.Clear();
			requestTimes.Clear();
			snapshot.Clear();
			previousMaster = 0;
			nextCheck = 0f;
		}
		if (!PhotonNetwork.InRoom)
		{
			Ready = false;
			return;
		}
		if (transitioning)
		{
			Ready = false;
			return;
		}
		if (Time.unscaledTime >= nextCheck)
		{
			nextCheck = Time.unscaledTime + 1f;
			if (!((Dictionary<object, object>)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"caspi.voidcart", out object version) || !object.Equals(version, "0.4.0"))
			{
				Player localPlayer = PhotonNetwork.LocalPlayer;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)(object)val).Add((object)"caspi.voidcart", (object)"0.4.0");
				localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
			if (PhotonNetwork.IsMasterClient && !((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"caspi.voidcart.epoch", out object value))
			{
				SetEpoch();
			}
			if (((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"caspi.voidcart.epoch", out value) && value is string && (!awaitFreshEpoch || (string)value != retiredEpoch) && epoch != (string)value)
			{
				plugin.RestoreAll();
				pending.Clear();
				epoch = (string)value;
				synchronized = PhotonNetwork.IsMasterClient;
				awaitFreshEpoch = false;
			}
			int actorNumber = PhotonNetwork.MasterClient.ActorNumber;
			if (previousMaster != 0 && actorNumber != previousMaster)
			{
				synchronized = PhotonNetwork.IsMasterClient;
			}
			previousMaster = actorNumber;
			Ready = epoch.Length != 0 && synchronized && pending.Count == 0 && PhotonNetwork.PlayerList.All((Player p) => ((Dictionary<object, object>)(object)p.CustomProperties).TryGetValue((object)"caspi.voidcart", out version) && object.Equals(version, "0.4.0"));
			if (!PhotonNetwork.IsMasterClient && !synchronized && epoch.Length != 0)
			{
				Send("sync", 0, 0, null, (ReceiverGroup)2, null);
			}
		}
		KeyValuePair<int, PendingStore>[] array = pending.ToArray();
		for (int num = 0; num < array.Length; num++)
		{
			KeyValuePair<int, PendingStore> keyValuePair = array[num];
			PhotonView val2 = PhotonView.Find(keyValuePair.Value.CartId);
			PhotonView val3 = PhotonView.Find(keyValuePair.Key);
			if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val3))
			{
				PhysGrabCart component = ((Component)val2).GetComponent<PhysGrabCart>();
				PhysGrabObject component2 = ((Component)val3).GetComponent<PhysGrabObject>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && component2.spawned && plugin.ApplyStore(component, component2) != null)
				{
					pending.Remove(keyValuePair.Key);
					continue;
				}
			}
			if (Time.unscaledTime > keyValuePair.Value.Deadline)
			{
				pending.Remove(keyValuePair.Key);
				synchronized = PhotonNetwork.IsMasterClient;
				VoidCartPlugin.LogWarning("An inventory object did not spawn in time; requesting a fresh host snapshot.");
			}
		}
	}

	private void SetEpoch()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		string value = Guid.NewGuid().ToString("N");
		Room obj = currentRoom;
		Hashtable val = new Hashtable();
		((Dictionary<object, object>)(object)val).Add((object)"caspi.voidcart.epoch", (object)value);
		obj.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
	}

	public void NewScene()
	{
		if (epoch.Length != 0)
		{
			retiredEpoch = epoch;
		}
		epoch = "";
		awaitFreshEpoch = retiredEpoch.Length != 0;
		transitioning = false;
		pending.Clear();
		snapshot.Clear();
		synchronized = false;
		Ready = false;
		nextCheck = 0f;
		if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
		{
			currentRoom = PhotonNetwork.CurrentRoom;
			SetEpoch();
		}
	}

	public void ClearPending()
	{
		pending.Clear();
		snapshot.Clear();
		synchronized = false;
		Ready = false;
		if (epoch.Length != 0)
		{
			retiredEpoch = epoch;
		}
		epoch = "";
		transitioning = true;
		awaitFreshEpoch = true;
	}

	private bool Send(string action, int cart, int item, object extra, ReceiverGroup receivers, int[] targets)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_0036: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMultiplayer())
		{
			return true;
		}
		if (!PhotonNetwork.InRoom || epoch.Length == 0 || transitioning || awaitFreshEpoch)
		{
			return false;
		}
		RaiseEventOptions val = new RaiseEventOptions();
		val.Receivers = receivers;
		val.TargetActors = targets;
		RaiseEventOptions val2 = val;
		return PhotonNetwork.RaiseEvent((byte)176, (object)new object[6] { "caspi.voidcart/1", epoch, action, cart, item, extra }, val2, SendOptions.SendReliable);
	}

	public bool BroadcastStore(PhysGrabCart cart, StoredItem item)
	{
		return Send("stored", VoidCartPlugin.ObjectId((Component)(object)cart), item.Id, null, (ReceiverGroup)0, null);
	}

	public bool BroadcastRelease(int id, Vector3 position, Quaternion rotation)
	{
		return Send("released", 0, id, new float[7] { position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, rotation.w }, (ReceiverGroup)0, null);
	}

	public void Request(string action, PhysGrabCart cart, int id)
	{
		if (!Send(action, VoidCartPlugin.ObjectId((Component)(object)cart), id, null, (ReceiverGroup)2, null))
		{
			plugin.Status = "Could not reach the host. Try again.";
		}
	}

	private void OnEvent(EventData data)
	{
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		if (data.Code != 176 || !PhotonNetwork.InRoom || transitioning || awaitFreshEpoch)
		{
			return;
		}
		object[] array = data.CustomData as object[];
		if (!WireProtocol.ValidEnvelope(array, "caspi.voidcart/1", epoch))
		{
			return;
		}
		string text = (string)array[2];
		int num = (int)array[3];
		int num2 = (int)array[4];
		try
		{
			bool flag = data.Sender == PhotonNetwork.MasterClient.ActorNumber;
			if (text == "notice" && flag && array[5] is string)
			{
				plugin.Status = (string)array[5];
			}
			else if (text == "stored" && flag)
			{
				pending[num2] = new PendingStore
				{
					CartId = num,
					Deadline = Time.unscaledTime + 20f
				};
			}
			else if (text == "released" && flag)
			{
				float[] array2 = array[5] as float[];
				if (WireProtocol.ValidPose(array2))
				{
					pending.Remove(num2);
					plugin.ApplyRelease(num2, new Vector3(array2[0], array2[1], array2[2]), new Quaternion(array2[3], array2[4], array2[5], array2[6]));
				}
			}
			else if (text == "snapshotBegin" && flag && array[5] is int)
			{
				snapshot.Clear();
				snapshotId = num;
				expectedSnapshotItems = (int)array[5];
				receivedChunks = 0;
				synchronized = false;
			}
			else if (text == "snapshot" && flag && num == snapshotId && num2 == receivedChunks)
			{
				if (array[5] is int[] array3 && array3.Length <= 200 && array3.Length % 2 == 0)
				{
					for (int i = 0; i < array3.Length; i += 2)
					{
						snapshot[array3[i + 1]] = array3[i];
					}
					receivedChunks++;
				}
			}
			else if (text == "synced" && flag && num == snapshotId && num2 == receivedChunks && snapshot.Count == expectedSnapshotItems)
			{
				StoredItem[] array4 = plugin.Items.Values.Where((StoredItem storedItem2) => !snapshot.ContainsKey(storedItem2.Id)).ToArray();
				foreach (StoredItem storedItem in array4)
				{
					plugin.ApplyRelease(storedItem.Id, storedItem.LastPosition, storedItem.OriginalRotation);
				}
				pending.Clear();
				foreach (KeyValuePair<int, int> item2 in snapshot)
				{
					pending[item2.Key] = new PendingStore
					{
						CartId = item2.Value,
						Deadline = Time.unscaledTime + 20f
					};
				}
				synchronized = true;
			}
			else
			{
				if (!PhotonNetwork.IsMasterClient || data.Sender == PhotonNetwork.LocalPlayer.ActorNumber)
				{
					return;
				}
				Player player = PhotonNetwork.CurrentRoom.GetPlayer(data.Sender, false);
				if (player == null || !((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"caspi.voidcart", out object value) || !object.Equals(value, "0.4.0") || (requestTimes.TryGetValue(data.Sender, out var value2) && Time.unscaledTime - value2 < 0.15f))
				{
					return;
				}
				requestTimes[data.Sender] = Time.unscaledTime;
				if (text == "sync")
				{
					int[] targets = new int[1] { data.Sender };
					StoredItem[] array5 = plugin.Items.Values.Where((StoredItem storedItem2) => Object.op_Implicit((Object)(object)storedItem2.Cart) && Object.op_Implicit((Object)(object)storedItem2.Object)).ToArray();
					int cart = ++nextSnapshotId;
					if (!Send("snapshotBegin", cart, 0, array5.Length, (ReceiverGroup)0, targets))
					{
						return;
					}
					int item = 0;
					for (int num4 = 0; num4 < array5.Length; num4 += 100)
					{
						int[] extra = array5.Skip(num4).Take(100).SelectMany((StoredItem storedItem2) => new int[2]
						{
							VoidCartPlugin.ObjectId((Component)(object)storedItem2.Cart),
							storedItem2.Id
						})
							.ToArray();
						if (!Send("snapshot", cart, item++, extra, (ReceiverGroup)0, targets))
						{
							return;
						}
					}
					Send("synced", cart, item, null, (ReceiverGroup)0, targets);
				}
				else
				{
					PhotonView val = PhotonView.Find(num);
					PhysGrabCart cart2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabCart>() : null);
					PlayerAvatar player2 = SemiFunc.PlayerAvatarGetFromPhotonPlayer(player);
					if (plugin.NearCart(cart2, player2))
					{
						plugin.HandleRequest(text, cart2, num2);
						Send("notice", num, num2, plugin.Status, (ReceiverGroup)0, new int[1] { data.Sender });
					}
				}
			}
		}
		catch (Exception ex)
		{
			VoidCartPlugin.LogWarning("Ignored a failed Void Cart network operation: " + ex.Message);
		}
	}

	public void Dispose()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
		pending.Clear();
		if (PhotonNetwork.InRoom)
		{
			Player localPlayer = PhotonNetwork.LocalPlayer;
			Hashtable val = new Hashtable();
			((Dictionary<object, object>)(object)val).Add((object)"caspi.voidcart", (object)null);
			localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
		}
	}
}
[BepInPlugin("caspi.voidcart", "Void Cart", "0.4.0")]
public sealed class VoidCartPlugin : BaseUnityPlugin
{
	public const string PluginId = "caspi.voidcart";

	public const string Version = "0.4.0";

	internal readonly Dictionary<int, StoredItem> Items = new Dictionary<int, StoredItem>();

	private readonly Dictionary<PhysGrabObject, float> candidates = new Dictionary<PhysGrabObject, float>();

	private readonly Dictionary<PhysGrabObject, PhysGrabCart> candidateCarts = new Dictionary<PhysGrabObject, PhysGrabCart>();

	private readonly Dictionary<PhysGrabObject, float> cooldowns = new Dictionary<PhysGrabObject, float>();

	private readonly HashSet<PhysGrabCart> carts = new HashSet<PhysGrabCart>();

	private readonly HashSet<PhysGrabCart> unloading = new HashSet<PhysGrabCart>();

	private readonly List<Action> afterTransition = new List<Action>();

	private ConfigEntry<KeyCode> openKey;

	private ConfigEntry<KeyCode> alternateOpenKey;

	private ConfigEntry<bool> autoStore;

	private ConfigEntry<bool> portalAccent;

	private ConfigEntry<float> interactionDistance;

	private ConfigEntry<float> settleTime;

	private Harmony harmony;

	private VoidCartNetwork network;

	private float nextScan;

	private float nextDiscover;

	private float nextUnload;

	private float nextRoomRefresh;

	private float nextHint;

	private float noticeUntil;

	private string inventoryNotice;

	private bool sceneChanging;

	private CursorLockMode previousLock;

	private bool previousCursorVisible;

	public static VoidCartPlugin Instance { get; private set; }

	public PhysGrabCart SelectedCart { get; private set; }

	public bool MenuOpen { get; private set; }

	public string Status { get; internal set; }

	public KeyCode OpenKey => openKey.Value;

	public KeyCode AlternateOpenKey => alternateOpenKey.Value;

	public string OpenKeys
	{
		get
		{
			//IL_0001: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if ((int)AlternateOpenKey != 0 && AlternateOpenKey != OpenKey)
			{
				return string.Concat(AlternateOpenKey, " / ", OpenKey);
			}
			return ((object)OpenKey).ToString();
		}
	}

	public string InventoryHint { get; private set; }

	internal bool IsHost
	{
		get
		{
			if (Object.op_Implicit((Object)(object)GameManager.instance))
			{
				if (SemiFunc.IsMultiplayer())
				{
					return PhotonNetwork.IsMasterClient;
				}
				return true;
			}
			return false;
		}
	}

	internal bool CanStore
	{
		get
		{
			if (Object.op_Implicit((Object)(object)GameManager.instance) && Object.op_Implicit((Object)(object)RunManager.instance) && !sceneChanging && network != null && network.Ready && !SemiFunc.RunIsShop())
			{
				return !SemiFunc.MenuLevel();
			}
			return false;
		}
	}

	internal float InteractionDistance => interactionDistance.Value;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected O, but got Unknown
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		GameObject gameObject = ((Component)this).gameObject;
		((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x3D);
		Instance = this;
		Status = "Buy a Void Cart in the shop, then drop loot inside to store it.";
		openKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "OpenInventory", (KeyCode)289, "Open the nearest Void Cart. Escape closes it.");
		alternateOpenKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "AlternateOpenInventory", (KeyCode)98, "Extra key to open the nearest Void Cart. It only opens, so typing in Search never closes the inventory. None disables it.");
		autoStore = ((BaseUnityPlugin)this).Config.Bind<bool>("Storage", "AutoStore", true, "Automatically store supported released loot whose center is inside a purchased Void Cart.");
		portalAccent = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "PurplePortal", true, "Show the custom dark basket, black void, animated purple vortex and illuminated rim on Void Carts.");
		interactionDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "InteractionDistance", 3.5f, new ConfigDescription("Maximum Void Cart interaction distance in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), new object[0]));
		settleTime = ((BaseUnityPlugin)this).Config.Bind<float>("Storage", "SettleTime", 0.6f, new ConfigDescription("Time an item must remain released inside the cart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f), new object[0]));
		try
		{
			GameAccess.Validate();
			VoidCartShop.Configure(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("caspi.voidcart");
			harmony.PatchAll(typeof(VoidCartPlugin).Assembly);
			if (Object.op_Implicit((Object)(object)StatsManager.instance))
			{
				VoidCartShop.EnsureRegistered(StatsManager.instance);
			}
			network = new VoidCartNetwork(this);
			((Component)this).gameObject.AddComponent<VoidCartUI>();
			SceneManager.sceneLoaded += SceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Void Cart 0.4.0 loaded. Buy a Void Cart in the shop; " + OpenKeys + " nearby opens its storage. Multiplayer requires this version on every player."));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Void Cart could not initialize against this game version: " + ex));
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			((Behaviour)this).enabled = false;
		}
	}

	internal static void LogWarning(string message)
	{
		if (Object.op_Implicit((Object)(object)Instance))
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)message);
		}
	}

	private void SceneLoaded(Scene scene, LoadSceneMode mode)
	{
		foreach (Action item in afterTransition)
		{
			item();
		}
		afterTransition.Clear();
		sceneChanging = false;
		nextDiscover = 0f;
		nextScan = Time.unscaledTime + 2f;
		if (network != null)
		{
			network.NewScene();
		}
	}

	private void Update()
	{
		//IL_0068: 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)
		if (network == null || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance))
		{
			return;
		}
		network.Tick();
		if (MenuOpen && (!Object.op_Implicit((Object)(object)SelectedCart) || !NearCart(SelectedCart, SemiFunc.PlayerAvatarLocal()) || SemiFunc.MenuLevel()))
		{
			CloseInventory();
		}
		if (KeyPressed(OpenKey) || (!MenuOpen && KeyPressed(AlternateOpenKey)))
		{
			if (MenuOpen)
			{
				CloseInventory();
			}
			else
			{
				OpenInventory();
			}
		}
		if (MenuOpen)
		{
			if (KeyPressed((KeyCode)27))
			{
				CloseInventory();
			}
			else
			{
				SemiFunc.CursorUnlock(0.15f);
				if (Object.op_Implicit((Object)(object)InputManager.instance))
				{
					InputManager.instance.DisableMovement(0.15f);
					InputManager.instance.DisableAiming(0.15f);
					InputManager.instance.DisableControlsExcept(0.15f, new List<InputKey>());
				}
				if (Object.op_Implicit((Object)(object)PhysGrabber.instance))
				{
					PhysGrabber.instance.OverrideGrabDisable(0.15f);
				}
			}
		}
		if (Time.unscaledTime >= nextDiscover)
		{
			nextDiscover = Time.unscaledTime + 2f;
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
			foreach (PhysGrabCart cart in array)
			{
				RegisterCart(cart);
			}
			carts.RemoveWhere((PhysGrabCart c) => !Object.op_Implicit((Object)(object)c) || !VoidCartShop.IsVoidCart(c));
			PhysGrabObject[] array2 = cooldowns.Keys.Where((PhysGrabObject o) => !Object.op_Implicit((Object)(object)o) || cooldowns[o] < Time.unscaledTime).ToArray();
			foreach (PhysGrabObject key in array2)
			{
				cooldowns.Remove(key);
			}
		}
		if (Time.unscaledTime >= nextHint)
		{
			nextHint = Time.unscaledTime + 0.25f;
			InventoryHint = null;
			if (!sceneChanging && !SemiFunc.MenuLevel())
			{
				PhysGrabCart nearby = NearestCart(SemiFunc.PlayerAvatarLocal());
				if (Time.unscaledTime < noticeUntil)
				{
					InventoryHint = inventoryNotice;
				}
				else if (Object.op_Implicit((Object)(object)nearby))
				{
					InventoryHint = OpenKeys + "  Open Void Cart  |  " + Items.Values.Count((StoredItem storedItem2) => (Object)(object)storedItem2.Cart == (Object)(object)nearby && Object.op_Implicit((Object)(object)storedItem2.Object)) + " stored";
				}
			}
		}
		if (Time.unscaledTime >= nextScan)
		{
			nextScan = Time.unscaledTime + 0.15f;
			if (IsHost && CanStore && autoStore.Value)
			{
				PhysGrabCart[] array3 = carts.ToArray();
				foreach (PhysGrabCart val in array3)
				{
					if (Object.op_Implicit((Object)(object)val) && !unloading.Contains(val))
					{
						ScanCart(val, immediate: false);
					}
				}
			}
			PhysGrabObject[] array4 = candidates.Keys.Where((PhysGrabObject o) => !Object.op_Implicit((Object)(object)o) || Time.unscaledTime - candidates[o] > 5f).ToArray();
			foreach (PhysGrabObject key2 in array4)
			{
				candidates.Remove(key2);
				candidateCarts.Remove(key2);
			}
		}
		if (!IsHost || !(Time.unscaledTime >= nextUnload))
		{
			return;
		}
		nextUnload = Time.unscaledTime + 0.35f;
		PhysGrabCart[] array5 = unloading.ToArray();
		foreach (PhysGrabCart cart2 in array5)
		{
			Dictionary<int, StoredItem>.ValueCollection values = Items.Values;
			Func<StoredItem, bool> predicate = (StoredItem storedItem2) => (Object)(object)storedItem2.Cart == (Object)(object)cart2 && Object.op_Implicit((Object)(object)storedItem2.Object);
			StoredItem storedItem = values.FirstOrDefault(predicate);
			if (storedItem == null || !Object.op_Implicit((Object)(object)cart2) || !VoidCartShop.IsVoidCart(cart2))
			{
				unloading.Remove(cart2);
			}
			else
			{
				WithdrawHost(cart2, storedItem.Id);
			}
		}
	}

	private void LateUpdate()
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		bool flag = Time.unscaledTime >= nextRoomRefresh;
		if (flag)
		{
			nextRoomRefresh = Time.unscaledTime + 0.5f;
		}
		StoredItem[] array = Items.Values.ToArray();
		foreach (StoredItem storedItem in array)
		{
			if (!Object.op_Implicit((Object)(object)storedItem.Object))
			{
				Items.Remove(storedItem.Id);
				continue;
			}
			if (!Object.op_Implicit((Object)(object)storedItem.Cart) || !VoidCartShop.IsVoidCart(storedItem.Cart))
			{
				storedItem.Restore(storedItem.LastPosition, storedItem.OriginalRotation);
				Items.Remove(storedItem.Id);
				continue;
			}
			storedItem.FollowCart();
			if (flag)
			{
				storedItem.RefreshRooms();
			}
		}
	}

	private static bool KeyPressed(KeyCode key)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key == 0)
		{
			return false;
		}
		if (Keyboard.current != null && Enum.TryParse<Key>(((object)key).ToString(), out Key result))
		{
			return ((ButtonControl)Keyboard.current[result]).wasPressedThisFrame;
		}
		return false;
	}

	private void OpenInventory()
	{
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		if (sceneChanging || SemiFunc.MenuLevel())
		{
			return;
		}
		PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
		if (!Object.op_Implicit((Object)(object)val))
		{
			return;
		}
		PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
		foreach (PhysGrabCart cart in array)
		{
			RegisterCart(cart);
		}
		SelectedCart = NearestCart(val);
		if (!Object.op_Implicit((Object)(object)SelectedCart))
		{
			Status = "Move within " + interactionDistance.Value.ToString("0.#") + "m of the purple Void Cart, then press " + OpenKeys + ".";
			inventoryNotice = Status;
			noticeUntil = Time.unscaledTime + 4f;
			nextHint = 0f;
			return;
		}
		noticeUntil = 0f;
		previousLock = Cursor.lockState;
		previousCursorVisible = Cursor.visible;
		MenuOpen = true;
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
		if (Object.op_Implicit((Object)(object)PhysGrabber.instance))
		{
			PhysGrabber.instance.OverrideGrabDisable(0.2f);
		}
		Status = ((!network.Ready) ? "Every player needs Void Cart 0.4.0 before storing items." : (SemiFunc.RunIsShop() ? "Storage pauses in the shop. Buy items normally first." : "Scroll to browse. Withdraw places the original item beside the cart."));
	}

	private PhysGrabCart NearestCart(PlayerAvatar player)
	{
		if (Object.op_Implicit((Object)(object)player))
		{
			return carts.Where((PhysGrabCart c) => Object.op_Implicit((Object)(object)c) && ((Component)c).gameObject.activeInHierarchy && NearCart(c, player)).OrderBy(delegate(PhysGrabCart c)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = ((Component)c).transform.position - ((Component)player).transform.position;
				return ((Vector3)(ref val)).sqrMagnitude;
			}).FirstOrDefault();
		}
		return null;
	}

	public void CloseInventory()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		if (MenuOpen)
		{
			MenuOpen = false;
			Cursor.lockState = previousLock;
			Cursor.visible = previousCursorVisible;
			SelectedCart = null;
		}
	}

	internal bool NearCart(PhysGrabCart cart, PlayerAvatar player)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart) && Object.op_Implicit((Object)(object)player))
		{
			return Vector3.Distance(((Component)cart).transform.position, ((Component)player).transform.position) <= interactionDistance.Value;
		}
		return false;
	}

	internal void RegisterCart(PhysGrabCart cart)
	{
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart) && carts.Add(cart) && portalAccent.Value && !Object.op_Implicit((Object)(object)((Component)cart).GetComponent<VoidCartVisual>()))
		{
			((Component)cart).gameObject.AddComponent<VoidCartVisual>();
		}
	}

	public List<StoredItem> GetEntries(PhysGrabCart cart)
	{
		if (!Object.op_Implicit((Object)(object)cart) || !VoidCartShop.IsVoidCart(cart))
		{
			return new List<StoredItem>();
		}
		return Items.Values.Where((StoredItem i) => (Object)(object)i.Cart == (Object)(object)cart && Object.op_Implicit((Object)(object)i.Object)).OrderBy<StoredItem, string>((StoredItem i) => i.DisplayName, StringComparer.OrdinalIgnoreCase).ThenBy((StoredItem i) => i.Id)
			.ToList();
	}

	internal static int ObjectId(Component obj)
	{
		if (!Object.op_Implicit((Object)(object)obj))
		{
			return 0;
		}
		if (!Object.op_Implicit((Object)(object)GameManager.instance))
		{
			return ((Object)obj).GetInstanceID();
		}
		PhotonView component = obj.GetComponent<PhotonView>();
		if (!SemiFunc.IsMultiplayer())
		{
			return ((Object)obj).GetInstanceID();
		}
		if (!Object.op_Implicit((Object)(object)component))
		{
			return 0;
		}
		return component.ViewID;
	}

	internal bool IsStored(PhysGrabObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj))
		{
			return false;
		}
		if (Items.TryGetValue(ObjectId((Component)(object)obj), out var value))
		{
			return (Object)(object)value.Object == (Object)(object)obj;
		}
		return false;
	}

	internal StoredItem Stored(PhysGrabObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj) || !Items.TryGetValue(ObjectId((Component)(object)obj), out var value) || !((Object)(object)value.Object == (Object)(object)obj))
		{
			return null;
		}
		return value;
	}

	private bool Eligible(PhysGrabObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj) || !((Behaviour)obj).enabled || !obj.spawned || obj.dead || obj.grabbed || (obj.playerGrabbing != null && obj.playerGrabbing.Count != 0) || IsStored(obj) || !GameAccess.SafeToStore(obj))
		{
			return false;
		}
		if (cooldowns.ContainsKey(obj) && cooldowns[obj] > Time.unscaledTime)
		{
			return false;
		}
		if (Object.op_Implicit((Object)(object)((Component)obj).GetComponentInParent<PhysGrabCart>()) || Object.op_Implicit((Object)(object)((Component)obj).GetComponentInParent<PlayerAvatar>()) || Object.op_Implicit((Object)(object)((Component)obj).GetComponentInParent<EnemyRigidbody>()))
		{
			return false;
		}
		if (!Object.op_Implicit((Object)(object)((Component)obj).GetComponent<ValuableObject>()) && !Object.op_Implicit((Object)(object)((Component)obj).GetComponent<ItemAttributes>()) && !Object.op_Implicit((Object)(object)((Component)obj).GetComponentInChildren<CosmeticWorldObject>(true)))
		{
			return false;
		}
		if (((Component)obj).GetComponentsInChildren<PhysGrabObject>(true).Length != 1 || (Object.op_Implicit((Object)(object)((Component)obj).transform.parent) && Object.op_Implicit((Object)(object)((Component)((Component)obj).transform.parent).GetComponentInParent<PhysGrabObject>())))
		{
			return false;
		}
		Joint[] componentsInChildren = ((Component)obj).GetComponentsInChildren<Joint>(true);
		foreach (Joint val in componentsInChildren)
		{
			if (Object.op_Implicit((Object)(object)val.connectedBody) && !((Component)val.connectedBody).transform.IsChildOf(((Component)obj).transform))
			{
				return false;
			}
		}
		if (ObjectId((Component)(object)obj) != 0)
		{
			return Object.op_Implicit((Object)(object)obj.rb);
		}
		return false;
	}

	private void ScanCart(PhysGrabCart cart, bool immediate)
	{
		//IL_006a: 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: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)cart) || !VoidCartShop.IsVoidCart(cart))
		{
			return;
		}
		Transform val = GameAccess.CartVolume(cart);
		if (!Object.op_Implicit((Object)(object)val) || !((Component)cart).gameObject.activeInHierarchy)
		{
			return;
		}
		HashSet<PhysGrabObject> seen = new HashSet<PhysGrabObject>();
		Collider[] array = Physics.OverlapBox(val.position, Vector3.Scale(val.lossyScale, Vector3.one * 0.5f), val.rotation, -1, (QueryTriggerInteraction)1);
		int num = 0;
		Collider[] array2 = array;
		foreach (Collider val2 in array2)
		{
			PhysGrabObject componentInParent = ((Component)val2).GetComponentInParent<PhysGrabObject>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || !seen.Add(componentInParent) || !Eligible(componentInParent))
			{
				continue;
			}
			Vector3 val3 = val.InverseTransformPoint(componentInParent.midPoint);
			if (Mathf.Abs(val3.x) > 0.52f || Mathf.Abs(val3.y) > 0.65f || Mathf.Abs(val3.z) > 0.52f)
			{
				candidates.Remove(componentInParent);
				continue;
			}
			if (!candidates.TryGetValue(componentInParent, out var value) || !candidateCarts.ContainsKey(componentInParent) || (Object)(object)candidateCarts[componentInParent] != (Object)(object)cart)
			{
				candidates[componentInParent] = Time.unscaledTime;
				candidateCarts[componentInParent] = cart;
				value = Time.unscaledTime;
			}
			if (immediate || !(Time.unscaledTime - value < settleTime.Value))
			{
				StoreHost(cart, componentInParent);
				candidates.Remove(componentInParent);
				if (++num >= 16)
				{
					break;
				}
			}
		}
		PhysGrabObject[] array3 = candidates.Keys.Where((PhysGrabObject o) => !Object.op_Implicit((Object)(object)o) || (candidateCarts.ContainsKey(o) && (Object)(object)candidateCarts[o] == (Object)(object)cart && !seen.Contains(o))).ToArray();
		foreach (PhysGrabObject key in array3)
		{
			candidates.Remove(key);
			candidateCarts.Remove(key);
		}
	}

	internal void StoreHost(PhysGrabCart cart, PhysGrabObject obj)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart) && IsHost && CanStore && Eligible(obj))
		{
			Vector3 position = ((Component)obj).transform.position;
			Quaternion rotation = ((Component)obj).transform.rotation;
			StoredItem storedItem = ApplyStore(cart, obj);
			if (storedItem != null && !network.BroadcastStore(cart, storedItem))
			{
				ApplyRelease(storedItem.Id, position, rotation);
				Status = "Network was busy; the item was returned to the cart.";
			}
		}
	}

	internal StoredItem ApplyStore(PhysGrabCart cart, PhysGrabObject obj)
	{
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)cart) || !VoidCartShop.IsVoidCart(cart) || !Object.op_Implicit((Object)(object)obj))
		{
			return null;
		}
		StoredItem storedItem = Stored(obj);
		if (storedItem != null)
		{
			if ((Object)(object)storedItem.Cart == (Object)(object)cart)
			{
				return storedItem;
			}
			ApplyRelease(storedItem.Id, storedItem.LastPosition, storedItem.OriginalRotation);
		}
		int num = ObjectId((Component)(object)obj);
		if (num == 0)
		{
			return null;
		}
		if (Items.TryGetValue(num, out var value))
		{
			if (Object.op_Implicit((Object)(object)value.Object))
			{
				LogWarning("Refusing an item ID already used by another object.");
				return null;
			}
			Items.Remove(num);
		}
		StoredItem storedItem2 = null;
		Vector3 position = ((Component)obj).transform.position;
		Quaternion rotation = ((Component)obj).transform.rotation;
		try
		{
			storedItem2 = new StoredItem(obj, cart, num);
			Items.Add(storedItem2.Id, storedItem2);
			RegisterCart(cart);
			return storedItem2;
		}
		catch (Exception ex)
		{
			storedItem2?.Restore(position, rotation);
			Items.Remove(num);
			((BaseUnityPlugin)this).Logger.LogError((object)("Item could not enter Void Cart: " + ex));
			Status = "This item could not be stored; see the BepInEx log.";
			return null;
		}
	}

	public void RequestStoreNearby(PhysGrabCart cart)
	{
		if (NearCart(cart, SemiFunc.PlayerAvatarLocal()))
		{
			if (!CanStore)
			{
				Status = "Storage needs all players on the same mod version and pauses in the shop.";
			}
			else if (IsHost)
			{
				ScanCart(cart, immediate: true);
			}
			else
			{
				network.Request("store", cart, 0);
			}
		}
	}

	public void RequestWithdraw(PhysGrabCart cart, int id)
	{
		if (NearCart(cart, SemiFunc.PlayerAvatarLocal()))
		{
			if (IsHost)
			{
				WithdrawHost(cart, id);
			}
			else
			{
				network.Request("withdraw", cart, id);
			}
		}
	}

	public void RequestReleaseAll(PhysGrabCart cart)
	{
		if (NearCart(cart, SemiFunc.PlayerAvatarLocal()))
		{
			if (IsHost)
			{
				QueueUnload(cart);
			}
			else
			{
				network.Request("unload", cart, 0);
			}
		}
	}

	internal void HandleRequest(string action, PhysGrabCart cart, int id)
	{
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart) && IsHost)
		{
			if (action == "store" && CanStore)
			{
				ScanCart(cart, immediate: true);
			}
			else if (action == "withdraw")
			{
				WithdrawHost(cart, id);
			}
			else if (action == "unload")
			{
				QueueUnload(cart);
			}
		}
	}

	private void QueueUnload(PhysGrabCart cart)
	{
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart))
		{
			if (!unloading.Add(cart))
			{
				unloading.Remove(cart);
				Status = "Unloading stopped.";
			}
			else
			{
				Status = "Unloading one item at a time. Move items away to make room; click Unload all again to stop.";
			}
		}
	}

	internal void WithdrawHost(PhysGrabCart cart, int id)
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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)
		if (Object.op_Implicit((Object)(object)cart) && VoidCartShop.IsVoidCart(cart) && IsHost && Items.TryGetValue(id, out var value) && !((Object)(object)value.Cart != (Object)(object)cart) && Object.op_Implicit((Object)(object)value.Object))
		{
			if (!FindReleasePosition(value, out var position))
			{
				Status = "No clear space beside the cart. Move the cart to an open area.";
				return;
			}
			if (!network.BroadcastRelease(id, position, value.OriginalRotation))
			{
				Status = "Network busy; try withdrawing again.";
				return;
			}
			ApplyRelease(id, position, value.OriginalRotation);
			Status = "Withdrew " + value.DisplayName + ".";
		}
	}

	internal void ApplyRelease(int id, Vector3 position, Quaternion rotation)
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: 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)
		if (Items.TryGetValue(id, out var value))
		{
			Items.Remove(id);
			if (Object.op_Implicit((Object)(object)value.Object))
			{
				cooldowns[value.Object] = Time.unscaledTime + 10f;
			}
			value.Restore(position, rotation);
			if (IsHost && Object.op_Implicit((Object)(object)value.Object))
			{
				value.Object.Teleport(position, rotation);
			}
		}
	}

	private static bool FindReleasePosition(StoredItem entry, out Vector3 position)
	{
		//IL_001a: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_0097: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		position = entry.LastPosition;
		Vector3 val = GameAccess.CartCenter(entry.Cart);
		Vector3 halfSize = entry.HalfSize;
		float num = Mathf.Max(halfSize.x, halfSize.z) + 1.05f;
		Vector3 val2 = default(Vector3);
		RaycastHit val4 = default(RaycastHit);
		Vector3 val5 = default(Vector3);
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 12; j++)
			{
				float num2 = (float)j * 30f * ((float)Math.PI / 180f);
				((Vector3)(ref val2))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2));
				Vector3 val3 = val + val2 * (num + (float)i * 0.65f);
				RaycastHit[] source = Physics.RaycastAll(val, val2, num + (float)i * 0.65f, -1, (QueryTriggerInteraction)1);
				if (!source.Any((RaycastHit h) => (Object)(object)((Component)((RaycastHit)(ref h)).collider).GetComponentInParent<PhysGrabCart>() != (Object)(object)entry.Cart) && Physics.Raycast(val3 + Vector3.up * 1.5f, Vector3.down, ref val4, 4f, -1, (QueryTriggerInteraction)1) && !(((RaycastHit)(ref val4)).normal.y < 0.6f) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<PhysGrabObject>()))
				{
					((Vector3)(ref val5))..ctor(val3.x, ((RaycastHit)(ref val4)).point.y + halfSize.y + 0.12f, val3.z);
					if (!Physics.CheckBox(val5, halfSize + Vector3.one * 0.035f, Quaternion.identity, -1, (QueryTriggerInteraction)1))
					{
						position = val5 - entry.BoundsOffset;
						return true;
					}
				}
			}
		}
		return false;
	}

	internal int IncludeStoredValue(PhysGrabCart cart, int physicalValue)
	{
		if (!Object.op_Implicit((Object)(object)cart) || !VoidCartShop.IsVoidCart(cart))
		{
			return physicalValue;
		}
		List<PhysGrabObject> list = GameAccess.PhysicalCartItems(cart);
		double num = physicalValue;
		foreach (StoredItem value in Items.Values)
		{
			if (!((Object)(object)value.Cart != (Object)(object)cart) && Object.op_Implicit((Object)(object)value.Object) && (list == null || !list.Contains(value.Object) || !Object.op_Implicit((Object)(object)((Component)value.Object).GetComponent<ValuableObject>())))
			{
				num += Math.Truncate(value.Value);
			}
		}
		int num2 = (int)Math.Min(2147483647.0, Math.Max(0.0, num));
		GameAccess.SetCartHaul(cart, num2);
		return num2;
	}

	internal void BeforeSceneChange()
	{
		sceneChanging = true;
		CloseInventory();
		RestoreAll(transition: true);
		if (network != null)
		{
			network.ClearPending();
		}
	}

	internal void RestoreAll(bool transition = false)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		StoredItem[] array = Items.Values.ToArray();
		foreach (StoredItem storedItem in array)
		{
			storedItem.Restore(storedItem.LastPosition, storedItem.OriginalRotation);
			if (!transition || !Object.op_Implicit((Object)(object)storedItem.Object))
			{
				continue;
			}
			Rigidbody[] componentsInChildren = ((Component)storedItem.Object).GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val in componentsInChildren)
			{
				Rigidbody b = val;
				bool kinematic = b.isKinematic;
				bool collisions = b.detectCollisions;
				afterTransition.Add(delegate
				{
					if (Object.op_Implicit((Object)(object)b))
					{
						b.isKinematic = kinematic;
						b.detectCollisions = collisions;
					}
				});
				b.isKinematic = true;
				b.detectCollisions = false;
			}
		}
		Items.Clear();
		candidates.Clear();
		candidateCarts.Clear();
		cooldowns.Clear();
		unloading.Clear();
	}

	private void OnDestroy()
	{
		CloseInventory();
		RestoreAll();
		SceneManager.sceneLoaded -= SceneLoaded;
		if (network != null)
		{
			network.Dispose();
		}
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		foreach (PhysGrabCart cart in carts)
		{
			if (Object.op_Implicit((Object)(object)cart))
			{
				VoidCartVisual component = ((Component)cart).GetComponent<VoidCartVisual>();
				if (Object.op_Implicit((Object)(object)component))
				{
					Object.Destroy((Object)(object)component);
				}
			}
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
internal static class VoidCartShop
{
	internal const string ItemId = "Item Void Cart";

	internal const string PrefabPath = "Items/CaspiVoidCart";

	private static GameObject holder;

	private static ConfigEntry<int> basePrice;

	private static bool reportedFailure;

	internal static Item Definition { get; private set; }

	internal static GameObject Prefab { get; private set; }

	internal static void Configure(ConfigFile config)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		basePrice = config.Bind<int>("Shop", "BasePrice", 50500, new ConfigDescription("Base price in dollars. The game's checkout rounds up to $1,000 steps and applies its normal shop multiplier. Restart the game after changing this.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 1000000), new object[0]));
	}

	internal static bool IsVoidCart(PhysGrabCart cart)
	{
		if (!Object.op_Implicit((Object)(object)cart) || !Object.op_Implicit((Object)(object)Definition))
		{
			return false;
		}
		ItemAttributes component = ((Component)cart).GetComponent<ItemAttributes>();
		if (Object.op_Implicit((Object)(object)component))
		{
			return (Object)(object)component.item == (Object)(object)Definition;
		}
		return false;
	}

	internal static void EnsureRegistered(StatsManager stats)
	{
		if (!Object.op_Implicit((Object)(object)stats))
		{
			return;
		}
		try
		{
			if (!Object.op_Implicit((Object)(object)Definition) || !Object.op_Implicit((Object)(object)Prefab))
			{
				BuildPrefab();
			}
			if (stats.itemDictionary.TryGetValue("Item Void Cart", out var value) && (Object)(object)value != (Object)(object)Definition)
			{
				throw new InvalidOperationException("Another item already uses Item Void Cart.");
			}
			stats.itemDictionary["Item Void Cart"] = Definition;
			RegisterPools();
		}
		catch (Exception ex)
		{
			if (!reportedFailure)
			{
				reportedFailure = true;
				VoidCartPlugin.LogWarning("Void Cart shop registration failed: " + ex);
			}
		}
	}

	private static void BuildPrefab()
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Expected O, but got Unknown
		GameObject val = Resources.Load<GameObject>("items/item cart medium");
		ItemAttributes val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemAttributes>() : null);
		if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.item) || !Object.op_Implicit((Object)(object)val2.item.value))
		{
			throw new InvalidOperationException("The installed medium cart item was not found.");
		}
		holder = new GameObject("Void Cart prefab holder");
		holder.SetActive(false);
		((Object)holder).hideFlags = (HideFlags)61;
		Object.DontDestroyOnLoad((Object)(object)holder);
		Prefab = Object.Instantiate<GameObject>(val, holder.transform, false);
		((Object)Prefab).name = "Item Void Cart";
		((Object)Prefab).hideFlags = (HideFlags)0;
		Prefab.transform.localPosition = Vector3.zero;
		Prefab.transform.localRotation = Quaternion.identity;
		Definition = Object.Instantiate<Item>(val2.item);
		((Object)Definition).name = "Item Void Cart";
		((Object)Definition).hideFlags = (HideFlags)61;
		Definition.itemName = "Void Cart";
		Definition.itemNameLocalized = null;
		Definition.description = "A cart with a bottomless void. Press F8 nearby to browse stored loot and cosmetic capsules.";
		Definition.disabled = false;
		Definition.minPlayerCount = 1;
		Definition.maxAmount = 1;
		Definition.maxAmountInShop = 1;
		Definition.maxPurchase = false;
		Definition.value = Object.Instantiate<Value>(val2.item.value);
		((Object)Definition.value).name = "Void Cart Price";
		((Object)Definition.value).hideFlags = (HideFlags)61;
		Definition.value.valueMin = ((basePrice == null) ? 50500 : basePrice.Value);
		Definition.value.valueMax = Definition.value.valueMin;
		Definition.prefab = new PrefabRef();
		((PrefabRef<GameObject>)(object)Definition.prefab).SetPrefab(Prefab, "Items/CaspiVoidCart");
		Prefab.GetComponent<ItemAttributes>().item = Definition;
		Prefab.SetActive(true);
	}

	internal static void RegisterPools()
	{
		if (Object.op_Implicit((Object)(object)Prefab) && Object.op_Implicit((Object)(object)RunManager.instance))
		{
			Dictionary<string, Object> dictionary = AccessTools.Field(typeof(RunManager), "singleplayerPool").GetValue(RunManager.instance) as Dictionary<string, Object>;
			object? value = AccessTools.Field(typeof(RunManager), "multiplayerPool").GetValue(RunManager.instance);
			MultiplayerPool val = (MultiplayerPool)((value is MultiplayerPool) ? value : null);
			if (dictionary != null)
			{
				dictionary["Items/CaspiVoidCart"] = (Object)(object)Prefab;
			}
			if (val != null)
			{
				val.ResourceCache["Items/CaspiVoidCart"] = Prefab;
			}
		}
	}

	internal static void ConstrainCartStock(ShopManager shop)
	{
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Definition) || !Object.op_Implicit((Object)(object)StatsManager.instance) || SemiFunc.IsNotMasterClient())
		{
			return;
		}
		StatsManager stats = StatsManager.instance;
		List<List<Item>> list = new List<List<Item>>();
		list.Add(shop.potentialItems);
		list.Add(shop.potentialItemConsumables);
		list.Add(shop.potentialItemUpgrades);
		list.Add(shop.potentialItemHealthPacks);
		List<List<Item>> list2 = list;
		list2.AddRange(shop.potentialSecretItems.Values);
		bool flag = list2.Any((List<Item> list3) => list3.Contains(Definition));
		if (!flag && stats.GetItemPurchased(Definition) == 0)
		{
			return;
		}
		int num = stats.itemDictionary.Values.Where((Item item) => Object.op_Implicit((Object)(object)item) && item.physicalItem && item.itemVolume == Definition.itemVolume).Sum((Item item) => Math.Max(0, stats.GetItemPurchased(item)));
		int num2 = Math.Max(0, 4 - num);
		bool flag2 = flag && num2 > 0;
		if (flag2)
		{
			num2--;
		}
		foreach (List<Item> item in list2)
		{
			for (int num3 = item.Count - 1; num3 >= 0; num3--)
			{
				Item val = item[num3];
				if (Object.op_Implicit((Object)(object)val) && val.physicalItem && val.itemVolume == Definition.itemVolume)
				{
					if ((Object)(object)val == (Object)(object)Definition)
					{
						if (flag2)
						{
							flag2 = false;
						}
						else
						{
							item.RemoveAt(num3);
						}
					}
					else if (num2 > 0)
					{
						num2--;
					}
					else
					{
						item.RemoveAt(num3);
					}
				}
			}
		}
	}
}
[HarmonyPatch(typeof(StatsManager), "LoadItemsFromFolder")]
internal static class VoidCartItemRegistryPatch
{
	private static void Postfix(StatsManager __instance)
	{
		VoidCartShop.EnsureRegistered(__instance);
	}
}
[HarmonyPatch(typeof(LevelGenerator), "Start")]
internal static class VoidCartScenePoolPatch
{
	private static void Postfix()
	{
		VoidCartShop.RegisterPools();
	}
}
[HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")]
internal static class VoidCartShopCapacityPatch
{
	private static void Postfix(ShopManager __instance)
	{
		VoidCartShop.ConstrainCartStock(__instance);
	}
}
[HarmonyPatch(typeof(PrefabRef<GameObject>), "get_Prefab")]
internal static class VoidCartPrefabReferencePatch
{
	private static bool Prefix(PrefabRef<GameObject> __instance, ref GameObject __result)
	{
		if (__instance.ResourcePath != "Items/CaspiVoidCart" || !Object.op_Implicit((Object)(object)VoidCartShop.Prefab))
		{
			return true;
		}
		__result = VoidCartShop.Prefab;
		return false;
	}
}
[HarmonyPatch(typeof(MultiplayerPool), "Instantiate")]
internal static class VoidCartNetworkPrefabPatch
{
	private static void Prefix(MultiplayerPool __instance, string __0)
	{
		if (__0 == "Items/CaspiVoidCart" && Object.op_Implicit((Object)(object)VoidCartShop.Prefab))
		{
			__instance.ResourceCache[__0] = VoidCartShop.Prefab;
		}
	}
}
public sealed class VoidCartUI : MonoBehaviour
{
	private const float RowHeight = 58f;

	private readonly List<StoredItem> filtered = new List<StoredItem>();

	private readonly List<Texture2D> textures = new List<Texture2D>();

	private GUIStyle panelStyle;

	private GUIStyle titleStyle;

	private GUIStyle subtitleStyle;

	private GUIStyle bodyStyle;

	private GUIStyle dimStyle;

	private GUIStyle itemNameStyle;

	private GUIStyle buttonStyle;

	private GUIStyle tabStyle;

	private GUIStyle activeTabStyle;

	private GUIStyle searchStyle;

	private GUIStyle rowStyle;

	private GUIStyle altRowStyle;

	private GUIStyle statusStyle;

	private Vector2 scroll;

	private string search = string.Empty;

	private StoredItemCategory selectedTab;

	private PhysGrabCart cachedCart;

	private float nextRefresh;

	private int inventoryCount;

	private int weaponCount;

	private int cosmeticCount;

	private float totalValue;

	private bool wasOpen;

	private void OnGUI()
	{
		//IL_01e8: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: 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)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: 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_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: 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_01ba: 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)
		VoidCartPlugin instance = VoidCartPlugin.Instance;
		if ((Object)(object)instance == (Object)null || !instance.MenuOpen)
		{
			wasOpen = false;
			if ((Object)(object)instance != (Object)null && !string.IsNullOrEmpty(instance.InventoryHint))
			{
				DrawInventoryHint(instance.InventoryHint);
			}
			return;
		}
		EnsureStyles();
		if (!wasOpen)
		{
			GUI.FocusControl((string)null);
			GUIUtility.keyboardControl = 0;
			nextRefresh = 0f;
			wasOpen = true;
		}
		if ((Object)(object)cachedCart != (Object)(object)instance.SelectedCart)
		{
			cachedCart = instance.SelectedCart;
			scroll = Vector2.zero;
			nextRefresh = 0f;
		}
		if (Time.unscaledTime >= nextRefresh)
		{
			RefreshEntries(instance);
		}
		Matrix4x4 matrix = GUI.matrix;
		Color color = GUI.color;
		Color backgroundColor = GUI.backgroundColor;
		Color contentColor = GUI.contentColor;
		bool enabled = GUI.enabled;
		int depth = GUI.depth;
		try
		{
			GUI.depth = -1000;
			GUI.color = Color.white;
			GUI.backgroundColor = Color.white;
			GUI.contentColor = Color.white;
			GUI.enabled = true;
			float num = Mathf.Clamp(Mathf.Min((float)Screen.width / 1020f, (float)Screen.height / 760f), 0.4f, 1.25f);
			GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
			float num2 = (float)Screen.width / num;
			float num3 = (float)Screen.height / num;
			float num4 = Mathf.Min(960f, num2 - 28f);
			float num5 = Mathf.Min(710f, num3 - 28f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((num2 - num4) * 0.5f, (num3 - num5) * 0.5f, num4, num5);
			GUI.Box(val, GUIContent.none, panelStyle);
			GUI.BeginGroup(val);
			try
			{
				DrawPanel(instance, num4, num5);
			}
			finally
			{
				GUI.EndGroup();
			}
		}
		finally
		{
			GUI.matrix = matrix;
			GUI.color = color;
			GUI.backgroundColor = backgroundColor;
			GUI.contentColor = contentColor;
			GUI.enabled = enabled;
			GUI.depth = depth;
		}
	}

	private void DrawInventoryHint(string text)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		EnsureStyles();
		Matrix4x4 matrix = GUI.matrix;
		Color color = GUI.color;
		Color contentColor = GUI.contentColor;
		Color backgroundColor = GUI.backgroundColor;
		int depth = GUI.depth;
		try
		{
			GUI.matrix = Matrix4x4.identity;
			GUI.color = (GUI.contentColor = (GUI.backgroundColor = Color.white));
			GUI.depth = -1000;
			float num = Mathf.Min(720f, (float)Screen.width - 32f);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((float)Screen.width - num) * 0.5f, (float)Screen.height * 0.78f, num, 64f);
			GUI.Box(val2, GUIContent.none, panelStyle);
			GUI.Label(new Rect(((Rect)(ref val2)).x + 16f, ((Rect)(ref val2)).y + 10f, num - 32f, 46f), text, statusStyle);
		}
		finally
		{
			GUI.matrix = matrix;
			GUI.color = color;
			GUI.contentColor = contentColor;
			GUI.backgroundColor = backgroundColor;
			GUI.depth = depth;
		}
	}

	private void DrawPanel(VoidCartPlugin plugin, float width, float height)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0320: Unknown result type (might be due to invalid IL or missing references)
		//IL_0352: Unknown result type (migh