Decompiled source of SebTruck v1.0.6

BepInEx\plugins\SebTruck\SebTruck.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SebBinds;
using SebCore;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SebTruck")]
[assembly: AssemblyProduct("SebTruck")]
[assembly: AssemblyFileVersion("1.0.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.6.0")]
[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 SebTruck
{
	[BepInPlugin("shibe.easydeliveryco.sebtruck", "SebTruck", "1.0.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal enum SpeedUnit
		{
			Kmh,
			Mph
		}

		internal enum HudReadoutAnchor
		{
			BottomLeft,
			BottomRight
		}

		private enum IndicatorMode
		{
			Off,
			Left,
			Right,
			Hazards
		}

		private sealed class IndicatorCache
		{
			public readonly List<Light> Left = new List<Light>();

			public readonly List<Light> Right = new List<Light>();

			public readonly Dictionary<int, (float intensity, bool enabled)> Defaults = new Dictionary<int, (float, bool)>();

			public readonly List<Material> LeftMats = new List<Material>();

			public readonly List<Material> RightMats = new List<Material>();

			public readonly Dictionary<int, (Color emissionColor, Color emissiveColor, bool emissionKeyword)> MatDefaults = new Dictionary<int, (Color, Color, bool)>();
		}

		private sealed class TurnSignalLightRig
		{
			public GameObject Root;

			public Light FL;

			public Light FR;

			public Light RL;

			public Light RR;

			public bool BaseComputed;

			public Vector3 BaseFL;

			public Vector3 BaseFR;

			public Vector3 BaseRL;

			public Vector3 BaseRR;
		}

		private sealed class TailLightCache
		{
			public readonly List<Light> Lights = new List<Light>();

			public readonly Dictionary<int, (float intensity, bool enabled)> Defaults = new Dictionary<int, (float, bool)>();

			public readonly List<Component> Flares = new List<Component>();

			public readonly Dictionary<int, (float intensity, bool enabled)> FlareDefaults = new Dictionary<int, (float, bool)>();
		}

		private struct PaintDefaults
		{
			public Texture baseMap;

			public Texture mainTex;
		}

		private sealed class HeadlightTuningCache
		{
			public readonly List<Light> Lights = new List<Light>(16);

			public float NextRescanTime;
		}

		[HarmonyPatch]
		private static class Headlights_Toggle_Patch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				return from m in AccessTools.GetDeclaredMethods(typeof(Headlights))
					where m != null && string.Equals(m.Name, "Toggle", StringComparison.Ordinal)
					select m;
			}

			private static bool Prefix()
			{
				return GetIgnitionEnabledEffective();
			}

			private static void Postfix(Headlights __instance)
			{
				try
				{
					if (!((Object)(object)__instance == (Object)null))
					{
						sCarController componentInParent = ((Component)__instance).GetComponentInParent<sCarController>();
						if (!((Object)(object)componentInParent == (Object)null))
						{
							ApplyHeadlightTuning(componentInParent);
						}
					}
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch]
		private static class Headlights_Break_Patch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				return from m in AccessTools.GetDeclaredMethods(typeof(Headlights))
					where m != null && string.Equals(m.Name, "Break", StringComparison.Ordinal)
					select m;
			}

			private static bool Prefix()
			{
				return GetIgnitionEnabledEffective();
			}
		}

		internal const string PrefKeyManualTransmissionEnabled = "SebTruck_ManualTransmission";

		internal const string PrefKeyManualGearCount = "SebTruck_ManualGearCount";

		internal const string PrefKeyManualSpeedMultForward = "SebTruck_ManualSpeedMultFwd";

		internal const string PrefKeyManualSpeedMultReverse = "SebTruck_ManualSpeedMultRev";

		internal const string PrefKeyIgnitionEnabled = "SebTruck_IgnitionEnabled";

		internal const string PrefKeyIgnitionFeatureEnabled = "SebTruck_IgnitionFeatureEnabled";

		internal const string PrefKeyIgnitionHoldSeconds = "SebTruck_IgnitionHoldSeconds";

		internal const string PrefKeyIgnitionSfxEnabled = "SebTruck_IgnitionSfxEnabled";

		internal const string PrefKeyIgnitionSfxVolume = "SebTruck_IgnitionSfxVolume";

		internal const string PrefKeyIndicatorFeatureEnabled = "SebTruck_IndicatorFeatureEnabled";

		internal const string PrefKeyIndicatorSfxEnabled = "SebTruck_IndicatorSfxEnabled";

		internal const string PrefKeyIndicatorSfxVolume = "SebTruck_IndicatorSfxVolume";

		internal const string PrefKeyIndicatorBlinkSeconds = "SebTruck_IndicatorBlinkSeconds";

		internal const string PrefKeyTurnSignalLightIntensity = "SebTruck_TurnSignalLightIntensity";

		internal static readonly Vector3 TurnSignalLightFrontOffset = new Vector3(0f, 0f, 0.05f);

		internal static readonly Vector3 TurnSignalLightRearOffset = new Vector3(0f, -0.3f, 0.05f);

		internal const string PrefKeyHudShowSpeed = "SebTruck_HudShowSpeed";

		internal const string PrefKeyHudShowTach = "SebTruck_HudShowTach";

		internal const string PrefKeyHudShowGear = "SebTruck_HudShowGear";

		internal const string PrefKeyHudSpeedUnits = "SebTruck_HudSpeedUnits";

		internal const string PrefKeyHudReadoutAnchor = "SebTruck_HudReadoutAnchor";

		internal const string PrefKeyHudSpeedAnchor = "SebTruck_HudSpeedAnchor";

		internal const string PrefKeyHudTachAnchor = "SebTruck_HudTachAnchor";

		internal const string PrefKeyHudGearAnchor = "SebTruck_HudGearAnchor";

		internal const string PrefKeyHeadlightIntensityMult = "SebTruck_HeadlightIntensityMult";

		internal const string PrefKeyHeadlightRangeMult = "SebTruck_HeadlightRangeMult";

		private const string SaveKeySnowcats = "cats";

		private const string SaveKeyDisplayBobble = "displayBobble";

		private const string SaveKeyEquippedPaint = "playerEquipedPaint";

		private static readonly List<int> _tmpIntList = new List<int>(64);

		private static bool _manualTransmissionEnabled;

		private static int _manualGear = 1;

		public const string PluginGuid = "shibe.easydeliveryco.sebtruck";

		public const string PluginName = "SebTruck";

		public const string PluginVersion = "1.0.6";

		internal static ManualLogSource Log;

		private static ConfigEntry<bool> _debugLogging;

		private static ConfigEntry<string> _ignitionSfxOnPath;

		private static Object _ignitionSfxOn;

		private static GameObject _ignitionHoldSfxGo;

		private static Component _ignitionHoldSfxSource;

		private static GameObject _indicatorClickSfxGo;

		private static Component _indicatorClickSfxSource;

		private static bool _turnSignalEmissivesTriedLoad;

		private static Texture2D _turnSignalEmissiveOff;

		private static Texture2D _turnSignalEmissiveLeft;

		private static Texture2D _turnSignalEmissiveRight;

		private static Texture2D _turnSignalEmissiveBoth;

		private static Texture2D _turnSignalEmissiveBrakeOff;

		private static Texture2D _turnSignalEmissiveBrakeLeft;

		private static Texture2D _turnSignalEmissiveBrakeRight;

		private static Texture2D _turnSignalEmissiveBrakeBoth;

		private static sCarController _currentCar;

		private static int _currentCarFrame = -1;

		private static bool _isInWalkingMode;

		private static float _currentSpeedKmh;

		private static float _currentSpeedMult = 1f;

		private static float _lastThrottle01;

		private static float _neutralRev01;

		private static float _ignitionHoldStart = -1f;

		private static bool _ignitionHoldConsumed;

		private static bool _ignitionHoldWasDown;

		private static bool _ignitionIgnoreHoldUntilRelease;

		private static float _ignitionOffSince = -1f;

		private static bool _ignitionPrevHeadlightsOn;

		private static bool _ignitionPrevRadioOn;

		private static IndicatorMode _indicatorMode;

		private static bool _indicatorBlinkOn;

		private static float _indicatorNextBlinkTime;

		private static float _indicatorPauseStart = -1f;

		private const float IndicatorCancelArmThreshold = 0.35f;

		private const float IndicatorCancelCenterThreshold = 0.12f;

		private static bool _indicatorCancelArmed;

		private static IndicatorMode _indicatorCancelArmedForMode;

		private static readonly BindingScheme[] _bindingSchemes = (BindingScheme[])(object)new BindingScheme[3]
		{
			default(BindingScheme),
			(BindingScheme)1,
			(BindingScheme)2
		};

		private static readonly Dictionary<int, IndicatorCache> _indicatorCaches = new Dictionary<int, IndicatorCache>();

		private static readonly Dictionary<int, bool> _truckBraking = new Dictionary<int, bool>();

		private static readonly Dictionary<int, bool> _isTruckCarById = new Dictionary<int, bool>();

		private static readonly Dictionary<int, TurnSignalLightRig> _turnSignalLightRigs = new Dictionary<int, TurnSignalLightRig>();

		private static readonly Dictionary<int, TailLightCache> _tailLightCaches = new Dictionary<int, TailLightCache>();

		private static readonly Dictionary<int, (float maxSpeedScale, float drivePowerScale)> _carScaleDefaults = new Dictionary<int, (float, float)>();

		private static readonly Dictionary<int, (float intensity, float range)> _lightDefaults = new Dictionary<int, (float, float)>();

		private static Type _engineSfxRuntimeType;

		private static FieldInfo _engineCarField;

		private static FieldInfo _engineIdleField;

		private static FieldInfo _engineDriveField;

		private static FieldInfo _engineIntenseField;

		private static FieldInfo _engineDistortionField;

		private static FieldInfo _radioTargetVolumeField;

		private static FieldInfo _radioRadioVolumeField;

		private static FieldInfo _radioSourceField;

		private static FieldInfo _radioNoiseField;

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

		private static Type _headlightsRuntimeType;

		private static FieldInfo _headlightsHeadLightsField;

		private static FieldInfo _headlightsCarMatField;

		private static FieldInfo _headlightsEmissiveRegularField;

		private static FieldInfo _headlightsHeadlightsOnField;

		private static FieldInfo _headlightsModelField;

		private static Texture2D _ignitionBlackEmissiveTex;

		private static readonly Dictionary<string, Material> _paintMaterialCache = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<int, PaintDefaults> _paintDefaultsByCarId = new Dictionary<int, PaintDefaults>();

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

		private static FieldInfo _carDamageCarMatField;

		private static int _paintLastCarId;

		private static int _paintLastIndex = int.MinValue;

		private static readonly Dictionary<int, HeadlightTuningCache> _headlightTuningCaches = new Dictionary<int, HeadlightTuningCache>();

		private static readonly HashSet<int> _tmpHeadlightLightIds = new HashSet<int>();

		internal static bool HasAnyUnlockedBobbleheads()
		{
			try
			{
				string @string = sSaveSystem.GetString("cats", "");
				if (string.IsNullOrEmpty(@string))
				{
					return false;
				}
				for (int i = 0; i < @string.Length; i++)
				{
					if (@string[i] == '1')
					{
						return true;
					}
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		internal static int GetSelectedBobbleIndex()
		{
			try
			{
				return sSaveSystem.GetInt("displayBobble", -1);
			}
			catch
			{
				return -1;
			}
		}

		internal static string GetBobbleLabel(int index)
		{
			if (index >= 0)
			{
				return "#" + (index + 1);
			}
			return "None";
		}

		internal static bool IsBobbleUnlocked(int index)
		{
			if (index < 0)
			{
				return true;
			}
			try
			{
				string @string = sSaveSystem.GetString("cats", "");
				if (string.IsNullOrEmpty(@string))
				{
					return false;
				}
				if (index >= @string.Length)
				{
					return false;
				}
				return @string[index] == '1';
			}
			catch
			{
				return false;
			}
		}

		internal static int GetSelectedBobbleIndexUnlockedOrNone()
		{
			int selectedBobbleIndex = GetSelectedBobbleIndex();
			if (!IsBobbleUnlocked(selectedBobbleIndex))
			{
				return -1;
			}
			return selectedBobbleIndex;
		}

		internal static void SetSelectedBobbleIndex(int index)
		{
			if (!IsBobbleUnlocked(index))
			{
				index = -1;
			}
			try
			{
				sSaveSystem.SetInt("displayBobble", index);
			}
			catch
			{
			}
			try
			{
				SnowcatManager val = Object.FindFirstObjectByType<SnowcatManager>();
				if ((Object)(object)val != (Object)null)
				{
					MethodInfo methodInfo = AccessTools.Method(typeof(SnowcatManager), "SetDisplayBobble", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						methodInfo.Invoke(val, new object[1] { index });
					}
				}
			}
			catch
			{
			}
		}

		internal static void CycleBobbleheadSelection()
		{
			int selectedBobbleIndexUnlockedOrNone = GetSelectedBobbleIndexUnlockedOrNone();
			_tmpIntList.Clear();
			try
			{
				string @string = sSaveSystem.GetString("cats", "");
				if (!string.IsNullOrEmpty(@string))
				{
					for (int i = 0; i < @string.Length; i++)
					{
						if (@string[i] == '1')
						{
							_tmpIntList.Add(i);
						}
					}
				}
			}
			catch
			{
			}
			if (_tmpIntList.Count == 0)
			{
				SetSelectedBobbleIndex(-1);
				return;
			}
			if (selectedBobbleIndexUnlockedOrNone < 0)
			{
				SetSelectedBobbleIndex(_tmpIntList[0]);
				return;
			}
			int num = _tmpIntList.IndexOf(selectedBobbleIndexUnlockedOrNone);
			if (num < 0)
			{
				SetSelectedBobbleIndex(_tmpIntList[0]);
			}
			else if (num + 1 >= _tmpIntList.Count)
			{
				SetSelectedBobbleIndex(-1);
			}
			else
			{
				SetSelectedBobbleIndex(_tmpIntList[num + 1]);
			}
		}

		private static bool TryGetCosmeticInfo(out sCosmeticInfo info)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			info = null;
			try
			{
				info = Object.FindFirstObjectByType<sCosmeticInfo>();
				if ((Object)(object)info != (Object)null)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				sCosmeticInfo[] array = Resources.FindObjectsOfTypeAll<sCosmeticInfo>();
				if (array != null)
				{
					for (int i = 0; i < array.Length; i++)
					{
						if (!((Object)(object)array[i] != (Object)null))
						{
							continue;
						}
						try
						{
							if (!((Object)(object)((Component)array[i]).gameObject != (Object)null))
							{
								continue;
							}
							Scene scene = ((Component)array[i]).gameObject.scene;
							if (((Scene)(ref scene)).IsValid())
							{
								scene = ((Component)array[i]).gameObject.scene;
								if (((Scene)(ref scene)).isLoaded)
								{
									info = array[i];
									return true;
								}
							}
						}
						catch
						{
						}
					}
					for (int j = 0; j < array.Length; j++)
					{
						if ((Object)(object)array[j] != (Object)null)
						{
							info = array[j];
							return true;
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				info = Object.FindFirstObjectByType<sCosmeticInfo>();
				return (Object)(object)info != (Object)null;
			}
			catch
			{
				info = null;
				return false;
			}
		}

		internal static int GetSelectedPaintIndex()
		{
			try
			{
				return sSaveSystem.GetInt("playerEquipedPaint", -1);
			}
			catch
			{
				return -1;
			}
		}

		internal static string GetPaintLabel(int index)
		{
			if (index < 0)
			{
				return "Default";
			}
			if (!TryGetCosmeticInfo(out var info) || (Object)(object)info == (Object)null || info.cosmetics == null)
			{
				return "#" + index;
			}
			if (index >= info.cosmetics.Length)
			{
				return "#" + index;
			}
			if (!string.IsNullOrWhiteSpace(info.cosmetics[index].name))
			{
				return info.cosmetics[index].name;
			}
			return "#" + index;
		}

		internal static bool TryGetPaintCosmeticName(int index, out string name)
		{
			name = string.Empty;
			if (index < 0)
			{
				return false;
			}
			if (!TryGetCosmeticInfo(out var info) || (Object)(object)info == (Object)null || info.cosmetics == null)
			{
				return false;
			}
			if (index >= info.cosmetics.Length)
			{
				return false;
			}
			string name2 = info.cosmetics[index].name;
			if (string.IsNullOrWhiteSpace(name2))
			{
				return false;
			}
			name = name2.Trim();
			return true;
		}

		internal static bool IsPaintUnlocked(int index)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			if (index < 0)
			{
				return true;
			}
			if (!TryGetCosmeticInfo(out var info) || (Object)(object)info == (Object)null || info.cosmetics == null)
			{
				return false;
			}
			if (index >= info.cosmetics.Length)
			{
				return false;
			}
			try
			{
				string text = ((info.cosmetics[index].name != null) ? info.cosmetics[index].name.Trim() : string.Empty);
				if ((int)info.cosmetics[index].type != 2 && (string.IsNullOrWhiteSpace(text) || !text.EndsWith(" Paint", StringComparison.OrdinalIgnoreCase)))
				{
					return false;
				}
				bool unlocked = info.cosmetics[index].unlocked;
				if (string.IsNullOrWhiteSpace(text))
				{
					return unlocked;
				}
				return sSaveSystem.GetBool("costmeticUnlocked_" + text, unlocked);
			}
			catch
			{
				return (int)info.cosmetics[index].type == 2 && info.cosmetics[index].unlocked;
			}
		}

		internal static bool TryGetPaintCosmeticTexture(int index, out Texture texture)
		{
			texture = null;
			if (index < 0)
			{
				return false;
			}
			try
			{
				if (!TryGetCosmeticInfo(out var info) || (Object)(object)info == (Object)null || info.cosmetics == null)
				{
					return false;
				}
				if (index >= info.cosmetics.Length)
				{
					return false;
				}
				texture = info.cosmetics[index].texture;
				return (Object)(object)texture != (Object)null;
			}
			catch
			{
				texture = null;
				return false;
			}
		}

		internal static int GetSelectedPaintIndexUnlockedOrDefault()
		{
			int selectedPaintIndex = GetSelectedPaintIndex();
			if (!IsPaintUnlocked(selectedPaintIndex))
			{
				return -1;
			}
			return selectedPaintIndex;
		}

		internal static void SetSelectedPaintIndex(int index)
		{
			if (!IsPaintUnlocked(index))
			{
				index = -1;
			}
			try
			{
				if (TryGetCosmeticInfo(out var info) && (Object)(object)info != (Object)null)
				{
					info.SetPlayerEquiped(index, (Type)2);
					return;
				}
			}
			catch
			{
			}
			try
			{
				sSaveSystem.SetInt("playerEquipedPaint", index);
			}
			catch
			{
			}
		}

		internal static void CyclePaintSelection()
		{
			int selectedPaintIndexUnlockedOrDefault = GetSelectedPaintIndexUnlockedOrDefault();
			_tmpIntList.Clear();
			if (TryGetCosmeticInfo(out var info) && (Object)(object)info != (Object)null && info.cosmetics != null)
			{
				for (int i = 0; i < info.cosmetics.Length; i++)
				{
					if (IsPaintUnlocked(i))
					{
						_tmpIntList.Add(i);
					}
				}
			}
			if (_tmpIntList.Count == 0)
			{
				SetSelectedPaintIndex(-1);
				return;
			}
			if (selectedPaintIndexUnlockedOrDefault < 0)
			{
				SetSelectedPaintIndex(_tmpIntList[0]);
				return;
			}
			int num = _tmpIntList.IndexOf(selectedPaintIndexUnlockedOrDefault);
			if (num < 0)
			{
				SetSelectedPaintIndex(_tmpIntList[0]);
			}
			else if (num + 1 >= _tmpIntList.Count)
			{
				SetSelectedPaintIndex(-1);
			}
			else
			{
				SetSelectedPaintIndex(_tmpIntList[num + 1]);
			}
		}

		internal static bool HasAnyUnlockedPaints()
		{
			if (!TryGetCosmeticInfo(out var info) || (Object)(object)info == (Object)null || info.cosmetics == null)
			{
				return false;
			}
			for (int i = 0; i < info.cosmetics.Length; i++)
			{
				if (IsPaintUnlocked(i))
				{
					return true;
				}
			}
			return false;
		}

		internal static int GetManualGearCount()
		{
			return Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_ManualGearCount", 5), 3, 6);
		}

		internal static void SetManualGearCount(int count)
		{
			count = Mathf.Clamp(count, 3, 6);
			PlayerPrefs.SetInt("SebTruck_ManualGearCount", count);
			if (_manualGear > count)
			{
				_manualGear = count;
			}
		}

		internal static int NextManualGearCount(int count)
		{
			count++;
			if (count > 6)
			{
				count = 3;
			}
			return count;
		}

		internal static bool GetManualTransmissionEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_ManualTransmission", 0) != 0;
		}

		internal static void SetManualTransmissionEnabled(bool enabled)
		{
			bool manualTransmissionEnabled = GetManualTransmissionEnabled();
			_manualTransmissionEnabled = enabled;
			PlayerPrefs.SetInt("SebTruck_ManualTransmission", enabled ? 1 : 0);
			if (!enabled)
			{
				_manualGear = Mathf.Clamp(_manualGear, 1, GetManualGearCount());
			}
			else if (_manualGear == 0)
			{
				_manualGear = 1;
			}
			if (manualTransmissionEnabled != enabled)
			{
				LogDebug("Manual transmission: " + (enabled ? "ON" : "OFF"));
			}
		}

		internal static void ToggleManualTransmission()
		{
			SetManualTransmissionEnabled(!GetManualTransmissionEnabled());
		}

		internal static int GetManualGear()
		{
			return _manualGear;
		}

		internal static void SetManualGearDirect(int gear)
		{
			if (GetManualTransmissionEnabled())
			{
				int manualGearCount = GetManualGearCount();
				int manualGear = _manualGear;
				gear = ((gear > 0) ? Mathf.Clamp(gear, 1, manualGearCount) : ((gear < 0) ? (-1) : 0));
				_manualGear = gear;
				if (manualGear != _manualGear)
				{
					LogDebug("Gear: " + manualGear + " -> " + _manualGear);
				}
			}
		}

		internal static string GetManualGearLabel()
		{
			if (_manualGear < 0)
			{
				return "R";
			}
			if (_manualGear == 0)
			{
				return "N";
			}
			return _manualGear.ToString();
		}

		internal static void ShiftManualGear(int delta)
		{
			if (!GetManualTransmissionEnabled())
			{
				_manualGear = Mathf.Clamp(_manualGear, 1, GetManualGearCount());
				return;
			}
			int manualGear = _manualGear;
			int manualGearCount = GetManualGearCount();
			int manualGear2 = _manualGear;
			if (manualGear2 == 0)
			{
				manualGear2 = ((delta > 0) ? 1 : (-1));
			}
			else if (manualGear2 < 0)
			{
				manualGear2 = ((delta <= 0) ? (-1) : 0);
			}
			else
			{
				manualGear2 += delta;
				if (manualGear2 > manualGearCount)
				{
					manualGear2 = manualGearCount;
				}
				if (manualGear2 < 1)
				{
					manualGear2 = 0;
				}
			}
			_manualGear = manualGear2;
			if (manualGear != _manualGear)
			{
				LogDebug("Shift: " + manualGear + " -> " + _manualGear);
			}
		}

		internal static bool GetIgnitionEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_IgnitionEnabled", 1) != 0;
		}

		internal static void SetIgnitionEnabled(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_IgnitionEnabled", enabled ? 1 : 0);
		}

		internal static bool GetIgnitionFeatureEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_IgnitionFeatureEnabled", 1) != 0;
		}

		internal static void SetIgnitionFeatureEnabled(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_IgnitionFeatureEnabled", enabled ? 1 : 0);
		}

		internal static float GetIgnitionHoldSeconds()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_IgnitionHoldSeconds", 1.35f), 0.25f, 5f);
		}

		internal static void SetIgnitionHoldSeconds(float seconds)
		{
			PlayerPrefs.SetFloat("SebTruck_IgnitionHoldSeconds", Mathf.Clamp(seconds, 0.25f, 5f));
		}

		internal static bool GetIgnitionSfxEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_IgnitionSfxEnabled", 1) != 0;
		}

		internal static void SetIgnitionSfxEnabled(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_IgnitionSfxEnabled", enabled ? 1 : 0);
		}

		internal static float GetIgnitionSfxVolume()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_IgnitionSfxVolume", 0.15f), 0f, 1f);
		}

		internal static void SetIgnitionSfxVolume(float volume01)
		{
			PlayerPrefs.SetFloat("SebTruck_IgnitionSfxVolume", Mathf.Clamp01(volume01));
		}

		internal static bool GetIgnitionEnabledEffective()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			if (!GetIgnitionFeatureEnabled())
			{
				return true;
			}
			bool flag = false;
			try
			{
				BindingScheme[] array = (BindingScheme[])Enum.GetValues(typeof(BindingScheme));
				for (int i = 0; i < array.Length; i++)
				{
					int num = (int)array[i];
					BindingInput binding = BindingStore.GetBinding((BindingScheme)num, (BindingLayer)0, (BindAction)16);
					BindingInput binding2 = BindingStore.GetBinding((BindingScheme)num, (BindingLayer)1, (BindAction)16);
					if ((int)binding.Kind != 0 || (int)binding2.Kind != 0)
					{
						flag = true;
						break;
					}
				}
			}
			catch
			{
				flag = true;
			}
			if (!flag)
			{
				return true;
			}
			return GetIgnitionEnabled();
		}

		internal static bool GetIndicatorFeatureEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_IndicatorFeatureEnabled", 1) != 0;
		}

		internal static void SetIndicatorFeatureEnabled(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_IndicatorFeatureEnabled", enabled ? 1 : 0);
		}

		internal static bool GetIndicatorSfxEnabled()
		{
			return PlayerPrefs.GetInt("SebTruck_IndicatorSfxEnabled", 1) != 0;
		}

		internal static void SetIndicatorSfxEnabled(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_IndicatorSfxEnabled", enabled ? 1 : 0);
		}

		internal static float GetIndicatorSfxVolume()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_IndicatorSfxVolume", 1f), 0f, 1f);
		}

		internal static void SetIndicatorSfxVolume(float volume01)
		{
			PlayerPrefs.SetFloat("SebTruck_IndicatorSfxVolume", Mathf.Clamp01(volume01));
		}

		internal static float GetIndicatorBlinkSeconds()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_IndicatorBlinkSeconds", 0.45f), 0.15f, 1.5f);
		}

		internal static void SetIndicatorBlinkSeconds(float seconds)
		{
			PlayerPrefs.SetFloat("SebTruck_IndicatorBlinkSeconds", Mathf.Clamp(seconds, 0.15f, 1.5f));
		}

		internal static float GetTurnSignalLightIntensity()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_TurnSignalLightIntensity", 0.25f), 0f, 1f);
		}

		internal static void SetTurnSignalLightIntensity(float intensity)
		{
			PlayerPrefs.SetFloat("SebTruck_TurnSignalLightIntensity", Mathf.Clamp(intensity, 0f, 1f));
		}

		internal static bool GetHudShowSpeed()
		{
			return PlayerPrefs.GetInt("SebTruck_HudShowSpeed", 1) != 0;
		}

		internal static void SetHudShowSpeed(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_HudShowSpeed", enabled ? 1 : 0);
		}

		internal static bool GetHudShowTach()
		{
			return PlayerPrefs.GetInt("SebTruck_HudShowTach", 1) != 0;
		}

		internal static void SetHudShowTach(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_HudShowTach", enabled ? 1 : 0);
		}

		internal static bool GetHudShowGear()
		{
			return PlayerPrefs.GetInt("SebTruck_HudShowGear", 1) != 0;
		}

		internal static void SetHudShowGear(bool enabled)
		{
			PlayerPrefs.SetInt("SebTruck_HudShowGear", enabled ? 1 : 0);
		}

		internal static SpeedUnit GetHudSpeedUnit()
		{
			return (SpeedUnit)Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_HudSpeedUnits", 0), 0, 1);
		}

		internal static void SetHudSpeedUnit(SpeedUnit unit)
		{
			PlayerPrefs.SetInt("SebTruck_HudSpeedUnits", (int)unit);
		}

		internal static SpeedUnit NextHudSpeedUnit(SpeedUnit unit)
		{
			if (unit != 0)
			{
				return SpeedUnit.Kmh;
			}
			return SpeedUnit.Mph;
		}

		internal static string GetHudSpeedUnitLabel(SpeedUnit unit)
		{
			if (unit != SpeedUnit.Mph)
			{
				return "kmh";
			}
			return "mph";
		}

		internal static float ConvertSpeedForHud(float kmh)
		{
			if (GetHudSpeedUnit() != SpeedUnit.Mph)
			{
				return kmh;
			}
			return kmh * 0.621371f;
		}

		internal static HudReadoutAnchor GetHudReadoutAnchor()
		{
			return (HudReadoutAnchor)Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_HudReadoutAnchor", 0), 0, 1);
		}

		internal static void SetHudReadoutAnchor(HudReadoutAnchor anchor)
		{
			PlayerPrefs.SetInt("SebTruck_HudReadoutAnchor", (int)anchor);
		}

		internal static HudReadoutAnchor NextHudReadoutAnchor(HudReadoutAnchor anchor)
		{
			if (anchor != 0)
			{
				return HudReadoutAnchor.BottomLeft;
			}
			return HudReadoutAnchor.BottomRight;
		}

		internal static string GetHudReadoutAnchorLabel(HudReadoutAnchor anchor)
		{
			if (anchor != HudReadoutAnchor.BottomRight)
			{
				return "Bottom Left";
			}
			return "Bottom Right";
		}

		internal static HudReadoutAnchor GetHudSpeedAnchor()
		{
			if (!PlayerPrefs.HasKey("SebTruck_HudSpeedAnchor"))
			{
				return GetHudReadoutAnchor();
			}
			return (HudReadoutAnchor)Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_HudSpeedAnchor", (int)GetHudReadoutAnchor()), 0, 1);
		}

		internal static void SetHudSpeedAnchor(HudReadoutAnchor anchor)
		{
			PlayerPrefs.SetInt("SebTruck_HudSpeedAnchor", (int)anchor);
		}

		internal static HudReadoutAnchor GetHudTachAnchor()
		{
			if (!PlayerPrefs.HasKey("SebTruck_HudTachAnchor"))
			{
				return GetHudReadoutAnchor();
			}
			return (HudReadoutAnchor)Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_HudTachAnchor", (int)GetHudReadoutAnchor()), 0, 1);
		}

		internal static void SetHudTachAnchor(HudReadoutAnchor anchor)
		{
			PlayerPrefs.SetInt("SebTruck_HudTachAnchor", (int)anchor);
		}

		internal static HudReadoutAnchor GetHudGearAnchor()
		{
			if (!PlayerPrefs.HasKey("SebTruck_HudGearAnchor"))
			{
				return GetHudReadoutAnchor();
			}
			return (HudReadoutAnchor)Mathf.Clamp(PlayerPrefs.GetInt("SebTruck_HudGearAnchor", (int)GetHudReadoutAnchor()), 0, 1);
		}

		internal static void SetHudGearAnchor(HudReadoutAnchor anchor)
		{
			PlayerPrefs.SetInt("SebTruck_HudGearAnchor", (int)anchor);
		}

		internal static float GetManualSpeedMultForward()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_ManualSpeedMultFwd", 1f), 0.25f, 2f);
		}

		internal static void SetManualSpeedMultForward(float mult)
		{
			PlayerPrefs.SetFloat("SebTruck_ManualSpeedMultFwd", Mathf.Clamp(mult, 0.25f, 2f));
		}

		internal static float GetManualSpeedMultReverse()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_ManualSpeedMultRev", 1f), 0.25f, 2f);
		}

		internal static void SetManualSpeedMultReverse(float mult)
		{
			PlayerPrefs.SetFloat("SebTruck_ManualSpeedMultRev", Mathf.Clamp(mult, 0.25f, 2f));
		}

		internal static float GetHeadlightIntensityMult()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_HeadlightIntensityMult", 1f), 0.1f, 3f);
		}

		internal static void SetHeadlightIntensityMult(float mult)
		{
			PlayerPrefs.SetFloat("SebTruck_HeadlightIntensityMult", Mathf.Clamp(mult, 0.1f, 3f));
		}

		internal static float GetHeadlightRangeMult()
		{
			return Mathf.Clamp(PlayerPrefs.GetFloat("SebTruck_HeadlightRangeMult", 1f), 0.1f, 1f);
		}

		internal static void SetHeadlightRangeMult(float mult)
		{
			PlayerPrefs.SetFloat("SebTruck_HeadlightRangeMult", Mathf.Clamp(mult, 0.1f, 1f));
		}

		internal static void ResetVehicleDefaults()
		{
			SetManualTransmissionEnabled(enabled: false);
			SetManualGearCount(5);
			SetIgnitionFeatureEnabled(enabled: true);
			SetIgnitionEnabled(enabled: true);
			SetIgnitionHoldSeconds(1.35f);
			SetIgnitionSfxEnabled(enabled: true);
			SetIgnitionSfxVolume(0.15f);
			SetIndicatorFeatureEnabled(enabled: true);
			SetIndicatorSfxEnabled(enabled: true);
			SetIndicatorSfxVolume(1f);
			SetIndicatorBlinkSeconds(0.45f);
			SetManualSpeedMultForward(1f);
			SetManualSpeedMultReverse(1f);
			SetHeadlightIntensityMult(1f);
			SetHeadlightRangeMult(1f);
			PlayerPrefs.Save();
		}

		internal static void ResetTransmissionDefaults()
		{
			SetManualTransmissionEnabled(enabled: false);
			SetManualGearCount(5);
			PlayerPrefs.Save();
		}

		internal static void ResetIgnitionDefaults()
		{
			SetIgnitionFeatureEnabled(enabled: true);
			SetIgnitionEnabled(enabled: true);
			SetIgnitionHoldSeconds(1.35f);
			SetIgnitionSfxEnabled(enabled: true);
			SetIgnitionSfxVolume(0.15f);
			PlayerPrefs.Save();
		}

		internal static void ResetIndicatorDefaults()
		{
			SetIndicatorFeatureEnabled(enabled: true);
			SetIndicatorSfxEnabled(enabled: true);
			SetIndicatorSfxVolume(1f);
			SetIndicatorBlinkSeconds(0.45f);
			PlayerPrefs.Save();
		}

		internal static void ResetTweaksDefaults()
		{
			SetManualSpeedMultForward(1f);
			SetManualSpeedMultReverse(1f);
			SetHeadlightIntensityMult(1f);
			SetHeadlightRangeMult(1f);
			PlayerPrefs.Save();
		}

		internal static void ResetHudDefaults()
		{
			SetHudSpeedUnit(SpeedUnit.Kmh);
			SetHudShowSpeed(enabled: true);
			SetHudShowTach(enabled: true);
			SetHudShowGear(enabled: true);
			SetHudReadoutAnchor(HudReadoutAnchor.BottomLeft);
			PlayerPrefs.DeleteKey("SebTruck_HudSpeedAnchor");
			PlayerPrefs.DeleteKey("SebTruck_HudTachAnchor");
			PlayerPrefs.DeleteKey("SebTruck_HudGearAnchor");
			PlayerPrefs.Save();
		}

		private void Awake()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			_debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "debug_logging", false, "Log debug information (verbose).");
			_ignitionSfxOnPath = ((BaseUnityPlugin)this).Config.Bind<string>("Ignition", "sfx_on_path", "", "Optional ignition ON sound. File name inside the plugin's sfx folder (e.g. ignition_on.wav). Leave blank to use sfx/ignition_on.wav.");
			TryMigrateLegacyIgnitionSfxVolumeFromConfig();
			TryLoadIgnitionSfx();
			TryLoadTurnSignalEmissives();
			new Harmony("shibe.easydeliveryco.sebtruck").PatchAll(typeof(Plugin));
			try
			{
				BindAction[] array = new BindAction[7];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				SebBindsApi.RegisterActionsPage("sebtruck", "Truck", (BindAction[])(object)array);
			}
			catch
			{
			}
			Log.LogInfo((object)"Loaded");
		}

		private static Type FindTypeInLoadedAssemblies(string fullName)
		{
			try
			{
				Type type = Type.GetType(fullName + ", UnityEngine.ImageConversionModule", throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			catch
			{
			}
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly == null)
					{
						continue;
					}
					try
					{
						Type type2 = assembly.GetType(fullName, throwOnError: false);
						if (type2 != null)
						{
							return type2;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static bool TryLoadImageIntoTexture(Texture2D tex, byte[] bytes)
		{
			if ((Object)(object)tex == (Object)null || bytes == null || bytes.Length == 0)
			{
				return false;
			}
			try
			{
				Type type = FindTypeInLoadedAssemblies("UnityEngine.ImageConversion");
				if (type == null)
				{
					return false;
				}
				MethodInfo methodInfo = null;
				try
				{
					methodInfo = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
					{
						typeof(Texture2D),
						typeof(byte[]),
						typeof(bool)
					}, null);
				}
				catch
				{
				}
				if (methodInfo != null)
				{
					return !(methodInfo.Invoke(null, new object[3] { tex, bytes, true }) is bool flag) || flag;
				}
				try
				{
					methodInfo = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
					{
						typeof(Texture2D),
						typeof(byte[])
					}, null);
				}
				catch
				{
				}
				if (methodInfo != null)
				{
					return !(methodInfo.Invoke(null, new object[2] { tex, bytes }) is bool flag2) || flag2;
				}
			}
			catch
			{
			}
			return false;
		}

		private static Texture2D LoadPngOrNull(string path)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
			{
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				if (array == null || array.Length < 16)
				{
					return null;
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)0;
				((Object)val).hideFlags = (HideFlags)61;
				((Object)val).name = Path.GetFileName(path);
				if (!TryLoadImageIntoTexture(val, array))
				{
					return null;
				}
				return val;
			}
			catch
			{
				return null;
			}
		}

		private static void TryLoadTurnSignalEmissives()
		{
			if (_turnSignalEmissivesTriedLoad)
			{
				return;
			}
			_turnSignalEmissivesTriedLoad = true;
			try
			{
				string path = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? string.Empty, "emissives");
				_turnSignalEmissiveOff = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive.png"));
				_turnSignalEmissiveLeft = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive_left_signal.png"));
				_turnSignalEmissiveRight = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive_right_signal.png"));
				_turnSignalEmissiveBoth = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive_both_signal.png"));
				_turnSignalEmissiveBrakeOff = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive-Breaking.png"));
				_turnSignalEmissiveBrakeLeft = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive-Breaking_left_signal.png"));
				_turnSignalEmissiveBrakeRight = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive-Breaking_right_signal.png"));
				_turnSignalEmissiveBrakeBoth = LoadPngOrNull(Path.Combine(path, "truck_texture Emissive-Breaking_both_signal.png"));
				int num = 0;
				if ((Object)(object)_turnSignalEmissiveOff != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveLeft != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveRight != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveBoth != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveBrakeOff != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveBrakeLeft != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveBrakeRight != (Object)null)
				{
					num++;
				}
				if ((Object)(object)_turnSignalEmissiveBrakeBoth != (Object)null)
				{
					num++;
				}
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("Turn signal emissives: loaded " + num + "/8"));
				}
			}
			catch
			{
			}
		}

		internal static Texture2D GetTurnSignalEmissive(bool braking, int indicatorMode, bool blinkOn)
		{
			TryLoadTurnSignalEmissives();
			Texture2D result = (braking ? _turnSignalEmissiveBrakeOff : _turnSignalEmissiveOff);
			if (!blinkOn || indicatorMode == 0)
			{
				return result;
			}
			Texture2D val = (braking ? _turnSignalEmissiveBrakeLeft : _turnSignalEmissiveLeft);
			Texture2D val2 = (braking ? _turnSignalEmissiveBrakeRight : _turnSignalEmissiveRight);
			Texture2D val3 = (braking ? _turnSignalEmissiveBrakeBoth : _turnSignalEmissiveBoth);
			switch (indicatorMode)
			{
			case 1:
				if (!((Object)(object)val != (Object)null))
				{
					return result;
				}
				return val;
			case 2:
				if (!((Object)(object)val2 != (Object)null))
				{
					return result;
				}
				return val2;
			case 3:
				if (!((Object)(object)val3 != (Object)null))
				{
					return result;
				}
				return val3;
			default:
				return result;
			}
		}

		private static void TryMigrateLegacyIgnitionSfxVolumeFromConfig()
		{
			try
			{
				if (PlayerPrefs.HasKey("SebTruck_IgnitionSfxVolume"))
				{
					return;
				}
				string path = Path.Combine(Paths.ConfigPath, "shibe.easydeliveryco.sebtruck.cfg");
				if (!File.Exists(path))
				{
					return;
				}
				bool flag = false;
				float num = -1f;
				string[] array = File.ReadAllLines(path);
				foreach (string text in array)
				{
					string text2 = ((text != null) ? text.Trim() : string.Empty);
					if (string.IsNullOrWhiteSpace(text2) || text2.StartsWith("#") || text2.StartsWith(";"))
					{
						continue;
					}
					if (text2.StartsWith("[") && text2.EndsWith("]"))
					{
						flag = string.Equals(text2.Substring(1, text2.Length - 2).Trim(), "Ignition", StringComparison.OrdinalIgnoreCase);
					}
					else
					{
						if (!flag)
						{
							continue;
						}
						int num2 = text2.IndexOf('=');
						if (num2 <= 0)
						{
							continue;
						}
						string a = text2.Substring(0, num2).Trim();
						string s = text2.Substring(num2 + 1).Trim();
						if (string.Equals(a, "sfx_volume", StringComparison.OrdinalIgnoreCase))
						{
							if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
							{
								num = Mathf.Clamp01(result);
							}
							else if (float.TryParse(s, out result))
							{
								num = Mathf.Clamp01(result);
							}
							break;
						}
					}
				}
				if (num >= 0f)
				{
					SetIgnitionSfxVolume(num);
					PlayerPrefs.Save();
					LogDebug("Migrated legacy ignition volume from config: " + num.ToString("0.00", CultureInfo.InvariantCulture));
				}
			}
			catch
			{
			}
		}

		internal static void LogDebug(string msg)
		{
			if (_debugLogging != null && _debugLogging.Value)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogMessage((object)msg);
				}
			}
		}

		private static void TryLoadIgnitionSfx()
		{
			string dir = Path.GetDirectoryName(typeof(Plugin).Assembly.Location) ?? string.Empty;
			_ignitionSfxOn = LoadWavOrNull(Resolve((_ignitionSfxOnPath != null) ? _ignitionSfxOnPath.Value : string.Empty, "ignition_on"));
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("Ignition SFX: on=" + (_ignitionSfxOn != (Object)null)));
			}
			string Resolve(string cfg, string baseName)
			{
				string path = Path.Combine(dir, "sfx");
				if (string.IsNullOrWhiteSpace(cfg))
				{
					string text = Path.Combine(path, baseName + ".wav");
					if (!File.Exists(text))
					{
						return string.Empty;
					}
					return text;
				}
				if (Path.IsPathRooted(cfg))
				{
					return cfg;
				}
				string text2 = Path.Combine(path, cfg);
				if (!File.Exists(text2))
				{
					return string.Empty;
				}
				return text2;
			}
		}

		private static Object LoadWavOrNull(string path)
		{
			if (string.IsNullOrWhiteSpace(path))
			{
				return null;
			}
			if (!string.Equals(Path.GetExtension(path), ".wav", StringComparison.OrdinalIgnoreCase))
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Ignition SFX: only .wav is supported in this build: " + path));
				}
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				if (array.Length < 44)
				{
					throw new Exception("WAV too small");
				}
				if (Encoding.ASCII.GetString(array, 0, 4) != "RIFF" || Encoding.ASCII.GetString(array, 8, 4) != "WAVE")
				{
					throw new Exception("Not a RIFF/WAVE file");
				}
				int num = BitConverter.ToInt16(array, 22);
				int sampleRate = BitConverter.ToInt32(array, 24);
				int num2 = BitConverter.ToInt16(array, 34);
				if (num2 != 16)
				{
					throw new Exception("Unsupported bit depth: " + num2);
				}
				int num3 = 12;
				int num4 = -1;
				int num5 = 0;
				while (num3 + 8 <= array.Length)
				{
					string @string = Encoding.ASCII.GetString(array, num3, 4);
					int num6 = BitConverter.ToInt32(array, num3 + 4);
					int num7 = num3 + 8;
					if (num7 + num6 > array.Length)
					{
						break;
					}
					if (@string == "data")
					{
						num4 = num7;
						num5 = num6;
						break;
					}
					num3 = num7 + num6;
					if ((num3 & 1) == 1)
					{
						num3++;
					}
				}
				if (num4 < 0 || num5 <= 0)
				{
					throw new Exception("Missing data chunk");
				}
				int num8 = num5 / 2;
				float[] array2 = new float[num8];
				int num9 = 0;
				for (int i = 0; i + 1 < num5; i += 2)
				{
					short num10 = BitConverter.ToInt16(array, num4 + i);
					array2[num9++] = (float)num10 / 32768f;
				}
				return CreateAudioClip("ignition_on", num8 / Math.Max(1, num), num, sampleRate, array2);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("Ignition SFX load failed: " + path + " (" + ex.Message + ")"));
				}
				return null;
			}
		}

		private static Object CreateAudioClip(string name, int samplesPerChannel, int channels, int sampleRate, float[] data)
		{
			try
			{
				Type type = Type.GetType("UnityEngine.AudioClip, UnityEngine.AudioModule");
				if (type == null)
				{
					return null;
				}
				MethodInfo method = type.GetMethod("Create", BindingFlags.Static | BindingFlags.Public, null, new Type[5]
				{
					typeof(string),
					typeof(int),
					typeof(int),
					typeof(int),
					typeof(bool)
				}, null);
				if (method == null)
				{
					return null;
				}
				object obj = method.Invoke(null, new object[5] { name, samplesPerChannel, channels, sampleRate, false });
				if (obj == null)
				{
					return null;
				}
				MethodInfo method2 = type.GetMethod("SetData", new Type[2]
				{
					typeof(float[]),
					typeof(int)
				});
				if (method2 != null)
				{
					method2.Invoke(obj, new object[2] { data, 0 });
				}
				return (Object)((obj is Object) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		internal static void PlayIgnitionOnSfx(sCarController car)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (!GetIgnitionSfxEnabled() || _ignitionSfxOn == (Object)null || (Object)(object)car == (Object)null)
			{
				return;
			}
			float ignitionSfxVolume = GetIgnitionSfxVolume();
			try
			{
				GameObject val = null;
				if ((Object)(object)car.headlights != (Object)null)
				{
					val = ((Component)car.headlights).gameObject;
				}
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)car).gameObject;
				}
				GameObject val2 = new GameObject("SebTruck_IgnitionSFX");
				((Object)val2).hideFlags = (HideFlags)61;
				val2.transform.SetParent(val.transform, false);
				Type type = Type.GetType("UnityEngine.AudioSource, UnityEngine.AudioModule");
				if (!(type == null))
				{
					Component c = val2.AddComponent(type);
					SetProp(c, "spatialBlend", 0f);
					SetProp(c, "volume", ignitionSfxVolume);
					SetProp(c, "playOnAwake", false);
					SetProp(c, "loop", false);
					SetProp(c, "clip", _ignitionSfxOn);
					Call(c, "Play");
					Object.Destroy((Object)(object)val2, 5f);
				}
			}
			catch
			{
			}
		}

		private static void SetProp(Component c, string name, object value)
		{
			if ((Object)(object)c == (Object)null || string.IsNullOrWhiteSpace(name))
			{
				return;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name);
				if (property != null && property.CanWrite)
				{
					property.SetValue(c, value, null);
				}
			}
			catch
			{
			}
		}

		private static float GetFloatProp(Component c, string name, float def = 0f)
		{
			if ((Object)(object)c == (Object)null || string.IsNullOrWhiteSpace(name))
			{
				return def;
			}
			try
			{
				PropertyInfo property = ((object)c).GetType().GetProperty(name);
				if (property != null && property.CanRead)
				{
					object value = property.GetValue(c, null);
					if (value is float result)
					{
						return result;
					}
					if (value is double num)
					{
						return (float)num;
					}
					if (value is int)
					{
						int num2 = (int)value;
						return num2;
					}
				}
			}
			catch
			{
			}
			return def;
		}

		private static void Call(Component c, string method, params object[] args)
		{
			if ((Object)(object)c == (Object)null || string.IsNullOrWhiteSpace(method))
			{
				return;
			}
			try
			{
				MethodInfo[] methods = ((object)c).GetType().GetMethods();
				MethodInfo methodInfo = null;
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (!(methodInfo2 == null) && string.Equals(methodInfo2.Name, method, StringComparison.Ordinal))
					{
						ParameterInfo[] parameters = methodInfo2.GetParameters();
						if (parameters != null && parameters.Length == ((args != null) ? args.Length : 0))
						{
							methodInfo = methodInfo2;
							break;
						}
					}
				}
				if (methodInfo != null)
				{
					methodInfo.Invoke(c, args);
				}
			}
			catch
			{
			}
		}

		internal static void PlayIndicatorClick(sCarController car, bool highPitch)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			if (!GetIndicatorSfxEnabled() || (Object)(object)car == (Object)null || car.GuyActive)
			{
				return;
			}
			Headlights headlights = car.headlights;
			if ((Object)(object)headlights == (Object)null)
			{
				return;
			}
			try
			{
				object? obj = AccessTools.Field(((object)headlights).GetType(), "headlightsOff")?.GetValue(headlights);
				Object val = (Object)((obj is Object) ? obj : null);
				if (val == (Object)null)
				{
					return;
				}
				float num = 0.22f * GetIndicatorSfxVolume();
				if (num <= 0.001f)
				{
					return;
				}
				float num2 = (highPitch ? 1.08f : 0.92f);
				if ((Object)(object)_indicatorClickSfxGo == (Object)null)
				{
					_indicatorClickSfxGo = new GameObject("SebTruck_IndicatorClickSFX");
					((Object)_indicatorClickSfxGo).hideFlags = (HideFlags)61;
					Type type = Type.GetType("UnityEngine.AudioSource, UnityEngine.AudioModule");
					if (type == null)
					{
						return;
					}
					_indicatorClickSfxSource = _indicatorClickSfxGo.AddComponent(type);
					SetProp(_indicatorClickSfxSource, "loop", false);
					SetProp(_indicatorClickSfxSource, "playOnAwake", false);
					SetProp(_indicatorClickSfxSource, "spatialBlend", 1f);
					SetProp(_indicatorClickSfxSource, "dopplerLevel", 0f);
					SetProp(_indicatorClickSfxSource, "minDistance", 3f);
					SetProp(_indicatorClickSfxSource, "maxDistance", 30f);
				}
				if ((Object)(object)_indicatorClickSfxGo.transform.parent != (Object)(object)((Component)car).transform)
				{
					_indicatorClickSfxGo.transform.SetParent(((Component)car).transform, false);
				}
				_indicatorClickSfxGo.transform.localPosition = Vector3.zero;
				SetProp(_indicatorClickSfxSource, "volume", num);
				SetProp(_indicatorClickSfxSource, "pitch", num2);
				Call(_indicatorClickSfxSource, "PlayOneShot", val, num);
			}
			catch
			{
			}
		}

		internal static void StartIgnitionHoldSfx(sCarController car)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (!GetIgnitionSfxEnabled() || _ignitionSfxOn == (Object)null || (Object)(object)car == (Object)null || car.GuyActive)
			{
				return;
			}
			float ignitionSfxVolume = GetIgnitionSfxVolume();
			if (ignitionSfxVolume <= 0.001f)
			{
				return;
			}
			try
			{
				if ((Object)(object)_ignitionHoldSfxGo == (Object)null)
				{
					_ignitionHoldSfxGo = new GameObject("SebTruck_IgnitionHoldSFX");
					((Object)_ignitionHoldSfxGo).hideFlags = (HideFlags)61;
					Type type = Type.GetType("UnityEngine.AudioSource, UnityEngine.AudioModule");
					if (type == null)
					{
						return;
					}
					_ignitionHoldSfxSource = _ignitionHoldSfxGo.AddComponent(type);
					SetProp(_ignitionHoldSfxSource, "loop", false);
					SetProp(_ignitionHoldSfxSource, "playOnAwake", false);
					SetProp(_ignitionHoldSfxSource, "spatialBlend", 1f);
					SetProp(_ignitionHoldSfxSource, "dopplerLevel", 0f);
					SetProp(_ignitionHoldSfxSource, "minDistance", 5f);
					SetProp(_ignitionHoldSfxSource, "maxDistance", 40f);
				}
				if ((Object)(object)_ignitionHoldSfxGo.transform.parent != (Object)(object)((Component)car).transform)
				{
					_ignitionHoldSfxGo.transform.SetParent(((Component)car).transform, false);
				}
				_ignitionHoldSfxGo.transform.localPosition = Vector3.zero;
				SetProp(_ignitionHoldSfxSource, "volume", ignitionSfxVolume);
				SetProp(_ignitionHoldSfxSource, "clip", _ignitionSfxOn);
				bool flag = false;
				try
				{
					PropertyInfo property = ((object)_ignitionHoldSfxSource).GetType().GetProperty("isPlaying");
					if (property != null)
					{
						flag = (bool)property.GetValue(_ignitionHoldSfxSource, null);
					}
				}
				catch
				{
				}
				if (!flag)
				{
					Call(_ignitionHoldSfxSource, "Play");
				}
			}
			catch
			{
			}
		}

		internal static void StopIgnitionHoldSfx()
		{
			try
			{
				if ((Object)(object)_ignitionHoldSfxSource != (Object)null)
				{
					Call(_ignitionHoldSfxSource, "Stop");
				}
			}
			catch
			{
			}
		}

		private static void EnsureHeadlightsRefs(object instance)
		{
			if (instance != null)
			{
				Type type = instance.GetType();
				if (!(_headlightsRuntimeType == type))
				{
					_headlightsRuntimeType = type;
					_headlightsHeadLightsField = AccessTools.Field(type, "headLights");
					_headlightsCarMatField = AccessTools.Field(type, "carMat");
					_headlightsEmissiveRegularField = AccessTools.Field(type, "emissiveRegular");
					_headlightsHeadlightsOnField = AccessTools.Field(type, "headlightsOn");
					_headlightsModelField = AccessTools.Field(type, "model");
				}
			}
		}

		private static void EnsureRadioRefs()
		{
			if (!(_radioTargetVolumeField != null))
			{
				_radioTargetVolumeField = AccessTools.Field(typeof(sRadioSystem), "targetVolume");
				_radioRadioVolumeField = AccessTools.Field(typeof(sRadioSystem), "radioVolume");
				_radioSourceField = AccessTools.Field(typeof(sRadioSystem), "source");
				_radioNoiseField = AccessTools.Field(typeof(sRadioSystem), "noise");
			}
		}

		private static void EnsureCarDamageRefs()
		{
			if (_carDamageCarMatField != null)
			{
				return;
			}
			try
			{
				_carDamageCarMatField = AccessTools.Field(typeof(CarDamage), "carMat");
			}
			catch
			{
				_carDamageCarMatField = null;
			}
		}

		private static Material FindMaterialByName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return null;
			}
			string text = name.Trim();
			if (_paintMaterialCache.TryGetValue(text, out var value))
			{
				return value;
			}
			try
			{
				Material[] array = Resources.FindObjectsOfTypeAll<Material>();
				if (array != null)
				{
					foreach (Material val in array)
					{
						if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, text, StringComparison.OrdinalIgnoreCase))
						{
							_paintMaterialCache[text] = val;
							return val;
						}
					}
				}
			}
			catch
			{
			}
			_paintMaterialCache[text] = null;
			return null;
		}

		private static string DeriveTruckPaintMaterialName(string cosmeticName)
		{
			if (string.IsNullOrWhiteSpace(cosmeticName))
			{
				return string.Empty;
			}
			string text = cosmeticName.Trim();
			if (text.Length == 0)
			{
				return string.Empty;
			}
			if (text.StartsWith("truck_texture", StringComparison.OrdinalIgnoreCase))
			{
				return text;
			}
			if (text.EndsWith(" paint", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - 5).Trim();
			}
			string text2 = text.ToLowerInvariant().Replace(' ', '_');
			if (text2 == "default" || text2 == "white")
			{
				return "truck_texture";
			}
			return "truck_texture_" + text2;
		}

		private static bool IsTailgateRenderer(MeshRenderer mr)
		{
			if ((Object)(object)mr == (Object)null)
			{
				return false;
			}
			try
			{
				string name = ((Object)mr).name;
				if (!string.IsNullOrWhiteSpace(name) && name.IndexOf("tailgate", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static int ComputeTailgateSignature(sCarController car)
		{
			if ((Object)(object)car == (Object)null)
			{
				return 0;
			}
			int num = 17;
			try
			{
				MeshRenderer[] componentsInChildren = ((Component)car).GetComponentsInChildren<MeshRenderer>(true);
				if (componentsInChildren != null)
				{
					foreach (MeshRenderer val in componentsInChildren)
					{
						if (IsTailgateRenderer(val))
						{
							num = num * 31 + ((Object)val).GetInstanceID();
							num = num * 31 + (((Object)(object)((Component)val).gameObject != (Object)null && ((Component)val).gameObject.activeInHierarchy) ? 1 : 0);
						}
					}
				}
			}
			catch
			{
			}
			return num;
		}

		private static bool IsTruckPaintMaterial(Material m)
		{
			if ((Object)(object)m == (Object)null)
			{
				return false;
			}
			try
			{
				return ((Object)m).name != null && ((Object)m).name.IndexOf("truck_texture", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			catch
			{
				return false;
			}
		}

		private static void ApplyTailgatePaintMaterialIfPresent(sCarController car, Material paintMat)
		{
			if ((Object)(object)car == (Object)null || (Object)(object)paintMat == (Object)null)
			{
				return;
			}
			try
			{
				MeshRenderer[] componentsInChildren = ((Component)car).GetComponentsInChildren<MeshRenderer>(true);
				if (componentsInChildren == null)
				{
					return;
				}
				foreach (MeshRenderer val in componentsInChildren)
				{
					if (!IsTailgateRenderer(val))
					{
						continue;
					}
					Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
					if (sharedMaterials == null || sharedMaterials.Length == 0)
					{
						continue;
					}
					bool flag = false;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						if (IsTruckPaintMaterial(sharedMaterials[j]) && sharedMaterials[j] != paintMat)
						{
							sharedMaterials[j] = paintMat;
							flag = true;
						}
					}
					if (flag)
					{
						((Renderer)val).sharedMaterials = sharedMaterials;
					}
				}
			}
			catch
			{
			}
		}

		private static void ApplyTruckPaintIfNeeded(sCarController car)
		{
			if ((Object)(object)car == (Object)null || !IsTruckCar(car))
			{
				return;
			}
			int instanceID = ((Object)car).GetInstanceID();
			int selectedPaintIndex = GetSelectedPaintIndex();
			bool num = instanceID != _paintLastCarId || selectedPaintIndex != _paintLastIndex;
			float unscaledTime = Time.unscaledTime;
			bool flag = num;
			if (!flag && (!_paintNextTailgateRescanTimeByCarId.TryGetValue(instanceID, out var value) || unscaledTime >= value))
			{
				flag = true;
			}
			if (!num && !flag)
			{
				return;
			}
			_paintLastCarId = instanceID;
			_paintLastIndex = selectedPaintIndex;
			_paintNextTailgateRescanTimeByCarId[instanceID] = unscaledTime + 1f;
			try
			{
				Headlights headlights = car.headlights;
				if ((Object)(object)headlights == (Object)null)
				{
					return;
				}
				EnsureHeadlightsRefs(headlights);
				GameObject val = (GameObject)((_headlightsModelField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				MeshRenderer component = val.GetComponent<MeshRenderer>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				Material material = ((Renderer)component).material;
				if ((Object)(object)material == (Object)null)
				{
					return;
				}
				if (!_paintDefaultsByCarId.ContainsKey(instanceID))
				{
					PaintDefaults value2 = default(PaintDefaults);
					try
					{
						if (material.HasProperty("_BaseMap"))
						{
							value2.baseMap = material.GetTexture("_BaseMap");
						}
					}
					catch
					{
					}
					try
					{
						if (material.HasProperty("_MainTex"))
						{
							value2.mainTex = material.GetTexture("_MainTex");
						}
					}
					catch
					{
					}
					_paintDefaultsByCarId[instanceID] = value2;
				}
				bool flag2 = false;
				Texture texture;
				if (selectedPaintIndex < 0)
				{
					if (_paintDefaultsByCarId.TryGetValue(instanceID, out var value3))
					{
						try
						{
							if (material.HasProperty("_BaseMap"))
							{
								material.SetTexture("_BaseMap", value3.baseMap);
							}
						}
						catch
						{
						}
						try
						{
							if (material.HasProperty("_MainTex"))
							{
								material.SetTexture("_MainTex", value3.mainTex);
							}
						}
						catch
						{
						}
						flag2 = true;
					}
				}
				else if (TryGetPaintCosmeticTexture(selectedPaintIndex, out texture) && (Object)(object)texture != (Object)null)
				{
					try
					{
						if (material.HasProperty("_BaseMap"))
						{
							material.SetTexture("_BaseMap", texture);
						}
					}
					catch
					{
					}
					try
					{
						if (material.HasProperty("_MainTex"))
						{
							material.SetTexture("_MainTex", texture);
						}
					}
					catch
					{
					}
					flag2 = true;
				}
				if (!flag2)
				{
					string name = ((selectedPaintIndex < 0) ? "truck_texture" : null);
					if (selectedPaintIndex >= 0 && !TryGetPaintCosmeticName(selectedPaintIndex, out name))
					{
						return;
					}
					Material val2 = FindMaterialByName(name);
					if ((Object)(object)val2 == (Object)null)
					{
						string text = DeriveTruckPaintMaterialName(name);
						val2 = FindMaterialByName(text);
						if ((Object)(object)val2 == (Object)null && string.Equals(text, "truck_texture", StringComparison.OrdinalIgnoreCase))
						{
							val2 = FindMaterialByName("truck_texture_white");
						}
						if ((Object)(object)val2 == (Object)null)
						{
							LogDebug("Paint material not found: " + name + " (derived=" + text + ")");
							return;
						}
					}
					((Renderer)component).material = val2;
					material = ((Renderer)component).material;
				}
				try
				{
					_headlightsCarMatField?.SetValue(headlights, material);
				}
				catch
				{
				}
				if (flag)
				{
					ApplyTailgatePaintMaterialIfPresent(car, material);
				}
				EnsureCarDamageRefs();
				if (!(_carDamageCarMatField != null))
				{
					return;
				}
				CarDamage componentInChildren = ((Component)car).GetComponentInChildren<CarDamage>(true);
				if (!((Object)(object)componentInChildren != (Object)null))
				{
					return;
				}
				try
				{
					_carDamageCarMatField.SetValue(componentInChildren, material);
				}
				catch
				{
				}
			}
			catch
			{
			}
		}

		private static void MuteRadioProximityIfIgnitionOff(sRadioSystem radio)
		{
			if ((Object)(object)radio == (Object)null || (Object)(object)radio.car == (Object)null || !radio.car.GuyActive || !GetIgnitionFeatureEnabled() || GetIgnitionEnabledEffective())
			{
				return;
			}
			EnsureRadioRefs();
			try
			{
				_radioTargetVolumeField?.SetValue(radio, 0f);
				_radioRadioVolumeField?.SetValue(radio, 0f);
				Component val = (Component)((_radioSourceField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val != (Object)null)
				{
					SetProp(val, "volume", 0f);
				}
				Component val2 = (Component)((_radioNoiseField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val2 != (Object)null)
				{
					SetProp(val2, "volume", 0f);
				}
			}
			catch
			{
			}
		}

		private static bool IsTruckCar(sCarController car)
		{
			if ((Object)(object)car == (Object)null)
			{
				return false;
			}
			int instanceID;
			try
			{
				instanceID = ((Object)car).GetInstanceID();
			}
			catch
			{
				return false;
			}
			if (_isTruckCarById.TryGetValue(instanceID, out var value))
			{
				return value;
			}
			try
			{
				bool flag = (Object)(object)((Component)car).GetComponentInChildren<sTruckSFX>(true) != (Object)null;
				_isTruckCarById[instanceID] = flag;
				return flag;
			}
			catch
			{
				_isTruckCarById[instanceID] = false;
				return false;
			}
		}

		private static bool GetTruckBraking(sCarController car)
		{
			if ((Object)(object)car == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)car).GetInstanceID();
			if (_truckBraking.TryGetValue(instanceID, out var value))
			{
				return value;
			}
			return false;
		}

		private static void SetTruckBraking(sCarController car, bool braking)
		{
			if (!((Object)(object)car == (Object)null))
			{
				_truckBraking[((Object)car).GetInstanceID()] = braking;
			}
		}

		private static void ApplyTruckEmissionMap(sCarController car)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)car == (Object)null || !GetIgnitionEnabledEffective() || !IsTruckCar(car))
			{
				return;
			}
			Headlights headlights = car.headlights;
			if ((Object)(object)headlights == (Object)null)
			{
				return;
			}
			EnsureHeadlightsRefs(headlights);
			Material val = (Material)((_headlightsCarMatField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Texture2D val2 = GetTurnSignalEmissive(GetTruckBraking(car), blinkOn: _indicatorMode != 0 && _indicatorBlinkOn, indicatorMode: (int)_indicatorMode);
			if (!((Object)(object)val2 != (Object)null))
			{
				return;
			}
			val.SetTexture("_EmissionMap", (Texture)(object)val2);
			try
			{
				if (val.HasProperty("_EmissionColor"))
				{
					val.SetColor("_EmissionColor", Color.white);
				}
			}
			catch
			{
			}
		}

		private static bool TryComputeModelBoundsInCarLocal(sCarController car, out Vector3 min, out Vector3 max)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//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_01d3: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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)
			min = Vector3.zero;
			max = Vector3.zero;
			if ((Object)(object)car == (Object)null)
			{
				return false;
			}
			Headlights headlights = car.headlights;
			if ((Object)(object)headlights == (Object)null)
			{
				return false;
			}
			EnsureHeadlightsRefs(headlights);
			GameObject val = (GameObject)((_headlightsModelField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			bool any = false;
			Vector3 vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
			Vector3 vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
			try
			{
				MeshFilter[] componentsInChildren = val.GetComponentsInChildren<MeshFilter>(true);
				if (componentsInChildren != null)
				{
					foreach (MeshFilter val2 in componentsInChildren)
					{
						if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null)
						{
							continue;
						}
						Bounds bounds = val2.sharedMesh.bounds;
						Vector3 center = ((Bounds)(ref bounds)).center;
						Vector3 extents = ((Bounds)(ref bounds)).extents;
						Transform transform = ((Component)val2).transform;
						for (int j = -1; j <= 1; j += 2)
						{
							for (int k = -1; k <= 1; k += 2)
							{
								for (int l = -1; l <= 1; l += 2)
								{
									Vector3 val3 = center + new Vector3(extents.x * (float)j, extents.y * (float)k, extents.z * (float)l);
									Vector3 val4 = transform.TransformPoint(val3);
									AddPoint(((Component)car).transform.InverseTransformPoint(val4));
								}
							}
						}
					}
				}
			}
			catch
			{
			}
			if (!any)
			{
				try
				{
					Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>(true);
					if (componentsInChildren2 != null)
					{
						foreach (Renderer val5 in componentsInChildren2)
						{
							if ((Object)(object)val5 == (Object)null)
							{
								continue;
							}
							Bounds bounds2 = val5.bounds;
							Vector3 center2 = ((Bounds)(ref bounds2)).center;
							Vector3 extents2 = ((Bounds)(ref bounds2)).extents;
							for (int n = -1; n <= 1; n += 2)
							{
								for (int num = -1; num <= 1; num += 2)
								{
									for (int num2 = -1; num2 <= 1; num2 += 2)
									{
										Vector3 val6 = center2 + new Vector3(extents2.x * (float)n, extents2.y * (float)num, extents2.z * (float)num2);
										AddPoint(((Component)car).transform.InverseTransformPoint(val6));
									}
								}
							}
						}
					}
				}
				catch
				{
				}
			}
			if (!any)
			{
				return false;
			}
			min = vMin;
			max = vMax;
			return true;
			void AddPoint(Vector3 p)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//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_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				if (!any)
				{
					any = true;
					vMin = p;
					vMax = p;
				}
				else
				{
					vMin = Vector3.Min(vMin, p);
					vMax = Vector3.Max(vMax, p);
				}
			}
		}

		private static void EnsureTurnSignalLightRig(sCarController car)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)car == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)car).GetInstanceID();
			if (_turnSignalLightRigs.TryGetValue(instanceID, out var value) && value != null && (Object)(object)value.Root != (Object)null)
			{
				if ((Object)(object)value.Root.transform.parent != (Object)(object)((Component)car).transform)
				{
					value.Root.transform.SetParent(((Component)car).transform, false);
				}
				return;
			}
			value = new TurnSignalLightRig();
			_turnSignalLightRigs[instanceID] = value;
			GameObject root = new GameObject("SebTruck_TurnSignalLights");
			((Object)root).hideFlags = (HideFlags)61;
			root.transform.SetParent(((Component)car).transform, false);
			root.transform.localPosition = Vector3.zero;
			value.Root = root;
			value.FL = NewLight("FL");
			value.FR = NewLight("FR");
			value.RL = NewLight("RL");
			value.RR = NewLight("RR");
			value.BaseComputed = false;
			Light NewLight(string name)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: 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)
				GameObject val = new GameObject(name)
				{
					hideFlags = (HideFlags)61
				};
				val.transform.SetParent(root.transform, false);
				val.transform.localPosition = Vector3.zero;
				Light obj = val.AddComponent<Light>();
				obj.type = (LightType)0;
				obj.shadows = (LightShadows)0;
				obj.color = new Color(1f, 0.55f, 0.12f);
				obj.spotAngle = 95f;
				obj.innerSpotAngle = 45f;
				((Behaviour)obj).enabled = false;
				return obj;
			}
		}

		private static void ApplyTurnSignalLightParams(TurnSignalLightRig rig)
		{
			if (rig != null)
			{
				ApplyFront(rig.FL, -20f);
				ApplyFront(rig.FR, 20f);
				ApplyRear(rig.RL, 175f);
				ApplyRear(rig.RR, 185f);
			}
			static void ApplyFront(Light l, float y)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)l == (Object)null))
				{
					l.spotAngle = 110f;
					l.innerSpotAngle = 15f;
					((Component)l).transform.localRotation = Quaternion.Euler(45f, y, 0f);
				}
			}
			static void ApplyRear(Light l, float y)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)l == (Object)null))
				{
					l.spotAngle = 145f;
					l.innerSpotAngle = 30f;
					((Component)l).transform.localRotation = Quaternion.Euler(30f, y, 0f);
				}
			}
		}

		private static void EnsureTurnSignalLightBasePositions(sCarController car)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0060: 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_0076: 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_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if ((Object)(object)car == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)car).GetInstanceID();
			if (_turnSignalLightRigs.TryGetValue(instanceID, out var value) && value != null && !value.BaseComputed)
			{
				if (TryComputeModelBoundsInCarLocal(car, out var min, out var max))
				{
					float num = 0.08f;
					float num2 = 0.12f;
					float num3 = min.x - num;
					float num4 = max.x + num;
					float num5 = max.z + num2;
					float num6 = min.z - num2;
					float num7 = Mathf.Lerp(min.y, max.y, 0.42f);
					value.BaseFL = new Vector3(num3, num7, num5);
					value.BaseFR = new Vector3(num4, num7, num5);
					value.BaseRL = new Vector3(num3, num7, num6);
					value.BaseRR = new Vector3(num4, num7, num6);
					value.BaseComputed = true;
				}
				else
				{
					value.BaseFL = new Vector3(-0.75f, 0.55f, 1.45f);
					value.BaseFR = new Vector3(0.75f, 0.55f, 1.45f);
					value.BaseRL = new Vector3(-0.8f, 0.55f, -1.55f);
					value.BaseRR = new Vector3(0.8f, 0.55f, -1.55f);
					value.BaseComputed = true;
				}
			}
		}

		private static void SetLightOn(Light l, bool on, float intensity, float range)
		{
			if (!((Object)(object)l == (Object)null))
			{
				l.range = range;
				l.intensity = intensity;
				((Behaviour)l).enabled = on && intensity > 0.0001f && range > 0.0001f;
			}
		}

		private static void UpdateTurnSignalWorldLights(sCarController car, bool leftOn, bool rightOn, bool forceOff)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_012b: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)car == (Object)null || !IsTruckCar(car))
			{
				return;
			}
			if (forceOff || !GetIgnitionEnabledEffective())
			{
				int instanceID = ((Object)car).GetInstanceID();
				if (_turnSignalLightRigs.TryGetValue(instanceID, out var value) && value != null)
				{
					SetLightOn(value.FL, on: false, 0f, 0f);
					SetLightOn(value.FR, on: false, 0f, 0f);
					SetLightOn(value.RL, on: false, 0f, 0f);
					SetLightOn(value.RR, on: false, 0f, 0f);
				}
				return;
			}
			EnsureTurnSignalLightRig(car);
			EnsureTurnSignalLightBasePositions(car);
			int instanceID2 = ((Object)car).GetInstanceID();
			if (_turnSignalLightRigs.TryGetValue(instanceID2, out var value2) && value2 != null)
			{
				float turnSignalLightIntensity = GetTurnSignalLightIntensity();
				float num = 0f;
				Vector3 turnSignalLightFrontOffset = TurnSignalLightFrontOffset;
				Vector3 turnSignalLightRearOffset = TurnSignalLightRearOffset;
				ApplyTurnSignalLightParams(value2);
				Vector3 localPosition = value2.BaseFL + turnSignalLightFrontOffset + new Vector3(0f - num, 0f, 0f);
				Vector3 localPosition2 = value2.BaseFR + turnSignalLightFrontOffset + new Vector3(num, 0f, 0f);
				Vector3 localPosition3 = value2.BaseRL + turnSignalLightRearOffset + new Vector3(0f - num, 0f, 0f);
				Vector3 localPosition4 = value2.BaseRR + turnSignalLightRearOffset + new Vector3(num, 0f, 0f);
				if ((Object)(object)value2.FL != (Object)null)
				{
					((Component)value2.FL).transform.localPosition = localPosition;
				}
				if ((Object)(object)value2.FR != (Object)null)
				{
					((Component)value2.FR).transform.localPosition = localPosition2;
				}
				if ((Object)(object)value2.RL != (Object)null)
				{
					((Component)value2.RL).transform.localPosition = localPosition3;
				}
				if ((Object)(object)value2.RR != (Object)null)
				{
					((Component)value2.RR).transform.localPosition = localPosition4;
				}
				SetLightOn(value2.FL, leftOn, turnSignalLightIntensity, 6f);
				SetLightOn(value2.RL, leftOn, turnSignalLightIntensity, 6f);
				SetLightOn(value2.FR, rightOn, turnSignalLightIntensity, 6f);
				SetLightOn(value2.RR, rightOn, turnSignalLightIntensity, 6f);
			}
		}

		private static void UpdateIndicatorAutoCancel(float steerX)
		{
			if (_indicatorMode != IndicatorMode.Left && _indicatorMode != IndicatorMode.Right)
			{
				_indicatorCancelArmed = false;
				_indicatorCancelArmedForMode = _indicatorMode;
				return;
			}
			if (_indicatorCancelArmedForMode != _indicatorMode)
			{
				_indicatorCancelArmedForMode = _indicatorMode;
				_indicatorCancelArmed = false;
			}
			if (!_indicatorCancelArmed)
			{
				if (_indicatorMode == IndicatorMode.Left && steerX <= -0.35f)
				{
					_indicatorCancelArmed = true;
				}
				else if (_indicatorMode == IndicatorMode.Right && steerX >= 0.35f)
				{
					_indicatorCancelArmed = true;
				}
			}
			else if (Mathf.Abs(steerX) <= 0.12f)
			{
				_indicatorMode = IndicatorMode.Off;
				_indicatorBlinkOn = false;
				_indicatorNextBlinkTime = 0f;
				_indicatorCancelArmed = false;
			}
		}

		private static Texture2D GetIgnitionBlackEmissionTex()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ignitionBlackEmissiveTex != (Object)null)
			{
				return _ignitionBlackEmissiveTex;
			}
			_ignitionBlackEmissiveTex = new Texture2D(2, 2, (TextureFormat)4, false);
			_ignitionBlackEmissiveTex.SetPixels((Color[])(object)new Color[4]
			{
				Color.black,
				Color.black,
				Color.black,
				Color.black
			});
			_ignitionBlackEmissiveTex.Apply(false, true);
			((Object)_ignitionBlackEmissiveTex).hideFlags = (HideFlags)61;
			return _ignitionBlackEmissiveTex;
		}

		private static void ForceVehicleLightsOff(sCarController car)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)car == (Object)null)
			{
				return;
			}
			Headlights headlights = car.headlights;
			if ((Object)(object)headlights == (Object)null)
			{
				return;
			}
			EnsureHeadlightsRefs(headlights);
			GameObject val = (GameObject)((_headlightsHeadLightsField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val != (Object)null && val.activeSelf)
			{
				val.SetActive(false);
			}
			try
			{
				headlights.headlightsOn = false;
			}
			catch
			{
			}
			Material val2 = (Material)((_headlightsCarMatField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.SetTexture("_EmissionMap", (Texture)(object)GetIgnitionBlackEmissionTex());
				if (val2.HasProperty("_EmissionColor"))
				{
					val2.SetColor("_EmissionColor", Color.black);
				}
			}
			ForceTailLightsOff(car);
			SetIndicators(car, IndicatorMode.Off, blinkOn: false, forceOff: true);
		}

		private static void ForceTailLightsOff(sCarController car)
		{
			if ((Object)(object)car == (Object)null)
			{
				return;
			}
			TailLightCache tailLightCache = GetTailLightCache(car);
			for (int i = 0; i < tailLightCache.Lights.Count; i++)
			{
				Light val = tailLightCache.Lights[i];
				if (!((Object)(object)val == (Object)null))
				{
					int instanceID = ((Object)val).GetInstanceID();
					if (!tailLightCache.Defaults.ContainsKey(instanceID))
					{
						tailLightCache.Defaults[instanceID] = (val.intensity, ((Behaviour)val).enabled);
					}
					val.intensity = 0f;
					((Behaviour)val).enabled = false;
				}
			}
			for (int j = 0; j < tailLightCache.Flares.Count; j++)
			{
				Component val2 = tailLightCache.Flares[j];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int instanceID2 = ((Object)val2).GetInstanceID();
				if (!tailLightCache.FlareDefaults.ContainsKey(instanceID2))
				{
					float item = 0f;
					bool item2 = true;
					try
					{
						PropertyInfo property = ((object)val2).GetType().GetProperty("intensity");
						if (property != null)
						{
							item = (float)property.GetValue(val2, null);
						}
					}
					catch
					{
					}
					try
					{
						PropertyInfo property2 = ((object)val2).GetType().GetProperty("enabled");
						if (property2 != null)
						{
							item2 = (bool)property2.GetValue(val2, null);
						}
					}
					catch
					{
					}
					tailLightCache.FlareDefaults[instanceID2] = (item, item2);
				}
				try
				{
					SetProp(val2, "intensity", 0f);
				}
				catch
				{
				}
				try
				{
					SetProp(val2, "enabled", false);
				}
				catch
				{
				}
			}
		}

		private static void RestoreTailLights(sCarController car)
		{
			if ((Object)(object)car == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)car).GetInstanceID();
			if (!_tailLightCaches.TryGetValue(instanceID, out var value) || value == null)
			{
				return;
			}
			for (int i = 0; i < value.Lights.Count; i++)
			{
				Light val = value.Lights[i];
				if (!((Object)(object)val == (Object)null))
				{
					int instanceID2 = ((Object)val).GetInstanceID();
					if (value.Defaults.TryGetValue(instanceID2, out (float, bool) value2))
					{
						((Behaviour)val).enabled = value2.Item2;
						val.intensity = value2.Item1;
					}
				}
			}
			for (int j = 0; j < value.Flares.Count; j++)
			{
				Component val2 = value.Flares[j];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int instanceID3 = ((Object)val2).GetInstanceID();
				if (value.FlareDefaults.TryGetValue(instanceID3, out (float, bool) value3))
				{
					try
					{
						SetProp(val2, "enabled", value3.Item2);
					}
					catch
					{
					}
					try
					{
						SetProp(val2, "intensity", value3.Item1);
					}
					catch
					{
					}
				}
			}
		}

		private static TailLightCache GetTailLightCache(sCarController car)
		{
			//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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)car).GetInstanceID();
			if (_tailLightCaches.TryGetValue(instanceID, out var value) && value != null)
			{
				return value;
			}
			TailLightCache tailLightCache = new TailLightCache();
			_tailLightCaches[instanceID] = tailLightCache;
			GameObject val = null;
			try
			{
				Headlights headlights = car.headlights;
				if ((Object)(object)headlights != (Object)null)
				{
					EnsureHeadlightsRefs(headlights);
					val = (GameObject)((_headlightsHeadLightsField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				}
			}
			catch
			{
				val = null;
			}
			Light[] array;
			try
			{
				array = ((Component)car).GetComponentsInChildren<Light>(true);
			}
			catch
			{
				array = null;
			}
			if (array == null)
			{
				return tailLightCache;
			}
			foreach (Light val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Object)(object)((Component)val2).transform != (Object)null) || !((Component)val2).transform.IsChildOf(val.transform)))
				{
					string text = ((Object)val2).name ?? string.Empty;
					bool flag = text.IndexOf("tail", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("brake", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("rear", StringComparison.OrdinalIgnoreCase) >= 0;
					bool flag2 = val2.color.r > 0.7f && val2.color.g < 0.45f && val2.color.b < 0.45f;
					bool flag3 = false;
					try
					{
						flag3 = ((Component)car).transform.InverseTransformPoint(((Component)val2).transform.position).z < -0.2f;
					}
					catch
					{
						flag3 = false;
					}
					if ((flag || (flag2 && flag3)) && !tailLightCache.Lights.Contains(val2))
					{
						tailLightCache.Lights.Add(val2);
					}
				}
			}
			try
			{
				Component[] componentsInChildren = ((Component)car).GetComponentsInChildren<Component>(true);
				if (componentsInChildren != null)
				{
					foreach (Component val3 in componentsInChildren)
					{
						if ((Object)(object)val3 == (Object)null)
						{
							continue;
						}
						string name = ((object)val3).GetType().Name;
						if (name == null || name.IndexOf("LensFlareComponentSRP", StringComparison.OrdinalIgnoreCase) < 0)
						{
							continue;
						}
						bool flag4 = false;
						try
						{
							flag4 = ((Component)car).transform.InverseTransformPoint(val3.transform.position).z < -0.2f;
						}
						catch
						{
							flag4 = false;
						}
						if (flag4)
						{
							string text2 = ((Object)val3).name ?? string.Empty;
							if ((text2.IndexOf("tail", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("rear", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("brake", StringComparison.OrdinalIgnoreCase) >= 0) && !tailLightCache.Flares.Contains(val3))
							{
								tailLightCache.Flares.Add(val3);
							}
						}
					}
				}
			}
			catch
			{
			}
			return tailLightCache;
		}

		private static IndicatorCache GetIndicatorCache(sCarController car)
		{
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0612: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: 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)
			//IL_012d: 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_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cd: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)car).GetInstanceID();
			if (_indicatorCaches.TryGetValue(instanceID, out var value) && value != null)
			{
				return value;
			}
			IndicatorCache indicatorCache = new IndicatorCache();
			_indicatorCaches[instanceID] = indicatorCache;
			GameObject val = null;
			try
			{
				Headlights headlights = car.headlights;
				if ((Object)(object)headlights != (Object)null)
				{
					EnsureHeadlightsRefs(headlights);
					val = (GameObject)((_headlightsHeadLightsField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				}
			}
			catch
			{
				val = null;
			}
			Light[] array;
			try
			{
				array = ((Component)car).GetComponentsInChildren<Light>(true);
			}
			catch
			{
				array = null;
			}
			foreach (Light val2 in array)
			{
				if ((Object)(object)val2 == (Object)null || ((Object)(object)val != (Object)null && (Object)(object)((Component)val2).transform != (Object)null && ((Component)val2).transform.IsChildOf(val.transform)))
				{
					continue;
				}
				string text = ((Object)val2).name ?? string.Empty;
				bool flag = text.IndexOf("indicator", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("blinker", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("turn", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("signal", StringComparison.OrdinalIgnoreCase) >= 0;
				bool flag2 = val2.color.r > 0.7f && val2.color.g > 0.25f && val2.color.b < 0.35f;
				bool flag3 = false;
				float num = 0f;
				try
				{
					Vector3 val3 = ((Component)car).transform.InverseTransformPoint(((Component)val2).transform.position);
					num = val3.x;
					flag3 = val3.z > 0.2f;
				}
				catch
				{
					flag3 = false;
				}
				if (flag || (flag2 && flag3))
				{
					bool flag4 = text.IndexOf("left", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("_l", StringComparison.OrdinalIgnoreCase) >= 0;
					bool flag5 = text.IndexOf("right", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("_r", StringComparison.OrdinalIgnoreCase) >= 0;
					if (!flag4 && !flag5)
					{
						flag4 = num < 0f;
						flag5 = !flag4;
					}
					if (flag4 && !indicatorCache.Left.Contains(val2))
					{
						indicatorCache.Left.Add(val2);
					}
					if (flag5 && !indicatorCache.Right.Contains(val2))
					{
						indicatorCache.Right.Add(val2);
					}
				}
			}
			try
			{
				Renderer[] componentsInChildren = ((Component)car).GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren != null)
				{
					foreach (Renderer val4 in componentsInChildren)
					{
						if ((Object)(object)val4 == (Object)null)
						{
							continue;
						}
						float num2 = 0f;
						float num3 = 0f;
						try
						{
							Vector3 val5 = ((Component)car).transform.InverseTransformPoint(((Component)val4).transform.position);
							num2 = val5.x;
							num3 = val5.z;
						}
						catch
						{
							num3 = 0f;
						}
						if (num3 < -0.35f)
						{
							continue;
						}
						string text2 = ((Object)val4).name ?? string.Empty;
						bool flag6 = text2.IndexOf("indicator", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("blinker", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("blink", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("turn", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("signal", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("lamp", StringComparison.OrdinalIgnoreCase) >=