Decompiled source of CartTrainLocomotives v0.2.7

plugins/CartTrainLocomotives/CartTrainLocomotives.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CartTrainLocomotives")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CartTrainLocomotives")]
[assembly: AssemblyTitle("CartTrainLocomotives")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 CartTrainLocomotives
{
	[BepInPlugin("CandyKane.CartTrainLocomotives", "CartTrain Locomotives", "0.2.7")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "CandyKane.CartTrainLocomotives";

		public const string PluginName = "CartTrain Locomotives";

		public const string PluginVersion = "0.2.7";

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> SnapDistance;

		internal static ConfigEntry<float> TowGap;

		internal static ConfigEntry<float> GrabStrength;

		internal static ConfigEntry<float> GrabDamping;

		internal static ConfigEntry<float> MaxGrabAcceleration;

		internal static ConfigEntry<float> MaxVerticalAcceleration;

		internal static ConfigEntry<float> VehicleRearPadding;

		internal static ConfigEntry<float> CartEndPadding;

		internal static ConfigEntry<float> MaxSnapAngle;

		internal static ConfigEntry<float> EmergencyBreakawayDistance;

		internal static ConfigEntry<float> CouplingGraceSeconds;

		internal static ConfigEntry<KeyCode> DetachKey;

		internal static ConfigEntry<bool> DebugLogging;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			SnapDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Coupling", "AutomaticSnapDistance", 1.5f, "Maximum rear-of-vehicle to nearest cart-end distance for automatic coupling.");
			TowGap = ((BaseUnityPlugin)this).Config.Bind<float>("Coupling", "TowGap", 0.18f, "Extra gap between the vehicle rear grab point and the cart handle/end.");
			MaxSnapAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Coupling", "MaximumSnapAngle", 85f, "Maximum alignment error allowed when snapping. Either end of the cart may attach.");
			EmergencyBreakawayDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Coupling", "EmergencyBreakawayDistance", 40f, "Safety-only distance at which a coupled cart is released. Normal driving should never reach this.");
			CouplingGraceSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Coupling", "CouplingGraceSeconds", 2.5f, "Seconds after coupling during which distance-based emergency breakaway is disabled.");
			VehicleRearPadding = ((BaseUnityPlugin)this).Config.Bind<float>("Anchors", "VehicleRearPadding", 0.1f, "Moves the cached vehicle rear anchor farther behind the vehicle.");
			CartEndPadding = ((BaseUnityPlugin)this).Config.Bind<float>("Anchors", "CartEndPadding", 0.08f, "Moves the cached cart coupling end outward.");
			GrabStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "GrabStrength", 18f, "Spring acceleration pulling the cart's selected end toward the vehicle's rear grab point.");
			GrabDamping = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "GrabDamping", 5.5f, "Damping against relative velocity at the virtual hand/cart handle connection.");
			MaxGrabAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "MaximumGrabAcceleration", 28f, "Maximum horizontal acceleration applied to the cart by the virtual hand.");
			MaxVerticalAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Physics", "MaximumVerticalAcceleration", 1.5f, "Maximum vertical correction. Kept intentionally low so the tow point cannot lift the cart or vehicle into ceilings.");
			DetachKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "DetachKey", (KeyCode)120, "Detach key. Hold Left Shift while pressing this key near a coupled locomotive/cart. This prevents accidental detaches from normal gameplay inputs.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Enable verbose logging.");
			_harmony = new Harmony("CandyKane.CartTrainLocomotives");
			_harmony.PatchAll();
			((Component)this).gameObject.AddComponent<LocomotiveManager>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CartTrain Locomotives 0.2.7 loaded. Optimized event-driven discovery enabled.");
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "Start")]
	internal static class CartStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysGrabCart __instance)
		{
			LocomotiveManager.RegisterCart(__instance);
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject), "Start")]
	internal static class PhysGrabObjectStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PhysGrabObject __instance)
		{
			LocomotiveManager.RegisterPotentialVehicle(__instance);
		}
	}
	internal sealed class LocomotiveManager : MonoBehaviour
	{
		private sealed class VehicleState
		{
			internal readonly PhysGrabObject Vehicle;

			internal readonly Rigidbody Body;

			internal readonly string DisplayName;

			internal readonly float HalfLength;

			internal PhysGrabCart? Cart;

			internal Rigidbody? CartBody;

			internal float CartEndSign = 1f;

			internal float CoupledAt;

			internal Vector3 RearAnchor => ((Component)Vehicle).transform.position - ((Component)Vehicle).transform.forward * (HalfLength + Plugin.VehicleRearPadding.Value);

			internal VehicleState(PhysGrabObject vehicle, Rigidbody body, string prefabName)
			{
				Vehicle = vehicle;
				Body = body;
				DisplayName = (prefabName.EndsWith(" Small", StringComparison.Ordinal) ? "Scout" : "Hauler");
				HalfLength = ComputeHalfLength(((Component)vehicle).gameObject, ((Component)vehicle).transform, 0.45f);
			}
		}

		private static LocomotiveManager? _instance;

		private static readonly HashSet<PhysGrabCart> Carts = new HashSet<PhysGrabCart>();

		private static readonly HashSet<PhysGrabCart> ClaimedFollowers = new HashSet<PhysGrabCart>();

		private static readonly Dictionary<PhysGrabCart, float> CartHalfLengths = new Dictionary<PhysGrabCart, float>();

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

		private float _nextFallbackScan;

		private float _nextCleanup;

		private void Awake()
		{
			_instance = this;
		}

		internal static void RegisterCart(PhysGrabCart cart)
		{
			if (!((Object)(object)cart == (Object)null))
			{
				Carts.Add(cart);
				if (!CartHalfLengths.ContainsKey(cart))
				{
					CartHalfLengths[cart] = ComputeHalfLength(((Component)cart).gameObject, ((Component)cart).transform, 0.35f);
				}
			}
		}

		internal static void RegisterPotentialVehicle(PhysGrabObject pgo)
		{
			if (!((Object)(object)_instance == (Object)null) && !((Object)(object)pgo == (Object)null))
			{
				_instance.TryRegisterVehicle(pgo);
			}
		}

		private void Update()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsAuthority())
			{
				return;
			}
			if (Time.unscaledTime >= _nextFallbackScan)
			{
				_nextFallbackScan = Time.unscaledTime + 5f;
				if (_vehicles.Count == 0)
				{
					FallbackDiscover();
				}
			}
			if (Time.unscaledTime >= _nextCleanup)
			{
				_nextCleanup = Time.unscaledTime + 3f;
				Cleanup();
			}
			if (Input.GetKey((KeyCode)304) && Input.GetKeyDown(Plugin.DetachKey.Value))
			{
				TryDetachNearest("manual Shift+" + ((object)Plugin.DetachKey.Value/*cast due to .constrained prefix*/).ToString());
			}
		}

		private void FixedUpdate()
		{
			if (!IsAuthority())
			{
				return;
			}
			foreach (VehicleState value in _vehicles.Values)
			{
				if (!((Object)(object)value.Vehicle == (Object)null) && !((Object)(object)value.Body == (Object)null))
				{
					if ((Object)(object)value.Cart == (Object)null)
					{
						TryAutoAttach(value);
					}
					else
					{
						DriveFollower(value);
					}
				}
			}
		}

		private void TryRegisterVehicle(PhysGrabObject pgo)
		{
			string text = CleanName(((Object)pgo).name);
			if (text != "Item Vehicle Semiscooter" && text != "Item Vehicle Semiscooter Small")
			{
				return;
			}
			int instanceID = ((Object)((Component)pgo).gameObject).GetInstanceID();
			if (!_vehicles.ContainsKey(instanceID))
			{
				Rigidbody val = (((Object)(object)pgo.rb != (Object)null) ? pgo.rb : ((Component)pgo).GetComponent<Rigidbody>());
				if (!((Object)(object)val == (Object)null))
				{
					_vehicles[instanceID] = new VehicleState(pgo, val, text);
					Plugin.Log.LogInfo((object)$"Tracking locomotive: {text} ({instanceID})");
				}
			}
		}

		private void FallbackDiscover()
		{
			PhysGrabObject[] array = Object.FindObjectsOfType<PhysGrabObject>();
			foreach (PhysGrabObject pgo in array)
			{
				TryRegisterVehicle(pgo);
			}
			PhysGrabCart[] array2 = Object.FindObjectsOfType<PhysGrabCart>();
			for (int i = 0; i < array2.Length; i++)
			{
				RegisterCart(array2[i]);
			}
		}

		private void Cleanup()
		{
			Carts.RemoveWhere((PhysGrabCart c) => (Object)(object)c == (Object)null);
			ClaimedFollowers.RemoveWhere((PhysGrabCart c) => (Object)(object)c == (Object)null);
			Dictionary<PhysGrabCart, float> dictionary = new Dictionary<PhysGrabCart, float>();
			foreach (KeyValuePair<PhysGrabCart, float> cartHalfLength in CartHalfLengths)
			{
				if ((Object)(object)cartHalfLength.Key != (Object)null)
				{
					dictionary[cartHalfLength.Key] = cartHalfLength.Value;
				}
			}
			CartHalfLengths.Clear();
			foreach (KeyValuePair<PhysGrabCart, float> item in dictionary)
			{
				CartHalfLengths[item.Key] = item.Value;
			}
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, VehicleState> vehicle in _vehicles)
			{
				if ((Object)(object)vehicle.Value.Vehicle == (Object)null)
				{
					list.Add(vehicle.Key);
				}
			}
			foreach (int item2 in list)
			{
				_vehicles.Remove(item2);
			}
		}

		private static void TryAutoAttach(VehicleState state)
		{
			//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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			Vector3 rearAnchor = state.RearAnchor;
			PhysGrabCart val = null;
			float num = Plugin.SnapDistance.Value;
			float cartEndSign = 1f;
			foreach (PhysGrabCart cart in Carts)
			{
				if ((Object)(object)cart == (Object)null || ClaimedFollowers.Contains(cart) || (Object)(object)((Component)cart).GetComponent<Rigidbody>() == (Object)null)
				{
					continue;
				}
				float cartHalfLength = GetCartHalfLength(cart);
				Vector3 val2 = ((Component)cart).transform.position + ((Component)cart).transform.forward * (cartHalfLength + Plugin.CartEndPadding.Value);
				Vector3 val3 = ((Component)cart).transform.position - ((Component)cart).transform.forward * (cartHalfLength + Plugin.CartEndPadding.Value);
				float num2 = Vector3.Distance(rearAnchor, val2);
				float num3 = Vector3.Distance(rearAnchor, val3);
				float num4 = ((num2 <= num3) ? 1f : (-1f));
				float num5 = Mathf.Min(num2, num3);
				if (!(num5 > num))
				{
					Vector3 val4 = Flat(((Component)cart).transform.forward * num4);
					if (!(Vector3.Angle(Flat(((Component)state.Vehicle).transform.forward), val4) > Plugin.MaxSnapAngle.Value))
					{
						val = cart;
						num = num5;
						cartEndSign = num4;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				Attach(state, val, cartEndSign);
			}
		}

		private static void Attach(VehicleState state, PhysGrabCart cart, float cartEndSign)
		{
			Rigidbody component = ((Component)cart).GetComponent<Rigidbody>();
			if (!((Object)(object)component == (Object)null))
			{
				state.Cart = cart;
				state.CartBody = component;
				state.CartEndSign = cartEndSign;
				state.CoupledAt = Time.time;
				ClaimedFollowers.Add(cart);
				Plugin.Log.LogInfo((object)$"Coupled {state.DisplayName} -> {((Object)cart).name} (end sign {cartEndSign:+0;-0}).");
			}
		}

		private static void Detach(VehicleState state, string reason = "unspecified")
		{
			if ((Object)(object)state.Cart != (Object)null)
			{
				ClaimedFollowers.Remove(state.Cart);
				Plugin.Log.LogInfo((object)("Detached " + state.DisplayName + " -> " + ((Object)state.Cart).name + " (reason: " + reason + ")"));
			}
			state.Cart = null;
			state.CartBody = null;
		}

		private static void DriveFollower(VehicleState state)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)state.Cart == (Object)null)
			{
				Detach(state, "cart destroyed/unloaded");
				return;
			}
			if ((Object)(object)state.CartBody == (Object)null)
			{
				state.CartBody = ((Component)state.Cart).GetComponent<Rigidbody>();
				if ((Object)(object)state.CartBody == (Object)null)
				{
					if (Plugin.DebugLogging.Value)
					{
						Plugin.Log.LogDebug((object)("Waiting for Rigidbody to return on " + ((Object)state.Cart).name + "; coupling retained."));
					}
					return;
				}
			}
			float num = Vector3.Distance(((Component)state.Vehicle).transform.position, ((Component)state.Cart).transform.position);
			if (Time.time - state.CoupledAt >= Plugin.CouplingGraceSeconds.Value && num > Plugin.EmergencyBreakawayDistance.Value)
			{
				Plugin.Log.LogWarning((object)$"Emergency breakaway: {state.DisplayName} -> {((Object)state.Cart).name} at {num:0.0}m.");
				Detach(state, $"emergency breakaway at {num:0.0}m");
				return;
			}
			Rigidbody? cartBody = state.CartBody;
			Vector3 val = CartEndAnchor(state.Cart, state.CartEndSign);
			Vector3 val2 = state.RearAnchor - ((Component)state.Vehicle).transform.forward * Plugin.TowGap.Value;
			Vector3 val3 = val2 - val;
			Vector3 pointVelocity = cartBody.GetPointVelocity(val);
			Vector3 val4 = state.Body.GetPointVelocity(val2) - pointVelocity;
			Vector3 val5 = new Vector3(val3.x, 0f, val3.z);
			Vector3 val6 = default(Vector3);
			((Vector3)(ref val6))..ctor(val4.x, 0f, val4.z);
			Vector3 val7 = Vector3.ClampMagnitude(val5 * Plugin.GrabStrength.Value + val6 * Plugin.GrabDamping.Value, Plugin.MaxGrabAcceleration.Value);
			float num2 = Mathf.Clamp(val3.y * (Plugin.GrabStrength.Value * 0.25f) + val4.y * (Plugin.GrabDamping.Value * 0.25f), 0f - Plugin.MaxVerticalAcceleration.Value, Plugin.MaxVerticalAcceleration.Value);
			Vector3 val8 = val7 + Vector3.up * num2;
			cartBody.AddForceAtPosition(val8, val, (ForceMode)5);
			if (Plugin.DebugLogging.Value && Time.frameCount % 120 == 0)
			{
				Plugin.Log.LogDebug((object)$"Virtual hand {state.DisplayName}: handle error={((Vector3)(ref val3)).magnitude:0.00}m, accel={((Vector3)(ref val8)).magnitude:0.0}, sign={state.CartEndSign:+0;-0}");
			}
		}

		private void TryDetachNearest(string reason)
		{
			//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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerController.instance == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)PlayerController.instance).transform.position;
			VehicleState vehicleState = null;
			float num = 3f;
			foreach (VehicleState value in _vehicles.Values)
			{
				if (!((Object)(object)value.Cart == (Object)null))
				{
					float num2 = Mathf.Min(Vector3.Distance(position, ((Component)value.Vehicle).transform.position), Vector3.Distance(position, ((Component)value.Cart).transform.position));
					if (num2 < num)
					{
						num = num2;
						vehicleState = value;
					}
				}
			}
			if (vehicleState != null)
			{
				Detach(vehicleState, reason);
			}
		}

		private static float GetCartHalfLength(PhysGrabCart cart)
		{
			if (!CartHalfLengths.TryGetValue(cart, out var value))
			{
				value = ComputeHalfLength(((Component)cart).gameObject, ((Component)cart).transform, 0.35f);
				CartHalfLengths[cart] = value;
			}
			return value;
		}

		private static Vector3 CartEndAnchor(PhysGrabCart cart, float sign)
		{
			//IL_0006: 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_0017: 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)
			return ((Component)cart).transform.position + ((Component)cart).transform.forward * sign * (GetCartHalfLength(cart) + Plugin.CartEndPadding.Value);
		}

		private static float ComputeHalfLength(GameObject go, Transform t, float fallback)
		{
			//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_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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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)
			Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>();
			if (componentsInChildren.Length == 0)
			{
				return fallback;
			}
			float num = 0f;
			float num2 = 0f;
			Vector3 position = t.position;
			Vector3 forward = t.forward;
			Vector3 normalized = ((Vector3)(ref forward)).normalized;
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Bounds bounds = val.bounds;
					Vector3 extents = ((Bounds)(ref bounds)).extents;
					float num3 = Vector3.Dot(((Bounds)(ref bounds)).center - position, normalized);
					float num4 = Mathf.Abs(normalized.x) * extents.x + Mathf.Abs(normalized.y) * extents.y + Mathf.Abs(normalized.z) * extents.z;
					num = Mathf.Min(num, num3 - num4);
					num2 = Mathf.Max(num2, num3 + num4);
				}
			}
			return Mathf.Max(fallback, Mathf.Max(Mathf.Abs(num), Mathf.Abs(num2)));
		}

		private static bool IsAuthority()
		{
			try
			{
				return SemiFunc.IsMasterClientOrSingleplayer();
			}
			catch
			{
				return true;
			}
		}

		private static string CleanName(string name)
		{
			if (!string.IsNullOrEmpty(name))
			{
				return name.Replace("Valuable ", string.Empty).Replace("(Clone)", string.Empty).Trim();
			}
			return string.Empty;
		}

		private static Vector3 Flat(Vector3 v)
		{
			//IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.x, 0f, v.z);
		}
	}
}