Decompiled source of ArenaRaceSpeedBoost v4.0.0

ArenaRaceSpeedBoost.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOJP.ArenaRaceSpeedBoost
{
	[BepInPlugin("REPOJP.ArenaRaceSpeedBoost", "ArenaRaceSpeedBoost", "1.0.5")]
	public class ArenaRaceSpeedBoostPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.ArenaRaceSpeedBoost";

		public const string PluginName = "ArenaRaceSpeedBoost";

		public const string PluginVersion = "1.0.5";

		internal static ManualLogSource Log;

		private Harmony harmony;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<float> DrivingPerformanceMultiplier;

		internal static ConfigEntry<float> DriftMultiplier;

		internal static ConfigEntry<float> BoostPadMultiplier;

		internal static ConfigEntry<float> BoostPadCorrectionMultiplier;

		internal static ConfigEntry<float> LightEffectMultiplier;

		internal static ConfigEntry<float> SmokeEffectMultiplier;

		private void Awake()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			try
			{
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Log = ((BaseUnityPlugin)this).Logger;
				BindConfigs();
				harmony = new Harmony("REPOJP.ArenaRaceSpeedBoost");
				harmony.PatchAll();
				Log.LogInfo((object)"ArenaRaceSpeedBoost loaded.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (harmony != null)
				{
					harmony.UnpatchSelf();
					harmony = null;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: OnDestroy\n" + ex));
			}
		}

		private ConfigEntry<float> BindMultiplierConfig(string section, string key, float defaultValue, string description)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
		}

		private void BindConfigs()
		{
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the entire mod.MOD全体の有効化を切り替えます。");
			DrivingPerformanceMultiplier = BindMultiplierConfig("Multipliers", "DrivingPerformanceMultiplier", 1.3f, "Multiplier for normal driving speed, acceleration, deceleration, reverse speed, hyper speed, and kmh limits.通常走行速度、加速、減速、後退速度、ハイパー速度、kmh制限の一括倍率です。");
			DriftMultiplier = BindMultiplierConfig("Multipliers", "DriftMultiplier", 1.3f, "Multiplier for drift speed, drift boost strength, drift boost duration, and drift exit boost.ドリフト速度、ドリフトブースト力、ドリフトブースト時間、ドリフト離脱ブーストの一括倍率です。");
			BoostPadMultiplier = BindMultiplierConfig("Multipliers", "BoostPadMultiplier", 1.1f, "Multiplier for boost pad speed, duration, force, and boost speed gain.ブーストPadの速度、時間、力、速度増加量の一括倍率です。");
			BoostPadCorrectionMultiplier = BindMultiplierConfig("Multipliers", "BoostPadCorrectionMultiplier", 1f, "Multiplier for boost pad yaw duration, pitch duration, and yaw correction strength.ブーストPadの向き補正時間、ピッチ補正時間、向き補正強度の一括倍率です。");
			LightEffectMultiplier = BindMultiplierConfig("Effects", "LightEffectMultiplier", 5f, "Multiplier for light and trail effects on racing Scouts.レース用スカウトの光と軌跡エフェクトの倍率です。");
			SmokeEffectMultiplier = BindMultiplierConfig("Effects", "SmokeEffectMultiplier", 0.2f, "Multiplier for smoke, dust, and particle effects on racing Scouts.レース用スカウトの煙、砂埃、粒子エフェクトの倍率です。");
		}
	}
	internal static class ArenaRaceSpeedBoostCore
	{
		private static readonly Dictionary<int, VehicleBaseValues> VehicleBaseValueMap = new Dictionary<int, VehicleBaseValues>();

		private static readonly Dictionary<int, VehicleEffectCache> VehicleEffectCacheMap = new Dictionary<int, VehicleEffectCache>();

		private static readonly Dictionary<int, PendingPadBoost> PendingPadBoostMap = new Dictionary<int, PendingPadBoost>();

		private static readonly Dictionary<int, ActiveBoostState> ActiveBoostStateMap = new Dictionary<int, ActiveBoostState>();

		private static readonly FieldInfo DriftBoostLevelField = AccessTools.Field(typeof(ItemVehicle), "driftBoostLevel");

		private static readonly FieldInfo DriftBoostActiveTimerField = AccessTools.Field(typeof(ItemVehicle), "driftBoostActiveTimer");

		private static readonly FieldInfo DriftBoostConstantDurationField = AccessTools.Field(typeof(ItemVehicle), "driftBoostConstantDuration");

		private static readonly FieldInfo DriftBoostFadeDurationField = AccessTools.Field(typeof(ItemVehicle), "driftBoostFadeDuration");

		private static readonly FieldInfo YawOverrideTimerField = AccessTools.Field(typeof(ItemVehicle), "yawOverrideTimer");

		private static readonly FieldInfo YawOverrideDirectionField = AccessTools.Field(typeof(ItemVehicle), "yawOverrideDirection");

		private static readonly FieldInfo SmoothedSteeringTargetField = AccessTools.Field(typeof(ItemVehicle), "smoothedSteeringTarget");

		private static readonly FieldInfo InputYField = AccessTools.Field(typeof(ItemVehicle), "inputY");

		private static readonly FieldInfo IsLoopPadField = AccessTools.Field(typeof(ItemVehicleBoostPad), "isALoopPad");

		private static readonly MethodInfo OverrideYawMethod = AccessTools.Method(typeof(ItemVehicle), "OverrideYaw", (Type[])null, (Type[])null);

		private static readonly MethodInfo OverridePitchMethod = AccessTools.Method(typeof(ItemVehicle), "OverridePitch", (Type[])null, (Type[])null);

		private static readonly MethodInfo OverrideLoopModeMethod = AccessTools.Method(typeof(ItemVehicle), "OverrideLoopMode", (Type[])null, (Type[])null);

		private static readonly MethodInfo OverrideCameraLookForwardMethod = AccessTools.Method(typeof(ItemVehicle), "OverrideCameraLookForward", (Type[])null, (Type[])null);

		internal static void RegisterVehicle(ItemVehicle vehicle)
		{
			try
			{
				if (!((Object)(object)vehicle == (Object)null))
				{
					int instanceID = ((Object)vehicle).GetInstanceID();
					if (!VehicleBaseValueMap.ContainsKey(instanceID))
					{
						VehicleBaseValueMap[instanceID] = new VehicleBaseValues(vehicle);
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("RegisterVehicle", ex);
			}
		}

		internal static void UnregisterVehicle(ItemVehicle vehicle)
		{
			try
			{
				if (!((Object)(object)vehicle == (Object)null))
				{
					int instanceID = ((Object)vehicle).GetInstanceID();
					if (VehicleEffectCacheMap.TryGetValue(instanceID, out var value))
					{
						value.Apply(enabled: false, 1f, 1f);
					}
					VehicleBaseValueMap.Remove(instanceID);
					VehicleEffectCacheMap.Remove(instanceID);
					PendingPadBoostMap.Remove(instanceID);
					ActiveBoostStateMap.Remove(instanceID);
				}
			}
			catch (Exception ex)
			{
				LogFailure("UnregisterVehicle", ex);
			}
		}

		internal static bool IsTargetVehicle(ItemVehicle vehicle)
		{
			if (ArenaRaceSpeedBoostPlugin.ModEnabled == null || !ArenaRaceSpeedBoostPlugin.ModEnabled.Value)
			{
				return false;
			}
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return false;
			}
			if ((Object)(object)vehicle == (Object)null)
			{
				return false;
			}
			if ((Object)(object)ArenaRace.instance == (Object)null)
			{
				return false;
			}
			if (!vehicle.isRacingVehicle)
			{
				return false;
			}
			return true;
		}

		internal static void ApplyVehicleMultipliers(ItemVehicle vehicle)
		{
			try
			{
				if (!IsTargetVehicle(vehicle))
				{
					return;
				}
				VehicleBaseValues baseValues = GetBaseValues(vehicle);
				if (baseValues != null)
				{
					UpdateActiveBoostState(vehicle);
					vehicle.maxForwardSpeed *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.maxReverseSpeed *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.hyperMaxSpeed *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.driftMaxSpeed *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
					vehicle.forwardAcceleration *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.hyperAcceleration *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.deceleration = baseValues.Deceleration * SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.maxSpeedKmh = baseValues.MaxSpeedKmh * SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					vehicle.softMaxSpeedKmh = baseValues.SoftMaxSpeedKmh * SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
					bool flag = IsPadBoostActive(vehicle);
					int activePadLevel = GetActivePadLevel(vehicle);
					vehicle.driftExitBoost *= SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
					vehicle.driftBoostLevel1ForwardBoost *= GetLevelForwardBoostMultiplier(1, flag && activePadLevel == 1);
					vehicle.driftBoostLevel2ForwardBoost *= GetLevelForwardBoostMultiplier(2, flag && activePadLevel == 2);
					vehicle.driftBoostLevel3ForwardBoost *= GetLevelForwardBoostMultiplier(3, flag && activePadLevel == 3);
					vehicle.driftBoostLevel1Duration = baseValues.DriftBoostLevel1Duration * GetLevelDurationMultiplier(1, flag && activePadLevel == 1);
					vehicle.driftBoostLevel2Duration = baseValues.DriftBoostLevel2Duration * GetLevelDurationMultiplier(2, flag && activePadLevel == 2);
					vehicle.driftBoostLevel3Duration = baseValues.DriftBoostLevel3Duration * GetLevelDurationMultiplier(3, flag && activePadLevel == 3);
					vehicle.driftBoostLevel1SpeedBoostMultiplier = baseValues.DriftBoostLevel1SpeedBoostMultiplier * GetLevelSpeedMultiplier(1, flag && activePadLevel == 1);
					vehicle.driftBoostLevel2SpeedBoostMultiplier = baseValues.DriftBoostLevel2SpeedBoostMultiplier * GetLevelSpeedMultiplier(2, flag && activePadLevel == 2);
					vehicle.driftBoostLevel3SpeedBoostMultiplier = baseValues.DriftBoostLevel3SpeedBoostMultiplier * GetLevelSpeedMultiplier(3, flag && activePadLevel == 3);
					if (flag)
					{
						vehicle.driftBoostSpeedOverTimeRate = baseValues.DriftBoostSpeedOverTimeRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
						vehicle.driftBoostHyperSpeedRate = baseValues.DriftBoostHyperSpeedRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
					}
					else
					{
						vehicle.driftBoostSpeedOverTimeRate = baseValues.DriftBoostSpeedOverTimeRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
						vehicle.driftBoostHyperSpeedRate = baseValues.DriftBoostHyperSpeedRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("ApplyVehicleMultipliers", ex);
			}
		}

		internal static void ApplyReverseAcceleration(ItemVehicle vehicle)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsTargetVehicle(vehicle))
				{
					return;
				}
				float num = SafeMultiplier(ArenaRaceSpeedBoostPlugin.DrivingPerformanceMultiplier.Value);
				if (num <= 1.0001f || (Object)(object)vehicle.rb == (Object)null || vehicle.rb.isKinematic)
				{
					return;
				}
				PlayerAvatar driver = GetDriver(vehicle);
				if ((Object)(object)driver == (Object)null || !IsDriverFullyMounted(vehicle))
				{
					return;
				}
				float privateFloat = GetPrivateFloat(InputYField, vehicle, 0f);
				if (!(privateFloat >= -0.1f))
				{
					Vector3 val = -((Component)vehicle).transform.forward;
					val.y = 0f;
					if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f))
					{
						((Vector3)(ref val)).Normalize();
						float num2 = vehicle.maxReverseSpeed * 10f * (num - 1f);
						vehicle.rb.AddForce(val * num2, (ForceMode)0);
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("ApplyReverseAcceleration", ex);
			}
		}

		internal static void PrepareDriftBoost(ItemVehicle vehicle)
		{
			try
			{
				if (!IsTargetVehicle(vehicle))
				{
					return;
				}
				int instanceID = ((Object)vehicle).GetInstanceID();
				if (PendingPadBoostMap.TryGetValue(instanceID, out var value))
				{
					VehicleBaseValues baseValues = GetBaseValues(vehicle);
					if (baseValues != null)
					{
						SetBoostFieldsForLevel(vehicle, baseValues, value.BoostLevel, padBoost: true);
						vehicle.driftBoostSpeedOverTimeRate = baseValues.DriftBoostSpeedOverTimeRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
						vehicle.driftBoostHyperSpeedRate = baseValues.DriftBoostHyperSpeedRate * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("PrepareDriftBoost", ex);
			}
		}

		internal static void FinishDriftBoost(ItemVehicle vehicle)
		{
			try
			{
				if (IsTargetVehicle(vehicle))
				{
					int privateInt = GetPrivateInt(DriftBoostLevelField, vehicle, 0);
					if (privateInt > 0)
					{
						int instanceID = ((Object)vehicle).GetInstanceID();
						bool flag = PendingPadBoostMap.ContainsKey(instanceID);
						ActiveBoostStateMap[instanceID] = new ActiveBoostState
						{
							IsPadBoost = flag,
							PadLevel = (flag ? PendingPadBoostMap[instanceID].BoostLevel : 0)
						};
						float baseBoostDuration = GetBaseBoostDuration(vehicle);
						float levelDurationMultiplier = GetLevelDurationMultiplier(privateInt, flag);
						float num = baseBoostDuration * levelDurationMultiplier;
						float privateFloat = GetPrivateFloat(DriftBoostActiveTimerField, vehicle, 0f);
						SetPrivateFloat(DriftBoostActiveTimerField, vehicle, Mathf.Max(privateFloat, num));
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("FinishDriftBoost", ex);
			}
		}

		internal static bool HandleBoostPad(ItemVehicleBoostPad pad, Collider other)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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)
			try
			{
				if (ArenaRaceSpeedBoostPlugin.ModEnabled == null || !ArenaRaceSpeedBoostPlugin.ModEnabled.Value)
				{
					return true;
				}
				if (!SemiFunc.IsMasterClientOrSingleplayer())
				{
					return false;
				}
				if ((Object)(object)pad == (Object)null || (Object)(object)other == (Object)null)
				{
					return false;
				}
				ItemVehicle componentInParent = ((Component)other).GetComponentInParent<ItemVehicle>();
				if ((Object)(object)componentInParent == (Object)null)
				{
					return false;
				}
				if (!IsTargetVehicle(componentInParent))
				{
					return true;
				}
				int num = Mathf.Clamp(pad.boostLevel, 1, 3);
				if (!IsBoostPadEnabled(num))
				{
					return false;
				}
				Vector3 forward = ((Component)pad).transform.forward;
				float angle = Mathf.Asin(forward.y) * 57.29578f;
				forward.y = 0f;
				if (((Vector3)(ref forward)).sqrMagnitude < 0.001f)
				{
					return false;
				}
				((Vector3)(ref forward)).Normalize();
				int instanceID = ((Object)componentInParent).GetInstanceID();
				PendingPadBoostMap[instanceID] = new PendingPadBoost
				{
					BoostLevel = num
				};
				try
				{
					float duration = 0.25f * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadCorrectionMultiplier.Value);
					float duration2 = 1f * SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadCorrectionMultiplier.Value);
					InvokeOverrideYaw(componentInParent, forward, duration, num);
					InvokeOverridePitch(componentInParent, angle, duration2);
					if (GetPrivateBool(IsLoopPadField, pad, defaultValue: false))
					{
						InvokeOverrideLoopMode(componentInParent, pad.loopPadDuration);
						InvokeOverrideCameraLookForward(componentInParent, pad.loopPadDuration);
					}
				}
				finally
				{
					PendingPadBoostMap.Remove(instanceID);
				}
				return false;
			}
			catch (Exception ex)
			{
				LogFailure("HandleBoostPad", ex);
				return false;
			}
		}

		internal static void ApplyYawCorrectionStrength(ItemVehicle vehicle)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsTargetVehicle(vehicle) || !IsPadBoostActive(vehicle))
				{
					return;
				}
				float num = SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadCorrectionMultiplier.Value);
				if (num <= 1.0001f || YawOverrideTimerField == null || YawOverrideDirectionField == null || SmoothedSteeringTargetField == null)
				{
					return;
				}
				float privateFloat = GetPrivateFloat(YawOverrideTimerField, vehicle, 0f);
				if (privateFloat <= 0f)
				{
					return;
				}
				Vector3 privateVector = GetPrivateVector3(SmoothedSteeringTargetField, vehicle, ((Component)vehicle).transform.forward);
				Vector3 privateVector2 = GetPrivateVector3(YawOverrideDirectionField, vehicle, ((Component)vehicle).transform.forward);
				if (!(((Vector3)(ref privateVector2)).sqrMagnitude < 0.001f))
				{
					privateVector2.y = 0f;
					((Vector3)(ref privateVector2)).Normalize();
					float num2 = MathF.PI * 4f * Time.fixedDeltaTime * (num - 1f);
					Vector3 val = Vector3.RotateTowards(privateVector, privateVector2, num2, 0f);
					val.y = 0f;
					if (!(((Vector3)(ref val)).sqrMagnitude < 0.001f))
					{
						((Vector3)(ref val)).Normalize();
						SmoothedSteeringTargetField.SetValue(vehicle, val);
					}
				}
			}
			catch (Exception ex)
			{
				LogFailure("ApplyYawCorrectionStrength", ex);
			}
		}

		internal static void ApplyEffectExaggeration(ItemVehicle vehicle)
		{
			try
			{
				if ((Object)(object)vehicle == (Object)null)
				{
					return;
				}
				int instanceID = ((Object)vehicle).GetInstanceID();
				VehicleEffectCache value;
				bool flag = VehicleEffectCacheMap.TryGetValue(instanceID, out value);
				if (!IsTargetVehicle(vehicle))
				{
					if (flag)
					{
						value.Apply(enabled: false, 1f, 1f);
					}
					return;
				}
				if (!flag)
				{
					value = new VehicleEffectCache(vehicle);
					VehicleEffectCacheMap[instanceID] = value;
				}
				float lightMultiplier = SafeMultiplier(ArenaRaceSpeedBoostPlugin.LightEffectMultiplier.Value);
				float smokeMultiplier = SafeMultiplier(ArenaRaceSpeedBoostPlugin.SmokeEffectMultiplier.Value);
				value.Apply(enabled: true, lightMultiplier, smokeMultiplier);
			}
			catch (Exception ex)
			{
				LogFailure("ApplyEffectExaggeration", ex);
			}
		}

		private static VehicleBaseValues GetBaseValues(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)vehicle).GetInstanceID();
			if (!VehicleBaseValueMap.TryGetValue(instanceID, out var value))
			{
				value = new VehicleBaseValues(vehicle);
				VehicleBaseValueMap[instanceID] = value;
			}
			return value;
		}

		private static PlayerAvatar GetDriver(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null || vehicle.seats == null || vehicle.seats.Length == 0 || vehicle.seats[0] == null)
			{
				return null;
			}
			return vehicle.seats[0].seatedPlayer;
		}

		private static bool IsDriverFullyMounted(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null || vehicle.seats == null || vehicle.seats.Length == 0 || vehicle.seats[0] == null)
			{
				return false;
			}
			return (Object)(object)vehicle.seats[0].seatedPlayer != (Object)null && (vehicle.seats[0].reachedFirstMount || (Object)(object)vehicle.seats[0].firstMountTransform == (Object)null);
		}

		private static void UpdateActiveBoostState(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)vehicle).GetInstanceID();
			if (ActiveBoostStateMap.ContainsKey(instanceID))
			{
				float privateFloat = GetPrivateFloat(DriftBoostActiveTimerField, vehicle, 0f);
				if (privateFloat <= 0.001f)
				{
					ActiveBoostStateMap.Remove(instanceID);
				}
			}
		}

		private static bool IsPadBoostActive(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null)
			{
				return false;
			}
			UpdateActiveBoostState(vehicle);
			if (!ActiveBoostStateMap.TryGetValue(((Object)vehicle).GetInstanceID(), out var value))
			{
				return false;
			}
			return value.IsPadBoost;
		}

		private static int GetActivePadLevel(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null)
			{
				return 0;
			}
			if (!ActiveBoostStateMap.TryGetValue(((Object)vehicle).GetInstanceID(), out var value))
			{
				return 0;
			}
			return value.PadLevel;
		}

		private static bool IsBoostPadEnabled(int level)
		{
			return level >= 1 && level <= 3;
		}

		private static float GetLevelSpeedMultiplier(int level, bool padBoost)
		{
			if (padBoost)
			{
				return SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
			}
			return SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
		}

		private static float GetLevelDurationMultiplier(int level, bool padBoost)
		{
			if (padBoost)
			{
				return SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
			}
			return SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
		}

		private static float GetLevelForwardBoostMultiplier(int level, bool padBoost)
		{
			if (padBoost)
			{
				return SafeMultiplier(ArenaRaceSpeedBoostPlugin.BoostPadMultiplier.Value);
			}
			return SafeMultiplier(ArenaRaceSpeedBoostPlugin.DriftMultiplier.Value);
		}

		private static float ConvertCurrentForwardBoostMultiplier(float currentValue, int level, bool padBoost)
		{
			float levelForwardBoostMultiplier = GetLevelForwardBoostMultiplier(level, padBoost: false);
			float levelForwardBoostMultiplier2 = GetLevelForwardBoostMultiplier(level, padBoost);
			if (levelForwardBoostMultiplier <= 0.0001f)
			{
				return currentValue * levelForwardBoostMultiplier2;
			}
			return currentValue / levelForwardBoostMultiplier * levelForwardBoostMultiplier2;
		}

		private static void SetBoostFieldsForLevel(ItemVehicle vehicle, VehicleBaseValues baseValues, int level, bool padBoost)
		{
			if (!((Object)(object)vehicle == (Object)null) && baseValues != null)
			{
				switch (level)
				{
				case 1:
					vehicle.driftBoostLevel1ForwardBoost = ConvertCurrentForwardBoostMultiplier(vehicle.driftBoostLevel1ForwardBoost, 1, padBoost);
					vehicle.driftBoostLevel1SpeedBoostMultiplier = baseValues.DriftBoostLevel1SpeedBoostMultiplier * GetLevelSpeedMultiplier(1, padBoost);
					vehicle.driftBoostLevel1Duration = baseValues.DriftBoostLevel1Duration * GetLevelDurationMultiplier(1, padBoost);
					break;
				case 2:
					vehicle.driftBoostLevel2ForwardBoost = ConvertCurrentForwardBoostMultiplier(vehicle.driftBoostLevel2ForwardBoost, 2, padBoost);
					vehicle.driftBoostLevel2SpeedBoostMultiplier = baseValues.DriftBoostLevel2SpeedBoostMultiplier * GetLevelSpeedMultiplier(2, padBoost);
					vehicle.driftBoostLevel2Duration = baseValues.DriftBoostLevel2Duration * GetLevelDurationMultiplier(2, padBoost);
					break;
				case 3:
					vehicle.driftBoostLevel3ForwardBoost = ConvertCurrentForwardBoostMultiplier(vehicle.driftBoostLevel3ForwardBoost, 3, padBoost);
					vehicle.driftBoostLevel3SpeedBoostMultiplier = baseValues.DriftBoostLevel3SpeedBoostMultiplier * GetLevelSpeedMultiplier(3, padBoost);
					vehicle.driftBoostLevel3Duration = baseValues.DriftBoostLevel3Duration * GetLevelDurationMultiplier(3, padBoost);
					break;
				}
			}
		}

		private static float GetBaseBoostDuration(ItemVehicle vehicle)
		{
			float privateFloat = GetPrivateFloat(DriftBoostConstantDurationField, vehicle, 1f);
			float privateFloat2 = GetPrivateFloat(DriftBoostFadeDurationField, vehicle, 0.5f);
			return Mathf.Max(0.01f, privateFloat + privateFloat2);
		}

		private static void InvokeOverrideYaw(ItemVehicle vehicle, Vector3 direction, float duration, int boostLevel)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (OverrideYawMethod != null)
			{
				OverrideYawMethod.Invoke(vehicle, new object[3] { direction, duration, boostLevel });
			}
		}

		private static void InvokeOverridePitch(ItemVehicle vehicle, float angle, float duration)
		{
			if (OverridePitchMethod != null)
			{
				OverridePitchMethod.Invoke(vehicle, new object[2] { angle, duration });
			}
		}

		private static void InvokeOverrideLoopMode(ItemVehicle vehicle, float duration)
		{
			if (OverrideLoopModeMethod != null)
			{
				OverrideLoopModeMethod.Invoke(vehicle, new object[1] { duration });
			}
		}

		private static void InvokeOverrideCameraLookForward(ItemVehicle vehicle, float duration)
		{
			if (OverrideCameraLookForwardMethod != null)
			{
				OverrideCameraLookForwardMethod.Invoke(vehicle, new object[1] { duration });
			}
		}

		private static float SafeMultiplier(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				return 1f;
			}
			return Mathf.Clamp(value, 0f, 20f);
		}

		private static int GetPrivateInt(FieldInfo field, object instance, int defaultValue)
		{
			if (field == null || instance == null)
			{
				return defaultValue;
			}
			if (!(field.GetValue(instance) is int result))
			{
				return defaultValue;
			}
			return result;
		}

		private static float GetPrivateFloat(FieldInfo field, object instance, float defaultValue)
		{
			if (field == null || instance == null)
			{
				return defaultValue;
			}
			if (!(field.GetValue(instance) is float result))
			{
				return defaultValue;
			}
			return result;
		}

		private static bool GetPrivateBool(FieldInfo field, object instance, bool defaultValue)
		{
			if (field == null || instance == null)
			{
				return defaultValue;
			}
			if (!(field.GetValue(instance) is bool result))
			{
				return defaultValue;
			}
			return result;
		}

		private static Vector3 GetPrivateVector3(FieldInfo field, object instance, Vector3 defaultValue)
		{
			//IL_0016: 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_0039: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (field == null || instance == null)
			{
				return defaultValue;
			}
			if (!(field.GetValue(instance) is Vector3 result))
			{
				return defaultValue;
			}
			return result;
		}

		private static void SetPrivateFloat(FieldInfo field, object instance, float value)
		{
			if (!(field == null) && instance != null)
			{
				field.SetValue(instance, value);
			}
		}

		private static void LogFailure(string process, Exception ex)
		{
			if (ArenaRaceSpeedBoostPlugin.Log != null)
			{
				ArenaRaceSpeedBoostPlugin.Log.LogError((object)("Failure: " + process + "\n" + ex));
			}
		}
	}
	internal sealed class VehicleBaseValues
	{
		internal readonly float Deceleration;

		internal readonly float MaxSpeedKmh;

		internal readonly float SoftMaxSpeedKmh;

		internal readonly float DriftBoostSpeedOverTimeRate;

		internal readonly float DriftBoostHyperSpeedRate;

		internal readonly float DriftBoostLevel1ForwardBoost;

		internal readonly float DriftBoostLevel2ForwardBoost;

		internal readonly float DriftBoostLevel3ForwardBoost;

		internal readonly float DriftBoostLevel1Duration;

		internal readonly float DriftBoostLevel2Duration;

		internal readonly float DriftBoostLevel3Duration;

		internal readonly float DriftBoostLevel1SpeedBoostMultiplier;

		internal readonly float DriftBoostLevel2SpeedBoostMultiplier;

		internal readonly float DriftBoostLevel3SpeedBoostMultiplier;

		internal VehicleBaseValues(ItemVehicle vehicle)
		{
			Deceleration = vehicle.deceleration;
			MaxSpeedKmh = vehicle.maxSpeedKmh;
			SoftMaxSpeedKmh = vehicle.softMaxSpeedKmh;
			DriftBoostSpeedOverTimeRate = vehicle.driftBoostSpeedOverTimeRate;
			DriftBoostHyperSpeedRate = vehicle.driftBoostHyperSpeedRate;
			DriftBoostLevel1ForwardBoost = vehicle.driftBoostLevel1ForwardBoost;
			DriftBoostLevel2ForwardBoost = vehicle.driftBoostLevel2ForwardBoost;
			DriftBoostLevel3ForwardBoost = vehicle.driftBoostLevel3ForwardBoost;
			DriftBoostLevel1Duration = vehicle.driftBoostLevel1Duration;
			DriftBoostLevel2Duration = vehicle.driftBoostLevel2Duration;
			DriftBoostLevel3Duration = vehicle.driftBoostLevel3Duration;
			DriftBoostLevel1SpeedBoostMultiplier = vehicle.driftBoostLevel1SpeedBoostMultiplier;
			DriftBoostLevel2SpeedBoostMultiplier = vehicle.driftBoostLevel2SpeedBoostMultiplier;
			DriftBoostLevel3SpeedBoostMultiplier = vehicle.driftBoostLevel3SpeedBoostMultiplier;
		}
	}
	internal sealed class VehicleEffectCache
	{
		private readonly List<ParticleRecord> particleRecords = new List<ParticleRecord>();

		private readonly List<LightRecord> lightRecords = new List<LightRecord>();

		private readonly List<TrailRecord> trailRecords = new List<TrailRecord>();

		private bool lastEnabled;

		private float lastMultiplier = -1f;

		internal VehicleEffectCache(ItemVehicle vehicle)
		{
			if ((Object)(object)vehicle == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = ((Component)vehicle).GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					particleRecords.Add(new ParticleRecord(componentsInChildren[i]));
				}
			}
			Light[] componentsInChildren2 = ((Component)vehicle).GetComponentsInChildren<Light>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if ((Object)(object)componentsInChildren2[j] != (Object)null)
				{
					lightRecords.Add(new LightRecord(componentsInChildren2[j]));
				}
			}
			TrailRenderer[] componentsInChildren3 = ((Component)vehicle).GetComponentsInChildren<TrailRenderer>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				if ((Object)(object)componentsInChildren3[k] != (Object)null)
				{
					trailRecords.Add(new TrailRecord(componentsInChildren3[k]));
				}
			}
		}

		internal void Apply(bool enabled, float lightMultiplier, float smokeMultiplier)
		{
			float num = lightMultiplier * 1000f + smokeMultiplier;
			if (lastEnabled != enabled || !(Mathf.Abs(lastMultiplier - num) < 0.001f))
			{
				float multiplier = (enabled ? lightMultiplier : 1f);
				float multiplier2 = (enabled ? smokeMultiplier : 1f);
				for (int i = 0; i < particleRecords.Count; i++)
				{
					particleRecords[i].Apply(multiplier2);
				}
				for (int j = 0; j < lightRecords.Count; j++)
				{
					lightRecords[j].Apply(multiplier);
				}
				for (int k = 0; k < trailRecords.Count; k++)
				{
					trailRecords[k].Apply(multiplier);
				}
				lastEnabled = enabled;
				lastMultiplier = num;
			}
		}
	}
	internal sealed class ParticleRecord
	{
		private readonly ParticleSystem particle;

		private readonly float startSizeMultiplier;

		private readonly float startSpeedMultiplier;

		private readonly float rateOverTimeMultiplier;

		private readonly float rateOverDistanceMultiplier;

		private readonly int maxParticles;

		internal ParticleRecord(ParticleSystem particleSystem)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			particle = particleSystem;
			MainModule main = particle.main;
			EmissionModule emission = particle.emission;
			startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier;
			startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier;
			rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier;
			rateOverDistanceMultiplier = ((EmissionModule)(ref emission)).rateOverDistanceMultiplier;
			maxParticles = ((MainModule)(ref main)).maxParticles;
		}

		internal void Apply(float multiplier)
		{
			//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)
			if (!((Object)(object)particle == (Object)null))
			{
				float num = Mathf.Max(0f, multiplier);
				MainModule main = particle.main;
				EmissionModule emission = particle.emission;
				((MainModule)(ref main)).startSizeMultiplier = startSizeMultiplier * num;
				((MainModule)(ref main)).startSpeedMultiplier = startSpeedMultiplier * num;
				((MainModule)(ref main)).maxParticles = GetSafeMaxParticles(maxParticles, num);
				((EmissionModule)(ref emission)).rateOverTimeMultiplier = rateOverTimeMultiplier * num;
				((EmissionModule)(ref emission)).rateOverDistanceMultiplier = rateOverDistanceMultiplier * num;
			}
		}

		private static int GetSafeMaxParticles(int baseMaxParticles, float multiplier)
		{
			if (baseMaxParticles <= 0)
			{
				return 1;
			}
			int num = Mathf.RoundToInt((float)baseMaxParticles * multiplier);
			int num2 = Mathf.Min(num, baseMaxParticles + 200);
			return Mathf.Max(1, num2);
		}
	}
	internal sealed class LightRecord
	{
		private readonly Light light;

		private readonly float intensity;

		private readonly float range;

		internal LightRecord(Light targetLight)
		{
			light = targetLight;
			intensity = light.intensity;
			range = light.range;
		}

		internal void Apply(float multiplier)
		{
			if (!((Object)(object)light == (Object)null))
			{
				float num = Mathf.Max(0f, multiplier);
				light.intensity = intensity * num;
				light.range = range * num;
			}
		}
	}
	internal sealed class TrailRecord
	{
		private readonly TrailRenderer trail;

		private readonly float widthMultiplier;

		private readonly float time;

		internal TrailRecord(TrailRenderer targetTrail)
		{
			trail = targetTrail;
			widthMultiplier = trail.widthMultiplier;
			time = trail.time;
		}

		internal void Apply(float multiplier)
		{
			if (!((Object)(object)trail == (Object)null))
			{
				float num = Mathf.Max(0f, multiplier);
				trail.widthMultiplier = widthMultiplier * num;
				trail.time = time * num;
			}
		}
	}
	internal struct PendingPadBoost
	{
		internal int BoostLevel;
	}
	internal struct ActiveBoostState
	{
		internal bool IsPadBoost;

		internal int PadLevel;
	}
	[HarmonyPatch(typeof(ItemVehicle), "Start")]
	internal static class ItemVehicleStartPatch
	{
		private static void Postfix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.RegisterVehicle(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "OnDestroy")]
	internal static class ItemVehicleOnDestroyPatch
	{
		private static void Prefix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.UnregisterVehicle(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "ApplyTuningMultipliers")]
	internal static class ItemVehicleApplyTuningMultipliersPatch
	{
		private static void Postfix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.ApplyVehicleMultipliers(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "FixedUpdateActive")]
	internal static class ItemVehicleFixedUpdateActivePatch
	{
		private static void Postfix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.ApplyReverseAcceleration(__instance);
			ArenaRaceSpeedBoostCore.ApplyEffectExaggeration(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "ApplyDriftBoost")]
	internal static class ItemVehicleApplyDriftBoostPatch
	{
		private static void Prefix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.PrepareDriftBoost(__instance);
		}

		private static void Postfix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.FinishDriftBoost(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicle), "ApplyVehicleSteering")]
	internal static class ItemVehicleApplyVehicleSteeringPatch
	{
		private static void Postfix(ItemVehicle __instance)
		{
			ArenaRaceSpeedBoostCore.ApplyYawCorrectionStrength(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemVehicleBoostPad), "OnTriggerEnter")]
	internal static class ItemVehicleBoostPadOnTriggerEnterPatch
	{
		private static bool Prefix(ItemVehicleBoostPad __instance, Collider _other)
		{
			return ArenaRaceSpeedBoostCore.HandleBoostPad(__instance, _other);
		}
	}
}