Decompiled source of DropperFix v1.1.12

plugins/com.github.Arof2.Beast_Mode.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 PEAKLib.Core;
using PEAKLib.Items;
using Photon.Pun;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.Arof2.Beast_Mode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+c78cc2c6e2e5c74e115f58a7282d2dbd82c59564")]
[assembly: AssemblyProduct("com.github.Arof2.Beast_Mode")]
[assembly: AssemblyTitle("Dropper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Dropper
{
	public class AddItemInNetwork : MonoBehaviourPun
	{
		private PhotonView photonView;

		private void Awake()
		{
			photonView = ((Component)this).GetComponent<PhotonView>();
		}

		public void AddItemIntoInventory(int itemID, int photonID)
		{
			photonView.RPC("AddItemIntoInventoryRPC", (RpcTarget)2, new object[2] { itemID, photonID });
			Plugin.Log.LogInfo((object)$"Client requesting item id: {itemID} to player with photonID: {photonID}");
		}

		[PunRPC]
		public void AddItemIntoInventoryRPC(int itemID, int photonID)
		{
			ItemSlot val = default(ItemSlot);
			((Component)PhotonNetwork.GetPhotonView(photonID)).GetComponent<Character>().player.AddItem((ushort)itemID, (ItemInstanceData)null, ref val);
			Plugin.Log.LogInfo((object)$"Host giving player {photonID} the item {(ushort)itemID}");
		}
	}
	public class InteractableBackPorter : MonoBehaviourPun, IInteractibleConstant, IInteractible
	{
		public Action<Character> Interacted;

		private MaterialPropertyBlock mpb;

		private MeshRenderer[] _mr;

		public float interactTime => 2f;

		public bool holdOnFinish
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		private MeshRenderer[] meshRenderers
		{
			get
			{
				if (_mr == null)
				{
					_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
					MonoBehaviour.print((object)_mr.Length);
				}
				return _mr;
			}
			set
			{
				_mr = value;
			}
		}

		public void CancelCast(Character interactor)
		{
		}

		public void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			mpb = new MaterialPropertyBlock();
		}

		public Vector3 Center()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position;
		}

		public string GetInteractionText()
		{
			return "Teleport To Last Area";
		}

		public float GetInteractTime(Character interactor)
		{
			return interactTime;
		}

		public string GetName()
		{
			return "Reverse Teleporter";
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public void HoverEnter()
		{
			if (mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				if ((Object)(object)meshRenderers[i] != (Object)null)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void HoverExit()
		{
			if (mpb != null)
			{
				mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
				for (int i = 0; i < meshRenderers.Length; i++)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void Interact(Character interactor)
		{
		}

		public void Interact_CastFinished(Character interactor)
		{
			Interacted?.Invoke(interactor);
		}

		public bool IsConstantlyInteractable(Character interactor)
		{
			return IsInteractible(interactor);
		}

		public bool IsInteractible(Character interactor)
		{
			return true;
		}

		public void ReleaseInteract(Character interactor)
		{
		}
	}
	public class InteractableBrewingStand : MonoBehaviourPun, IInteractibleConstant, IInteractible
	{
		private bool ineracted;

		public Action<Character> Interacted;

		private MaterialPropertyBlock mpb;

		private MeshRenderer[] _mr;

		public float interactTime => 0.5f;

		public bool holdOnFinish
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		private MeshRenderer[] meshRenderers
		{
			get
			{
				if (_mr == null)
				{
					_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
					MonoBehaviour.print((object)_mr.Length);
				}
				return _mr;
			}
			set
			{
				_mr = value;
			}
		}

		public void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			mpb = new MaterialPropertyBlock();
		}

		public void CancelCast(Character interactor)
		{
		}

		public Vector3 Center()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position;
		}

		public string GetInteractionText()
		{
			return "Take Potion";
		}

		public float GetInteractTime(Character interactor)
		{
			return interactTime;
		}

		public string GetName()
		{
			return "Brewing stand";
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public void HoverEnter()
		{
			if (ineracted || mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				if ((Object)(object)meshRenderers[i] != (Object)null)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void HoverExit()
		{
			if (mpb != null)
			{
				mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
				for (int i = 0; i < meshRenderers.Length; i++)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void Interact(Character interactor)
		{
		}

		public void Interact_CastFinished(Character interactor)
		{
			if (!ineracted)
			{
				((Component)this).gameObject.layer = 2;
				((Component)((Component)this).transform.GetChild(0)).gameObject.SetActive(false);
				((Component)((Component)this).transform.GetChild(1)).gameObject.SetActive(true);
				HarmonyPatches.SetupMaterial(((Component)((Component)this).transform.GetChild(1)).gameObject);
				ineracted = true;
				Interacted?.Invoke(interactor);
			}
		}

		public bool IsConstantlyInteractable(Character interactor)
		{
			return IsInteractible(interactor);
		}

		public bool IsInteractible(Character interactor)
		{
			return true;
		}

		public void ReleaseInteract(Character interactor)
		{
		}
	}
	public class InteratableFinisher : MonoBehaviourPun, IInteractibleConstant, IInteractible
	{
		public Action<Character> Interacted;

		private MaterialPropertyBlock mpb;

		private MeshRenderer[] _mr;

		public float interactTime => 2f;

		public bool holdOnFinish
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		private MeshRenderer[] meshRenderers
		{
			get
			{
				if (_mr == null)
				{
					_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
					MonoBehaviour.print((object)_mr.Length);
				}
				return _mr;
			}
			set
			{
				_mr = value;
			}
		}

		public void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			mpb = new MaterialPropertyBlock();
		}

		public void CancelCast(Character interactor)
		{
		}

		public Vector3 Center()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position;
		}

		public string GetInteractionText()
		{
			Plugin.Log.LogDebug((object)$"Current Spawn point Index: {HarmonyPatches.CurrentSpawnPointIndex} | Max index: {HarmonyPatches.MaxSpawnPointIndex}");
			if (HarmonyPatches.CurrentSpawnPointIndex == HarmonyPatches.MaxSpawnPointIndex)
			{
				return "Finish the game for all players";
			}
			return "Breaking out of the map doesn't allow you to finish early";
		}

		public float GetInteractTime(Character interactor)
		{
			return interactTime;
		}

		public string GetName()
		{
			return "Goal";
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public void HoverEnter()
		{
			if (mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				if ((Object)(object)meshRenderers[i] != (Object)null)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void HoverExit()
		{
			if (mpb != null)
			{
				mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
				for (int i = 0; i < meshRenderers.Length; i++)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void Interact(Character interactor)
		{
		}

		public void Interact_CastFinished(Character interactor)
		{
			if (HarmonyPatches.CurrentSpawnPointIndex == HarmonyPatches.MaxSpawnPointIndex)
			{
				Interacted?.Invoke(interactor);
			}
		}

		public bool IsConstantlyInteractable(Character interactor)
		{
			return IsInteractible(interactor);
		}

		public bool IsInteractible(Character interactor)
		{
			return true;
		}

		public void ReleaseInteract(Character interactor)
		{
		}
	}
	public class InteratableTeleporter : MonoBehaviourPun, IInteractibleConstant, IInteractible
	{
		public Action<Character> Interacted;

		private MaterialPropertyBlock mpb;

		private MeshRenderer[] _mr;

		public float interactTime => 2f;

		public bool holdOnFinish
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		private MeshRenderer[] meshRenderers
		{
			get
			{
				if (_mr == null)
				{
					_mr = ((Component)this).GetComponentsInChildren<MeshRenderer>();
					MonoBehaviour.print((object)_mr.Length);
				}
				return _mr;
			}
			set
			{
				_mr = value;
			}
		}

		public void CancelCast(Character interactor)
		{
		}

		public void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			mpb = new MaterialPropertyBlock();
		}

		public Vector3 Center()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position;
		}

		public string GetInteractionText()
		{
			return "Teleport To Next Area";
		}

		public float GetInteractTime(Character interactor)
		{
			return interactTime;
		}

		public string GetName()
		{
			return "Teleporter";
		}

		public Transform GetTransform()
		{
			return ((Component)this).transform;
		}

		public void HoverEnter()
		{
			if (mpb == null)
			{
				return;
			}
			mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 1f);
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				if ((Object)(object)meshRenderers[i] != (Object)null)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void HoverExit()
		{
			if (mpb != null)
			{
				mpb.SetFloat(Item.PROPERTY_INTERACTABLE, 0f);
				for (int i = 0; i < meshRenderers.Length; i++)
				{
					((Renderer)meshRenderers[i]).SetPropertyBlock(mpb);
				}
			}
		}

		public void Interact(Character interactor)
		{
		}

		public void Interact_CastFinished(Character interactor)
		{
			Interacted?.Invoke(interactor);
		}

		public bool IsConstantlyInteractable(Character interactor)
		{
			return IsInteractible(interactor);
		}

		public bool IsInteractible(Character interactor)
		{
			return true;
		}

		public void ReleaseInteract(Character interactor)
		{
		}
	}
	public class LoadCorrectDropper : MonoBehaviourPun
	{
		[PunRPC]
		public void LoadDropper(int ascentIndex)
		{
			switch (ascentIndex)
			{
			default:
				Plugin.ToggleModpack(-1);
				break;
			case -101:
				Plugin.ToggleModpack(0);
				break;
			case -102:
				Plugin.ToggleModpack(1);
				break;
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.github.Beast.Dropper", "Dropper", "1.1.3")]
	public class Plugin : BaseUnityPlugin
	{
		public static Action<int> ToggleModpack;

		public static bool alreadyPatched;

		public static bool PlayingDropperMap;

		public static Item ResetBerryItem;

		public static Item HealthPotion;

		internal static ManualLogSource Log { get; private set; }

		public static AssetBundle Bundle { get; private set; }

		internal static ModDefinition Definition { get; set; }

		public static string PluginName => "Dropper";

		public static Version PLuginVersion => new Version(1, 1, 3);

		public static string PLuginID => "com.github.Beast.Dropper";

		private void Awake()
		{
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			LoadBundle();
			ToggleModpack = delegate(int mode)
			{
				Log.LogInfo((object)$"Setting up Modpack with mode {mode}");
				switch (mode)
				{
				case 0:
					PlayingDropperMap = true;
					HarmonyPatches.Mode = HarmonyPatches.GameMode.Dropper;
					if (!alreadyPatched)
					{
						alreadyPatched = true;
						Harmony.CreateAndPatchAll(typeof(HarmonyPatches), "com.github.Beast.Dropper.runtime");
					}
					break;
				case 1:
					PlayingDropperMap = true;
					HarmonyPatches.Mode = HarmonyPatches.GameMode.Descend;
					if (!alreadyPatched)
					{
						Harmony.CreateAndPatchAll(typeof(HarmonyPatches), "com.github.Beast.Dropper.runtime");
						alreadyPatched = true;
					}
					break;
				default:
					PlayingDropperMap = false;
					alreadyPatched = false;
					Harmony.UnpatchID("com.github.Beast.Dropper.runtime");
					break;
				}
			};
			Log.LogInfo((object)"Adding Localisation");
			LocalizedText.mainTable.Add("Name_Reset".ToUpperInvariant(), GetLocalisationOf("Resetter"));
			LocalizedText.mainTable.Add("Force reset on #targetchar".ToUpperInvariant(), GetLocalisationOf("force reset #targetchar"));
			LocalizedText.mainTable.Add("Name_Instant Health I".ToUpperInvariant(), GetLocalisationOf("Instant Health I"));
			LocalizedText.mainTable.Add("administer #targetchar".ToUpperInvariant(), GetLocalisationOf("administer #targetchar"));
			LocalizedText.mainTable.Add("Dropper".ToUpperInvariant(), GetLocalisationOf("Dropper"));
			LocalizedText.mainTable.Add("Immense dread".ToUpperInvariant(), GetLocalisationOf("Immense dread"));
			LocalizedText.mainTable.Add("Desc_Dropper".ToUpperInvariant(), GetLocalisationOf("Does falling from 50 meters and crushing all your bones hurt? YES! But the adrenaline keeps you alive and ready to hit the portal next time!"));
			LocalizedText.mainTable.Add("Dropper - Descend".ToUpperInvariant(), GetLocalisationOf("Dropper - Descent"));
			LocalizedText.mainTable.Add("Desc_Dropper - Descend".ToUpperInvariant(), GetLocalisationOf("Instead of doing it all in one jump, how about we mix it up with some parkour to climb down. Why would you do that? Well let's finish the first map an you will see why"));
			Log.LogInfo((object)"Applying MandatoryHarmonyPatches");
			Harmony.CreateAndPatchAll(typeof(MandatoryHarmonyPatches), (string)null);
			Log.LogInfo((object)"Done Applying MandatoryHarmonyPatches");
			Definition = ModDefinition.GetOrCreate(PLuginID, PluginName, PLuginVersion);
			Log.LogInfo((object)"Adding Custom Items via PeakLibItems");
			ResetBerryItem = Bundle.LoadAsset<GameObject>("ResetBerry").GetComponent<Item>();
			new ItemContent(ResetBerryItem).Register(Definition);
			HealthPotion = Bundle.LoadAsset<GameObject>("Health potion").GetComponent<Item>();
			new ItemContent(HealthPotion).Register(Definition);
			Log.LogInfo((object)"Plugin Dropper is loaded!");
		}

		private List<string> GetLocalisationOf(string input)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < 15; i++)
			{
				list.Add(input);
			}
			return list;
		}

		private void LoadBundle()
		{
			Log.LogInfo((object)"Loading AssetBundle...");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string path = "dropper_assets";
			string text = Path.Combine(directoryName, path);
			if (File.Exists(text))
			{
				Log.LogInfo((object)"Found AssetBundle");
				Bundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)Bundle == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load AssetBundle!");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"AssetBundle loaded successfully!");
				}
			}
			else
			{
				Log.LogError((object)("AssetBundle not found at " + text));
			}
		}
	}
	internal class HarmonyPatches
	{
		public enum GameMode
		{
			Dropper,
			Descend
		}

		[CompilerGenerated]
		private sealed class <<UnPassOut>g__Wait3s|14_0>d : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

			[DebuggerHidden]
			public <<UnPassOut>g__Wait3s|14_0>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					gainFullControlOfCharacter = true;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					gainFullControlOfCharacter = false;
					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 <>c__DisplayClass12_0
		{
			public int localindex;

			public TriggerTeleporter component;

			internal void <DelayedActivation>b__0(Character character)
			{
				//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass12_1 CS$<>8__locals0 = new <>c__DisplayClass12_1
				{
					character = character
				};
				if (CS$<>8__locals0.character.IsLocal)
				{
					Character character2 = CS$<>8__locals0.character;
					Vector3 val = spawnPoints[localindex + 1].position - Vector3.up;
					PhotonMessageInfo val2 = default(PhotonMessageInfo);
					PhotonMessageInfo val3 = default(PhotonMessageInfo);
					PhotonMessageInfo val4 = default(PhotonMessageInfo);
					PhotonMessageInfo val5 = default(PhotonMessageInfo);
					PhotonMessageInfo val6 = default(PhotonMessageInfo);
					PhotonMessageInfo val7 = default(PhotonMessageInfo);
					PhotonMessageInfo val8 = default(PhotonMessageInfo);
					PhotonMessageInfo val9 = default(PhotonMessageInfo);
					character2.WarpPlayerRPC(val, true);
					Plugin.Log.LogInfo((object)$"Teleported {((Object)CS$<>8__locals0.character).name} to Spawn Point {localindex + 1} from Teleporter {((Object)((Component)component).gameObject).name}");
					CurrentSpawnPointIndex = localindex + 1;
					((MonoBehaviour)CS$<>8__locals0.character).StartCoroutine(FixPassout());
				}
				[IteratorStateMachine(typeof(<>c__DisplayClass12_1.<<DelayedActivation>g__FixPassout|1>d))]
				IEnumerator FixPassout()
				{
					//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
					return new <>c__DisplayClass12_1.<<DelayedActivation>g__FixPassout|1>d(0)
					{
						<>4__this = CS$<>8__locals0
					};
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass12_1
		{
			public Character character;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass12_2
		{
			public int localindex;

			public InteratableTeleporter component;

			internal void <DelayedActivation>b__2(Character character)
			{
				//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass12_3 CS$<>8__locals0 = new <>c__DisplayClass12_3
				{
					character = character
				};
				if (CS$<>8__locals0.character.IsLocal)
				{
					Character character2 = CS$<>8__locals0.character;
					Vector3 val = spawnPoints[localindex + 1].position - Vector3.up;
					PhotonMessageInfo val2 = default(PhotonMessageInfo);
					PhotonMessageInfo val3 = default(PhotonMessageInfo);
					PhotonMessageInfo val4 = default(PhotonMessageInfo);
					PhotonMessageInfo val5 = default(PhotonMessageInfo);
					PhotonMessageInfo val6 = default(PhotonMessageInfo);
					PhotonMessageInfo val7 = default(PhotonMessageInfo);
					PhotonMessageInfo val8 = default(PhotonMessageInfo);
					PhotonMessageInfo val9 = default(PhotonMessageInfo);
					character2.WarpPlayerRPC(val, true);
					Plugin.Log.LogInfo((object)$"Teleported {((Object)CS$<>8__locals0.character).name} to Spawn Point {localindex + 1} from Teleporter {((Object)((Component)component).gameObject).name}");
					CurrentSpawnPointIndex = localindex + 1;
					CS$<>8__locals0.character.refs.afflictions.ClearAllStatus(false);
					((MonoBehaviour)CS$<>8__locals0.character).StartCoroutine(FixPassout());
				}
				[IteratorStateMachine(typeof(<>c__DisplayClass12_3.<<DelayedActivation>g__FixPassout|3>d))]
				IEnumerator FixPassout()
				{
					//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
					return new <>c__DisplayClass12_3.<<DelayedActivation>g__FixPassout|3>d(0)
					{
						<>4__this = CS$<>8__locals0
					};
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass12_3
		{
			public Character character;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass12_4
		{
			public int localindex;

			internal void <DelayedActivation>b__4(Character character)
			{
				//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_0024: 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_0034: 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_0044: 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_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				if (character.IsLocal)
				{
					Vector3 val = spawnPoints[localindex].position - Vector3.up;
					PhotonMessageInfo val2 = default(PhotonMessageInfo);
					PhotonMessageInfo val3 = default(PhotonMessageInfo);
					PhotonMessageInfo val4 = default(PhotonMessageInfo);
					PhotonMessageInfo val5 = default(PhotonMessageInfo);
					PhotonMessageInfo val6 = default(PhotonMessageInfo);
					PhotonMessageInfo val7 = default(PhotonMessageInfo);
					PhotonMessageInfo val8 = default(PhotonMessageInfo);
					PhotonMessageInfo val9 = default(PhotonMessageInfo);
					character.WarpPlayerRPC(val, true);
					CurrentSpawnPointIndex = localindex;
					Plugin.Log.LogInfo((object)$"reverse Teleported {((Object)character).name} to Spawn Point {localindex}");
					character.refs.afflictions.ClearAllStatus(false);
					GiveResetBerry(character);
				}
			}
		}

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

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Expected O, but got Unknown
				//IL_0630: Unknown result type (might be due to invalid IL or missing references)
				//IL_0638: Unknown result type (might be due to invalid IL or missing references)
				//IL_0640: Unknown result type (might be due to invalid IL or missing references)
				//IL_0648: Unknown result type (might be due to invalid IL or missing references)
				//IL_0650: Unknown result type (might be due to invalid IL or missing references)
				//IL_0656: Unknown result type (might be due to invalid IL or missing references)
				//IL_065b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0661: Unknown result type (might be due to invalid IL or missing references)
				//IL_0666: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Expected O, but got Unknown
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0200: Expected O, but got Unknown
				//IL_026b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0272: Expected O, but got Unknown
				//IL_0540: Unknown result type (might be due to invalid IL or missing references)
				//IL_0547: Expected O, but got Unknown
				//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0600: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Plugin.Log.LogInfo((object)"Delaying Activation of ScoutmasterSpawner ------------------------------------ new Round ----------------------------------------------");
					CurrentSpawnPointIndex = 0;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Plugin.Log.LogInfo((object)"Moving Peak Finisher So that we can use it later");
					((Component)Singleton<PeakHandler>.Instance).transform.SetParent((Transform)null, true);
					Plugin.Log.LogInfo((object)"Deactivating Map Parts");
					foreach (Transform item2 in GameObject.Find("Map").transform)
					{
						Transform val7 = item2;
						((Component)val7).gameObject.SetActive(false);
					}
					GameObject.Find("EdgeWalls").SetActive(false);
					GameObject.Find("FogCutouts").SetActive(false);
					GameObject.Find("MountainProgress").SetActive(false);
					GameObject.Find("FogSphereSystem").SetActive(false);
					GameObject.Find("BlindPost").SetActive(false);
					GameObject.Find("Post Fog").SetActive(false);
					GameObject.Find("WaterMesh").SetActive(false);
					GameObject.Find("WaterZone").SetActive(false);
					Plugin.Log.LogInfo((object)"Instantiating Cutom Map Prefab");
					GameObject val8 = Plugin.Bundle.LoadAsset<GameObject>("Dropper Prefab");
					GameObject val9 = Object.Instantiate<GameObject>(val8, Vector3.up * 10f, Quaternion.identity);
					Plugin.Log.LogInfo((object)"Setting up Networking objects");
					GameObject val10 = GameObject.Find("GAME");
					addItemScript = val10.gameObject.AddComponent<AddItemInNetwork>();
					photonScript = val10.gameObject.GetComponent<PhotonView>();
					Plugin.Log.LogInfo((object)"Setting up Default Material");
					DefaultMaterial = new Material(((Renderer)((Component)val9.transform.Find("Dummy test object (1)")).GetComponent<MeshRenderer>()).material);
					DefaultMaterial.shader = Shader.Find("W/Peak_Standard");
					Plugin.Log.LogInfo((object)"Setting up Materials");
					SetupMaterial(val9);
					Plugin.Log.LogInfo((object)"Setting up Spawn Points");
					Transform val11 = val9.gameObject.transform.Find("Spawn Points Modding");
					spawnPoints = new List<Transform>();
					foreach (Transform item3 in val11)
					{
						Transform item = item3;
						spawnPoints.Add(item);
					}
					Plugin.Log.LogInfo((object)$"Found {spawnPoints.Count} Spawn points");
					Plugin.Log.LogInfo((object)"Setting Up Teleporation Cubes");
					if (Mode == GameMode.Dropper)
					{
						GameObject val12 = GameObject.Find("ohter parent");
						Plugin.Log.LogInfo((object)$"Found {val12.transform.childCount} End Portals");
						MaxSpawnPointIndex = val12.transform.childCount;
						for (int i = 0; i < val12.transform.childCount; i++)
						{
							<>c__DisplayClass12_0 CS$<>8__locals0 = new <>c__DisplayClass12_0
							{
								localindex = i,
								component = ((Component)val12.transform.GetChild(i)).gameObject.AddComponent<TriggerTeleporter>()
							};
							TriggerTeleporter component = CS$<>8__locals0.component;
							component.Interacted = (Action<Character>)Delegate.Combine(component.Interacted, (Action<Character>)delegate(Character character)
							{
								//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
								//IL_004d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0055: Unknown result type (might be due to invalid IL or missing references)
								//IL_005d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0065: Unknown result type (might be due to invalid IL or missing references)
								//IL_006d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0073: Unknown result type (might be due to invalid IL or missing references)
								//IL_0078: Unknown result type (might be due to invalid IL or missing references)
								//IL_007e: Unknown result type (might be due to invalid IL or missing references)
								//IL_0083: Unknown result type (might be due to invalid IL or missing references)
								<>c__DisplayClass12_1 CS$<>8__locals4 = new <>c__DisplayClass12_1
								{
									character = character
								};
								if (CS$<>8__locals4.character.IsLocal)
								{
									Character character3 = CS$<>8__locals4.character;
									Vector3 val34 = spawnPoints[CS$<>8__locals0.localindex + 1].position - Vector3.up;
									PhotonMessageInfo val35 = default(PhotonMessageInfo);
									PhotonMessageInfo val36 = default(PhotonMessageInfo);
									PhotonMessageInfo val37 = default(PhotonMessageInfo);
									PhotonMessageInfo val38 = default(PhotonMessageInfo);
									PhotonMessageInfo val39 = default(PhotonMessageInfo);
									PhotonMessageInfo val40 = default(PhotonMessageInfo);
									PhotonMessageInfo val41 = default(PhotonMessageInfo);
									PhotonMessageInfo val42 = default(PhotonMessageInfo);
									character3.WarpPlayerRPC(val34, true);
									Plugin.Log.LogInfo((object)$"Teleported {((Object)CS$<>8__locals4.character).name} to Spawn Point {CS$<>8__locals0.localindex + 1} from Teleporter {((Object)((Component)CS$<>8__locals0.component).gameObject).name}");
									CurrentSpawnPointIndex = CS$<>8__locals0.localindex + 1;
									((MonoBehaviour)CS$<>8__locals4.character).StartCoroutine(FixPassout());
								}
								[IteratorStateMachine(typeof(<>c__DisplayClass12_1.<<DelayedActivation>g__FixPassout|1>d))]
								IEnumerator FixPassout()
								{
									//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
									return new <>c__DisplayClass12_1.<<DelayedActivation>g__FixPassout|1>d(0)
									{
										<>4__this = CS$<>8__locals4
									};
								}
							});
						}
					}
					else if (Mode == GameMode.Descend)
					{
						GameObject val13 = GameObject.Find("Next Stage Parent");
						Plugin.Log.LogInfo((object)$"Found {val13.transform.childCount} Teleporters");
						MaxSpawnPointIndex = val13.transform.childCount;
						for (int j = 0; j < val13.transform.childCount; j++)
						{
							<>c__DisplayClass12_2 CS$<>8__locals1 = new <>c__DisplayClass12_2
							{
								localindex = j,
								component = ((Component)val13.transform.GetChild(j).GetChild(0)).gameObject.AddComponent<InteratableTeleporter>()
							};
							InteratableTeleporter component2 = CS$<>8__locals1.component;
							component2.Interacted = (Action<Character>)Delegate.Combine(component2.Interacted, (Action<Character>)delegate(Character character)
							{
								//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
								//IL_004d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0055: Unknown result type (might be due to invalid IL or missing references)
								//IL_005d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0065: Unknown result type (might be due to invalid IL or missing references)
								//IL_006d: Unknown result type (might be due to invalid IL or missing references)
								//IL_0073: Unknown result type (might be due to invalid IL or missing references)
								//IL_0078: Unknown result type (might be due to invalid IL or missing references)
								//IL_007e: Unknown result type (might be due to invalid IL or missing references)
								//IL_0083: Unknown result type (might be due to invalid IL or missing references)
								<>c__DisplayClass12_3 CS$<>8__locals3 = new <>c__DisplayClass12_3
								{
									character = character
								};
								if (CS$<>8__locals3.character.IsLocal)
								{
									Character character2 = CS$<>8__locals3.character;
									Vector3 val25 = spawnPoints[CS$<>8__locals1.localindex + 1].position - Vector3.up;
									PhotonMessageInfo val26 = default(PhotonMessageInfo);
									PhotonMessageInfo val27 = default(PhotonMessageInfo);
									PhotonMessageInfo val28 = default(PhotonMessageInfo);
									PhotonMessageInfo val29 = default(PhotonMessageInfo);
									PhotonMessageInfo val30 = default(PhotonMessageInfo);
									PhotonMessageInfo val31 = default(PhotonMessageInfo);
									PhotonMessageInfo val32 = default(PhotonMessageInfo);
									PhotonMessageInfo val33 = default(PhotonMessageInfo);
									character2.WarpPlayerRPC(val25, true);
									Plugin.Log.LogInfo((object)$"Teleported {((Object)CS$<>8__locals3.character).name} to Spawn Point {CS$<>8__locals1.localindex + 1} from Teleporter {((Object)((Component)CS$<>8__locals1.component).gameObject).name}");
									CurrentSpawnPointIndex = CS$<>8__locals1.localindex + 1;
									CS$<>8__locals3.character.refs.afflictions.ClearAllStatus(false);
									((MonoBehaviour)CS$<>8__locals3.character).StartCoroutine(FixPassout());
								}
								[IteratorStateMachine(typeof(<>c__DisplayClass12_3.<<DelayedActivation>g__FixPassout|3>d))]
								IEnumerator FixPassout()
								{
									//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
									return new <>c__DisplayClass12_3.<<DelayedActivation>g__FixPassout|3>d(0)
									{
										<>4__this = CS$<>8__locals3
									};
								}
							});
						}
					}
					Plugin.Log.LogInfo((object)"Setting up Reverse Teleporters");
					GameObject val14 = GameObject.Find("Reverse Teleporters");
					for (int k = 0; k < val14.transform.childCount; k++)
					{
						<>c__DisplayClass12_4 CS$<>8__locals2 = new <>c__DisplayClass12_4();
						Transform child = val14.transform.GetChild(k);
						CS$<>8__locals2.localindex = k;
						InteractableBackPorter interactableBackPorter = ((Component)child).gameObject.AddComponent<InteractableBackPorter>();
						interactableBackPorter.Interacted = (Action<Character>)Delegate.Combine(interactableBackPorter.Interacted, (Action<Character>)delegate(Character character)
						{
							//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_0024: 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_0034: 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_0044: 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_0054: 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_005f: Unknown result type (might be due to invalid IL or missing references)
							//IL_0065: Unknown result type (might be due to invalid IL or missing references)
							//IL_006a: Unknown result type (might be due to invalid IL or missing references)
							if (character.IsLocal)
							{
								Vector3 val16 = spawnPoints[CS$<>8__locals2.localindex].position - Vector3.up;
								PhotonMessageInfo val17 = default(PhotonMessageInfo);
								PhotonMessageInfo val18 = default(PhotonMessageInfo);
								PhotonMessageInfo val19 = default(PhotonMessageInfo);
								PhotonMessageInfo val20 = default(PhotonMessageInfo);
								PhotonMessageInfo val21 = default(PhotonMessageInfo);
								PhotonMessageInfo val22 = default(PhotonMessageInfo);
								PhotonMessageInfo val23 = default(PhotonMessageInfo);
								PhotonMessageInfo val24 = default(PhotonMessageInfo);
								character.WarpPlayerRPC(val16, true);
								CurrentSpawnPointIndex = CS$<>8__locals2.localindex;
								Plugin.Log.LogInfo((object)$"reverse Teleported {((Object)character).name} to Spawn Point {CS$<>8__locals2.localindex}");
								character.refs.afflictions.ClearAllStatus(false);
								GiveResetBerry(character);
							}
						});
					}
					InteratableFinisher interatableFinisher = GameObject.Find("Finisher").AddComponent<InteratableFinisher>();
					interatableFinisher.Interacted = (Action<Character>)Delegate.Combine(interatableFinisher.Interacted, (Action<Character>)delegate(Character character)
					{
						MethodInfo method = typeof(Character).GetMethod("TestWin", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
						method.Invoke(character, new object[0]);
					});
					foreach (Transform item4 in GameObject.Find("Brewing stands").transform)
					{
						Transform val15 = item4;
						InteractableBrewingStand interactableBrewingStand = ((Component)val15).gameObject.AddComponent<InteractableBrewingStand>();
						interactableBrewingStand.Interacted = (Action<Character>)Delegate.Combine(interactableBrewingStand.Interacted, (Action<Character>)delegate(Character character)
						{
							Plugin.Log.LogInfo((object)$"Character  {character.characterName} has interacted with the brewing stand | Is character local: {character.IsLocal}");
							_ = character.IsLocal;
							addItemScript.AddItemIntoInventory(Plugin.HealthPotion.itemID, ((MonoBehaviourPun)character).photonView.ViewID);
						});
					}
					if (Mode == GameMode.Dropper)
					{
						GameObject.Find("Dropper Map").SetActive(true);
						GameObject.Find("Descend map").SetActive(false);
					}
					else
					{
						GameObject.Find("Dropper Map").SetActive(false);
						GameObject.Find("Descend map").SetActive(true);
					}
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 2;
					return true;
				}
				case 2:
					<>1__state = -1;
					if (spawnPoints.Count > 0)
					{
						Character localCharacter = Character.localCharacter;
						Vector3 position = spawnPoints[0].position;
						PhotonMessageInfo val = default(PhotonMessageInfo);
						PhotonMessageInfo val2 = default(PhotonMessageInfo);
						PhotonMessageInfo val3 = default(PhotonMessageInfo);
						PhotonMessageInfo val4 = default(PhotonMessageInfo);
						PhotonMessageInfo val5 = default(PhotonMessageInfo);
						PhotonMessageInfo val6 = default(PhotonMessageInfo);
						localCharacter.WarpPlayerRPC(position, true);
						Plugin.Log.LogInfo((object)$"Teleporting Players to Spawn Point {0} | {((Object)((Component)spawnPoints[0]).gameObject).name}");
					}
					else
					{
						Plugin.Log.LogError((object)"No spawn points found in the prefab!");
					}
					GiveResetBerry(Character.localCharacter);
					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();
			}
		}

		public static Material DefaultMaterial;

		public static List<Transform> spawnPoints;

		public static int CurrentSpawnPointIndex = 0;

		public static int MaxSpawnPointIndex = 0;

		public static PhotonView photonScript;

		public static AddItemInNetwork addItemScript;

		public static GameMode Mode = GameMode.Dropper;

		public static bool gainFullControlOfCharacter = false;

		public static string ResetBerryName = Plugin.PLuginID + ":ResetBerry";

		public static string HealthPotionName = Plugin.PLuginID + ":Health potion";

		private static Dictionary<string, Shader> _peakShaders = null;

		internal static Dictionary<string, Shader> PeakShaders
		{
			get
			{
				if (_peakShaders == null)
				{
					List<string> list = new List<string>
					{
						"W/Peak_Standard", "W/Character", "W/Peak_Transparent", "W/Peak_Glass", "W/Peak_Clip", "W/Peak_glass_liquid", "W/Peak_GroundTransition", "W/Peak_Guidebook", "W/Peak_Honey", "W/Peak_Ice",
						"W/Peak_Rock", "W/Peak_Rope", "W/Peak_Splash", "W/Peak_Waterfall", "W/Vine", "Universal Render Pipeline/Lit"
					};
					_peakShaders = new Dictionary<string, Shader>();
					foreach (string item in list)
					{
						Shader val = Shader.Find(item);
						if ((Object)(object)val == (Object)null)
						{
							Plugin.Log.LogWarning((object)("Shader " + item + " not found, skipping."));
						}
						else
						{
							_peakShaders[item] = val;
						}
					}
				}
				return _peakShaders;
			}
		}

		[HarmonyPatch(typeof(ScoutmasterSpawner), "Awake")]
		[HarmonyPostfix]
		private static void ScoutmasterSpawner_Awake_Postfix(ScoutmasterSpawner __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(DelayedActivation());
		}

		[IteratorStateMachine(typeof(<DelayedActivation>d__12))]
		public static IEnumerator DelayedActivation()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedActivation>d__12(0);
		}

		public static void GiveResetBerry(Character character)
		{
			if ((Object)(object)character.player.itemSlots[0].prefab == (Object)(object)Plugin.ResetBerryItem || (Object)(object)character.player.itemSlots[1].prefab == (Object)(object)Plugin.ResetBerryItem || (Object)(object)character.player.itemSlots[2].prefab == (Object)(object)Plugin.ResetBerryItem)
			{
				Plugin.Log.LogInfo((object)("Not giving charater: " + character.characterName));
			}
			else
			{
				addItemScript.AddItemIntoInventory(Plugin.ResetBerryItem.itemID, ((MonoBehaviourPun)character).photonView.ViewID);
			}
		}

		private static void UnPassOut(Character character)
		{
			FieldInfo field = typeof(Character).GetField("UnPassOutCalled", BindingFlags.Instance | BindingFlags.NonPublic);
			field.SetValue(character, false);
			((MonoBehaviour)character).StartCoroutine(Wait3s());
			[IteratorStateMachine(typeof(<<UnPassOut>g__Wait3s|14_0>d))]
			static IEnumerator Wait3s()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <<UnPassOut>g__Wait3s|14_0>d(0);
			}
		}

		[HarmonyPatch(typeof(CharacterData), "GetTargetRagdollControll")]
		[HarmonyPrefix]
		public static bool Prefix(CharacterData __instance, ref float __result)
		{
			if (gainFullControlOfCharacter)
			{
				__result = 1f;
				__instance.fallSeconds = 0f;
				__instance.passedOut = false;
				__instance.passOutValue = 0f;
				__instance.fullyPassedOut = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")]
		[HarmonyPrefix]
		private static bool AchievementManager_ThrowAchievement_Prefix(AchievementManager __instance)
		{
			return false;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool OverrideHungerRateMultiplier(ref float __result)
		{
			__result = 0f;
			return false;
		}

		[HarmonyPatch(typeof(BerryBush), "SpawnItems")]
		[HarmonyPrefix]
		private static void BerryBush_SpawnItems_Prefix(BerryBush __instance, ref List<Transform> spawnSpots)
		{
			spawnSpots.Clear();
		}

		[HarmonyPatch(typeof(ScoutmasterSpawner), "SpawnScoutmaster")]
		[HarmonyPrefix]
		private static bool ScoutmasterSpawner_SpawnScoutmaster_Prefix(ScoutmasterSpawner __instance)
		{
			return false;
		}

		[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
		[HarmonyPrefix]
		private static bool Character_RPCA_PassOut_Prefix(Character __instance)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)$"Preventing {((Object)__instance).name} from passing out and respawning him at spawnpointIndex: {CurrentSpawnPointIndex}");
			__instance.refs.afflictions.ClearAllStatus(false);
			Vector3 position = spawnPoints[CurrentSpawnPointIndex].position;
			PhotonMessageInfo val = default(PhotonMessageInfo);
			PhotonMessageInfo val2 = default(PhotonMessageInfo);
			PhotonMessageInfo val3 = default(PhotonMessageInfo);
			PhotonMessageInfo val4 = default(PhotonMessageInfo);
			PhotonMessageInfo val5 = default(PhotonMessageInfo);
			PhotonMessageInfo val6 = default(PhotonMessageInfo);
			PhotonMessageInfo val7 = default(PhotonMessageInfo);
			PhotonMessageInfo val8 = default(PhotonMessageInfo);
			__instance.WarpPlayerRPC(position, true);
			return false;
		}

		[HarmonyPatch(typeof(CharacterItems), "DoDropping")]
		[HarmonyPrefix]
		private static bool CharacterItems_DoDropping_Prefix(CharacterItems __instance)
		{
			return false;
		}

		[HarmonyPatch(typeof(ItemSlot), "EmptyOut")]
		[HarmonyPrefix]
		private static bool ItemSlot_EmptyOut_Prefix(ItemSlot __instance)
		{
			Plugin.Log.LogInfo((object)("Preventing " + ((Object)((Component)__instance.prefab).gameObject).name + " from being dropped isntead " + ResetBerryName));
			if (((Object)((Component)__instance.prefab).gameObject).name == ResetBerryName)
			{
				return false;
			}
			return true;
		}

		private static void CheckEveryMaterialShader(GameObject gameObject)
		{
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				for (int j = 0; j < val.materials.Length; j++)
				{
					Material val2 = val.materials[j];
					Plugin.Log.LogInfo((object)("Rendere " + ((Object)((Component)val).gameObject).name + " with Material " + ((Object)val2).name + " uses shader " + ((Object)val2.shader).name));
				}
			}
		}

		public static void SetupMaterial(GameObject gameObject)
		{
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if (PeakShaders.TryGetValue(((Object)val2.shader).name, out Shader value))
					{
						val2.shader = value;
					}
				}
			}
			Renderer[] componentsInChildren2 = gameObject.GetComponentsInChildren<Renderer>();
			foreach (Renderer val3 in componentsInChildren2)
			{
				Material[] materials2 = val3.materials;
				foreach (Material val4 in materials2)
				{
					if (((Object)val4.shader).name == "Universal Render Pipeline/Lit" && !val4.IsKeywordEnabled("_EMISSION") && !IsTransparent(val4) && !HasAlphaClipping(val4))
					{
						Texture texture = val4.GetTexture("_BaseMap");
						if ((Object)(object)texture == (Object)null)
						{
							Plugin.Log.LogInfo((object)("No texture found for material " + ((Object)val4).name + ", skipping conversion."));
							continue;
						}
						val4.shader = DefaultMaterial.shader;
						val4.SetTexture("_BaseTexture", texture);
					}
				}
				val3.materials = materials2;
			}
		}

		private static bool IsTransparent(Material mat)
		{
			if (mat.HasProperty("_Surface"))
			{
				float @float = mat.GetFloat("_Surface");
				return @float > 0.5f;
			}
			return mat.renderQueue >= 3000;
		}

		private static bool HasAlphaClipping(Material mat)
		{
			return mat.IsKeywordEnabled("_ALPHATEST_ON");
		}
	}
	internal class MandatoryHarmonyPatches
	{
		private static bool modifiedBoardpass;

		private static LoadCorrectDropper loader;

		[HarmonyPatch(typeof(AchievementManager), "GetMaxAscent")]
		[HarmonyPostfix]
		public static void AchievementManager_GetMaxAscent_Postfix(ref int __result)
		{
		}

		[HarmonyPatch(typeof(AirportCheckInKiosk), "Awake")]
		[HarmonyPostfix]
		private static void AirportCheckInKiosk_Awake_Postfix(AirportCheckInKiosk __instance)
		{
			Plugin.Log.LogInfo((object)"Starting To add in additional Game Modes");
			loader = ((Component)__instance).gameObject.AddComponent<LoadCorrectDropper>();
			AddGameModes();
		}

		private static void AddGameModes()
		{
		}

		[HarmonyPatch(typeof(BoardingPass), "Initialize")]
		[HarmonyPrefix]
		public static void Prefix(BoardingPass __instance)
		{
		}

		[HarmonyPatch(typeof(BoardingPass), "StartGame")]
		[HarmonyPrefix]
		public static void BoardingPass_StartGame_Prefix(BoardingPass __instance)
		{
		}

		[HarmonyPatch(typeof(AscentUI), "Start")]
		[HarmonyPostfix]
		public static void AscentUI_Update_Postfix(AscentUI __instance)
		{
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		public static void OverrideAscentDifficulty(ref int __result)
		{
			if (Plugin.PlayingDropperMap)
			{
				__result = 0;
			}
		}
	}
	public class TriggerTeleporter : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <EnableCharactersDelayed>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TriggerTeleporter <>4__this;

			public int id;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				TriggerTeleporter triggerTeleporter = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					triggerTeleporter.charactersInTrigger.Remove(id);
					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();
			}
		}

		public Action<Character> Interacted;

		public List<int> charactersInTrigger = new List<int>();

		private void OnTriggerEnter(Collider other)
		{
			Character componentInParent = ((Component)((Component)other).transform).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				int viewID = ((Component)componentInParent).GetComponent<PhotonView>().ViewID;
				if (!charactersInTrigger.Contains(viewID))
				{
					charactersInTrigger.Add(viewID);
					Interacted?.Invoke(componentInParent);
					((MonoBehaviour)componentInParent).StartCoroutine(EnableCharactersDelayed(viewID));
				}
			}
		}

		[IteratorStateMachine(typeof(<EnableCharactersDelayed>d__3))]
		private IEnumerator EnableCharactersDelayed(int id)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnableCharactersDelayed>d__3(0)
			{
				<>4__this = this,
				id = id
			};
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

plugins/DropperPeakLevelSelectSwitcher.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using Dropper;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DropperPeakLevelSelectSwitcher
{
	[BepInPlugin("com.github.Beast.Dropper.PeakLevelSelectSwitcher", "Dropper PeakLevelSelect Switcher", "1.1.12")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class SwitcherPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.github.Beast.Dropper.PeakLevelSelectSwitcher";

		public const string PluginName = "Dropper PeakLevelSelect Switcher";

		public const string PluginVersion = "1.1.12";

		internal static ManualLogSource Log;

		internal static SwitcherPlugin Instance;

		private SwitcherPhotonCallbacks photonCallbacks;

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			DropperText.Install();
			Harmony.CreateAndPatchAll(typeof(BoardingPassSwitcher), "com.github.Beast.Dropper.PeakLevelSelectSwitcher");
			BoardingPassSwitcher.InstallManualPatches();
			photonCallbacks = new SwitcherPhotonCallbacks();
			PhotonNetwork.AddCallbackTarget((object)photonCallbacks);
			Log.LogInfo((object)"Dropper/PeakLevelSelect boarding pass switcher loaded.");
		}

		private void OnDestroy()
		{
			if (photonCallbacks != null)
			{
				PhotonNetwork.RemoveCallbackTarget((object)photonCallbacks);
				photonCallbacks = null;
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal sealed class SwitcherPhotonCallbacks : IInRoomCallbacks, IMatchmakingCallbacks
	{
		public void OnJoinedRoom()
		{
			BoardingPassSwitcher.OnJoinedRoom();
		}

		public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			BoardingPassSwitcher.OnRoomPropertiesUpdate(propertiesThatChanged);
		}

		public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
			BoardingPassSwitcher.OnPlayerPropertiesUpdate(targetPlayer, changedProps);
		}

		public void OnPlayerEnteredRoom(Player newPlayer)
		{
			BoardingPassSwitcher.OnPlayerEnteredRoom(newPlayer);
		}

		public void OnPlayerLeftRoom(Player otherPlayer)
		{
		}

		public void OnMasterClientSwitched(Player newMasterClient)
		{
		}

		public void OnFriendListUpdate(List<FriendInfo> friendList)
		{
		}

		public void OnCreatedRoom()
		{
			BoardingPassSwitcher.OnJoinedRoom();
		}

		public void OnCreateRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRoomFailed(short returnCode, string message)
		{
		}

		public void OnJoinRandomFailed(short returnCode, string message)
		{
		}

		public void OnLeftRoom()
		{
			BoardingPassSwitcher.OnLeftRoom();
		}
	}
	internal static class DropperText
	{
		private const int ChineseLanguageIndex = 9;

		public static bool IsChinese
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				try
				{
					return (int)LocalizedText.CURRENT_LANGUAGE == 9;
				}
				catch
				{
					return false;
				}
			}
		}

		public static string Choose(string english, string chinese)
		{
			if (!IsChinese)
			{
				return english;
			}
			return chinese;
		}

		public static void Install()
		{
			Set("Name_Reset", "Resetter", "重置器");
			Set("Force reset on #targetchar", "force reset #targetchar", "强制重置 #targetchar");
			Set("Name_Instant Health I", "Instant Health I", "瞬间治疗 I");
			Set("administer #targetchar", "administer #targetchar", "使用于 #targetchar");
			Set("Dropper", "Dropper", "坠落挑战");
			Set("Immense dread", "Immense dread", "无尽恐惧");
			Set("Desc_Dropper", "Does falling from 50 meters and crushing all your bones hurt? YES! But the adrenaline keeps you alive and ready to hit the portal next time!", "从 50 米高空坠落并摔碎全身骨头会痛吗?当然会!但肾上腺素会让你活下来,准备好下一次冲进传送门!");
			Set("Dropper - Descend", "Dropper - Descent", "坠落挑战 - 下降");
			Set("Desc_Dropper - Descend", "Instead of doing it all in one jump, how about we mix it up with some parkour to climb down. Why would you do that? Well let's finish the first map an you will see why", "不再一次跳到底,而是加入一些跑酷向下推进。为什么要这样做?先完成第一张地图,你就会明白。");
		}

		private static void Set(string key, string english, string chinese)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < 15; i++)
			{
				list.Add(english);
			}
			list[9] = chinese;
			LocalizedText.mainTable[key.ToUpperInvariant()] = list;
		}
	}
	[HarmonyAfter(new string[] { "PeakLevelSelect", "com.github.Beast.Dropper" })]
	internal static class BoardingPassSwitcher
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__107_0;

			public static UnityAction <>9__107_1;

			internal void <EnsureButtons>b__107_0()
			{
				useDropperControls = !useDropperControls;
				SwitcherPlugin.Log.LogInfo((object)("Dropper feature switch clicked. Dropper controls: " + useDropperControls));
				if (!useDropperControls)
				{
					ApplyDropperToggle(-1);
					PublishDropperOffSelection();
				}
				if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.boardingPass != (Object)null)
				{
					if (useDropperControls)
					{
						ClampAscentIndex(GUIManager.instance.boardingPass);
					}
					Refresh(GUIManager.instance.boardingPass);
				}
			}

			internal void <EnsureButtons>b__107_1()
			{
				dropperMode = ((dropperMode == 0) ? 1 : 0);
				SwitcherPlugin.Log.LogInfo((object)("Dropper mode switch clicked. Mode: " + dropperMode));
				if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.boardingPass != (Object)null)
				{
					Refresh(GUIManager.instance.boardingPass);
				}
			}
		}

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

			private object <>2__current;

			public string source;

			private float <timeout>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(4f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<timeout>5__2 = Time.realtimeSinceStartup + 12f;
					break;
				case 2:
					<>1__state = -1;
					break;
				case 3:
					<>1__state = -1;
					dropperMapActivationRunning = false;
					ScheduleDropperSpawnRecovery("map activation after " + source);
					return false;
				}
				if (Time.realtimeSinceStartup < <timeout>5__2)
				{
					if (!IsDropperModeActive())
					{
						dropperMapActivationRunning = false;
						return false;
					}
					if (IsDropperMapBuilt())
					{
						dropperMapActivationRunning = false;
						ScheduleDropperSpawnRecovery("map already active after " + source);
						return false;
					}
					if (!IsGameplaySceneForDropperBuild() || (Object)(object)GameObject.Find("Map") == (Object)null || (Object)(object)GameObject.Find("GAME") == (Object)null)
					{
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					IEnumerator enumerator = null;
					try
					{
						enumerator = AccessTools.Method(AccessTools.TypeByName("Dropper.HarmonyPatches"), "DelayedActivation", (Type[])null, (Type[])null)?.Invoke(null, null) as IEnumerator;
					}
					catch (Exception ex)
					{
						SwitcherPlugin.Log.LogWarning((object)("Failed to start Dropper map activation after " + source + ": " + ex.Message));
					}
					if (enumerator == null)
					{
						dropperMapActivationRunning = false;
						return false;
					}
					SwitcherPlugin.Log.LogInfo((object)("Running Dropper map activation after late room mode sync from " + source + "."));
					<>2__current = ((MonoBehaviour)SwitcherPlugin.Instance).StartCoroutine(enumerator);
					<>1__state = 3;
					return true;
				}
				dropperMapActivationRunning = false;
				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 <DropperSpawnRecoveryRoutine>d__161 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public string source;

			private float <timeout>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeout>5__2 = Time.realtimeSinceStartup + 8f;
					break;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				case 3:
					<>1__state = -1;
					break;
				case 4:
					<>1__state = -1;
					break;
				case 5:
					<>1__state = -1;
					break;
				}
				if (Time.realtimeSinceStartup < <timeout>5__2)
				{
					if (!IsDropperModeActive() && !Plugin.PlayingDropperMap)
					{
						return false;
					}
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter == (Object)null)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					KeepDropperSpawnAlive(localCharacter);
					if (localCharacter.inAirport)
					{
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					if (localCharacter.warping)
					{
						<>2__current = null;
						<>1__state = 3;
						return true;
					}
					if (!DropperSpawnPointsReadyForRecovery(0.85f))
					{
						<>2__current = null;
						<>1__state = 4;
						return true;
					}
					if (TryGetDropperSpawnPosition(localCharacter, out var position) && Vector3.Distance(localCharacter.Center, position) < 2.5f)
					{
						TryRunDropperUnPassOut(localCharacter);
						return false;
					}
					if (TryWarpLocalCharacterToDropperSpawn(localCharacter))
					{
						TryRunDropperUnPassOut(localCharacter);
						SwitcherPlugin.Log.LogInfo((object)("Recovered local Dropper spawn after " + source + "."));
						return false;
					}
					<>2__current = null;
					<>1__state = 5;
					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 <WarpLocalCharacterToDropperSpawnWhenReady>d__167 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Character character;

			private float <timeout>5__2;

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

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

			[DebuggerHidden]
			public <WarpLocalCharacterToDropperSpawnWhenReady>d__167(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;
					<timeout>5__2 = Time.realtimeSinceStartup + 5f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)character != (Object)null && Time.realtimeSinceStartup < <timeout>5__2)
				{
					KeepDropperSpawnAlive(character);
					if (TryWarpLocalCharacterToDropperSpawn(character))
					{
						return false;
					}
					<>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();
			}
		}

		private const int OffSentinel = -1;

		private const int DropperSentinel = -101;

		private const int DescendSentinel = -102;

		private const int PeakLevelSelectDefault = -2;

		private const int PeakLevelSelectUnset = -9999;

		private const string RoomDropperModeKey = "DropperFix.Mode";

		private const string RoomPeakLevelKey = "DropperFix.PeakLevel";

		private const string RoomPeakAscentKey = "DropperFix.PeakAscent";

		private const string PlayerSwitcherInstalledKey = "DropperFix.SwitcherInstalled";

		private const float LocalPublishedModeGraceSeconds = 120f;

		private static bool useDropperControls;

		private static int dropperMode;

		private static int localPublishedMode = -9999;

		private static float localPublishedModeExpiresAt;

		private static GameObject switchButton;

		private static GameObject dropperModeButton;

		private static TextMeshProUGUI switchButtonText;

		private static TextMeshProUGUI dropperModeButtonText;

		private static bool checkedPeakLevelSelect;

		private static Type peakLevelSelectPatchType;

		private static bool dropperUiApplied;

		private static bool capturedDescLayout;

		private static bool defaultDescAutoSizing;

		private static float defaultDescLineSpacing;

		private static float defaultDescParagraphSpacing;

		private static Vector4 defaultDescMargin;

		private static float defaultDescFontSizeMin;

		private static float defaultDescFontSizeMax;

		private static RectTransform ascentTitleRect;

		private static Vector2 defaultAscentTitleAnchoredPosition;

		private static Vector2 defaultAscentTitleSizeDelta;

		private static bool capturedTitleLayout;

		private static bool capturedRewardState;

		private static bool defaultRewardActive;

		private static bool capturedCustomOptionsState;

		private static bool defaultCustomOptionsActive;

		private static bool capturedTextState;

		private static string defaultAscentTitleText;

		private static Color defaultAscentTitleColor;

		private static string defaultAscentDescText;

		private static bool peakLevelSelectHiddenByDropper;

		private static bool loggedDropperFogFreeze;

		private static bool loggedDropperLavaFreeze;

		private static bool loggedDropperSpawnDeathBypass;

		private static bool loggedDropperDeathBypass;

		private static bool fogColdControlPatched;

		private static bool checkedFogColdControl;

		private static bool loggedInstallAdvertisement;

		private static bool loggedDropperPassOutUnpatch;

		private static bool dropperMapActivationRunning;

		private static bool dropperPlayerSpawnInFlight;

		private static bool loggedDuplicateDropperSpawnSuppression;

		private static float lastDropperMapActivationAt;

		private static float dropperPlayerSpawnInFlightAt;

		private static float nextDropperSpawnRecoveryAt;

		private static float dropperSpawnPointsReadyAt;

		private static int lastDropperSpawnPointCount;

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

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

		private static readonly Color Blue = new Color(0.1922f, 0.2941f, 0.9804f, 1f);

		private static readonly Color Yellow = new Color(0.9804f, 0.8075f, 0.1922f, 1f);

		[HarmonyPatch(typeof(OrbFogHandler), "Update")]
		[HarmonyPrefix]
		private static bool OrbFogHandler_Update_Prefix(OrbFogHandler __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeOrbFog(__instance, "Update");
			return false;
		}

		[HarmonyPatch(typeof(OrbFogHandler), "WaitToMove")]
		[HarmonyPrefix]
		private static bool OrbFogHandler_WaitToMove_Prefix(OrbFogHandler __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeOrbFog(__instance, "WaitToMove");
			return false;
		}

		[HarmonyPatch(typeof(OrbFogHandler), "StartMovingRPC")]
		[HarmonyPrefix]
		private static bool OrbFogHandler_StartMovingRPC_Prefix(OrbFogHandler __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeOrbFog(__instance, "StartMovingRPC");
			return false;
		}

		[HarmonyPatch(typeof(OrbFogHandler), "RPCA_SyncFog")]
		[HarmonyPrefix]
		private static bool OrbFogHandler_RPCA_SyncFog_Prefix(OrbFogHandler __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeOrbFog(__instance, "RPCA_SyncFog");
			return false;
		}

		[HarmonyPatch(typeof(OrbFogHandler), "RPC_InitFog")]
		[HarmonyPrefix]
		private static bool OrbFogHandler_RPC_InitFog_Prefix(OrbFogHandler __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeOrbFog(__instance, "RPC_InitFog");
			return false;
		}

		[HarmonyPatch(typeof(Fog), "Update")]
		[HarmonyPrefix]
		private static bool Fog_Update_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			if ((Object)(object)Character.localCharacter?.data != (Object)null)
			{
				Character.localCharacter.data.isInFog = false;
			}
			LogDropperFogFreeze("legacy fog Update");
			return false;
		}

		[HarmonyPatch(typeof(Fog), "RPCA_Resume")]
		[HarmonyPrefix]
		private static bool Fog_RPCA_Resume_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperFogFreeze("legacy fog resume");
			return false;
		}

		[HarmonyPatch(typeof(Fog), "RPCA_SyncFog")]
		[HarmonyPrefix]
		private static bool Fog_RPCA_SyncFog_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperFogFreeze("legacy fog sync");
			return false;
		}

		[HarmonyPatch(typeof(LavaRising), "Update")]
		[HarmonyPrefix]
		private static bool LavaRising_Update_Prefix(LavaRising __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeLavaRising(__instance, "Update");
			return false;
		}

		[HarmonyPatch(typeof(LavaRising), "StartWaiting")]
		[HarmonyPrefix]
		private static bool LavaRising_StartWaiting_Prefix(LavaRising __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeLavaRising(__instance, "StartWaiting");
			return false;
		}

		[HarmonyPatch(typeof(LavaRising), "RecieveLavaData")]
		[HarmonyPrefix]
		private static bool LavaRising_RecieveLavaData_Prefix(LavaRising __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			FreezeLavaRising(__instance, "RecieveLavaData");
			return false;
		}

		[HarmonyPatch(typeof(MovingLava), "Update")]
		[HarmonyPrefix]
		private static bool MovingLava_Update_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperLavaFreeze("moving lava Update");
			return false;
		}

		[HarmonyPatch(typeof(MovingLava), "RPCA_StartLavaRise")]
		[HarmonyPrefix]
		private static bool MovingLava_RPCA_StartLavaRise_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperLavaFreeze("moving lava start");
			return false;
		}

		[HarmonyPatch(typeof(MovingLava), "RPCA_SyncLavaHeight")]
		[HarmonyPrefix]
		private static bool MovingLava_RPCA_SyncLavaHeight_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperLavaFreeze("moving lava sync");
			return false;
		}

		[HarmonyPatch(typeof(CharacterSpawner), "KillImmediately")]
		[HarmonyPrefix]
		private static bool CharacterSpawner_KillImmediately_Prefix(Character self)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			KeepDropperSpawnAlive(self);
			if ((Object)(object)self != (Object)null && self.IsLocal)
			{
				if (!TryWarpLocalCharacterToDropperSpawn(self))
				{
					ScheduleDropperSpawnRecovery("late-join death spawn");
				}
				TryRunDropperUnPassOut(self);
			}
			if (!loggedDropperSpawnDeathBypass)
			{
				loggedDropperSpawnDeathBypass = true;
				SwitcherPlugin.Log.LogInfo((object)"Bypassed vanilla late-join death spawn while Dropper mode is active.");
			}
			return false;
		}

		[HarmonyPatch(typeof(Character), "StartPassedOutOnTheBeach")]
		[HarmonyPostfix]
		private static void Character_StartPassedOutOnTheBeach_Postfix(Character __instance)
		{
			if (IsDropperModeActive() && !((Object)(object)__instance == (Object)null))
			{
				KeepDropperSpawnAlive(__instance);
				if (__instance.IsLocal)
				{
					TryRunDropperUnPassOut(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Character), "RPCA_SetDead")]
		[HarmonyPrefix]
		private static bool Character_RPCA_SetDead_Prefix(Character __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			KeepDropperSpawnAlive(__instance);
			if ((Object)(object)__instance != (Object)null && __instance.IsLocal)
			{
				if (!TryWarpLocalCharacterToDropperSpawn(__instance))
				{
					ScheduleDropperSpawnRecovery("dead reconnect spawn");
				}
				TryRunDropperUnPassOut(__instance);
			}
			return false;
		}

		[HarmonyPatch(typeof(Character), "RPCA_Die")]
		[HarmonyPrefix]
		private static bool Character_RPCA_Die_Prefix(Character __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			KeepDropperSpawnAlive(__instance);
			if (!TryWarpLocalCharacterToDropperSpawn(__instance) && (Object)(object)__instance != (Object)null && __instance.IsLocal)
			{
				((MonoBehaviour)__instance).StartCoroutine(WarpLocalCharacterToDropperSpawnWhenReady(__instance));
			}
			if (!loggedDropperDeathBypass)
			{
				loggedDropperDeathBypass = true;
				SwitcherPlugin.Log.LogInfo((object)"Bypassed vanilla death RPC while Dropper mode is active.");
			}
			return false;
		}

		[HarmonyPatch(typeof(Character), "RPCA_PassOut")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "com.github.Beast.Dropper.runtime" })]
		private static bool Character_RPCA_PassOut_Prefix(Character __instance)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			KeepDropperSpawnAlive(__instance);
			if ((Object)(object)__instance != (Object)null && __instance.IsLocal)
			{
				TryWarpLocalCharacterToDropperSpawn(__instance);
				TryRunDropperUnPassOut(__instance);
			}
			return false;
		}

		[HarmonyPatch(typeof(AddItemInNetwork), "AddItemIntoInventory")]
		[HarmonyPrefix]
		private static bool AddItemInNetwork_AddItemIntoInventory_Prefix(int itemID, int photonID)
		{
			if (!IsDropperModeActive() || (Object)(object)Plugin.ResetBerryItem == (Object)null || itemID != Plugin.ResetBerryItem.itemID)
			{
				return true;
			}
			Character val = TryGetCharacterByPhotonId(photonID);
			if ((Object)(object)val != (Object)null && HasResetBerry(val))
			{
				return false;
			}
			int num = (((Object)(object)val != (Object)null) ? GetPlayerKey(val) : photonID);
			if (num == 0)
			{
				num = photonID;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (LastResetBerryGrantTimes.TryGetValue(num, out var value) && realtimeSinceStartup - value < 2f)
			{
				return false;
			}
			LastResetBerryGrantTimes[num] = realtimeSinceStartup;
			return true;
		}

		[HarmonyPatch(typeof(ScoutmasterSpawner), "Awake")]
		[HarmonyPostfix]
		private static void ScoutmasterSpawner_Awake_DropperProgress_Postfix()
		{
			PlayerSpawnPointIndexes.Clear();
			LastResetBerryGrantTimes.Clear();
		}

		[HarmonyPatch(typeof(TriggerTeleporter), "OnTriggerEnter")]
		[HarmonyPostfix]
		private static void TriggerTeleporter_OnTriggerEnter_Postfix(TriggerTeleporter __instance, Collider other)
		{
			if (!IsDropperModeActive() || (Object)(object)__instance == (Object)null || (Object)(object)other == (Object)null)
			{
				return;
			}
			Character componentInParent = ((Component)other).GetComponentInParent<Character>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				Transform transform = ((Component)__instance).transform;
				if ((Object)(object)transform.parent != (Object)null && ((Object)((Component)transform.parent).gameObject).name == "ohter parent")
				{
					SetPlayerSpawnPointIndex(componentInParent, transform.GetSiblingIndex() + 1);
				}
			}
		}

		[HarmonyPatch(typeof(InteratableTeleporter), "Interact_CastFinished")]
		[HarmonyPostfix]
		private static void InteratableTeleporter_Interact_CastFinished_Postfix(InteratableTeleporter __instance, Character interactor)
		{
			if (IsDropperModeActive() && !((Object)(object)__instance == (Object)null) && !((Object)(object)interactor == (Object)null))
			{
				Transform transform = ((Component)__instance).transform;
				if ((Object)(object)transform.parent != (Object)null && (Object)(object)transform.parent.parent != (Object)null && ((Object)((Component)transform.parent.parent).gameObject).name == "Next Stage Parent")
				{
					SetPlayerSpawnPointIndex(interactor, transform.parent.GetSiblingIndex() + 1);
				}
			}
		}

		[HarmonyPatch(typeof(InteractableBackPorter), "Interact_CastFinished")]
		[HarmonyPostfix]
		private static void InteractableBackPorter_Interact_CastFinished_Postfix(InteractableBackPorter __instance, Character interactor)
		{
			if (IsDropperModeActive() && !((Object)(object)__instance == (Object)null) && !((Object)(object)interactor == (Object)null))
			{
				SetPlayerSpawnPointIndex(interactor, ((Component)__instance).transform.GetSiblingIndex());
			}
		}

		[HarmonyPatch(typeof(InteratableFinisher), "GetInteractionText")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "com.github.Beast.Dropper.runtime" })]
		private static bool InteratableFinisher_GetInteractionText_Prefix(ref string __result)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			__result = (IsLocalPlayerAtDropperFinish() ? "Finish the game for all players" : "Breaking out of the map doesn't allow you to finish early");
			return false;
		}

		[HarmonyPatch(typeof(InteratableFinisher), "Interact_CastFinished")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "com.github.Beast.Dropper.runtime" })]
		private static bool InteratableFinisher_Interact_CastFinished_Prefix(InteratableFinisher __instance, Character interactor)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			if ((Object)(object)interactor != (Object)null && IsPlayerAtDropperFinish(interactor))
			{
				__instance.Interacted?.Invoke(interactor);
			}
			return false;
		}

		private static bool HarmonyPatches_GiveResetBerry_Prefix(Character character)
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			TryGiveResetBerryOnce(character);
			return false;
		}

		internal static void InstallManualPatches()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MethodInfo methodInfo = AccessTools.Method("Dropper.HarmonyPatches:GiveResetBerry", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					SwitcherPlugin.Log.LogWarning((object)"Dropper GiveResetBerry patch skipped: target method not found.");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(BoardingPassSwitcher), "HarmonyPatches_GiveResetBerry_Prefix", (Type[])null, (Type[])null));
				val.priority = 800;
				val.before = new string[1] { "com.github.Beast.Dropper.runtime" };
				HarmonyMethod val2 = val;
				new Harmony("com.github.Beast.Dropper.PeakLevelSelectSwitcher.ManualDropperPatches").Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				SwitcherPlugin.Log.LogInfo((object)"Patched Dropper GiveResetBerry for per-player dedupe.");
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogError((object)("Failed to install manual Dropper compatibility patches: " + ex));
			}
		}

		[HarmonyPatch(typeof(AirportCheckInKiosk), "BeginIslandLoadRPC")]
		[HarmonyPrefix]
		private static void AirportCheckInKiosk_BeginIslandLoadRPC_Prefix()
		{
			ApplyRoomSelection("BeginIslandLoadRPC");
		}

		[HarmonyPatch(typeof(AirportCheckInKiosk), "LoadIslandMaster")]
		[HarmonyPrefix]
		private static void AirportCheckInKiosk_LoadIslandMaster_Prefix(ref byte[] serializedRunSettings)
		{
			ApplyRoomSelection("LoadIslandMaster");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_NewPlayerSpawn")]
		[HarmonyPrefix]
		private static bool CharacterSpawner_RPC_NewPlayerSpawn_Prefix()
		{
			ApplyRoomSelection("RPC_NewPlayerSpawn");
			return AllowDropperPlayerSpawnRpc("new player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_NewPlayerSpawn")]
		[HarmonyPostfix]
		private static void CharacterSpawner_RPC_NewPlayerSpawn_Postfix()
		{
			ScheduleDropperSpawnRecovery("new player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_ReconnectingPlayerSpawn")]
		[HarmonyPrefix]
		private static bool CharacterSpawner_RPC_ReconnectingPlayerSpawn_Prefix()
		{
			ApplyRoomSelection("RPC_ReconnectingPlayerSpawn");
			return AllowDropperPlayerSpawnRpc("reconnecting player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_ReconnectingPlayerSpawn")]
		[HarmonyPostfix]
		private static void CharacterSpawner_RPC_ReconnectingPlayerSpawn_Postfix()
		{
			ScheduleDropperSpawnRecovery("reconnecting player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_MiniRunPlayerSpawn")]
		[HarmonyPrefix]
		private static bool CharacterSpawner_RPC_MiniRunPlayerSpawn_Prefix()
		{
			ApplyRoomSelection("RPC_MiniRunPlayerSpawn");
			return AllowDropperPlayerSpawnRpc("mini run player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "RPC_MiniRunPlayerSpawn")]
		[HarmonyPostfix]
		private static void CharacterSpawner_RPC_MiniRunPlayerSpawn_Postfix()
		{
			ScheduleDropperSpawnRecovery("mini run player spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "SpawnHostCharacter")]
		[HarmonyPrefix]
		private static void CharacterSpawner_SpawnHostCharacter_Prefix()
		{
			ApplyRoomSelection("SpawnHostCharacter");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "SpawnSelfOnShore")]
		[HarmonyPostfix]
		private static void CharacterSpawner_SpawnSelfOnShore_Postfix()
		{
			ScheduleDropperSpawnRecovery("vanilla shore spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "SpawnDeadAtBaseCamp")]
		[HarmonyPostfix]
		private static void CharacterSpawner_SpawnDeadAtBaseCamp_Postfix()
		{
			ScheduleDropperSpawnRecovery("vanilla basecamp spawn");
		}

		[HarmonyPatch(typeof(CharacterSpawner), "SpawnMyPlayerCharacter")]
		[HarmonyPostfix]
		private static void CharacterSpawner_SpawnMyPlayerCharacter_Postfix()
		{
			dropperPlayerSpawnInFlight = false;
			ScheduleDropperSpawnRecovery("local player character spawn");
		}

		[HarmonyPatch(typeof(RunSettings), "PushRunSettings")]
		[HarmonyPrefix]
		private static bool RunSettings_PushRunSettings_Prefix(Player player = null)
		{
			TryAdvertiseSwitcherInstall();
			return true;
		}

		[HarmonyPatch(typeof(GUIManager), "Start")]
		[HarmonyPostfix]
		private static void GUIManager_Start_Postfix()
		{
			TryAdvertiseSwitcherInstall();
			TryPatchFogColdControl();
			if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.boardingPass != (Object)null)
			{
				EnsureButtons(GUIManager.instance.boardingPass);
				Refresh(GUIManager.instance.boardingPass);
			}
		}

		[HarmonyPatch(typeof(BoardingPass), "UpdateAscent")]
		[HarmonyPrefix]
		private static void BoardingPass_UpdateAscent_Prefix(BoardingPass __instance)
		{
			ClampAscentIndex(__instance);
		}

		[HarmonyPatch(typeof(BoardingPass), "UpdateAscent")]
		[HarmonyPostfix]
		private static void BoardingPass_UpdateAscent_Postfix(BoardingPass __instance)
		{
			EnsureButtons(__instance);
			Refresh(__instance);
		}

		[HarmonyPatch(typeof(BoardingPass), "StartGame")]
		[HarmonyPrefix]
		private static bool BoardingPass_StartGame_Prefix(BoardingPass __instance)
		{
			TryAdvertiseSwitcherInstall();
			if ((Object)(object)__instance == (Object)null || LoadingScreenHandler.loading)
			{
				return true;
			}
			if (RunSettings.IsCustomRun || !useDropperControls)
			{
				DisableDropperForVanillaStart(__instance);
				return true;
			}
			RunSettings.IsCustomRun = false;
			ClearPeakLevelSelectSelection();
			int mode = ((dropperMode == 0) ? (-101) : (-102));
			PublishRoomSelection(mode);
			SendDropperMode(__instance, mode);
			if ((Object)(object)__instance.kiosk != (Object)null)
			{
				__instance.kiosk.StartGame(__instance.ascentIndex);
			}
			return false;
		}

		[HarmonyPatch(typeof(AirportCheckInKiosk), "StartGame")]
		[HarmonyPrefix]
		private static void AirportCheckInKiosk_StartGame_Prefix(ref int ascent)
		{
			TryAdvertiseSwitcherInstall();
		}

		private static void EnsureButtons(BoardingPass pass)
		{
			//IL_0085: 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_00e3: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			if ((Object)(object)pass == (Object)null || (Object)(object)switchButton != (Object)null)
			{
				return;
			}
			Transform val = ((Component)pass).transform.Find("BoardingPass/Panel");
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)pass).transform.Find("Panel");
			}
			if ((Object)(object)val == (Object)null || (Object)(object)pass.incrementAscentButton == (Object)null)
			{
				SwitcherPlugin.Log.LogWarning((object)"Could not find boarding pass panel/reference button for Dropper switcher.");
				return;
			}
			GameObject gameObject = ((Component)pass.incrementAscentButton).gameObject;
			Transform parent = val;
			Vector2 position = new Vector2(545f, 405f);
			Vector2 size = new Vector2(120f, 30f);
			object obj = <>c.<>9__107_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					useDropperControls = !useDropperControls;
					SwitcherPlugin.Log.LogInfo((object)("Dropper feature switch clicked. Dropper controls: " + useDropperControls));
					if (!useDropperControls)
					{
						ApplyDropperToggle(-1);
						PublishDropperOffSelection();
					}
					if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.boardingPass != (Object)null)
					{
						if (useDropperControls)
						{
							ClampAscentIndex(GUIManager.instance.boardingPass);
						}
						Refresh(GUIManager.instance.boardingPass);
					}
				};
				<>c.<>9__107_0 = val2;
				obj = (object)val2;
			}
			switchButton = CreateButton(pass, gameObject, parent, "DropperFeatureSwitch", position, size, (UnityAction)obj, out switchButtonText);
			GameObject gameObject2 = ((Component)pass.incrementAscentButton).gameObject;
			Transform parent2 = val;
			Vector2 position2 = new Vector2(690f, 405f);
			Vector2 size2 = new Vector2(135f, 30f);
			object obj2 = <>c.<>9__107_1;
			if (obj2 == null)
			{
				UnityAction val3 = delegate
				{
					dropperMode = ((dropperMode == 0) ? 1 : 0);
					SwitcherPlugin.Log.LogInfo((object)("Dropper mode switch clicked. Mode: " + dropperMode));
					if ((Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.boardingPass != (Object)null)
					{
						Refresh(GUIManager.instance.boardingPass);
					}
				};
				<>c.<>9__107_1 = val3;
				obj2 = (object)val3;
			}
			dropperModeButton = CreateButton(pass, gameObject2, parent2, "DropperModeSwitch", position2, size2, (UnityAction)obj2, out dropperModeButtonText);
			SwitcherPlugin.Log.LogInfo((object)"Created Dropper switcher buttons on boarding pass.");
		}

		private static void ClampAscentIndex(BoardingPass pass)
		{
			if ((Object)(object)pass == (Object)null || (Object)(object)pass.ascentData == (Object)null || pass.ascentData.ascents == null)
			{
				return;
			}
			int num = Math.Min(7, pass.ascentData.ascents.Count - 3);
			if (num < -1)
			{
				return;
			}
			bool flag = pass.ascentIndex < -1;
			int num2 = ((!flag) ? Mathf.Min(pass.ascentIndex, num) : 0);
			if (num2 != pass.ascentIndex)
			{
				SwitcherPlugin.Log.LogWarning((object)("Clamped invalid boarding pass ascent index from " + pass.ascentIndex + " to " + num2 + "."));
				pass.ascentIndex = num2;
				if (GetPeakLevelSelectValue("SelectedAscent", -2) != -2)
				{
					SetPeakLevelSelectValue("SelectedAscent", flag ? (-2) : num2);
				}
			}
		}

		private static GameObject CreateButton(BoardingPass pass, GameObject referenceButton, Transform parent, string name, Vector2 position, Vector2 size, UnityAction onClick, out TextMeshProUGUI label)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00de: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			GameObject val = Object.Instantiate<GameObject>(referenceButton, parent, false);
			((Object)val).name = name;
			Animator component = val.GetComponent<Animator>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Transform val2 = val.transform.Find("Image");
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			RectTransform component2 = val.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.zero;
			component2.pivot = Vector2.zero;
			component2.anchoredPosition = position;
			component2.sizeDelta = size;
			Button component3 = val.GetComponent<Button>();
			((UnityEventBase)component3.onClick).RemoveAllListeners();
			((UnityEvent)component3.onClick).AddListener(onClick);
			((Selectable)component3).interactable = true;
			label = val.GetComponentInChildren<TextMeshProUGUI>(true);
			if ((Object)(object)label == (Object)null)
			{
				GameObject val3 = new GameObject("Text (TMP)");
				val3.transform.SetParent(val.transform, false);
				RectTransform obj = val3.AddComponent<RectTransform>();
				obj.anchorMin = Vector2.zero;
				obj.anchorMax = Vector2.one;
				obj.offsetMin = Vector2.zero;
				obj.offsetMax = Vector2.zero;
				label = val3.AddComponent<TextMeshProUGUI>();
			}
			((TMP_Text)label).alignment = (TextAlignmentOptions)514;
			if ((Object)(object)pass.ascentTitle != (Object)null && (Object)(object)pass.ascentTitle.font != (Object)null)
			{
				((TMP_Text)label).font = pass.ascentTitle.font;
			}
			((TMP_Text)label).enableAutoSizing = true;
			((TMP_Text)label).fontSizeMin = 10f;
			((TMP_Text)label).fontSizeMax = 15f;
			((TMP_Text)label).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)label).overflowMode = (TextOverflowModes)1;
			((TMP_Text)label).margin = new Vector4(8f, 0f, 8f, 0f);
			((Graphic)label).raycastTarget = false;
			val.transform.SetAsLastSibling();
			return val;
		}

		private static void Refresh(BoardingPass pass)
		{
			//IL_0073: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)switchButton == (Object)null) && !((Object)(object)dropperModeButton == (Object)null))
			{
				bool isCustomRun = RunSettings.IsCustomRun;
				switchButton.SetActive(!isCustomRun);
				bool flag = useDropperControls && !isCustomRun;
				dropperModeButton.SetActive(flag);
				MakeButtonUsable(switchButton);
				if (flag)
				{
					MakeButtonUsable(dropperModeButton);
				}
				SetButtonColor(switchButton, useDropperControls ? Yellow : Blue);
				SetButtonColor(dropperModeButton, Yellow);
				SetText(switchButtonText, GetFeatureButtonText());
				SetText(dropperModeButtonText, GetModeButtonText());
				if (!flag)
				{
					RestoreBoardingPassUi(pass);
				}
				else
				{
					ApplyDropperBoardingPassUi(pass);
				}
			}
		}

		private static void SetOriginalAscentButtons(BoardingPass pass, bool visible)
		{
			if ((Object)(object)pass.incrementAscentButton != (Object)null)
			{
				((Component)pass.incrementAscentButton).gameObject.SetActive(visible);
			}
			if ((Object)(object)pass.decrementAscentButton != (Object)null)
			{
				((Component)pass.decrementAscentButton).gameObject.SetActive(visible);
			}
		}

		private static void ApplyDropperBoardingPassUi(BoardingPass pass)
		{
			//IL_00b2: 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)
			if ((Object)(object)pass == (Object)null)
			{
				return;
			}
			peakLevelSelectHiddenByDropper = true;
			SetPeakLevelSelectVisible(visible: false);
			if (!dropperUiApplied)
			{
				dropperUiApplied = true;
				if ((Object)(object)pass.reward != (Object)null && !capturedRewardState)
				{
					capturedRewardState = true;
					defaultRewardActive = pass.reward.activeSelf;
				}
				if ((Object)(object)pass.customOptionsButton != (Object)null && !capturedCustomOptionsState)
				{
					capturedCustomOptionsState = true;
					defaultCustomOptionsActive = ((Component)pass.customOptionsButton).gameObject.activeSelf;
				}
				if (!capturedTextState)
				{
					capturedTextState = true;
					if ((Object)(object)pass.ascentTitle != (Object)null)
					{
						defaultAscentTitleText = pass.ascentTitle.text;
						defaultAscentTitleColor = ((Graphic)pass.ascentTitle).color;
					}
					if ((Object)(object)pass.ascentDesc != (Object)null)
					{
						defaultAscentDescText = pass.ascentDesc.text;
					}
				}
			}
			SetOriginalAscentButtons(pass, visible: true);
			ApplyDropperDescriptionLayout(pass);
			pass.ascentTitle.richText = true;
			pass.ascentTitle.text = GetModeTitle(pass);
			pass.ascentDesc.text = GetModeDescription();
			if ((Object)(object)pass.reward != (Object)null)
			{
				pass.reward.SetActive(false);
			}
			if ((Object)(object)pass.customOptionsButton != (Object)null)
			{
				((Component)pass.customOptionsButton).gameObject.SetActive(false);
			}
		}

		private static void RestoreBoardingPassUi(BoardingPass pass)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pass == (Object)null || !dropperUiApplied)
			{
				return;
			}
			RestoreDescriptionLayout(pass);
			SetOriginalAscentButtons(pass, visible: true);
			if (peakLevelSelectHiddenByDropper)
			{
				SetPeakLevelSelectVisible(visible: true);
				peakLevelSelectHiddenByDropper = false;
			}
			if (capturedRewardState && (Object)(object)pass.reward != (Object)null)
			{
				pass.reward.SetActive(defaultRewardActive);
			}
			if (capturedCustomOptionsState && (Object)(object)pass.customOptionsButton != (Object)null)
			{
				((Component)pass.customOptionsButton).gameObject.SetActive(defaultCustomOptionsActive);
			}
			if (capturedTextState)
			{
				if ((Object)(object)pass.ascentTitle != (Object)null)
				{
					pass.ascentTitle.text = defaultAscentTitleText;
					((Graphic)pass.ascentTitle).color = defaultAscentTitleColor;
				}
				if ((Object)(object)pass.ascentDesc != (Object)null)
				{
					pass.ascentDesc.text = defaultAscentDescText;
				}
				capturedTextState = false;
			}
			dropperUiApplied = false;
		}

		private static void ApplyDropperDescriptionLayout(BoardingPass pass)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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)
			if (!((Object)(object)pass == (Object)null) && !((Object)(object)pass.ascentDesc == (Object)null))
			{
				if (!capturedDescLayout)
				{
					capturedDescLayout = true;
					defaultDescAutoSizing = pass.ascentDesc.enableAutoSizing;
					defaultDescLineSpacing = pass.ascentDesc.lineSpacing;
					defaultDescParagraphSpacing = pass.ascentDesc.paragraphSpacing;
					defaultDescMargin = pass.ascentDesc.margin;
					defaultDescFontSizeMin = pass.ascentDesc.fontSizeMin;
					defaultDescFontSizeMax = pass.ascentDesc.fontSizeMax;
				}
				CaptureTitleLayout(pass);
				ApplyTitleLayout(pass);
				pass.ascentDesc.enableAutoSizing = true;
				pass.ascentDesc.lineSpacing = (DropperText.IsChinese ? 10f : 1f);
				pass.ascentDesc.paragraphSpacing = 0f;
				pass.ascentDesc.fontSizeMin = (DropperText.IsChinese ? defaultDescFontSizeMin : 22f);
				pass.ascentDesc.fontSizeMax = (DropperText.IsChinese ? defaultDescFontSizeMax : 29f);
				pass.ascentDesc.margin = (DropperText.IsChinese ? new Vector4(0f, 10f, 0f, 0f) : new Vector4(0f, 4f, 12f, 0f));
			}
		}

		private static void RestoreDescriptionLayout(BoardingPass pass)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (capturedDescLayout && !((Object)(object)pass == (Object)null) && !((Object)(object)pass.ascentDesc == (Object)null))
			{
				pass.ascentDesc.lineSpacing = defaultDescLineSpacing;
				pass.ascentDesc.paragraphSpacing = defaultDescParagraphSpacing;
				pass.ascentDesc.margin = defaultDescMargin;
				pass.ascentDesc.enableAutoSizing = defaultDescAutoSizing;
				pass.ascentDesc.fontSizeMin = defaultDescFontSizeMin;
				pass.ascentDesc.fontSizeMax = defaultDescFontSizeMax;
				RestoreTitleLayout();
			}
		}

		private static void CaptureTitleLayout(BoardingPass pass)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			if (!capturedTitleLayout && !((Object)(object)pass == (Object)null) && !((Object)(object)pass.ascentTitle == (Object)null))
			{
				ascentTitleRect = pass.ascentTitle.rectTransform;
				if (!((Object)(object)ascentTitleRect == (Object)null))
				{
					capturedTitleLayout = true;
					defaultAscentTitleAnchoredPosition = ascentTitleRect.anchoredPosition;
					defaultAscentTitleSizeDelta = ascentTitleRect.sizeDelta;
				}
			}
		}

		private static void ApplyTitleLayout(BoardingPass pass)
		{
			//IL_004d: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)pass?.ascentTitle == (Object)null) && !((Object)(object)ascentTitleRect == (Object)null))
			{
				if (DropperText.IsChinese)
				{
					ascentTitleRect.anchoredPosition = defaultAscentTitleAnchoredPosition;
					ascentTitleRect.sizeDelta = defaultAscentTitleSizeDelta;
				}
				else
				{
					ascentTitleRect.anchoredPosition = defaultAscentTitleAnchoredPosition + new Vector2(12f, 0f);
					ascentTitleRect.sizeDelta = new Vector2(defaultAscentTitleSizeDelta.x - 12f, defaultAscentTitleSizeDelta.y);
				}
			}
		}

		private static void RestoreTitleLayout()
		{
			//IL_001a: 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)
			if (capturedTitleLayout && !((Object)(object)ascentTitleRect == (Object)null))
			{
				ascentTitleRect.anchoredPosition = defaultAscentTitleAnchoredPosition;
				ascentTitleRect.sizeDelta = defaultAscentTitleSizeDelta;
			}
		}

		private static void SetPeakLevelSelectVisible(bool visible)
		{
			try
			{
				Type type = GetPeakLevelSelectPatchType();
				if (type == null)
				{
					return;
				}
				object? obj = AccessTools.Field(type, "dropDown")?.GetValue(null);
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(visible);
				}
				if (!(AccessTools.Property(type, "buttons")?.GetValue(null, null) is IEnumerable enumerable))
				{
					return;
				}
				foreach (object item in enumerable)
				{
					GameObject val2 = (GameObject)((item is GameObject) ? item : null);
					if (val2 != null)
					{
						val2.SetActive(visible);
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("PeakLevelSelect visibility refresh skipped: " + ex.Message));
			}
		}

		private static Type GetPeakLevelSelectPatchType()
		{
			if (checkedPeakLevelSelect)
			{
				return peakLevelSelectPatchType;
			}
			checkedPeakLevelSelect = true;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				peakLevelSelectPatchType = assemblies[i].GetType("PeakLevelSelect.GUIManagerPatch", throwOnError: false);
				if (peakLevelSelectPatchType != null)
				{
					break;
				}
			}
			return peakLevelSelectPatchType;
		}

		private static void SendDropperMode(BoardingPass pass, int mode)
		{
			try
			{
				ApplyDropperToggle(mode switch
				{
					-102 => 1, 
					-101 => 0, 
					_ => -1, 
				});
				TryAdvertiseSwitcherInstall();
				if ((Object)(object)pass == (Object)null || (Object)(object)pass.kiosk == (Object)null || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
				{
					SwitcherPlugin.Log.LogInfo((object)("Applied local Dropper mode without direct peer sync: " + mode));
					return;
				}
				PhotonView component = ((Component)pass.kiosk).GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null)
				{
					SwitcherPlugin.Log.LogInfo((object)("Applied local Dropper mode without kiosk PhotonView: " + mode));
					return;
				}
				int num = 0;
				Player[] playerListOthers = PhotonNetwork.PlayerListOthers;
				foreach (Player val in playerListOthers)
				{
					if (PlayerHasSwitcherInstalled(val))
					{
						component.RPC("LoadDropper", val, new object[1] { mode });
						num++;
					}
				}
				PhotonNetwork.SendAllOutgoingCommands();
				SwitcherPlugin.Log.LogInfo((object)("Applied local Dropper mode " + mode + " and sent direct sync to " + num + " installed peer(s)."));
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogError((object)("Failed to apply local Dropper mode: " + ex));
			}
		}

		private static void DisableDropperForVanillaStart(BoardingPass pass)
		{
			try
			{
				ApplyDropperToggle(-1);
				PublishDropperOffSelection();
				SendDropperMode(pass, -1);
				SwitcherPlugin.Log.LogInfo((object)"Published Dropper off state before vanilla start.");
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogWarning((object)("Failed to publish Dropper off state before vanilla start: " + ex.Message));
			}
		}

		private static void PublishDropperOffSelection()
		{
			//IL_0009: 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_0027: 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_003e: Expected O, but got Unknown
			try
			{
				if (CanPublishRoomSelection())
				{
					Hashtable val = new Hashtable
					{
						[(object)"DropperFix.Mode"] = -1,
						[(object)"DropperFix.PeakLevel"] = null,
						[(object)"DropperFix.PeakAscent"] = null
					};
					SetLocalPublishedMode(-1);
					PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
					PhotonNetwork.SendAllOutgoingCommands();
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Failed to publish Dropper off selection: " + ex.Message));
			}
		}

		private static void PublishRoomSelection(int mode)
		{
			//IL_0028: 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_0046: 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_0069: Expected O, but got Unknown
			try
			{
				if (mode == -101 || mode == -102)
				{
					ApplyDropperToggle((mode != -101) ? 1 : 0);
					if (CanPublishRoomSelection())
					{
						Hashtable val = new Hashtable
						{
							[(object)"DropperFix.Mode"] = mode,
							[(object)"DropperFix.PeakLevel"] = -2,
							[(object)"DropperFix.PeakAscent"] = -2
						};
						SetLocalPublishedMode(mode);
						PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
						PhotonNetwork.SendAllOutgoingCommands();
						SwitcherPlugin.Log.LogInfo((object)("Published Dropper host selection: mode=" + mode));
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogWarning((object)("Failed to publish host selection: " + ex.Message));
			}
		}

		private static void ClearPublishedRoomSelection()
		{
			//IL_0009: 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_0022: 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_0039: Expected O, but got Unknown
			try
			{
				if (CanPublishRoomSelection())
				{
					Hashtable val = new Hashtable
					{
						[(object)"DropperFix.Mode"] = null,
						[(object)"DropperFix.PeakLevel"] = null,
						[(object)"DropperFix.PeakAscent"] = null
					};
					PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
					PhotonNetwork.SendAllOutgoingCommands();
					SwitcherPlugin.Log.LogInfo((object)"Cleared Dropper host selection.");
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Failed to clear Dropper host selection: " + ex.Message));
			}
		}

		private static bool CanPublishRoomSelection()
		{
			if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
			{
				return PhotonNetwork.IsMasterClient;
			}
			return false;
		}

		internal static void OnJoinedRoom()
		{
			TryAdvertiseSwitcherInstall();
			ApplyRoomSelection("OnJoinedRoom");
			if (IsDropperModeActive())
			{
				ScheduleDropperSpawnRecovery("joined room");
			}
		}

		internal static void OnLeftRoom()
		{
			localPublishedMode = -9999;
			localPublishedModeExpiresAt = 0f;
			nextDropperSpawnRecoveryAt = 0f;
			dropperMapActivationRunning = false;
			dropperPlayerSpawnInFlight = false;
			dropperPlayerSpawnInFlightAt = 0f;
			loggedDuplicateDropperSpawnSuppression = false;
			dropperSpawnPointsReadyAt = 0f;
			lastDropperSpawnPointCount = 0;
			ApplyDropperToggle(-1);
		}

		internal static void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (propertiesThatChanged != null && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"DropperFix.Mode"))
			{
				ApplyRoomSelection("OnRoomPropertiesUpdate");
				if (IsDropperModeActive())
				{
					ScheduleDropperSpawnRecovery("room property update");
				}
			}
		}

		internal static void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
			if (targetPlayer == PhotonNetwork.LocalPlayer)
			{
				TryAdvertiseSwitcherInstall();
			}
		}

		internal static void OnPlayerEnteredRoom(Player newPlayer)
		{
			TryAdvertiseSwitcherInstall();
		}

		private static void ApplyRoomSelection(string source)
		{
			try
			{
				TryAdvertiseSwitcherInstall();
				TryPatchFogColdControl();
				if (TryGetFreshLocalPublishedMode(out var mode))
				{
					ApplyDropperToggle(mode switch
					{
						-102 => 1, 
						-101 => 0, 
						_ => -1, 
					});
					SwitcherPlugin.Log.LogInfo((object)$"Applied pending local Dropper selection from {source}: mode={mode}");
					if (mode == -101 || mode == -102)
					{
						ScheduleDropperMapActivation(source);
					}
				}
				else
				{
					if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
					{
						return;
					}
					Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
					if (customProperties == null)
					{
						return;
					}
					if (TryGetInt(customProperties, "DropperFix.Mode", out var value) && (value == -101 || value == -102 || value == -1))
					{
						ApplyDropperToggle(value switch
						{
							-102 => 1, 
							-101 => 0, 
							_ => -1, 
						});
						SwitcherPlugin.Log.LogInfo((object)$"Applied Dropper room selection from {source}: mode={value}");
						if (value == -101 || value == -102)
						{
							ScheduleDropperMapActivation(source);
						}
					}
					else
					{
						ApplyDropperToggle(-1);
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogWarning((object)("Failed to apply room selection: " + ex.Message));
			}
		}

		private static void TryPatchFogColdControl()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			if (fogColdControlPatched || checkedFogColdControl)
			{
				return;
			}
			checkedFogColdControl = true;
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				type = assemblies[i].GetType("FogColdControl.Plugin", throwOnError: false);
				if (type != null)
				{
					break;
				}
			}
			if (!(type == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, "StartFogMovement", (Type[])null, (Type[])null);
				if (!(methodInfo == null))
				{
					MethodInfo methodInfo2 = AccessTools.Method(typeof(BoardingPassSwitcher), "FogColdControl_StartFogMovement_Prefix", (Type[])null, (Type[])null);
					new Harmony("com.github.Beast.Dropper.PeakLevelSelectSwitcher.FogColdControl").Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					fogColdControlPatched = true;
					SwitcherPlugin.Log.LogInfo((object)"Patched Fog&ColdControl fog start for Dropper mode compatibility.");
				}
			}
		}

		private static void TryAdvertiseSwitcherInstall()
		{
			//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_0037: Expected O, but got Unknown
			try
			{
				if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null && !PlayerHasSwitcherInstalled(PhotonNetwork.LocalPlayer))
				{
					Hashtable val = new Hashtable { [(object)"DropperFix.SwitcherInstalled"] = true };
					PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
					PhotonNetwork.SendAllOutgoingCommands();
					if (!loggedInstallAdvertisement)
					{
						loggedInstallAdvertisement = true;
						SwitcherPlugin.Log.LogInfo((object)"Advertised Dropper switcher install state for safe peer sync.");
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Failed to advertise Dropper switcher install state: " + ex.Message));
			}
		}

		private static bool PlayerHasSwitcherInstalled(Player player)
		{
			try
			{
				Hashtable val = ((player != null) ? player.CustomProperties : null);
				if (val == null || !((Dictionary<object, object>)(object)val).ContainsKey((object)"DropperFix.SwitcherInstalled"))
				{
					return false;
				}
				object obj = val[(object)"DropperFix.SwitcherInstalled"];
				if (obj is bool result)
				{
					return result;
				}
				bool result2;
				return bool.TryParse(obj?.ToString(), out result2) && result2;
			}
			catch
			{
				return false;
			}
		}

		private static void SetLocalPublishedMode(int mode)
		{
			localPublishedMode = mode;
			localPublishedModeExpiresAt = Time.realtimeSinceStartup + 120f;
		}

		private static bool TryGetFreshLocalPublishedMode(out int mode)
		{
			mode = localPublishedMode;
			if (mode != -101 && mode != -102 && mode != -1)
			{
				return false;
			}
			if (Time.realtimeSinceStartup > localPublishedModeExpiresAt)
			{
				localPublishedMode = -9999;
				return false;
			}
			return true;
		}

		private static bool FogColdControl_StartFogMovement_Prefix()
		{
			if (!IsDropperModeActive())
			{
				return true;
			}
			LogDropperFogFreeze("Fog&ColdControl StartFogMovement");
			return false;
		}

		internal static bool IsDropperModeActive()
		{
			try
			{
				if (Plugin.PlayingDropperMap)
				{
					return true;
				}
				if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
				{
					return false;
				}
				Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
				int value;
				return customProperties != null && TryGetInt(customProperties, "DropperFix.Mode", out value) && (value == -101 || value == -102);
			}
			catch
			{
				return false;
			}
		}

		private static void FreezeOrbFog(OrbFogHandler fogHandler, string source)
		{
			if (!((Object)(object)fogHandler == (Object)null))
			{
				fogHandler.speed = 0f;
				fogHandler.isMoving = false;
				fogHandler.hasArrived = false;
				fogHandler.currentWaitTime = 0f;
				if (fogHandler.currentSize < 800f)
				{
					fogHandler.currentSize = 800f;
				}
				LogDropperFogFreeze("orb fog " + source);
			}
		}

		private static void FreezeLavaRising(LavaRising lavaRising, string source)
		{
			if (!((Object)(object)lavaRising == (Object)null))
			{
				lavaRising.started = false;
				lavaRising.ended = false;
				lavaRising.timeTraveled = 0f;
				lavaRising.secondsWaitedToStart = 0f;
				LogDropperLavaFreeze("lava rising " + source);
			}
		}

		private static void KeepDropperSpawnAlive(Character character)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				return;
			}
			character.data.dead = false;
			character.data.passedOut = false;
			character.data.fullyPassedOut = false;
			character.data.deathTimer = 0f;
			character.data.fallSeconds = 0f;
			character.data.sinceGrounded = 0f;
			CharacterRefs refs = character.refs;
			if (refs != null)
			{
				CharacterAfflictions afflictions = refs.afflictions;
				if (afflictions != null)
				{
					afflictions.ClearAllStatus(false);
				}
			}
		}

		private static int GetPlayerKey(Character character)
		{
			try
			{
				PhotonView val = (((Object)(object)character != (Object)null) ? ((Component)character).GetComponent<PhotonView>() : null);
				if ((Object)(object)val != (Object)null && val.ViewID != 0)
				{
					return val.ViewID;
				}
				if ((Object)(object)val != (Object)null && val.Owner != null)
				{
					return -val.Owner.ActorNumber;
				}
			}
			catch
			{
			}
			return 0;
		}

		private static void SetPlayerSpawnPointIndex(Character character, int index)
		{
			int playerKey = GetPlayerKey(character);
			if (playerKey != 0)
			{
				int num = Mathf.Clamp(index, 0, Mathf.Max(0, GetDropperSpawnPointCount() - 1));
				PlayerSpawnPointIndexes[playerKey] = num;
				if ((Object)(object)character != (Object)null && character.IsLocal)
				{
					SetDropperGlobalSpawnPointIndex(num);
				}
			}
		}

		private static int GetPlayerSpawnPointIndex(Character character)
		{
			int playerKey = GetPlayerKey(character);
			if (playerKey != 0 && PlayerSpawnPointIndexes.TryGetValue(playerKey, out var value))
			{
				return value;
			}
			if ((Object)(object)character != (Object)null && character.IsLocal)
			{
				return GetDropperGlobalSpawnPointIndex();
			}
			return 0;
		}

		private static int GetDropperGlobalSpawnPointIndex()
		{
			try
			{
				object obj = AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "CurrentSpawnPointIndex")?.GetValue(null);
				if (obj is int)
				{
					return (int)obj;
				}
			}
			catch
			{
			}
			return 0;
		}

		private static void SetDropperGlobalSpawnPointIndex(int index)
		{
			try
			{
				AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "CurrentSpawnPointIndex")?.SetValue(null, index);
			}
			catch
			{
			}
		}

		private static int GetDropperMaxSpawnPointIndex()
		{
			try
			{
				object obj = AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "MaxSpawnPointIndex")?.GetValue(null);
				if (obj is int)
				{
					return (int)obj;
				}
			}
			catch
			{
			}
			return Mathf.Max(0, GetDropperSpawnPointCount() - 1);
		}

		private static int GetDropperSpawnPointCount()
		{
			try
			{
				if (AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "spawnPoints")?.GetValue(null) is IList list)
				{
					return list.Count;
				}
			}
			catch
			{
			}
			return 1;
		}

		private static bool IsLocalPlayerAtDropperFinish()
		{
			if ((Object)(object)Character.localCharacter != (Object)null)
			{
				return IsPlayerAtDropperFinish(Character.localCharacter);
			}
			return false;
		}

		private static bool IsPlayerAtDropperFinish(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			return GetPlayerSpawnPointIndex(character) >= GetDropperMaxSpawnPointIndex();
		}

		private static void TryRunDropperUnPassOut(Character character)
		{
			try
			{
				AccessTools.Method(AccessTools.TypeByName("Dropper.HarmonyPatches"), "UnPassOut", (Type[])null, (Type[])null)?.Invoke(null, new object[1] { character });
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Dropper UnPassOut compatibility call skipped: " + ex.Message));
			}
		}

		private static bool HasResetBerry(Character character)
		{
			try
			{
				if (((character == null) ? null : character.player?.itemSlots) == null || (Object)(object)Plugin.ResetBerryItem == (Object)null)
				{
					return false;
				}
				ItemSlot[] itemSlots = character.player.itemSlots;
				foreach (ItemSlot val in itemSlots)
				{
					if (val != null && (Object)(object)val.prefab == (Object)(object)Plugin.ResetBerryItem)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static Character TryGetCharacterByPhotonId(int photonID)
		{
			try
			{
				PhotonView photonView = PhotonNetwork.GetPhotonView(photonID);
				return ((Object)(object)photonView != (Object)null) ? ((Component)photonView).GetComponent<Character>() : null;
			}
			catch
			{
				return null;
			}
		}

		private static void TryGiveResetBerryOnce(Character character)
		{
			if ((Object)(object)character == (Object)null || HasResetBerry(character))
			{
				return;
			}
			try
			{
				object? obj = AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "addItemScript")?.GetValue(null);
				AddItemInNetwork val = (AddItemInNetwork)((obj is AddItemInNetwork) ? obj : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)Plugin.ResetBerryItem == (Object)null))
				{
					PhotonView component = ((Component)character).GetComponent<PhotonView>();
					if (!((Object)(object)component == (Object)null))
					{
						val.AddItemIntoInventory((int)Plugin.ResetBerryItem.itemID, component.ViewID);
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("ResetBerry grant skipped: " + ex.Message));
			}
		}

		private static bool TryWarpLocalCharacterToDropperSpawn(Character character)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)character == (Object)null || !character.IsLocal)
				{
					return false;
				}
				if (!TryGetDropperSpawnPosition(character, out var position))
				{
					return false;
				}
				character.WarpPlayerRPC(position, true);
				return true;
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Dropper death warp skipped: " + ex.Message));
				return false;
			}
		}

		private static bool TryGetDropperSpawnPosition(Character character, out Vector3 position)
		{
			//IL_0001: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			position = default(Vector3);
			try
			{
				if (!(AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "spawnPoints")?.GetValue(null) is IList list) || list.Count == 0)
				{
					return false;
				}
				int num = Mathf.Clamp(GetPlayerSpawnPointIndex(character), 0, list.Count - 1);
				SetDropperGlobalSpawnPointIndex(num);
				object? obj = list[num];
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val == null)
				{
					return false;
				}
				position = val.position;
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static bool DropperSpawnPointsReadyForRecovery(float settleSeconds)
		{
			int dropperSpawnPointCount = GetDropperSpawnPointCount();
			if (dropperSpawnPointCount <= 0)
			{
				lastDropperSpawnPointCount = 0;
				dropperSpawnPointsReadyAt = 0f;
				return false;
			}
			if (dropperSpawnPointCount != lastDropperSpawnPointCount || dropperSpawnPointsReadyAt <= 0f)
			{
				lastDropperSpawnPointCount = dropperSpawnPointCount;
				dropperSpawnPointsReadyAt = Time.realtimeSinceStartup;
				return false;
			}
			return Time.realtimeSinceStartup - dropperSpawnPointsReadyAt >= settleSeconds;
		}

		private static void ScheduleDropperSpawnRecovery(string source)
		{
			if (!((Object)(object)SwitcherPlugin.Instance == (Object)null) && (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient) && (IsDropperModeActive() || Plugin.PlayingDropperMap))
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (!(realtimeSinceStartup < nextDropperSpawnRecoveryAt))
				{
					nextDropperSpawnRecoveryAt = realtimeSinceStartup + 0.5f;
					((MonoBehaviour)SwitcherPlugin.Instance).StartCoroutine(DropperSpawnRecoveryRoutine(source));
				}
			}
		}

		private static bool AllowDropperPlayerSpawnRpc(string source)
		{
			if (!IsDropperModeActive())
			{
				dropperPlayerSpawnInFlight = false;
				return true;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (dropperPlayerSpawnInFlight && realtimeSinceStartup - dropperPlayerSpawnInFlightAt > 8f)
			{
				dropperPlayerSpawnInFlight = false;
			}
			if ((Object)(object)Character.localCharacter != (Object)null || dropperPlayerSpawnInFlight)
			{
				ScheduleDropperSpawnRecovery("suppressed duplicate " + source);
				if (!loggedDuplicateDropperSpawnSuppression)
				{
					loggedDuplicateDropperSpawnSuppression = true;
					SwitcherPlugin.Log.LogInfo((object)"Suppressed duplicate vanilla player spawn RPC while Dropper mode is active.");
				}
				return false;
			}
			dropperPlayerSpawnInFlight = true;
			dropperPlayerSpawnInFlightAt = realtimeSinceStartup;
			return true;
		}

		[IteratorStateMachine(typeof(<DropperSpawnRecoveryRoutine>d__161))]
		private static IEnumerator DropperSpawnRecoveryRoutine(string source)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DropperSpawnRecoveryRoutine>d__161(0)
			{
				source = source
			};
		}

		private static void ScheduleDropperMapActivation(string source)
		{
			if (!((Object)(object)SwitcherPlugin.Instance == (Object)null) && IsDropperModeActive() && (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient) && !IsDropperMapBuilt() && !dropperMapActivationRunning && IsGameplaySceneForDropperBuild())
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (!(realtimeSinceStartup - lastDropperMapActivationAt < 1f))
				{
					lastDropperMapActivationAt = realtimeSinceStartup;
					dropperMapActivationRunning = true;
					((MonoBehaviour)SwitcherPlugin.Instance).StartCoroutine(DropperMapActivationRoutine(source));
				}
			}
		}

		[IteratorStateMachine(typeof(<DropperMapActivationRoutine>d__163))]
		private static IEnumerator DropperMapActivationRoutine(string source)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DropperMapActivationRoutine>d__163(0)
			{
				source = source
			};
		}

		private static bool IsDropperMapBuilt()
		{
			try
			{
				if (AccessTools.Field(AccessTools.TypeByName("Dropper.HarmonyPatches"), "spawnPoints")?.GetValue(null) is IList list && list.Count > 0)
				{
					foreach (object item in list)
					{
						Transform val = (Transform)((item is Transform) ? item : null);
						if (val != null && (Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy)
						{
							return true;
						}
					}
				}
				return (Object)(object)GameObject.Find("Spawn Points Modding") != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		private static bool IsGameplaySceneForDropperBuild()
		{
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && localCharacter.inAirport)
				{
					return false;
				}
				return GameHandler.IsOnIsland || GameHandler.IsInGameplayScene;
			}
			catch
			{
				return false;
			}
		}

		private static bool ShouldRecoverDropperSpawn()
		{
			if (!IsDropperModeActive())
			{
				return false;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && localCharacter.inAirport)
			{
				return false;
			}
			if (Plugin.PlayingDropperMap)
			{
				return true;
			}
			try
			{
				return GameHandler.IsOnIsland || GameHandler.IsInGameplayScene;
			}
			catch
			{
				return false;
			}
		}

		[IteratorStateMachine(typeof(<WarpLocalCharacterToDropperSpawnWhenReady>d__167))]
		private static IEnumerator WarpLocalCharacterToDropperSpawnWhenReady(Character character)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WarpLocalCharacterToDropperSpawnWhenReady>d__167(0)
			{
				character = character
			};
		}

		private static void LogDropperFogFreeze(string source)
		{
			if (!loggedDropperFogFreeze)
			{
				loggedDropperFogFreeze = true;
				SwitcherPlugin.Log.LogInfo((object)("Frozen fog movement for Dropper mode via " + source + "."));
			}
		}

		private static void LogDropperLavaFreeze(string source)
		{
			if (!loggedDropperLavaFreeze)
			{
				loggedDropperLavaFreeze = true;
				SwitcherPlugin.Log.LogInfo((object)("Frozen lava movement for Dropper mode via " + source + "."));
			}
		}

		private static bool TryGetInt(Hashtable table, string key, out int value)
		{
			value = 0;
			if (!((Dictionary<object, object>)(object)table).ContainsKey((object)key))
			{
				return false;
			}
			object obj = table[(object)key];
			if (obj is int num)
			{
				value = num;
				return true;
			}
			if (obj is short num2)
			{
				value = num2;
				return true;
			}
			if (obj is byte b)
			{
				value = b;
				return true;
			}
			return int.TryParse(obj?.ToString(), out value);
		}

		private static void SyncPeakLevelSelectFromLocal(out int selectedLevel, out int selectedAscent)
		{
			selectedLevel = GetPeakLevelSelectValue("SelectedLevel", -2);
			selectedAscent = GetPeakLevelSelectValue("SelectedAscent", -2);
		}

		private static int GetPeakLevelSelectValue(string propertyName, int fallback)
		{
			object obj = GetPeakLevelSelectPluginType()?.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
			object obj2 = obj?.GetType().GetProperty("Value")?.GetValue(obj, null);
			if (obj2 is int)
			{
				return (int)obj2;
			}
			return fallback;
		}

		private static void SetPeakLevelSelectValue(string propertyName, int value)
		{
			if (value != -9999)
			{
				object obj = GetPeakLevelSelectPluginType()?.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
				obj?.GetType().GetProperty("Value")?.SetValue(obj, value, null);
			}
		}

		private static void ClearPeakLevelSelectSelection()
		{
			ForceSetPeakLevelSelectValue("SelectedLevel", -2);
			ForceSetPeakLevelSelectValue("SelectedAscent", -2);
		}

		private static void ForceSetPeakLevelSelectValue(string propertyName, int value)
		{
			try
			{
				object obj = GetPeakLevelSelectPluginType()?.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
				obj?.GetType().GetProperty("Value")?.SetValue(obj, value, null);
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("PeakLevelSelect reset skipped for " + propertyName + ": " + ex.Message));
			}
		}

		private static Type GetPeakLevelSelectPluginType()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType("PeakLevelSelect.PeakLevelSelectPlugin", throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private static void SetButtonColor(GameObject button, Color color)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Image component = button.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = color;
				((Graphic)component).raycastTarget = true;
			}
		}

		private static void MakeButtonUsable(GameObject button)
		{
			if ((Object)(object)button == (Object)null)
			{
				return;
			}
			Button component = button.GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				((Selectable)component).interactable = true;
			}
			Image component2 = button.GetComponent<Image>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Graphic)component2).raycastTarget = true;
				if ((Object)(object)component != (Object)null)
				{
					((Selectable)component).targetGraphic = (Graphic)(object)component2;
				}
			}
			button.transform.SetAsLastSibling();
		}

		private static void ApplyDropperToggle(int mode)
		{
			Plugin.ToggleModpack(mode);
			if (mode == 0 || mode == 1)
			{
				EnsureDropperRuntimeCompatibilityPatches();
			}
		}

		private static void EnsureDropperRuntimeCompatibilityPatches()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Character), "RPCA_PassOut", (Type[])null, (Type[])null);
				Patches val = ((methodInfo != null) ? Harmony.GetPatchInfo((MethodBase)methodInfo) : null);
				if (val == null)
				{
					return;
				}
				Harmony val2 = new Harmony("com.github.Beast.Dropper.PeakLevelSelectSwitcher.DropperRuntimeFixes");
				foreach (Patch prefix in val.Prefixes)
				{
					MethodInfo patchMethod = prefix.PatchMethod;
					if (prefix.owner == "com.github.Beast.Dropper.runtime" && patchMethod != null && patchMethod.DeclaringType != null && patchMethod.DeclaringType.FullName == "Dropper.HarmonyPatches" && patchMethod.Name == "Character_RPCA_PassOut_Prefix")
					{
						val2.Unpatch((MethodBase)methodInfo, patchMethod);
						if (!loggedDropperPassOutUnpatch)
						{
							loggedDropperPassOutUnpatch = true;
							SwitcherPlugin.Log.LogInfo((object)"Replaced Dropper global pass-out respawn with per-player DropperFix respawn.");
						}
					}
				}
			}
			catch (Exception ex)
			{
				SwitcherPlugin.Log.LogDebug((object)("Dropper pass-out runtime patch cleanup skipped: " + ex.Message));
			}
		}

		private static void SetText(TextMeshProUGUI label, string text)
		{
			if ((Object)(object)label != (Object)null)
			{
				((TMP_Text)label).text = text;
			}
		}

		private static string GetFeatureButtonText()
		{
			if (!useDropperControls)
			{
				return DropperText.Choose("Default", "原版");
			}
			return DropperText.Choose("Dropper", "坠落");
		}

		private static string GetModeButtonText()
		{
			if (dropperMode != 0)
			{
				return DropperText.Choose("Descend", "下降");
			}
			return DropperText.Choose("Classic", "经典");
		}

		private static string GetModeTitle(BoardingPass pass)
		{
			string text = ((dropperMode == 0) ? DropperText.Choose("Dropper", "坠落挑战") : DropperText.Choose("Dropper - Descent", "坠落挑战 - 下降"));
			string currentAscentTitle = GetCurrentAscentTitle(pass);
			if (string.IsNullOrEmpty(currentAscentTitle))
			{
				return text;
			}
			return text + " <size=60%>" + currentAscentTitle + "</size>";
		}

		private static string GetCurrentAscentTitle(BoardingPass pass)
		{
			try
			{
				if (pass?.ascentData?.ascents == null)
				{
					return string.Empty;
				}
				int num = pass.ascentIndex + 2;
				if (num < 0 || num >= pass.ascentData.ascents.Count)
				{
					return string.Empty;
				}
				return pass.ascentData.ascents[num].localizedTitle ?? string.Empty;
			}
			catch
			{
				return string.Empty;
			}
		}

		private static string GetModeDescription()
		{
			if (dropperMode != 0)
			{
				return DropperText.Choose("Climb and parkour down in stages\ninstead of dropping straight down.", "下降模式:不再直接坠到底部,\n需要分段攀爬和跑酷向下推进。");
			}
			return DropperText.Choose("Jump from high platforms, survive,\nthen take the portal to the next drop.", "坠落模式:从高处平台跳下,\n存活后通过传送门进入下一段。");
		}
	}
}