Decompiled source of Repo Company v1.0.0

TruckDropoff.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[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: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TruckDropoff")]
[assembly: AssemblyTitle("TruckDropoff")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 Empress.TruckDropoffOnly
{
	[BepInPlugin("Empress.TruckDropoffOnly", "TruckDropoffOnly", "1.5.2")]
	public class TruckDropoffOnly : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <EnforceLoop>d__62 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TruckDropoffOnly <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnforceLoop>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Expected O, but got Unknown
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				if (!IsGameplayScene())
				{
					<>4__this._appliedForThisLevel = false;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				}
				<>4__this.TryApply();
				<>2__current = (object)new WaitForSeconds(<>4__this._enforceContinuously.Value ? Mathf.Max(0.1f, <>4__this._enforceIntervalSeconds.Value) : 0.5f);
				<>1__state = 2;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnsureDoorColliderNextFrame>d__60 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TruckDropoffOnly <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsureDoorColliderNextFrame>d__60(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this.EnsureDoorCollider();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <FallbackCloseDoorRoutine>d__80 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TruckDropoffOnly <>4__this;

			private Transform <door>5__1;

			private bool <local>5__2;

			private float <dur>5__3;

			private float <from>5__4;

			private float <to>5__5;

			private float <t>5__6;

			private float <a>5__7;

			private float <ny>5__8;

			private Vector3 <lp>5__9;

			private Vector3 <wp>5__10;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FallbackCloseDoorRoutine>d__80(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<door>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0169: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<door>5__1 = <>4__this.FindDoorTransform();
					if ((Object)(object)<door>5__1 == (Object)null)
					{
						return false;
					}
					<local>5__2 = <>4__this._doorUseLocal.Value;
					<dur>5__3 = Mathf.Max(0.05f, <>4__this._doorCloseDuration.Value);
					<from>5__4 = (<local>5__2 ? <door>5__1.localPosition.y : <door>5__1.position.y);
					<to>5__5 = <>4__this._doorClosedY.Value;
					<t>5__6 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__6 < <dur>5__3)
				{
					<t>5__6 += Time.deltaTime;
					<a>5__7 = Mathf.Clamp01(<t>5__6 / <dur>5__3);
					<ny>5__8 = Mathf.Lerp(<from>5__4, <to>5__5, <a>5__7);
					if (<local>5__2)
					{
						<lp>5__9 = <door>5__1.localPosition;
						<lp>5__9.y = <ny>5__8;
						<door>5__1.localPosition = <lp>5__9;
					}
					else
					{
						<wp>5__10 = <door>5__1.position;
						<wp>5__10.y = <ny>5__8;
						<door>5__1.position = <wp>5__10;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LeaveSequenceCoroutine>d__78 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public MonoBehaviour screen;

			public TruckDropoffOnly <>4__this;

			private bool <usedController>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LeaveSequenceCoroutine>d__78(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: Expected O, but got Unknown
				//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ef: Expected O, but got Unknown
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.TryPlayDepartSound();
					if (!<>4__this.SuppressEngineStartSound)
					{
						<>4__this.TryCallPrivate(screen, "EngineStartSound");
					}
					if (<>4__this._enableAutoCloseOnLeave.Value)
					{
						<usedController>5__1 = <>4__this.TryTruckDoorControllerClose();
						if (!<usedController>5__1 && <>4__this._fallbackCloseDoorIfNoController.Value)
						{
							if (<>4__this._ensureDoorCollider.Value)
							{
								<>4__this.EnsureDoorCollider();
							}
							<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.FallbackCloseDoorRoutine());
							<>1__state = 1;
							return true;
						}
						goto IL_0110;
					}
					goto IL_0146;
				case 1:
					<>1__state = -1;
					goto IL_0110;
				case 2:
					<>1__state = -1;
					goto IL_0146;
				case 3:
					<>1__state = -1;
					goto IL_01ca;
				case 4:
					{
						<>1__state = -1;
						RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)0);
						return false;
					}
					IL_01ca:
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0f, <>4__this._preChangeLevelDelay.Value));
					<>1__state = 4;
					return true;
					IL_0146:
					if (<>4__this._enableAutoLiftOnLeave.Value)
					{
						TruckLiftRelay.RequestLift(<>4__this._truckLiftHeight.Value, <>4__this._truckLiftDuration.Value, <>4__this.FindTruckRootForAnimation(screen));
						<>2__current = (object)new WaitForSeconds(Mathf.Max(0.01f, <>4__this._truckLiftDuration.Value));
						<>1__state = 3;
						return true;
					}
					goto IL_01ca;
					IL_0110:
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0f, <>4__this._doorCloseWaitSeconds.Value));
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadAndPlayOgg>d__88 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string filePath;

			public float vol;

			public TruckDropoffOnly <>4__this;

			private UnityWebRequest <req>5__1;

			private AudioClip <clip>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadAndPlayOgg>d__88(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<req>5__1 = null;
				<clip>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<req>5__1 = UnityWebRequestMultimedia.GetAudioClip("file://" + filePath, (AudioType)14);
						<>1__state = -3;
						<>2__current = <req>5__1.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						if (<req>5__1.isNetworkError || <req>5__1.isHttpError)
						{
							Logger.LogDebug((object)("Audio load error: " + <req>5__1.error));
							result = false;
						}
						else
						{
							<clip>5__2 = DownloadHandlerAudioClip.GetContent(<req>5__1);
							if (!((Object)(object)<clip>5__2 == (Object)null))
							{
								<>4__this._audioSource.volume = Mathf.Clamp01(vol);
								<>4__this._audioSource.clip = <clip>5__2;
								<>4__this._audioSource.Play();
								<clip>5__2 = null;
								<>m__Finally1();
								<req>5__1 = null;
								result = false;
								break;
							}
							result = false;
						}
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<req>5__1 != null)
				{
					((IDisposable)<req>5__1).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PLUGIN_GUID = "Empress.TruckDropoffOnly";

		public const string PLUGIN_NAME = "TruckDropoffOnly";

		public const string PLUGIN_VERSION = "1.5.2";

		private ConfigEntry<bool> _forceSingleExtractor = null;

		private ConfigEntry<bool> _lockNonTruckExtractors = null;

		private ConfigEntry<bool> _skipAllChangesOnShop = null;

		private ConfigEntry<bool> _disableNonTruckExtractions = null;

		private ConfigEntry<bool> _enforceContinuously = null;

		private ConfigEntry<float> _enforceIntervalSeconds = null;

		private ConfigEntry<bool> _forceExploreExtractionRooms = null;

		private ConfigEntry<string> _truckExtractorNameHints = null;

		private ConfigEntry<float> _truckExtractorMaxDistance = null;

		private ConfigEntry<bool> _autoActivateExtractorButtons = null;

		private ConfigEntry<bool> _onlyHostActivatesButtons = null;

		private ConfigEntry<string> _buttonNameContains = null;

		private ConfigEntry<string> _buttonMethodNames = null;

		private ConfigEntry<string> _buttonFlagNames = null;

		private ConfigEntry<bool> _enableAutoCloseOnLeave = null;

		private ConfigEntry<bool> _enableAutoLiftOnLeave = null;

		private ConfigEntry<float> _doorCloseWaitSeconds = null;

		internal ConfigEntry<string> _truckRootNameHint = null;

		private ConfigEntry<float> _truckLiftHeight = null;

		private ConfigEntry<float> _truckLiftDuration = null;

		private ConfigEntry<float> _preChangeLevelDelay = null;

		private ConfigEntry<bool> _onlyHostRunsSequence = null;

		private ConfigEntry<bool> _fallbackCloseDoorIfNoController = null;

		private ConfigEntry<bool> _doorUseLocal = null;

		private ConfigEntry<float> _doorClosedY = null;

		private ConfigEntry<float> _doorCloseDuration = null;

		private ConfigEntry<string> _doorRootHint = null;

		private ConfigEntry<string> _doorParentName = null;

		private ConfigEntry<string> _doorName = null;

		private ConfigEntry<bool> _ensureDoorCollider = null;

		private ConfigEntry<bool> _doorColliderIsTrigger = null;

		private ConfigEntry<string> _departureOggFileName = null;

		private ConfigEntry<float> _departureVolume = null;

		private ConfigEntry<bool> _suppressEngineStartSound = null;

		private bool _loggedMissingClip;

		private bool _appliedForThisLevel;

		private AudioSource _audioSource = null;

		private readonly HashSet<int> _pressedButtons = new HashSet<int>();

		internal static TruckDropoffOnly Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		internal bool SuppressEngineStartSound => _suppressEngineStartSound.Value;

		private void Awake()
		{
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			_forceSingleExtractor = ((BaseUnityPlugin)this).Config.Bind<bool>("Mode", "ForceSingleExtractor", true, "Rounds behave as if there is exactly one extractor. Items only need to be brought to the truck.");
			_lockNonTruckExtractors = ((BaseUnityPlugin)this).Config.Bind<bool>("Mode", "LockNonTruckExtractors", true, "Non-truck ExtractionPoint consoles are locked and show 'LOCKED'. Truck stays unlocked.");
			_skipAllChangesOnShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Mode", "SkipAllChangesOnShop", true, "Shop level stays vanilla (prevents purchases from breaking).");
			_disableNonTruckExtractions = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableNonTruckExtractionRooms", true, "Turn OFF Extraction on any RoomVolume that is not the Truck.");
			_enforceContinuously = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnforceContinuously", true, "Re-apply truck-only extraction periodically.");
			_enforceIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "EnforceIntervalSeconds", 1f, "How often (seconds) to re-apply when EnforceContinuously is true.");
			_forceExploreExtractionRooms = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceExploreExtractionRooms", true, "Call SetExplored() on all Extraction rooms so tally works cleanly.");
			_truckExtractorNameHints = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TruckExtractorNameHints", "Truck;Truck Run;TruckRoom;Truck_Bay;TruckBay;TruckArea", "Semicolon-separated name hints used on parents to identify the truck extractor if no RoomVolume.Truck is set.");
			_truckExtractorMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TruckExtractorMaxDistance", 40f, "If name/flags are ambiguous, an ExtractionPoint within this many meters of the truck root is treated as the truck extractor.");
			_autoActivateExtractorButtons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoActivateExtractorButtons", true, "Auto-press/activate extractor consoles/buttons under TRUCK extraction volumes only.");
			_onlyHostActivatesButtons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyHostActivatesButtons", true, "Host/singleplayer only performs auto-activation to avoid duplicate presses.");
			_buttonNameContains = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ButtonNameContains", "button;switch;console;terminal;extractor;panel", "Semicolon-separated substrings to detect button/console MonoBehaviours.");
			_buttonMethodNames = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ButtonMethodNames", "Press;Activate;TurnOn;Toggle;Use;Interact;OnInteract", "Semicolon-separated method names to try (0-arg / (bool) / (GameObject)/(Component)).");
			_buttonFlagNames = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ButtonFlagNames", "activated;active;isActive;on;enabled;open;pressed", "Semicolon-separated boolean fields/properties to set true as a fallback.");
			_enableAutoCloseOnLeave = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLeave", "EnableAutoCloseDoor", true, "Auto close truck door when leaving.");
			_enableAutoLiftOnLeave = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLeave", "EnableAutoLift", true, "Lift the truck upwards when leaving.");
			_doorCloseWaitSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave", "DoorCloseExtraWait", 0.6f, "Extra wait after requesting close (seconds).");
			_truckRootNameHint = ((BaseUnityPlugin)this).Config.Bind<string>("AutoLeave", "TruckRootNameHint", "Truck Run", "Root GameObject name that contains the truck.");
			_truckLiftHeight = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave", "TruckLiftHeight", 25f, "Meters to lift the truck upwards.");
			_truckLiftDuration = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave", "TruckLiftDuration", 8f, "Seconds to lift the truck.");
			_preChangeLevelDelay = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave", "DelayBeforeChangeLevel", 8f, "Seconds to wait before changing level.");
			_onlyHostRunsSequence = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLeave", "HostAuthoritative", true, "Only host triggers leave sequence; visuals synced.");
			_fallbackCloseDoorIfNoController = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLeave.DoorFallback", "EnableFallbackClose", true, "If TruckDoorController mod isn't installed, move door Y directly.");
			_doorUseLocal = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoLeave.DoorFallback", "UseLocal", false, "Animate in local (true) or world (false) space.");
			_doorClosedY = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave.DoorFallback", "ClosedY", 1f, "Y coordinate when door is closed (fallback).");
			_doorCloseDuration = ((BaseUnityPlugin)this).Config.Bind<float>("AutoLeave.DoorFallback", "CloseDuration", 0.8f, "Seconds to roll the door down (fallback).");
			_doorRootHint = ((BaseUnityPlugin)this).Config.Bind<string>("AutoLeave.DoorFallback", "RootHint", "Truck Run", "Top-level object name that contains the door.");
			_doorParentName = ((BaseUnityPlugin)this).Config.Bind<string>("AutoLeave.DoorFallback", "ParentName", "Door", "Parent object that holds the truck door.");
			_doorName = ((BaseUnityPlugin)this).Config.Bind<string>("AutoLeave.DoorFallback", "DoorName", "Truck Door", "Exact GameObject name for the truck door.");
			_ensureDoorCollider = ((BaseUnityPlugin)this).Config.Bind<bool>("DoorCollider", "EnsureDoorCollider", true, "Add a collider to the truck door if missing.");
			_doorColliderIsTrigger = ((BaseUnityPlugin)this).Config.Bind<bool>("DoorCollider", "ColliderIsTrigger", false, "Create collider as trigger.");
			_departureOggFileName = ((BaseUnityPlugin)this).Config.Bind<string>("Sound", "DepartureOggFileName", "truck_depart.ogg", "Filename of .ogg next to this DLL to play when truck departs.");
			_departureVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Sound", "DepartureVolume", 0.85f, "Volume [0..1] for the departure sound.");
			_suppressEngineStartSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Sound", "SuppressVanillaEngineStartSound", true, "If true, mutes the base game's truck engine start jingle (EngineStartSound/EngineStartRPC).\nThis does NOT affect your custom departure .ogg.");
			GameObject val = new GameObject("Empress_TruckDropoffOnly_Host");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)52;
			val.AddComponent<TruckLiftRelay>();
			_audioSource = val.AddComponent<AudioSource>();
			_audioSource.playOnAwake = false;
			_audioSource.loop = false;
			_audioSource.spatialBlend = 0f;
			SceneManager.sceneLoaded += OnSceneLoaded;
			Patch();
			((MonoBehaviour)this).StartCoroutine(EnforceLoop());
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded — Truck-only drop-off (SingleExtractor={_forceSingleExtractor.Value}).");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll(typeof(TruckDropoffOnly));
			Harmony.PatchAll(typeof(Patch_TruckScreenText_GotoNextLevel));
			Harmony.PatchAll(typeof(Patch_PhysGrabObject_SquelchNRE));
			Harmony.PatchAll(typeof(Patch_ExtractionPoint_HaulGoalSet_ForceSingle));
			Harmony.PatchAll(typeof(Patch_TruckScreenText_EngineStartSound_Mute));
			Harmony.PatchAll(typeof(Patch_TruckScreenText_EngineStartRPC_Mute));
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode m)
		{
			_appliedForThisLevel = false;
			_pressedButtons.Clear();
			if (IsGameplayScene() && _ensureDoorCollider.Value)
			{
				((MonoBehaviour)this).StartCoroutine(EnsureDoorColliderNextFrame());
			}
		}

		[IteratorStateMachine(typeof(<EnsureDoorColliderNextFrame>d__60))]
		private IEnumerator EnsureDoorColliderNextFrame()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsureDoorColliderNextFrame>d__60(0)
			{
				<>4__this = this
			};
		}

		internal static bool IsGameplayScene()
		{
			//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)
			Scene activeScene = SceneManager.GetActiveScene();
			string text = ((Scene)(ref activeScene)).name ?? string.Empty;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (text.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (text.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (text.IndexOf("MainMenu", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (text.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			return true;
		}

		[IteratorStateMachine(typeof(<EnforceLoop>d__62))]
		private IEnumerator EnforceLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnforceLoop>d__62(0)
			{
				<>4__this = this
			};
		}

		private void TryApply()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			if (_skipAllChangesOnShop.Value && SemiFunc.RunIsShop())
			{
				return;
			}
			LevelGenerator val = SemiSafeFindLevelGenerator();
			if ((Object)(object)val == (Object)null)
			{
				_appliedForThisLevel = false;
			}
			else
			{
				if ((int)val.State < 11)
				{
					return;
				}
				if (!_appliedForThisLevel)
				{
					int num = ApplyTruckAsOnlyExtraction();
					if (num >= 0)
					{
						_appliedForThisLevel = true;
						Logger.LogInfo((object)$"TruckDropoffOnly applied. Truck volumes set as Extraction. DisabledOthers={_disableNonTruckExtractions.Value}");
					}
				}
				else if (_enforceContinuously.Value)
				{
					ApplyTruckAsOnlyExtraction();
				}
				if (_forceSingleExtractor.Value)
				{
					ForceSingleExtractorRound();
					if (_lockNonTruckExtractors.Value)
					{
						LockAllNonTruckExtractionPoints();
					}
				}
				if (_forceExploreExtractionRooms.Value)
				{
					ForceExploreAllExtractionRooms();
				}
				if (_autoActivateExtractorButtons.Value)
				{
					TryAutoActivateExtractorButtons(truckOnly: true);
				}
			}
		}

		private int ApplyTruckAsOnlyExtraction()
		{
			int num = 0;
			RoomVolume[] array = Object.FindObjectsOfType<RoomVolume>();
			if (array == null || array.Length == 0)
			{
				return -1;
			}
			RoomVolume[] array2 = array;
			foreach (RoomVolume val in array2)
			{
				if (!((Object)(object)val == (Object)null) && val.Truck && !val.Extraction)
				{
					val.Extraction = true;
					num++;
				}
			}
			if (_disableNonTruckExtractions.Value)
			{
				RoomVolume[] array3 = array;
				foreach (RoomVolume val2 in array3)
				{
					if (!((Object)(object)val2 == (Object)null) && !val2.Truck && val2.Extraction)
					{
						val2.Extraction = false;
						num++;
					}
				}
			}
			return num;
		}

		private void ForceExploreAllExtractionRooms()
		{
			RoomVolume[] array = Object.FindObjectsOfType<RoomVolume>();
			if (array == null || array.Length == 0)
			{
				return;
			}
			RoomVolume[] array2 = array;
			foreach (RoomVolume val in array2)
			{
				if (Object.op_Implicit((Object)(object)val) && val.Extraction)
				{
					val.SetExplored();
				}
			}
		}

		private void TryAutoActivateExtractorButtons(bool truckOnly)
		{
			if (_onlyHostActivatesButtons.Value && !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			string[] needles = SplitList(_buttonNameContains.Value);
			string[] methodNames = SplitList(_buttonMethodNames.Value);
			string[] flagNames = SplitList(_buttonFlagNames.Value);
			RoomVolume[] array = Object.FindObjectsOfType<RoomVolume>();
			if (array == null || array.Length == 0)
			{
				return;
			}
			RoomVolume[] array2 = array;
			foreach (RoomVolume val in array2)
			{
				if (!Object.op_Implicit((Object)(object)val) || !val.Extraction || (truckOnly && !val.Truck))
				{
					continue;
				}
				MonoBehaviour[] componentsInChildren = ((Component)((Component)val).transform).GetComponentsInChildren<MonoBehaviour>(true);
				MonoBehaviour[] array3 = componentsInChildren;
				foreach (MonoBehaviour val2 in array3)
				{
					if (!Object.op_Implicit((Object)(object)val2))
					{
						continue;
					}
					GameObject gameObject = ((Component)val2).gameObject;
					int instanceID = ((Object)gameObject).GetInstanceID();
					if (_pressedButtons.Contains(instanceID))
					{
						continue;
					}
					string text = ((Object)gameObject).name ?? string.Empty;
					string text2 = ((object)val2).GetType().Name ?? string.Empty;
					if (MatchesAny(text, needles) || MatchesAny(text2, needles))
					{
						bool flag = false;
						try
						{
							flag = TryInvokeActivation(val2, methodNames) || TrySetFlagTrue(val2, flagNames);
						}
						catch (Exception ex)
						{
							Logger.LogDebug((object)("AutoActivate: " + text2 + "('" + text + "') threw: " + ex.Message));
						}
						if (flag)
						{
							_pressedButtons.Add(instanceID);
							Logger.LogInfo((object)("AutoActivate: triggered " + text2 + " on \"" + text + "\""));
						}
					}
				}
			}
		}

		private static string[] SplitList(string s)
		{
			return string.IsNullOrWhiteSpace(s) ? Array.Empty<string>() : (from x in s.Split(new char[3] { ';', ',', '|' }, StringSplitOptions.RemoveEmptyEntries)
				select x.Trim() into x
				where x.Length > 0
				select x).ToArray();
		}

		private static bool MatchesAny(string hay, string[] needles)
		{
			if (needles == null || needles.Length == 0)
			{
				return false;
			}
			foreach (string value in needles)
			{
				if (hay.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryInvokeActivation(MonoBehaviour mb, string[] methodNames)
		{
			if (methodNames == null || methodNames.Length == 0)
			{
				return false;
			}
			Type type = ((object)mb).GetType();
			foreach (string name in methodNames)
			{
				MethodInfo method = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (method != null)
				{
					method.Invoke(mb, null);
					return true;
				}
				MethodInfo method2 = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null);
				if (method2 != null)
				{
					method2.Invoke(mb, new object[1] { true });
					return true;
				}
				MethodInfo method3 = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(GameObject) }, null);
				if (method3 != null)
				{
					method3.Invoke(mb, new object[1] { ((Component)mb).gameObject });
					return true;
				}
				MethodInfo method4 = type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(Component) }, null);
				if (method4 != null)
				{
					method4.Invoke(mb, new object[1] { mb });
					return true;
				}
			}
			MethodInfo method5 = type.GetMethod("Interact", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (method5 != null)
			{
				method5.Invoke(mb, null);
				return true;
			}
			return false;
		}

		private static bool TrySetFlagTrue(MonoBehaviour mb, string[] flagNames)
		{
			if (flagNames == null || flagNames.Length == 0)
			{
				return false;
			}
			Type type = ((object)mb).GetType();
			foreach (string name in flagNames)
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(bool))
				{
					field.SetValue(mb, true);
					return true;
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(bool) && property.CanWrite)
				{
					property.SetValue(mb, true);
					return true;
				}
			}
			return false;
		}

		private LevelGenerator? SemiSafeFindLevelGenerator()
		{
			try
			{
				return LevelGenerator.Instance;
			}
			catch
			{
				return Object.FindObjectOfType<LevelGenerator>();
			}
		}

		private void Update()
		{
			if (!IsGameplayScene())
			{
				_appliedForThisLevel = false;
			}
			else if ((Object)(object)SemiSafeFindLevelGenerator() == (Object)null)
			{
				_appliedForThisLevel = false;
			}
		}

		private void ForceSingleExtractorRound()
		{
			try
			{
				RoundDirector instance = RoundDirector.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				FieldInfo fieldInfo = AccessTools.Field(((object)instance).GetType(), "extractionPoints");
				if (fieldInfo != null && (int)fieldInfo.GetValue(instance) != 1)
				{
					fieldInfo.SetValue(instance, 1);
					Logger.LogDebug((object)"Forced RoundDirector.extractionPoints = 1");
				}
				bool foundAny;
				IEnumerable<ExtractionPoint> collection = IdentifyTruckExtractionPoints(out foundAny);
				if (!foundAny)
				{
					Logger.LogDebug((object)"Could not positively identify truck extractor; not trimming list.");
					return;
				}
				FieldInfo fieldInfo2 = AccessTools.Field(((object)instance).GetType(), "extractionPointList");
				if (!(fieldInfo2 != null) || !(fieldInfo2.GetValue(instance) is List<GameObject> list) || list.Count <= 1)
				{
					return;
				}
				HashSet<ExtractionPoint> truckSet = new HashSet<ExtractionPoint>(collection);
				list.RemoveAll(delegate(GameObject go)
				{
					if (!Object.op_Implicit((Object)(object)go))
					{
						return true;
					}
					ExtractionPoint component = go.GetComponent<ExtractionPoint>();
					return !Object.op_Implicit((Object)(object)component) || !truckSet.Contains(component);
				});
				Logger.LogDebug((object)$"Trimmed RoundDirector.extractionPointList to {list.Count} truck EP(s).");
			}
			catch (Exception ex)
			{
				Logger.LogDebug((object)("ForceSingleExtractorRound error: " + ex.Message));
			}
		}

		private void LockAllNonTruckExtractionPoints()
		{
			try
			{
				ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(true);
				if (array == null || array.Length == 0)
				{
					return;
				}
				bool foundAny;
				IEnumerable<ExtractionPoint> collection = IdentifyTruckExtractionPoints(out foundAny);
				if (!foundAny)
				{
					Logger.LogDebug((object)"No truck EP positively identified. Skipping locks to avoid bricking the level.");
					return;
				}
				HashSet<ExtractionPoint> truckSet = new HashSet<ExtractionPoint>(collection);
				ExtractionPoint[] array2 = array;
				foreach (ExtractionPoint val in array2)
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						bool flag = truckSet.Contains(val);
						val.isLocked = !flag;
					}
				}
				Logger.LogDebug((object)$"Locked {array.Count((ExtractionPoint ep) => Object.op_Implicit((Object)(object)ep) && !truckSet.Contains(ep))} non-truck extractor(s); unlocked {truckSet.Count()} truck extractor(s).");
			}
			catch (Exception ex)
			{
				Logger.LogDebug((object)("LockAllNonTruckExtractionPoints error: " + ex.Message));
			}
		}

		private IEnumerable<ExtractionPoint> IdentifyTruckExtractionPoints(out bool foundAny)
		{
			foundAny = false;
			ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(true);
			if (array == null || array.Length == 0)
			{
				return Array.Empty<ExtractionPoint>();
			}
			List<ExtractionPoint> list = new List<ExtractionPoint>();
			ExtractionPoint[] array2 = array;
			foreach (ExtractionPoint val in array2)
			{
				try
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						RoomVolume val2 = null;
						if (Object.op_Implicit((Object)(object)val.extractionArea))
						{
							val2 = val.extractionArea.GetComponentInParent<RoomVolume>();
						}
						if (!Object.op_Implicit((Object)(object)val2))
						{
							val2 = ((Component)val).GetComponentInParent<RoomVolume>();
						}
						if (Object.op_Implicit((Object)(object)val2) && val2.Truck)
						{
							list.Add(val);
						}
					}
				}
				catch
				{
				}
			}
			if (list.Count > 0)
			{
				foundAny = true;
				return list;
			}
			string[] hints = SplitList(_truckExtractorNameHints.Value);
			List<ExtractionPoint> list2 = array.Where((ExtractionPoint ep) => Object.op_Implicit((Object)(object)ep) && HasTruckNameHint(((Component)ep).transform, hints)).ToList();
			if (list2.Count > 0)
			{
				foundAny = true;
				return list2;
			}
			Transform root = FindTruckRootForAnimation(null);
			if (Object.op_Implicit((Object)(object)root))
			{
				float maxDist = Mathf.Max(3f, _truckExtractorMaxDistance.Value);
				List<ExtractionPoint> list3 = array.Where((ExtractionPoint ep) => Object.op_Implicit((Object)(object)ep) && Vector3.Distance(((Component)ep).transform.position, root.position) <= maxDist).ToList();
				if (list3.Count > 0)
				{
					foundAny = true;
					return list3;
				}
			}
			if (array.Length == 1)
			{
				foundAny = true;
				return array;
			}
			return Array.Empty<ExtractionPoint>();
		}

		private bool HasTruckNameHint(Transform t, string[] hints)
		{
			if ((Object)(object)t == (Object)null || hints == null || hints.Length == 0)
			{
				return false;
			}
			int num = 0;
			Transform val = t;
			while ((Object)(object)val != (Object)null && num < 8)
			{
				string hay = ((Object)val).name ?? string.Empty;
				if (MatchesAny(hay, hints))
				{
					return true;
				}
				val = val.parent;
				num++;
			}
			return false;
		}

		internal bool HandleTruckGotoNextLevel(object truckScreenTextInstance)
		{
			if (!IsGameplayScene())
			{
				return true;
			}
			if (_onlyHostRunsSequence.Value && !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			if (!_enableAutoCloseOnLeave.Value && !_enableAutoLiftOnLeave.Value)
			{
				return true;
			}
			((MonoBehaviour)this).StartCoroutine(LeaveSequenceCoroutine((MonoBehaviour)((truckScreenTextInstance is MonoBehaviour) ? truckScreenTextInstance : null)));
			return false;
		}

		[IteratorStateMachine(typeof(<LeaveSequenceCoroutine>d__78))]
		private IEnumerator LeaveSequenceCoroutine(MonoBehaviour screen)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LeaveSequenceCoroutine>d__78(0)
			{
				<>4__this = this,
				screen = screen
			};
		}

		private bool TryTruckDoorControllerClose()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				Type type = assemblies.SelectMany(delegate(Assembly a)
				{
					try
					{
						return a.GetTypes();
					}
					catch
					{
						return Array.Empty<Type>();
					}
				}).FirstOrDefault((Type t) => t.FullName == "Empress.TruckDoorController.DoorEventHandler");
				if (type == null)
				{
					return false;
				}
				MethodInfo method = type.GetMethod("RequestClose", BindingFlags.Static | BindingFlags.Public);
				if (method == null)
				{
					return false;
				}
				method.Invoke(null, new object[1] { true });
				Logger.LogDebug((object)"Invoked TruckDoorController.DoorEventHandler.RequestClose(true)");
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogDebug((object)("Door controller reflection failed: " + ex.Message));
				return false;
			}
		}

		[IteratorStateMachine(typeof(<FallbackCloseDoorRoutine>d__80))]
		private IEnumerator FallbackCloseDoorRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FallbackCloseDoorRoutine>d__80(0)
			{
				<>4__this = this
			};
		}

		private Transform? FindDoorTransform()
		{
			Transform val = null;
			if (!string.IsNullOrWhiteSpace(_doorRootHint.Value))
			{
				GameObject val2 = GameObject.Find(_doorRootHint.Value);
				if ((Object)(object)val2 != (Object)null)
				{
					val = val2.transform;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				Transform val3 = FindRecursive(val, _doorParentName.Value);
				if ((Object)(object)val3 != (Object)null)
				{
					Transform val4 = val3.Find(_doorName.Value);
					if ((Object)(object)val4 != (Object)null)
					{
						return val4;
					}
				}
				Transform val5 = FindRecursive(val, _doorName.Value);
				if ((Object)(object)val5 != (Object)null)
				{
					return val5;
				}
			}
			Transform[] array = Object.FindObjectsOfType<Transform>(true);
			foreach (Transform val6 in array)
			{
				if (((Object)val6).name.Equals(_doorName.Value, StringComparison.OrdinalIgnoreCase) || ((Object)val6).name.Equals("TruckDoor", StringComparison.OrdinalIgnoreCase) || ((Object)val6).name.Equals("Truck_Door", StringComparison.OrdinalIgnoreCase))
				{
					return val6;
				}
			}
			return null;
		}

		private static Transform? FindRecursive(Transform t, string name)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if ((Object)(object)t == (Object)null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			foreach (Transform item in t)
			{
				Transform val = item;
				if (((Object)val).name.Equals(name, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
				Transform val2 = FindRecursive(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		internal Transform? FindTruckRootForAnimation(MonoBehaviour screen)
		{
			//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_0133: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrWhiteSpace(_truckRootNameHint.Value))
			{
				GameObject val = GameObject.Find(_truckRootNameHint.Value);
				if ((Object)(object)val != (Object)null)
				{
					return val.transform;
				}
			}
			Transform val2 = FindDoorTransform();
			if ((Object)(object)val2 != (Object)null)
			{
				Transform val3 = val2;
				for (int i = 0; i < 6; i++)
				{
					if (!((Object)(object)val3 != (Object)null))
					{
						break;
					}
					if (((Object)val3).name.IndexOf("truck", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val3;
					}
					val3 = val3.parent;
				}
				return val2.parent;
			}
			Transform result = null;
			float num = float.MaxValue;
			Transform[] array = Object.FindObjectsOfType<Transform>(true);
			Transform[] array2 = array;
			foreach (Transform val4 in array2)
			{
				if (Object.op_Implicit((Object)(object)val4) && ((Object)val4).name.IndexOf("truck", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					float num2 = (((Object)(object)screen != (Object)null) ? Vector3.SqrMagnitude(val4.position - ((Component)screen).transform.position) : 0f);
					if (num2 < num)
					{
						num = num2;
						result = val4;
					}
				}
			}
			return result;
		}

		private void TryCallPrivate(object instance, string method)
		{
			if (instance == null)
			{
				return;
			}
			try
			{
				AccessTools.Method(instance.GetType(), method, (Type[])null, (Type[])null)?.Invoke(instance, null);
			}
			catch (Exception ex)
			{
				Logger.LogDebug((object)("Failed to call private " + method + ": " + ex.Message));
			}
		}

		private void EnsureDoorCollider()
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindDoorTransform();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)val).gameObject;
			Collider val2 = default(Collider);
			if (gameObject.TryGetComponent<Collider>(ref val2))
			{
				return;
			}
			MeshFilter component = gameObject.GetComponent<MeshFilter>();
			Mesh val3 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
			bool flag = false;
			try
			{
				flag = (Object)(object)val3 != (Object)null && val3.isReadable;
			}
			catch
			{
				flag = false;
			}
			if ((Object)(object)val3 != (Object)null && flag)
			{
				MeshCollider val4 = gameObject.AddComponent<MeshCollider>();
				val4.sharedMesh = val3;
				val4.convex = true;
				((Collider)val4).isTrigger = _doorColliderIsTrigger.Value;
				Logger.LogInfo((object)"Added MeshCollider to truck door (readable mesh).");
				return;
			}
			BoxCollider val5 = gameObject.AddComponent<BoxCollider>();
			((Collider)val5).isTrigger = _doorColliderIsTrigger.Value;
			if (!TryGetCombinedLocalBounds(val, out var localCenter, out var localSize))
			{
				val5.center = Vector3.zero;
				val5.size = new Vector3(1.5f, 2f, 0.2f);
				Logger.LogInfo((object)"Added BoxCollider to truck door (default size; no renderers found).");
			}
			else
			{
				val5.center = localCenter;
				val5.size = localSize;
				Logger.LogInfo((object)"Added BoxCollider to truck door (from combined renderer bounds; mesh not readable).");
			}
		}

		private static bool TryGetCombinedLocalBounds(Transform root, out Vector3 localCenter, out Vector3 localSize)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0042: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			localCenter = Vector3.zero;
			localSize = Vector3.zero;
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return false;
			}
			Bounds bounds = componentsInChildren[0].bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			bounds = componentsInChildren[0].bounds;
			Bounds val = default(Bounds);
			((Bounds)(ref val))..ctor(center, ((Bounds)(ref bounds)).size);
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				((Bounds)(ref val)).Encapsulate(componentsInChildren[i].bounds);
			}
			Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix;
			Vector3 center2 = ((Bounds)(ref val)).center;
			Vector3 extents = ((Bounds)(ref val)).extents;
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int num = 0;
			for (int j = -1; j <= 1; j += 2)
			{
				for (int k = -1; k <= 1; k += 2)
				{
					for (int l = -1; l <= 1; l += 2)
					{
						array[num++] = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint(center2 + Vector3.Scale(extents, new Vector3((float)j, (float)k, (float)l)));
					}
				}
			}
			Vector3 val2 = array[0];
			Vector3 val3 = array[0];
			Vector3[] array2 = array;
			foreach (Vector3 val4 in array2)
			{
				val2 = Vector3.Min(val2, val4);
				val3 = Vector3.Max(val3, val4);
			}
			localCenter = (val3 + val2) * 0.5f;
			localSize = val3 - val2;
			return true;
		}

		internal void TryPlayDepartSound()
		{
			string location = ((BaseUnityPlugin)this).Info.Location;
			string path = Path.GetDirectoryName(location) ?? Paths.PluginPath;
			string text = Path.Combine(path, _departureOggFileName.Value);
			if (!File.Exists(text))
			{
				if (!_loggedMissingClip)
				{
					_loggedMissingClip = true;
					Logger.LogInfo((object)("Departure .ogg not found at '" + text + "'. Drop your file there to enable the sound."));
				}
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(LoadAndPlayOgg(text, _departureVolume.Value));
			}
		}

		[IteratorStateMachine(typeof(<LoadAndPlayOgg>d__88))]
		private IEnumerator LoadAndPlayOgg(string filePath, float vol)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAndPlayOgg>d__88(0)
			{
				<>4__this = this,
				filePath = filePath,
				vol = vol
			};
		}
	}
	[HarmonyPatch(typeof(TruckScreenText), "GotoNextLevel")]
	internal static class Patch_TruckScreenText_GotoNextLevel
	{
		private static bool Prefix(TruckScreenText __instance)
		{
			return TruckDropoffOnly.Instance.HandleTruckGotoNextLevel(__instance);
		}
	}
	[HarmonyPatch(typeof(TruckScreenText))]
	internal static class Patch_TruckScreenText_EngineStartSound_Mute
	{
		[HarmonyPatch("EngineStartSound")]
		[HarmonyPrefix]
		private static bool Prefix()
		{
			return !TruckDropoffOnly.Instance.SuppressEngineStartSound;
		}
	}
	[HarmonyPatch]
	internal static class Patch_TruckScreenText_EngineStartRPC_Mute
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(TruckScreenText), "EngineStartRPC", new Type[1] { typeof(PhotonMessageInfo) }, (Type[])null);
		}

		private static bool Prefix()
		{
			return !TruckDropoffOnly.Instance.SuppressEngineStartSound;
		}
	}
	[HarmonyPatch]
	internal static class Patch_ExtractionPoint_HaulGoalSet_ForceSingle
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(ExtractionPoint), "HaulGoalSet", (Type[])null, (Type[])null);
		}

		private static void Prefix(ref int value)
		{
			if (SemiFunc.RunIsShop())
			{
				return;
			}
			try
			{
				RoundDirector instance = RoundDirector.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				FieldInfo fieldInfo = AccessTools.Field(((object)instance).GetType(), "haulGoal");
				if (!(fieldInfo == null))
				{
					int num = (int)fieldInfo.GetValue(instance);
					if (num > 0)
					{
						value = num;
					}
				}
			}
			catch (Exception ex)
			{
				TruckDropoffOnly.Logger.LogDebug((object)("HaulGoalSet Prefix error: " + ex.Message));
			}
		}
	}
	[DisallowMultipleComponent]
	internal class TruckLiftRelay : MonoBehaviour, IOnEventCallback
	{
		[CompilerGenerated]
		private sealed class <AnimateLiftLocal>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float upMeters;

			public float duration;

			public Transform hint;

			public TruckLiftRelay <>4__this;

			private Transform <target>5__1;

			private Vector3 <from>5__2;

			private Vector3 <to>5__3;

			private float <t>5__4;

			private float <a>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateLiftLocal>d__9(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<target>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: 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_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<target>5__1 = <>4__this.FindTruckRoot(hint);
					if (!Object.op_Implicit((Object)(object)<target>5__1))
					{
						return false;
					}
					<from>5__2 = <target>5__1.position;
					<to>5__3 = <from>5__2 + new Vector3(0f, upMeters, 0f);
					<t>5__4 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__4 < duration)
				{
					<t>5__4 += Time.deltaTime;
					<a>5__5 = Mathf.Clamp01(<t>5__4 / duration);
					<target>5__1.position = Vector3.Lerp(<from>5__2, <to>5__3, <a>5__5);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				<target>5__1.position = <to>5__3;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const byte EVT_TRUCK_LIFT = 177;

		private static TruckLiftRelay _inst;

		private bool _callbackHooked;

		private void Awake()
		{
			_inst = this;
			SceneManager.sceneLoaded += OnSceneLoaded;
			TryHookForCurrentScene();
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (_callbackHooked)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				_callbackHooked = false;
			}
			if ((Object)(object)_inst == (Object)(object)this)
			{
				_inst = null;
			}
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode m)
		{
			TryHookForCurrentScene();
		}

		private void TryHookForCurrentScene()
		{
			if (!TruckDropoffOnly.IsGameplayScene())
			{
				if (_callbackHooked)
				{
					PhotonNetwork.RemoveCallbackTarget((object)this);
					_callbackHooked = false;
				}
			}
			else if (!_callbackHooked)
			{
				PhotonNetwork.AddCallbackTarget((object)this);
				_callbackHooked = true;
			}
		}

		public static void RequestLift(float upMeters, float duration, Transform hint)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0057: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (TruckDropoffOnly.IsGameplayScene())
			{
				TruckLiftRelay inst = _inst;
				if (inst != null)
				{
					((MonoBehaviour)inst).StartCoroutine(_inst.AnimateLiftLocal(upMeters, duration, hint));
				}
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"up", (object)upMeters);
				((Dictionary<object, object>)val).Add((object)"dur", (object)duration);
				Hashtable val2 = val;
				if (PhotonNetwork.InRoom)
				{
					RaiseEventOptions val3 = new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)1
					};
					SendOptions val4 = default(SendOptions);
					((SendOptions)(ref val4)).Reliability = true;
					PhotonNetwork.RaiseEvent((byte)177, (object)val2, val3, val4);
				}
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code != 177 || !TruckDropoffOnly.IsGameplayScene())
			{
				return;
			}
			try
			{
				float upMeters = 5f;
				float duration = 2f;
				object customData = photonEvent.CustomData;
				Hashtable val = (Hashtable)((customData is Hashtable) ? customData : null);
				if (val != null)
				{
					if (((Dictionary<object, object>)(object)val).ContainsKey((object)"up"))
					{
						upMeters = Convert.ToSingle(val[(object)"up"]);
					}
					if (((Dictionary<object, object>)(object)val).ContainsKey((object)"dur"))
					{
						duration = Convert.ToSingle(val[(object)"dur"]);
					}
				}
				TruckDropoffOnly.Instance?.TryPlayDepartSound();
				((MonoBehaviour)this).StartCoroutine(AnimateLiftLocal(upMeters, duration, null));
			}
			catch (Exception ex)
			{
				TruckDropoffOnly.Logger.LogDebug((object)("Lift event error: " + ex.Message));
			}
		}

		[IteratorStateMachine(typeof(<AnimateLiftLocal>d__9))]
		private IEnumerator AnimateLiftLocal(float upMeters, float duration, Transform hint)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateLiftLocal>d__9(0)
			{
				<>4__this = this,
				upMeters = upMeters,
				duration = duration,
				hint = hint
			};
		}

		private Transform FindTruckRoot(Transform hint)
		{
			if (Object.op_Implicit((Object)(object)hint))
			{
				return hint;
			}
			string value = TruckDropoffOnly.Instance._truckRootNameHint.Value;
			if (!string.IsNullOrWhiteSpace(value))
			{
				GameObject val = GameObject.Find(value);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val.transform;
				}
			}
			object obj = TruckDropoffOnly.Instance.FindTruckRootForAnimation(null);
			if (obj == null)
			{
				TruckScreenText obj2 = Object.FindObjectOfType<TruckScreenText>();
				obj = ((obj2 != null) ? ((Component)obj2).transform : null);
			}
			return (Transform)obj;
		}
	}
	[HarmonyPatch]
	internal static class Patch_PhysGrabObject_SquelchNRE
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private Type <physType>5__1;

			private BindingFlags <flags>5__2;

			private MethodInfo <m1>5__3;

			private MethodInfo <m2>5__4;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<physType>5__1 = null;
				<m1>5__3 = null;
				<m2>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<physType>5__1 = AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a)
					{
						try
						{
							return a.GetTypes();
						}
						catch
						{
							return Array.Empty<Type>();
						}
					}).FirstOrDefault((Type t) => t.Name == "PhysGrabObject");
					if (<physType>5__1 == null)
					{
						return false;
					}
					<flags>5__2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
					<m1>5__3 = <physType>5__1.GetMethod("OverrideTimersTick", <flags>5__2);
					<m2>5__4 = <physType>5__1.GetMethod("Update", <flags>5__2);
					if (<m1>5__3 != null)
					{
						<>2__current = <m1>5__3;
						<>1__state = 1;
						return true;
					}
					goto IL_0107;
				case 1:
					<>1__state = -1;
					goto IL_0107;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_0107:
					if (<m2>5__4 != null)
					{
						<>2__current = <m2>5__4;
						<>1__state = 2;
						return true;
					}
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		private static Exception Finalizer(Exception __exception)
		{
			if (__exception is NullReferenceException)
			{
				TruckDropoffOnly.Logger.LogDebug((object)"Swallowed NRE from PhysGrabObject (OverrideTimersTick/Update).");
				return null;
			}
			return __exception;
		}
	}
}