Decompiled source of AdjustablePortals v0.3.0

plugins/AdjustablePortals.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
namespace AdjustablePortals
{
	[BepInPlugin("MidnightsFX.AdjustablePortals", "AdjustablePortals", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*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.3.0";

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

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		internal static ManualLogSource Log;

		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			new ValConfig(((BaseUnityPlugin)this).Config);
			TeleportItems.SetupTeleportLists();
			Compatibility.CheckModCompat();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			Harmony.PatchAll(executingAssembly);
			Compatibility.TargetPortalCompat();
		}
	}
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_001d: 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)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

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

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

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

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

		public static void LogError(string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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<bool> EnablePortalPieceRequirements;

		public static ConfigEntry<bool> EnablePortalRequireFuel;

		public static ConfigEntry<int> PortalFuelUsagesPerBatch;

		public static ConfigEntry<int> PortalFuelBatchSize;

		public static ConfigEntry<string> PortalFuelPrefab;

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

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_001b: 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_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
			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", 1000, "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.");
			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", "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;
		}

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

		private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
		{
			if (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_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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0014: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_001b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0014: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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.modules
{
	internal static class ActivationRequirements
	{
		[HarmonyPatch(typeof(TeleportWorld))]
		internal static class PortalInstanceActivatable
		{
			private static readonly int pieceMask = LayerMask.GetMask(new string[1] { "piece" });

			private static readonly string fuelKey = "AJP_FUEL";

			private static readonly string nearbyPiecesKey = "AJP_PORT_BUILD_NEARBY";

			private static float update_timer = 0f;

			private static float current_update_time = 0f;

			private static Dictionary<uint, int> nearbyPiecesByPortal = new Dictionary<uint, int>();

			private static int GetCurrentPiecesForSpecificPortal(ZDO portalZDO)
			{
				uint iD = ((ZDOID)(ref portalZDO.m_uid)).ID;
				int num;
				if (nearbyPiecesByPortal.ContainsKey(iD))
				{
					num = nearbyPiecesByPortal[iD];
				}
				else
				{
					num = portalZDO.GetInt(nearbyPiecesKey, 1);
					nearbyPiecesByPortal.Add(iD, num);
				}
				return num;
			}

			[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.m_nview == (Object)null) && instance.m_nview.IsValid() && ValConfig.EnablePortalRequireFuel.Value)
				{
					int @int = instance.m_nview.GetZDO().GetInt(fuelKey, 0);
					if (@int > 0)
					{
						@int--;
						instance.m_nview.GetZDO().Set(fuelKey, @int);
						Logger.LogDebug("Consumed 1 usage of portal fuel.");
					}
				}
			}

			public static bool AreActivationRequirementsMet(TeleportWorld instance, out string reason)
			{
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				reason = "";
				bool result = true;
				if ((Object)(object)instance.m_nview == (Object)null || !instance.m_nview.IsValid())
				{
					return result;
				}
				if (ValConfig.EnablePortalPieceRequirements.Value)
				{
					ZDO zDO = instance.m_nview.GetZDO();
					int num = GetCurrentPiecesForSpecificPortal(zDO);
					current_update_time += Time.fixedDeltaTime;
					if (update_timer <= current_update_time)
					{
						num = instance.m_nview.GetZDO().GetInt(nearbyPiecesKey, 0);
						update_timer = current_update_time + 10f;
						Collider[] array = Physics.OverlapSphere(((Component)instance).transform.position, ValConfig.PortalPieceActivationDistance.Value, pieceMask);
						num = array.Length;
						nearbyPiecesByPortal[((ZDOID)(ref zDO.m_uid)).ID] = num;
						zDO.Set(nearbyPiecesKey, num);
					}
					if (num < ValConfig.PortalNearbyPiecesForActivation.Value)
					{
						reason = $"More nearby structures required ({num}/{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_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
				{
					return true;
				}
				if (!Compatibility.IsTargetPortalInstalled && __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 currentPiecesForSpecificPortal = GetCurrentPiecesForSpecificPortal(__instance.m_nview.GetZDO());
					if (currentPiecesForSpecificPortal < ValConfig.PortalNearbyPiecesForActivation.Value)
					{
						__result += Localization.instance.Localize($"\nMore nearby structures required ({currentPiecesForSpecificPortal}/{ValConfig.PortalNearbyPiecesForActivation.Value})");
					}
				}
				if (ValConfig.EnablePortalRequireFuel.Value)
				{
					int @int = __instance.m_nview.GetZDO().GetInt(fuelKey, 0);
					if (@int == 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 {@int}.");
					}
				}
			}

			[HarmonyPatch(typeof(TeleportWorld), "TargetFound")]
			[HarmonyPostfix]
			internal static void TargetFoundPrevention(TeleportWorld __instance, ref bool __result)
			{
				if (!((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && ValConfig.EnablePortalPieceRequirements.Value)
				{
					CheckActivationRequirements(__instance, ref __result);
				}
			}

			[HarmonyPatch(typeof(TeleportWorld), "UseItem")]
			[HarmonyPrefix]
			internal static bool TeleportCost(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;
				}
				int @int = __instance.m_nview.GetZDO().GetInt(fuelKey, 0);
				if ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == ValConfig.PortalFuelPrefab.Value)
				{
					if (item.m_stack >= ValConfig.PortalFuelBatchSize.Value)
					{
						user.m_inventory.RemoveItemByPrefab(ValConfig.PortalFuelPrefab.Value, ValConfig.PortalFuelBatchSize.Value);
						@int += ValConfig.PortalFuelUsagesPerBatch.Value;
						__instance.m_nview.GetZDO().Set(fuelKey, @int);
						((Character)user).Message((MessageType)2, $"Added {ValConfig.PortalFuelPrefab.Value}x{ValConfig.PortalFuelBatchSize.Value} for {ValConfig.PortalFuelUsagesPerBatch.Value} fuel.", 0, (Sprite)null);
					}
					else
					{
						((Character)user).Message((MessageType)2, $"Requires at least {ValConfig.PortalFuelPrefab.Value}x{ValConfig.PortalFuelBatchSize.Value}.", 0, (Sprite)null);
					}
					__result = true;
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
			[HarmonyPostfix]
			internal static void TeleportCost(TeleportWorld __instance)
			{
				if (!((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && ValConfig.EnablePortalRequireFuel.Value)
				{
					int @int = __instance.m_nview.GetZDO().GetInt(fuelKey, 0);
					if (@int > 0)
					{
						@int--;
						__instance.m_nview.GetZDO().Set(fuelKey, @int);
						Logger.LogDebug("Consumed 1 usage of portal fuel.");
					}
				}
			}
		}
	}
	internal static class Compatibility
	{
		public static bool IsTargetPortalInstalled;

		private static TeleportWorld activeSourcePortal;

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

		internal static void TargetPortalCompat()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, reason, 0, (Sprite)null);
				return false;
			}
			activeSourcePortal = __0.m_teleportWorld;
			return true;
		}

		private static void TeleportToPostfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)activeSourcePortal == (Object)null))
			{
				ActivationRequirements.PortalInstanceActivatable.ConsumeFuel(activeSourcePortal);
				activeSourcePortal = null;
			}
		}
	}
	public static class TeleportItems
	{
		[HarmonyPatch(typeof(Humanoid))]
		private static class AllowConfiguredTeleportableItems
		{
			[HarmonyPatch("IsTeleportable")]
			private static void Postfix(Humanoid __instance, ref bool __result)
			{
				if (__result)
				{
					return;
				}
				List<ItemData> list = (from x in __instance.m_inventory.GetAllItems()
					where !x.m_shared.m_teleportable
					select x).Distinct().ToList();
				List<string> list2 = new List<string>();
				foreach (ItemData item in list)
				{
					if (!PerPlayerTeleportableItems.IsItemTeleportable(item))
					{
						list2.Add(((Object)item.m_dropPrefab).name);
					}
				}
				if (list2.Count == 0)
				{
					__result = true;
					return;
				}
				Logger.LogDebug("The following items are not teleportable " + string.Join(", ", list2));
				__result = false;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem))]
		public static class ClearTeleportableCache
		{
			[HarmonyPostfix]
			[HarmonyPatch(typeof(ZoneSystem), "SetGlobalKey", new Type[] { typeof(string) })]
			private static void ClearGlobalKeyReset(string name)
			{
				PlayerItemsAllowTeleport.Clear();
			}
		}

		[HarmonyPatch(typeof(Player))]
		public static class ClearTeleportableCachePrivateKeys
		{
			[HarmonyPostfix]
			[HarmonyPatch(typeof(Player), "AddUniqueKey", new Type[] { typeof(string) })]
			private static void ClearPrivateKeyReset(string name)
			{
				PlayerItemsAllowTeleport.Clear();
			}
		}

		[HarmonyPatch(typeof(InventoryGrid))]
		public static class PerPlayerTeleportableItems
		{
			[HarmonyTranspiler]
			[HarmonyPatch("UpdateGui")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Expected O, but got Unknown
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(SharedData), "m_teleportable"), (string)null)
				}).RemoveInstructions(3).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Ldloc_S, (object)18),
					Transpilers.EmitDelegate<Func<ItemData, bool>>((Func<ItemData, bool>)IsItemTeleportable)
				})
					.ThrowIfNotMatch("Unable to patch item teleport visual display.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			public static bool IsItemTeleportable(ItemData item)
			{
				if (item == null || item.m_shared == null || (Object)(object)item.m_dropPrefab == (Object)null)
				{
					return true;
				}
				string name = ((Object)item.m_dropPrefab).name;
				if (PlayerItemsAllowTeleport.ContainsKey(name))
				{
					return PlayerItemsAllowTeleport[name];
				}
				bool flag = item.m_shared.m_teleportable;
				if (!flag && ZoneSystem.instance.GetGlobalKey((GlobalKeys)33) && EikthyrAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey((GlobalKeys)36) && ElderAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey((GlobalKeys)37) && BonemassAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey((GlobalKeys)34) && ModerAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey((GlobalKeys)35) && YagluthAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey("defeated_queen") && QueenAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				if (!flag && ZoneSystem.instance.GetGlobalKey("defeated_fader") && FaderAllowedTeleports.Contains(name))
				{
					flag = true;
				}
				Logger.LogInfo($"Item is teleportable? {name} - {flag}");
				if (!PlayerItemsAllowTeleport.ContainsKey(name))
				{
					PlayerItemsAllowTeleport.Add(name, flag);
				}
				return false;
			}
		}

		internal static List<string> EikthyrAllowedTeleports = new List<string>();

		internal static List<string> ElderAllowedTeleports = new List<string>();

		internal static List<string> BonemassAllowedTeleports = new List<string>();

		internal static List<string> ModerAllowedTeleports = new List<string>();

		internal static List<string> YagluthAllowedTeleports = new List<string>();

		internal static List<string> QueenAllowedTeleports = new List<string>();

		internal static List<string> FaderAllowedTeleports = new List<string>();

		private static Dictionary<string, bool> PlayerItemsAllowTeleport = new Dictionary<string, bool>();

		internal static void SetupTeleportLists()
		{
			ConfigListChanged(EikthyrAllowedTeleports, ValConfig.DefeatedEikthyrAllowedItems.Value);
			ConfigListChanged(ElderAllowedTeleports, ValConfig.DefeatedElderAllowedItems.Value);
			ConfigListChanged(BonemassAllowedTeleports, ValConfig.DefeatedBonemassAllowedItems.Value);
			ConfigListChanged(ModerAllowedTeleports, ValConfig.DefeatedModerAllowItems.Value);
			ConfigListChanged(YagluthAllowedTeleports, ValConfig.DefeatedYagluthAllowItems.Value);
			ConfigListChanged(QueenAllowedTeleports, ValConfig.DefeatedQueenAllowItems.Value);
			ConfigListChanged(FaderAllowedTeleports, ValConfig.DefeatedFaderAllowItems.Value);
		}

		internal static void EikthyrAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(EikthyrAllowedTeleports, ValConfig.DefeatedEikthyrAllowedItems.Value);
		}

		internal static void ElderAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(ElderAllowedTeleports, ValConfig.DefeatedElderAllowedItems.Value);
		}

		internal static void BonemassAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(BonemassAllowedTeleports, ValConfig.DefeatedBonemassAllowedItems.Value);
		}

		internal static void ModerAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(ModerAllowedTeleports, ValConfig.DefeatedModerAllowItems.Value);
		}

		internal static void YagluthAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(YagluthAllowedTeleports, ValConfig.DefeatedYagluthAllowItems.Value);
		}

		internal static void QueenAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(QueenAllowedTeleports, ValConfig.DefeatedQueenAllowItems.Value);
		}

		internal static void FaderAllowedTeleportsChanged(object s, EventArgs e)
		{
			ConfigListChanged(FaderAllowedTeleports, ValConfig.DefeatedFaderAllowItems.Value);
		}

		private static void ConfigListChanged(List<string> targetList, string configValue)
		{
			PlayerItemsAllowTeleport.Clear();
			try
			{
				List<string> list = new List<string>();
				string[] array = configValue.Split(new char[1] { ',' });
				foreach (string item in array)
				{
					list.Add(item);
				}
				if (list.Count > 0)
				{
					targetList.Clear();
					targetList.AddRange(list);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Error parsing ConfigList: {arg}");
			}
		}
	}
}
namespace AdjustablePortals.common
{
	internal static class Extensions
	{
		public static bool RemoveItemByPrefab(this Inventory inv, string prefab, int countToRemove)
		{
			List<ItemData> allItems = inv.GetAllItems();
			int num = countToRemove;
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData item in allItems)
			{
				if (!(((Object)item.m_dropPrefab).name == prefab))
				{
					continue;
				}
				if (item.m_stack > 0)
				{
					if (num < item.m_stack)
					{
						item.m_stack -= num;
						break;
					}
					if (item.m_stack <= num)
					{
						list.Add(item);
						num -= item.m_stack;
					}
					else
					{
						item.m_stack -= num;
						num = 0;
					}
				}
				else
				{
					list.Add(item);
				}
			}
			foreach (ItemData item2 in list)
			{
				inv.RemoveItem(item2);
			}
			Logger.LogDebug($"Remove summary: {prefab}x{countToRemove} successfully removed: {countToRemove - num}");
			return num == 0;
		}
	}
}