Decompiled source of ValheimVehicle v1.5.4

BepInEx/plugins/ValheimVehicle/ValheimVehicle.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Newtonsoft.Json.Linq;
using Splatform;
using UnityEngine;
using UnityEngine.Networking;

[assembly: Guid("0ff27dff-2359-4065-842f-ba66aaac02ff")]
[assembly: CompilationRelaxations(8)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("1.5.3.1")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("ValheimVehicle")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimVehicle")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.5.3.1")]
[BepInPlugin("Dropoff.VehicleMod", "Vehicle Mod", "1.5.4")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Player), "SetControls")]
	private static class DriverMovementPatch
	{
		private static void Prefix(Player __instance, ref Vector3 movedir, ref bool run, ref bool autoRun, bool jump)
		{
			//IL_0054: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ((Character)__instance).IsAttached())
			{
				Transform attachPoint = __instance.GetAttachPoint();
				RearWheelDrive rearWheelDrive = (Object.op_Implicit((Object)(object)attachPoint) ? ((Component)attachPoint).GetComponentInParent<RearWheelDrive>() : null);
				if (Object.op_Implicit((Object)(object)rearWheelDrive) && rearWheelDrive.IsLocalDriver())
				{
					rearWheelDrive.SetMovementInput((InputBlocked() || jump) ? Vector3.zero : movedir);
					movedir = Vector3.zero;
					run = (autoRun = false);
					__instance.m_autoRun = false;
				}
			}
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	private static class RegisterVehicle
	{
		private static void Prefix(ZNetScene __instance)
		{
			if (!Object.op_Implicit((Object)(object)VehiclePrefab))
			{
				return;
			}
			GameObject val = __instance.m_prefabs.Find((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == ((Object)VehiclePrefab).name);
			if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)VehiclePrefab)
			{
				((BaseUnityPlugin)instance).Logger.LogError((object)("A different mod already registered prefab " + ((Object)VehiclePrefab).name));
				return;
			}
			ImpactEffect component = VehiclePrefab.GetComponent<ImpactEffect>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_hitEffect.m_effectPrefabs = (from name in new string[1] { "vfx_HitSparks" }
					select __instance.m_prefabs.Find((GameObject p) => Object.op_Implicit((Object)(object)p) && ((Object)p).name == name) into p
					where Object.op_Implicit((Object)(object)p)
					select p).Select(delegate(GameObject p)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Expected O, but got Unknown
					EffectData val2 = new EffectData();
					val2.m_prefab = p;
					return val2;
				}).ToArray();
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				__instance.m_prefabs.Add(VehiclePrefab);
			}
		}
	}

	[HarmonyPatch(typeof(Chair), "Interact")]
	private static class VehicleSeats
	{
		private static float lastSitTime = -10f;

		private static bool Prefix(Chair __instance, Humanoid human, bool hold, ref bool __result)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			RearWheelDrive componentInParent = ((Component)__instance).GetComponentInParent<RearWheelDrive>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return true;
			}
			__result = false;
			Player val = (Player)(object)((human is Player) ? human : null);
			if (hold || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)__instance.m_attachPoint) || ((Character)val).IsEncumbered() || Time.time - lastSitTime < 2f || Vector3.Distance(((Component)val).transform.position, __instance.m_attachPoint.position) >= __instance.m_useDistance)
			{
				return false;
			}
			if (__instance.IsInUse())
			{
				((Character)val).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null, false);
				return false;
			}
			ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				return false;
			}
			if (((Object)__instance.m_attachPoint).name == "attachpoint_driver")
			{
				if (component.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) != val.GetPlayerID())
				{
					((Character)val).Message((MessageType)2, "Only the player who spawned this vehicle can drive it", 0, (Sprite)null, false);
					return false;
				}
				component.ClaimOwnership();
			}
			((Character)val).AttachStart(__instance.m_attachPoint, ((Component)componentInParent).gameObject, false, false, true, __instance.m_attachAnimation, __instance.m_detachOffset, (Transform)null);
			lastSitTime = Time.time;
			return false;
		}
	}

	public const string PluginId = "Dropoff.VehicleMod";

	internal const string CreatorKey = "Dropoff.VehicleMod.Creator";

	internal const string LightsKey = "Dropoff.VehicleMod.Lights";

	internal static ConfigEntry<KeyCode> SpawnKey;

	internal static ConfigEntry<KeyCode> BrakeKey;

	internal static ConfigEntry<KeyCode> FlipKey;

	internal static ConfigEntry<KeyCode> LightKey;

	internal static ConfigEntry<KeyCode> DespawnKey;

	private readonly Harmony harmony = new Harmony("Dropoff.VehicleMod");

	private GameObject spawnedPrefab;

	private AssetBundle bundle;

	private GameObject templateRoot;

	private static BepInExPlugin instance;

	private bool spawnHeld;

	private bool despawnHeld;

	public static GameObject VehiclePrefab { get; private set; }

	private void Awake()
	{
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Expected O, but got Unknown
		instance = this;
		SpawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Spawn", (KeyCode)278, "Spawn or recall your vehicle.");
		BrakeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Brake", (KeyCode)121, "Hold to brake.");
		FlipKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Flip", (KeyCode)277, "Right the vehicle while in the driver seat.");
		LightKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Headlights", (KeyCode)104, "Toggle headlights while in the driver seat.");
		DespawnKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Despawn", (KeyCode)279, "Store your unoccupied vehicle; trunk items are kept with the character.");
		ConfigEntry<int> version = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "ControlsVersion", 0, "Internal migration version. Leave this value unchanged.");
		MigrateLegacyControls(SpawnKey, DespawnKey, FlipKey, version);
		try
		{
			bundle = GetAssetBundleFromResources("greenwood");
			if (!Object.op_Implicit((Object)(object)bundle))
			{
				throw new InvalidOperationException("Could not load the embedded vehicle AssetBundle.");
			}
			GameObject val = bundle.LoadAsset<GameObject>("Assets/ValheimVehicles/greenwood/greenwood.prefab");
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Original vehicle framework is missing.");
			}
			templateRoot = new GameObject("ValheimVehicle_Templates");
			templateRoot.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)templateRoot);
			VehiclePrefab = Object.Instantiate<GameObject>(val, templateRoot.transform, false);
			((Object)VehiclePrefab).name = ((Object)val).name;
			if (!Object.op_Implicit((Object)(object)VehiclePrefab) || !Object.op_Implicit((Object)(object)VehiclePrefab.GetComponent<RearWheelDrive>()) || !Object.op_Implicit((Object)(object)VehiclePrefab.GetComponent<ZNetView>()))
			{
				throw new InvalidOperationException("Vehicle prefab or its required scripts are missing.");
			}
			VehicleCollisionGeometry.Apply(VehiclePrefab);
			VehiclePrefab.SetActive(true);
			Chair[] componentsInChildren = VehiclePrefab.GetComponentsInChildren<Chair>(true);
			foreach (Chair val2 in componentsInChildren)
			{
				val2.m_inShip = true;
			}
			VehiclePrefab.AddComponent<VehicleTrunk>();
			harmony.PatchAll(typeof(BepInExPlugin).Assembly);
			((Component)this).gameObject.AddComponent<VehicleRadio>().Initialize(this);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Original Greenwood model from 1.2.1 ready; Radio X available in vehicle.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("ValheimVehicle 1.5.4 loaded for Valheim " + Version.GetVersionString(false) + "; Unity " + Application.unityVersion));
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Vehicle initialization failed: " + ex));
			((Behaviour)this).enabled = false;
		}
	}

	internal static void MigrateLegacyControls(ConfigEntry<KeyCode> spawn, ConfigEntry<KeyCode> despawn, ConfigEntry<KeyCode> flip, ConfigEntry<int> version)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Invalid comparison between Unknown and I4
		if (version.Value < 1)
		{
			if ((int)spawn.Value == 116)
			{
				spawn.Value = (KeyCode)278;
			}
			if ((int)despawn.Value == 103)
			{
				despawn.Value = (KeyCode)279;
			}
			if ((int)flip.Value == 102)
			{
				flip.Value = (KeyCode)277;
			}
			version.Value = 1;
		}
	}

	internal static void LogInfo(string text)
	{
		if (Object.op_Implicit((Object)(object)instance))
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)text);
		}
	}

	internal static void LogError(string text)
	{
		if (Object.op_Implicit((Object)(object)instance))
		{
			((BaseUnityPlugin)instance).Logger.LogError((object)text);
		}
	}

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

	public static AssetBundle GetAssetBundleFromResources(string fileName)
	{
		Assembly assembly = typeof(BepInExPlugin).Assembly;
		string name = assembly.GetManifestResourceNames().Single((string n) => n.EndsWith("." + fileName, StringComparison.Ordinal));
		using Stream stream = assembly.GetManifestResourceStream(name);
		using MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		return AssetBundle.LoadFromMemory(memoryStream.ToArray());
	}

	public static bool InputBlocked()
	{
		if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Menu.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Hud.InRadial() && !StoreGui.IsVisible() && !Minimap.IsOpen())
		{
			if (Object.op_Implicit((Object)(object)TextViewer.instance))
			{
				return TextViewer.instance.IsVisible();
			}
			return false;
		}
		return true;
	}

	internal static bool Pressed(KeyCode key, ref bool wasHeld)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		bool key2 = ZInput.GetKey(key, true);
		bool result = key2 && !wasHeld;
		wasHeld = key2;
		return result;
	}

	private void Update()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		bool flag = Pressed(SpawnKey.Value, ref spawnHeld);
		bool flag2 = Pressed(DespawnKey.Value, ref despawnHeld);
		if (!InputBlocked())
		{
			if (Object.op_Implicit((Object)(object)VehiclePrefab) && Object.op_Implicit((Object)(object)ZNetScene.instance) && flag)
			{
				SpawnOrRecall();
			}
			if (Object.op_Implicit((Object)(object)ZNetScene.instance) && flag2)
			{
				Despawn();
			}
		}
	}

	public GameObject SpawnOrRecall()
	{
		//IL_0046: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)VehiclePrefab) || !Object.op_Implicit((Object)(object)ZNetScene.instance) || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).IsDead())
		{
			return null;
		}
		Vector3 val = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 5f + Vector3.up * 4f;
		Quaternion val2 = ((Component)localPlayer).transform.rotation * Quaternion.Euler(0f, -90f, 0f);
		if (!Object.op_Implicit((Object)(object)spawnedPrefab))
		{
			spawnedPrefab = FindOwnedVehicle(localPlayer.GetPlayerID());
		}
		if (!Object.op_Implicit((Object)(object)spawnedPrefab))
		{
			spawnedPrefab = Object.Instantiate<GameObject>(VehiclePrefab, val, val2);
			spawnedPrefab.GetComponent<ZNetView>().GetZDO().Set("Dropoff.VehicleMod.Creator", localPlayer.GetPlayerID());
			Piece component = spawnedPrefab.GetComponent<Piece>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.SetCreator(localPlayer.GetPlayerID(), ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID);
			}
		}
		else
		{
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (((Character)allPlayer).IsAttached() && Object.op_Implicit((Object)(object)allPlayer.GetAttachPoint()) && allPlayer.GetAttachPoint().IsChildOf(spawnedPrefab.transform))
				{
					((Character)localPlayer).Message((MessageType)2, "Vehicle is occupied", 0, (Sprite)null, false);
					return spawnedPrefab;
				}
			}
			ZNetView component2 = spawnedPrefab.GetComponent<ZNetView>();
			component2.ClaimOwnership();
			Rigidbody component3 = spawnedPrefab.GetComponent<Rigidbody>();
			component3.position = val;
			component2.GetZDO().SetPosition(val);
			component3.rotation = val2;
			component3.linearVelocity = Vector3.zero;
			component3.angularVelocity = Vector3.zero;
			component3.WakeUp();
		}
		return spawnedPrefab;
	}

	private static GameObject FindOwnedVehicle(long creator)
	{
		VehicleTrunk[] array = Object.FindObjectsByType<VehicleTrunk>((FindObjectsSortMode)0);
		foreach (VehicleTrunk vehicleTrunk in array)
		{
			ZNetView component = ((Component)vehicleTrunk).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == creator)
			{
				return ((Component)vehicleTrunk).gameObject;
			}
		}
		return null;
	}

	public bool Despawn()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNetScene.instance))
		{
			return false;
		}
		if (!Object.op_Implicit((Object)(object)spawnedPrefab))
		{
			spawnedPrefab = FindOwnedVehicle(localPlayer.GetPlayerID());
		}
		if (!Object.op_Implicit((Object)(object)spawnedPrefab))
		{
			return false;
		}
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			if (((Character)allPlayer).IsAttached() && Object.op_Implicit((Object)(object)allPlayer.GetAttachPoint()) && allPlayer.GetAttachPoint().IsChildOf(spawnedPrefab.transform))
			{
				((Character)localPlayer).Message((MessageType)2, "Сначала все должны выйти из машины", 0, (Sprite)null, false);
				return false;
			}
		}
		VehicleTrunk component = spawnedPrefab.GetComponent<VehicleTrunk>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.CloseAndPersist();
		}
		spawnedPrefab.GetComponent<ZNetView>().ClaimOwnership();
		ZNetScene.instance.Destroy(spawnedPrefab);
		spawnedPrefab = null;
		return true;
	}

	private void OnDestroy()
	{
		harmony.UnpatchAll("Dropoff.VehicleMod");
		if (Object.op_Implicit((Object)(object)templateRoot))
		{
			Object.Destroy((Object)(object)templateRoot);
		}
		VehicleCollisionGeometry.Release();
		if (Object.op_Implicit((Object)(object)bundle))
		{
			bundle.Unload(false);
		}
		VehiclePrefab = null;
		instance = null;
	}
}
public class MeshesDeformation : MonoBehaviour
{
	public MeshFilter[] meshFilters;

	public MeshCollider[] colliders;

	public float impactDamage;

	public float deformationRadius;

	public float maxDeformation;

	public float minVelocity;

	private float delayTimeDeform = 0.1f;

	private Vector3[][] originalVertices;

	private float nextTimeDeform;

	private void Start()
	{
		originalVertices = new Vector3[meshFilters.Length][];
		for (int i = 0; i < meshFilters.Length; i++)
		{
			originalVertices[i] = meshFilters[i].mesh.vertices;
			meshFilters[i].mesh.MarkDynamic();
		}
	}

	private void DeformationMesh(Mesh mesh, Transform localTransform, List<Vector3> contactPoints, Vector3 contactVelocity, int i)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		Vector3 val = localTransform.InverseTransformDirection(contactVelocity);
		Vector3[] vertices = mesh.vertices;
		for (int j = 0; j < vertices.Length; j++)
		{
			foreach (Vector3 contactPoint in contactPoints)
			{
				Vector3 val2 = localTransform.InverseTransformPoint(contactPoint);
				Vector3 val3 = val2 - vertices[j];
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (magnitude <= deformationRadius)
				{
					ref Vector3 reference = ref vertices[j];
					reference += val * (deformationRadius - magnitude) * impactDamage;
					Vector3 val4 = vertices[j] - originalVertices[i][j];
					if (((Vector3)(ref val4)).magnitude > maxDeformation)
					{
						ref Vector3 reference2 = ref vertices[j];
						reference2 = originalVertices[i][j] + ((Vector3)(ref val4)).normalized * maxDeformation;
					}
					flag = true;
				}
			}
		}
		if (flag)
		{
			mesh.vertices = vertices;
			mesh.RecalculateNormals();
			mesh.RecalculateBounds();
			if (colliders.Length != 0 && (Object)(object)colliders[i] != (Object)null)
			{
				colliders[i].sharedMesh = mesh;
			}
		}
	}

	private void OnCollisionEnter(Collision collision)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		if (!((Behaviour)this).isActiveAndEnabled || originalVertices == null || !(Time.time > nextTimeDeform))
		{
			return;
		}
		Vector3 relativeVelocity = collision.relativeVelocity;
		if (!(((Vector3)(ref relativeVelocity)).magnitude > minVelocity))
		{
			return;
		}
		List<ContactPoint> list = new List<ContactPoint>(collision.contactCount);
		collision.GetContacts(list);
		List<Vector3> list2 = new List<Vector3>(collision.contactCount);
		for (int i = 0; i < collision.contactCount; i++)
		{
			ContactPoint val = list[i];
			list2.Add(((ContactPoint)(ref val)).point);
		}
		Vector3 contactVelocity = collision.relativeVelocity * 0.02f;
		for (int j = 0; j < meshFilters.Length; j++)
		{
			if ((Object)(object)meshFilters[j] != (Object)null)
			{
				DeformationMesh(meshFilters[j].mesh, ((Component)meshFilters[j]).transform, list2, contactVelocity, j);
			}
		}
		nextTimeDeform = Time.time + delayTimeDeform;
	}
}
public class RearWheelDrive : MonoBehaviour
{
	public WheelCollider[] wheels;

	public float maxAngle = 30f;

	public float maxTorque = 150f;

	public GameObject wheelShape;

	private Rigidbody body;

	private ZNetView view;

	private Transform driverSeat;

	private Transform headlights;

	private readonly VehicleWaterDrive waterDrive = new VehicleWaterDrive();

	private readonly List<Transform> wheelVisuals = new List<Transform>();

	private float steer;

	private float throttle;

	private bool brake;

	private bool flipHeld;

	private bool lightsHeld;

	public bool InWater => waterDrive.InWater;

	public void Start()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		body = ((Component)this).GetComponent<Rigidbody>();
		view = ((Component)this).GetComponent<ZNetView>();
		if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)view))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		body.centerOfMass = new Vector3(0f, 0.04f, 0f);
		wheels = ((Component)this).GetComponentsInChildren<WheelCollider>();
		driverSeat = ((Component)this).transform.Find("attachpoint_driver");
		headlights = ((Component)this).transform.Find("Headlights");
		WheelCollider[] array = wheels;
		foreach (WheelCollider val in array)
		{
			Transform item = null;
			if (Object.op_Implicit((Object)(object)wheelShape))
			{
				GameObject val2 = Object.Instantiate<GameObject>(wheelShape, ((Component)val).transform, false);
				MeshRenderer componentInChildren = val2.GetComponentInChildren<MeshRenderer>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					((Renderer)componentInChildren).enabled = true;
				}
				item = val2.transform;
			}
			wheelVisuals.Add(item);
		}
	}

	public bool IsLocalDriver()
	{
		Player localPlayer = Player.m_localPlayer;
		if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)view) && view.IsValid() && ((Character)localPlayer).IsAttached() && (Object)(object)localPlayer.GetAttachPoint() == (Object)(object)driverSeat)
		{
			return view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == localPlayer.GetPlayerID();
		}
		return false;
	}

	internal void SetMovementInput(Vector3 movement)
	{
		steer = Mathf.Clamp(movement.x, -1f, 1f);
		throttle = Mathf.Clamp(movement.z, -1f, 1f);
	}

	public void Update()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_00b5: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: 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_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)view) || !view.IsValid())
		{
			return;
		}
		if (!IsLocalDriver() || BepInExPlugin.InputBlocked())
		{
			SetMovementInput(Vector3.zero);
		}
		brake = false;
		bool flag = BepInExPlugin.Pressed(BepInExPlugin.FlipKey.Value, ref flipHeld);
		bool flag2 = BepInExPlugin.Pressed(BepInExPlugin.LightKey.Value, ref lightsHeld);
		if (IsLocalDriver())
		{
			if (!view.IsOwner())
			{
				view.ClaimOwnership();
			}
			if (!BepInExPlugin.InputBlocked())
			{
				brake = ZInput.GetKey(BepInExPlugin.BrakeKey.Value, true);
				if (flag)
				{
					Rigidbody obj = body;
					obj.position += Vector3.up * 0.5f;
					Rigidbody obj2 = body;
					Quaternion rotation = body.rotation;
					obj2.rotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
					body.linearVelocity = Vector3.zero;
					body.angularVelocity = Vector3.zero;
				}
				if (flag2)
				{
					view.GetZDO().Set("Dropoff.VehicleMod.Lights", !view.GetZDO().GetBool("Dropoff.VehicleMod.Lights", false));
				}
			}
		}
		if (Object.op_Implicit((Object)(object)headlights))
		{
			((Component)headlights).gameObject.SetActive(view.GetZDO().GetBool("Dropoff.VehicleMod.Lights", false));
		}
		Vector3 val2 = default(Vector3);
		Quaternion val3 = default(Quaternion);
		for (int i = 0; i < wheels.Length; i++)
		{
			Transform val = wheelVisuals[i];
			if (Object.op_Implicit((Object)(object)val))
			{
				wheels[i].GetWorldPose(ref val2, ref val3);
				val.SetPositionAndRotation(val2, val3);
				Transform val4 = ((((Component)wheels[i]).transform.childCount > 1) ? ((Component)wheels[i]).transform.GetChild(0) : null);
				if (Object.op_Implicit((Object)(object)val4) && (Object)(object)val4 != (Object)(object)val)
				{
					val4.position = val2;
				}
			}
		}
	}

	private void FixedUpdate()
	{
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)view) && view.IsValid() && wheels != null)
		{
			bool flag = view.IsOwner();
			bool flag2 = flag && IsLocalDriver() && !BepInExPlugin.InputBlocked();
			if (flag && !body.isKinematic)
			{
				waterDrive.Step(body, flag2, throttle, steer, brake);
			}
			WheelCollider[] array = wheels;
			foreach (WheelCollider val in array)
			{
				val.motorTorque = ((flag2 && !brake) ? (maxTorque * throttle) : 0f);
				val.brakeTorque = ((flag2 && brake) ? maxTorque : 0f);
				val.steerAngle = ((flag2 && ((Component)val).transform.localPosition.z > 0f) ? (maxAngle * steer) : 0f);
			}
		}
	}

	public bool IsOnGround()
	{
		if (wheels == null)
		{
			return false;
		}
		WheelCollider[] array = wheels;
		foreach (WheelCollider val in array)
		{
			if (Object.op_Implicit((Object)(object)val) && val.isGrounded)
			{
				return true;
			}
		}
		return false;
	}
}
internal static class VehicleCollisionGeometry
{
	private static readonly List<Mesh> generated = new List<Mesh>();

	internal static Bounds GetPartBounds(Transform root, string part)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: 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_00bf: 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_00ca: 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_00ec: 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_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		Bounds result = default(Bounds);
		MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val in componentsInChildren)
		{
			if (((Object)val).name != part || !Object.op_Implicit((Object)(object)val.sharedMesh))
			{
				continue;
			}
			Renderer component = ((Component)val).GetComponent<Renderer>();
			if (!Object.op_Implicit((Object)(object)component) || !component.enabled)
			{
				continue;
			}
			bool flag2 = true;
			Transform val2 = ((Component)val).transform;
			while (Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 != (Object)(object)root)
			{
				if (!((Component)val2).gameObject.activeSelf)
				{
					flag2 = false;
					break;
				}
				val2 = val2.parent;
			}
			if (!flag2)
			{
				continue;
			}
			Vector3[] vertices = val.sharedMesh.vertices;
			foreach (Vector3 val3 in vertices)
			{
				Vector3 val4 = root.InverseTransformPoint(((Component)val).transform.TransformPoint(val3));
				if (!flag)
				{
					result = new Bounds(val4, Vector3.zero);
					flag = true;
				}
				else
				{
					((Bounds)(ref result)).Encapsulate(val4);
				}
			}
		}
		if (!flag)
		{
			throw new InvalidOperationException("Original car mesh not found: " + part);
		}
		return result;
	}

	internal static void Apply(GameObject car)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00b4: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		Bounds partBounds = GetPartBounds(car.transform, "boot_ok");
		Bounds partBounds2 = GetPartBounds(car.transform, "bonnet_ok");
		MeshCollider val = null;
		MeshCollider[] componentsInChildren = car.GetComponentsInChildren<MeshCollider>(true);
		foreach (MeshCollider val2 in componentsInChildren)
		{
			if (((Collider)val2).enabled && ((Object)val2).name == "col_back")
			{
				val = val2;
				break;
			}
		}
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMesh))
		{
			throw new InvalidOperationException("Original body collision mesh is missing.");
		}
		Vector3[] vertices = val.sharedMesh.vertices;
		for (int j = 0; j < vertices.Length; j++)
		{
			ref Vector3 reference = ref vertices[j];
			reference = car.transform.InverseTransformPoint(((Component)val).transform.TransformPoint(vertices[j]));
		}
		int[] triangles = val.sharedMesh.triangles;
		AddSection(car, val, vertices, triangles, "Rear", float.NegativeInfinity, ((Bounds)(ref partBounds)).max.z);
		AddSection(car, val, vertices, triangles, "Cabin", ((Bounds)(ref partBounds)).max.z, ((Bounds)(ref partBounds2)).min.z);
		AddSection(car, val, vertices, triangles, "Front", ((Bounds)(ref partBounds2)).min.z, float.PositiveInfinity);
		((Collider)val).enabled = false;
	}

	private static void AddSection(GameObject car, MeshCollider original, Vector3[] points, int[] faces, string name, float minimum, float maximum)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		BuildSectionData(points, faces, minimum, maximum, out var vertices, out var triangles);
		if (triangles.Count < 12)
		{
			throw new InvalidOperationException("Body collision section is empty: " + name);
		}
		Mesh val = new Mesh();
		((Object)val).name = "VehicleCollision_" + name;
		val.SetVertices(vertices);
		val.SetTriangles(triangles, 0);
		val.RecalculateBounds();
		generated.Add(val);
		GameObject val2 = new GameObject("VehicleBody_" + name);
		val2.layer = ((Component)original).gameObject.layer;
		val2.transform.SetParent(car.transform, false);
		MeshCollider val3 = val2.AddComponent<MeshCollider>();
		((Collider)val3).sharedMaterial = ((Collider)original).sharedMaterial;
		val3.convex = true;
		val3.sharedMesh = val;
		((Collider)val3).contactOffset = ((Collider)original).contactOffset;
	}

	internal static void BuildSectionData(Vector3[] points, int[] faces, float minimum, float maximum, out List<Vector3> vertices, out List<int> triangles)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_00b1: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		vertices = new List<Vector3>();
		triangles = new List<int>();
		for (int i = 0; i < faces.Length; i += 3)
		{
			List<Vector3> list = new List<Vector3>();
			list.Add(points[faces[i]]);
			list.Add(points[faces[i + 1]]);
			list.Add(points[faces[i + 2]]);
			List<Vector3> list2 = list;
			if (!float.IsNegativeInfinity(minimum))
			{
				list2 = Clip(list2, minimum, above: true);
			}
			if (!float.IsPositiveInfinity(maximum))
			{
				list2 = Clip(list2, maximum, above: false);
			}
			if (list2.Count < 3)
			{
				continue;
			}
			int count = vertices.Count;
			vertices.AddRange(list2);
			for (int j = 1; j + 1 < list2.Count; j++)
			{
				Vector3 val = Vector3.Cross(list2[j] - list2[0], list2[j + 1] - list2[0]);
				if (!(((Vector3)(ref val)).sqrMagnitude < 1E-12f))
				{
					triangles.Add(count);
					triangles.Add(count + j);
					triangles.Add(count + j + 1);
				}
			}
		}
	}

	private static List<Vector3> Clip(List<Vector3> input, float plane, bool above)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: 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_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		if (input.Count == 0)
		{
			return list;
		}
		Vector3 val = input[input.Count - 1];
		bool flag = (above ? (val.z >= plane) : (val.z <= plane));
		foreach (Vector3 item in input)
		{
			bool flag2 = (above ? (item.z >= plane) : (item.z <= plane));
			if (flag2 != flag)
			{
				float num = (plane - val.z) / (item.z - val.z);
				list.Add(Vector3.LerpUnclamped(val, item, num));
			}
			if (flag2)
			{
				list.Add(item);
			}
			val = item;
			flag = flag2;
		}
		return list;
	}

	internal static void Release()
	{
		foreach (Mesh item in generated)
		{
			if (Object.op_Implicit((Object)(object)item))
			{
				Object.Destroy((Object)(object)item);
			}
		}
		generated.Clear();
	}
}
public sealed class VehicleRadio : MonoBehaviour
{
	private ConfigEntry<KeyCode> toggleKey;

	private ConfigEntry<KeyCode> nextKey;

	private ConfigEntry<bool> radioEnabled;

	private ConfigEntry<float> volume;

	private VehicleRadioFiles.Track[] tracks = new VehicleRadioFiles.Track[0];

	private BepInExPlugin plugin;

	private string musicFolder;

	private AudioSource source;

	private AudioClip clip;

	private UnityWebRequest request;

	private Coroutine loadingRoutine;

	private int index;

	private int generation;

	private bool loading;

	private bool initialized;

	private bool paused;

	private bool started;

	private bool observedPlaying;

	private bool toggleHeld;

	private bool nextHeld;

	private bool wasInVehicle;

	private float playRequestedAt;

	public int TrackIndex => index;

	public int TrackCount => tracks.Length;

	public string TrackTitle
	{
		get
		{
			if (tracks.Length != 0)
			{
				return tracks[index].title;
			}
			return "";
		}
	}

	public bool IsPlaying
	{
		get
		{
			if (Object.op_Implicit((Object)(object)source))
			{
				return source.isPlaying;
			}
			return false;
		}
	}

	public bool IsEnabled
	{
		get
		{
			if (radioEnabled != null)
			{
				return radioEnabled.Value;
			}
			return false;
		}
	}

	public bool IsLoading => loading;

	public AudioSource Source => source;

	public void Initialize(BepInExPlugin owner)
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Expected O, but got Unknown
		toggleKey = ((BaseUnityPlugin)owner).Config.Bind<KeyCode>("Controls", "RadioToggle", (KeyCode)289, "Turn Radio X on or off while seated in the car.");
		nextKey = ((BaseUnityPlugin)owner).Config.Bind<KeyCode>("Controls", "RadioNext", (KeyCode)290, "Next Radio X track while seated in the car.");
		radioEnabled = ((BaseUnityPlugin)owner).Config.Bind<bool>("Radio", "Enabled", false, "Remember whether Radio X is switched on. Playback only occurs inside this mod's car.");
		volume = ((BaseUnityPlugin)owner).Config.Bind<float>("Radio", "Volume", 0.55f, new ConfigDescription("Radio volume. Also follows the game's master volume; does not change other game audio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0]));
		plugin = owner;
		LoadPlaylist();
		GameObject val = new GameObject("ValheimVehicle_RadioX_Local");
		val.transform.SetParent(((Component)this).transform, false);
		source = val.AddComponent<AudioSource>();
		source.playOnAwake = false;
		source.loop = false;
		source.spatialBlend = 0f;
		source.priority = 64;
		source.bypassReverbZones = true;
		source.ignoreListenerPause = false;
		initialized = true;
	}

	private void LoadPlaylist()
	{
		try
		{
			musicFolder = VehicleRadioFiles.ResolveFolder((((BaseUnityPlugin)plugin).Info == null) ? null : ((BaseUnityPlugin)plugin).Info.Location, typeof(VehicleRadio).Assembly.Location);
			tracks = VehicleRadioFiles.Load(musicFolder, Warn);
			index = 0;
			BepInExPlugin.LogInfo("Radio X: " + tracks.Length + " tracks from " + musicFolder);
			if (tracks.Length == 0)
			{
				Warn("No supported audio files found in '" + musicFolder + "'. Press the radio toggle to retry after adding files.");
			}
		}
		catch (Exception ex)
		{
			tracks = new VehicleRadioFiles.Track[0];
			Warn("Cannot load radio files from '" + musicFolder + "': " + ex.Message);
		}
	}

	private static AudioType GetAudioType(string file)
	{
		return (AudioType)(Path.GetExtension(file).ToLowerInvariant() switch
		{
			".mp3" => 13, 
			".ogg" => 14, 
			".wav" => 20, 
			_ => 0, 
		});
	}

	private static bool InVehicle()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || !((Character)localPlayer).IsAttached())
		{
			return false;
		}
		Transform attachPoint = localPlayer.GetAttachPoint();
		if (Object.op_Implicit((Object)(object)attachPoint))
		{
			return Object.op_Implicit((Object)(object)((Component)attachPoint).GetComponentInParent<RearWheelDrive>());
		}
		return false;
	}

	private bool ShouldPlay()
	{
		if (initialized && IsEnabled)
		{
			return InVehicle();
		}
		return false;
	}

	private void Update()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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)
		if (!initialized)
		{
			return;
		}
		bool flag = BepInExPlugin.Pressed(toggleKey.Value, ref toggleHeld);
		bool flag2 = BepInExPlugin.Pressed(nextKey.Value, ref nextHeld);
		bool flag3 = InVehicle();
		if (flag3 && !wasInVehicle)
		{
			Notify(string.Concat("Radio X: ", IsEnabled ? "включено" : "выключено", " [", toggleKey.Value, "] · Следующая [", nextKey.Value, "]"));
		}
		wasInVehicle = flag3;
		if (flag3 && !BepInExPlugin.InputBlocked())
		{
			if (flag)
			{
				if (tracks.Length == 0)
				{
					LoadPlaylist();
				}
				if (tracks.Length == 0)
				{
					radioEnabled.Value = false;
					Notify("Radio X: музыка не найдена. Путь указан в LogOutput.log; F8 — повторить поиск");
				}
				else
				{
					radioEnabled.Value = !radioEnabled.Value;
					Notify("Radio X: " + (IsEnabled ? "включено" : "выключено"));
				}
			}
			if (flag2 && tracks.Length > 0)
			{
				Advance();
				Notify("Radio X: " + TrackTitle);
			}
		}
		source.volume = Mathf.Clamp01(volume.Value) * Mathf.Clamp01(PlatformPrefs.GetFloat("MasterVolume", 1f));
		if (!ShouldPlay())
		{
			Pause();
		}
		else if (tracks.Length == 0)
		{
			radioEnabled.Value = false;
		}
		else
		{
			if (loading)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)clip))
			{
				loading = true;
				loadingRoutine = ((MonoBehaviour)this).StartCoroutine(LoadTrack(generation));
				return;
			}
			if (paused)
			{
				source.UnPause();
				paused = false;
				playRequestedAt = Time.realtimeSinceStartup;
			}
			else if (!started)
			{
				source.Play();
				started = true;
				playRequestedAt = Time.realtimeSinceStartup;
			}
			if (source.isPlaying)
			{
				observedPlaying = true;
			}
			if (started && observedPlaying && !paused && !source.isPlaying && !AudioListener.pause && Time.timeScale > 0f && Time.realtimeSinceStartup - playRequestedAt > 0.25f)
			{
				Advance();
			}
		}
	}

	private void Pause()
	{
		if (Object.op_Implicit((Object)(object)source) && Object.op_Implicit((Object)(object)clip) && started && !paused)
		{
			source.Pause();
			paused = true;
		}
	}

	private void Advance()
	{
		CancelLoad();
		ClearClip();
		if (tracks.Length > 0)
		{
			index = (index + 1) % tracks.Length;
		}
	}

	private IEnumerator LoadTrack(int ticket)
	{
		int attempt = 0;
		while (true)
		{
			if (attempt < tracks.Length)
			{
				string path = Path.Combine(musicFolder, tracks[index].file);
				UnityWebRequestAsyncOperation operation = null;
				string error = null;
				try
				{
					if (!File.Exists(path))
					{
						throw new FileNotFoundException("Track is missing.", tracks[index].file);
					}
					request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, GetAudioType(path));
					((DownloadHandlerAudioClip)request.downloadHandler).streamAudio = true;
					request.timeout = 30;
					operation = request.SendWebRequest();
				}
				catch (Exception ex)
				{
					error = ex.Message;
				}
				if (operation != null)
				{
					yield return operation;
				}
				if (ticket != generation)
				{
					break;
				}
				AudioClip loaded = null;
				try
				{
					if (error == null)
					{
						if ((int)request.result != 1)
						{
							error = request.error;
						}
						else
						{
							loaded = DownloadHandlerAudioClip.GetContent(request);
						}
						if (!Object.op_Implicit((Object)(object)loaded) && error == null)
						{
							error = "Decoder did not return an audio clip.";
						}
					}
				}
				catch (Exception ex2)
				{
					error = ex2.Message;
				}
				if (request != null)
				{
					request.Dispose();
					request = null;
				}
				if (Object.op_Implicit((Object)(object)loaded) && error == null)
				{
					clip = loaded;
					((Object)clip).name = TrackTitle;
					source.clip = clip;
					VehicleRadio vehicleRadio = this;
					VehicleRadio vehicleRadio2 = this;
					VehicleRadio vehicleRadio3 = this;
					bool flag = false;
					vehicleRadio3.observedPlaying = false;
					vehicleRadio.started = (vehicleRadio2.paused = flag);
					loading = false;
					loadingRoutine = null;
					if (ShouldPlay())
					{
						Notify("Radio X · " + (index + 1) + "/" + tracks.Length + ": " + TrackTitle);
					}
					break;
				}
				if (Object.op_Implicit((Object)(object)loaded))
				{
					Object.Destroy((Object)(object)loaded);
				}
				Warn("Skipping " + tracks[index].file + ": " + error);
				index = (index + 1) % tracks.Length;
				attempt++;
				continue;
			}
			loading = false;
			loadingRoutine = null;
			radioEnabled.Value = false;
			Notify("Radio X: записи не удалось открыть. Проверь папку RadioX.");
			break;
		}
	}

	private void CancelLoad()
	{
		generation++;
		if (request != null)
		{
			request.Abort();
		}
		if (loadingRoutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(loadingRoutine);
		}
		loadingRoutine = null;
		if (request != null)
		{
			request.Dispose();
			request = null;
		}
		loading = false;
	}

	private void ClearClip()
	{
		if (Object.op_Implicit((Object)(object)source))
		{
			source.Stop();
			source.clip = null;
		}
		if (Object.op_Implicit((Object)(object)clip))
		{
			Object.Destroy((Object)(object)clip);
		}
		clip = null;
		started = (paused = (observedPlaying = false));
	}

	private void OnDisable()
	{
		Pause();
		CancelLoad();
	}

	private void OnDestroy()
	{
		CancelLoad();
		ClearClip();
		if (Object.op_Implicit((Object)(object)source))
		{
			Object.Destroy((Object)(object)((Component)source).gameObject);
		}
	}

	private void Notify(string message)
	{
		if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false);
		}
	}

	private void Warn(string message)
	{
		BepInExPlugin.LogWarning("Radio X: " + message);
	}
}
internal static class VehicleRadioFiles
{
	internal sealed class Track
	{
		public string file;

		public string title;
	}

	internal static string ResolveFolder(string pluginLocation, string assemblyLocation)
	{
		string text = null;
		string[] array = new string[2] { pluginLocation, assemblyLocation };
		foreach (string text2 in array)
		{
			if (!string.IsNullOrWhiteSpace(text2))
			{
				string text3 = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(text2)), "RadioX");
				if (text == null)
				{
					text = text3;
				}
				if (Directory.Exists(text3))
				{
					return text3;
				}
			}
		}
		if (text == null)
		{
			throw new InvalidDataException("BepInEx did not provide the plugin location.");
		}
		return text;
	}

	internal static Track[] Load(string folder, Action<string> warn)
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Invalid comparison between Unknown and I4
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Invalid comparison between Unknown and I4
		string text = Path.Combine(folder, "playlist.json");
		if (File.Exists(text))
		{
			try
			{
				JToken obj = JObject.Parse(File.ReadAllText(text))["tracks"];
				JArray val = (JArray)(object)((obj is JArray) ? obj : null);
				if (val == null || ((JContainer)val).Count == 0)
				{
					throw new InvalidDataException("Empty or absent tracks array.");
				}
				List<Track> list = new List<Track>();
				foreach (JToken item in val)
				{
					JObject val2 = (JObject)(object)((item is JObject) ? item : null);
					if (val2 == null || val2["file"] == null || (int)val2["file"].Type != 8)
					{
						throw new InvalidDataException("Playlist entry has no string file name.");
					}
					string text2 = (string)val2["file"];
					if (!IsLocalAudioFileName(text2))
					{
						throw new InvalidDataException("Playlist entries must be local MP3, OGG or WAV file names.");
					}
					string text3 = ((val2["title"] != null && (int)val2["title"].Type == 8) ? ((string)val2["title"]) : null);
					list.Add(new Track
					{
						file = text2,
						title = (string.IsNullOrWhiteSpace(text3) ? Path.GetFileNameWithoutExtension(text2) : text3)
					});
				}
				return list.ToArray();
			}
			catch (Exception ex)
			{
				warn("Cannot read playlist '" + text + "': " + ex.Message + " Using local file order.");
			}
		}
		List<Track> list2 = new List<Track>();
		if (Directory.Exists(folder))
		{
			string[] files = Directory.GetFiles(folder);
			Array.Sort(files, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
			string[] array = files;
			foreach (string path in array)
			{
				string fileName = Path.GetFileName(path);
				if (IsLocalAudioFileName(fileName))
				{
					list2.Add(new Track
					{
						file = fileName,
						title = Path.GetFileNameWithoutExtension(fileName)
					});
				}
			}
		}
		return list2.ToArray();
	}

	internal static bool IsLocalAudioFileName(string file)
	{
		if (string.IsNullOrWhiteSpace(file) || file != Path.GetFileName(file) || Path.IsPathRooted(file) || file.IndexOfAny(new char[3] { '/', '\\', ':' }) >= 0)
		{
			return false;
		}
		string extension = Path.GetExtension(file);
		if (!string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase) && !string.Equals(extension, ".ogg", StringComparison.OrdinalIgnoreCase))
		{
			return string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase);
		}
		return true;
	}
}
public class VehicleTrunk : MonoBehaviour
{
	[HarmonyPatch(typeof(Container), "Save")]
	private static class Changed
	{
		private static void Postfix(Container __instance)
		{
			VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				componentInParent.Persist();
			}
		}
	}

	[HarmonyPatch(typeof(Container), "Load")]
	private static class PersonalInventory
	{
		private static bool Prefix(Container __instance, ref bool __result)
		{
			VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || (!componentInParent.Ready && !componentInParent.LoadFailed))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	[HarmonyPatch(typeof(Container), "CheckAccess")]
	private static class Access
	{
		private static bool Prefix(Container __instance, long playerID, ref bool __result)
		{
			VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return true;
			}
			__result = Object.op_Implicit((Object)(object)componentInParent.view) && componentInParent.view.IsValid() && !componentInParent.LoadFailed && componentInParent.view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) == playerID;
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && playerID == Player.m_localPlayer.GetPlayerID())
			{
				__result &= componentInParent.Ready;
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Container), "OnDestroyed")]
	private static class KeepContents
	{
		private static bool Prefix(Container __instance)
		{
			VehicleTrunk componentInParent = ((Component)__instance).GetComponentInParent<VehicleTrunk>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return true;
			}
			componentInParent.CloseAndPersist();
			return false;
		}
	}

	[HarmonyPatch(typeof(Player), "Save")]
	private static class SaveWithCharacter
	{
		private static void Prefix(Player __instance)
		{
			foreach (VehicleTrunk item in live)
			{
				if (Object.op_Implicit((Object)(object)item) && (Object)(object)item.character == (Object)(object)__instance)
				{
					item.Persist();
				}
			}
		}
	}

	public const string StorageKey = "Dropoff.VehicleMod.Trunk.v1";

	private static readonly List<VehicleTrunk> live = new List<VehicleTrunk>();

	private static readonly MethodInfo saveContainer = AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null);

	private static readonly MethodInfo closeContainer = AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null);

	private static readonly FieldInfo currentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer");

	private ZNetView view;

	private Player character;

	private bool restoring;

	public Container Container { get; private set; }

	public bool Ready { get; private set; }

	public bool LoadFailed { get; private set; }

	private void Start()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: 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)
		view = ((Component)this).GetComponent<ZNetView>();
		if (Object.op_Implicit((Object)(object)view) && view.IsValid())
		{
			live.Add(this);
			GameObject val = new GameObject("VehicleTrunk");
			val.SetActive(false);
			val.transform.SetParent(((Component)this).transform, false);
			Bounds partBounds = VehicleCollisionGeometry.GetPartBounds(((Component)this).transform, "boot_ok");
			val.transform.localPosition = ((Bounds)(ref partBounds)).center;
			val.layer = LayerMask.NameToLayer("piece");
			BoxCollider val2 = val.AddComponent<BoxCollider>();
			val2.size = ((Bounds)(ref partBounds)).size + Vector3.one * 0.04f;
			((Collider)val2).isTrigger = true;
			Container = val.AddComponent<Container>();
			Container.m_rootObjectOverride = view;
			Container.m_name = "Багажник";
			Container.m_width = 8;
			Container.m_height = 4;
			Container.m_privacy = (PrivacySetting)0;
			Container.m_checkGuardStone = false;
			Container.m_autoDestroyEmpty = false;
			val.SetActive(true);
			TryInitialize();
		}
	}

	private void Update()
	{
		if (!Ready && !LoadFailed && Object.op_Implicit((Object)(object)Container))
		{
			TryInitialize();
		}
	}

	private void TryInitialize()
	{
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Expected O, but got Unknown
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Expected O, but got Unknown
		Player player = Player.m_localPlayer;
		if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)Container) || Container.GetInventory() == null || view.GetZDO().GetLong("Dropoff.VehicleMod.Creator", 0L) != player.GetPlayerID() || live.Any((VehicleTrunk t) => Object.op_Implicit((Object)(object)t) && (Object)(object)t != (Object)(object)this && t.Ready && (Object)(object)t.character == (Object)(object)player))
		{
			return;
		}
		character = player;
		view.ClaimOwnership();
		restoring = true;
		try
		{
			if (player.m_customData.TryGetValue("Dropoff.VehicleMod.Trunk.v1", out var value))
			{
				string[] array = value.Split(new char[1] { '|' }, 3);
				if (array.Length != 3 || array[0] != "1" || !int.TryParse(array[1], out var result) || result < 0 || result > 32)
				{
					throw new InvalidOperationException("Unsupported trunk save format.");
				}
				byte[] array2 = Convert.FromBase64String(array[2]);
				Inventory val = new Inventory("Vehicle trunk validation", (Sprite)null, 8, 4);
				val.Load(new ZPackage(array2));
				if (val.NrOfItems() != result)
				{
					throw new InvalidOperationException("Some saved items are unavailable; original trunk data retained.");
				}
				Container.GetInventory().Load(new ZPackage(array2));
			}
			else
			{
				Container.GetInventory().RemoveAll();
			}
			Ready = true;
			saveContainer.Invoke(Container, null);
		}
		catch (Exception ex)
		{
			LoadFailed = true;
			BepInExPlugin.LogError("Trunk could not be restored; saved contents were preserved: " + ex);
			((Character)player).Message((MessageType)2, "Багажник не загружен. Исходные вещи сохранены; проверьте LogOutput.log.", 0, (Sprite)null, false);
		}
		finally
		{
			restoring = false;
		}
		if (Ready)
		{
			Persist();
		}
	}

	public void Persist()
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		if (Ready && !restoring && !LoadFailed && Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)Container) && Container.GetInventory() != null)
		{
			ZPackage val = new ZPackage();
			Inventory inventory = Container.GetInventory();
			inventory.Save(val);
			character.m_customData["Dropoff.VehicleMod.Trunk.v1"] = "1|" + inventory.NrOfItems() + "|" + Convert.ToBase64String(val.GetArray());
		}
	}

	public void CloseAndPersist()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		if (Object.op_Implicit((Object)(object)Container) && Object.op_Implicit((Object)(object)InventoryGui.instance) && (Object)(Container)currentContainer.GetValue(InventoryGui.instance) == (Object)(object)Container)
		{
			closeContainer.Invoke(InventoryGui.instance, null);
		}
		Persist();
	}

	private void OnDestroy()
	{
		CloseAndPersist();
		live.Remove(this);
	}
}
public sealed class VehicleWaterDrive
{
	private readonly Vector3[] pontoons = (Vector3[])(object)new Vector3[4]
	{
		new Vector3(-0.85f, -1.2f, 2.6f),
		new Vector3(0.85f, -1.2f, 2.6f),
		new Vector3(-0.85f, -1.2f, -2.6f),
		new Vector3(0.85f, -1.2f, -2.6f)
	};

	public bool InWater { get; private set; }

	public float Immersion { get; private set; }

	public void Step(Rigidbody body, bool driving, float throttle, float steer, bool brake)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: 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_00ab: 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_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		Immersion = 0f;
		Vector3[] array = pontoons;
		foreach (Vector3 val in array)
		{
			Vector3 val2 = ((Component)body).transform.TransformPoint(val);
			float liquidLevel = Floating.GetLiquidLevel(val2, 1f, (LiquidType)0);
			if (!(liquidLevel < -9999f) && !(liquidLevel <= val2.y))
			{
				float num = liquidLevel - val2.y;
				Immersion += Mathf.Clamp01(num / 0.3f) * 0.25f;
				float num2 = Mathf.Clamp(num * 30f - body.GetPointVelocity(val2).y * 3f, 0f, 35f);
				body.AddForceAtPosition(Vector3.up * (body.mass * num2 * 0.25f), val2, (ForceMode)0);
			}
		}
		InWater = Immersion > 0.05f;
		if (InWater)
		{
			body.WakeUp();
			Vector3 val3 = Vector3.ProjectOnPlane(((Component)body).transform.forward, Vector3.up);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			Vector3 val4 = Vector3.Cross(Vector3.up, normalized);
			float num3 = Vector3.Dot(body.linearVelocity, normalized);
			float num4 = Vector3.Dot(body.linearVelocity, val4);
			bool flag = driving && Vector3.Dot(((Component)body).transform.up, Vector3.up) > 0.3f;
			float num5 = ((flag && !brake) ? (throttle * 3.2f) : 0f);
			float num6 = ((brake && flag) ? 2.5f : 0.4f);
			Vector3 val5 = normalized * (num5 - num3 * num6) - val4 * (num4 * 2f);
			body.AddForce(val5 * Immersion, (ForceMode)5);
			float num7 = ((flag && !brake) ? (steer * 0.65f * ((throttle < -0.1f) ? (-1f) : 1f)) : 0f);
			Vector3 angularVelocity = body.angularVelocity;
			Quaternion val6 = Quaternion.FromToRotation(((Component)body).transform.up, Vector3.up);
			float num8 = default(float);
			Vector3 val7 = default(Vector3);
			((Quaternion)(ref val6)).ToAngleAxis(ref num8, ref val7);
			if (num8 > 180f)
			{
				num8 -= 360f;
			}
			Vector3 val8 = ((Mathf.Abs(num8) < 0.01f) ? Vector3.zero : (((Vector3)(ref val7)).normalized * Mathf.Clamp(num8 * ((float)Math.PI / 180f) * 60f, -60f, 60f)));
			Vector3 val9 = default(Vector3);
			((Vector3)(ref val9))..ctor((0f - angularVelocity.x) * 12f, (num7 - angularVelocity.y) * 3f, (0f - angularVelocity.z) * 12f);
			body.AddTorque((val8 + val9) * Immersion, (ForceMode)5);
		}
	}
}