Decompiled source of AddExtractionButton v0.1.0

BepInEx/plugins/AddExtractionButton/AddExtractionButton.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("DJ-DarkLucky")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+b2bdd423d5494a2408072f302741eb84344966d0")]
[assembly: AssemblyProduct("AddExtractionButton")]
[assembly: AssemblyTitle("AddExtractionButton")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 AddExtractionButton
{
	internal sealed class ExtractionClownController : MonoBehaviour
	{
		private readonly struct PlacementBasis
		{
			internal Vector3 Origin { get; }

			internal Vector3 Right { get; }

			internal Vector3 Up { get; }

			internal Vector3 Into { get; }

			internal Bounds StorageBounds { get; }

			internal float ExpectedFloor { get; }

			internal PlacementBasis(Vector3 origin, Vector3 right, Vector3 up, Vector3 into, Bounds storageBounds, float expectedFloor)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				Origin = origin;
				Right = right;
				Up = up;
				Into = into;
				StorageBounds = storageBounds;
				ExpectedFloor = expectedFloor;
			}
		}

		private static readonly Dictionary<int, ExtractionClownController> ProxyOwners = new Dictionary<int, ExtractionClownController>();

		private static readonly string[] ClownResourcePathCandidates = new string[2] { "valuables/03 medium/Valuable Clown", "valuables/03 medium/Valueable Clown" };

		private const float HeldSuccessDelaySeconds = 1.5f;

		private const float SpawnRetrySeconds = 1f;

		private const float StorageEdgeGap = 0.18f;

		private const float FloorClearance = 0.015f;

		private const float LockRefreshSeconds = 0.25f;

		private const float PositionCorrectionTolerance = 0.025f;

		private const float RotationCorrectionToleranceDegrees = 1f;

		private const float NetworkCorrectionCooldownSeconds = 0.2f;

		private const float MaximumFloorOffsetFromStorage = 1.25f;

		private ExtractionPoint _extractionPoint;

		private Transform _platform;

		private GameObject? _clownRoot;

		private PhysGrabObject? _physGrabObject;

		private Rigidbody? _rigidbody;

		private bool _initialized;

		private bool _gateArmed;

		private bool _proxyConsumed;

		private bool _replacementRequested;

		private bool _pendingSuccess;

		private bool _allowSuccessCall;

		private bool _submissionSent;

		private bool _blockedSuccessLogged;

		private bool _quotaPreviouslyReached;

		private bool _spawnFailureLogged;

		private int _clownViewId;

		private float _nextSpawnAttemptAt;

		private float _nextNetworkCorrectionAt;

		private Vector3 _anchorPosition;

		private Quaternion _anchorRotation;

		private string? _resolvedResourcePath;

		private GameObject? _resolvedPrefab;

		private string? _lastDetailedSpawnFailure;

		internal void Initialize(ExtractionPoint extractionPoint)
		{
			_extractionPoint = extractionPoint;
			_platform = (((Object)(object)extractionPoint.platform != (Object)null) ? extractionPoint.platform : ((Component)extractionPoint).transform);
			_initialized = true;
			Plugin.Log.LogInfo((object)("Attached network-clown controller to '" + ((Object)extractionPoint).name + "'. Platform='" + ((Object)_platform).name + "', extractionArea='" + (((Object)(object)extractionPoint.extractionArea != (Object)null) ? ((Object)extractionPoint.extractionArea).name : "<none>") + "', ramp='" + (((Object)(object)extractionPoint.ramp != (Object)null) ? ((Object)extractionPoint.ramp).name : "<none>") + "'."));
		}

		internal static ExtractionClownController? FindOwner(ClownTrap clown)
		{
			int clownLookupId = GetClownLookupId(clown);
			if (clownLookupId == 0)
			{
				return null;
			}
			if (!ProxyOwners.TryGetValue(clownLookupId, out ExtractionClownController value))
			{
				return null;
			}
			if ((Object)(object)value != (Object)null && value.OwnsClown(clown))
			{
				return value;
			}
			ProxyOwners.Remove(clownLookupId);
			return null;
		}

		internal bool OwnsClown(ClownTrap clown)
		{
			if (_initialized && _clownViewId != 0)
			{
				return GetClownLookupId(clown) == _clownViewId;
			}
			return false;
		}

		internal bool ShouldSuppressExplosion(ClownTrap clown)
		{
			return OwnsClown(clown);
		}

		internal void OnNosePressed(ClownTrap clown, int playerActorNumber)
		{
			if (_initialized && _gateArmed && !_proxyConsumed && !_submissionSent && SemiFunc.IsMasterClientOrSingleplayer() && IsCurrentActivePoint() && OwnsClown(clown))
			{
				_proxyConsumed = true;
				if (IsQuotaReached())
				{
					_pendingSuccess = true;
					Plugin.Log.LogInfo((object)($"Quota confirmation received from clown ViewID={_clownViewId}, " + $"playerActor={playerActorNumber}, haul={_extractionPoint.haulCurrent}/{_extractionPoint.haulGoal}. " + "Vanilla Success will be requested on the next host frame."));
				}
				else
				{
					PlayVanillaDeny(playerActorNumber);
					_replacementRequested = true;
					Plugin.Log.LogInfo((object)($"Pre-quota clown press accepted from playerActor={playerActorNumber}, " + $"haul={_extractionPoint.haulCurrent}/{_extractionPoint.haulGoal}. " + "The used clown will be replaced with a fresh network instance."));
				}
			}
		}

		internal bool AllowVanillaStateSet(State requestedState)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (!_initialized || (int)requestedState != 3 || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return true;
			}
			if (_allowSuccessCall && IsQuotaReached())
			{
				_blockedSuccessLogged = false;
				return true;
			}
			if (_submissionSent)
			{
				return true;
			}
			if (!_gateArmed || !IsCurrentActivePoint())
			{
				return true;
			}
			ApplySubmissionGate();
			if (!_blockedSuccessLogged)
			{
				_blockedSuccessLogged = true;
				Plugin.Log.LogWarning((object)("Blocked vanilla Success at '" + ((Object)_extractionPoint).name + "' until the network clown nose is pressed with the quota filled."));
			}
			return false;
		}

		internal void BeforeVanillaUpdate()
		{
			TickExtractionSession();
		}

		internal void AfterVanillaUpdate()
		{
			TickExtractionSession();
		}

		internal void BeforeVanillaStateActive()
		{
			if (_initialized && SemiFunc.IsMasterClientOrSingleplayer() && IsCurrentActivePoint())
			{
				EnsureSessionStarted();
				if (_gateArmed)
				{
					ApplySubmissionGate();
				}
			}
		}

		private void TickExtractionSession()
		{
			if (!_initialized || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (!IsCurrentActivePoint())
			{
				if (_gateArmed || (Object)(object)_clownRoot != (Object)null || _submissionSent)
				{
					EndSession(_submissionSent ? "the extraction point left Active after submission" : "the extraction point left Active before submission");
				}
				return;
			}
			if (_submissionSent)
			{
				_extractionPoint.successDelay = 0f;
				return;
			}
			EnsureSessionStarted();
			if (_gateArmed)
			{
				if ((Object)(object)_clownRoot == (Object)null && Time.realtimeSinceStartup >= _nextSpawnAttemptAt && !TrySpawnClown())
				{
					_nextSpawnAttemptAt = Time.realtimeSinceStartup + 1f;
				}
				ApplySubmissionGate();
			}
		}

		private void LateUpdate()
		{
			if (_initialized && SemiFunc.IsMasterClientOrSingleplayer())
			{
				if (_pendingSuccess)
				{
					ProcessPendingSuccess();
				}
				else if (_replacementRequested)
				{
					ReplaceConsumedClown();
				}
				if (_gateArmed && IsCurrentActivePoint())
				{
					MaintainClownLock(forceNetworkCorrection: false);
				}
			}
		}

		private void FixedUpdate()
		{
			if (_initialized && _gateArmed && SemiFunc.IsMasterClientOrSingleplayer() && IsCurrentActivePoint())
			{
				MaintainClownLock(forceNetworkCorrection: false);
			}
		}

		private void OnDisable()
		{
			CleanupForTeardown();
		}

		private void OnDestroy()
		{
			CleanupForTeardown();
		}

		private void EnsureSessionStarted()
		{
			if (_gateArmed || _submissionSent || Time.realtimeSinceStartup < _nextSpawnAttemptAt)
			{
				return;
			}
			if (TrySpawnClown())
			{
				_gateArmed = true;
				_quotaPreviouslyReached = IsQuotaReached();
				_spawnFailureLogged = false;
				ApplySubmissionGate();
				Plugin.Log.LogInfo((object)("Extraction confirmation gate armed at '" + ((Object)_extractionPoint).name + "'. Automatic submission is held until the network clown nose is pressed."));
			}
			else
			{
				_nextSpawnAttemptAt = Time.realtimeSinceStartup + 1f;
				if (!_spawnFailureLogged)
				{
					_spawnFailureLogged = true;
					Plugin.Log.LogError((object)("Could not create the network clown at '" + ((Object)_extractionPoint).name + "'. Vanilla extraction remains available while the mod retries."));
				}
			}
		}

		private void ApplySubmissionGate()
		{
			if (!_gateArmed || _submissionSent)
			{
				return;
			}
			bool flag = IsQuotaReached();
			if (_pendingSuccess && !flag)
			{
				_pendingSuccess = false;
				_replacementRequested = true;
			}
			_extractionPoint.successDelay = 1.5f;
			if (flag != _quotaPreviouslyReached)
			{
				_quotaPreviouslyReached = flag;
				if (flag)
				{
					Plugin.Log.LogInfo((object)("Quota reached at '" + ((Object)_extractionPoint).name + "'. Automatic submission remains held until the clown nose is pressed."));
				}
				else
				{
					Plugin.Log.LogInfo((object)("Quota is no longer reached at '" + ((Object)_extractionPoint).name + "'."));
				}
			}
		}

		private void ProcessPendingSuccess()
		{
			_pendingSuccess = false;
			if (!_gateArmed || _submissionSent || !IsCurrentActivePoint() || !IsQuotaReached())
			{
				_replacementRequested = true;
				_proxyConsumed = true;
				PlayVanillaDeny(-1);
				return;
			}
			try
			{
				_allowSuccessCall = true;
				_submissionSent = true;
				_extractionPoint.successDelay = 0f;
				_extractionPoint.StateSet((State)3);
				Plugin.Log.LogInfo((object)("Clown confirmation submitted '" + ((Object)_extractionPoint).name + "' through vanilla " + $"StateSet(Success), haul={_extractionPoint.haulCurrent}/{_extractionPoint.haulGoal}."));
			}
			catch (Exception ex)
			{
				_submissionSent = false;
				_replacementRequested = true;
				Plugin.Log.LogError((object)("Vanilla StateSet(Success) failed with " + ex.GetType().Name + ": " + ex.Message + ". The extraction gate remains armed and a fresh clown will be spawned."));
				return;
			}
			finally
			{
				_allowSuccessCall = false;
			}
			_gateArmed = false;
			DestroyCurrentClown("vanilla extraction Success started");
		}

		private void ReplaceConsumedClown()
		{
			if (!_gateArmed || _submissionSent || !IsCurrentActivePoint())
			{
				_replacementRequested = false;
			}
			else if (!(Time.realtimeSinceStartup < _nextSpawnAttemptAt))
			{
				_replacementRequested = false;
				if (!DestroyCurrentClown("the nose was pressed"))
				{
					_replacementRequested = true;
					_nextSpawnAttemptAt = Time.realtimeSinceStartup + 0.2f;
				}
				else if (!TrySpawnClown())
				{
					_nextSpawnAttemptAt = Time.realtimeSinceStartup + 1f;
					Plugin.Log.LogError((object)"Fresh clown respawn failed. Submission remains held and the mod will retry.");
				}
			}
		}

		private bool TrySpawnClown()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_clownRoot != (Object)null)
			{
				return true;
			}
			if (!TryResolveClownPrefab(out string resourcePath, out GameObject prefab))
			{
				return false;
			}
			if (!TryPreparePlacementBasis(out PlacementBasis basis, out Vector3 provisionalPosition, out Quaternion desiredRotation, out string source))
			{
				LogDetailedSpawnFailure("Could not calculate a clown placement at '" + ((Object)_extractionPoint).name + "': " + source + ".");
				return false;
			}
			GameObject val = null;
			try
			{
				if (PhotonNetwork.InRoom)
				{
					if (!PhotonNetwork.IsMasterClient)
					{
						return false;
					}
					val = PhotonNetwork.InstantiateRoomObject(resourcePath, provisionalPosition, desiredRotation, (byte)0, (object[])null);
				}
				else
				{
					val = Object.Instantiate<GameObject>(prefab, provisionalPosition, desiredRotation);
				}
				ClownTrap componentInChildren = val.GetComponentInChildren<ClownTrap>(true);
				PhysGrabObject val2 = (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.physgrabobject != (Object)null) ? componentInChildren.physgrabobject : (((Object)(object)componentInChildren != (Object)null && (Object)(object)((Trap)componentInChildren).physGrabObject != (Object)null) ? ((Trap)componentInChildren).physGrabObject : val.GetComponentInChildren<PhysGrabObject>(true)));
				PhotonView val3 = (PhotonView)(((Object)(object)componentInChildren != (Object)null) ? ((object)GetClownPhotonView(componentInChildren)) : ((object)val.GetComponentInChildren<PhotonView>(true)));
				if ((Object)(object)componentInChildren == (Object)null || (Object)(object)val2 == (Object)null || (PhotonNetwork.InRoom && ((Object)(object)val3 == (Object)null || val3.ViewID == 0)))
				{
					DestroyUntrackedSpawn(val);
					LogDetailedSpawnFailure("Resolved prefab '" + resourcePath + "' did not create a usable ClownTrap + PhysGrabObject + PhotonView instance.");
					return false;
				}
				_clownRoot = val;
				_physGrabObject = val2;
				_rigidbody = (((Object)(object)val2.rb != (Object)null) ? val2.rb : val.GetComponentInChildren<Rigidbody>(true));
				_clownViewId = GetClownLookupId(componentInChildren);
				if (!TryCalculateFinalPose(basis, val, out _anchorPosition, out string source2))
				{
					DestroyUntrackedSpawn(val);
					ClearProxyReferences();
					LogDetailedSpawnFailure("No safe floor placement was found at '" + ((Object)_extractionPoint).name + "': " + source2 + ".");
					return false;
				}
				_anchorRotation = desiredRotation;
				val.transform.SetPositionAndRotation(_anchorPosition, _anchorRotation);
				ProxyOwners[_clownViewId] = this;
				_proxyConsumed = false;
				_replacementRequested = false;
				_nextSpawnAttemptAt = 0f;
				_nextNetworkCorrectionAt = 0f;
				_lastDetailedSpawnFailure = null;
				MaintainClownLock(forceNetworkCorrection: true);
				Plugin.Log.LogInfo((object)("Spawned network clown for '" + ((Object)_extractionPoint).name + "': resourcePath='" + resourcePath + "', prefab='" + ((Object)prefab).name + "', " + $"ViewID={_clownViewId}, position={FormatVector(_anchorPosition)}, " + "rotation=" + FormatQuaternion(_anchorRotation) + ", basis=" + source + ", final=" + source2 + ", visual=" + GetSpawnVisualSnapshot(val) + "."));
				return true;
			}
			catch (Exception ex)
			{
				if ((Object)(object)val != (Object)null)
				{
					DestroyUntrackedSpawn(val);
				}
				ClearProxyReferences();
				LogDetailedSpawnFailure("Network clown spawn failed with " + ex.GetType().Name + ": " + ex.Message + ".");
				return false;
			}
		}

		private bool TryResolveClownPrefab(out string resourcePath, out GameObject prefab)
		{
			if (!string.IsNullOrEmpty(_resolvedResourcePath) && (Object)(object)_resolvedPrefab != (Object)null && IsClownPrefab(_resolvedPrefab))
			{
				resourcePath = _resolvedResourcePath;
				prefab = _resolvedPrefab;
				return true;
			}
			ValuableDirector instance = ValuableDirector.instance;
			if ((Object)(object)instance != (Object)null && instance.mediumValuables != null)
			{
				foreach (PrefabRef mediumValuable in instance.mediumValuables)
				{
					if (mediumValuable == null)
					{
						continue;
					}
					try
					{
						GameObject prefab2 = ((PrefabRef<GameObject>)(object)mediumValuable).Prefab;
						if ((Object)(object)prefab2 != (Object)null && IsClownPrefab(prefab2) && !string.IsNullOrEmpty(((PrefabRef<GameObject>)(object)mediumValuable).ResourcePath))
						{
							return CacheResolvedPrefab(((PrefabRef<GameObject>)(object)mediumValuable).ResourcePath, prefab2, out resourcePath, out prefab);
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Inspecting a vanilla medium valuable PrefabRef failed with " + ex.GetType().Name + ": " + ex.Message + "."));
					}
				}
			}
			string[] clownResourcePathCandidates = ClownResourcePathCandidates;
			foreach (string text in clownResourcePathCandidates)
			{
				GameObject val = Resources.Load<GameObject>(text);
				if ((Object)(object)val != (Object)null && IsClownPrefab(val))
				{
					return CacheResolvedPrefab(text, val, out resourcePath, out prefab);
				}
			}
			GameObject[] array = Resources.LoadAll<GameObject>("valuables/03 medium");
			foreach (GameObject val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && IsClownPrefab(val2))
				{
					string text2 = "valuables/03 medium/" + ((Object)val2).name;
					GameObject val3 = Resources.Load<GameObject>(text2);
					if ((Object)(object)val3 != (Object)null && IsClownPrefab(val3))
					{
						return CacheResolvedPrefab(text2, val3, out resourcePath, out prefab);
					}
				}
			}
			resourcePath = string.Empty;
			prefab = null;
			LogDetailedSpawnFailure("The vanilla Valuable Clown prefab could not be found in Resources.");
			return false;
		}

		private bool CacheResolvedPrefab(string path, GameObject candidate, out string resourcePath, out GameObject prefab)
		{
			_resolvedResourcePath = path;
			_resolvedPrefab = candidate;
			resourcePath = path;
			prefab = candidate;
			Plugin.Log.LogInfo((object)("Resolved vanilla clown prefab: path='" + path + "', prefab='" + ((Object)candidate).name + "'."));
			return true;
		}

		private static bool IsClownPrefab(GameObject candidate)
		{
			return (Object)(object)candidate.GetComponentInChildren<ClownTrap>(true) != (Object)null;
		}

		private bool TryPreparePlacementBasis(out PlacementBasis basis, out Vector3 provisionalPosition, out Quaternion desiredRotation, out string source)
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			basis = default(PlacementBasis);
			provisionalPosition = Vector3.zero;
			desiredRotation = Quaternion.identity;
			source = string.Empty;
			Vector3 position = _platform.position;
			Vector3 val = _platform.up;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (!TryGetWorldCenter(_extractionPoint.extractionArea, out var center))
			{
				center = _platform.position + _platform.forward;
			}
			Vector3 val2 = (((Object)(object)_extractionPoint.ramp != (Object)null) ? _extractionPoint.ramp.position : (_platform.position - _platform.forward));
			Vector3 val3 = Vector3.ProjectOnPlane(center - val2, normalized);
			if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
			{
				val3 = Vector3.ProjectOnPlane(_platform.forward, normalized);
			}
			if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
			{
				source = "could not determine the direction from the ramp into the platform";
				return false;
			}
			((Vector3)(ref val3)).Normalize();
			val = Vector3.Cross(normalized, val3);
			Vector3 normalized2 = ((Vector3)(ref val)).normalized;
			Bounds val4 = CreateSyntheticStorageBounds(position, normalized2, normalized, val3, center, val2);
			float num = Vector3.Dot(val2 - position, normalized);
			float expectedFloor = ((Mathf.Abs(num) <= 1.25f) ? num : 0f);
			basis = new PlacementBasis(position, normalized2, normalized, val3, val4, expectedFloor);
			desiredRotation = Quaternion.LookRotation(-val3, normalized);
			float num2 = Mathf.Lerp(((Bounds)(ref val4)).min.x, ((Bounds)(ref val4)).max.x, 0.2f);
			float num3 = ((Bounds)(ref val4)).min.y + 0.5f;
			float num4 = ((Bounds)(ref val4)).min.z - 1f;
			provisionalPosition = position + normalized2 * num2 + normalized * num3 + val3 * num4;
			source = "storageBoundsSource='fixed ramp-relative footprint', storageBounds=" + FormatBounds(val4) + ", platformWorld=" + FormatVector(position) + ", rampWorld=" + FormatVector(val2) + ", areaWorld=" + FormatVector(center);
			return true;
		}

		private bool TryCalculateFinalPose(PlacementBasis basis, GameObject spawned, out Vector3 position, out string source)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0116: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			position = spawned.transform.position;
			source = string.Empty;
			if (!TryGetProxyOffsets(spawned, basis, out var offsets))
			{
				source = "could not calculate clown renderer/collider bounds";
				return false;
			}
			float expectedFloor = basis.ExpectedFloor;
			Bounds storageBounds = basis.StorageBounds;
			float item = ((Bounds)(ref storageBounds)).min.x - 0.18f - ((Bounds)(ref offsets)).max.x;
			storageBounds = basis.StorageBounds;
			float item2 = ((Bounds)(ref storageBounds)).max.x + 0.18f - ((Bounds)(ref offsets)).min.x;
			storageBounds = basis.StorageBounds;
			float item3 = ((Bounds)(ref storageBounds)).min.z - 0.18f - ((Bounds)(ref offsets)).max.z;
			storageBounds = basis.StorageBounds;
			float z = ((Bounds)(ref storageBounds)).min.z;
			storageBounds = basis.StorageBounds;
			float item4 = Mathf.Lerp(z, ((Bounds)(ref storageBounds)).max.z, 0.25f) - ((Bounds)(ref offsets)).center.z;
			storageBounds = basis.StorageBounds;
			float x = ((Bounds)(ref storageBounds)).min.x;
			storageBounds = basis.StorageBounds;
			float item5 = Mathf.Lerp(x, ((Bounds)(ref storageBounds)).max.x, 0.2f) - ((Bounds)(ref offsets)).center.x;
			storageBounds = basis.StorageBounds;
			float x2 = ((Bounds)(ref storageBounds)).min.x;
			storageBounds = basis.StorageBounds;
			float item6 = Mathf.Lerp(x2, ((Bounds)(ref storageBounds)).max.x, 0.8f) - ((Bounds)(ref offsets)).center.x;
			(string, float, float)[] array = new(string, float, float)[4]
			{
				("entrance left", item5, item3),
				("entrance right", item6, item3),
				("left side", item, item4),
				("right side", item2, item4)
			};
			(string, float, float)[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				var (text, num, num2) = array2[i];
				if (TryFindPlatformFloor(basis, num, num2, expectedFloor, spawned.transform, out float floor, out string floorSource))
				{
					float num3 = floor + 0.015f - ((Bounds)(ref offsets)).min.y;
					position = basis.Origin + basis.Right * num + basis.Up * num3 + basis.Into * num2;
					source = "candidate='" + text + "', proxyOffsets=" + FormatBounds(offsets) + ", " + $"floor='{floorSource}', floorOffset={floor - expectedFloor:0.###}";
					return true;
				}
			}
			source = "no upward-facing floor surface was found at the left, entrance, or right outside edge; proxyOffsets=" + FormatBounds(offsets);
			return false;
		}

		private bool TryGetProxyOffsets(GameObject spawned, PlacementBasis basis, out Bounds offsets)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			Bounds collectedOffsets = default(Bounds);
			bool initialized = false;
			Vector3 rootPosition = spawned.transform.position;
			Collider[] componentsInChildren = spawned.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !val.isTrigger)
				{
					ForEachBoundsCorner(val.bounds, delegate(Vector3 point)
					{
						//IL_0000: Unknown result type (might be due to invalid IL or missing references)
						//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_000c: Unknown result type (might be due to invalid IL or missing references)
						//IL_000f: Unknown result type (might be due to invalid IL or missing references)
						//IL_0016: Unknown result type (might be due to invalid IL or missing references)
						//IL_0020: Unknown result type (might be due to invalid IL or missing references)
						//IL_0027: 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_0038: 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)
						Vector3 val3 = point - rootPosition;
						Vector3 point2 = default(Vector3);
						((Vector3)(ref point2))..ctor(Vector3.Dot(val3, basis.Right), Vector3.Dot(val3, basis.Up), Vector3.Dot(val3, basis.Into));
						EncapsulatePoint(ref collectedOffsets, ref initialized, point2);
					});
				}
			}
			Renderer[] componentsInChildren2 = spawned.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null) && !(val2 is ParticleSystemRenderer) && !(val2 is TrailRenderer) && !(val2 is LineRenderer))
				{
					ForEachBoundsCorner(val2.bounds, delegate(Vector3 point)
					{
						//IL_0000: Unknown result type (might be due to invalid IL or missing references)
						//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_000c: Unknown result type (might be due to invalid IL or missing references)
						//IL_000f: Unknown result type (might be due to invalid IL or missing references)
						//IL_0016: Unknown result type (might be due to invalid IL or missing references)
						//IL_0020: Unknown result type (might be due to invalid IL or missing references)
						//IL_0027: 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_0038: 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)
						Vector3 val3 = point - rootPosition;
						Vector3 point2 = default(Vector3);
						((Vector3)(ref point2))..ctor(Vector3.Dot(val3, basis.Right), Vector3.Dot(val3, basis.Up), Vector3.Dot(val3, basis.Into));
						EncapsulatePoint(ref collectedOffsets, ref initialized, point2);
					});
				}
			}
			offsets = collectedOffsets;
			return initialized;
		}

		private bool TryFindPlatformFloor(PlacementBasis basis, float targetRight, float targetInto, float expectedFloor, Transform excludedRoot, out float floor, out string floorSource)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			floor = expectedFloor;
			floorSource = string.Empty;
			Vector3 val = basis.Origin + basis.Right * targetRight + basis.Into * targetInto + basis.Up * (expectedFloor + 3f);
			RaycastHit[] array = Physics.RaycastAll(val, -basis.Up, 8f, -1, (QueryTriggerInteraction)1);
			bool result = false;
			float num = float.MaxValue;
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val2 = array2[i];
				Collider collider = ((RaycastHit)(ref val2)).collider;
				if (!((Object)(object)collider == (Object)null) && !IsSameOrChildOf(((Component)collider).transform, excludedRoot) && !((Object)(object)((Component)collider).GetComponentInParent<PhysGrabObject>() != (Object)null) && !(Vector3.Dot(((RaycastHit)(ref val2)).normal, basis.Up) < 0.5f))
				{
					float num2 = Vector3.Dot(((RaycastHit)(ref val2)).point - basis.Origin, basis.Up);
					float num3 = Mathf.Abs(num2 - expectedFloor);
					if (!(num3 > 1.25f) && !(num3 >= num))
					{
						num = num3;
						floor = num2;
						floorSource = GetTransformPath(((Component)collider).transform);
						result = true;
					}
				}
			}
			return result;
		}

		private void MaintainClownLock(bool forceNetworkCorrection)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_clownRoot == (Object)null || (Object)(object)_physGrabObject == (Object)null)
			{
				return;
			}
			try
			{
				_physGrabObject.OverrideKinematic(0.25f);
				_physGrabObject.OverrideIndestructible(0.25f);
				if ((Object)(object)_rigidbody != (Object)null)
				{
					if (!_rigidbody.isKinematic)
					{
						_rigidbody.velocity = Vector3.zero;
						_rigidbody.angularVelocity = Vector3.zero;
					}
					_rigidbody.constraints = (RigidbodyConstraints)126;
					_rigidbody.isKinematic = true;
				}
				bool flag = Vector3.Distance(_clownRoot.transform.position, _anchorPosition) > 0.025f;
				bool flag2 = Quaternion.Angle(_clownRoot.transform.rotation, _anchorRotation) > 1f;
				if (forceNetworkCorrection || flag || flag2)
				{
					_clownRoot.transform.SetPositionAndRotation(_anchorPosition, _anchorRotation);
					if ((Object)(object)_rigidbody != (Object)null)
					{
						_rigidbody.position = _anchorPosition;
						_rigidbody.rotation = _anchorRotation;
					}
					if (PhotonNetwork.InRoom && (Object)(object)_physGrabObject.photonView != (Object)null && _physGrabObject.photonView.ViewID != 0 && (forceNetworkCorrection || Time.realtimeSinceStartup >= _nextNetworkCorrectionAt))
					{
						_nextNetworkCorrectionAt = Time.realtimeSinceStartup + 0.2f;
						_physGrabObject.photonView.RPC("SetPositionRPC", (RpcTarget)0, new object[2] { _anchorPosition, _anchorRotation });
					}
					else if (!PhotonNetwork.InRoom)
					{
						_physGrabObject.SetPositionLogic(_anchorPosition, _anchorRotation);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Maintaining the network clown lock failed with " + ex.GetType().Name + ": " + ex.Message + "."));
			}
		}

		private void PlayVanillaDeny(int playerActorNumber)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PhotonView photonView = _extractionPoint.photonView;
				if (PhotonNetwork.InRoom && (Object)(object)photonView != (Object)null && photonView.ViewID != 0)
				{
					photonView.RPC("ButtonDenyRPC", (RpcTarget)0, Array.Empty<object>());
				}
				else
				{
					_extractionPoint.ButtonDenyRPC(default(PhotonMessageInfo));
				}
				Plugin.Log.LogInfo((object)("Played vanilla ButtonDenyRPC for clown press by " + $"playerActor={playerActorNumber}."));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Vanilla ButtonDenyRPC failed with " + ex.GetType().Name + ": " + ex.Message + ". The extraction remains gated."));
			}
		}

		private bool DestroyCurrentClown(string reason)
		{
			GameObject clownRoot = _clownRoot;
			int clownViewId = _clownViewId;
			if ((Object)(object)clownRoot == (Object)null)
			{
				if (clownViewId != 0)
				{
					ProxyOwners.Remove(clownViewId);
				}
				ClearProxyReferences();
				return true;
			}
			try
			{
				if (PhotonNetwork.InRoom)
				{
					PhotonNetwork.Destroy(clownRoot);
				}
				else
				{
					Object.Destroy((Object)(object)clownRoot);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)($"Destroying clown ViewID={clownViewId} failed with " + ex.GetType().Name + ": " + ex.Message + "."));
				return false;
			}
			ProxyOwners.Remove(clownViewId);
			ClearProxyReferences();
			Plugin.Log.LogInfo((object)$"Removed network clown ViewID={clownViewId} because {reason}.");
			return true;
		}

		private void DestroyUntrackedSpawn(GameObject spawned)
		{
			try
			{
				if (PhotonNetwork.InRoom)
				{
					PhotonNetwork.Destroy(spawned);
				}
				else
				{
					Object.Destroy((Object)(object)spawned);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Cleaning up an unusable clown spawn failed with " + ex.GetType().Name + ": " + ex.Message + "."));
			}
		}

		private void EndSession(string reason)
		{
			bool flag = _gateArmed || (Object)(object)_clownRoot != (Object)null || _submissionSent;
			_gateArmed = false;
			_replacementRequested = false;
			_pendingSuccess = false;
			_allowSuccessCall = false;
			_submissionSent = false;
			_blockedSuccessLogged = false;
			DestroyCurrentClown(reason);
			if (flag)
			{
				Plugin.Log.LogInfo((object)("Network-clown extraction session ended because " + reason + "."));
			}
		}

		private void CleanupForTeardown()
		{
			if (_initialized)
			{
				EndSession("the extraction controller was destroyed");
				_initialized = false;
			}
		}

		private void ClearProxyReferences()
		{
			_clownRoot = null;
			_physGrabObject = null;
			_rigidbody = null;
			_clownViewId = 0;
			_proxyConsumed = false;
		}

		private bool IsCurrentActivePoint()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((int)_extractionPoint.currentState == 2 && (Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.extractionPointActive)
			{
				return (Object)(object)RoundDirector.instance.extractionPointCurrent == (Object)(object)_extractionPoint;
			}
			return false;
		}

		private bool IsQuotaReached()
		{
			if (_extractionPoint.haulGoalFetched && _extractionPoint.haulGoal > 0)
			{
				return _extractionPoint.haulCurrent >= _extractionPoint.haulGoal;
			}
			return false;
		}

		private static PhotonView? GetClownPhotonView(ClownTrap clown)
		{
			if ((Object)(object)((Trap)clown).photonView != (Object)null)
			{
				return ((Trap)clown).photonView;
			}
			if ((Object)(object)clown.physgrabobject != (Object)null && (Object)(object)clown.physgrabobject.photonView != (Object)null)
			{
				return clown.physgrabobject.photonView;
			}
			if ((Object)(object)((Trap)clown).physGrabObject != (Object)null && (Object)(object)((Trap)clown).physGrabObject.photonView != (Object)null)
			{
				return ((Trap)clown).physGrabObject.photonView;
			}
			return ((Component)clown).GetComponentInParent<PhotonView>();
		}

		private static int GetClownLookupId(ClownTrap clown)
		{
			PhotonView clownPhotonView = GetClownPhotonView(clown);
			if (!((Object)(object)clownPhotonView != (Object)null) || clownPhotonView.ViewID == 0)
			{
				return ((Object)clown).GetInstanceID();
			}
			return clownPhotonView.ViewID;
		}

		private static bool TryGetWorldCenter(GameObject? source, out Vector3 center)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			center = Vector3.zero;
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			Collider[] componentsInChildren = source.GetComponentsInChildren<Collider>(true);
			if (componentsInChildren.Length == 0)
			{
				center = source.transform.position;
				return true;
			}
			Bounds bounds = componentsInChildren[0].bounds;
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
			}
			center = ((Bounds)(ref bounds)).center;
			return true;
		}

		private static bool TryGetObjectBoundsInBasis(GameObject? source, Vector3 origin, Vector3 right, Vector3 up, Vector3 into, bool includeTriggers, Transform? excludedRoot, out Bounds result)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008d: Unknown result type (might be due to invalid IL or missing references)
			Bounds collectedBounds = default(Bounds);
			if ((Object)(object)source == (Object)null)
			{
				result = collectedBounds;
				return false;
			}
			bool initialized = false;
			Collider[] componentsInChildren = source.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && (includeTriggers || !val.isTrigger) && (!((Object)(object)excludedRoot != (Object)null) || !IsSameOrChildOf(((Component)val).transform, excludedRoot)))
				{
					ForEachBoundsCorner(val.bounds, delegate(Vector3 worldPoint)
					{
						//IL_0000: Unknown result type (might be due to invalid IL or missing references)
						//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_000c: Unknown result type (might be due to invalid IL or missing references)
						//IL_000f: Unknown result type (might be due to invalid IL or missing references)
						//IL_0011: Unknown result type (might be due to invalid IL or missing references)
						//IL_001b: Unknown result type (might be due to invalid IL or missing references)
						//IL_001d: Unknown result type (might be due to invalid IL or missing references)
						//IL_0027: Unknown result type (might be due to invalid IL or missing references)
						//IL_0029: Unknown result type (might be due to invalid IL or missing references)
						//IL_0044: Unknown result type (might be due to invalid IL or missing references)
						Vector3 val2 = worldPoint - origin;
						Vector3 point = default(Vector3);
						((Vector3)(ref point))..ctor(Vector3.Dot(val2, right), Vector3.Dot(val2, up), Vector3.Dot(val2, into));
						EncapsulatePoint(ref collectedBounds, ref initialized, point);
					});
				}
			}
			result = collectedBounds;
			return initialized;
		}

		private static bool TryGetBoxCheckerBoundsInBasis(GameObject? source, Vector3 origin, Vector3 right, Vector3 up, Vector3 into, out Bounds result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = default(Bounds);
			bool initialized = false;
			if ((Object)(object)source != (Object)null)
			{
				PhysGrabObjectComponentInsideBoxChecker[] componentsInChildren = source.GetComponentsInChildren<PhysGrabObjectComponentInsideBoxChecker>(true);
				foreach (PhysGrabObjectComponentInsideBoxChecker val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						EncapsulateUnitBoxTransform(((Component)val).transform, origin, right, up, into, ref bounds, ref initialized);
					}
				}
			}
			result = bounds;
			return initialized;
		}

		private static bool TryGetUnitBoxTransformBoundsInBasis(Transform? source, Vector3 origin, Vector3 right, Vector3 up, Vector3 into, out Bounds result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Bounds bounds = default(Bounds);
			bool initialized = false;
			if ((Object)(object)source != (Object)null)
			{
				EncapsulateUnitBoxTransform(source, origin, right, up, into, ref bounds, ref initialized);
			}
			result = bounds;
			return initialized;
		}

		private static bool TryGetRendererBoundsInBasis(GameObject? source, Vector3 origin, Vector3 right, Vector3 up, Vector3 into, out Bounds result)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Bounds collectedBounds = default(Bounds);
			bool initialized = false;
			if ((Object)(object)source != (Object)null)
			{
				Renderer[] componentsInChildren = source.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null) && !(val is ParticleSystemRenderer) && !(val is TrailRenderer) && !(val is LineRenderer))
					{
						ForEachBoundsCorner(val.bounds, delegate(Vector3 worldPoint)
						{
							//IL_0000: Unknown result type (might be due to invalid IL or missing references)
							//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_000c: Unknown result type (might be due to invalid IL or missing references)
							//IL_000f: Unknown result type (might be due to invalid IL or missing references)
							//IL_0011: Unknown result type (might be due to invalid IL or missing references)
							//IL_001b: Unknown result type (might be due to invalid IL or missing references)
							//IL_001d: Unknown result type (might be due to invalid IL or missing references)
							//IL_0027: Unknown result type (might be due to invalid IL or missing references)
							//IL_0029: Unknown result type (might be due to invalid IL or missing references)
							//IL_0044: Unknown result type (might be due to invalid IL or missing references)
							Vector3 val2 = worldPoint - origin;
							Vector3 point = default(Vector3);
							((Vector3)(ref point))..ctor(Vector3.Dot(val2, right), Vector3.Dot(val2, up), Vector3.Dot(val2, into));
							EncapsulatePoint(ref collectedBounds, ref initialized, point);
						});
					}
				}
			}
			result = collectedBounds;
			return initialized;
		}

		private static void EncapsulateUnitBoxTransform(Transform boxTransform, Vector3 origin, Vector3 right, Vector3 up, Vector3 into, ref Bounds bounds, ref bool initialized)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			Vector3 point = default(Vector3);
			for (int i = 0; i <= 1; i++)
			{
				for (int j = 0; j <= 1; j++)
				{
					for (int k = 0; k <= 1; k++)
					{
						((Vector3)(ref val))..ctor((i == 0) ? (-0.5f) : 0.5f, (j == 0) ? (-0.5f) : 0.5f, (k == 0) ? (-0.5f) : 0.5f);
						Vector3 val2 = boxTransform.TransformPoint(val) - origin;
						((Vector3)(ref point))..ctor(Vector3.Dot(val2, right), Vector3.Dot(val2, up), Vector3.Dot(val2, into));
						EncapsulatePoint(ref bounds, ref initialized, point);
					}
				}
			}
		}

		private static Bounds CreateSyntheticStorageBounds(Vector3 origin, Vector3 right, Vector3 up, Vector3 into, Vector3 areaCenterWorld, Vector3 rampWorld)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = areaCenterWorld - origin;
			Vector3 val2 = rampWorld - origin;
			float num = Vector3.Dot(val, into);
			float num2 = Vector3.Dot(val2, right);
			float num3 = Vector3.Dot(val2, into);
			float num4 = Vector3.Dot(val2, up);
			float num5 = Mathf.Clamp(Mathf.Abs(num - num3), 1.5f, 3f);
			float num6 = Mathf.Clamp(num5 * 1.1f, 2f, 2.5f);
			float num7 = ((Mathf.Abs(num4) <= 1.25f) ? num4 : 0f);
			return new Bounds(new Vector3(num2, num7 + 0.5f, num3 + num5), new Vector3(num6 * 2f, 1f, num5 * 2f));
		}

		private static bool IsUsableStorageBounds(Bounds bounds)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (!float.IsNaN(size.x) && !float.IsInfinity(size.x) && !float.IsNaN(size.z) && !float.IsInfinity(size.z) && size.x >= 0.25f)
			{
				return size.z >= 0.25f;
			}
			return false;
		}

		private static bool IsPlausibleMarkerBounds(Bounds bounds)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (IsUsableStorageBounds(bounds) && ((Bounds)(ref bounds)).size.x >= 1.5f)
			{
				return ((Bounds)(ref bounds)).size.z >= 1.5f;
			}
			return false;
		}

		private static void ForEachBoundsCorner(Bounds bounds, Action<Vector3> visitor)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_003a: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector3 min = ((Bounds)(ref bounds)).min;
			Vector3 max = ((Bounds)(ref bounds)).max;
			for (int i = 0; i <= 1; i++)
			{
				for (int j = 0; j <= 1; j++)
				{
					for (int k = 0; k <= 1; k++)
					{
						visitor(new Vector3((i == 0) ? min.x : max.x, (j == 0) ? min.y : max.y, (k == 0) ? min.z : max.z));
					}
				}
			}
		}

		private static void EncapsulatePoint(ref Bounds bounds, ref bool initialized, Vector3 point)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized)
			{
				bounds = new Bounds(point, Vector3.zero);
				initialized = true;
			}
			else
			{
				((Bounds)(ref bounds)).Encapsulate(point);
			}
		}

		private static bool IsSameOrChildOf(Transform candidate, Transform? root)
		{
			if ((Object)(object)root != (Object)null)
			{
				if (!((Object)(object)candidate == (Object)(object)root))
				{
					return candidate.IsChildOf(root);
				}
				return true;
			}
			return false;
		}

		private static string GetTransformPath(Transform transform)
		{
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent.parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private void LogDetailedSpawnFailure(string message)
		{
			if (!string.Equals(_lastDetailedSpawnFailure, message, StringComparison.Ordinal))
			{
				_lastDetailedSpawnFailure = message;
				Plugin.Log.LogError((object)message);
			}
		}

		private string GetSpawnVisualSnapshot(GameObject spawned)
		{
			//IL_0008: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			bool flag = false;
			Bounds bounds = default(Bounds);
			Renderer[] componentsInChildren = spawned.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !(val is ParticleSystemRenderer) && !(val is TrailRenderer) && !(val is LineRenderer))
				{
					num++;
					if (val.enabled && ((Component)val).gameObject.activeInHierarchy)
					{
						num2++;
					}
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			return $"rootActive={spawned.activeInHierarchy}, " + $"renderers={num2}/{num}, " + "rendererBounds=" + (flag ? FormatBounds(bounds) : "<none>") + ", rigidbodyPosition=" + (((Object)(object)_rigidbody != (Object)null) ? FormatVector(_rigidbody.position) : "<none>");
		}

		private static string FormatVector(Vector3 value)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({value.x:0.###}, {value.y:0.###}, {value.z:0.###})";
		}

		private static string FormatQuaternion(Quaternion value)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return $"({value.x:0.###}, {value.y:0.###}, " + $"{value.z:0.###}, {value.w:0.###})";
		}

		private static string FormatBounds(Bounds bounds)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return "center=" + FormatVector(((Bounds)(ref bounds)).center) + ", size=" + FormatVector(((Bounds)(ref bounds)).size);
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint))]
	internal static class ExtractionPointPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void StartPostfix(ExtractionPoint __instance)
		{
			Plugin.Log.LogInfo((object)("Saw extraction point '" + ((Object)__instance).name + "' during Start: " + $"isShop={__instance.isShop}, runIsLevel={SemiFunc.RunIsLevel()}, " + $"host={SemiFunc.IsMasterClientOrSingleplayer()}."));
			TryAttach(__instance);
		}

		private static ExtractionClownController? TryAttach(ExtractionPoint extractionPoint)
		{
			if (extractionPoint.isShop)
			{
				return null;
			}
			ExtractionClownController component = ((Component)extractionPoint).GetComponent<ExtractionClownController>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			ExtractionClownController extractionClownController = ((Component)extractionPoint).gameObject.AddComponent<ExtractionClownController>();
			extractionClownController.Initialize(extractionPoint);
			return extractionClownController;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static void UpdatePrefix(ExtractionPoint __instance)
		{
			TryAttach(__instance)?.BeforeVanillaUpdate();
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdatePostfix(ExtractionPoint __instance)
		{
			TryAttach(__instance)?.AfterVanillaUpdate();
		}

		[HarmonyPrefix]
		[HarmonyPatch("StateActive")]
		private static void StateActivePrefix(ExtractionPoint __instance)
		{
			TryAttach(__instance)?.BeforeVanillaStateActive();
		}

		[HarmonyPrefix]
		[HarmonyPatch("StateSet")]
		private static bool StateSetPrefix(ExtractionPoint __instance, State __0)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			ExtractionClownController extractionClownController = TryAttach(__instance);
			if (!((Object)(object)extractionClownController == (Object)null))
			{
				return extractionClownController.AllowVanillaStateSet(__0);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ClownTrap), "TouchNoseRPC")]
	internal static class ClownTrapTouchNoseRpcPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ClownTrap __instance, ref PhotonMessageInfo __0)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				ExtractionClownController extractionClownController = ExtractionClownController.FindOwner(__instance);
				if (!((Object)(object)extractionClownController == (Object)null) && extractionClownController.OwnsClown(__instance))
				{
					int playerActorNumber = ((__0.Sender != null) ? __0.Sender.ActorNumber : (-1));
					extractionClownController.OnNosePressed(__instance, playerActorNumber);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ClownTrap), "TrapStop")]
	internal static class ClownTrapStopPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ClownTrap __instance)
		{
			ExtractionClownController extractionClownController = ExtractionClownController.FindOwner(__instance);
			if ((Object)(object)extractionClownController == (Object)null || !extractionClownController.ShouldSuppressExplosion(__instance))
			{
				return true;
			}
			Plugin.Log.LogWarning((object)("Suppressed vanilla explosion for extraction clown '" + ((Object)__instance).name + "'."));
			return false;
		}
	}
	[BepInPlugin("DJDarkLucky.AddExtractionButton", "Add Extraction Button", "0.1.0")]
	[BepInProcess("REPO.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "DJDarkLucky.AddExtractionButton";

		public const string PluginName = "Add Extraction Button";

		public const string PluginVersion = "0.1.0";

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)("Add Extraction Button v0.1.0 loading from '" + typeof(Plugin).Assembly.Location + "'. " + $"MVID={typeof(Plugin).Assembly.ManifestModule.ModuleVersionId}."));
			Harmony val = new Harmony("DJDarkLucky.AddExtractionButton");
			try
			{
				val.PatchAll(typeof(Plugin).Assembly);
				MethodBase[] array = val.GetPatchedMethods().ToArray();
				string text = ((array.Length == 0) ? "none" : string.Join(", ", array.Select((MethodBase method) => method.DeclaringType?.Name + "." + method.Name)));
				Log.LogInfo((object)($"Harmony registered {array.Length} patched original method(s): " + text + "."));
			}
			catch (Exception arg)
			{
				Log.LogError((object)("Harmony patching failed. Clown confirmation cannot work until the patches load. " + $"{arg}"));
			}
			Log.LogInfo((object)"Add Extraction Button v0.1.0 loaded. Waiting for active level extraction points.");
		}
	}
}