Decompiled source of Bulk Cart v0.1.1

plugins/CrackBulkCart.dll

Decompiled 12 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using CrackMods.Shared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Mirror.RemoteCalls;
using Newtonsoft.Json;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CrackBulkCart")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CrackBulkCart")]
[assembly: AssemblyTitle("CrackBulkCart")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CrackMods.Shared
{
	internal static class ModHandshake
	{
		[HarmonyPatch(typeof(SteamLobby), "OnLobbyCreated")]
		private static class PublishPatch
		{
			private static void Postfix(SteamLobby __instance)
			{
				Publish(__instance);
			}
		}

		[HarmonyPatch(typeof(SteamLobby), "RefreshModdedLobbyData")]
		private static class RefreshPatch
		{
			private static void Postfix(SteamLobby __instance)
			{
				Publish(__instance);
			}
		}

		[HarmonyPatch(typeof(SteamLobby), "HostIsInLobby")]
		private static class JoinCheckPatch
		{
			private static bool Prefix(CSteamID lobby, ref bool __result)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (!IsLeader(_ownGuid))
				{
					return true;
				}
				string lobbyData = SteamMatchmaking.GetLobbyData(lobby, "cmods");
				string text = LocalToken();
				if (lobbyData == text)
				{
					return true;
				}
				_pendingReason = Describe(lobbyData, text);
				Debug.LogWarning((object)("[CrackMods] refusing to join: " + _pendingReason));
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(SteamLobby), "FailConnect")]
		private static class FailMessagePatch
		{
			private static void Prefix(ref string messageKey)
			{
				if (_pendingReason != null && !(messageKey != "Error_JoinFailed"))
				{
					messageKey = _pendingReason;
					_pendingReason = null;
				}
			}
		}

		internal const string GuidPrefix = "com.altma.crack.";

		private const string LobbyKey = "cmods";

		private static string _ownGuid;

		private static string _pendingReason;

		internal static string LocalToken()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, PluginInfo> item in Chainloader.PluginInfos.OrderBy((KeyValuePair<string, PluginInfo> k) => k.Key))
			{
				if (item.Key.StartsWith("com.altma.crack."))
				{
					string text = item.Key.Substring("com.altma.crack.".Length) + "=" + item.Value.Metadata.Version;
					object instance = item.Value.Instance;
					PropertyInfo propertyInfo = ((instance != null) ? AccessTools.Property(instance.GetType(), "HandshakeExtra") : null);
					if (propertyInfo != null && propertyInfo.GetGetMethod() != null && propertyInfo.GetGetMethod().IsStatic)
					{
						text = text + "+" + propertyInfo.GetValue(null, null);
					}
					list.Add(text);
				}
			}
			return string.Join(";", list.ToArray());
		}

		private static bool IsLeader(string ownGuid)
		{
			string text = (from k in Chainloader.PluginInfos.Keys
				where k.StartsWith("com.altma.crack.")
				orderby k
				select k).FirstOrDefault();
			if (text != null)
			{
				return text == ownGuid;
			}
			return true;
		}

		internal static void Install(string ownGuid)
		{
			_ownGuid = ownGuid;
		}

		private static void Publish(SteamLobby lobby)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (IsLeader(_ownGuid) && !((Object)(object)lobby == (Object)null) && ((CSteamID)(ref lobby.currentLobbyID)).IsValid())
			{
				string text = LocalToken();
				SteamMatchmaking.SetLobbyData(lobby.currentLobbyID, "cmods", text);
				Debug.Log((object)("[CrackMods] lobby mods: " + text));
			}
		}

		internal static string Describe(string host, string local)
		{
			Dictionary<string, string> dictionary = Parse(host);
			Dictionary<string, string> dictionary2 = Parse(local);
			List<string> list = new List<string>();
			foreach (string item in from k in dictionary.Keys.Union(dictionary2.Keys)
				orderby k
				select k)
			{
				dictionary.TryGetValue(item, out var value);
				dictionary2.TryGetValue(item, out var value2);
				if (!(value == value2))
				{
					list.Add(item + ": host " + (value ?? "doesn't have it") + ", you " + (value2 ?? "don't have it"));
				}
			}
			return "CrackMods don't match the host. " + string.Join(". ", list.ToArray());
			static Dictionary<string, string> Parse(string s)
			{
				return (from p in (s ?? "").Split(new char[1] { ';' })
					where p.Contains("=")
					select p).ToDictionary((string p) => p.Substring(0, p.IndexOf('=')), (string p) => p.Substring(p.IndexOf('=') + 1));
			}
		}
	}
}
namespace CrackBulkCart
{
	internal static class Bricks
	{
		internal const uint AssetId = 2353691394u;

		internal const int Units = 70;

		private static GameObject _template;

		internal static bool Ready => (Object)(object)_template != (Object)null;

		internal static void Ensure(Transform holder)
		{
			if (!((Object)(object)_template != (Object)null) && !((Object)(object)holder == (Object)null))
			{
				GameObject val = ((IEnumerable<GameObject>)NetworkClient.prefabs.Values).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => (Object)(object)p != (Object)null && ((Object)p).name.EndsWith("Bucket_Tier4")));
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"No Mk IV bucket prefab; carts can't unload");
					return;
				}
				_template = Object.Instantiate<GameObject>(val, holder);
				((Object)_template).name = "BulkCart Brick";
				Traverse.Create((object)_template.GetComponent<NetworkIdentity>()).Field("_assetId").SetValue((object)0u);
				Traverse.Create((object)_template.GetComponent<HeldItem>()).Field("_saveExempt").SetValue((object)true);
				_template.AddComponent<BrickLook>();
				NetworkClient.RegisterPrefab(_template, 2353691394u);
			}
		}

		internal static Bucket Spawn(ResourceType type, int units, Vector3 position, Quaternion rotation)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || (Object)(object)_template == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(_template, position, rotation);
			((Object)obj).name = "BulkCart Brick";
			Rigidbody component = obj.GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.isKinematic = true;
			}
			NetworkServer.Spawn(obj, (NetworkConnectionToClient)null);
			Bucket component2 = obj.GetComponent<Bucket>();
			component2.ServerSetContents(type, true, Mathf.Clamp(units, 1, 70));
			((HeldItem)component2).NetworkPickupLocked = true;
			return component2;
		}
	}
	internal sealed class BrickLook : MonoBehaviour
	{
		private static readonly Vector3 Size = new Vector3(0.42f, 0.28f, 0.42f);

		private Bucket _bucket;

		private Renderer[] _bucketRenderers;

		private MeshRenderer _brick;

		private bool _wasFull;

		private void Awake()
		{
			//IL_005f: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			_bucket = ((Component)this).GetComponent<Bucket>();
			_bucketRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			((Object)val).name = "Brick";
			val.layer = ((Component)this).gameObject.layer;
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.up * (Size.y / 2f);
			val.transform.localScale = Size;
			_brick = val.GetComponent<MeshRenderer>();
		}

		private void LateUpdate()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] bucketRenderers = _bucketRenderers;
			foreach (Renderer val in bucketRenderers)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = false;
				}
			}
			bool flag = (Object)(object)_bucket != (Object)null && _bucket.HasType && _bucket.CurrentUnits > 0;
			((Renderer)_brick).enabled = flag;
			if (flag)
			{
				((Renderer)_brick).sharedMaterial = CartFill.MaterialFor(_bucket.LockedType) ?? ((Renderer)_brick).sharedMaterial;
			}
			if (flag)
			{
				_wasFull = true;
			}
			if (NetworkServer.active && _wasFull && !flag && !DepositMachine.InAnyPipeline(((NetworkBehaviour)_bucket).netId))
			{
				NetworkServer.Destroy(((Component)this).gameObject);
			}
		}
	}
	public class BulkCart : InteractionStation
	{
		internal const int Capacity = 140;

		private const float PaceShare = 0.9f;

		private const float BackShare = 0.6f;

		private const float TurnSpeed = 70f;

		internal static readonly List<BulkCart> All;

		private int _units;

		private int _type;

		private bool _hasType;

		private Vector2 _serverMove;

		private bool _serverSprint;

		private bool _unloading;

		private Vector3 _lastPos;

		private float _speed;

		private Transform _root;

		private Transform _gripL;

		private Transform _gripR;

		private Transform _tub;

		private Transform _fill;

		private Rigidbody _body;

		private readonly CartSounds _sounds = new CartSounds();

		private readonly CartWheels _wheels = new CartWheels();

		private Vector2 _lastSent;

		private bool _lastSprint;

		private static float _walk;

		private static float _sprint;

		private static readonly FieldRef<DepositMachine, bool> Accepting;

		private const float SeizeTimeout = 5f;

		private const float GlideTime = 0.35f;

		private const string CmdPushName = "System.Void BulkCart::CmdPush(UnityEngine.Vector2,System.Boolean,Mirror.NetworkConnectionToClient)";

		private const string CmdPourName = "System.Void BulkCart::CmdPour(System.UInt32,Mirror.NetworkConnectionToClient)";

		private const string CmdUnloadName = "System.Void BulkCart::CmdUnload(Mirror.NetworkConnectionToClient)";

		private const string RpcPouredName = "System.Void BulkCart::RpcPoured(System.Int32)";

		private const string RpcSoldName = "System.Void BulkCart::RpcSold(System.Int32,UnityEngine.Vector3)";

		internal int Units => _units;

		internal bool HasType => _hasType;

		internal ResourceType Type => (ResourceType)_type;

		internal Transform Root => _root;

		internal bool Unloading => _unloading;

		internal float Speed => _speed;

		internal bool Running => Mathf.Abs(_speed) > PlayerPace(sprint: false) * 0.9f * 1.1f;

		protected override void Awake()
		{
			((InteractionStation)this).Awake();
			_root = ((Component)this).transform.parent;
			_body = ((Component)_root).GetComponent<Rigidbody>();
			_gripL = _root.Find("GripL");
			_gripR = _root.Find("GripR");
			AttachVisual();
			All.Add(this);
		}

		private void OnDestroy()
		{
			All.Remove(this);
			_sounds.Stop();
		}

		internal void AttachVisual()
		{
			Transform val = _root.Find("Visual");
			_tub = (((Object)(object)val != (Object)null) ? val.Find("Tub") : null);
			if ((Object)(object)_tub != (Object)null && (Object)(object)((Component)_tub).GetComponent<BulkCartTub>() == (Object)null)
			{
				((Component)_tub).gameObject.AddComponent<BulkCartTub>().Cart = this;
			}
			_fill = (((Object)(object)_tub != (Object)null) ? CartFill.Build(_tub, _root) : null);
			_wheels.Bind(_root, val);
			RefreshFill();
			Traverse.Create((object)(((Component)this).GetComponent<HoverOutlineTarget>() ?? ((Component)this).gameObject.AddComponent<HoverOutlineTarget>())).Field("renderers").SetValue((object)(((Object)(object)val == (Object)null) ? ((Array)new Renderer[0]) : ((Array)(from r in ((Component)val).GetComponentsInChildren<Renderer>(true)
				where ((Object)r).name.StartsWith("Grip") || ((Object)r).name.StartsWith("Leg")
				select r).ToArray())));
		}

		public override bool GetLeftHandTarget(out Vector3 position, out Quaternion rotation)
		{
			return Grip(_gripL, out position, out rotation);
		}

		public override bool GetRightHandTarget(out Vector3 position, out Quaternion rotation)
		{
			return Grip(_gripR, out position, out rotation);
		}

		private static bool Grip(Transform t, out Vector3 position, out Quaternion rotation)
		{
			//IL_0016: 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_0012: 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_0036: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			position = (Vector3)(((Object)(object)t != (Object)null) ? t.position : default(Vector3));
			rotation = (Quaternion)(((Object)(object)t != (Object)null) ? t.rotation : default(Quaternion));
			return (Object)(object)t != (Object)null;
		}

		public override void UpdateStation(Player player, StationInput input, float deltaTime)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0010: 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_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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003f: 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)
			Vector2 val = Vector2.ClampMagnitude(input.move, 1f);
			bool flag = SprintHeld(player);
			Vector2 val2 = val - _lastSent;
			if (((Vector2)(ref val2)).sqrMagnitude > 0.0025f || val == Vector2.zero != (_lastSent == Vector2.zero) || flag != _lastSprint)
			{
				_lastSent = val;
				_lastSprint = flag;
				CmdPush(val, flag);
			}
		}

		private static bool SprintHeld(Player player)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			GameplayActions value = Traverse.Create((object)player).Field("gameplayInput").GetValue<GameplayActions>();
			if (((GameplayActions)(ref value)).Sprint != null)
			{
				return ((GameplayActions)(ref value)).Sprint.IsPressed();
			}
			return false;
		}

		private static float PlayerPace(bool sprint)
		{
			if (_walk <= 0f)
			{
				PlayerCharacter val = Object.FindAnyObjectByType<PlayerCharacter>();
				_walk = (((Object)(object)val != (Object)null) ? Traverse.Create((object)val).Field("walkSpeed").GetValue<float>() : 0f);
				_sprint = (((Object)(object)val != (Object)null) ? Traverse.Create((object)val).Field("sprintSpeed").GetValue<float>() : 0f);
				if (_walk <= 0f)
				{
					_walk = 3f;
					_sprint = 5f;
				}
			}
			if (!sprint)
			{
				return _walk;
			}
			return Mathf.Max(_sprint, _walk);
		}

		protected override void Update()
		{
			//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_0032: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			((InteractionStation)this).Update();
			if (!((Object)(object)_root == (Object)null) && !(Time.deltaTime <= 0f))
			{
				float num = Vector3.Dot(_root.position - _lastPos, _root.forward) / Time.deltaTime;
				_lastPos = _root.position;
				_speed = Mathf.Lerp(_speed, (Mathf.Abs(num) < 0.05f) ? 0f : num, Mathf.Clamp01(Time.deltaTime * 12f));
				_wheels.Update();
				_sounds.Update(_root, Mathf.Clamp01(Mathf.Abs(_speed) / (PlayerPace(sprint: true) * 0.9f)));
			}
		}

		protected override void OnServerOccupantReleased()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_serverMove = Vector2.zero;
		}

		private void FixedUpdate()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0092: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_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_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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || (Object)(object)_body == (Object)null)
			{
				return;
			}
			if (((InteractionStation)this).OccupantNetId == 0 || _unloading)
			{
				_serverMove = Vector2.zero;
			}
			if (!(_serverMove == Vector2.zero))
			{
				float fixedDeltaTime = Time.fixedDeltaTime;
				float num = PlayerPace(_serverSprint && _serverMove.y > 0f) * ((_serverMove.y >= 0f) ? 0.9f : 0.6f);
				Quaternion val = _root.rotation * Quaternion.Euler(0f, _serverMove.x * 70f * fixedDeltaTime * ((_serverMove.y < -0.1f) ? (-1f) : 1f), 0f);
				Vector3 val2 = val * Vector3.forward * (_serverMove.y * num * fixedDeltaTime);
				if (Blocked(val2))
				{
					val2 = Vector3.zero;
				}
				Vector3 val3 = _root.position + val2;
				float? num2 = Floor(val3);
				if (num2.HasValue)
				{
					val3.y = num2.Value;
				}
				_body.MovePosition(val3);
				_body.MoveRotation(val);
			}
		}

		private float? Floor(Vector3 pos)
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			float? result = null;
			RaycastHit[] array = Physics.RaycastAll(pos + Vector3.up * 0.3f, Vector3.down, 0.8f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val = array[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody == (Object)(object)_body))
				{
					Rigidbody attachedRigidbody = ((RaycastHit)(ref val)).collider.attachedRigidbody;
					if ((!((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic) && (!result.HasValue || ((RaycastHit)(ref val)).point.y > result.Value))
					{
						result = ((RaycastHit)(ref val)).point.y;
					}
				}
			}
			return result;
		}

		private bool Blocked(Vector3 step)
		{
			//IL_0018: 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_0033: 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)
			float magnitude = ((Vector3)(ref step)).magnitude;
			if (magnitude < 1E-05f)
			{
				return false;
			}
			RaycastHit[] array = _body.SweepTestAll(step / magnitude, magnitude + 0.03f, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val = array[i];
				Rigidbody attachedRigidbody = ((RaycastHit)(ref val)).collider.attachedRigidbody;
				if ((!((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Player>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerCharacter>() != (Object)null))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool CanPour(BulkCart cart, Bucket bucket)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between I4 and Unknown
			if ((Object)(object)bucket == (Object)null || bucket.CurrentUnits <= 0 || !bucket.HasType || cart._units >= 140)
			{
				return false;
			}
			if (cart._hasType && cart._units != 0)
			{
				return cart._type == (int)bucket.LockedType;
			}
			return true;
		}

		private void ServerPour(Bucket bucket, NetworkConnectionToClient sender)
		{
			//IL_0055: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected I4, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected I4, but got Unknown
			if ((Object)(object)bucket == (Object)null || (Object)(object)((HeldItem)bucket).Holder == (Object)null || (Object)(object)((HeldItem)bucket).Holder.Player == (Object)null)
			{
				return;
			}
			NetworkIdentity component = ((Component)((HeldItem)bucket).Holder.Player).GetComponent<NetworkIdentity>();
			if ((Object)(object)component == (Object)null || component.connectionToClient != sender)
			{
				return;
			}
			if (Vector3.Distance(((Component)bucket).transform.position, _root.position) > 4f || _unloading || !CanPour(this, bucket))
			{
				Plugin.Log.LogInfo((object)$"Pour refused: {bucket.CurrentUnits} x {bucket.LockedType} into {_units} x {(object)(ResourceType)_type}");
				return;
			}
			int num = Mathf.Min(bucket.CurrentUnits, 140 - _units);
			ResourceType lockedType = bucket.LockedType;
			if (num >= bucket.CurrentUnits)
			{
				bucket.OnMachineProcess();
			}
			else
			{
				bucket.ServerSetContents(lockedType, true, bucket.CurrentUnits - num);
			}
			SetContents((int)lockedType, hasType: true, _units + num);
			RpcPoured((int)lockedType);
		}

		internal void SetContents(int type, bool hasType, int units)
		{
			((NetworkBehaviour)this).GeneratedSyncVarSetter<int>(type, ref _type, 2uL, (Action<int, int>)null);
			((NetworkBehaviour)this).GeneratedSyncVarSetter<bool>(hasType, ref _hasType, 4uL, (Action<bool, bool>)null);
			((NetworkBehaviour)this).GeneratedSyncVarSetter<int>(Mathf.Clamp(units, 0, 140), ref _units, 8uL, (Action<int, int>)null);
			RefreshFill();
		}

		private void RefreshFill()
		{
			CartFill.Show(_fill, (_hasType && _units > 0) ? new ResourceType?((ResourceType)_type) : ((ResourceType?)null), (float)_units / 140f);
		}

		internal DepositMachine MachineAhead(out BadgeReader reader)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0061: 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)
			reader = null;
			Vector3 val = _root.position + _root.forward * 0.9f;
			DepositMachine[] array = Object.FindObjectsByType<DepositMachine>((FindObjectsSortMode)0);
			foreach (DepositMachine val2 in array)
			{
				Transform value = Traverse.Create((object)val2).Field("enterStart").GetValue<Transform>();
				if (!((Object)(object)value == (Object)null))
				{
					Vector3 val3 = value.position - val;
					val3.y = 0f;
					if (!(((Vector3)(ref val3)).magnitude > 2.2f))
					{
						reader = Traverse.Create((object)val2).Field("badgeReader").GetValue<BadgeReader>();
						return val2;
					}
				}
			}
			return null;
		}

		private IEnumerator ServerUnload(DepositMachine machine, BadgeReader reader)
		{
			_unloading = true;
			if (!Bricks.Ready)
			{
				Bricks.Ensure(CartPrefab.Holder);
			}
			Transform value = Traverse.Create((object)machine).Field("enterStart").GetValue<Transform>();
			Vector3 intake = ((value != null) ? value.position : ((Component)machine).transform.position);
			Transform drop = (from p in DepositDropPoint.All.Where((DepositDropPoint p) => (Object)(object)p != (Object)null).OrderBy(delegate(DepositDropPoint p)
				{
					//IL_0006: 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_0016: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val3 = ((Component)p).transform.position - intake;
					return ((Vector3)(ref val3)).sqrMagnitude;
				})
				select ((Component)p).transform).FirstOrDefault();
			int bricks = 0;
			while (_units > 0 && (Object)(object)drop != (Object)null && Bricks.Ready && reader.HasBadgeAuthoritative)
			{
				while (Accepting.Invoke(machine) && reader.HasBadgeAuthoritative)
				{
					yield return null;
				}
				if (!reader.HasBadgeAuthoritative)
				{
					break;
				}
				int num = Mathf.Min(70, _units);
				ResourceType type = (ResourceType)_type;
				Vector3 val = (((Object)(object)_fill != (Object)null) ? _fill.position : (_root.position + Vector3.up * 0.8f));
				Bucket brick = Bricks.Spawn(type, num, val, Quaternion.Euler(0f, _root.eulerAngles.y, 0f));
				if ((Object)(object)brick == (Object)null)
				{
					break;
				}
				SetContents(_type, _units - num > 0, _units - num);
				RpcSold(_type, val);
				Vector3 val2 = BeltDirection(machine);
				yield return Glide(brick, Landing(drop.position, val2), Quaternion.LookRotation(val2));
				Release(brick);
				bricks++;
				float t = 0f;
				while ((Object)(object)brick != (Object)null && !DepositMachine.InAnyPipeline(((NetworkBehaviour)brick).netId) && t < 5f)
				{
					yield return null;
					t += Time.deltaTime;
				}
				if ((Object)(object)brick != (Object)null && !DepositMachine.InAnyPipeline(((NetworkBehaviour)brick).netId))
				{
					Plugin.Log.LogWarning((object)"The machine didn't take a brick; stopping");
					break;
				}
			}
			Plugin.Log.LogInfo((object)$"Unloaded {bricks} brick(s) onto {((Object)machine).name}, {_units} units left");
			_unloading = false;
		}

		private static Vector3 BeltDirection(DepositMachine machine)
		{
			//IL_003f: 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_0047: 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_0052: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			Traverse obj = Traverse.Create((object)machine);
			Transform value = obj.Field("enterStart").GetValue<Transform>();
			Transform value2 = obj.Field("enterEnd").GetValue<Transform>();
			Vector3 val = (((Object)(object)value != (Object)null && (Object)(object)value2 != (Object)null) ? (value2.position - value.position) : ((Component)machine).transform.forward);
			val.y = 0f;
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private static Vector3 Landing(Vector3 drop, Vector3 belt)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0041: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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)
			float[] array = Kitbash.Settings?.brickLanding;
			if (array == null || array.Length != 3)
			{
				array = new float[3] { 0.3f, 0.5f, 0f };
			}
			return drop + Vector3.Cross(Vector3.up, belt) * array[0] + Vector3.up * array[1] + belt * array[2];
		}

		private IEnumerator Glide(Bucket brick, Vector3 to, Quaternion toRot)
		{
			//IL_0015: 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_001c: 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)
			((HeldItem)brick).ServerGiveToHost();
			((HeldItem)brick).ServerEnsureNetworkTransform();
			RobotCargo.ForceClaim((Component)(object)brick, (Component)(object)this);
			RobotCargo.SetCarried((Component)(object)brick, (Component)(object)this);
			Vector3 from = ((Component)brick).transform.position;
			Quaternion fromRot = ((Component)brick).transform.rotation;
			float num = Vector3.Distance(from, to);
			float lift = 0.3f * Mathf.Clamp01(num);
			float time = 0.35f * Mathf.Max(1f, num);
			for (float t = 0f; t < 1f; t += Time.deltaTime / time)
			{
				if (!((Object)(object)brick != (Object)null))
				{
					break;
				}
				float num2 = ((t < 0.5f) ? (2f * t * t) : (1f - (2f - 2f * t) * (2f - 2f * t) / 2f));
				((Component)brick).transform.SetPositionAndRotation(Vector3.Lerp(from, to, num2) + Vector3.up * (lift * 4f * num2 * (1f - num2)), Quaternion.Slerp(fromRot, toRot, num2));
				yield return null;
			}
			if ((Object)(object)brick != (Object)null)
			{
				((Component)brick).transform.SetPositionAndRotation(to, toRot);
			}
		}

		private void Release(Bucket brick)
		{
			//IL_0031: 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)
			if (!((Object)(object)brick == (Object)null))
			{
				RobotCargo.ClearCarried((Component)(object)brick, (Component)(object)this);
				RobotCargo.Release((Component)(object)brick, (Component)(object)this);
				Rigidbody component = ((Component)brick).GetComponent<Rigidbody>();
				if (!((Object)(object)component == (Object)null))
				{
					component.isKinematic = false;
					component.linearVelocity = Vector3.zero;
					component.angularVelocity = Vector3.zero;
				}
			}
		}

		static BulkCart()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			All = new List<BulkCart>();
			Accepting = AccessTools.FieldRefAccess<DepositMachine, bool>("_accepting");
			RemoteProcedureCalls.RegisterCommand(typeof(BulkCart), "System.Void BulkCart::CmdPush(UnityEngine.Vector2,System.Boolean,Mirror.NetworkConnectionToClient)", new RemoteCallDelegate(InvokeCmdPush), false);
			RemoteProcedureCalls.RegisterCommand(typeof(BulkCart), "System.Void BulkCart::CmdPour(System.UInt32,Mirror.NetworkConnectionToClient)", new RemoteCallDelegate(InvokeCmdPour), false);
			RemoteProcedureCalls.RegisterCommand(typeof(BulkCart), "System.Void BulkCart::CmdUnload(Mirror.NetworkConnectionToClient)", new RemoteCallDelegate(InvokeCmdUnload), false);
			RemoteProcedureCalls.RegisterRpc(typeof(BulkCart), "System.Void BulkCart::RpcPoured(System.Int32)", new RemoteCallDelegate(InvokeRpcPoured));
			RemoteProcedureCalls.RegisterRpc(typeof(BulkCart), "System.Void BulkCart::RpcSold(System.Int32,UnityEngine.Vector3)", new RemoteCallDelegate(InvokeRpcSold));
		}

		public override bool Weaved()
		{
			return true;
		}

		private static int Hash(string name)
		{
			return Extensions.GetStableHashCode(name) & 0xFFFF;
		}

		private void CmdPush(Vector2 move, bool sprint)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			NetworkWriterPooled val = NetworkWriterPool.Get();
			NetworkWriterExtensions.WriteVector2((NetworkWriter)(object)val, move);
			NetworkWriterExtensions.WriteBool((NetworkWriter)(object)val, sprint);
			((NetworkBehaviour)this).SendCommandInternal("System.Void BulkCart::CmdPush(UnityEngine.Vector2,System.Boolean,Mirror.NetworkConnectionToClient)", Hash("System.Void BulkCart::CmdPush(UnityEngine.Vector2,System.Boolean,Mirror.NetworkConnectionToClient)"), (NetworkWriter)(object)val, 0, false);
			NetworkWriterPool.Return(val);
		}

		internal void CmdPour(uint bucketNetId)
		{
			NetworkWriterPooled val = NetworkWriterPool.Get();
			NetworkWriterExtensions.WriteVarUInt((NetworkWriter)(object)val, bucketNetId);
			((NetworkBehaviour)this).SendCommandInternal("System.Void BulkCart::CmdPour(System.UInt32,Mirror.NetworkConnectionToClient)", Hash("System.Void BulkCart::CmdPour(System.UInt32,Mirror.NetworkConnectionToClient)"), (NetworkWriter)(object)val, 0, false);
			NetworkWriterPool.Return(val);
		}

		internal void CmdUnload()
		{
			NetworkWriterPooled val = NetworkWriterPool.Get();
			((NetworkBehaviour)this).SendCommandInternal("System.Void BulkCart::CmdUnload(Mirror.NetworkConnectionToClient)", Hash("System.Void BulkCart::CmdUnload(Mirror.NetworkConnectionToClient)"), (NetworkWriter)(object)val, 0, false);
			NetworkWriterPool.Return(val);
		}

		private void RpcPoured(int type)
		{
			NetworkWriterPooled val = NetworkWriterPool.Get();
			NetworkWriterExtensions.WriteVarInt((NetworkWriter)(object)val, type);
			((NetworkBehaviour)this).SendRPCInternal("System.Void BulkCart::RpcPoured(System.Int32)", Hash("System.Void BulkCart::RpcPoured(System.Int32)"), (NetworkWriter)(object)val, 0, true);
			NetworkWriterPool.Return(val);
		}

		private void RpcSold(int type, Vector3 at)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			NetworkWriterPooled val = NetworkWriterPool.Get();
			NetworkWriterExtensions.WriteVarInt((NetworkWriter)(object)val, type);
			NetworkWriterExtensions.WriteVector3((NetworkWriter)(object)val, at);
			((NetworkBehaviour)this).SendRPCInternal("System.Void BulkCart::RpcSold(System.Int32,UnityEngine.Vector3)", Hash("System.Void BulkCart::RpcSold(System.Int32,UnityEngine.Vector3)"), (NetworkWriter)(object)val, 0, true);
			NetworkWriterPool.Return(val);
		}

		private static void InvokeRpcSold(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient sender)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			CartSounds.Collect((ResourceType)NetworkReaderExtensions.ReadVarInt(reader), NetworkReaderExtensions.ReadVector3(reader), 0.9f);
		}

		private static bool IsOccupant(BulkCart cart, NetworkConnectionToClient sender)
		{
			if (sender != null && ((InteractionStation)cart).OccupantNetId != 0 && NetworkServer.spawned.TryGetValue(((InteractionStation)cart).OccupantNetId, out var value))
			{
				return value.connectionToClient == sender;
			}
			return false;
		}

		private static void InvokeCmdPush(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient sender)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0032: Unknown result type (might be due to invalid IL or missing references)
			BulkCart bulkCart = (BulkCart)(object)obj;
			Vector2 val = NetworkReaderExtensions.ReadVector2(reader);
			bool serverSprint = NetworkReaderExtensions.ReadBool(reader);
			if (NetworkServer.active && IsOccupant(bulkCart, sender))
			{
				bulkCart._serverMove = Vector2.ClampMagnitude(val, 1f);
				bulkCart._serverSprint = serverSprint;
			}
		}

		private static void InvokeCmdPour(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient sender)
		{
			uint key = NetworkReaderExtensions.ReadVarUInt(reader);
			if (NetworkServer.active && NetworkServer.spawned.TryGetValue(key, out var value))
			{
				((BulkCart)(object)obj).ServerPour(((Component)value).GetComponent<Bucket>(), sender);
			}
		}

		private static void InvokeCmdUnload(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient sender)
		{
			BulkCart bulkCart = (BulkCart)(object)obj;
			if (NetworkServer.active && !bulkCart._unloading && bulkCart._units > 0)
			{
				BadgeReader reader2;
				DepositMachine val = bulkCart.MachineAhead(out reader2);
				if ((Object)(object)val == (Object)null || (Object)(object)reader2 == (Object)null || !reader2.HasBadgeAuthoritative)
				{
					Plugin.Log.LogInfo((object)$"Unload refused: machine {(Object)(object)val != (Object)null}, reader {(Object)(object)reader2 != (Object)null}, card in {(Object)(object)reader2 != (Object)null && reader2.HasBadgeAuthoritative}");
					return;
				}
				Plugin.Log.LogInfo((object)$"Unloading {bulkCart._units} x {(object)(ResourceType)bulkCart._type} into {((Object)val).name}");
				((MonoBehaviour)bulkCart).StartCoroutine(bulkCart.ServerUnload(val, reader2));
			}
		}

		private static void InvokeRpcPoured(NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient sender)
		{
			//IL_0034: 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)
			BulkCart bulkCart = (BulkCart)(object)obj;
			int num = NetworkReaderExtensions.ReadVarInt(reader);
			bulkCart.RefreshFill();
			CartSounds.Collect((ResourceType)num, ((Object)(object)bulkCart._tub != (Object)null) ? bulkCart._tub.position : bulkCart._root.position);
		}

		public override void SerializeSyncVars(NetworkWriter writer, bool forceAll)
		{
			((InteractionStation)this).SerializeSyncVars(writer, forceAll);
			if (forceAll)
			{
				NetworkWriterExtensions.WriteVarInt(writer, _type);
				NetworkWriterExtensions.WriteBool(writer, _hasType);
				NetworkWriterExtensions.WriteVarInt(writer, _units);
				return;
			}
			NetworkWriterExtensions.WriteVarULong(writer, ((NetworkBehaviour)this).syncVarDirtyBits);
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 2) != 0L)
			{
				NetworkWriterExtensions.WriteVarInt(writer, _type);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 4) != 0L)
			{
				NetworkWriterExtensions.WriteBool(writer, _hasType);
			}
			if ((((NetworkBehaviour)this).syncVarDirtyBits & 8) != 0L)
			{
				NetworkWriterExtensions.WriteVarInt(writer, _units);
			}
		}

		public override void DeserializeSyncVars(NetworkReader reader, bool initialState)
		{
			((InteractionStation)this).DeserializeSyncVars(reader, initialState);
			if (initialState)
			{
				_type = NetworkReaderExtensions.ReadVarInt(reader);
				_hasType = NetworkReaderExtensions.ReadBool(reader);
				_units = NetworkReaderExtensions.ReadVarInt(reader);
			}
			else
			{
				ulong num = NetworkReaderExtensions.ReadVarULong(reader);
				if ((num & 2) != 0L)
				{
					_type = NetworkReaderExtensions.ReadVarInt(reader);
				}
				if ((num & 4) != 0L)
				{
					_hasType = NetworkReaderExtensions.ReadBool(reader);
				}
				if ((num & 8) != 0L)
				{
					_units = NetworkReaderExtensions.ReadVarInt(reader);
				}
			}
			RefreshFill();
		}
	}
	public class BulkCartTub : Interactable
	{
		internal BulkCart Cart;

		private bool _unload;

		public override string PromptKey
		{
			get
			{
				if (!_unload)
				{
					return "BulkCart_Pour";
				}
				return "BulkCart_Unload";
			}
		}

		public override bool CanInteract(PlayerItemHolder holder)
		{
			if ((Object)(object)Cart == (Object)null || Cart.Unloading)
			{
				return false;
			}
			HeldItem currentItem = holder.CurrentItem;
			Bucket val = (Bucket)(object)((currentItem is Bucket) ? currentItem : null);
			if (val != null && val.CurrentUnits > 0)
			{
				_unload = false;
				return Cart.Units < 140;
			}
			_unload = true;
			if (Cart.Units > 0 && (Object)(object)Cart.MachineAhead(out var reader) != (Object)null && (Object)(object)reader != (Object)null)
			{
				return reader.HasBadgeAuthoritative;
			}
			return false;
		}

		public override void Interact(PlayerItemHolder holder)
		{
			//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)
			if ((Object)(object)Cart == (Object)null)
			{
				return;
			}
			if (!_unload)
			{
				HeldItem currentItem = holder.CurrentItem;
				Bucket val = (Bucket)(object)((currentItem is Bucket) ? currentItem : null);
				if (val != null)
				{
					if (BulkCart.CanPour(Cart, val))
					{
						Cart.CmdPour(((NetworkBehaviour)val).netId);
					}
					else if (Cart.HasType && Cart.Units > 0 && val.LockedType != Cart.Type)
					{
						Tips.Show("Tip_BucketOneMaterial");
					}
					return;
				}
			}
			if (_unload)
			{
				Cart.CmdUnload();
			}
		}
	}
	internal static class CartFill
	{
		internal sealed class FillRange : MonoBehaviour
		{
			public Vector3 Center;

			public float Low;

			public float High;
		}

		private const float Wall = 0.06f;

		private const float Floor = 0.05f;

		private const float Rim = 0.06f;

		private static readonly Dictionary<ResourceType, Material> materials = new Dictionary<ResourceType, Material>();

		internal static Transform Build(Transform tub, Transform root)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0058: 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_0088: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			Transform val = tub.Find("Fill");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			MeshFilter component = ((Component)tub).GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				return null;
			}
			Bounds bounds = component.sharedMesh.bounds;
			Vector3 lossyScale = tub.lossyScale;
			float num = 0.06f / Mathf.Max(lossyScale.x, 0.001f);
			float num2 = 0.06f / Mathf.Max(lossyScale.z, 0.001f);
			GameObject val2 = new GameObject("Fill")
			{
				layer = ((Component)tub).gameObject.layer
			};
			val2.transform.SetParent(tub, false);
			val2.AddComponent<MeshFilter>().sharedMesh = Quad(((Bounds)(ref bounds)).size.x - 2f * num, ((Bounds)(ref bounds)).size.z - 2f * num2);
			((Renderer)val2.AddComponent<MeshRenderer>()).enabled = false;
			FillRange fillRange = val2.AddComponent<FillRange>();
			fillRange.Center = new Vector3(((Bounds)(ref bounds)).center.x, 0f, ((Bounds)(ref bounds)).center.z);
			fillRange.Low = ((Bounds)(ref bounds)).min.y + 0.05f / Mathf.Max(lossyScale.y, 0.001f);
			fillRange.High = ((Bounds)(ref bounds)).max.y - 0.06f / Mathf.Max(lossyScale.y, 0.001f);
			return val2.transform;
		}

		internal static void Show(Transform fill, ResourceType? type, float amount)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)fill == (Object)null))
			{
				MeshRenderer component = ((Component)fill).GetComponent<MeshRenderer>();
				Material val = (type.HasValue ? MaterialFor(type.Value) : null);
				((Renderer)component).enabled = (Object)(object)val != (Object)null && amount > 0f;
				if (((Renderer)component).enabled)
				{
					((Renderer)component).sharedMaterial = val;
					FillRange component2 = ((Component)fill).GetComponent<FillRange>();
					fill.localPosition = component2.Center + Vector3.up * Mathf.Lerp(component2.Low, component2.High, Mathf.Clamp01(amount));
				}
			}
		}

		internal static Bounds LocalBounds(Transform tub, Transform root)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_005c: 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_007b: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = ((Component)tub).GetComponent<MeshFilter>().sharedMesh.bounds;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(root.InverseTransformPoint(tub.TransformPoint(((Bounds)(ref bounds)).center)), Vector3.zero);
			Vector3 val = default(Vector3);
			for (int i = 0; i < 8; i++)
			{
				((Vector3)(ref val))..ctor(((i & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((i & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((i & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z);
				((Bounds)(ref result)).Encapsulate(root.InverseTransformPoint(tub.TransformPoint(val)));
			}
			return result;
		}

		internal static Material MaterialFor(ResourceType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			if (materials.TryGetValue(type, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Bucket[] array = Resources.FindObjectsOfTypeAll<Bucket>();
			for (int i = 0; i < array.Length; i++)
			{
				if (!(Traverse.Create((object)array[i]).Field("resourceTypes").GetValue() is Array array2))
				{
					continue;
				}
				foreach (object item in array2)
				{
					Traverse val = Traverse.Create(item);
					if (val.Field("type").GetValue<ResourceType>() == type)
					{
						GameObject value2 = val.Field("fillObject").GetValue<GameObject>();
						Renderer val2 = (((Object)(object)value2 != (Object)null) ? value2.GetComponentInChildren<Renderer>(true) : null);
						if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMaterial == (Object)null))
						{
							return materials[type] = val2.sharedMaterial;
						}
					}
				}
			}
			return null;
		}

		private static Mesh Quad(float w, float d)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			float num = w / 2f;
			float num2 = d / 2f;
			Mesh val = new Mesh
			{
				name = "BulkCart_Fill"
			};
			val.vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f - num, 0f, 0f - num2),
				new Vector3(0f - num, 0f, num2),
				new Vector3(num, 0f, num2),
				new Vector3(num, 0f, 0f - num2)
			};
			val.uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(0f, 1f),
				new Vector2(1f, 1f),
				new Vector2(1f, 0f)
			};
			val.normals = (Vector3[])(object)new Vector3[4]
			{
				Vector3.up,
				Vector3.up,
				Vector3.up,
				Vector3.up
			};
			val.triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
			val.RecalculateBounds();
			val.RecalculateTangents();
			return val;
		}
	}
	internal static class CartIcon
	{
		private const int Layer = 31;

		private static readonly Vector3 Stage = new Vector3(0f, -1000f, 0f);

		internal static Sprite Render(Transform visual, Kitbash.IconSettings s, string pngPath)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_01a8: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: 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)
			GameObject val = Object.Instantiate<GameObject>(((Component)visual).gameObject, Stage, Quaternion.identity);
			((Object)val).name = "BulkCart Icon Model";
			GameObject val2 = new GameObject("BulkCart Icon Camera");
			GameObject val3 = new GameObject("BulkCart Icon Light");
			RenderTexture val4 = new RenderTexture(s.size, s.size, 24, (RenderTextureFormat)0)
			{
				antiAliasing = 4
			};
			try
			{
				Bounds val5 = Prepare(val);
				Camera obj = val2.AddComponent<Camera>();
				((Behaviour)obj).enabled = false;
				obj.cullingMask = int.MinValue;
				obj.clearFlags = (CameraClearFlags)2;
				obj.fieldOfView = s.fov;
				obj.targetTexture = val4;
				Vector3 val6 = Quaternion.Euler(0f - s.pitch, s.yaw, 0f) * Vector3.forward;
				Vector3 extents = ((Bounds)(ref val5)).extents;
				float num = ((Vector3)(ref extents)).magnitude / Mathf.Sin(s.fov * 0.5f * ((float)Math.PI / 180f));
				((Component)obj).transform.position = ((Bounds)(ref val5)).center + val6 * num;
				((Component)obj).transform.LookAt(((Bounds)(ref val5)).center);
				extents = ((Bounds)(ref val5)).extents;
				obj.nearClipPlane = Mathf.Max(0.01f, num - ((Vector3)(ref extents)).magnitude * 2f);
				extents = ((Bounds)(ref val5)).extents;
				obj.farClipPlane = num + ((Vector3)(ref extents)).magnitude * 2f;
				Light obj2 = val3.AddComponent<Light>();
				obj2.type = (LightType)1;
				obj2.cullingMask = int.MinValue;
				obj2.intensity = s.light;
				obj2.shadows = (LightShadows)0;
				val3.transform.rotation = Quaternion.Euler(s.lightPitch, s.yaw + s.lightYaw, 0f);
				Color[] array = Shoot(obj, val4, Color.black);
				Color[] array2 = Shoot(obj, val4, Color.white);
				Texture2D val7 = new Texture2D(s.size, s.size, (TextureFormat)4, false);
				Color[] array3 = (Color[])(object)new Color[array.Length];
				for (int i = 0; i < array3.Length; i++)
				{
					float num2 = Mathf.Clamp01(1f - (array2[i].r - array[i].r + (array2[i].g - array[i].g) + (array2[i].b - array[i].b)) / 3f);
					array3[i] = (Color)((num2 > 0.004f) ? new Color(array[i].r / num2, array[i].g / num2, array[i].b / num2, num2) : Color.clear);
				}
				val7.SetPixels(array3);
				Texture2D val8 = Crop(val7, array3, s.size, 8);
				Object.Destroy((Object)(object)val7);
				if (pngPath != null)
				{
					File.WriteAllBytes(pngPath, ImageConversion.EncodeToPNG(val8));
				}
				return Sprite.Create(val8, new Rect(0f, 0f, (float)((Texture)val8).width, (float)((Texture)val8).height), new Vector2(0.5f, 0.5f), 100f);
			}
			finally
			{
				Object.Destroy((Object)(object)val);
				Object.Destroy((Object)(object)val2);
				Object.Destroy((Object)(object)val3);
				val4.Release();
				Object.Destroy((Object)(object)val4);
			}
		}

		private static Bounds Prepare(GameObject copy)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			Transform[] componentsInChildren = copy.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.layer = 31;
			}
			Collider[] componentsInChildren2 = copy.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			Renderer[] componentsInChildren3 = copy.GetComponentsInChildren<Renderer>(true);
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(copy.transform.position, Vector3.zero);
			Renderer[] array = componentsInChildren3;
			foreach (Renderer val in array)
			{
				if (val.enabled)
				{
					val.lightProbeUsage = (LightProbeUsage)0;
					val.shadowCastingMode = (ShadowCastingMode)0;
					if (((Bounds)(ref bounds)).size == Vector3.zero)
					{
						bounds = val.bounds;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			return bounds;
		}

		private static Color[] Shoot(Camera cam, RenderTexture rt, Color background)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0083: Expected O, but got Unknown
			cam.backgroundColor = background;
			StandardRequest val = new StandardRequest
			{
				destination = rt
			};
			if (RenderPipeline.SupportsRenderRequest<StandardRequest>(cam, val))
			{
				RenderPipeline.SubmitRenderRequest<StandardRequest>(cam, val);
			}
			else
			{
				cam.Render();
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = rt;
			Texture2D val2 = new Texture2D(((Texture)rt).width, ((Texture)rt).height, (TextureFormat)4, false);
			val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)rt).width, (float)((Texture)rt).height), 0, 0, false);
			RenderTexture.active = active;
			Color[] pixels = val2.GetPixels();
			Object.Destroy((Object)val2);
			return pixels;
		}

		private static Texture2D Crop(Texture2D full, Color[] px, int size, int pad)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			int num = size;
			int num2 = size;
			int num3 = -1;
			int num4 = -1;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					if (px[i * size + j].a > 0.02f)
					{
						num = Mathf.Min(num, j);
						num3 = Mathf.Max(num3, j);
						num2 = Mathf.Min(num2, i);
						num4 = Mathf.Max(num4, i);
					}
				}
			}
			if (num3 < 0)
			{
				return full;
			}
			num = Mathf.Max(0, num - pad);
			num2 = Mathf.Max(0, num2 - pad);
			num3 = Mathf.Min(size - 1, num3 + pad);
			num4 = Mathf.Min(size - 1, num4 + pad);
			Texture2D val = new Texture2D(num3 - num + 1, num4 - num2 + 1, (TextureFormat)4, false);
			val.SetPixels(full.GetPixels(num, num2, ((Texture)val).width, ((Texture)val).height));
			val.Apply();
			return val;
		}
	}
	internal sealed class CartInfo : MonoBehaviour, IWorldInfo
	{
		private BulkCart _cart;

		private Transform _anchor;

		public bool ShowInfo
		{
			get
			{
				if ((Object)(object)Cart != (Object)null)
				{
					return !PushedByMe(Cart);
				}
				return false;
			}
		}

		public Transform InfoAnchor
		{
			get
			{
				if (!((Object)(object)_anchor != (Object)null))
				{
					return ((Component)this).transform;
				}
				return _anchor;
			}
		}

		private BulkCart Cart
		{
			get
			{
				if (!((Object)(object)_cart != (Object)null))
				{
					return _cart = ((Component)this).GetComponentInChildren<BulkCart>();
				}
				return _cart;
			}
		}

		private static bool PushedByMe(BulkCart cart)
		{
			if (((InteractionStation)cart).OccupantNetId != 0 && NetworkClient.spawned.TryGetValue(((InteractionStation)cart).OccupantNetId, out var value))
			{
				if (!value.isLocalPlayer)
				{
					return value.isOwned;
				}
				return true;
			}
			return false;
		}

		private void Awake()
		{
			_anchor = ((Component)this).transform.Find("InfoAnchor");
		}

		public string GetInfoTitle()
		{
			return LocalizationManager.Get("BulkCart_Name", Array.Empty<object>());
		}

		public void GetInfoAttributes(List<ItemAttribute> list)
		{
			Attributes(Cart, list);
		}

		internal static void Attributes(BulkCart cart, List<ItemAttribute> list)
		{
			//IL_0026: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			bool flag = cart.HasType && cart.Units > 0;
			list.Add(ItemAttribute.Text("Attr_Contents", LocalizationManager.Get(flag ? ResourceTypeNames.NameKey(cart.Type) : "Attr_Contents_Empty", Array.Empty<object>())));
			list.Add(ItemAttribute.Meter("Attr_Fill", cart.Units, 140));
		}
	}
	internal static class CartPrefab
	{
		internal const uint AssetId = 2353691393u;

		private static readonly Vector3 GripCentre = new Vector3(0f, 1.16f, -0.82f);

		private const float GripHalfWidth = 0.27f;

		private static GameObject _holder;

		private static GameObject _template;

		internal static bool Ready => (Object)(object)_template != (Object)null;

		internal static GameObject Template => _template;

		internal static Transform Holder
		{
			get
			{
				if (!((Object)(object)_holder != (Object)null))
				{
					return null;
				}
				return _holder.transform;
			}
		}

		internal static void Ensure(Scene scene)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_003f: 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_0050: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00ee: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: 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)
			GameObject root;
			if (!((Object)(object)_template != (Object)null))
			{
				int layer = InteractLayer();
				_holder = new GameObject("BulkCart Templates");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
				root = new GameObject("BulkCart")
				{
					layer = layer
				};
				root.transform.SetParent(_holder.transform, false);
				root.AddComponent<NetworkIdentity>();
				Rigidbody obj = root.AddComponent<Rigidbody>();
				obj.isKinematic = true;
				obj.interpolation = (RigidbodyInterpolation)1;
				root.AddComponent<NetworkTransformReliable>();
				AddVisual(root.transform, layer, scene);
				Quaternion rot = Quaternion.LookRotation(Vector3.forward, Vector3.up);
				Point("GripL", GripCentre + Vector3.left * 0.27f, rot);
				Point("GripR", GripCentre + Vector3.right * 0.27f, rot);
				Transform value = Point("Seat", new Vector3(0f, 0f, -1.35f), Quaternion.identity);
				Transform value2 = Point("Camera", new Vector3(0f, 1.55f, -1.35f), Quaternion.identity);
				Transform value3 = Point("Exit", new Vector3(0f, 0f, -1.75f), Quaternion.identity);
				Point("InfoAnchor", new Vector3(0f, 1.1f, 0.1f), Quaternion.identity);
				root.AddComponent<CartInfo>();
				GameObject val = new GameObject("Handle")
				{
					layer = layer
				};
				val.transform.SetParent(root.transform, false);
				BoxCollider obj2 = val.AddComponent<BoxCollider>();
				((Collider)obj2).isTrigger = true;
				obj2.center = GripCentre;
				obj2.size = new Vector3(0.9f, 0.3f, 0.3f);
				Traverse obj3 = Traverse.Create((object)val.AddComponent<BulkCart>());
				obj3.Field("seatPoint").SetValue((object)value);
				obj3.Field("cameraPoint").SetValue((object)value2);
				obj3.Field("exitPoint").SetValue((object)value3);
				obj3.Field("lookAngleLimit").SetValue((object)75f);
				obj3.Field("lookSensitivityMultiplier").SetValue((object)0.8f);
				_template = root;
				Bricks.Ensure(_holder.transform);
				NetworkClient.RegisterPrefab(_template, 2353691393u);
				if ((Object)(object)ShopItem.Item != (Object)null)
				{
					ShopItem.Item.spawnPrefab = _template;
				}
				RenderIcon();
				Plugin.Log.LogInfo((object)"Bulk Cart prefab registered");
			}
			Transform Point(string name, Vector3 pos, Quaternion localRotation)
			{
				//IL_0001: 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_0025: Unknown result type (might be due to invalid IL or missing references)
				Transform transform = new GameObject(name).transform;
				transform.SetParent(root.transform, false);
				transform.localPosition = pos;
				transform.localRotation = localRotation;
				return transform;
			}
		}

		internal static void AddVisual(Transform root, int layer, Scene scene)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Transform val = root.Find("Visual");
			if ((Object)(object)val != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
			}
			GameObject obj = Kitbash.Build("Cart", layer, scene);
			((Object)obj).name = "Visual";
			obj.transform.SetParent(root, false);
		}

		private static void RenderIcon()
		{
			try
			{
				string pngPath = null;
				ShopItem.SetIcon(CartIcon.Render(_template.transform.Find("Visual"), Kitbash.Settings.icon ?? new Kitbash.IconSettings(), pngPath));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Couldn't render the cart icon: " + ex.Message));
			}
		}

		internal static void ReloadVisuals(Scene scene)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_template == (Object)null)
			{
				return;
			}
			int layer = _template.layer;
			AddVisual(_template.transform, layer, scene);
			RenderIcon();
			foreach (BulkCart item in BulkCart.All)
			{
				AddVisual(item.Root, layer, scene);
				item.AttachVisual();
			}
		}

		internal static BulkCart Spawn(Vector3 position, Quaternion rotation, int type = 0, bool hasType = false, int units = 0)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || (Object)(object)_template == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(_template, position, rotation);
			((Object)obj).name = "BulkCart";
			NetworkServer.Spawn(obj, (NetworkConnectionToClient)null);
			BulkCart componentInChildren = obj.GetComponentInChildren<BulkCart>();
			componentInChildren.SetContents(type, hasType, units);
			return componentInChildren;
		}

		private static int InteractLayer()
		{
			BadgeReaderInteractable val = ((IEnumerable<BadgeReaderInteractable>)Resources.FindObjectsOfTypeAll<BadgeReaderInteractable>()).FirstOrDefault((Func<BadgeReaderInteractable, bool>)delegate(BadgeReaderInteractable r)
			{
				//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)
				Scene scene = ((Component)r).gameObject.scene;
				return ((Scene)(ref scene)).IsValid();
			});
			if (!((Object)(object)val != (Object)null))
			{
				return 0;
			}
			return ((Component)val).gameObject.layer;
		}
	}
	[HarmonyPatch]
	internal static class CartSave
	{
		private sealed class Entry
		{
			public float x;

			public float y;

			public float z;

			public float yaw;

			public int type;

			public int units;

			public bool hasType;
		}

		private static string Sidecar(string worldPath)
		{
			return worldPath + ".bulkcart.json";
		}

		[HarmonyPatch(typeof(SaveManager), "WriteSnapshot")]
		[HarmonyPostfix]
		private static void Write(string path)
		{
			//IL_0035: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected I4, but got Unknown
			if (!NetworkServer.active)
			{
				return;
			}
			List<Entry> list = new List<Entry>();
			foreach (BulkCart item in BulkCart.All)
			{
				Transform root = item.Root;
				list.Add(new Entry
				{
					x = root.position.x,
					y = root.position.y,
					z = root.position.z,
					yaw = root.eulerAngles.y,
					type = (int)item.Type,
					hasType = item.HasType,
					units = item.Units
				});
			}
			File.WriteAllText(Sidecar(path), JsonConvert.SerializeObject((object)list));
		}

		[HarmonyPatch(typeof(SaveManager), "Load")]
		[HarmonyPostfix]
		private static void AfterLoad()
		{
			RestoreLater(SaveSlots.WorldPath(SaveSlots.SelectedSlot));
		}

		[HarmonyPatch(typeof(SaveManager), "LoadCheckpoint")]
		[HarmonyPostfix]
		private static void AfterCheckpoint()
		{
			RestoreLater(SaveSlots.WorldPath(SaveSlots.SelectedSlot));
		}

		[HarmonyPatch(typeof(SaveManager), "LoadBaseline")]
		[HarmonyPostfix]
		private static void AfterBaseline()
		{
			RestoreLater(SaveSlots.BaselinePath(SaveSlots.SelectedSlot));
		}

		[HarmonyPatch(typeof(SaveManager), "ResetCheckpointToBaseline")]
		[HarmonyPostfix]
		private static void AfterReset()
		{
			string text = Sidecar(SaveSlots.BaselinePath(SaveSlots.SelectedSlot));
			string text2 = Sidecar(SaveSlots.WorldPath(SaveSlots.SelectedSlot));
			if (File.Exists(text))
			{
				File.Copy(text, text2, overwrite: true);
			}
			else if (File.Exists(text2))
			{
				File.Delete(text2);
			}
		}

		[HarmonyPatch(typeof(SaveSlots), "DeleteSlot")]
		[HarmonyPostfix]
		private static void AfterDelete(int slot)
		{
			string[] array = new string[2]
			{
				SaveSlots.WorldPath(slot),
				SaveSlots.BaselinePath(slot)
			};
			foreach (string worldPath in array)
			{
				if (File.Exists(Sidecar(worldPath)))
				{
					File.Delete(Sidecar(worldPath));
				}
			}
		}

		private static void RestoreLater(string worldPath)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(Restore(worldPath));
			}
		}

		private static IEnumerator Restore(string worldPath)
		{
			yield return null;
			for (float t = 0f; t < 60f; t += Time.unscaledDeltaTime)
			{
				if (!((Object)(object)SaveManager.Instance == (Object)null) && !SaveManager.LoadInProgress && CartPrefab.Ready)
				{
					break;
				}
				yield return null;
			}
			if (!NetworkServer.active)
			{
				yield break;
			}
			BulkCart[] array = BulkCart.All.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				NetworkServer.Destroy(((Component)array[i].Root).gameObject);
			}
			string path = Sidecar(worldPath);
			if (!File.Exists(path))
			{
				yield break;
			}
			List<Entry> list = JsonConvert.DeserializeObject<List<Entry>>(File.ReadAllText(path)) ?? new List<Entry>();
			foreach (Entry item in list)
			{
				CartPrefab.Spawn(new Vector3(item.x, item.y, item.z), Quaternion.Euler(0f, item.yaw, 0f), item.type, item.hasType, item.units);
			}
			Plugin.Log.LogInfo((object)$"Restored {list.Count} Bulk Cart(s)");
		}
	}
	internal sealed class CartSounds
	{
		private static SoundDefinition _roll;

		private static float _rollVolume = 1f;

		private static float _fadeSpeed = 4f;

		private SoundHandle _loop = SoundHandle.None;

		private float _volume;

		private static void FindRoll()
		{
			if (!((Object)(object)_roll != (Object)null))
			{
				PushableScaffold val = Object.FindAnyObjectByType<PushableScaffold>();
				if (!((Object)(object)val == (Object)null))
				{
					Traverse val2 = Traverse.Create((object)val);
					_roll = val2.Field("pushLoopSound").GetValue<SoundDefinition>();
					_rollVolume = val2.Field("pushLoopMaxVolume").GetValue<float>();
					_fadeSpeed = Mathf.Max(0.5f, val2.Field("pushLoopFadeSpeed").GetValue<float>());
				}
			}
		}

		internal void Update(Transform at, float rolling)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			FindRoll();
			float num = ((rolling > 0.03f) ? _rollVolume : 0f);
			_volume = Mathf.MoveTowards(_volume, num, _fadeSpeed * Time.unscaledDeltaTime);
			if (_volume > 0.001f && (Object)(object)_roll != (Object)null)
			{
				if (!((SoundHandle)(ref _loop)).IsPlaying)
				{
					_loop = SoundFX.PlayLoopAttached(_roll, at, 1f);
					((SoundHandle)(ref _loop)).SetVolume(0f);
				}
				if (((SoundHandle)(ref _loop)).IsPlaying)
				{
					((SoundHandle)(ref _loop)).SetVolume(_volume);
					((SoundHandle)(ref _loop)).SetPitch(Mathf.Lerp(0.85f, 1.25f, rolling));
				}
			}
			else
			{
				Stop();
			}
		}

		internal void Stop()
		{
			//IL_001e: 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)
			if (((SoundHandle)(ref _loop)).IsPlaying)
			{
				((SoundHandle)(ref _loop)).Stop(0f);
			}
			_loop = SoundHandle.None;
		}

		internal static void Collect(ResourceType type, Vector3 position, float pitch = 1f)
		{
			//IL_0015: 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)
			ResourceData val = (((Object)(object)ResourcePickupManager.Instance != (Object)null) ? ResourcePickupManager.Instance.GetResourceData(type) : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.collectSound != (Object)null)
			{
				SoundFX.PlayAt(val.collectSound, position, pitch, 1f, 0f);
			}
		}
	}
	internal sealed class CartWheels
	{
		private struct Wheel
		{
			public Transform Pivot;

			public float Radius;

			public float Side;
		}

		private readonly List<Wheel> _wheels = new List<Wheel>();

		private Transform _root;

		private Vector3 _lastPos;

		private float _lastYaw;

		internal void Bind(Transform root, Transform visual)
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			_wheels.Clear();
			_root = root;
			if ((Object)(object)visual == (Object)null)
			{
				return;
			}
			foreach (Transform item in new List<Transform>(visual.Cast()))
			{
				if (((Object)item).name.StartsWith("Wheel"))
				{
					Renderer component = ((Component)item).GetComponent<Renderer>();
					if (!((Object)(object)component == (Object)null))
					{
						Bounds bounds = component.bounds;
						Transform transform = new GameObject(((Object)item).name + " Pivot")
						{
							layer = ((Component)item).gameObject.layer
						}.transform;
						transform.SetParent(visual, false);
						transform.position = ((Bounds)(ref bounds)).center;
						transform.rotation = root.rotation;
						item.SetParent(transform, true);
						_wheels.Add(new Wheel
						{
							Pivot = transform,
							Radius = Mathf.Max(0.05f, ((Bounds)(ref bounds)).extents.y),
							Side = root.InverseTransformPoint(((Bounds)(ref bounds)).center).x
						});
					}
				}
			}
			_lastPos = root.position;
			_lastYaw = root.eulerAngles.y;
		}

		internal void Update()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root == (Object)null || _wheels.Count == 0)
			{
				return;
			}
			float num = Vector3.Dot(_root.position - _lastPos, _root.forward);
			float num2 = Mathf.DeltaAngle(_lastYaw, _root.eulerAngles.y) * ((float)Math.PI / 180f);
			_lastPos = _root.position;
			_lastYaw = _root.eulerAngles.y;
			if (Mathf.Abs(num) < 1E-05f && Mathf.Abs(num2) < 1E-06f)
			{
				return;
			}
			foreach (Wheel wheel in _wheels)
			{
				float num3 = num - num2 * wheel.Side;
				wheel.Pivot.Rotate(Vector3.right, num3 / wheel.Radius * 57.29578f, (Space)1);
			}
		}
	}
	internal static class TransformExtensions
	{
		internal static IEnumerable<Transform> Cast(this Transform t)
		{
			foreach (Transform item in t)
			{
				yield return item;
			}
		}
	}
	internal static class GameMeshes
	{
		internal sealed class Part
		{
			public string Name;

			public float[] Pos;

			public float[] Normal;

			public float[] Uv;

			public int[] Index;
		}

		private sealed class Reader
		{
			private readonly byte[] _b;

			public int Pos;

			public Reader(byte[] b)
			{
				_b = b;
			}

			public int Int()
			{
				int result = BitConverter.ToInt32(_b, Pos);
				Pos += 4;
				return result;
			}

			public uint UInt()
			{
				return (uint)Int();
			}

			public byte Byte()
			{
				return _b[Pos++];
			}

			public void Align()
			{
				Pos = (Pos + 3) & -4;
			}

			public void Skip(int n)
			{
				Pos += n;
			}

			public byte[] Bytes(int n)
			{
				byte[] array = new byte[n];
				Array.Copy(_b, Pos, array, 0, n);
				Pos += n;
				return array;
			}

			public string Str()
			{
				int num = Int();
				string result = Encoding.UTF8.GetString(_b, Pos, num);
				Pos += num;
				Align();
				return result;
			}

			public void SkipArray(int elementSize)
			{
				Skip(Int() * elementSize);
				Align();
			}

			public byte[] ByteArray()
			{
				byte[] result = Bytes(Int());
				Align();
				return result;
			}
		}

		private sealed class MeshData
		{
			public float[][] Pos;

			public float[][] Normal;

			public float[][] Uv;

			public List<int[]> Tris = new List<int[]>();
		}

		private const int MeshClass = 43;

		private static readonly string[] Files = new string[3] { "sharedassets0.assets", "sharedassets1.assets", "resources.assets" };

		private static readonly int[] FormatSize = new int[12]
		{
			4, 2, 1, 1, 2, 2, 1, 1, 2, 2,
			4, 4
		};

		public static List<Part> Extract(string dataDir, IEnumerable<string> names)
		{
			Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
			foreach (string item in names.Distinct())
			{
				int num = item.IndexOf('#');
				if (num > 0)
				{
					string key = item.Substring(0, num);
					if (!dictionary.TryGetValue(key, out var value))
					{
						value = (dictionary[key] = new List<string>());
					}
					value.Add(item.Substring(num + 1));
				}
			}
			List<Part> list2 = new List<Part>();
			if (dictionary.Count == 0)
			{
				return list2;
			}
			Dictionary<string, MeshData> dictionary2 = new Dictionary<string, MeshData>();
			string[] files = Files;
			foreach (string path in files)
			{
				string path2 = Path.Combine(dataDir, path);
				if (File.Exists(path2))
				{
					Scan(path2, dataDir, dictionary, dictionary2);
				}
				if (dictionary2.Count == dictionary.Count)
				{
					break;
				}
			}
			foreach (KeyValuePair<string, List<string>> item2 in dictionary)
			{
				if (!dictionary2.TryGetValue(item2.Key, out var value2))
				{
					throw new InvalidDataException("mesh " + item2.Key + " not found");
				}
				List<List<int[]>> pieces = Pieces(value2);
				foreach (string item3 in item2.Value)
				{
					list2.Add(Cut(value2, pieces, item2.Key, item3));
				}
			}
			return list2;
		}

		private static void Scan(string path, string dataDir, Dictionary<string, List<string>> wanted, Dictionary<string, MeshData> found)
		{
			using FileStream fileStream = File.OpenRead(path);
			using BinaryReader binaryReader = new BinaryReader(fileStream);
			fileStream.Position = 8L;
			if (BigEndian(binaryReader.ReadBytes(4)) != 22)
			{
				throw new InvalidDataException(Path.GetFileName(path) + ": not format 22");
			}
			fileStream.Position = 16L;
			if (binaryReader.ReadByte() != 0)
			{
				throw new InvalidDataException("big-endian asset file");
			}
			fileStream.Position = 32L;
			long num = (long)BigEndian(binaryReader.ReadBytes(8));
			fileStream.Position = 48L;
			while (binaryReader.ReadByte() != 0)
			{
			}
			binaryReader.ReadInt32();
			if (binaryReader.ReadBoolean())
			{
				throw new InvalidDataException("asset file has type trees");
			}
			int num2 = binaryReader.ReadInt32();
			int[] array = new int[num2];
			for (int i = 0; i < num2; i++)
			{
				array[i] = binaryReader.ReadInt32();
				binaryReader.ReadByte();
				binaryReader.ReadInt16();
				if (array[i] == 114)
				{
					binaryReader.ReadBytes(16);
				}
				binaryReader.ReadBytes(16);
			}
			int num3 = binaryReader.ReadInt32();
			List<(long, uint)> list = new List<(long, uint)>();
			for (int j = 0; j < num3; j++)
			{
				fileStream.Position = (fileStream.Position + 3) & -4;
				binaryReader.ReadInt64();
				long item = binaryReader.ReadInt64() + num;
				uint item2 = binaryReader.ReadUInt32();
				int num4 = binaryReader.ReadInt32();
				if (num4 >= 0 && num4 < num2 && array[num4] == 43)
				{
					list.Add((item, item2));
				}
			}
			foreach (var item5 in list)
			{
				long item3 = item5.Item1;
				uint item4 = item5.Item2;
				fileStream.Position = item3;
				int num5 = binaryReader.ReadInt32();
				if (num5 > 0 && num5 <= 256)
				{
					string key = Encoding.UTF8.GetString(binaryReader.ReadBytes(num5));
					if (wanted.ContainsKey(key) && !found.ContainsKey(key))
					{
						fileStream.Position = item3;
						found[key] = ReadMesh(new Reader(binaryReader.ReadBytes((int)item4)), dataDir);
					}
				}
			}
		}

		private static ulong BigEndian(byte[] b)
		{
			ulong num = 0uL;
			foreach (byte b2 in b)
			{
				num = (num << 8) | b2;
			}
			return num;
		}

		private static MeshData ReadMesh(Reader r, string dataDir)
		{
			r.Str();
			int num = r.Int();
			(uint, uint, int)[] array = new(uint, uint, int)[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = (r.UInt(), r.UInt(), r.Int());
				r.Skip(36);
			}
			r.Align();
			r.SkipArray(40);
			r.SkipArray(12);
			int num2 = r.Int();
			for (int j = 0; j < num2; j++)
			{
				r.Str();
				r.Skip(12);
			}
			r.Align();
			r.SkipArray(4);
			r.SkipArray(64);
			r.SkipArray(4);
			r.Skip(4);
			r.SkipArray(24);
			r.SkipArray(4);
			byte num3 = r.Byte();
			r.Skip(3);
			r.Align();
			if (num3 != 0)
			{
				throw new InvalidDataException("compressed mesh");
			}
			bool flag = r.Int() != 0;
			byte[] b = r.ByteArray();
			int count = r.Int();
			int num4 = r.Int();
			(int, int, int, int)[] array2 = new(int, int, int, int)[num4];
			for (int k = 0; k < num4; k++)
			{
				array2[k] = (r.Byte(), r.Byte(), r.Byte(), r.Byte() & 0xF);
			}
			r.Align();
			byte[] array3 = r.ByteArray();
			r.Align();
			for (int l = 0; l < 4; l++)
			{
				SkipBits(r, ranged: true);
			}
			for (int m = 0; m < 3; m++)
			{
				SkipBits(r, ranged: false);
			}
			SkipBits(r, ranged: true);
			for (int n = 0; n < 2; n++)
			{
				SkipBits(r, ranged: false);
			}
			r.Skip(36);
			r.ByteArray();
			r.ByteArray();
			r.Skip(8);
			r.Align();
			long offset = BitConverter.ToInt64(r.Bytes(8), 0);
			uint num5 = r.UInt();
			string path = r.Str();
			if (array3.Length == 0 && num5 != 0)
			{
				array3 = ReadStream(Path.Combine(dataDir, Path.GetFileName(path)), offset, num5);
			}
			MeshData meshData = new MeshData();
			(int, int)[] streams = Streams(array2, count);
			meshData.Pos = Channel(array3, array2, streams, 0, count);
			meshData.Normal = Channel(array3, array2, streams, 1, count);
			meshData.Uv = Channel(array3, array2, streams, 4, count);
			if (meshData.Pos == null)
			{
				throw new InvalidDataException("mesh has no positions");
			}
			(uint, uint, int)[] array4 = array;
			for (int num6 = 0; num6 < array4.Length; num6++)
			{
				(uint, uint, int) tuple = array4[num6];
				var (num7, num8, _) = tuple;
				if (tuple.Item3 != 0)
				{
					throw new InvalidDataException("non-triangle submesh");
				}
				long num9 = num7 / (flag ? 4 : 2);
				for (long num10 = num9; num10 + 2 < num9 + num8; num10 += 3)
				{
					meshData.Tris.Add(new int[3]
					{
						Index(b, num10, flag),
						Index(b, num10 + 1, flag),
						Index(b, num10 + 2, flag)
					});
				}
			}
			return meshData;
		}

		private static void SkipBits(Reader r, bool ranged)
		{
			r.Skip(ranged ? 12 : 4);
			r.ByteArray();
			r.Skip(1);
			r.Align();
		}

		private static byte[] ReadStream(string path, long offset, uint size)
		{
			using FileStream fileStream = File.OpenRead(path);
			fileStream.Position = offset;
			byte[] array = new byte[size];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = fileStream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					throw new EndOfStreamException(path);
				}
			}
			return array;
		}

		private static int Index(byte[] b, long i, bool wide)
		{
			if (!wide)
			{
				return BitConverter.ToUInt16(b, (int)(i * 2));
			}
			return BitConverter.ToInt32(b, (int)(i * 4));
		}

		private static (int offset, int stride)[] Streams((int stream, int offset, int format, int dimension)[] chans, int count)
		{
			int num = ((chans.Length != 0) ? (chans.Max(((int stream, int offset, int format, int dimension) c) => c.stream) + 1) : 0);
			(int, int)[] array = new(int, int)[num];
			int s = 0;
			int num2 = 0;
			for (; s < num; s++)
			{
				int num3 = chans.Where(((int stream, int offset, int format, int dimension) c) => c.stream == s && c.dimension > 0).Sum(((int stream, int offset, int format, int dimension) c) => c.dimension * FormatSize[c.format]);
				array[s] = (num2, num3);
				num2 = (num2 + count * num3 + 15) & -16;
			}
			return array;
		}

		private static float[][] Channel(byte[] data, (int stream, int offset, int format, int dimension)[] chans, (int offset, int stride)[] streams, int channel, int count)
		{
			if (channel >= chans.Length || chans[channel].dimension == 0)
			{
				return null;
			}
			(int, int, int, int) tuple = chans[channel];
			(int offset, int stride) tuple2 = streams[tuple.Item1];
			int item = tuple2.offset;
			int item2 = tuple2.stride;
			int num = FormatSize[tuple.Item3];
			float[][] array = new float[count][];
			for (int i = 0; i < count; i++)
			{
				array[i] = new float[tuple.Item4];
				for (int j = 0; j < tuple.Item4; j++)
				{
					array[i][j] = Component(data, item + i * item2 + tuple.Item2 + j * num, tuple.Item3);
				}
			}
			return array;
		}

		private static float Component(byte[] b, int at, int format)
		{
			return format switch
			{
				0 => BitConverter.ToSingle(b, at), 
				1 => Half(BitConverter.ToUInt16(b, at)), 
				2 => (float)(int)b[at] / 255f, 
				3 => Math.Max((float)(sbyte)b[at] / 127f, -1f), 
				4 => (float)(int)BitConverter.ToUInt16(b, at) / 65535f, 
				5 => Math.Max((float)BitConverter.ToInt16(b, at) / 32767f, -1f), 
				_ => throw new InvalidDataException($"vertex format {format}"), 
			};
		}

		private static float Half(ushort h)
		{
			int num = h >> 15;
			int num2 = (h >> 10) & 0x1F;
			int num3 = h & 0x3FF;
			float num4 = num2 switch
			{
				31 => (num3 == 0) ? float.PositiveInfinity : float.NaN, 
				0 => (float)num3 / 1024f * (float)Math.Pow(2.0, -14.0), 
				_ => (1f + (float)num3 / 1024f) * (float)Math.Pow(2.0, num2 - 15), 
			};
			if (num != 1)
			{
				return num4;
			}
			return 0f - num4;
		}

		private static List<List<int[]>> Pieces(MeshData m)
		{
			int num = m.Pos.Length;
			int[] parent = Enumerable.Range(0, num).ToArray();
			Dictionary<(double, double, double), int> dictionary = new Dictionary<(double, double, double), int>();
			for (int i = 0; i < num; i++)
			{
				(double, double, double) key = (Math.Round(m.Pos[i][0], 4), Math.Round(m.Pos[i][1], 4), Math.Round(m.Pos[i][2], 4));
				if (dictionary.TryGetValue(key, out var value))
				{
					parent[Find(i)] = Find(value);
				}
				else
				{
					dictionary[key] = i;
				}
			}
			foreach (int[] tri in m.Tris)
			{
				parent[Find(tri[1])] = Find(tri[0]);
				parent[Find(tri[2])] = Find(tri[0]);
			}
			Dictionary<int, List<int[]>> groups = new Dictionary<int, List<int[]>>();
			List<int> list = new List<int>();
			foreach (int[] tri2 in m.Tris)
			{
				int num2 = Find(tri2[0]);
				if (!groups.TryGetValue(num2, out var value2))
				{
					value2 = (groups[num2] = new List<int[]>());
					list.Add(num2);
				}
				value2.Add(tri2);
			}
			return (from k in list
				select groups[k] into g
				orderby g.Count descending
				select g).ToList();
			int Find(int a)
			{
				while (parent[a] != a)
				{
					a = (parent[a] = parent[parent[a]]);
				}
				return a;
			}
		}

		private static Part Cut(MeshData m, List<List<int[]>> pieces, string mesh, string spec)
		{
			List<int[]> source = spec.Split(new char[1] { ',' }).Select(int.Parse).SelectMany((int k) => pieces[k])
				.ToList();
			List<int> used = (from i in source.SelectMany((int[] t) => t).Distinct()
				orderby i
				select i).ToList();
			Dictionary<int, int> remap = new Dictionary<int, int>();
			for (int num = 0; num < used.Count; num++)
			{
				remap[used[num]] = num;
			}
			return new Part
			{
				Name = mesh + "#" + spec,
				Pos = Take(m.Pos, 3),
				Normal = Take(m.Normal, 3),
				Uv = Take(m.Uv, 2),
				Index = source.SelectMany((int[] t) => t.Select((int i) => remap[i])).ToArray()
			};
			float[] Take(float[][] src, int dims)
			{
				return used.SelectMany((int i) => (src == null) ? new float[dims] : src[i].Take(dims)).ToArray();
			}
		}
	}
	internal static class Kitbash
	{
		[Serializable]
		internal class Piece
		{
			public string name;

			public string mesh;

			public string shape;

			p