Decompiled source of CruiserImproved v1.4.1

BepInEx/plugins/CruiserImproved/DiggC.CruiserImproved.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using CruiserImproved.Network;
using CruiserImproved.Patches;
using CruiserImproved.Utils;
using GameNetcodeStuff;
using HarmonyLib;
using LCVR.Player;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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("DiggC.CruiserImproved")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1+6159533fee9c5748ef667067a9cbb66ba5fa6237")]
[assembly: AssemblyProduct("CruiserImproved")]
[assembly: AssemblyTitle("DiggC.CruiserImproved")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 CruiserImproved
{
	internal static class LCVRCompatibility
	{
		public static string modGUID = "io.daxcess.lcvr";

		private static bool? _enabled;

		public static bool modEnabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey(modGUID);
				}
				return _enabled.Value;
			}
		}

		public static bool inVrSession
		{
			get
			{
				if (modEnabled)
				{
					return GetInVrSession();
				}
				return false;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static bool GetInVrSession()
		{
			return VRSession.InVR;
		}
	}
	[BepInPlugin("DiggC.CruiserImproved", "CruiserImproved", "1.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class CruiserImproved : BaseUnityPlugin
	{
		public static Version Version = new Version("1.4.1");

		public static CruiserImproved Instance;

		private Harmony harmony;

		public static void LogError(object data)
		{
			((BaseUnityPlugin)Instance).Logger.LogError(data);
		}

		public static void LogWarning(object data)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning(data);
		}

		public static void LogMessage(object data)
		{
			((BaseUnityPlugin)Instance).Logger.LogMessage(data);
		}

		public static void LogInfo(object data)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo(data);
		}

		[Conditional("DEBUG")]
		public static void LogDebug(object data)
		{
			((BaseUnityPlugin)Instance).Logger.LogDebug(data);
		}

		public void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Instance = this;
			harmony = new Harmony("DiggC.CruiserImproved");
			UserConfig.InitConfig();
			harmony.PatchAll();
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "DiggC.CruiserImproved";

		public const string PLUGIN_NAME = "CruiserImproved";

		public const string PLUGIN_VERSION = "1.4.1";
	}
}
namespace CruiserImproved.Utils
{
	public class NullMemberException : Exception
	{
		private NullMemberException(string message)
			: base(message)
		{
		}

		public static NullMemberException Method(Type type, string methodName, Type[] parameters = null, Type[] generics = null)
		{
			string text = "";
			string text2 = "";
			if (parameters != null && parameters.Length != 0)
			{
				text = string.Join(", ", parameters.Select((Type param) => param.ToString()));
			}
			if (generics != null && generics.Length != 0)
			{
				text2 = "<" + string.Join(", ", generics.Select((Type param) => param.ToString())) + ">";
			}
			return new NullMemberException("Could not find method " + type.Name + ":" + text2 + methodName + "(" + text + ")");
		}

		public static NullMemberException Field(Type type, string fieldName)
		{
			return new NullMemberException("Could not find field " + type.Name + "." + fieldName);
		}
	}
	internal static class PatchUtils
	{
		public struct OpcodeMatch
		{
			public OpCode opcode;

			public object operandOrNull;

			public OpcodeMatch(OpCode opcode)
			{
				operandOrNull = null;
				this.opcode = opcode;
			}

			public OpcodeMatch(OpCode opcode, object operand)
			{
				operandOrNull = null;
				this.opcode = opcode;
				operandOrNull = operand;
			}
		}

		public static bool OperandCompare(object inputOperand, object codeInstructionOperand)
		{
			if (inputOperand.Equals(codeInstructionOperand))
			{
				return true;
			}
			if (codeInstructionOperand.GetType() == typeof(LocalBuilder))
			{
				return inputOperand.Equals(((LocalBuilder)codeInstructionOperand).LocalIndex);
			}
			return Convert.ChangeType(inputOperand, codeInstructionOperand.GetType())?.Equals(codeInstructionOperand) ?? false;
		}

		public static int LocateCodeSegment(int startIndex, List<CodeInstruction> searchSpace, List<OpcodeMatch> searchFor)
		{
			if (startIndex < 0 || startIndex >= searchSpace.Count)
			{
				return -1;
			}
			int num = 0;
			for (int i = startIndex; i < searchSpace.Count; i++)
			{
				CodeInstruction val = searchSpace[i];
				OpcodeMatch opcodeMatch = searchFor[num];
				bool flag = val.opcode == opcodeMatch.opcode;
				if (flag && opcodeMatch.operandOrNull != null)
				{
					flag = OperandCompare(opcodeMatch.operandOrNull, val.operand);
				}
				if (flag)
				{
					num++;
					if (num == searchFor.Count)
					{
						return i - num + 1;
					}
				}
				else
				{
					num = 0;
				}
			}
			return -1;
		}

		public static string GetAllMaskLayers(LayerMask _mask)
		{
			int value = ((LayerMask)(ref _mask)).value;
			string text = "";
			for (int i = 0; i < 32; i++)
			{
				if (((1 << i) & value) != 0)
				{
					text = text + " " + LayerMask.LayerToName(i);
				}
			}
			return text;
		}

		public static bool TryMethod(Type type, string name, out MethodInfo methodInfo)
		{
			return TryMethod(type, name, null, null, out methodInfo);
		}

		public static bool TryMethod(Type type, string name, Type[] parameters, out MethodInfo methodInfo)
		{
			return TryMethod(type, name, parameters, null, out methodInfo);
		}

		public static bool TryMethod(Type type, string name, Type[] parameters, Type[] generics, out MethodInfo methodInfo)
		{
			if (parameters == null && generics == null)
			{
				methodInfo = type.GetMethod(name, AccessTools.all);
			}
			else
			{
				if (generics == null)
				{
					generics = Type.EmptyTypes;
				}
				if (parameters == null)
				{
					parameters = Type.EmptyTypes;
				}
				methodInfo = type.GetMethod(name, generics.Length, AccessTools.all, null, parameters, null);
				if (generics.Length != 0)
				{
					methodInfo = methodInfo.MakeGenericMethod(generics);
				}
			}
			return methodInfo != null;
		}

		public static MethodInfo Method(Type type, string name, Type[] parameters = null, Type[] generics = null)
		{
			if (!TryMethod(type, name, parameters, generics, out var methodInfo))
			{
				throw NullMemberException.Method(type, name, parameters, generics);
			}
			return methodInfo;
		}

		public static bool TryField(Type type, string name, out FieldInfo fieldInfo)
		{
			fieldInfo = AccessTools.Field(type, name);
			return fieldInfo != null;
		}

		public static FieldInfo Field(Type type, string name)
		{
			if (!TryField(type, name, out var fieldInfo))
			{
				throw NullMemberException.Field(type, name);
			}
			return fieldInfo;
		}
	}
	internal static class SaveManager
	{
		private static string SavePrefix = "CruiserImproved.";

		public static void Save<T>(string key, T data)
		{
			ES3.Save<T>(SavePrefix + key, data, GameNetworkManager.Instance.currentSaveFileName);
		}

		public static bool TryLoad<T>(string key, out T data)
		{
			if (!ES3.KeyExists(SavePrefix + key, GameNetworkManager.Instance.currentSaveFileName))
			{
				data = default(T);
				return false;
			}
			data = ES3.Load<T>(SavePrefix + key, GameNetworkManager.Instance.currentSaveFileName);
			return true;
		}

		public static void Delete(string key)
		{
			ES3.DeleteKey(SavePrefix + key, GameNetworkManager.Instance.currentSaveFileName);
		}
	}
	[Flags]
	public enum ScanNodeOptions
	{
		Enabled = 1,
		VisibleThroughWalls = 2,
		HealthEstimate = 4,
		HealthPercentage = 8,
		TurboEstimate = 0x10,
		TurboPercentage = 0x20
	}
	internal class UserConfig
	{
		internal static ConfigEntry<bool> AllowLean;

		internal static ConfigEntry<bool> PreventMissileKnockback;

		internal static ConfigEntry<bool> AllowPushDestroyedCar;

		internal static ConfigEntry<bool> SilentCollisions;

		internal static ConfigEntry<float> SeatBoostScale;

		internal static ConfigEntry<bool> DisableRadioStatic;

		internal static ConfigEntry<bool> TurboExhaust;

		internal static ConfigEntry<ScanNodeOptions> CruiserScanNode;

		internal static ConfigEntry<float> CruiserInvulnerabilityDuration;

		internal static ConfigEntry<float> CruiserCriticalInvulnerabilityDuration;

		internal static ConfigEntry<int> MaxCriticalHitCount;

		internal static ConfigEntry<bool> AntiSideslip;

		internal static ConfigEntry<bool> SyncSeat;

		internal static ConfigEntry<bool> PreventPassengersEjectingDriver;

		internal static ConfigEntry<bool> EntitiesAvoidCruiser;

		internal static ConfigEntry<bool> SortEquipmentOnLoad;

		internal static ConfigEntry<bool> SaveCruiserValues;

		internal static ConfigEntry<bool> HandsfreeDoors;

		internal static ConfigEntry<bool> StandingKeyRemoval;

		internal static Dictionary<ConfigDefinition, ConfigEntryBase> ConfigMigrations;

		internal static void InitConfig()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			ConfigFile config = ((BaseUnityPlugin)CruiserImproved.Instance).Config;
			RetrieveOldConfigFile(config);
			config.SaveOnConfigSet = false;
			AllowLean = config.Bind<bool>("General", "Allow Leaning", true, "If true, allow the player to look backward out the window or through the cabin window.");
			PreventMissileKnockback = config.Bind<bool>("General", "Prevent Missile Knockback", true, "If true, prevent the player being ejected from seats by Old Bird missile knockback.");
			AllowPushDestroyedCar = config.Bind<bool>("General", "Allow Pushing Destroyed Cruisers", true, "If true, allow players to push destroyed cruisers.");
			SilentCollisions = config.Bind<bool>("General", "Silent Collisions", true, "If true, entities hitting the Cruiser when it's engine is off will not make noise.\nThis means Eyeless Dogs will not get stuck in a loop attacking it, triggering noise, and attacking it again while the engine is off.");
			DisableRadioStatic = config.Bind<bool>("General", "Disable Radio Static", false, "If true, disable the radio interference static sound on the radio.");
			TurboExhaust = config.Bind<bool>("General", "Turbo Exhaust Smoke", true, "If true, the Cruiser's exhaust will be slightly tinted blue when at least one turbo boost is stored.");
			CruiserScanNode = config.Bind<ScanNodeOptions>("General", "Cruiser Scan Node", ScanNodeOptions.Enabled | ScanNodeOptions.VisibleThroughWalls | ScanNodeOptions.HealthEstimate, "Customize a scan node to easily find your Cruiser, like the scan nodes on the ship and the main entrance.\nCan display information according to values set. If multiple settings are specified for the same information, the most detailed is used.");
			AcceptableValueRange<float> val = new AcceptableValueRange<float>(0f, 1f);
			SeatBoostScale = config.Bind<float>("General", "Seat Boost Scale", 1f, new ConfigDescription("How much to boost the seat up? Set 0 to disable.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			AcceptableValueRange<float> val2 = new AcceptableValueRange<float>(0f, 2f);
			CruiserInvulnerabilityDuration = config.Bind<float>("Cruiser Health", "Cruiser Invulnerability Duration", 0.5f, new ConfigDescription("How long after taking damage is the Cruiser invulnerable for? Set 0 to disable.", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			AcceptableValueRange<float> val3 = new AcceptableValueRange<float>(0f, 6f);
			CruiserCriticalInvulnerabilityDuration = config.Bind<float>("Cruiser Health", "Cruiser Critical Invulnerability Duration", 4f, new ConfigDescription("How long after critical damage (engine on fire) is the Cruiser invulnerable for? Set 0 to disable.", (AcceptableValueBase)(object)val3, Array.Empty<object>()));
			AcceptableValueRange<int> val4 = new AcceptableValueRange<int>(0, 100);
			MaxCriticalHitCount = config.Bind<int>("Cruiser Health", "Critical Protection Hit Count", 1, new ConfigDescription("Number of hits the Cruiser can block during the Critical Invulnerability Duration. \nIf the Cruiser receives this many hits while critical, it will emit a sound cue before exploding once the duration is up.\nIf 0, any hit that triggers the critical state will also trigger this delayed explosion.", (AcceptableValueBase)(object)val4, Array.Empty<object>()));
			AntiSideslip = config.Bind<bool>("Physics", "Anti-Sideslip", true, "If true, prevent the Cruiser from sliding sideways when on slopes.");
			SyncSeat = config.Bind<bool>("Host-side", "Synchronise Seat Boost", false, "If true, set all other players using CruiserImproved in your lobbies to have the same Seat Boost Scale setting as you.\nAll other settings are always synchronised.");
			EntitiesAvoidCruiser = config.Bind<bool>("Host-side", "Entities Avoid Cruiser", true, "If true, entities will pathfind around stationary cruisers with no driver.\nEyeless Dogs will still attack it if they hear noise!");
			PreventPassengersEjectingDriver = config.Bind<bool>("Host-side", "Prevent Passengers Eject Driver", false, "If true, prevent anyone except the driver of the cruiser from using the eject button in your lobbies.");
			SortEquipmentOnLoad = config.Bind<bool>("Host-side", "Sort Equipment On Load", true, "If true, equipment and weapons will be separated from other scrap when items are moved out of the Cruiser on save load.\nThese items will be placed in a second pile in the center of the ship.");
			SaveCruiserValues = config.Bind<bool>("Host-side", "Save Cruiser Values", true, "If true, the Cruiser's turbo count, ignition state, and magnet position will be saved to/loaded from the save file.");
			HandsfreeDoors = config.Bind<bool>("Quality of Life", "Handsfree Doors", true, "If true, allow opening the Cruiser's back and side doors when holding a 2 handed item.");
			StandingKeyRemoval = config.Bind<bool>("Quality of Life", "Standing Key Removal", true, "If true, allow the removal of the key from the ignition when not seated.");
			MigrateOldConfigs(config);
			config.Save();
			config.SaveOnConfigSet = true;
		}

		private static void RetrieveOldConfigFile(ConfigFile config)
		{
			string text = Path.Combine(Paths.ConfigPath, "DiggC.CompanyCruiserImproved.cfg");
			if (File.Exists(text))
			{
				File.Copy(text, config.ConfigFilePath, overwrite: true);
				File.Delete(text);
				config.Reload();
				CruiserImproved.LogMessage("Successfuly renamed old config file.");
			}
		}

		private static void MigrateOldConfigs(ConfigFile config)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			ConfigMigrations = new Dictionary<ConfigDefinition, ConfigEntryBase>
			{
				{
					new ConfigDefinition("General", "Prevent Passengers Eject Driver"),
					(ConfigEntryBase)(object)PreventPassengersEjectingDriver
				},
				{
					new ConfigDefinition("General", "Entities Avoid Cruiser"),
					(ConfigEntryBase)(object)EntitiesAvoidCruiser
				}
			};
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(config);
			foreach (KeyValuePair<ConfigDefinition, string> item in dictionary)
			{
				if (ConfigMigrations.TryGetValue(item.Key, out var value))
				{
					CruiserImproved.LogMessage("Migrated old config " + ((object)item.Key)?.ToString() + " : " + item.Value);
					value.SetSerializedValue(item.Value);
				}
			}
			dictionary.Clear();
		}
	}
}
namespace CruiserImproved.Patches
{
	[HarmonyPatch(typeof(BaboonBirdAI))]
	internal class BaboonBirdAIPatches
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix(BaboonBirdAI __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)__instance).enemyType.SizeLimit = (NavSizeLimit)0;
		}
	}
	[HarmonyPatch(typeof(ElevatorAnimationEvents))]
	internal class ElevatorAnimationEventsPatches
	{
		[HarmonyPatch("ElevatorFullyRunning")]
		[HarmonyPrefix]
		private static void ElevatorFullyRunning_Prefix()
		{
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!((Object)(object)localPlayerController.physicsParent == (Object)null))
			{
				VehicleController componentInParent = ((Component)localPlayerController.physicsParent).GetComponentInParent<VehicleController>();
				if (Object.op_Implicit((Object)(object)componentInParent) && componentInParent.magnetedToShip)
				{
					localPlayerController.isInElevator = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatches
	{
		[HarmonyPatch("SaveItemsInShip")]
		[HarmonyPostfix]
		private static void SaveItemsInShip_Postfix(GameNetworkManager __instance)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (UserConfig.SaveCruiserValues.Value && Object.op_Implicit((Object)(object)StartOfRound.Instance.attachedVehicle))
				{
					VehicleController attachedVehicle = StartOfRound.Instance.attachedVehicle;
					SaveManager.Save<Vector3>("AttachedVehicleRotation", ((Quaternion)(ref attachedVehicle.magnetTargetRotation)).eulerAngles);
					SaveManager.Save<Vector3>("AttachedVehiclePosition", attachedVehicle.magnetTargetPosition);
					SaveManager.Save("AttachedVehicleTurbo", attachedVehicle.turboBoosts);
					SaveManager.Save("AttachedVehicleIgnition", attachedVehicle.ignitionStarted);
					CruiserImproved.LogMessage("Successfully saved cruiser data.");
				}
				else
				{
					SaveManager.Delete("AttachedVehicleRotation");
					SaveManager.Delete("AttachedVehiclePosition");
					SaveManager.Delete("AttachedVehicleTurbo");
					SaveManager.Delete("AttachedVehicleIgnition");
				}
			}
			catch (Exception ex)
			{
				CruiserImproved.LogError("Exception caught saving Cruiser data:\n" + ex);
			}
		}
	}
	[HarmonyPatch(typeof(Landmine))]
	internal class LandminePatches
	{
		private static MethodInfo get_magnitude = PatchUtils.Method(typeof(Vector3), "get_magnitude");

		private static bool ShouldNotDealKnockback(PlayerControllerB instance)
		{
			if (NetworkSync.Config.PreventMissileKnockback)
			{
				return instance.inVehicleAnimation;
			}
			return false;
		}

		[HarmonyPatch("SpawnExplosion")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> SpawnExplosion_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(7)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldloca_S, 16),
				new PatchUtils.OpcodeMatch(OpCodes.Call, get_magnitude),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_R4, 2),
				new PatchUtils.OpcodeMatch(OpCodes.Ble_Un),
				new PatchUtils.OpcodeMatch(OpCodes.Ldloca_S, 16),
				new PatchUtils.OpcodeMatch(OpCodes.Call, get_magnitude),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_R4, 10)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not patch landmine knockback vehicle check!");
				return list;
			}
			object operand = list[num + 3].operand;
			list.InsertRange(num + 4, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldloc_S, (object)4),
				new CodeInstruction(OpCodes.Call, (object)PatchUtils.Method(typeof(LandminePatches), "ShouldNotDealKnockback")),
				new CodeInstruction(OpCodes.Brtrue_S, operand)
			}));
			return list;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Update_Postfix(PlayerControllerB __instance)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0087: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (LCVRCompatibility.inVrSession || (!NetworkSync.Config.AllowLean && !(NetworkSync.Config.SeatBoostScale > 0f)))
			{
				return;
			}
			Vector3 localPosition = Vector3.zero;
			if (__instance.inVehicleAnimation)
			{
				localPosition = new Vector3(0f, 0.25f, -0.05f) * NetworkSync.Config.SeatBoostScale;
				Vector3 val = ((Component)__instance.gameplayCamera).transform.localRotation * Vector3.forward;
				val.y = 0f;
				float num = Vector3.Angle(val, Vector3.back);
				if (num < 70f && NetworkSync.Config.AllowLean)
				{
					localPosition.x = Mathf.Sign(val.x) * ((70f - num) / 70f);
				}
			}
			((Component)__instance.gameplayCamera).transform.localPosition = localPosition;
		}

		[HarmonyPatch("PlaceGrabbableObject")]
		[HarmonyPostfix]
		private static void PlaceGrabbableObject_Postfix(GrabbableObject placeObject)
		{
			ScanNodeProperties componentInChildren = ((Component)placeObject).GetComponentInChildren<ScanNodeProperties>();
			if (Object.op_Implicit((Object)(object)componentInChildren) && !Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<Rigidbody>()))
			{
				((Component)componentInChildren).gameObject.AddComponent<Rigidbody>().isKinematic = true;
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatches
	{
		private static void SetItemPosition(StartOfRound instance, int index, Vector3[] positionArray, int[] itemArray)
		{
			if (!UserConfig.SortEquipmentOnLoad.Value)
			{
				return;
			}
			try
			{
				Item val = instance.allItemsList.itemsList[itemArray[index]];
				if (!val.isScrap || val.isDefensiveWeapon)
				{
					positionArray[index].z += Random.Range(-2.5f, -1.5f);
				}
			}
			catch (Exception ex)
			{
				CruiserImproved.LogError("Exception caught placing Cruiser items in ship:\n" + ex);
			}
		}

		[HarmonyPatch("LoadShipGrabbableItems")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> LoadShipGrabbableItems_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(1)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, PatchUtils.Field(typeof(StartOfRound), "shipBounds"))
			});
			if (num != -1)
			{
				list[num].operand = PatchUtils.Field(typeof(StartOfRound), "shipInnerRoomBounds");
			}
			else
			{
				num = 0;
				CruiserImproved.LogWarning("Could not patch LoadShipGrabbableItems bounds!");
			}
			num = PatchUtils.LocateCodeSegment(num, list, new List<PatchUtils.OpcodeMatch>(3)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, PatchUtils.Field(typeof(StartOfRound), "allItemsList")),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, PatchUtils.Field(typeof(AllItemsList), "itemsList"))
			});
			if (num != -1)
			{
				list.InsertRange(num, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[5]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_S, (object)9),
					new CodeInstruction(OpCodes.Ldloc_2, (object)null),
					new CodeInstruction(OpCodes.Ldloc_1, (object)null),
					new CodeInstruction(OpCodes.Call, (object)PatchUtils.Method(typeof(StartOfRoundPatches), "SetItemPosition"))
				}));
			}
			else
			{
				CruiserImproved.LogWarning("Could not patch LoadShipGrabbableItems sorting!");
			}
			return list;
		}

		[HarmonyPatch("LoadAttachedVehicle")]
		[HarmonyPostfix]
		private static void LoadAttachedVehicle_Postfix(StartOfRound __instance)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance.attachedVehicle))
			{
				return;
			}
			try
			{
				VehicleController attachedVehicle = __instance.attachedVehicle;
				((Component)attachedVehicle).transform.rotation = Quaternion.Euler(new Vector3(0f, 90f, 0f));
				_ = GameNetworkManager.Instance.currentSaveFileName;
				if (UserConfig.SaveCruiserValues.Value)
				{
					if (SaveManager.TryLoad<Vector3>("AttachedVehicleRotation", out var data))
					{
						((Component)attachedVehicle).transform.rotation = Quaternion.Euler(data);
					}
					if (SaveManager.TryLoad<Vector3>("AttachedVehiclePosition", out var data2))
					{
						((Component)attachedVehicle).transform.position = StartOfRound.Instance.elevatorTransform.TransformPoint(data2);
					}
					if (SaveManager.TryLoad<int>("AttachedVehicleTurbo", out var data3))
					{
						attachedVehicle.turboBoosts = data3;
					}
					if (SaveManager.TryLoad<bool>("AttachedVehicleIgnition", out var data4))
					{
						attachedVehicle.SetIgnition(data4);
					}
				}
			}
			catch (Exception ex)
			{
				CruiserImproved.LogError("Exception caught loading saved Cruiser data:\n" + ex);
			}
		}
	}
	[HarmonyPatch(typeof(VehicleCollisionTrigger))]
	internal class VehicleCollisionTriggerPatches
	{
		[HarmonyPatch("OnTriggerEnter")]
		[HarmonyPrefix]
		private static bool OnTriggerEnter_Prefix(VehicleCollisionTrigger __instance, Collider other)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.mainScript.hasBeenSpawned)
			{
				return true;
			}
			if (__instance.mainScript.magnetedToShip && __instance.mainScript.magnetTime > 0.8f)
			{
				return true;
			}
			VehicleControllerPatches.VehicleControllerData vehicleControllerData = VehicleControllerPatches.vehicleData[__instance.mainScript];
			PlayerControllerB componentInParent;
			if (((Component)other).CompareTag("Player") && Object.op_Implicit((Object)(object)(componentInParent = ((Component)other).GetComponentInParent<PlayerControllerB>())))
			{
				Transform physicsTransform = __instance.mainScript.physicsRegion.physicsTransform;
				if ((Object)(object)componentInParent.physicsParent == (Object)(object)physicsTransform || (Object)(object)componentInParent.overridePhysicsParent == (Object)(object)physicsTransform)
				{
					return false;
				}
				return true;
			}
			EnemyAICollisionDetect componentInParent2;
			if (((Component)other).CompareTag("Enemy") && Object.op_Implicit((Object)(object)(componentInParent2 = ((Component)other).GetComponentInParent<EnemyAICollisionDetect>())))
			{
				if (!Object.op_Implicit((Object)(object)componentInParent2.mainScript) || !Object.op_Implicit((Object)(object)componentInParent2.mainScript.agent) || !Object.op_Implicit(componentInParent2.mainScript.agent.navMeshOwner))
				{
					return true;
				}
				if (NetworkSync.Config.EntitiesAvoidCruiser)
				{
					EnemyAI mainScript = componentInParent2.mainScript;
					MouthDogAI val = (MouthDogAI)(object)((mainScript is MouthDogAI) ? mainScript : null);
					if ((!Object.op_Implicit((Object)(object)val) || val.suspicionLevel <= 8) && ((Component)vehicleControllerData.navObstacle).gameObject.activeSelf)
					{
						return false;
					}
				}
				if (((Component)(Behaviour)componentInParent2.mainScript.agent.navMeshOwner).transform.IsChildOf(((Component)__instance.mainScript).transform))
				{
					return false;
				}
				if (!componentInParent2.mainScript.enemyType.canDie && (int)componentInParent2.mainScript.enemyType.SizeLimit == 0)
				{
					return false;
				}
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(VehicleController))]
	internal class VehicleControllerPatches
	{
		public class VehicleControllerData
		{
			public int lastDamageReceived;

			public float timeLastDamaged;

			public float timeLastCriticalDamage;

			public int hitsBlockedThisCrit;

			public Coroutine destroyCoroutine;

			public NavMeshObstacle navObstacle;

			public float lastSteeringAngle;

			public float timeLastSyncedRadio;

			public ScanNodeProperties scanNode;

			public int lastScanHP = -1;

			public int lastScanTurbo = -1;

			public bool usingColoredExhaust;

			public ParticleSystem particleSystemSwap;
		}

		private static readonly int CriticalThreshold = 2;

		private static readonly int ScanDamagedThreshold = 15;

		private static readonly int ScanCriticalThreshold = 5;

		private static readonly string DefaultScanText = "Company Cruiser";

		private static readonly string DefaultScanSubtext = "You've got work to do.";

		private static readonly string ScanDamagedText = "Damaged Cruiser";

		private static readonly string ScanCriticalText = "Critical Cruiser";

		private static readonly string ScanDestroyedText = "Destroyed Cruiser";

		private static readonly string ScanDetailedHealthText = "Company Cruiser ({0}%)";

		private static readonly string ScanTurboSubtext = "Turbocharged";

		private static readonly string ScanDetailedTurboSubtext = "{0}% Turbocharged";

		private static readonly string[] DestroyDisableList = new string[11]
		{
			"HPMeter", "TurboMeter", "Triggers/ButtonAnimContainer", "Meshes/FrontLight", "Meshes/GearStickContainer", "Meshes/SteeringWheelContainer", "Meshes/DriverSeatContainer", "Meshes/DoorLeftContainer", "Meshes/DoorRightContainer", "Meshes/FrontCabinLight",
			"Meshes/CabinWindowContainer"
		};

		public static Dictionary<VehicleController, VehicleControllerData> vehicleData = new Dictionary<VehicleController, VehicleControllerData>();

		private static void RemoveStaleVehicleData()
		{
			List<VehicleController> list = new List<VehicleController>();
			foreach (VehicleController key in vehicleData.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					list.Add(key);
				}
			}
			foreach (VehicleController item in list)
			{
				vehicleData.Remove(item);
			}
		}

		private static void SetupSyncedVehicleFeatures(VehicleController vehicle)
		{
			//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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			VehicleControllerData vehicleControllerData = vehicleData[vehicle];
			if (NetworkSync.Config.AllowLean)
			{
				vehicle.driverSeatTrigger.horizontalClamp = 163f;
				vehicle.passengerSeatTrigger.horizontalClamp = 163f;
			}
			if (NetworkSync.SyncedWithHost && NetworkSync.Config.EntitiesAvoidCruiser)
			{
				GameObject val = new GameObject("CruiserObstacle");
				val.transform.localPosition = new Vector3(0f, -2f, 0f);
				val.transform.localScale = new Vector3(4f, -2f, 9f);
				NavMeshObstacle val2 = val.AddComponent<NavMeshObstacle>();
				val2.carveOnlyStationary = true;
				val2.carving = true;
				val2.shape = (NavMeshObstacleShape)1;
				vehicleControllerData.navObstacle = val2;
				val.transform.parent = ((Component)vehicle).transform;
			}
			if (NetworkSync.Config.HandsfreeDoors)
			{
				vehicle.driverSideDoorTrigger.twoHandedItemAllowed = true;
				vehicle.passengerSideDoorTrigger.twoHandedItemAllowed = true;
				CollectionExtensions.Do<InteractTrigger>((IEnumerable<InteractTrigger>)vehicle.backDoorContainer.GetComponentsInChildren<InteractTrigger>(), (Action<InteractTrigger>)delegate(InteractTrigger trigger)
				{
					trigger.twoHandedItemAllowed = true;
				});
			}
			if (NetworkSync.Config.CruiserScanNode.HasFlag(ScanNodeOptions.Enabled))
			{
				GameObject val3 = new GameObject("CruiserScanNode")
				{
					layer = LayerMask.NameToLayer("ScanNode")
				};
				val3.AddComponent<Rigidbody>().isKinematic = true;
				val3.AddComponent<BoxCollider>();
				ScanNodeProperties val4 = val3.AddComponent<ScanNodeProperties>();
				val4.requiresLineOfSight = !NetworkSync.Config.CruiserScanNode.HasFlag(ScanNodeOptions.VisibleThroughWalls);
				val4.maxRange = 100;
				val4.minRange = 6;
				val4.headerText = DefaultScanText;
				val4.subText = DefaultScanSubtext;
				vehicleControllerData.scanNode = val4;
				val3.transform.parent = ((Component)vehicle).transform;
				val3.transform.localPosition = Vector3.zero;
				UpdateCruiserScanText(vehicle);
			}
			if (NetworkSync.Config.TurboExhaust)
			{
				vehicleControllerData.particleSystemSwap = Object.Instantiate<ParticleSystem>(vehicle.carExhaustParticle, ((Component)vehicle).transform);
				((Object)vehicleControllerData.particleSystemSwap).name = "Turbo Exhaust";
				ColorOverLifetimeModule colorOverLifetime = vehicleControllerData.particleSystemSwap.colorOverLifetime;
				MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
				GradientColorKey[] colorKeys = ((MinMaxGradient)(ref color)).gradient.colorKeys;
				colorKeys[0].color = new Color(0.17f, 0.17f, 0.3f);
				colorKeys[0].time = 0.3f;
				colorKeys[1].time = 0.7f;
				MinMaxGradient color2 = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
				((MinMaxGradient)(ref color2)).gradient.SetKeys(colorKeys, ((MinMaxGradient)(ref color2)).gradient.alphaKeys);
				((ColorOverLifetimeModule)(ref colorOverLifetime)).color = color2;
			}
		}

		public static void UpdateCruiserScanText(VehicleController vehicle, bool forceUpdate = false)
		{
			VehicleControllerData vehicleControllerData = vehicleData[vehicle];
			if (vehicleControllerData == null || !Object.op_Implicit((Object)(object)vehicleControllerData.scanNode) || (vehicleControllerData.lastScanTurbo == vehicle.turboBoosts && vehicleControllerData.lastScanHP == vehicle.carHP && !forceUpdate))
			{
				return;
			}
			vehicleControllerData.lastScanTurbo = vehicle.turboBoosts;
			vehicleControllerData.lastScanHP = vehicle.carHP;
			ScanNodeProperties scanNode = vehicleControllerData.scanNode;
			ScanNodeOptions cruiserScanNode = NetworkSync.Config.CruiserScanNode;
			bool num = (cruiserScanNode & (ScanNodeOptions.TurboEstimate | ScanNodeOptions.TurboPercentage)) != 0;
			bool flag = (cruiserScanNode & (ScanNodeOptions.HealthEstimate | ScanNodeOptions.HealthPercentage)) != 0;
			bool flag2 = cruiserScanNode.HasFlag(ScanNodeOptions.TurboPercentage);
			bool flag3 = cruiserScanNode.HasFlag(ScanNodeOptions.HealthPercentage);
			if (!num || vehicle.turboBoosts == 0)
			{
				scanNode.subText = DefaultScanSubtext;
			}
			else if (!flag2)
			{
				scanNode.subText = ScanTurboSubtext;
			}
			else
			{
				int num2 = vehicle.turboBoosts * 100 / 5;
				scanNode.subText = string.Format(ScanDetailedTurboSubtext, num2);
			}
			if (flag)
			{
				if (vehicle.carDestroyed || vehicle.carHP <= 0)
				{
					scanNode.headerText = ScanDestroyedText;
					scanNode.subText = "";
				}
				else if (flag3)
				{
					int num3 = vehicle.carHP * 100 / vehicle.baseCarHP;
					scanNode.headerText = string.Format(ScanDetailedHealthText, num3);
				}
				else if (vehicle.carHP < ScanCriticalThreshold)
				{
					scanNode.headerText = ScanCriticalText;
				}
				else if (vehicle.carHP < ScanDamagedThreshold)
				{
					scanNode.headerText = ScanDamagedText;
				}
				else
				{
					scanNode.headerText = DefaultScanText;
				}
			}
		}

		private static void UpdateExhaustColor(VehicleController vehicle)
		{
			VehicleControllerData vehicleControllerData = vehicleData[vehicle];
			bool flag = vehicle.turboBoosts > 0;
			if (flag != vehicleControllerData.usingColoredExhaust && Object.op_Implicit((Object)(object)vehicleControllerData.particleSystemSwap))
			{
				vehicleControllerData.usingColoredExhaust = flag;
				bool isPlaying = vehicle.carExhaustParticle.isPlaying;
				vehicle.carExhaustParticle.Stop(true, (ParticleSystemStopBehavior)1);
				ParticleSystem carExhaustParticle = vehicle.carExhaustParticle;
				ParticleSystem particleSystemSwap = vehicleControllerData.particleSystemSwap;
				vehicleControllerData.particleSystemSwap = carExhaustParticle;
				vehicle.carExhaustParticle = particleSystemSwap;
				if (isPlaying)
				{
					vehicle.carExhaustParticle.Play();
				}
			}
		}

		public static void OnSync()
		{
			RemoveStaleVehicleData();
			foreach (KeyValuePair<VehicleController, VehicleControllerData> vehicleDatum in vehicleData)
			{
				try
				{
					SetupSyncedVehicleFeatures(vehicleDatum.Key);
				}
				catch (Exception ex)
				{
					CruiserImproved.LogError("Exception caught setting up synced vehicle features:\n" + ex);
				}
			}
		}

		public static void SendClientSyncData(ulong clientId)
		{
			RemoveStaleVehicleData();
			foreach (KeyValuePair<VehicleController, VehicleControllerData> vehicleDatum in vehicleData)
			{
				VehicleController vehicle = vehicleDatum.Key;
				if (vehicle.turboBoosts > 0)
				{
					RpcSender.SendClientRpc((NetworkBehaviour)(object)vehicle, 4268487771u, new <>z__ReadOnlySingleElementList<ulong>(clientId), delegate(ref FastBufferWriter fastBufferWriter)
					{
						//IL_0001: 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)
						BytePacker.WriteValueBitPacked(fastBufferWriter, 0);
						BytePacker.WriteValueBitPacked(fastBufferWriter, vehicle.turboBoosts);
					});
				}
				if (vehicle.ignitionStarted)
				{
					RpcSender.SendClientRpc((NetworkBehaviour)(object)vehicle, 3273216474u, new <>z__ReadOnlySingleElementList<ulong>(clientId), delegate(ref FastBufferWriter fastBufferWriter)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						BytePacker.WriteValueBitPacked(fastBufferWriter, 0);
					});
				}
				if (vehicle.magnetedToShip)
				{
					RpcSender.SendClientRpc((NetworkBehaviour)(object)vehicle, 2845017736u, new <>z__ReadOnlySingleElementList<ulong>(clientId), delegate(ref FastBufferWriter fastBufferWriter)
					{
						//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_002b: Unknown result type (might be due to invalid IL or missing references)
						((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe(ref vehicle.magnetTargetPosition);
						Vector3 eulerAngles = ((Quaternion)(ref vehicle.magnetTargetRotation)).eulerAngles;
						((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe(ref eulerAngles);
						BytePacker.WriteValueBitPacked(fastBufferWriter, 0);
					});
				}
			}
		}

		private static IEnumerator DestroyAfterSeconds(VehicleController __instance, float seconds)
		{
			VehicleControllerData extraData = vehicleData[__instance];
			yield return (object)new WaitForSeconds(seconds);
			__instance.DestroyCarServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
			__instance.DestroyCar();
			extraData.destroyCoroutine = null;
		}

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void Awake_Postfix(VehicleController __instance)
		{
			//IL_007e: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			RemoveStaleVehicleData();
			VehicleControllerData value = new VehicleControllerData();
			vehicleData.Add(__instance, value);
			Transform[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Transform>();
			int num = LayerMask.NameToLayer("MoldSpore");
			int layer = LayerMask.NameToLayer("Triggers");
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if (((Component)val).gameObject.layer == num)
				{
					((Component)val).gameObject.layer = layer;
				}
			}
			Transform transform = ((Component)__instance.physicsRegion.itemDropCollider).transform;
			transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y, 5f);
			if (NetworkSync.FinishedSync)
			{
				SetupSyncedVehicleFeatures(__instance);
			}
		}

		[HarmonyPatch("FixedUpdate")]
		[HarmonyPostfix]
		private static void FixedUpdate_Postfix(VehicleController __instance)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00ce: 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_00d4: 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_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_00ec: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Invalid comparison between Unknown and I4
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (!NetworkSync.Config.AntiSideslip)
			{
				return;
			}
			List<WheelCollider> obj = new List<WheelCollider>(4) { __instance.FrontLeftWheel, __instance.FrontRightWheel, __instance.BackLeftWheel, __instance.BackRightWheel };
			Vector3 val = Vector3.zero;
			int num = 0;
			WheelHit val2 = default(WheelHit);
			foreach (WheelCollider item in obj)
			{
				if (item.GetGroundHit(ref val2))
				{
					val += ((WheelHit)(ref val2)).normal;
					num++;
				}
			}
			val = ((Vector3)(ref val)).normalized;
			if (num >= 3 && !(Vector3.Angle(-val, Physics.gravity) > 30f))
			{
				Vector3 val3 = Vector3.ProjectOnPlane(((Component)__instance).transform.forward, val);
				Vector3 normalized = ((Vector3)(ref val3)).normalized;
				Vector3 val4 = -val;
				val3 = Physics.gravity;
				Vector3 val5 = val4 * ((Vector3)(ref val3)).magnitude - Physics.gravity;
				if ((int)__instance.gear != 3)
				{
					val5 = Vector3.ProjectOnPlane(val5, normalized);
				}
				__instance.mainRigidbody.AddForce(val5, (ForceMode)5);
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void Update_Postfix(VehicleController __instance)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			if (!((NetworkBehaviour)__instance).IsSpawned)
			{
				return;
			}
			VehicleControllerData vehicleControllerData = vehicleData[__instance];
			UpdateCruiserScanText(__instance);
			UpdateExhaustColor(__instance);
			if (NetworkSync.Config.DisableRadioStatic)
			{
				__instance.radioSignalQuality = 3f;
			}
			if (((NetworkBehaviour)__instance).IsHost && Time.realtimeSinceStartup - vehicleControllerData.timeLastSyncedRadio > 1f)
			{
				vehicleControllerData.timeLastSyncedRadio = Time.realtimeSinceStartup;
				FastBufferWriter buffer = default(FastBufferWriter);
				((FastBufferWriter)(ref buffer))..ctor(16, (Allocator)2, -1);
				NetworkObjectReference val = new NetworkObjectReference(((NetworkBehaviour)__instance).NetworkObject);
				((FastBufferWriter)(ref buffer)).WriteValue<NetworkObjectReference>(ref val, default(ForNetworkSerializable));
				((FastBufferWriter)(ref buffer)).WriteValue<float>(ref __instance.currentSongTime, default(ForPrimitives));
				NetworkSync.SendToClients("SyncRadioTimeRpc", ref buffer);
			}
			if (__instance.finishedMagneting)
			{
				__instance.loadedVehicleFromSave = false;
			}
			if (__instance.magnetedToShip)
			{
				__instance.physicsRegion.priority = 1;
			}
			if ((vehicleControllerData.hitsBlockedThisCrit > NetworkSync.Config.MaxCriticalHitCount && __instance.carHP == 1) || vehicleControllerData.destroyCoroutine != null)
			{
				__instance.underExtremeStress = true;
				if (((NetworkBehaviour)__instance).IsOwner && vehicleControllerData.destroyCoroutine == null && !__instance.carDestroyed)
				{
					float seconds = NetworkSync.Config.CruiserCriticalInvulnerabilityDuration - (Time.realtimeSinceStartup - vehicleControllerData.timeLastCriticalDamage);
					vehicleControllerData.destroyCoroutine = ((MonoBehaviour)__instance).StartCoroutine(DestroyAfterSeconds(__instance, seconds));
				}
			}
			if (NetworkSync.Config.EntitiesAvoidCruiser && Object.op_Implicit((Object)(object)vehicleControllerData.navObstacle))
			{
				bool active = ((Vector3)(ref __instance.averageVelocity)).magnitude < 0.5f && !Object.op_Implicit((Object)(object)__instance.currentDriver) && !Object.op_Implicit((Object)(object)__instance.currentPassenger);
				((Component)vehicleControllerData.navObstacle).gameObject.SetActive(active);
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(6)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, PatchUtils.Field(typeof(VehicleController), "localPlayerInControl")),
				new PatchUtils.OpcodeMatch(OpCodes.Brfalse),
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Call, PatchUtils.Method(typeof(NetworkBehaviour), "get_IsOwner")),
				new PatchUtils.OpcodeMatch(OpCodes.Brtrue)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not transpile VehicleController.Update");
				return list;
			}
			list[num + 3].labels.AddRange(list[num].labels);
			list.RemoveRange(num, 3);
			return list;
		}

		[HarmonyPatch("DealPermanentDamage")]
		[HarmonyPrefix]
		private static void DealPermanentDamage_Prefix(VehicleController __instance, ref int damageAmount, Vector3 damagePosition)
		{
			if (((Object)(object)StartOfRound.Instance.testRoom == (Object)null && StartOfRound.Instance.inShipPhase) || __instance.carDestroyed || !((NetworkBehaviour)__instance).IsOwner)
			{
				return;
			}
			int num = damageAmount;
			VehicleControllerData vehicleControllerData = vehicleData[__instance];
			float num2 = Time.realtimeSinceStartup - vehicleControllerData.timeLastDamaged;
			float num3 = Time.realtimeSinceStartup - vehicleControllerData.timeLastCriticalDamage;
			float cruiserInvulnerabilityDuration = NetworkSync.Config.CruiserInvulnerabilityDuration;
			float cruiserCriticalInvulnerabilityDuration = NetworkSync.Config.CruiserCriticalInvulnerabilityDuration;
			bool flag = num2 < cruiserInvulnerabilityDuration;
			bool flag2 = num3 < cruiserCriticalInvulnerabilityDuration;
			if (flag && vehicleControllerData.lastDamageReceived >= damageAmount)
			{
				CruiserImproved.LogInfo($"Vehicle ignored {damageAmount} damage due to I-frames from previous damage {vehicleControllerData.lastDamageReceived} ({Math.Round(num2, 2)}s)");
				damageAmount = 0;
				return;
			}
			if (flag && vehicleControllerData.lastDamageReceived > 0)
			{
				damageAmount -= vehicleControllerData.lastDamageReceived;
				CruiserImproved.LogInfo($"Vehicle reduced {num} to {damageAmount} due to I-frames from previous damage {vehicleControllerData.lastDamageReceived} ({Math.Round(num2, 2)}s)");
			}
			if (!flag2)
			{
				vehicleControllerData.lastDamageReceived = num;
				vehicleControllerData.timeLastDamaged = Time.realtimeSinceStartup;
			}
			if (__instance.carHP - damageAmount > CriticalThreshold)
			{
				return;
			}
			float num4 = damageAmount;
			bool flag3 = false;
			if (__instance.carHP > CriticalThreshold)
			{
				flag3 = true;
				vehicleControllerData.timeLastCriticalDamage = Time.realtimeSinceStartup;
				vehicleControllerData.hitsBlockedThisCrit = 0;
				num3 = 0f;
			}
			if (!(num3 < cruiserCriticalInvulnerabilityDuration))
			{
				return;
			}
			damageAmount = Mathf.Min(damageAmount, __instance.carHP - 1);
			if (__instance.carHP - damageAmount == 1)
			{
				vehicleControllerData.hitsBlockedThisCrit++;
				if (vehicleControllerData.hitsBlockedThisCrit > NetworkSync.Config.MaxCriticalHitCount && vehicleControllerData.destroyCoroutine == null)
				{
					float seconds = NetworkSync.Config.CruiserCriticalInvulnerabilityDuration - (Time.realtimeSinceStartup - vehicleControllerData.timeLastCriticalDamage);
					vehicleControllerData.destroyCoroutine = ((MonoBehaviour)__instance).StartCoroutine(DestroyAfterSeconds(__instance, seconds));
				}
			}
			string arg = $"({vehicleControllerData.hitsBlockedThisCrit}/{NetworkSync.Config.MaxCriticalHitCount})";
			if (flag3)
			{
				CruiserImproved.LogInfo($"{arg} Critical protection triggered for {cruiserCriticalInvulnerabilityDuration}s due to {damageAmount} vehicle damage");
			}
			else
			{
				CruiserImproved.LogInfo($"{arg} Critical protection reduced vehicle damage from {num4} to {damageAmount}");
			}
		}

		[HarmonyPatch("DealDamageClientRpc")]
		[HarmonyPostfix]
		private static void DealDamageClientRpc_Postfix(VehicleController __instance, int amount, int sentByClient)
		{
			if ((int)GameNetworkManager.Instance.localPlayerController.playerClientId == sentByClient || amount <= 0)
			{
				return;
			}
			VehicleControllerData vehicleControllerData = vehicleData[__instance];
			if (__instance.carHP <= CriticalThreshold && __instance.carHP + amount > CriticalThreshold)
			{
				vehicleControllerData.timeLastCriticalDamage = Time.realtimeSinceStartup;
				vehicleControllerData.hitsBlockedThisCrit = 0;
			}
			float num = Time.realtimeSinceStartup - vehicleControllerData.timeLastDamaged;
			float num2 = Time.realtimeSinceStartup - vehicleControllerData.timeLastCriticalDamage;
			bool flag = num < NetworkSync.Config.CruiserInvulnerabilityDuration;
			bool flag2 = num2 < NetworkSync.Config.CruiserCriticalInvulnerabilityDuration;
			if (!flag && flag2 && __instance.carHP - amount == 1)
			{
				vehicleControllerData.hitsBlockedThisCrit++;
			}
			if (!flag2)
			{
				vehicleControllerData.timeLastDamaged = Time.realtimeSinceStartup;
				if (flag)
				{
					vehicleControllerData.lastDamageReceived += amount;
				}
				else
				{
					vehicleControllerData.lastDamageReceived = amount;
				}
			}
		}

		[HarmonyPatch("AddEngineOilOnLocalClient")]
		[HarmonyPostfix]
		private static void AddEngineOilOnLocalClient_Postfix(VehicleController __instance, int setCarHP)
		{
			if (setCarHP > 1)
			{
				VehicleControllerData vehicleControllerData = vehicleData[__instance];
				if (vehicleControllerData.destroyCoroutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(vehicleControllerData.destroyCoroutine);
					vehicleControllerData.destroyCoroutine = null;
					__instance.underExtremeStress = false;
				}
			}
		}

		[HarmonyPatch("DestroyCar")]
		[HarmonyPostfix]
		private static void DestroyCar_Postfix(VehicleController __instance)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			UpdateCruiserScanText(__instance, forceUpdate: true);
			__instance.carExhaustParticle.Stop(true, (ParticleSystemStopBehavior)1);
			string[] destroyDisableList = DestroyDisableList;
			foreach (string text in destroyDisableList)
			{
				Transform val = ((Component)__instance).transform.Find(text);
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
			if (!NetworkSync.Config.AllowPushDestroyedCar)
			{
				return;
			}
			foreach (Transform item in ((Component)__instance).transform)
			{
				Transform val2 = item;
				if (((Object)val2).name == "PushTrigger")
				{
					((Component)val2).GetComponent<InteractTrigger>().interactable = true;
					break;
				}
			}
		}

		[HarmonyPatch("GetVehicleInput")]
		[HarmonyPrefix]
		private static void GetVehicleInput_Prefix(VehicleController __instance)
		{
			//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)
			if (!__instance.localPlayerInControl)
			{
				__instance.drivePedalPressed = false;
				__instance.brakePedalPressed = false;
				__instance.moveInputVector = Vector2.zero;
			}
		}

		[HarmonyPatch("GetVehicleInput")]
		[HarmonyPostfix]
		private static void GetVehicleInput_Postfix(VehicleController __instance)
		{
			if (__instance.magnetedToShip)
			{
				__instance.brakePedalPressed = !__instance.drivePedalPressed;
			}
		}

		[HarmonyPatch("GetVehicleInput")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> GetVehicleInput_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			FieldInfo fieldInfo = PatchUtils.Field(typeof(VehicleController), "currentDriver");
			FieldInfo fieldInfo2 = PatchUtils.Field(typeof(PlayerControllerB), "isTypingChat");
			FieldInfo fieldInfo3 = PatchUtils.Field(typeof(PlayerControllerB), "quickMenuManager");
			FieldInfo fieldInfo4 = PatchUtils.Field(typeof(QuickMenuManager), "isMenuOpen");
			FieldInfo fieldInfo5 = PatchUtils.Field(typeof(VehicleController), "moveInputVector");
			FieldInfo fieldInfo6 = PatchUtils.Field(typeof(VehicleController), "steeringWheelTurnSpeed");
			if (fieldInfo == null || fieldInfo2 == null || fieldInfo3 == null || fieldInfo4 == null || fieldInfo5 == null || fieldInfo6 == null)
			{
				CruiserImproved.LogWarning("Could not find fields for VehicleInput transpiler!");
				return list;
			}
			MethodInfo methodInfo = PatchUtils.Method(typeof(Vector2), "get_zero");
			if (methodInfo == null)
			{
				CruiserImproved.LogWarning("Could not find vector method required for VehicleInput transpiler!");
				return list;
			}
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(3)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, fieldInfo6),
				new PatchUtils.OpcodeMatch(OpCodes.Stloc_0)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not find insertion point for VehicleInput transpiler!");
			}
			List<Label> labels = list[num].labels;
			Label label = il.DefineLabel();
			Label label2 = il.DefineLabel();
			list[num].labels = new List<Label>(1) { label };
			CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
			val.labels.Add(label2);
			list.InsertRange(num, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[12]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo2),
				new CodeInstruction(OpCodes.Brtrue_S, (object)label2),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo3),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo4),
				new CodeInstruction(OpCodes.Brfalse_S, (object)label),
				val,
				new CodeInstruction(OpCodes.Call, (object)methodInfo),
				new CodeInstruction(OpCodes.Stfld, (object)fieldInfo5)
			}));
			list[num].labels.AddRange(labels);
			return list;
		}

		[HarmonyPatch("DoTurboBoost")]
		[HarmonyPrefix]
		private static bool DoTurboBoost_Prefix(VehicleController __instance)
		{
			if (__instance.localPlayerInControl && Object.op_Implicit((Object)(object)__instance.currentDriver) && (__instance.currentDriver.isTypingChat || __instance.currentDriver.quickMenuManager.isMenuOpen))
			{
				return false;
			}
			return true;
		}

		private static void PatchSmallEntityCarKill(List<CodeInstruction> codes)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			int num = PatchUtils.LocateCodeSegment(0, codes, new List<PatchUtils.OpcodeMatch>(5)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_S, 5),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_R4, 1),
				new PatchUtils.OpcodeMatch(OpCodes.Bgt_Un),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ret)
			}) + 3;
			if (num == -1)
			{
				CruiserImproved.LogWarning("PatchSmallEntityCarKill: Failed to find ret code!");
				return;
			}
			int num2 = PatchUtils.LocateCodeSegment(num, codes, new List<PatchUtils.OpcodeMatch>(1)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Br)
			});
			if (num2 == -1)
			{
				CruiserImproved.LogWarning("PatchSmallEntityCarKill: Failed to find branch instruction!");
				return;
			}
			object operand = codes[num2].operand;
			codes.RemoveRange(num, 2);
			codes.InsertRange(num, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldc_R4, (object)1f),
				new CodeInstruction(OpCodes.Stloc_0, (object)null),
				new CodeInstruction(OpCodes.Br, operand)
			}));
		}

		private static void PatchLocalEntityDamage(List<CodeInstruction> codes)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			MethodInfo operand = PatchUtils.Method(typeof(EnemyAI), "HitEnemy");
			MethodInfo operand2 = PatchUtils.Method(typeof(EnemyAI), "HitEnemyOnLocalClient");
			MethodInfo methodInfo = PatchUtils.Method(typeof(Vector2), "get_zero");
			int num = PatchUtils.LocateCodeSegment(0, codes, new List<PatchUtils.OpcodeMatch>(5)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_1),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4),
				new PatchUtils.OpcodeMatch(OpCodes.Callvirt, operand)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("PatchLocalEntityDamage: Failed to find HitEnemy call!");
				return;
			}
			codes[num + 4].operand = operand2;
			codes.Insert(num, new CodeInstruction(OpCodes.Call, (object)methodInfo));
		}

		[HarmonyPatch("CarReactToObstacle")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CarReactToObstacle_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			PatchSmallEntityCarKill(list);
			PatchLocalEntityDamage(list);
			return list;
		}

		[HarmonyPatch("OnCollisionEnter")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> OnCollisionEnter_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			FieldInfo fieldInfo = PatchUtils.Field(typeof(VehicleController), "carHP");
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(4)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, fieldInfo),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_3),
				new PatchUtils.OpcodeMatch(OpCodes.Bge)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not patch VehicleController.OnCollisionEnter instakill!");
				return list;
			}
			int num2 = PatchUtils.LocateCodeSegment(num, list, new List<PatchUtils.OpcodeMatch>(1)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldloca_S, 4)
			});
			if (num2 == -1)
			{
				CruiserImproved.LogWarning("Could not locate VehicleController.OnCollisionEnter instakill patch end point!");
				return list;
			}
			list.RemoveRange(num, num2 - num);
			list.InsertRange(num, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[7]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo),
				new CodeInstruction(OpCodes.Ldc_I4_1, (object)null),
				new CodeInstruction(OpCodes.Sub, (object)null),
				new CodeInstruction(OpCodes.Ldc_I4_2, (object)null),
				new CodeInstruction(OpCodes.Call, (object)typeof(Math).GetMethod("Max", new Type[2]
				{
					typeof(int),
					typeof(int)
				}))
			}));
			return list;
		}

		public static void SyncSteeringRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_000f: 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_0051: 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_0064: 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)
			NetworkObjectReference val = default(NetworkObjectReference);
			((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref val);
			float lastSteeringAngle = default(float);
			((FastBufferReader)(ref reader)).ReadValue<float>(ref lastSteeringAngle, default(ForPrimitives));
			NetworkObject val2 = default(NetworkObject);
			VehicleController key = default(VehicleController);
			if (((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null) && ((Component)val2).TryGetComponent<VehicleController>(ref key))
			{
				if (NetworkManager.Singleton.IsHost)
				{
					FastBufferWriter buffer = default(FastBufferWriter);
					((FastBufferWriter)(ref buffer))..ctor(16, (Allocator)2, -1);
					((FastBufferWriter)(ref buffer)).WriteValue<NetworkObjectReference>(ref val, default(ForNetworkSerializable));
					((FastBufferWriter)(ref buffer)).WriteValue<float>(ref lastSteeringAngle, default(ForPrimitives));
					NetworkSync.SendToClients("SyncSteeringRpc", ref buffer);
				}
				vehicleData[key].lastSteeringAngle = lastSteeringAngle;
			}
		}

		[HarmonyPatch("SetCarEffects")]
		[HarmonyPrefix]
		private static void SetCarEffects_Prefix(VehicleController __instance, ref float setSteering)
		{
			//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_0064: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			setSteering = 0f;
			if (__instance.localPlayerInControl)
			{
				__instance.steeringWheelAnimFloat = __instance.steeringInput / 6f;
				if (Mathf.Abs(__instance.steeringInput - vehicleData[__instance].lastSteeringAngle) > 0.02f)
				{
					FastBufferWriter buffer = default(FastBufferWriter);
					((FastBufferWriter)(ref buffer))..ctor(16, (Allocator)2, -1);
					NetworkObjectReference val = new NetworkObjectReference(((NetworkBehaviour)__instance).NetworkObject);
					((FastBufferWriter)(ref buffer)).WriteValue<NetworkObjectReference>(ref val, default(ForNetworkSerializable));
					((FastBufferWriter)(ref buffer)).WriteValue<float>(ref __instance.steeringInput, default(ForPrimitives));
					NetworkSync.SendToHost("SyncSteeringRpc", buffer);
				}
			}
			else
			{
				__instance.steeringWheelAnimFloat = vehicleData[__instance].lastSteeringAngle / 6f;
				__instance.steeringInput = vehicleData[__instance].lastSteeringAngle;
			}
		}

		[HarmonyPatch("SetCarEffects")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> SetCarEffects_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(5)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Ldfld, PatchUtils.Field(typeof(VehicleController), "FrontLeftWheel")),
				new PatchUtils.OpcodeMatch(OpCodes.Callvirt, PatchUtils.Method(typeof(WheelCollider), "get_motorTorque")),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_R4),
				new PatchUtils.OpcodeMatch(OpCodes.Ble_Un)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not patch SetCarEffects!");
				return instructions;
			}
			object operand = list[num + 4].operand;
			list.Insert(num, new CodeInstruction(OpCodes.Br, operand));
			return list;
		}

		[HarmonyPatch("__rpc_handler_46143233")]
		[HarmonyPrefix]
		private static bool SpringDriverSeatServerRpc_Handler_Prefix(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkSync.Config.PreventPassengersEjectingDriver)
			{
				return true;
			}
			NetworkManager networkManager = target.NetworkManager;
			if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening)
			{
				return true;
			}
			VehicleController val = (VehicleController)target;
			if ((Object)(object)val.currentDriver == (Object)null || rpcParams.Server.Receive.SenderClientId != val.currentDriver.actualClientId)
			{
				return false;
			}
			return true;
		}

		private static bool CheckExitPointInvalid(Vector3 playerPos, Vector3 exitPoint, int layerMask, QueryTriggerInteraction interaction)
		{
			//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_0003: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0050: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (Physics.Linecast(playerPos, exitPoint, layerMask, interaction))
			{
				return true;
			}
			if (Physics.CheckCapsule(exitPoint, exitPoint + Vector3.up, 0.5f, layerMask, interaction))
			{
				return true;
			}
			LayerMask val = LayerMask.op_Implicit(layerMask | LayerMask.GetMask(new string[1] { "Vehicle" }));
			if (!Physics.Linecast(exitPoint, exitPoint + Vector3.down * 4f, LayerMask.op_Implicit(val), interaction))
			{
				return true;
			}
			return false;
		}

		[HarmonyPatch("CanExitCar")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CanExitCar_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo method = typeof(Physics).GetMethod("Linecast", BindingFlags.Static | BindingFlags.Public, null, new Type[4]
			{
				typeof(Vector3),
				typeof(Vector3),
				typeof(int),
				typeof(QueryTriggerInteraction)
			}, null);
			MethodInfo method2 = typeof(VehicleControllerPatches).GetMethod("CheckExitPointInvalid", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[4]
			{
				typeof(Vector3),
				typeof(Vector3),
				typeof(int),
				typeof(QueryTriggerInteraction)
			}, null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Call && (MethodInfo)instruction.operand == method)
				{
					instruction.operand = method2;
				}
			}
			return instructions;
		}

		[HarmonyPatch("ExitPassengerSideSeat")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ExitPassengerSideSeat_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo operand = PatchUtils.Method(typeof(VehicleController), "CanExitCar");
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(2)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_1),
				new PatchUtils.OpcodeMatch(OpCodes.Call, operand)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Could not patch ExitPassengerSideSeat!");
				return list;
			}
			list[num].opcode = OpCodes.Ldc_I4_0;
			return list;
		}

		private static bool ShouldPlayDetectableAudio(VehicleController instance)
		{
			if (!instance.ignitionStarted)
			{
				return !NetworkSync.Config.SilentCollisions;
			}
			return true;
		}

		[HarmonyPatch("PlayRandomClipAndPropertiesFromAudio")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PlayRandomClipAndPropertiesFromAudio_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo operand = PatchUtils.Method(typeof(RoundManager), "get_Instance");
			PatchUtils.Field(typeof(VehicleController), "ignitionStarted");
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(4)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_S, 4),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_2),
				new PatchUtils.OpcodeMatch(OpCodes.Blt),
				new PatchUtils.OpcodeMatch(OpCodes.Call, operand)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Failed to find code segment in PlayRandomClipAndPropertiesFromAudio");
				return list;
			}
			int num2 = PatchUtils.LocateCodeSegment(num, list, new List<PatchUtils.OpcodeMatch>(3)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_S, 4),
				new PatchUtils.OpcodeMatch(OpCodes.Ldc_I4_M1),
				new PatchUtils.OpcodeMatch(OpCodes.Bne_Un)
			});
			if (num2 == -1)
			{
				CruiserImproved.LogWarning("Failed to find end jump segment in PlayRandomClipAndPropertiesFromAudio");
				return list;
			}
			Label label = list[num2].labels[0];
			list.InsertRange(num, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)PatchUtils.Method(typeof(VehicleControllerPatches), "ShouldPlayDetectableAudio")),
				new CodeInstruction(OpCodes.Brfalse_S, (object)label)
			}));
			return list;
		}

		private static Vector3 FixMagnet(VehicleController instance)
		{
			//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_000e: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00ec: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 eulerAngles = ((Component)instance).transform.eulerAngles;
			eulerAngles.y = Mathf.Round((eulerAngles.y + 90f) / 180f) * 180f - 90f;
			eulerAngles.z = Mathf.Round(eulerAngles.z / 90f) * 90f;
			float num = Mathf.Repeat(eulerAngles.x + Random.Range(-5f, 5f) + 180f, 360f) - 180f;
			eulerAngles.x = Mathf.Clamp(num, -20f, 20f);
			instance.magnetTargetRotation = Quaternion.Euler(eulerAngles);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, -0.5f, (0f - instance.boundsCollider.size.x) * 0.5f * ((Component)instance.boundsCollider).transform.lossyScale.x);
			Vector3 val2 = StartOfRound.Instance.magnetPoint.position + val;
			instance.magnetTargetPosition = StartOfRound.Instance.elevatorTransform.InverseTransformPoint(val2);
			return eulerAngles;
		}

		[HarmonyPatch("StartMagneting")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StartMagneting_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = PatchUtils.Method(typeof(NetworkBehaviour), "get_IsOwner");
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(4)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Ldarg_0),
				new PatchUtils.OpcodeMatch(OpCodes.Call, methodInfo),
				new PatchUtils.OpcodeMatch(OpCodes.Brtrue),
				new PatchUtils.OpcodeMatch(OpCodes.Ret)
			});
			if (num == -1)
			{
				CruiserImproved.LogWarning("Failed to remove owner check from StartMagneting!");
			}
			else
			{
				list.RemoveRange(num, 4);
			}
			MethodInfo operand = PatchUtils.Method(typeof(VehicleController), "CollectItemsInTruck");
			MethodInfo methodInfo2 = PatchUtils.Method(typeof(VehicleControllerPatches), "FixMagnet");
			int num2 = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(1)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Call, operand)
			});
			if (num2 == -1)
			{
				CruiserImproved.LogWarning("Failed to patch StartMagneting!");
			}
			Label label = il.DefineLabel();
			list[num2 + 1].labels.Add(label);
			list.InsertRange(num2 + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[12]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)methodInfo2),
				new CodeInstruction(OpCodes.Stloc_1, (object)null),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)methodInfo),
				new CodeInstruction(OpCodes.Brtrue, (object)label),
				new CodeInstruction(OpCodes.Ret, (object)null),
				new CodeInstruction(OpCodes.Call, (object)PatchUtils.Method(typeof(GameNetworkManager), "get_Instance")),
				new CodeInstruction(OpCodes.Ldfld, (object)PatchUtils.Field(typeof(GameNetworkManager), "localPlayerController")),
				new CodeInstruction(OpCodes.Call, (object)typeof(Object).GetMethod("op_Implicit")),
				new CodeInstruction(OpCodes.Brtrue, (object)label),
				new CodeInstruction(OpCodes.Ret, (object)null)
			}));
			return list;
		}

		[HarmonyPatch("SetRadioStationClientRpc")]
		[HarmonyPostfix]
		private static void SetRadioStationClientRpc_Postfix(VehicleController __instance)
		{
			__instance.SetRadioOnLocalClient(true, true);
		}

		private static void SetRadioTime(VehicleController instance)
		{
			instance.radioAudio.time = Mathf.Clamp(instance.currentSongTime % instance.radioAudio.clip.length, 0.01f, instance.radioAudio.clip.length - 0.1f);
		}

		[HarmonyPatch("SetRadioOnLocalClient")]
		[HarmonyPostfix]
		private static void SetRadioOnLocalClient_Postfix(VehicleController __instance, bool on, bool setClip)
		{
			if (on && setClip)
			{
				SetRadioTime(__instance);
			}
		}

		[HarmonyPatch("SwitchRadio")]
		[HarmonyPostfix]
		private static void SwitchRadio_Postfix(VehicleController __instance)
		{
			if (__instance.radioOn)
			{
				__instance.SetRadioStationServerRpc(__instance.currentRadioClip, (int)Mathf.Round(__instance.radioSignalQuality));
				SetRadioTime(__instance);
			}
		}

		public static void SyncRadioTimeRpc(ulong clientId, FastBufferReader reader)
		{
			//IL_000f: 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)
			NetworkObjectReference val = default(NetworkObjectReference);
			((FastBufferReader)(ref reader)).ReadNetworkSerializable<NetworkObjectReference>(ref val);
			float currentSongTime = default(float);
			((FastBufferReader)(ref reader)).ReadValue<float>(ref currentSongTime, default(ForPrimitives));
			NetworkObject val2 = default(NetworkObject);
			VehicleController val3 = default(VehicleController);
			if (((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null) && ((Component)val2).TryGetComponent<VehicleController>(ref val3) && clientId == 0L)
			{
				val3.currentSongTime = currentSongTime;
			}
		}

		[HarmonyPatch("RemoveKeyFromIgnition")]
		[HarmonyPostfix]
		public static void RemoveKeyFromIgnition_Postfix(VehicleController __instance)
		{
			if (!__instance.localPlayerInControl && !((Object)(object)__instance.currentDriver != (Object)null) && NetworkSync.Config.StandingKeyRemoval)
			{
				if (__instance.keyIgnitionCoroutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(__instance.keyIgnitionCoroutine);
				}
				__instance.keyIgnitionCoroutine = ((MonoBehaviour)__instance).StartCoroutine(__instance.RemoveKey());
				__instance.RemoveKeyFromIgnitionServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
			}
		}
	}
}
namespace CruiserImproved.Patches.Targeted
{
	[HarmonyPatch]
	internal class ItemFallthroughPatch
	{
		public static MethodBase TargetMethod()
		{
			if (PatchUtils.TryMethod(typeof(GrabbableObject), "GetPhysicsRegionOfDroppedObject", new Type[2]
			{
				typeof(PlayerControllerB),
				typeof(Vector3).MakeByRefType()
			}, out var methodInfo))
			{
				return methodInfo;
			}
			if (PatchUtils.TryMethod(typeof(PlayerControllerB), "DiscardHeldObject", out methodInfo))
			{
				return methodInfo;
			}
			CruiserImproved.LogWarning("No valid method for ItemFallthroughPatch found.");
			return null;
		}

		public static PlayerPhysicsRegion FindPhysicsRegionOnTransform(ref Transform transform)
		{
			PlayerPhysicsRegion componentInChildren = ((Component)transform).GetComponentInChildren<PlayerPhysicsRegion>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				return componentInChildren;
			}
			VehicleController componentInParent = ((Component)transform).GetComponentInParent<VehicleController>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				transform = ((Component)componentInParent).transform;
				return componentInParent.physicsRegion;
			}
			return null;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = PatchUtils.LocateCodeSegment(0, list, new List<PatchUtils.OpcodeMatch>(1)
			{
				new PatchUtils.OpcodeMatch(OpCodes.Callvirt, PatchUtils.Method(typeof(Component), "GetComponentInChildren", null, new Type[1] { typeof(PlayerPhysicsRegion) }))
			});
			if (num != -1)
			{
				CodeInstruction obj = list[num - 1];
				if (obj.opcode == OpCodes.Ldloc_0)
				{
					list[num - 1] = new CodeInstruction(OpCodes.Ldloca, (object)0);
				}
				if (obj.opcode == OpCodes.Ldloc_1)
				{
					list[num - 1] = new CodeInstruction(OpCodes.Ldloca, (object)1);
				}
				list[num] = new CodeInstruction(OpCodes.Call, (object)PatchUtils.Method(typeof(ItemFallthroughPatch), "FindPhysicsRegionOnTransform"));
				return list;
			}
			CruiserImproved.LogWarning("Could not patch ItemFallthroughPatch!");
			return instructions;
		}
	}
}
namespace CruiserImproved.Network
{
	internal class NetworkConfig : INetworkSerializable
	{
		public Version version = new Version("1.4.1");

		public bool SyncSeat;

		public float SeatBoostScale;

		public bool AllowLean;

		public bool PreventMissileKnockback;

		public bool AllowPushDestroyedCar;

		public bool PreventPassengersEjectingDriver;

		public bool EntitiesAvoidCruiser;

		public bool SilentCollisions;

		public float CruiserInvulnerabilityDuration;

		public float CruiserCriticalInvulnerabilityDuration;

		public int MaxCriticalHitCount;

		public bool AntiSideslip;

		public bool DisableRadioStatic;

		public bool HandsfreeDoors;

		public bool StandingKeyRemoval;

		public bool TurboExhaust;

		public ScanNodeOptions CruiserScanNode;

		public void CopyLocalConfig()
		{
			SyncSeat = UserConfig.SyncSeat.Value;
			AllowLean = UserConfig.AllowLean.Value;
			SeatBoostScale = UserConfig.SeatBoostScale.Value;
			PreventMissileKnockback = UserConfig.PreventMissileKnockback.Value;
			AllowPushDestroyedCar = UserConfig.AllowPushDestroyedCar.Value;
			PreventPassengersEjectingDriver = UserConfig.PreventPassengersEjectingDriver.Value;
			EntitiesAvoidCruiser = UserConfig.EntitiesAvoidCruiser.Value;
			SilentCollisions = UserConfig.SilentCollisions.Value;
			CruiserInvulnerabilityDuration = UserConfig.CruiserInvulnerabilityDuration.Value;
			CruiserCriticalInvulnerabilityDuration = UserConfig.CruiserCriticalInvulnerabilityDuration.Value;
			MaxCriticalHitCount = UserConfig.MaxCriticalHitCount.Value;
			AntiSideslip = UserConfig.AntiSideslip.Value;
			DisableRadioStatic = UserConfig.DisableRadioStatic.Value;
			HandsfreeDoors = UserConfig.HandsfreeDoors.Value;
			StandingKeyRemoval = UserConfig.StandingKeyRemoval.Value;
			CruiserScanNode = UserConfig.CruiserScanNode.Value;
			TurboExhaust = UserConfig.TurboExhaust.Value;
		}

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_005a: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0112: 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_0128: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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)
			//IL_015a: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if (serializer.IsWriter)
			{
				text = version.ToString();
			}
			serializer.SerializeValue(ref text, false);
			if (serializer.IsReader)
			{
				version = new Version(text);
			}
			if (version < new Version(1, 2, 0))
			{
				return;
			}
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref SyncSeat, default(ForPrimitives));
			if (SyncSeat)
			{
				((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref SeatBoostScale, default(ForPrimitives));
			}
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref AllowLean, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref PreventMissileKnockback, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref AllowPushDestroyedCar, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref PreventPassengersEjectingDriver, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref EntitiesAvoidCruiser, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref SilentCollisions, default(ForPrimitives));
			((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref CruiserInvulnerabilityDuration, default(ForPrimitives));
			((BufferSerializer<float>*)(&serializer))->SerializeValue<float>(ref CruiserCriticalInvulnerabilityDuration, default(ForPrimitives));
			((BufferSerializer<int>*)(&serializer))->SerializeValue<int>(ref MaxCriticalHitCount, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref AntiSideslip, default(ForPrimitives));
			if (!(version < new Version(1, 3, 0)))
			{
				((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref DisableRadioStatic, default(ForPrimitives));
				if (!(version < new Version(1, 4, 0)))
				{
					((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref HandsfreeDoors, default(ForPrimitives));
					((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref StandingKeyRemoval, default(ForPrimitives));
					((BufferSerializer<ScanNodeOptions>*)(&serializer))->SerializeValue<ScanNodeOptions>(ref CruiserScanNode, default(ForEnums));
					((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref TurboExhaust, default(ForPrimitives));
				}
			}
		}
	}
	internal static class NetworkSync
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__ContactServerRpc;

			public static Action<ulong> <1>__OnClientDisconnect;

			public static HandleNamedMessageDelegate <2>__SendConfigClientRpc;

			public static HandleNamedMessageDelegate <3>__SyncSteeringRpc;

			public static HandleNamedMessageDelegate <4>__SyncRadioTimeRpc;
		}

		public static NetworkConfig Config;

		public static bool SyncedWithHost;

		public static bool FinishedSync;

		public static List<ulong> HostSyncedList;

		public static void Init()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_00f7: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			Config = new NetworkConfig();
			Config.CopyLocalConfig();
			SyncedWithHost = false;
			FinishedSync = false;
			AddAllMessageHandlers();
			if (NetworkManager.Singleton.IsHost)
			{
				CruiserImproved.LogMessage("Setup as host!");
				HostSyncedList = new List<ulong>();
				SyncedWithHost = true;
				object obj = <>O.<0>__ContactServerRpc;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = ContactServerRpc;
					<>O.<0>__ContactServerRpc = val;
					obj = (object)val;
				}
				SetupMessageHandler("ContactServerRpc", (HandleNamedMessageDelegate)obj);
				FinishSync(hostSynced: true);
				NetworkManager.Singleton.OnClientDisconnec