Decompiled source of AdjustablePortals v0.7.0

plugins/AdjustablePortals.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using AdjustablePortals.common;
using AdjustablePortals.modules;
using AdjustablePortals.ui;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Splatform;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AdjustablePortals")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AdjustablePortals")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.7.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.7.0.0")]
namespace AdjustablePortals
{
	[BepInPlugin("MidnightsFX.AdjustablePortals", "AdjustablePortals", "0.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class AdjustablePortals : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.AdjustablePortals";

		public const string PluginName = "AdjustablePortals";

		public const string PluginVersion = "0.7.0";

		internal static Harmony Harmony = new Harmony("MidnightsFX.AdjustablePortals");

		public static CustomLocalization Localization;

		internal static ManualLogSource Log;

		internal static AdjustablePortals Instance;

		public void Awake()
		{
			Localization = LocalizationManager.Instance.GetLocalization();
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			new ValConfig(((BaseUnityPlugin)this).Config);
			TeleportItems.SetupTeleportLists();
			Compatibility.CheckModCompat();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Harmony.PatchAll(executingAssembly);
			Compatibility.TargetPortalCompat();
			Compatibility.BackpacksCompat();
		}

		public void Update()
		{
			Compatibility.RefreshStaleBackpacks();
			PortalTargeting.Update();
		}
	}
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void setDebugLogging(bool state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (state)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				AdjustablePortals.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				AdjustablePortals.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				AdjustablePortals.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				AdjustablePortals.Log.LogError((object)message);
			}
		}
	}
	internal class ValConfig
	{
		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<float> PortalPieceActivationDistance;

		public static ConfigEntry<int> PortalNearbyPiecesForActivation;

		public static ConfigEntry<string> DefeatedEikthyrAllowedItems;

		public static ConfigEntry<string> DefeatedElderAllowedItems;

		public static ConfigEntry<string> DefeatedBonemassAllowedItems;

		public static ConfigEntry<string> DefeatedModerAllowItems;

		public static ConfigEntry<string> DefeatedYagluthAllowItems;

		public static ConfigEntry<string> DefeatedQueenAllowItems;

		public static ConfigEntry<string> DefeatedFaderAllowItems;

		public static ConfigEntry<string> NonTeleportableItems;

		public static ConfigEntry<bool> UsePrivateKeys;

		public static ConfigEntry<bool> EnablePortalPieceRequirements;

		public static ConfigEntry<bool> EnablePortalRequireFuel;

		public static ConfigEntry<int> PortalFuelUsagesPerBatch;

		public static ConfigEntry<int> PortalFuelBatchSize;

		public static ConfigEntry<string> PortalFuelPrefab;

		public static ConfigEntry<bool> EnableTeleportMounts;

		public static ConfigEntry<bool> EnableTeleportTames;

		public static ConfigEntry<float> TeleportTamesRadius;

		public static ConfigEntry<int> TeleportTamesMaxCount;

		public static ConfigEntry<bool> TeleportTamesRequireFollowing;

		public static ConfigEntry<bool> EnableTeleportCarts;

		public static ConfigEntry<bool> ReattachCartAfterTeleport;

		public static ConfigEntry<PortalTargeting.TargetingMode> PortalTargetingMode;

		private static FileSystemWatcher configWatcher;

		public ValConfig(ConfigFile cf)
		{
			cfg = cf;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(cf);
			Logger.setDebugLogging(EnableDebugMode.Value);
			SetupMainFileWatcher();
			SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
		}

		private static void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs e)
		{
			if (e.UpdatedPluginGUIDs != null && e.UpdatedPluginGUIDs.Contains("MidnightsFX.AdjustablePortals"))
			{
				Logger.LogInfo("Server configuration applied (" + (e.InitialSynchronization ? "on join" : "update") + "). Nearby pieces required: " + (EnablePortalPieceRequirements.Value ? PortalNearbyPiecesForActivation.Value.ToString() : "off") + ", " + $"fuel required: {EnablePortalRequireFuel.Value}, private keys: {UsePrivateKeys.Value}, " + $"portal targeting: {PortalTargetingMode.Value}.");
			}
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//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_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.enableDebugLogging;
			EnablePortalPieceRequirements = BindServerConfig("PortalActivation", "EnablePortalPieceRequirements", value: true, "When enabled, portals require a set number of building pieces around them in order to activate");
			PortalNearbyPiecesForActivation = BindServerConfig("PortalActivation", "PortalNearbyPiecesForActivation", 300, "The number of building pieces required nearby in order for a portal to be activated.", advanced: false, 0, 10000);
			PortalPieceActivationDistance = BindServerConfig("PortalActivation", "PortalPieceActivationDistance", 100f, "The distance that will be checked for nearby building pieces to meet the required structures nearby.");
			EnablePortalRequireFuel = BindServerConfig("PortalActivation", "EnablePortalRequireFuel", value: false, "When enabled, portals require a fuel item to teleport users");
			PortalFuelUsagesPerBatch = BindServerConfig("PortalActivation", "PortalFuelUsagesPerBatch", 20, "The number of usages that one batch of the fuel type provides");
			PortalFuelBatchSize = BindServerConfig("PortalActivation", "PortalFuelBatchSize", 1, "The number of the portal fuel required for activation.");
			PortalFuelPrefab = BindServerConfig("PortalActivation", "PortalFuelPrefab", "SurtlingCore", "The prefab name that will be used for the portal costs.");
			EnableTeleportMounts = BindServerConfig("PortalCompanions", "EnableTeleportMounts", value: true, "When enabled, a player riding a mount into a portal takes the mount with them and is put back in the saddle on arrival.");
			EnableTeleportTames = BindServerConfig("PortalCompanions", "EnableTeleportTames", value: true, "When enabled, tamed creatures near the portal travel with the player to the destination.");
			TeleportTamesRadius = BindServerConfig("PortalCompanions", "TeleportTamesRadius", 5f, "The distance around the portal that tamed creatures are collected from.", advanced: false, 0f, 50f);
			TeleportTamesMaxCount = BindServerConfig("PortalCompanions", "TeleportTamesMaxCount", 5, "The most tamed creatures that one teleport will take along. The closest to the portal go first.", advanced: false, 0, 50);
			TeleportTamesRequireFollowing = BindServerConfig("PortalCompanions", "TeleportTamesRequireFollowing", value: true, "When enabled, only tames that have been told to follow the teleporting player travel with them. Turn this off to take every tame standing near the portal, penned livestock included.");
			EnableTeleportCarts = BindServerConfig("PortalCompanions", "EnableTeleportCarts", value: true, "When enabled, a cart the player is pulling travels with them. The cart may only hold items that the player themselves could teleport with, and blocks the teleport otherwise.");
			ReattachCartAfterTeleport = BindServerConfig("PortalCompanions", "ReattachCartAfterTeleport", value: true, "When enabled, a cart that travelled through a portal is hitched back up on arrival instead of being left loose at the destination.", null, advanced: true);
			PortalTargetingMode = BindServerConfig("PortalTargeting", "PortalTargetingMode", PortalTargeting.TargetingMode.Vanilla, "How a player chooses where a portal sends them. Vanilla: portals connect to the portal with the same name. SelectFromList: stepping into a portal opens a list of every other portal to pick from. SelectOnMap: stepping into a portal opens the map with every other portal marked on it - when the map is disabled this uses SelectInSpace instead. SelectInSpace: stepping into a portal shows every other portal at its rough position against a starfield rather than the map, so it works without a map. In every mode but Vanilla, a portal is only offered as a destination once it has the nearby building pieces it needs to activate itself. Ignored while the TargetPortal mod is installed, which has its own map.");
			PortalTargetingMode.SettingChanged += PortalTargeting.TargetingModeChanged;
			UsePrivateKeys = BindServerConfig("PortalProgression", "UsePrivateKeys", value: false, "When enabled, the items below unlock for each player by the bosses that player has helped defeat, instead of by the bosses defeated anywhere in the world. Every player who landed a hit on a boss is credited with it when it dies.");
			UsePrivateKeys.SettingChanged += TeleportItems.ProgressionKeySourceChanged;
			DefeatedEikthyrAllowedItems = BindServerConfig("PortalProgression", "DefeatedEikthyrAllowedItems", "", "Comma seperated list of prefab items that will be allowed to teleported once Eikthyr is defeated.");
			DefeatedEikthyrAllowedItems.SettingChanged += TeleportItems.EikthyrAllowedTeleportsChanged;
			DefeatedElderAllowedItems = BindServerConfig("PortalProgression", "DefeatedElderAllowedItems", "", "Comma seperated list of prefab items that will be allowed to be teleported once The Elder is defeated.");
			DefeatedElderAllowedItems.SettingChanged += TeleportItems.ElderAllowedTeleportsChanged;
			DefeatedBonemassAllowedItems = BindServerConfig("PortalProgression", "DefeatedBonemassAllowedItems", "Bronze,Copper,Tin,CopperOre,TinOre,BronzeScrap,CopperScrap", "Comma seperated list of prefab items that will be allowed to be teleported once Bonemass is defeated.");
			DefeatedBonemassAllowedItems.SettingChanged += TeleportItems.BonemassAllowedTeleportsChanged;
			DefeatedModerAllowItems = BindServerConfig("PortalProgression", "DefeatedModerAllowItems", "Iron,IronOre,Ironpit,IronScrap,chest_hildir1,chest_hildir2,chest_hildir3", "Comma seperated list of prefab items that will be allowed to be teleported once Moder is defeated.");
			DefeatedModerAllowItems.SettingChanged += TeleportItems.ModerAllowedTeleportsChanged;
			DefeatedYagluthAllowItems = BindServerConfig("PortalProgression", "DefeatedYagluthAllowItems", "Silver,SilverOre,DragonEgg", "Comma seperated list of prefab items that will be allowed to be teleported once Yagluth is defeated.");
			DefeatedYagluthAllowItems.SettingChanged += TeleportItems.YagluthAllowedTeleportsChanged;
			DefeatedQueenAllowItems = BindServerConfig("PortalProgression", "DefeatedQueenAllowItems", "MechanicalSpring,BlackMetal,BlackMetalScrap", "Comma seperated list of prefab items that will be allowed to be teleported once The Seeker Queen is defeated.");
			DefeatedQueenAllowItems.SettingChanged += TeleportItems.QueenAllowedTeleportsChanged;
			DefeatedFaderAllowItems = BindServerConfig("PortalProgression", "DefeatedFaderAllowItems", "DvergrNeedle", "Comma seperated list of prefab items that will be allowed to be teleported once Fader is defeated.");
			DefeatedFaderAllowItems.SettingChanged += TeleportItems.FaderAllowedTeleportsChanged;
			NonTeleportableItems = BindServerConfig("PortalProgression", "NonTeleportableItems", "", "Comma seperated list of prefab items that may never be teleported, whatever bosses have been defeated. This applies everywhere, including portals and world settings that would otherwise let every item through.");
			NonTeleportableItems.SettingChanged += TeleportItems.NonTeleportableItemsChanged;
		}

		internal static void SetupMainFileWatcher()
		{
			configWatcher = new FileSystemWatcher();
			configWatcher.NotifyFilter = NotifyFilters.LastWrite;
			configWatcher.Path = Path.GetDirectoryName(cfg.ConfigFilePath);
			configWatcher.Filter = Path.GetFileName(cfg.ConfigFilePath);
			configWatcher.Changed += OnConfigFileChanged;
			configWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			configWatcher.EnableRaisingEvents = true;
		}

		private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				Logger.LogInfo("Configuration file has been changed, reloading settings.");
				cfg.Reload();
			}
		}

		public static ConfigEntry<List<string>> BindServerConfig(string catagory, string key, List<string> value, string description, bool advanced = false)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return cfg.Bind<List<string>>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float[]> BindServerConfig(string catagory, string key, float[] value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float[]>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<int> BindServerConfig(string catagory, string key, int value, string description, bool advanced = false, int valmin = 0, int valmax = 150)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<int>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<T> BindServerConfig<T>(string catagory, string key, T value, string description, bool advanced = false) where T : struct, Enum
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			return cfg.Bind<T>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
}
namespace AdjustablePortals.ui
{
	internal static class PickerUI
	{
		internal const float TitleHeight = 34f;

		internal static readonly Color OverlayColor = new Color(0f, 0f, 0f, 0.35f);

		private static readonly Vector3[] itemCorners = (Vector3[])(object)new Vector3[4];

		private static readonly Vector3[] viewportCorners = (Vector3[])(object)new Vector3[4];

		internal static GameObject NewUI(string name, Transform parent, params Type[] components)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			GameObject val = new GameObject(name, components)
			{
				layer = 5
			};
			if ((Object)(object)val.GetComponent<RectTransform>() == (Object)null)
			{
				val.AddComponent<RectTransform>();
			}
			val.transform.SetParent(parent, false);
			return val;
		}

		internal static RectTransform NewRect(string name, Transform parent, float x, float y, float w, float h)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0023: Expected O, but got Unknown
			RectTransform val = (RectTransform)NewUI(name, parent).transform;
			PlaceTopLeft(val, x, y, w, h);
			return val;
		}

		internal static void PlaceTopLeft(RectTransform rt, float x, float y, float w, float h)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = new Vector2(0f, 1f);
			rt.anchorMax = new Vector2(0f, 1f);
			rt.pivot = new Vector2(0f, 1f);
			rt.sizeDelta = new Vector2(w, h);
			rt.anchoredPosition = new Vector2(x, 0f - y);
		}

		internal static GameObject CreateOverlay(string name, out PickerWindow window)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005e: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			window = null;
			if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return null;
			}
			GameObject val = NewUI(name, GUIManager.CustomGUIFront.transform, typeof(Image));
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			((Graphic)val.GetComponent<Image>()).color = OverlayColor;
			Button obj = val.AddComponent<Button>();
			((Selectable)obj).transition = (Transition)0;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj).navigation = navigation;
			((UnityEvent)obj.onClick).AddListener(new UnityAction(PortalTargeting.Cancel));
			window = val.AddComponent<PickerWindow>();
			return val;
		}

		internal static GameObject CreatePanel(Transform parent, float w, float h, string title)
		{
			//IL_0010: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateWoodpanel(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, w, h, false);
			AddText(obj.transform, 0f, 14f, w, 34f, title, 22, (TextAnchor)4, GUIManager.Instance.ValheimYellow);
			return obj;
		}

		internal static Text AddText(Transform parent, float x, float y, float w, float h, string text, int fontSize, TextAnchor anchor, Color? color = null)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_004b: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateText(text, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), GUIManager.Instance.AveriaSerifBold, fontSize, (Color)(((??)color) ?? GUIManager.Instance.ValheimBeige), true, Color.black, w, h, false);
			PlaceTopLeft((RectTransform)obj.transform, x, y, w, h);
			Text component = obj.GetComponent<Text>();
			component.alignment = anchor;
			component.supportRichText = false;
			((Graphic)component).raycastTarget = false;
			component.horizontalOverflow = (HorizontalWrapMode)0;
			component.verticalOverflow = (VerticalWrapMode)0;
			return component;
		}

		internal static GameObject NewLayoutRow(Transform content, float width, float height)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			GameObject obj = NewUI("Row", content, typeof(RectTransform), typeof(LayoutElement));
			PlaceTopLeft((RectTransform)obj.transform, 0f, 0f, width, height);
			LayoutElement component = obj.GetComponent<LayoutElement>();
			component.minHeight = height;
			component.preferredHeight = height;
			component.minWidth = width;
			component.preferredWidth = width;
			return obj;
		}

		internal static void KeepInView(ScrollRect scroll, RectTransform item)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)scroll == (Object)null) && !((Object)(object)scroll.content == (Object)null) && !((Object)(object)item == (Object)null))
			{
				object obj = (((Object)(object)scroll.viewport != (Object)null) ? ((object)scroll.viewport) : ((object)(RectTransform)((Component)scroll).transform));
				item.GetWorldCorners(itemCorners);
				((RectTransform)obj).GetWorldCorners(viewportCorners);
				float num = itemCorners[1].y - viewportCorners[1].y;
				float num2 = viewportCorners[0].y - itemCorners[0].y;
				if (num > 0f)
				{
					RectTransform content = scroll.content;
					((Transform)content).position = ((Transform)content).position - new Vector3(0f, num, 0f);
				}
				else if (num2 > 0f)
				{
					RectTransform content2 = scroll.content;
					((Transform)content2).position = ((Transform)content2).position + new Vector3(0f, num2, 0f);
				}
			}
		}

		internal static Button AddButton(Transform parent, float x, float y, float w, float h, string text, UnityAction onClick)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_004b: Expected O, but got Unknown
			GameObject obj = GUIManager.Instance.CreateButton(text, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), w, h);
			PlaceTopLeft((RectTransform)obj.transform, x, y, w, h);
			Button component = obj.GetComponent<Button>();
			if (onClick != null)
			{
				((UnityEvent)component.onClick).AddListener(onClick);
			}
			return component;
		}

		internal static InputField AddTextField(Transform parent, float x, float y, float w, float h, string placeholder)
		{
			//IL_0010: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			GameObject obj = GUIManager.Instance.CreateInputField(parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(x, 0f - y), (ContentType)0, placeholder, 16, w, h);
			PlaceTopLeft((RectTransform)obj.transform, x, y, w, h);
			return obj.GetComponent<InputField>();
		}

		internal static Sprite PortalIcon(int prefabHash)
		{
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			Sprite val = PieceIcon(instance.GetPrefab(prefabHash));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return PieceIcon(instance.GetPrefab("portal_wood"));
		}

		private static Sprite PieceIcon(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			Piece component = prefab.GetComponent<Piece>();
			if (!((Object)(object)component != (Object)null))
			{
				return null;
			}
			return component.m_icon;
		}
	}
	internal class PickerWindow : MonoBehaviour
	{
		internal const float InputDelaySeconds = 0.3f;

		internal Action Dismissed;

		private float openedAt;

		private bool holdingInput;

		internal bool AcceptingInput => Time.unscaledTime - openedAt >= 0.3f;

		private void Awake()
		{
			openedAt = Time.unscaledTime;
			holdingInput = true;
			GUIManager.BlockInput(true);
		}

		private void Update()
		{
			if (AcceptingInput && !Console.IsVisible() && (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB")))
			{
				ZInput.ResetButtonStatus("JoyButtonB");
				PortalTargeting.Cancel();
			}
		}

		private void OnDestroy()
		{
			if (holdingInput)
			{
				holdingInput = false;
				GUIManager.BlockInput(false);
			}
			Action dismissed = Dismissed;
			Dismissed = null;
			dismissed?.Invoke();
		}
	}
	internal class PortalListPicker : MonoBehaviour
	{
		private const float PanelWidth = 480f;

		private const float PanelHeight = 600f;

		private const float Margin = 20f;

		private const float FilterTop = 56f;

		private const float FilterHeight = 30f;

		private const float ListTop = 96f;

		private const float FooterHeight = 64f;

		private const float RowHeight = 34f;

		private const float ButtonWidth = 140f;

		private const float ButtonHeight = 36f;

		private const int MaxRows = 300;

		private static PortalListPicker current;

		private PickerWindow window;

		private List<PortalTargeting.Destination> destinations;

		private InputField filter;

		private ScrollRect scroll;

		private Transform content;

		private float contentWidth;

		private readonly List<Button> rows = new List<Button>();

		private PortalTargeting.Destination firstShown;

		private GameObject lastSelected;

		internal static bool Open(TeleportWorld source, List<PortalTargeting.Destination> destinations)
		{
			Close();
			PickerWindow pickerWindow;
			GameObject val = PickerUI.CreateOverlay("AJP_PortalListPicker", out pickerWindow);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			pickerWindow.Dismissed = PortalTargeting.Cancel;
			current = val.AddComponent<PortalListPicker>();
			current.window = pickerWindow;
			current.Build(destinations);
			return true;
		}

		internal static void Close()
		{
			if (!((Object)(object)current == (Object)null))
			{
				PortalListPicker portalListPicker = current;
				current = null;
				portalListPicker.window.Dismissed = null;
				Object.Destroy((Object)(object)((Component)portalListPicker).gameObject);
			}
		}

		private void Build(List<PortalTargeting.Destination> list)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			destinations = new List<PortalTargeting.Destination>(list);
			destinations.Sort(delegate(PortalTargeting.Destination a, PortalTargeting.Destination b)
			{
				int num3 = string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
				return (num3 == 0) ? a.Distance.CompareTo(b.Distance) : num3;
			});
			GameObject val = PickerUI.CreatePanel(((Component)this).transform, 480f, 600f, "Choose a destination");
			float num = 440f;
			filter = PickerUI.AddTextField(val.transform, 20f, 56f, num, 30f, "Filter...");
			((UnityEvent<string>)(object)filter.onValueChanged).AddListener((UnityAction<string>)Rebuild);
			((UnityEvent<string>)(object)filter.onEndEdit).AddListener((UnityAction<string>)SubmitFilter);
			float num2 = 440f;
			RectTransform val2 = PickerUI.NewRect("ScrollHolder", val.transform, 20f, 96f, num, num2);
			GameObject val3 = GUIManager.Instance.CreateScrollView((Transform)(object)val2, false, true, 8f, 4f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.5f), num, num2);
			content = val3.transform.Find("Scroll View/Viewport/Content");
			scroll = val3.GetComponentInChildren<ScrollRect>();
			if ((Object)(object)scroll != (Object)null)
			{
				scroll.scrollSensitivity = 200f;
			}
			contentWidth = num - 16f;
			PickerUI.AddButton(val.transform, 170f, 548f, 140f, 36f, "Cancel", new UnityAction(PortalTargeting.Cancel));
			Rebuild("");
			if (ZInput.IsGamepadActive())
			{
				SelectFirstRow();
			}
			else
			{
				filter.ActivateInputField();
			}
		}

		private void Rebuild(string needle)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)content == (Object)null)
			{
				return;
			}
			foreach (Transform item in content)
			{
				((Component)item).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			rows.Clear();
			firstShown = null;
			int num = 0;
			foreach (PortalTargeting.Destination destination in destinations)
			{
				if (!string.IsNullOrEmpty(needle) && destination.Name.IndexOf(needle, StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				if (rows.Count >= 300)
				{
					num++;
					continue;
				}
				if (firstShown == null)
				{
					firstShown = destination;
				}
				rows.Add(AddRow(destination));
			}
			if (rows.Count == 0)
			{
				AddNote("No portals match.");
			}
			else if (num > 0)
			{
				AddNote($"... {num} more, type to narrow the list.");
			}
			if (ZInput.IsGamepadActive())
			{
				SelectFirstRow();
			}
		}

		private Button AddRow(PortalTargeting.Destination destination)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = PickerUI.NewLayoutRow(content, contentWidth, 34f);
			float h = 32f;
			Button obj2 = PickerUI.AddButton(obj.transform, 0f, 0f, contentWidth, h, "", (UnityAction)delegate
			{
				Pick(destination);
			});
			float num = contentWidth * 0.62f;
			PickerUI.AddText(((Component)obj2).transform, 10f, 0f, num - 10f, h, destination.Name, 16, (TextAnchor)3);
			PickerUI.AddText(((Component)obj2).transform, num, 0f, contentWidth - num - 10f, h, destination.DistanceText, 14, (TextAnchor)5, GUIManager.Instance.ValheimOrange);
			return obj2;
		}

		private void AddNote(string text)
		{
			PickerUI.AddText(PickerUI.NewLayoutRow(content, contentWidth, 34f).transform, 10f, 0f, contentWidth - 20f, 34f, text, 14, (TextAnchor)3);
		}

		private void Pick(PortalTargeting.Destination destination)
		{
			if (!((Object)(object)window == (Object)null) && window.AcceptingInput)
			{
				PortalTargeting.TravelTo(destination);
			}
		}

		private void SubmitFilter(string text)
		{
			if (firstShown != null && (ZInput.GetKeyDown((KeyCode)13, true) || ZInput.GetKeyDown((KeyCode)271, true)))
			{
				Pick(firstShown);
			}
		}

		private void SelectFirstRow()
		{
			if (rows.Count != 0 && !((Object)(object)EventSystem.current == (Object)null))
			{
				EventSystem.current.SetSelectedGameObject(((Component)rows[0]).gameObject);
			}
		}

		private void Update()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			if ((Object)(object)EventSystem.current == (Object)null)
			{
				return;
			}
			GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
			if (!((Object)(object)currentSelectedGameObject == (Object)(object)lastSelected))
			{
				lastSelected = currentSelectedGameObject;
				if ((Object)(object)currentSelectedGameObject != (Object)null && (Object)(object)content != (Object)null && currentSelectedGameObject.transform.IsChildOf(content))
				{
					PickerUI.KeepInView(scroll, (RectTransform)currentSelectedGameObject.transform);
				}
			}
		}
	}
	internal static class PortalMapPicker
	{
		[HarmonyPatch(typeof(Minimap))]
		private static class MapClicks
		{
			[HarmonyPatch("OnMapLeftClick")]
			[HarmonyPrefix]
			private static bool LeftClick(Minimap __instance)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if (!selecting)
				{
					return true;
				}
				PickAt(__instance, __instance.ScreenToWorldPoint(ZInput.pointerPosition));
				return false;
			}

			[HarmonyPatch("OnMapDblClick")]
			[HarmonyPrefix]
			private static bool DoubleClick()
			{
				return !InDoubleClickGrace();
			}

			[HarmonyPatch("ShowPinNameInput")]
			[HarmonyPrefix]
			private static bool PinNameInput()
			{
				return !InDoubleClickGrace();
			}

			[HarmonyPatch("RemovePinUnderPointer")]
			[HarmonyPrefix]
			private static bool RightClick()
			{
				return !selecting;
			}

			[HarmonyPatch("OnMapMiddleClick")]
			[HarmonyPrefix]
			private static bool MiddleClick()
			{
				return !selecting;
			}

			[HarmonyPatch("Update")]
			[HarmonyPrefix]
			private static void GamepadPick(Minimap __instance)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Invalid comparison between Unknown and I4
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				if (selecting && (int)__instance.m_mode == 2 && ZInput.GetButtonUp("JoyButtonA") && !ZInput.IsMouseActive() && !Minimap.InTextInput() && __instance.inputDelay <= 0f && MapTakesInput())
				{
					PickAt(__instance, __instance.ScreenToWorldPoint(new Vector3((float)(Screen.width / 2), (float)(Screen.height / 2))));
				}
			}

			[HarmonyPatch("SetMapMode")]
			[HarmonyPrefix]
			private static bool KeepOpenThroughKeyChanges(MapMode mode)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				if (selecting && inUpdateNoMap && !Game.m_noMap)
				{
					return (int)mode == 2;
				}
				return true;
			}

			[HarmonyPatch("SetMapMode")]
			[HarmonyPostfix]
			private static void CancelWhenMapCloses(Minimap __instance)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Invalid comparison between Unknown and I4
				if (selecting && (int)__instance.m_mode != 2)
				{
					PortalTargeting.Cancel();
				}
			}
		}

		[HarmonyPatch(typeof(Game), "UpdateNoMap")]
		private static class NoMapRefresh
		{
			private static void Prefix()
			{
				inUpdateNoMap = true;
			}

			private static Exception Finalizer(Exception __exception)
			{
				inUpdateNoMap = false;
				return __exception;
			}
		}

		private const float DoubleClickGraceSeconds = 0.35f;

		private const float ExtraZoomIn = 1.25f;

		private static readonly Dictionary<PinData, PortalTargeting.Destination> pins = new Dictionary<PinData, PortalTargeting.Destination>();

		private static bool selecting = false;

		private static float closedAt = -10f;

		private static bool inUpdateNoMap = false;

		private static float vanillaMinZoom = -1f;

		internal static bool Open(TeleportWorld source, List<PortalTargeting.Destination> destinations)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Close();
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			instance.ShowPointOnMap(((Component)source).transform.position);
			if ((int)instance.m_mode != 2)
			{
				return false;
			}
			selecting = true;
			vanillaMinZoom = instance.m_minZoom;
			instance.m_minZoom = vanillaMinZoom / 1.25f;
			foreach (PortalTargeting.Destination destination in destinations)
			{
				PinData val = instance.AddPin(destination.Position, (PinType)8, destination.Name, false, false, 0L, default(PlatformUserID));
				val.m_icon = PickerUI.PortalIcon(destination.PrefabHash);
				pins[val] = destination;
			}
			return true;
		}

		internal static void Close()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			if (!selecting)
			{
				return;
			}
			selecting = false;
			closedAt = Time.unscaledTime;
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance != (Object)null)
			{
				foreach (PinData key in pins.Keys)
				{
					instance.RemovePin(key);
				}
				if (vanillaMinZoom > 0f)
				{
					instance.m_minZoom = vanillaMinZoom;
					instance.LargeZoom = instance.LargeZoom;
				}
				if ((int)instance.m_mode == 2)
				{
					instance.SetMapMode((MapMode)1);
				}
			}
			pins.Clear();
			vanillaMinZoom = -1f;
		}

		private static bool InDoubleClickGrace()
		{
			if (!selecting)
			{
				return Time.unscaledTime - closedAt < 0.35f;
			}
			return true;
		}

		private static void PickAt(Minimap map, Vector3 worldPoint)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			float pinInteractRadius = map.PinInteractRadius;
			PortalTargeting.Destination destination = null;
			float num = float.MaxValue;
			foreach (KeyValuePair<PinData, PortalTargeting.Destination> pin in pins)
			{
				float num2 = Utils.DistanceXZ(worldPoint, pin.Key.m_pos);
				if (num2 < pinInteractRadius && num2 < num)
				{
					destination = pin.Value;
					num = num2;
				}
			}
			if (destination != null)
			{
				PortalTargeting.TravelTo(destination);
			}
		}

		private static bool MapTakesInput()
		{
			if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsActive())
			{
				return !InventoryGui.IsVisible();
			}
			return false;
		}
	}
	internal class PortalSpacePicker : MonoBehaviour
	{
		private class Marker
		{
			public PortalTargeting.Destination Destination;

			public Vector2 WorldXZ;

			public RectTransform Rect;

			public Text Label;
		}

		private class SpaceViewInput : MonoBehaviour, IScrollHandler, IEventSystemHandler, IDragHandler
		{
			internal PortalSpacePicker Picker;

			public void OnScroll(PointerEventData eventData)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: 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)
				if (eventData.scrollDelta.y != 0f)
				{
					Picker.Zoom(eventData.scrollDelta.y, eventData.position, eventData.enterEventCamera);
				}
			}

			public void OnDrag(PointerEventData eventData)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				Picker.Pan(eventData.position, eventData.delta, eventData.pressEventCamera);
			}
		}

		private class MarkerFocus : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler
		{
			internal PortalSpacePicker Picker;

			internal Marker Marker;

			public void OnPointerEnter(PointerEventData eventData)
			{
				Picker.SetFocus(Marker, fromSelection: false);
			}

			public void OnPointerExit(PointerEventData eventData)
			{
				Picker.ClearFocus(Marker);
			}

			public void OnSelect(BaseEventData eventData)
			{
				Picker.SetFocus(Marker, fromSelection: true);
			}

			public void OnDeselect(BaseEventData eventData)
			{
				Picker.ClearFocus(Marker);
			}
		}

		private const float PanelWidth = 880f;

		private const float PanelHeight = 680f;

		private const float Margin = 20f;

		private const float ViewTop = 56f;

		private const float FooterHeight = 92f;

		private const float ButtonWidth = 120f;

		private const float ButtonHeight = 34f;

		private const float MarkerSize = 30f;

		private const float SourceMarkerSize = 26f;

		private const float FocusedScale = 1.35f;

		private const float LabelWidth = 160f;

		private const float LabelHeight = 20f;

		private const float MinimumSpanMetres = 200f;

		private const float FitPadding = 1.2f;

		private const float MinZoomOfFit = 0.5f;

		private const float MaxPixelsPerMetre = 3.75f;

		private const float ZoomStep = 1.25f;

		private const int AlwaysLabelCount = 20;

		private const float LabelAllPixelsPerMetre = 0.4f;

		private const int StarfieldSeed = 7351;

		private const float StarsPerPixel = 0.0012f;

		private static readonly Color SourceTint = new Color(0.45f, 0.85f, 1f, 1f);

		private static readonly Color32 SkyColour = new Color32((byte)6, (byte)8, (byte)20, byte.MaxValue);

		private const string DefaultFooter = "Pick a portal to travel to.";

		private const string Hint = "Scroll to zoom, drag to look around.";

		private static PortalSpacePicker current = null;

		private PickerWindow window;

		private RectTransform markerRoot;

		private Text footer;

		private Texture2D starfield;

		private float viewWidth;

		private float viewHeight;

		private readonly List<Marker> markers = new List<Marker>();

		private int destinationCount;

		private Marker focused;

		private Vector2 viewCentre;

		private float pixelsPerMetre;

		private float minPixelsPerMetre;

		private float maxPixelsPerMetre;

		private Vector2 boundsMin;

		private Vector2 boundsMax;

		internal static bool Open(TeleportWorld source, List<PortalTargeting.Destination> destinations)
		{
			Close();
			PickerWindow pickerWindow;
			GameObject val = PickerUI.CreateOverlay("AJP_PortalSpacePicker", out pickerWindow);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			pickerWindow.Dismissed = PortalTargeting.Cancel;
			current = val.AddComponent<PortalSpacePicker>();
			current.window = pickerWindow;
			current.Build(source, destinations);
			return true;
		}

		internal static void Close()
		{
			if (!((Object)(object)current == (Object)null))
			{
				PortalSpacePicker portalSpacePicker = current;
				current = null;
				portalSpacePicker.window.Dismissed = null;
				Object.Destroy((Object)(object)((Component)portalSpacePicker).gameObject);
			}
		}

		private void Build(TeleportWorld source, List<PortalTargeting.Destination> destinations)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = PickerUI.CreatePanel(((Component)this).transform, 880f, 680f, "Choose a destination");
			viewWidth = 840f;
			viewHeight = 532f;
			RectTransform val2 = PickerUI.NewRect("Space", val.transform, 20f, 56f, viewWidth, viewHeight);
			starfield = CreateStarfield(Mathf.RoundToInt(viewWidth), Mathf.RoundToInt(viewHeight));
			((Component)val2).gameObject.AddComponent<RawImage>().texture = (Texture)(object)starfield;
			((Component)val2).gameObject.AddComponent<RectMask2D>();
			((Component)val2).gameObject.AddComponent<SpaceViewInput>().Picker = this;
			markerRoot = (RectTransform)PickerUI.NewUI("Portals", (Transform)(object)val2).transform;
			markerRoot.anchorMin = new Vector2(0.5f, 0.5f);
			markerRoot.anchorMax = new Vector2(0.5f, 0.5f);
			markerRoot.pivot = new Vector2(0.5f, 0.5f);
			markerRoot.sizeDelta = Vector2.zero;
			markerRoot.anchoredPosition = Vector2.zero;
			float num = 56f + viewHeight;
			footer = PickerUI.AddText(val.transform, 20f, num + 8f, viewWidth, 28f, "Pick a portal to travel to.", 18, (TextAnchor)4);
			PickerUI.AddText(val.transform, 20f, num + 46f, viewWidth - 120f - 10f, 34f, "Scroll to zoom, drag to look around.", 14, (TextAnchor)3);
			PickerUI.AddButton(val.transform, 740f, num + 46f, 120f, 34f, "Cancel", new UnityAction(PortalTargeting.Cancel));
			Vector3 position = ((Component)source).transform.position;
			Vector2 worldXZ = default(Vector2);
			((Vector2)(ref worldXZ))..ctor(position.x, position.z);
			Marker marker = null;
			foreach (PortalTargeting.Destination destination in destinations)
			{
				Marker marker2 = AddMarker(destination, new Vector2(destination.Position.x, destination.Position.z), PickerUI.PortalIcon(destination.PrefabHash), destination.Name, Color.white, 30f);
				if (marker == null || destination.Distance < marker.Destination.Distance)
				{
					marker = marker2;
				}
			}
			destinationCount = destinations.Count;
			AddMarker(null, worldXZ, PickerUI.PortalIcon(source.m_nview.GetZDO().GetPrefab()), "You are here", SourceTint, 26f);
			FitView();
			if (ZInput.IsGamepadActive() && marker != null && (Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(((Component)marker.Rect).gameObject);
			}
		}

		private Marker AddMarker(PortalTargeting.Destination destination, Vector2 worldXZ, Sprite icon, string label, Color tint, float size)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_005e: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			GameObject val = PickerUI.NewUI((destination != null) ? "Portal" : "YouAreHere", (Transform)(object)markerRoot, typeof(Image));
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0.5f, 0.5f);
			val2.anchorMax = new Vector2(0.5f, 0.5f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(size, size);
			Image component = val.GetComponent<Image>();
			component.sprite = icon;
			((Graphic)component).color = tint;
			component.preserveAspect = true;
			Marker marker = new Marker
			{
				Destination = destination,
				WorldXZ = worldXZ,
				Rect = val2
			};
			marker.Label = PickerUI.AddText(val.transform, (size - 160f) / 2f, size, 160f, 20f, label, 13, (TextAnchor)1, (destination != null) ? GUIManager.Instance.ValheimBeige : SourceTint);
			if (destination != null)
			{
				Button obj = val.AddComponent<Button>();
				((Selectable)obj).targetGraphic = (Graphic)(object)component;
				((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
				{
					Pick(destination);
				});
				MarkerFocus markerFocus = val.AddComponent<MarkerFocus>();
				markerFocus.Picker = this;
				markerFocus.Marker = marker;
			}
			else
			{
				((Graphic)component).raycastTarget = false;
			}
			markers.Add(marker);
			return marker;
		}

		private void FitView()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0063: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			boundsMin = markers[0].WorldXZ;
			boundsMax = markers[0].WorldXZ;
			foreach (Marker marker in markers)
			{
				boundsMin = Vector2.Min(boundsMin, marker.WorldXZ);
				boundsMax = Vector2.Max(boundsMax, marker.WorldXZ);
			}
			float num = Mathf.Max(boundsMax.x - boundsMin.x, 200f) * 1.2f;
			float num2 = Mathf.Max(boundsMax.y - boundsMin.y, 200f) * 1.2f;
			pixelsPerMetre = Mathf.Min(viewWidth / num, viewHeight / num2);
			minPixelsPerMetre = pixelsPerMetre * 0.5f;
			maxPixelsPerMetre = Mathf.Max(3.75f, pixelsPerMetre);
			viewCentre = (boundsMin + boundsMax) * 0.5f;
			Layout();
		}

		private void Layout()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			bool flag = destinationCount <= 20 || pixelsPerMetre >= 0.4f;
			foreach (Marker marker in markers)
			{
				marker.Rect.anchoredPosition = (marker.WorldXZ - viewCentre) * pixelsPerMetre;
				((Behaviour)marker.Label).enabled = flag || marker == focused || marker.Destination == null;
			}
		}

		private void Zoom(float direction, Vector2 screenPoint, Camera eventCamera)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			Vector2 val = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(markerRoot, screenPoint, eventCamera, ref val))
			{
				Vector2 val2 = viewCentre + val / pixelsPerMetre;
				float num = Mathf.Clamp(pixelsPerMetre * ((direction > 0f) ? 1.25f : 0.8f), minPixelsPerMetre, maxPixelsPerMetre);
				if (!Mathf.Approximately(num, pixelsPerMetre))
				{
					pixelsPerMetre = num;
					viewCentre = ClampToBounds(val2 - val / pixelsPerMetre);
					Layout();
				}
			}
		}

		private void Pan(Vector2 screenPoint, Vector2 screenDelta, Camera eventCamera)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Vector2 val = default(Vector2);
			Vector2 val2 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(markerRoot, screenPoint, eventCamera, ref val) && RectTransformUtility.ScreenPointToLocalPointInRectangle(markerRoot, screenPoint - screenDelta, eventCamera, ref val2))
			{
				viewCentre = ClampToBounds(viewCentre - (val - val2) / pixelsPerMetre);
				Layout();
			}
		}

		private Vector2 ClampToBounds(Vector2 centre)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return Vector2.Max(boundsMin, Vector2.Min(boundsMax, centre));
		}

		private void SetFocus(Marker marker, bool fromSelection)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (focused != null && focused != marker)
			{
				((Transform)focused.Rect).localScale = Vector3.one;
			}
			focused = marker;
			if (marker == null)
			{
				footer.text = "Pick a portal to travel to.";
				Layout();
				return;
			}
			((Transform)marker.Rect).localScale = new Vector3(1.35f, 1.35f, 1f);
			((Transform)marker.Rect).SetAsLastSibling();
			footer.text = marker.Destination.Name + "   " + marker.Destination.DistanceText;
			if (fromSelection && !IsInView(marker))
			{
				viewCentre = marker.WorldXZ;
			}
			Layout();
		}

		private void ClearFocus(Marker marker)
		{
			if (focused == marker)
			{
				SetFocus(null, fromSelection: false);
			}
		}

		private bool IsInView(Marker marker)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			Vector2 val = (marker.WorldXZ - viewCentre) * pixelsPerMetre;
			if (Mathf.Abs(val.x) <= (viewWidth - 30f) / 2f)
			{
				return Mathf.Abs(val.y) <= (viewHeight - 30f) / 2f;
			}
			return false;
		}

		private void Pick(PortalTargeting.Destination destination)
		{
			if (!((Object)(object)window == (Object)null) && window.AcceptingInput)
			{
				PortalTargeting.TravelTo(destination);
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)starfield != (Object)null)
			{
				Object.Destroy((Object)(object)starfield);
				starfield = null;
			}
		}

		private static Texture2D CreateStarfield(int width, int height)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color32[] array = (Color32[])(object)new Color32[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = SkyColour;
			}
			Random random = new Random(7351);
			int num = Mathf.RoundToInt((float)(width * height) * 0.0012f);
			Color32 val3 = default(Color32);
			for (int j = 0; j < num; j++)
			{
				int num2 = random.Next(width);
				int num3 = random.Next(height);
				byte b = (byte)random.Next(70, 256);
				Color32 val2 = (array[num3 * width + num2] = ((random.Next(4) == 0) ? new Color32(b, (byte)((float)(int)b * 0.9f), (byte)((float)(int)b * 0.75f), byte.MaxValue) : new Color32((byte)((float)(int)b * 0.85f), (byte)((float)(int)b * 0.9f), b, byte.MaxValue)));
				if (b > 230 && random.Next(3) == 0)
				{
					((Color32)(ref val3))..ctor((byte)(val2.r / 2), (byte)(val2.g / 2), (byte)(val2.b / 2), byte.MaxValue);
					if (num2 > 0)
					{
						array[num3 * width + num2 - 1] = val3;
					}
					if (num2 < width - 1)
					{
						array[num3 * width + num2 + 1] = val3;
					}
					if (num3 > 0)
					{
						array[(num3 - 1) * width + num2] = val3;
					}
					if (num3 < height - 1)
					{
						array[(num3 + 1) * width + num2] = val3;
					}
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			return val;
		}
	}
}
namespace AdjustablePortals.modules
{
	internal static class ActivationRequirements
	{
		[HarmonyPatch(typeof(TeleportWorld))]
		internal static class PortalInstanceActivatable
		{
			private struct PortalPieceState
			{
				public int Pieces;

				public float NextScanTime;
			}

			private static readonly string fuelKey = "AJP_FUEL";

			private static readonly string nearbyPiecesKey = "AJP_PORT_BUILD_NEARBY";

			private const float ScanIntervalSeconds = 10f;

			private const float InitialGraceSeconds = 5f;

			private const float InitialScanSpreadSeconds = 10f;

			private const float StaleEntrySeconds = 60f;

			private const float PruneIntervalSeconds = 60f;

			private static readonly Dictionary<ZDOID, PortalPieceState> nearbyPiecesByPortal = new Dictionary<ZDOID, PortalPieceState>();

			private static float nextPruneTime = 0f;

			private static readonly List<ZDOID> pruneBuffer = new List<ZDOID>();

			private static TeleportWorld lastFuelChargePortal = null;

			private static int lastFuelChargeFrame = -1;

			private static int GetPieceCount(TeleportWorld instance)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				ZDO zDO = instance.m_nview.GetZDO();
				ZDOID uid = zDO.m_uid;
				if (nearbyPiecesByPortal.TryGetValue(uid, out var value))
				{
					if (Time.time < value.NextScanTime)
					{
						return value.Pieces;
					}
					PruneUnloadedPortals();
					value.Pieces = PieceProximity.CountWithin(((Component)instance).transform.position, ValConfig.PortalPieceActivationDistance.Value);
					value.NextScanTime = Time.time + 10f;
					nearbyPiecesByPortal[uid] = value;
					if (instance.m_nview.IsOwner())
					{
						zDO.Set(nearbyPiecesKey, value.Pieces);
					}
					return value.Pieces;
				}
				value.Pieces = zDO.GetInt(nearbyPiecesKey, 0);
				value.NextScanTime = Time.time + 5f + Random.Range(0f, 10f);
				nearbyPiecesByPortal[uid] = value;
				return value.Pieces;
			}

			private static void PruneUnloadedPortals()
			{
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				if (Time.time < nextPruneTime)
				{
					return;
				}
				nextPruneTime = Time.time + 60f;
				float num = Time.time - 60f;
				pruneBuffer.Clear();
				foreach (KeyValuePair<ZDOID, PortalPieceState> item in nearbyPiecesByPortal)
				{
					if (item.Value.NextScanTime < num)
					{
						pruneBuffer.Add(item.Key);
					}
				}
				for (int i = 0; i < pruneBuffer.Count; i++)
				{
					nearbyPiecesByPortal.Remove(pruneBuffer[i]);
				}
				pruneBuffer.Clear();
			}

			[HarmonyPatch(typeof(TeleportWorld), "HaveTarget")]
			[HarmonyBefore(new string[] { "org.bepinex.plugins.targetportal" })]
			[HarmonyPrefix]
			internal static bool Activator(TeleportWorld __instance, ref bool __result)
			{
				return CheckActivationRequirements(__instance, ref __result);
			}

			public static void ConsumeFuel(TeleportWorld instance)
			{
				if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_nview == (Object)null) && instance.m_nview.IsValid() && ValConfig.EnablePortalRequireFuel.Value && (!((Object)(object)lastFuelChargePortal == (Object)(object)instance) || lastFuelChargeFrame != Time.frameCount))
				{
					int num = instance.m_nview.GetZDO().GetInt(fuelKey, 0);
					if (num > 0)
					{
						lastFuelChargePortal = instance;
						lastFuelChargeFrame = Time.frameCount;
						instance.m_nview.ClaimOwnership();
						instance.m_nview.GetZDO().Set(fuelKey, num - 1);
						Logger.LogDebug("Consumed 1 usage of portal fuel.");
					}
				}
			}

			internal static bool StoredPiecesMeetRequirement(ZDO portal)
			{
				if (!ValConfig.EnablePortalPieceRequirements.Value)
				{
					return true;
				}
				return portal.GetInt(nearbyPiecesKey, 0) >= ValConfig.PortalNearbyPiecesForActivation.Value;
			}

			public static bool AreActivationRequirementsMet(TeleportWorld instance, out string reason)
			{
				reason = "";
				bool result = true;
				if ((Object)(object)instance.m_nview == (Object)null || !instance.m_nview.IsValid())
				{
					return result;
				}
				if (ValConfig.EnablePortalPieceRequirements.Value)
				{
					int pieceCount = GetPieceCount(instance);
					if (pieceCount < ValConfig.PortalNearbyPiecesForActivation.Value)
					{
						reason = $"More nearby structures required ({pieceCount}/{ValConfig.PortalNearbyPiecesForActivation.Value})";
						result = false;
					}
				}
				if (ValConfig.EnablePortalRequireFuel.Value && instance.m_nview.GetZDO().GetInt(fuelKey, 0) <= 0)
				{
					reason = $"Fuel is required, add {ValConfig.PortalFuelPrefab.Value} x {ValConfig.PortalFuelBatchSize.Value}";
					result = false;
				}
				return result;
			}

			public static bool CheckActivationRequirements(TeleportWorld __instance, ref bool __result)
			{
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
				{
					return true;
				}
				if (!ValConfig.EnablePortalPieceRequirements.Value && !ValConfig.EnablePortalRequireFuel.Value)
				{
					if (PortalTargeting.IsActive)
					{
						__result = true;
						return false;
					}
					return true;
				}
				if (!Compatibility.IsTargetPortalInstalled && !PortalTargeting.IsActive && __instance.m_nview.GetZDO().GetConnectionZDOID((ConnectionType)1) == ZDOID.None)
				{
					__result = false;
					return false;
				}
				__result = AreActivationRequirementsMet(__instance, out var reason);
				if (!__result)
				{
					Logger.LogDebug($"Is portal active? {__result} {reason}");
				}
				return false;
			}

			[HarmonyPatch(typeof(TeleportWorld), "GetHoverText")]
			[HarmonyPostfix]
			internal static void OnHoverHelp(TeleportWorld __instance, ref string __result)
			{
				if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
				{
					return;
				}
				if (ValConfig.EnablePortalPieceRequirements.Value)
				{
					int pieceCount = GetPieceCount(__instance);
					if (pieceCount < ValConfig.PortalNearbyPiecesForActivation.Value)
					{
						__result += Localization.instance.Localize($"\nMore nearby structures required ({pieceCount}/{ValConfig.PortalNearbyPiecesForActivation.Value})");
					}
				}
				if (ValConfig.EnablePortalRequireFuel.Value)
				{
					int num = __instance.m_nview.GetZDO().GetInt(fuelKey, 0);
					if (num <= 0)
					{
						__result += Localization.instance.Localize($"\nFuel is required, add <color=red>{ValConfig.PortalFuelPrefab.Value}</color> x {ValConfig.PortalFuelBatchSize.Value}");
					}
					else
					{
						__result += Localization.instance.Localize($"\nCurrent Fuel {num}.");
					}
				}
			}

			[HarmonyPatch(typeof(TeleportWorld), "TargetFound")]
			[HarmonyPostfix]
			internal static void TargetFoundPrevention(TeleportWorld __instance, ref bool __result)
			{
				if (__result && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && (ValConfig.EnablePortalPieceRequirements.Value || ValConfig.EnablePortalRequireFuel.Value) && !AreActivationRequirementsMet(__instance, out var reason))
				{
					Logger.LogDebug("Portal blocked: " + reason);
					__result = false;
				}
			}

			[HarmonyPatch(typeof(TeleportWorld), "UseItem")]
			[HarmonyPrefix]
			internal static bool AddFuelOnUseItem(TeleportWorld __instance, Humanoid user, ItemData item, ref bool __result)
			{
				if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !ValConfig.EnablePortalRequireFuel.Value)
				{
					return true;
				}
				if ((Object)(object)user == (Object)null || user.m_inventory == null || item == null || (Object)(object)item.m_dropPrefab == (Object)null || ((Object)item.m_dropPrefab).name != ValConfig.PortalFuelPrefab.Value)
				{
					return true;
				}
				int value = ValConfig.PortalFuelBatchSize.Value;
				if (user.m_inventory.CountItemsByPrefab(ValConfig.PortalFuelPrefab.Value) < value || !user.m_inventory.RemoveItemByPrefab(ValConfig.PortalFuelPrefab.Value, value))
				{
					((Character)user).Message((MessageType)2, $"Requires at least {ValConfig.PortalFuelPrefab.Value}x{value}.", 0, (Sprite)null, false);
					__result = true;
					return false;
				}
				__instance.m_nview.ClaimOwnership();
				int num = __instance.m_nview.GetZDO().GetInt(fuelKey, 0) + ValConfig.PortalFuelUsagesPerBatch.Value;
				__instance.m_nview.GetZDO().Set(fuelKey, num);
				((Character)user).Message((MessageType)2, $"Added {ValConfig.PortalFuelPrefab.Value}x{value} for {ValConfig.PortalFuelUsagesPerBatch.Value} fuel.", 0, (Sprite)null, false);
				__result = true;
				return false;
			}

			[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
			[HarmonyPrefix]
			internal static void ConsumeFuelAfterTeleportPrefix(Player player, out bool __state)
			{
				__state = (Object)(object)player != (Object)null && ((Character)player).IsTeleporting();
			}

			[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
			[HarmonyPostfix]
			internal static void ConsumeFuelAfterTeleport(TeleportWorld __instance, Player player, bool __state)
			{
				if (!__state && !((Object)(object)player == (Object)null) && ((Character)player).IsTeleporting())
				{
					ConsumeFuel(__instance);
				}
			}

			internal static void ClearPortalPieceCache()
			{
				nearbyPiecesByPortal.Clear();
				pruneBuffer.Clear();
				nextPruneTime = 0f;
				PieceProximity.Clear();
				lastFuelChargePortal = null;
				lastFuelChargeFrame = -1;
			}
		}

		[HarmonyPatch(typeof(ZNetScene))]
		internal static class PortalCacheLifetime
		{
			[HarmonyPatch("Shutdown")]
			[HarmonyPostfix]
			private static void OnShutdown()
			{
				PortalInstanceActivatable.ClearPortalPieceCache();
				TeleportCompanions.ClearSessionState();
				PortalTargeting.ClearSessionState();
			}
		}
	}
	internal static class Compatibility
	{
		internal const string BackpacksGUID = "org.bepinex.plugins.backpacks";

		public static bool IsTargetPortalInstalled;

		public static bool IsBackpacksInstalled;

		private static BaseUnityPlugin backpacksPlugin;

		private static Func<Inventory, List<Inventory>> getBackpackInventories;

		private static bool backpacksStale;

		private static TeleportWorld activeSourcePortal;

		private static float activeSourcePortalExpiry;

		private const float ActiveSourcePortalLifetime = 30f;

		internal static TeleportWorld GetActiveSourcePortal()
		{
			if ((Object)(object)activeSourcePortal == (Object)null || Time.time > activeSourcePortalExpiry)
			{
				return null;
			}
			return activeSourcePortal;
		}

		internal static void CheckModCompat()
		{
			try
			{
				Dictionary<string, BaseUnityPlugin> plugins = BepInExUtils.GetPlugins(false);
				if (plugins != null)
				{
					if (Enumerable.Contains(plugins.Keys, "org.bepinex.plugins.targetportal"))
					{
						IsTargetPortalInstalled = true;
					}
					if (plugins.TryGetValue("org.bepinex.plugins.backpacks", out backpacksPlugin) && (Object)(object)backpacksPlugin != (Object)null)
					{
						IsBackpacksInstalled = true;
					}
				}
			}
			catch
			{
				Logger.LogWarning("Unable to check mod compatibility. Ensure that Bepinex can load.");
			}
		}

		internal static void BackpacksCompat()
		{
			if (IsBackpacksInstalled)
			{
				Type type = ((object)backpacksPlugin).GetType().Assembly.GetType("Backpacks.API");
				MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "GetAllBackpackInventories", new Type[1] { typeof(Inventory) }, (Type[])null) : null);
				if (methodInfo == null || methodInfo.ReturnType != typeof(List<Inventory>))
				{
					Logger.LogWarning("Could not find Backpacks.API.GetAllBackpackInventories - backpacks may keep a stale portal restriction until their contents change.");
					return;
				}
				getBackpackInventories = (Func<Inventory, List<Inventory>>)Delegate.CreateDelegate(typeof(Func<Inventory, List<Inventory>>), methodInfo);
				Logger.LogInfo("Backpacks detected, backpack portal restrictions will follow boss progression.");
			}
		}

		internal static void MarkBackpacksStale()
		{
			backpacksStale = true;
		}

		internal static void RefreshStaleBackpacks()
		{
			if (!backpacksStale || getBackpackInventories == null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			backpacksStale = false;
			try
			{
				foreach (Inventory item in getBackpackInventories(((Humanoid)localPlayer).GetInventory()))
				{
					if (item != null)
					{
						item.Changed(false, false);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning("Unable to refresh backpack portal restrictions: " + ex.Message);
			}
		}

		internal static void TargetPortalCompat()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			if (IsTargetPortalInstalled)
			{
				Logger.LogInfo("TargetPortal detected, applying compatibility patches...");
				Type type = AccessTools.TypeByName("TargetPortal.Map")?.GetNestedType("OpenMapOnPortalEnter", AccessTools.all);
				MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "Prefix", (Type[])null, (Type[])null) : null);
				if (methodInfo == null)
				{
					Logger.LogWarning("Could not find TargetPortal.Map.OpenMapOnPortalEnter.Prefix - TargetPortal compatibility patches will not be applied.");
					return;
				}
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(Compatibility), "BlockOrTrackPortalEntry", (Type[])null, (Type[])null));
				AdjustablePortals.Harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Player), "TeleportTo", (Type[])null, (Type[])null);
				HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(Compatibility), "TeleportToPostfix", (Type[])null, (Type[])null));
				AdjustablePortals.Harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo("TargetPortal compatibility patches applied.");
			}
		}

		private static bool BlockOrTrackPortalEntry(TeleportWorldTrigger __0)
		{
			if ((Object)(object)__0 == (Object)null || (Object)(object)__0.m_teleportWorld == (Object)null)
			{
				return true;
			}
			if (!ActivationRequirements.PortalInstanceActivatable.AreActivationRequirementsMet(__0.m_teleportWorld, out var reason))
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, reason, 0, (Sprite)null, false);
				}
				return false;
			}
			activeSourcePortal = __0.m_teleportWorld;
			activeSourcePortalExpiry = Time.time + 30f;
			return true;
		}

		private static void TeleportToPostfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)activeSourcePortal == (Object)null))
			{
				if (Time.time > activeSourcePortalExpiry)
				{
					activeSourcePortal = null;
					return;
				}
				ActivationRequirements.PortalInstanceActivatable.ConsumeFuel(activeSourcePortal);
				activeSourcePortal = null;
			}
		}
	}
	internal static class PortalTargeting
	{
		internal enum TargetingMode
		{
			Vanilla,
			SelectFromList,
			SelectOnMap,
			SelectInSpace
		}

		internal class Destination
		{
			public ZDOID Id;

			public string Name;

			public Vector3 Position;

			public Quaternion Rotation;

			public int PrefabHash;

			public float Distance;

			public string Direction;

			public string DistanceText => FormatDistance(Distance) + " " + Direction;
		}

		private enum SessionState
		{
			None,
			Pending,
			Open
		}

		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRPCs
		{
			private static void Postfix()
			{
				ZRoutedRpc.instance.Register<int>("AJP_RequestPortals", (Action<long, int>)RPC_RequestPortals);
				ZRoutedRpc.instance.Register<int, ZPackage>("AJP_PortalList", (Action<long, int, ZPackage>)RPC_PortalList);
				WarnIfIgnored();
			}
		}

		[HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")]
		private static class ChooseDestinationOnEnter
		{
			private static bool Prefix(TeleportWorldTrigger __instance, Collider colliderIn)
			{
				if (!IsActive)
				{
					return true;
				}
				Player val = (((Object)(object)colliderIn != (Object)null) ? ((Component)colliderIn).GetComponent<Player>() : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				BeginSelection(__instance.m_teleportWorld, val);
				return false;
			}
		}

		[HarmonyPatch(typeof(TeleportWorld), "TargetFound")]
		private static class EveryPortalHasATarget
		{
			private static bool Prefix(TeleportWorld __instance, ref bool __result)
			{
				if (!IsActive || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		private const string RequestPortalsRPC = "AJP_RequestPortals";

		private const string PortalListRPC = "AJP_PortalList";

		private const float TeleportCooldownSeconds = 2f;

		private const float RequestTimeoutSeconds = 5f;

		private const string UnnamedPortal = "Unnamed portal";

		private static readonly string[] CompassPoints = new string[8] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };

		private static SessionState state = SessionState.None;

		private static TargetingMode openMode = TargetingMode.Vanilla;

		private static TeleportWorld sourcePortal = null;

		private static Player sessionPlayer = null;

		private static int requestId = 0;

		private static float requestTime = 0f;

		private static bool warnedAboutTargetPortal = false;

		private static readonly List<ZDO> eligibleBuffer = new List<ZDO>();

		internal static bool IsActive
		{
			get
			{
				if (!Compatibility.IsTargetPortalInstalled)
				{
					return ValConfig.PortalTargetingMode.Value != TargetingMode.Vanilla;
				}
				return false;
			}
		}

		internal static void TargetingModeChanged(object sender, EventArgs e)
		{
			WarnIfIgnored();
			EndSession();
		}

		private static void WarnIfIgnored()
		{
			if (!warnedAboutTargetPortal && Compatibility.IsTargetPortalInstalled && ValConfig.PortalTargetingMode.Value != TargetingMode.Vanilla)
			{
				warnedAboutTargetPortal = true;
				Logger.LogWarning($"PortalTargetingMode is set to {ValConfig.PortalTargetingMode.Value}, but TargetPortal is installed and chooses destinations itself. Portal targeting is left to TargetPortal.");
			}
		}

		private static void BeginSelection(TeleportWorld source, Player player)
		{
			if (state == SessionState.None && !((Object)(object)source == (Object)null) && !((Object)(object)source.m_nview == (Object)null) && source.m_nview.IsValid() && !((Character)player).IsTeleporting() && !(player.m_teleportCooldown < 2f))
			{
				if (!CanTravelFrom(source, player, out var reason))
				{
					((Character)player).Message((MessageType)2, reason, 0, (Sprite)null, false);
					return;
				}
				state = SessionState.Pending;
				sourcePortal = source;
				sessionPlayer = player;
				requestTime = Time.time;
				requestId++;
				ZRoutedRpc.instance.InvokeRoutedRPC("AJP_RequestPortals", new object[1] { requestId });
			}
		}

		internal static bool CanTravelFrom(TeleportWorld source, Player player, out string reason)
		{
			if (!ActivationRequirements.PortalInstanceActivatable.AreActivationRequirementsMet(source, out reason))
			{
				return false;
			}
			ZoneSystem instance = ZoneSystem.instance;
			if (instance.GetGlobalKey((GlobalKeys)32))
			{
				reason = "$msg_blocked";
				return false;
			}
			float num = default(float);
			if (instance.GetGlobalKey((GlobalKeys)33) && (RandEventSystem.instance.GetBossEvent() != null || (instance.GetGlobalKey((GlobalKeys)47, ref num) && num > 0f)))
			{
				reason = "$msg_blockedbyboss";
				return false;
			}
			if (TeleportCompanions.CartBlocksPortal(player, source, out var blockedBy))
			{
				reason = "$msg_noteleport (" + blockedBy + ")";
				return false;
			}
			if (!((Humanoid)player).IsTeleportable(source.m_allowAllItems))
			{
				reason = "$msg_noteleport";
				return false;
			}
			reason = "";
			return true;
		}

		private static void RPC_RequestPortals(long sender, int id)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
				{
					return;
				}
				eligibleBuffer.Clear();
				foreach (ZDO portal in ZDOMan.instance.GetPortalList())
				{
					if (ActivationRequirements.PortalInstanceActivatable.StoredPiecesMeetRequirement(portal))
					{
						eligibleBuffer.Add(portal);
					}
				}
				ZPackage val = new ZPackage();
				val.Write(eligibleBuffer.Count);
				foreach (ZDO item in eligibleBuffer)
				{
					val.Write(item.m_uid);
					val.Write(item.GetPosition());
					val.Write(item.GetRotation());
					val.Write(item.GetPrefab());
					val.Write(item.GetString(ZDOVars.s_tag, ""));
					val.Write(item.GetString(ZDOVars.s_tagauthor, ""));
				}
				eligibleBuffer.Clear();
				Logger.LogDebug($"Sending {val.Size()} bytes of portal destinations to {sender}.");
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "AJP_PortalList", new object[2] { id, val });
			}
			catch (Exception arg)
			{
				eligibleBuffer.Clear();
				Logger.LogWarning($"Unable to list portal destinations: {arg}");
			}
		}

		private static void RPC_PortalList(long sender, int id, ZPackage package)
		{
			try
			{
				if (state != SessionState.Pending || id != requestId)
				{
					return;
				}
				if (!SessionStillValid() || Menu.IsVisible() || Console.IsVisible() || TextInput.IsVisible())
				{
					EndSession();
					return;
				}
				List<Destination> list = ReadDestinations(package, sourcePortal);
				if (list.Count == 0)
				{
					((Character)sessionPlayer).Message((MessageType)2, "There are no other portals to travel to.", 0, (Sprite)null, false);
					EndSession();
				}
				else
				{
					OpenPicker(list);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Unable to show portal destinations: {arg}");
				EndSession();
			}
		}

		private static List<Destination> ReadDestinations(ZPackage package, TeleportWorld source)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			ZDOID uid = source.m_nview.GetZDO().m_uid;
			Vector3 position = ((Component)source).transform.position;
			int num = package.ReadInt();
			List<Destination> list = new List<Destination>(num);
			for (int i = 0; i < num; i++)
			{
				Destination destination = new Destination();
				destination.Id = package.ReadZDOID();
				destination.Position = package.ReadVector3();
				destination.Rotation = package.ReadQuaternion();
				destination.PrefabHash = package.ReadInt();
				string text = package.ReadString();
				string text2 = package.ReadString();
				if (!(destination.Id == uid))
				{
					PlatformUserID val = (PlatformUserID)(string.IsNullOrEmpty(text2) ? PlatformUserID.None : new PlatformUserID(text2));
					string text3 = (string.IsNullOrEmpty(text) ? "" : CensorShittyWords.FilterUGC(text, (UGCType)4, val, 0L, (GetUserProfileCompletedHandler)null));
					text3 = (string.IsNullOrEmpty(text3) ? "" : StringExtensionMethods.RemoveRichTextTags(text3).Trim());
					destination.Name = ((text3.Length > 0) ? text3 : "Unnamed portal");
					Vector3 offset = destination.Position - position;
					offset.y = 0f;
					destination.Distance = ((Vector3)(ref offset)).magnitude;
					destination.Direction = CompassPoint(offset);
					list.Add(destination);
				}
			}
			return list;
		}

		private static void OpenPicker(List<Destination> destinations)
		{
			TargetingMode targetingMode = ValConfig.PortalTargetingMode.Value;
			if (targetingMode == TargetingMode.SelectOnMap && (Game.m_noMap || (Object)(object)Minimap.instance == (Object)null))
			{
				targetingMode = TargetingMode.SelectInSpace;
			}
			if (InventoryGui.IsVisible())
			{
				InventoryGui.instance.Hide();
			}
			state = SessionState.Open;
			openMode = targetingMode;
			bool flag;
			switch (targetingMode)
			{
			case TargetingMode.SelectOnMap:
				flag = PortalMapPicker.Open(sourcePortal, destinations);
				break;
			case TargetingMode.SelectInSpace:
				CloseLargeMap();
				flag = PortalSpacePicker.Open(sourcePortal, destinations);
				break;
			default:
				CloseLargeMap();
				flag = PortalListPicker.Open(sourcePortal, destinations);
				break;
			}
			if (!flag)
			{
				EndSession();
			}
		}

		private static void CloseLargeMap()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2)
			{
				Minimap.instance.SetMapMode((MapMode)1);
			}
		}

		internal static void TravelTo(Destination destination)
		{
			//IL_0047: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			if (state != SessionState.Open || destination == null)
			{
				return;
			}
			if (!SessionStillValid())
			{
				EndSession();
				return;
			}
			TeleportWorld val = sourcePortal;
			Player val2 = sessionPlayer;
			if (!CanTravelFrom(val, val2, out var reason))
			{
				((Character)val2).Message((MessageType)2, reason, 0, (Sprite)null, false);
				EndSession();
				return;
			}
			EndSession();
			Vector3 val3 = destination.Position + destination.Rotation * Vector3.forward * val.m_exitDistance + Vector3.up;
			TeleportCompanions.NoteSourcePortal(val);
			if (((Character)val2).TeleportTo(val3, destination.Rotation, true))
			{
				Logger.LogDebug("Travelling to portal \"" + destination.Name + "\" " + destination.DistanceText + ".");
				ActivationRequirements.PortalInstanceActivatable.ConsumeFuel(val);
				Game.instance.IncrementPlayerStat((PlayerStatType)15, 1f, false);
			}
		}

		internal static void Cancel()
		{
			EndSession();
		}

		internal static void Update()
		{
			if (state != SessionState.None)
			{
				if (!SessionStillValid())
				{
					EndSession();
				}
				else if (state == SessionState.Pending && Time.time - requestTime > 5f)
				{
					Logger.LogDebug("The server did not answer with portal destinations in time.");
					EndSession();
				}
			}
		}

		private static bool SessionStillValid()
		{
			//IL_006f: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer != (Object)(object)sessionPlayer || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting())
			{
				return false;
			}
			if ((Object)(object)sourcePortal == (Object)null || (Object)(object)sourcePortal.m_nview == (Object)null || !sourcePortal.m_nview.IsValid())
			{
				return false;
			}
			if (!IsActive)
			{
				return false;
			}
			return Vector3.Distance(((Component)localPlayer).transform.position, ((Component)sourcePortal).transform.position) <= sourcePortal.m_activationRange;
		}

		private static void EndSession()
		{
			if (state == SessionState.None)
			{
				return;
			}
			SessionState num = state;
			TargetingMode targetingMode = openMode;
			state = SessionState.None;
			openMode = TargetingMode.Vanilla;
			sourcePortal = null;
			sessionPlayer = null;
			if (num == SessionState.Open)
			{
				switch (targetingMode)
				{
				case TargetingMode.SelectOnMap:
					PortalMapPicker.Close();
					break;
				case TargetingMode.SelectInSpace:
					PortalSpacePicker.Close();
					break;
				default:
					PortalListPicker.Close();
					break;
				}
			}
		}

		internal static void ClearSessionState()
		{
			EndSession();
			eligibleBuffer.Clear();
			warnedAboutTargetPortal = false;
		}

		private static string CompassPoint(Vector3 offset)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref offset)).sqrMagnitude < 0.01f)
			{
				return "";
			}
			int num = Mathf.RoundToInt(Mathf.Repeat(Mathf.Atan2(offset.x, offset.z) * 57.29578f, 360f) / 45f) % CompassPoints.Length;
			return CompassPoints[num];
		}

		internal static string FormatDistance(float metres)
		{
			if (metres < 1000f)
			{
				return $"{Mathf.RoundToInt(metres)} m";
			}
			return (metres / 1000f).ToString("0.0", CultureInfo.InvariantCulture) + " km";
		}
	}
	internal static class ProgressionKeys
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRPCs
		{
			private static void Postfix()
			{
				ZRoutedRpc.instance.Register<string>("AJP_GrantBossKey", (Action<long, string>)RPC_GrantBossKey);
			}
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		private static class CreditBossKeyToAttackers
		{
			private static void Prefix(Character __instance)
			{
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: