Decompiled source of UltraPortal v0.1.4

UltraPortal/UltraPortal.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Configgy;
using HarmonyLib;
using TMPro;
using ULTRAKILL.Portal;
using ULTRAKILL.Portal.Geometry;
using UltraPortal.Colorizers;
using UltraPortal.Extensions;
using UltraPortal.Projectiles;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UltraPortal")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UltraPortal")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E06BCEE7-CB1F-477B-B385-AF8D67AD477C")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UltraPortal
{
	public static class AssetBundleHelpers
	{
		private static Dictionary<string, AssetBundle> LoadedBundles = new Dictionary<string, AssetBundle>();

		public static AssetBundle LoadAssetBundle(string bundleName)
		{
			string text = Path.Combine(Constants.AssetPaths.BundlePath, bundleName);
			if (!LoadedBundles.ContainsKey(bundleName))
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if ((Object)(object)val == (Object)null)
				{
					string text2 = "Failed to load Asset Bundle: " + bundleName;
					MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("<color=red>" + text2 + "</color>", "", "", 0, false, false, true);
					Plugin.LogSource.LogError((object)text2);
					return null;
				}
				LoadedBundles.Add(bundleName, val);
			}
			return LoadedBundles[bundleName];
		}
	}
	public static class Constants
	{
		public static class AssetPaths
		{
			public static bool UseAltBundlePath;

			public const string PortalBundle = "portals";

			public const string WeaponBundle = "weapons";

			public const string PortalExit = "Portal Exit";

			public const string Mirror = "Mirror";

			public const string PortalGun = "Portal Gun";

			public const string MirrorGun = "Mirror Gun";

			public const string Projectile = "Projectile";

			public const string PortalGunIcon = "UltraPortalGunIcon";

			public const string PortalGunIconGlow = "UltraPortalGunIconGlow";

			public static string AssemblyPath => Assembly.GetExecutingAssembly().Location;

			public static string AssemblyFolderPath => Path.GetDirectoryName(AssemblyPath);

			public static string BundlePath
			{
				get
				{
					if (UseAltBundlePath)
					{
						return AssemblyFolderPath;
					}
					return Path.Combine(AssemblyFolderPath, "Bundles");
				}
			}
		}

		private static Camera _mainCamera;

		public static LayerMask EnvironmentLayer => LayerMask.op_Implicit(LayerMask.GetMask(new string[5] { "Environment", "EnvironmentBaked", "PlayerOnly", "Outdoors", "OutdoorsBaked" }));

		public static LayerMask PortalLayer => LayerMask.op_Implicit(LayerMask.NameToLayer("Portal"));

		public static Camera MainCamera
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_mainCamera))
				{
					_mainCamera = Camera.main;
				}
				return _mainCamera;
			}
		}
	}
	public class DynamicPortalExit : MonoBehaviour
	{
		private const string TooCloseTrigger = "Too Close Trigger";

		private static bool _playerNearEntry;

		private static bool _playerNearExit;

		private const string ExpectedPassableName = "Passable";

		private const float SphereCheckRadius = 0.2f;

		private static Action<PortalSide, Collider, bool> _toggleColliderAction;

		public Action OnInitialized;

		public Portal hostPortal;

		public PortalSide side;

		private DynamicPortalTooClose _tooClose;

		private GameObject _passableBlockage;

		private List<Collider> _colliders = new List<Collider>();

		private readonly List<Collider> _currentTravellers = new List<Collider>();

		private ParticleSystem _particles;

		private PortalColorManager _colorManager;

		public bool IsEntityNear
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)side == 1)
				{
					return _playerNearEntry;
				}
				return _playerNearExit;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)side == 1)
				{
					_playerNearEntry = value;
				}
				else
				{
					_playerNearExit = value;
				}
			}
		}

		public bool AssistedPortalTravel { get; private set; } = false;


		public Vector3 PortalCenter
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//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)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if ((int)side == 1)
				{
					return hostPortal.entryCenter;
				}
				return hostPortal.exitCenter;
			}
		}

		public bool IsBlocked
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_passableBlockage))
				{
					return false;
				}
				return _passableBlockage.activeSelf;
			}
		}

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).gameObject.layer = LayerMask.op_Implicit(Constants.PortalLayer);
			_particles = ((Component)this).GetComponentInChildren<ParticleSystem>();
			_passableBlockage = ((Component)((Component)this).transform.Find("Passable")).gameObject;
			_colorManager = ((Component)this).gameObject.AddComponent<PortalColorManager>();
			_colorManager.associated = this;
			_toggleColliderAction = (Action<PortalSide, Collider, bool>)Delegate.Combine(_toggleColliderAction, (Action<PortalSide, Collider, bool>)delegate(PortalSide portalSide, Collider collider, bool toggle)
			{
				ToggleColliders(toggle, collider);
			});
		}

		private void AddCollider(Collider c)
		{
			if (Object.op_Implicit((Object)(object)c))
			{
				Plugin.LogSource.LogInfo((object)("Adding collider: " + ((Object)c).name));
				_colliders.Add(c);
			}
		}

		private void GetNearbyCollider()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Collider[] collection = Physics.OverlapSphere(((Component)this).transform.position, 0.2f, LayerMask.op_Implicit(Constants.EnvironmentLayer), (QueryTriggerInteraction)1);
			_colliders.AddRange(collection);
			RaycastHit[] array = Physics.SphereCastAll(((Component)this).transform.position, 0.2f, ((Component)this).transform.forward, 3f, LayerMask.op_Implicit(Constants.EnvironmentLayer), (QueryTriggerInteraction)1);
			if (array.Length < 1)
			{
				return;
			}
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val = array2[i];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider))
				{
					AddCollider(((RaycastHit)(ref val)).collider);
				}
			}
		}

		public void Initialize(Portal portal, PortalSide portalSide, RaycastHit hit)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)portal))
			{
				Plugin.LogSource.LogError((object)"Portal is invalid!");
				return;
			}
			if (_colliders.Count > 0)
			{
				foreach (Collider currentTraveller in _currentTravellers)
				{
					if (Object.op_Implicit((Object)(object)currentTraveller))
					{
						Plugin.LogSource.LogInfo((object)("Resetting: " + ((Object)currentTraveller).name));
						ToggleColliders(value: false, currentTraveller);
					}
				}
			}
			_colliders = new List<Collider>();
			if (ModConfig.ShowPortalSpawnParticles && Object.op_Implicit((Object)(object)_particles))
			{
				_particles.Play();
			}
			((Component)this).transform.forward = -((RaycastHit)(ref hit)).normal;
			Transform transform = ((Component)this).transform;
			Vector3 point = ((RaycastHit)(ref hit)).point;
			Vector3 normal = ((RaycastHit)(ref hit)).normal;
			transform.position = point + ((Vector3)(ref normal)).normalized * ModConfig.PortalWallOffset;
			float num = Mathf.Abs(Vector3.Dot(((Component)this).transform.forward, PhysicsExtensions.GetGravityVector(MonoSingleton<NewMovement>.Instance.rb)));
			AssistedPortalTravel = num > 0.6f;
			hostPortal = portal;
			side = portalSide;
			AddCollider(((RaycastHit)(ref hit)).collider);
			GetNearbyCollider();
			Transform val = ((Component)this).transform.Find("Too Close Trigger");
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.LogSource.LogError((object)("Failed to find Too Close Trigger on " + ((Object)this).name + "."));
				return;
			}
			_tooClose = ((Component)val).gameObject.AddComponent<DynamicPortalTooClose>();
			if (OnInitialized != null)
			{
				OnInitialized();
			}
			_colorManager.ColorPortal();
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if ((Object.op_Implicit((Object)(object)_passableBlockage) && _passableBlockage.activeSelf) || _colliders.Contains(other))
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)other.attachedRigidbody))
			{
				if (!other.isTrigger)
				{
					AddCollider(other);
				}
			}
			else if (!(((Object)other).name == "Projectile Parry Zone"))
			{
				_toggleColliderAction(side, other, arg3: true);
				if (!_currentTravellers.Contains(other))
				{
					_currentTravellers.Add(other);
				}
			}
		}

		public void SetPassable(bool canPass)
		{
			if (!Object.op_Implicit((Object)(object)_passableBlockage))
			{
				Plugin.LogSource.LogInfo((object)(((Object)this).name + " doesn't have a portal blockage defined! Ensure your blockage is called: \"Passable\""));
			}
			else
			{
				_passableBlockage.SetActive(!canPass);
			}
		}

		private void OnTriggerExit(Collider other)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((!Object.op_Implicit((Object)(object)_passableBlockage) || !_passableBlockage.activeSelf) && !_colliders.Contains(other) && Object.op_Implicit((Object)(object)other.attachedRigidbody))
			{
				_toggleColliderAction(side, other, arg3: false);
				if (_currentTravellers.Contains(other))
				{
					_currentTravellers.Remove(other);
				}
			}
		}

		private void ToggleColliders(bool value, Collider other)
		{
			foreach (Collider collider in _colliders)
			{
				if (Object.op_Implicit((Object)(object)collider))
				{
					if (!AssistedPortalTravel || !((Component)other).CompareTag("Player"))
					{
						Physics.IgnoreCollision(collider, other, value);
					}
					else
					{
						collider.enabled = !value;
					}
				}
			}
		}
	}
	public class DynamicPortalTooClose : MonoBehaviour
	{
		public List<Collider> travellers;

		private void Awake()
		{
			travellers = new List<Collider>();
		}

		private void OnTriggerEnter(Collider other)
		{
			if (Object.op_Implicit((Object)(object)other.attachedRigidbody) && !other.isTrigger)
			{
				travellers.Add(other);
			}
		}

		private void OnTriggerExit(Collider other)
		{
			if (travellers.Contains(other))
			{
				travellers.Remove(other);
			}
		}
	}
	public static class ModConfig
	{
		[Configgable("Controls", "Portal Gun Slot", 0, null)]
		public static KeyCode PortalGunKeybind = (KeyCode)55;

		[Configgable("Controls", "Despawn Portals", 0, null)]
		public static KeyCode DespawnPortalsKeybind = (KeyCode)116;

		[Configgable("Gameplay", null, 0, null)]
		public static bool UseOtherPortalForProjectileTeleport = true;

		[Configgable("Visuals", null, 0, null)]
		public static Color PrimaryPortalColor = new Color(84f / 85f, 1f / 85f, 23f / 85f);

		[Configgable("Visuals", null, 0, null)]
		public static Color PrimaryPortalParticleColor = new Color(0.5803922f, 8f / 85f, 19f / 85f);

		[Configgable("Visuals", null, 0, null)]
		public static Color SecondaryPortalColor = new Color(0.18039216f, 0.23529412f, 1f);

		[Configgable("Visuals", null, 0, null)]
		public static Color SecondaryPortalParticleColor = new Color(0.101960786f, 0.11764706f, 0.36078432f);

		[Configgable("Visuals", null, 0, null)]
		public static bool UseEmission = true;

		[Configgable("Visuals", null, 0, null)]
		public static bool ShowPortalSpawnParticles = true;

		[Configgable("Gameplay/Projectiles/Advanced", "Projectile Speed", 0, null)]
		public static float PortalProjectileSpeed = 95f;

		[Configgable("", "Enabled", 0, null)]
		public static bool IsEnabled = true;

		[Configgable("Gameplay/Projectiles/Advanced", null, 0, null)]
		public static float ProjectileEnemyGroundPortalBoostMultiplier = 0.5f;

		[Configgable("Gameplay/Projectiles/Advanced", null, 0, null)]
		public static float ProjectileEnemyNormalPortalBoostMultiplier = 2f;

		[Configgable("Gameplay/Portals/Advanced", "Minimum Entry/Exit Speed (scene reload required)", 0, null)]
		public static float MinimumEntryExitSpeed = 20f;

		[Configgable("Gameplay/Portals/Advanced", "Portal Wall Offset", 0, null)]
		public static float PortalWallOffset = 0.45f;
	}
	[HarmonyPatch]
	public static class LevelPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(FinalRank), "SetInfo")]
		private static void SetInfoPatch(ref FinalRank __instance, int restarts, bool damage, bool majorUsed, bool cheatsUsed)
		{
			Plugin.LogSource.LogInfo((object)"Patching level ending!");
			if (PortalGunManager.EquippedPortalGun)
			{
				Plugin.LogSource.LogInfo((object)"Portal gun was used!");
				TMP_Text extraInfo = __instance.extraInfo;
				extraInfo.text += "- <color=#FA0A56>PORTAL GUN USED</color>\n";
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameProgressSaver), "SaveRank")]
		private static void SaveRankPatch(ref bool __runOriginal)
		{
			if (PortalGunManager.EquippedPortalGun)
			{
				__runOriginal = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(FinalCyberRank), "GameOver")]
		private static void GameOverPatch()
		{
			if (PortalGunManager.EquippedPortalGun)
			{
				MonoSingleton<StatsManager>.Instance.majorUsed = true;
			}
		}
	}
	[HarmonyPatch]
	public static class PlayerPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(NewMovement), "Respawn")]
		private static void RespawnPatch()
		{
			PortalGun portalGun = Object.FindObjectOfType<PortalGun>(true);
			if (Object.op_Implicit((Object)(object)portalGun))
			{
				portalGun.Reset();
			}
			MirrorGun mirrorGun = Object.FindObjectOfType<MirrorGun>(true);
			if (Object.op_Implicit((Object)(object)mirrorGun))
			{
				mirrorGun.Reset();
			}
		}
	}
	[BepInPlugin("com.ultraportal", "ULTRAPORTAL", "0.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		private static class PluginInfo
		{
			public const string Name = "ULTRAPORTAL";

			public const string Guid = "com.ultraportal";

			public const string Version = "0.1.1";
		}

		private ConfigBuilder config;

		public static ManualLogSource LogSource { get; private set; }

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			LogSource = ((BaseUnityPlugin)this).Logger;
			Harmony val = new Harmony("com.ultraportal");
			val.PatchAll();
			config = new ConfigBuilder("com.ultraportal", "ULTRAPORTAL");
			config.BuildAll();
			if (!Directory.Exists(Constants.AssetPaths.BundlePath))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Path for ULTRAPORTAL bundles does not exist! Looked for: " + Constants.AssetPaths.BundlePath + "; Trying other bundle path."));
				Constants.AssetPaths.UseAltBundlePath = true;
			}
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode loadMode)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			PortalGunManager.EquippedPortalGun = false;
			if ((int)loadMode != 0 || SceneHelper.CurrentScene == "Intro" || SceneHelper.CurrentScene == "Main Menu")
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Currently playing: " + SceneHelper.CurrentScene));
				GameObject val = new GameObject("Portal Gun Manager");
				val.AddComponent<PortalGunManager>();
			}
			catch
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Scene is not compatible! Failed to spawn portal spawner!");
			}
		}
	}
	[DefaultExecutionOrder(-100000)]
	public class PortalGunManager : MonoBehaviour
	{
		public static PortalGunManager Instance;

		private static int PortalGunSlot = -1;

		public static bool EquippedPortalGun = false;

		private int _currentVariationIndex = -1;

		private PortalGun _portalGun;

		private MirrorGun _mirrorGun;

		private bool _wasEnabledLastFrame = false;

		private GunBase SpawnPortalGun(Type type, string assetPrefabPath, WeaponVariant variant, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (!type.IsSubclassOf(typeof(GunBase)))
			{
				Plugin.LogSource.LogError((object)"Type must be a subclass of GunBase!");
				return null;
			}
			AssetBundle val = AssetBundleHelpers.LoadAssetBundle("weapons");
			GameObject val2 = val.LoadAsset<GameObject>(assetPrefabPath);
			GameObject val3 = Object.Instantiate<GameObject>(val2, Vector3.zero, Quaternion.identity, ((Component)MonoSingleton<GunControl>.Instance).transform);
			val3.transform.localPosition = position;
			val3.transform.localEulerAngles = rotation;
			val3.transform.localScale = scale;
			GunBase gunBase = val3.AddComponent(type) as GunBase;
			gunBase.fireCooldown = 0.5f;
			gunBase.icon = val.LoadAsset<Sprite>("UltraPortalGunIcon");
			gunBase.glowIcon = val.LoadAsset<Sprite>("UltraPortalGunIconGlow");
			gunBase.variant = variant;
			val3.SetActive(false);
			return gunBase;
		}

		private void Start()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			_portalGun = SpawnPortalGun(typeof(PortalGun), "Portal Gun", (WeaponVariant)0, new Vector3(0.8236f, -0.7478f, 0.8907f), new Vector3(0f, 263.3673f, 14.1545f), Vector3.one * 1.2f) as PortalGun;
			_mirrorGun = SpawnPortalGun(typeof(MirrorGun), "Mirror Gun", (WeaponVariant)1, new Vector3(0.8236f, -0.7478f, 0.8907f), new Vector3(0f, 263.3673f, 14.1545f), Vector3.one * 1.2f) as MirrorGun;
			if (!Object.op_Implicit((Object)(object)_portalGun) || !Object.op_Implicit((Object)(object)_mirrorGun))
			{
				Plugin.LogSource.LogError((object)$"Portal Gun?: {_portalGun}, Mirror Gun?: {_mirrorGun}");
			}
			if (ModConfig.IsEnabled)
			{
				AddToSlots();
			}
		}

		private void AddToSlots()
		{
			MonoSingleton<GunControl>.Instance.slots.Add(new List<GameObject>
			{
				((Component)_portalGun).gameObject,
				((Component)_mirrorGun).gameObject
			});
			PortalGunSlot = MonoSingleton<GunControl>.Instance.slots.Count;
		}

		public void DestroyPortals()
		{
			if (Object.op_Implicit((Object)(object)_portalGun))
			{
				_portalGun.Reset();
			}
			if (Object.op_Implicit((Object)(object)_mirrorGun))
			{
				_mirrorGun.Reset();
			}
		}

		private void Update()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (MonoSingleton<GunControl>.Instance.currentSlotIndex != PortalGunSlot)
			{
				_currentVariationIndex = -1;
			}
			if (!ModConfig.IsEnabled)
			{
				if (_wasEnabledLastFrame)
				{
					_wasEnabledLastFrame = false;
					DestroyPortals();
					if (MonoSingleton<GunControl>.Instance.currentSlotIndex == PortalGunSlot)
					{
						MonoSingleton<GunControl>.Instance.SwitchWeapon(1, (int?)null, false, false, false);
					}
					MonoSingleton<GunControl>.Instance.slots.RemoveAt(PortalGunSlot - 1);
					PortalGunSlot = -1;
				}
				return;
			}
			if (PortalGunSlot == -1)
			{
				AddToSlots();
			}
			if (!MonoSingleton<OptionsManager>.Instance.paused)
			{
				_wasEnabledLastFrame = true;
				if (Input.GetKeyDown(ModConfig.DespawnPortalsKeybind))
				{
					DestroyPortals();
				}
				if (Input.GetKeyDown(ModConfig.PortalGunKeybind) && Object.op_Implicit((Object)(object)MonoSingleton<GunControl>.Instance))
				{
					EquippedPortalGun = true;
					MonoSingleton<GunControl>.Instance.SwitchWeapon(PortalGunSlot, (int?)(_currentVariationIndex + 1), false, false, true);
					_currentVariationIndex = MonoSingleton<GunControl>.Instance.currentVariationIndex;
				}
			}
		}
	}
	public class CollisionPrinter : MonoBehaviour
	{
		private void OnCollisionEnter(Collision other)
		{
			Plugin.LogSource.LogInfo((object)(((Object)this).name + " COLLIDED WITH " + ((Object)other.gameObject).name));
		}

		private void OnCollisionExit(Collision other)
		{
			Plugin.LogSource.LogInfo((object)(((Object)this).name + " STOPPED COLLIDING WITH " + ((Object)other.gameObject).name));
		}

		private void OnTriggerEnter(Collider other)
		{
			Plugin.LogSource.LogInfo((object)(((Object)this).name + " IN TRIGGER " + ((Object)((Component)other).gameObject).name));
		}

		private void OnTriggerExit(Collider other)
		{
			Plugin.LogSource.LogInfo((object)(((Object)this).name + " STOPPED TRIGGERING " + ((Object)((Component)other).gameObject).name));
		}
	}
	public class LayerPrinter : MonoBehaviour
	{
		private List<int> _collectedLayers = new List<int>();

		private Dictionary<int, List<GameObject>> _objectMap = new Dictionary<int, List<GameObject>>();

		private void GatherChildren(Transform root)
		{
			for (int i = 0; i < root.childCount; i++)
			{
				GameObject gameObject = ((Component)((Component)this).transform.GetChild(i)).gameObject;
				AddLayer(gameObject.layer, gameObject);
			}
		}

		private void Start()
		{
			_collectedLayers = new List<int>();
			_objectMap = new Dictionary<int, List<GameObject>>();
			AddLayer(((Component)this).gameObject.layer, ((Component)this).gameObject);
			GatherChildren(((Component)this).transform);
			Plugin.LogSource.LogInfo((object)("-- LAYERS IN " + ((Object)((Component)this).gameObject).name + " --"));
			foreach (int collectedLayer in _collectedLayers)
			{
				Plugin.LogSource.LogInfo((object)("- " + LayerMask.LayerToName(collectedLayer) + " -"));
				foreach (GameObject item in _objectMap[collectedLayer])
				{
					Plugin.LogSource.LogInfo((object)(((Object)item).name ?? ""));
				}
			}
		}

		private void AddLayer(int layer, GameObject obj)
		{
			if (_collectedLayers.Contains(layer))
			{
				List<GameObject> list = _objectMap[layer];
				list.Add(obj);
			}
			else
			{
				_collectedLayers.Add(layer);
				_objectMap.Add(layer, new List<GameObject>());
			}
		}
	}
	public class GunBase : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <IFireCooldown>d__13 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public bool isPrimary;

			public GunBase <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>4__this.SetCanFire(isPrimary, value: false);
					<>2__current = (object)new WaitForSeconds(<>4__this.fireCooldown);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>4__this.SetCanFire(isPrimary, value: true);
					return false;
				}
			}

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

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

		public float fireCooldown = 1f;

		protected Action OnPrimaryFire;

		protected Action OnSecondaryFire;

		protected bool CanPrimaryFire = true;

		protected bool CanSecondaryFire = true;

		public WeaponVariant variant;

		public Sprite icon;

		public Sprite glowIcon;

		protected WeaponPos WeaponPos;

		protected WeaponIcon WeaponIcon;

		protected WeaponIdentifier WeaponIdentifier;

		protected virtual void Start()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			WeaponPos = ((Component)this).gameObject.AddComponent<WeaponPos>();
			WeaponIdentifier = ((Component)this).gameObject.AddComponent<WeaponIdentifier>();
			WeaponIdentifier.speedMultiplier = 1f;
			WeaponIcon = ((Component)this).gameObject.AddComponent<WeaponIcon>();
			WeaponIcon.weaponDescriptor = ScriptableObject.CreateInstance<WeaponDescriptor>();
			WeaponIcon.weaponDescriptor.icon = icon;
			WeaponIcon.weaponDescriptor.glowIcon = glowIcon;
			WeaponIcon.weaponDescriptor.variationColor = variant;
		}

		private void SetCanFire(bool isPrimary, bool value)
		{
			if (isPrimary)
			{
				CanPrimaryFire = value;
			}
			else
			{
				CanSecondaryFire = false;
			}
		}

		[IteratorStateMachine(typeof(<IFireCooldown>d__13))]
		protected virtual IEnumerator IFireCooldown(bool isPrimary)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <IFireCooldown>d__13(0)
			{
				<>4__this = this,
				isPrimary = isPrimary
			};
		}

		protected virtual void Update()
		{
			if (MonoSingleton<OptionsManager>.Instance.paused)
			{
				return;
			}
			if (MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasPerformedThisFrame && CanPrimaryFire)
			{
				if (OnPrimaryFire != null)
				{
					OnPrimaryFire();
				}
				((MonoBehaviour)this).StartCoroutine(IFireCooldown(isPrimary: true));
			}
			if (MonoSingleton<InputManager>.Instance.InputSource.Fire2.WasPerformedThisFrame && CanPrimaryFire)
			{
				if (OnSecondaryFire != null)
				{
					OnSecondaryFire();
				}
				((MonoBehaviour)this).StartCoroutine(IFireCooldown(isPrimary: true));
			}
		}

		protected void PlayerHeadRaycast(out bool success, out RaycastHit hit)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			success = Physics.Raycast(((Component)Constants.MainCamera).transform.position, ((Component)Constants.MainCamera).transform.forward, ref hit, float.PositiveInfinity, LayerMask.op_Implicit(Constants.EnvironmentLayer), (QueryTriggerInteraction)1);
		}

		protected Projectile SpawnProjectileFromAsset(string assetName, float speed)
		{
			AssetBundle val = AssetBundleHelpers.LoadAssetBundle("weapons");
			return SpawnProjectileFromPrefab(val.LoadAsset<GameObject>(assetName), speed);
		}

		protected Projectile SpawnProjectileFromPrefab(GameObject prefab, float speed)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)Constants.MainCamera).transform.position + ((Component)Constants.MainCamera).transform.forward, Quaternion.identity);
			Projectile val2 = val.AddComponent<Projectile>();
			val2.damage = 0f;
			val2.sourceWeapon = ((Component)this).gameObject;
			val2.friendly = true;
			val2.speed = speed;
			val2.bulletType = "";
			val2.ignoreEnvironment = false;
			val2.ignoreExplosions = false;
			val2.unparryable = true;
			((Component)val2).transform.forward = ((Component)Constants.MainCamera).transform.forward;
			return val2;
		}

		protected virtual void OnDisable()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			CanPrimaryFire = true;
			CanSecondaryFire = true;
		}
	}
	public class MirrorGun : PortalGunBase
	{
		private Animator _animator;

		private readonly Vector2 _portalSize = new Vector2(11f, 11f);

		private Portal _portal;

		private DynamicPortalExit _primaryMirror;

		private static ManualLogSource Logger => Plugin.LogSource;

		private static int PrimaryFireAnimHash => Animator.StringToHash("Base Layer.Primary Fire");

		private static int SecondaryFireAnimHash => Animator.StringToHash("Base Layer.Secondary Fire");

		protected override void Start()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			base.Start();
			AssetBundle val = AssetBundleHelpers.LoadAssetBundle("portals");
			GameObject val2 = val.LoadAsset<GameObject>("Mirror");
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Logger.LogError((object)"Failed to load mirror prefab!");
				return;
			}
			_animator = ((Component)this).GetComponentInChildren<Animator>();
			if (!Object.op_Implicit((Object)(object)_animator))
			{
				MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("<color=#ff000>Animator is invalid!</color>", "", "", 0, false, false, true);
			}
			Vector3 val3 = Vector3.down * 100000f;
			GameObject val4 = Object.Instantiate<GameObject>(val2, val3, Quaternion.identity);
			((Object)val4).name = "Mirror Transform";
			_primaryMirror = val4.AddComponent<DynamicPortalExit>();
			_primaryMirror.side = (PortalSide)1;
			DynamicPortalExit primaryMirror = _primaryMirror;
			primaryMirror.OnInitialized = (Action)Delegate.Combine(primaryMirror.OnInitialized, (Action)delegate
			{
				_primaryMirror.SetPassable(canPass: true);
			});
			OnPrimaryFire = (Action)Delegate.Combine(OnPrimaryFire, (Action)delegate
			{
				FireProjectile(_primaryMirror, _portal);
				_animator.Play(PrimaryFireAnimHash);
			});
			UpdateLastProjectile(_primaryMirror.side);
			InitMirror();
		}

		private void InitMirror()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Mirror Head")
			{
				layer = LayerMask.op_Implicit(Constants.PortalLayer)
			};
			_portal = val.AddComponent<Portal>();
			_portal.additionalSampleThreshold = 0f;
			_portal.allowCameraTraversals = true;
			_portal.appearsInRecursions = true;
			_portal.canHearAudio = false;
			_portal.canSeeItself = true;
			_portal.canSeePortalLayer = true;
			_portal.clippingMethod = (PortalClippingMethod)0;
			_portal.consumeAudio = false;
			_portal.disableRange = 0f;
			_portal.enableOverrideFog = false;
			_portal.enterOffset = 1.5f;
			_portal.entry = ((Component)_primaryMirror).transform;
			_portal.minimumEntrySideSpeed = ModConfig.MinimumEntryExitSpeed;
			_portal.exit = ((Component)_primaryMirror).transform;
			_portal.exitOffset = 1.5f;
			_portal.minimumExitSideSpeed = ModConfig.MinimumEntryExitSpeed;
			_portal.renderSettings = (PortalSideFlags)6;
			_portal.fakeVPMatrix = Matrix4x4.zero;
			_portal.mirror = false;
			_portal.shape = (IPortalShape)(object)new PlaneShape
			{
				width = _portalSize.x,
				height = _portalSize.y
			};
		}

		public void Reset()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_primaryMirror))
			{
				((Component)_primaryMirror).transform.position = PortalGun.DefaultPortalPosition;
			}
		}
	}
	public class PortalGun : PortalGunBase
	{
		public static readonly Vector3 DefaultPortalPosition = new Vector3(0f, -1000000f, 0f);

		private Portal _portal;

		private GameObject _portalObject;

		private readonly Vector2 _portalSize = new Vector2(5.95f, 7.95f);

		private DynamicPortalExit _portalEntry;

		private DynamicPortalExit _portalExit;

		private Animator _animator;

		private static ManualLogSource Logger => Plugin.LogSource;

		private static int PrimaryFireAnimHash => Animator.StringToHash("Base Layer.Primary Fire");

		private static int SecondaryFireAnimHash => Animator.StringToHash("Base Layer.Secondary Fire");

		public bool BothPortalsInit
		{
			get
			{
				//IL_0033: 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)
				if (!Object.op_Implicit((Object)(object)_portalEntry) || !Object.op_Implicit((Object)(object)_portalExit))
				{
					return false;
				}
				return ((Component)_portalEntry).transform.position.y > DefaultPortalPosition.y && ((Component)_portalExit).transform.position.y > DefaultPortalPosition.y;
			}
		}

		protected override void Start()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			base.Start();
			AssetBundle val = AssetBundleHelpers.LoadAssetBundle("portals");
			GameObject val2 = val.LoadAsset<GameObject>("Portal Exit");
			if (!Object.op_Implicit((Object)(object)val2))
			{
				Logger.LogError((object)"Failed to load portal prefab!");
				return;
			}
			_animator = ((Component)this).GetComponentInChildren<Animator>();
			if (!Object.op_Implicit((Object)(object)_animator))
			{
				MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("<color=#ff000>Animator is invalid!</color>", "", "", 0, false, false, true);
			}
			Vector3 defaultPortalPosition = DefaultPortalPosition;
			GameObject val3 = Object.Instantiate<GameObject>(val2, defaultPortalPosition, Quaternion.identity);
			((Object)val3).name = "Entry";
			_portalEntry = val3.AddComponent<DynamicPortalExit>();
			_portalEntry.side = (PortalSide)1;
			DynamicPortalExit portalEntry = _portalEntry;
			portalEntry.OnInitialized = (Action)Delegate.Combine(portalEntry.OnInitialized, new Action(UpdatePortalPassable));
			_portalEntry.hostPortal = _portal;
			GameObject val4 = Object.Instantiate<GameObject>(val2, defaultPortalPosition, Quaternion.identity);
			((Object)val4).name = "Exit";
			_portalExit = val4.AddComponent<DynamicPortalExit>();
			DynamicPortalExit portalExit = _portalExit;
			portalExit.OnInitialized = (Action)Delegate.Combine(portalExit.OnInitialized, new Action(UpdatePortalPassable));
			_portalExit.side = (PortalSide)2;
			_portalExit.hostPortal = _portal;
			OnPrimaryFire = (Action)Delegate.Combine(OnPrimaryFire, (Action)delegate
			{
				FireProjectile(_portalEntry, _portal);
				UpdateLastProjectile((PortalSide)1);
				_animator.Play(PrimaryFireAnimHash);
			});
			OnSecondaryFire = (Action)Delegate.Combine(OnSecondaryFire, (Action)delegate
			{
				FireProjectile(_portalExit, _portal);
				UpdateLastProjectile((PortalSide)2);
				_animator.Play(SecondaryFireAnimHash);
			});
			InitPortals();
		}

		private void UpdatePortalPassable()
		{
			if (Object.op_Implicit((Object)(object)_portalEntry))
			{
				_portalEntry.SetPassable(BothPortalsInit);
			}
			if (Object.op_Implicit((Object)(object)_portalExit))
			{
				_portalExit.SetPassable(BothPortalsInit);
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_portal))
			{
				Object.Destroy((Object)(object)((Component)_portal).gameObject);
			}
			if (Object.op_Implicit((Object)(object)_portalEntry))
			{
				Object.Destroy((Object)(object)((Component)_portalEntry).gameObject);
			}
			if (Object.op_Implicit((Object)(object)_portalExit))
			{
				Object.Destroy((Object)(object)((Component)_portalExit).gameObject);
			}
		}

		private void InitPortals()
		{
			//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_0022: Expected O, but got Unknown
			//IL_0086: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			_portalObject = new GameObject("Portal")
			{
				layer = LayerMask.op_Implicit(Constants.PortalLayer)
			};
			_portal = _portalObject.AddComponent<Portal>();
			_portal.additionalSampleThreshold = 0f;
			_portal.allowCameraTraversals = true;
			_portal.appearsInRecursions = true;
			_portal.canHearAudio = false;
			_portal.canSeeItself = true;
			_portal.canSeePortalLayer = true;
			_portal.clippingMethod = (PortalClippingMethod)0;
			_portal.consumeAudio = false;
			_portal.disableRange = 0f;
			_portal.enableOverrideFog = false;
			_portal.enterOffset = 1.5f;
			_portal.entry = ((Component)_portalEntry).transform;
			_portal.minimumEntrySideSpeed = ModConfig.MinimumEntryExitSpeed;
			_portal.exit = ((Component)_portalExit).transform;
			_portal.exitOffset = 1.5f;
			_portal.minimumExitSideSpeed = ModConfig.MinimumEntryExitSpeed;
			_portal.renderSettings = (PortalSideFlags)6;
			_portal.fakeVPMatrix = Matrix4x4.zero;
			_portal.mirror = false;
			_portal.shape = (IPortalShape)(object)new PlaneShape
			{
				width = _portalSize.x,
				height = _portalSize.y
			};
		}

		public void Reset()
		{
			//IL_001c: 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)
			if (Object.op_Implicit((Object)(object)_portalEntry))
			{
				((Component)_portalEntry).transform.position = DefaultPortalPosition;
			}
			if (Object.op_Implicit((Object)(object)_portalExit))
			{
				((Component)_portalExit).transform.position = DefaultPortalPosition;
			}
			UpdatePortalPassable();
		}
	}
	public class PortalGunBase : GunBase
	{
		private const string LastProjectileVisual = "UltraPortalGun/PoralGunRig/RootPortal/Last Projectile";

		protected ProjectileColorManager LastProjectileColors;

		protected override void Start()
		{
			base.Start();
			Transform val = ((Component)this).transform.Find("UltraPortalGun/PoralGunRig/RootPortal/Last Projectile");
			if (Object.op_Implicit((Object)(object)val))
			{
				LastProjectileColors = ((Component)val).gameObject.AddComponent<ProjectileColorManager>();
			}
			else
			{
				Plugin.LogSource.LogWarning((object)"UltraPortalGun/PoralGunRig/RootPortal/Last Projectile is not present on portal gun!");
			}
		}

		protected virtual void UpdateLastProjectile(PortalSide side)
		{
			//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)
			if (Object.op_Implicit((Object)(object)LastProjectileColors))
			{
				LastProjectileColors.side = side;
				LastProjectileColors.ColorProjectile();
			}
		}

		protected virtual void OnEnable()
		{
			if (Object.op_Implicit((Object)(object)LastProjectileColors) && LastProjectileColors.FirstColorDone)
			{
				LastProjectileColors.ColorProjectile();
			}
		}

		protected virtual void FireProjectile(DynamicPortalExit exit, Portal portal)
		{
			//IL_003a: 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)
			Projectile val = SpawnProjectileFromAsset("Projectile", ModConfig.PortalProjectileSpeed);
			PortalProjectileHelper portalProjectileHelper = ((Component)val).gameObject.AddComponent<PortalProjectileHelper>();
			portalProjectileHelper.exit = exit;
			portalProjectileHelper.portal = portal;
			ProjectileColorManager projectileColorManager = ((Component)val).gameObject.AddComponent<ProjectileColorManager>();
			projectileColorManager.side = exit.side;
			projectileColorManager.ColorProjectile();
		}
	}
}
namespace UltraPortal.Projectiles
{
	public class PortalProjectileHelper : MonoBehaviour
	{
		public DynamicPortalExit exit;

		public Portal portal;

		private Transform OtherExitTransform
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Invalid comparison between Unknown and I4
				if ((int)exit.side == 1)
				{
					return portal.exit;
				}
				return portal.entry;
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			EnemyIdentifier componentInParent = ((Component)other).GetComponentInParent<EnemyIdentifier>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				if (Object.op_Implicit((Object)(object)portal) && !exit.IsBlocked)
				{
					Rigidbody component = ((Component)componentInParent).gameObject.GetComponent<Rigidbody>();
					Transform val = (ModConfig.UseOtherPortalForProjectileTeleport ? OtherExitTransform : ((Component)exit).transform);
					DynamicPortalExit dynamicPortalExit = (ModConfig.UseOtherPortalForProjectileTeleport ? ((Component)val).GetComponent<DynamicPortalExit>() : exit);
					((Component)componentInParent).transform.position = val.position - val.forward;
					float num = (dynamicPortalExit.AssistedPortalTravel ? ModConfig.ProjectileEnemyGroundPortalBoostMultiplier : ModConfig.ProjectileEnemyNormalPortalBoostMultiplier);
					component.velocity = -val.forward * ModConfig.PortalProjectileSpeed * num;
				}
			}
			else if (Object.op_Implicit((Object)(object)other) && Constants.EnvironmentLayer.Contains(((Component)other).gameObject.layer))
			{
				Vector3 position = ((Component)this).transform.position;
				Vector3 forward = ((Component)this).transform.forward;
				RaycastHit hit = default(RaycastHit);
				if (!Physics.Raycast(position - ((Vector3)(ref forward)).normalized, ((Component)this).transform.forward, ref hit, float.PositiveInfinity, LayerMask.op_Implicit(Constants.EnvironmentLayer), (QueryTriggerInteraction)1))
				{
					Plugin.LogSource.LogError((object)"Failed to find surface that projectile hit!");
				}
				else
				{
					exit.Initialize(portal, exit.side, hit);
				}
			}
		}
	}
}
namespace UltraPortal.Extensions
{
	public static class LayerMaskExtensions
	{
		public static bool Contains(this LayerMask mask, int layer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return (LayerMask.op_Implicit(mask) & (1 << layer)) != 0;
		}
	}
}
namespace UltraPortal.Colorizers
{
	public class PortalColorManager : MonoBehaviour
	{
		private const string VisualsPath = "Visuals";

		public DynamicPortalExit associated;

		private Renderer[] _renderers;

		private void Start()
		{
			Transform val = ((Component)this).transform.Find("Visuals");
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.LogSource.LogInfo((object)("Couldn't find visuals for " + ((Object)this).name + ", please group your visuals under an object called \"Visuals\""));
				((Behaviour)this).enabled = false;
			}
			_renderers = ((Component)val).GetComponentsInChildren<Renderer>();
		}

		public void ColorPortal()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_002b: 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_0030: 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_0085: 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)
			if (_renderers.Length < 1)
			{
				return;
			}
			Color val = (((int)associated.side == 1) ? ModConfig.PrimaryPortalColor : ModConfig.SecondaryPortalColor);
			Renderer[] renderers = _renderers;
			foreach (Renderer val2 in renderers)
			{
				val2.material.SetColor("_Color", val);
				if (ModConfig.UseEmission)
				{
					val2.material.SetColor("_EmissionColor", val);
				}
				else
				{
					val2.material.SetColor("_EmissionColor", Color.black);
				}
			}
		}
	}
	public class ProjectileColorManager : MonoBehaviour
	{
		private const float AltParticleColorMultiplier = 0.784f;

		private const float GlowColorMultiplier = 1.2f;

		private const string GlowParticlesName = "Glow";

		private const string LightningParticles = "Lightning Particles";

		public bool FirstColorDone;

		private Renderer _renderer;

		private ParticleSystem _lightningParticles;

		private ParticleSystem _glowParticles;

		private Light _light;

		public PortalSide side;

		private Color DesiredColor
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//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_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if ((int)side == 1)
				{
					return ModConfig.PrimaryPortalColor;
				}
				return ModConfig.SecondaryPortalColor;
			}
		}

		private Color DesiredParticleColor
		{
			get
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				//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_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if ((int)side == 1)
				{
					return ModConfig.PrimaryPortalParticleColor;
				}
				return ModConfig.SecondaryPortalParticleColor;
			}
		}

		private void GetParticlesInChild(string childName, out ParticleSystem system)
		{
			Transform val = ((Component)this).transform.Find(childName);
			system = null;
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.LogSource.LogError((object)(childName + " not found on " + ((Object)this).name));
				((Behaviour)this).enabled = false;
				return;
			}
			system = ((Component)val).GetComponent<ParticleSystem>();
			if (!Object.op_Implicit((Object)(object)system))
			{
				Plugin.LogSource.LogError((object)("No particle system on " + childName));
				((Behaviour)this).enabled = false;
			}
		}

		private void Awake()
		{
			_renderer = ((Component)this).GetComponent<Renderer>();
			GetParticlesInChild("Lightning Particles", out _lightningParticles);
			GetParticlesInChild("Glow", out _glowParticles);
			_light = ((Component)this).GetComponentInChildren<Light>();
		}

		public void ColorProjectile()
		{
			//IL_0019: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			FirstColorDone = true;
			_renderer.material.SetColor("_Color", DesiredColor);
			_renderer.material.SetColor("_EmissionColor", DesiredColor);
			if (Object.op_Implicit((Object)(object)_light))
			{
				_light.color = DesiredColor;
			}
			_lightningParticles.Stop();
			MainModule main = _lightningParticles.main;
			((MainModule)(ref main)).startColor = new MinMaxGradient(DesiredParticleColor, DesiredParticleColor * 0.784f);
			_lightningParticles.Play();
			_glowParticles.Stop();
			MainModule main2 = _glowParticles.main;
			((MainModule)(ref main2)).startColor = new MinMaxGradient(DesiredParticleColor * 1.2f);
			_glowParticles.Play();
		}
	}
}