Decompiled source of Espejo v1.0.1

plugins\Espejo.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BoplFixedMath;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Espejo")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Bopl Battle mirror shield. Reflects lasers for 6s. Cooldown 6s after it ends.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Espejo")]
[assembly: AssemblyTitle("Espejo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Espejo
{
	public static class EspejoAbility
	{
		public const string AbilityName = "espejo";

		public const string TemplateNameFragment = "invis";

		public const string IconTextureName = "EspejoIcon";

		public const int CooldownSeconds = 6;

		public const int DurationSeconds = 6;

		public const int TicksPerSecond = 60;

		public const int DurationTicks = 360;

		public const int FadeTicks = 30;

		public const float SizeMultiplier = 1.5f;

		public const float HeldWorldSize = 3.8999999f;

		public const float HoldDistance = 1.8000001f;

		public const float HoldHeight = 0f;

		public static readonly Fix HalfLength = (Fix)1.9499999f;

		public static readonly Fix HalfThickness = (Fix)1.4320312f;

		public static readonly Fix BounceOffset = (Fix)0.08f;

		public static readonly Fix MinHitDistance = (Fix)0.05f;

		public static readonly Fix BeamRadiusFallback = (Fix)0.8f;

		public static readonly Vector4 CircleExtents = new Vector4(0.04882813f, 0.04882813f, 0.08300781f, 0.9287109f);

		public static bool IsEspejo(GameObject go)
		{
			if ((Object)(object)go != (Object)null)
			{
				return ((Object)go).name.ToLower().Contains("espejo");
			}
			return false;
		}

		public static bool IsEspejoIcon(Sprite sprite)
		{
			if ((Object)(object)sprite != (Object)null && (Object)(object)sprite.texture != (Object)null)
			{
				return ((Object)sprite.texture).name == "EspejoIcon";
			}
			return false;
		}

		public static Vec2 AimOf(int playerId)
		{
			//IL_0028: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0021: 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_0045: 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)
			PlayerHandler val = PlayerHandler.Get();
			Player val2 = ((val == null) ? null : val.GetPlayer(playerId));
			if (val2 == null)
			{
				return new Vec2(Fix.One, Fix.Zero);
			}
			Vec2 val3 = val2.AimVector();
			if (Vec2.Magnitude(val3) > (Fix)0.2f)
			{
				return Vec2.NormalizedSafe(val3);
			}
			return new Vec2(Fix.One, Fix.Zero);
		}

		public static float PlayerScale(int playerId)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			PlayerHandler val = PlayerHandler.Get();
			Player val2 = ((val == null) ? null : val.GetPlayer(playerId));
			if (val2 != null)
			{
				return Mathf.Max(0.01f, (float)val2.Scale);
			}
			return 1f;
		}

		public static Fix PlayerScaleFix(int playerId)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_003c: 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)
			PlayerHandler val = PlayerHandler.Get();
			Player val2 = ((val == null) ? null : val.GetPlayer(playerId));
			if (val2 == null)
			{
				return Fix.One;
			}
			Fix scale = val2.Scale;
			if (!(scale > (Fix)0.01f))
			{
				return Fix.One;
			}
			return scale;
		}

		public static Sprite LoadIcon(Sprite template)
		{
			//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_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)
			Texture2D val = LoadTexture("Espejo.AbilityIcon.png");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			int size = 128;
			float pixelsPerUnit = 100f;
			if ((Object)(object)template != (Object)null)
			{
				Rect rect = template.rect;
				if (((Rect)(ref rect)).width > 8f)
				{
					rect = template.rect;
					size = Mathf.RoundToInt(((Rect)(ref rect)).width);
				}
				pixelsPerUnit = template.pixelsPerUnit;
			}
			Texture2D obj = BlitCentered(val, size, 0.78f);
			((Object)obj).name = "EspejoIcon";
			((Texture)obj).filterMode = (FilterMode)1;
			((Texture)obj).wrapMode = (TextureWrapMode)1;
			obj.Apply(false, false);
			Sprite obj2 = Build(obj, pixelsPerUnit);
			((Object)obj2).name = "espejo";
			return obj2;
		}

		public static Sprite LoadHeldMirror()
		{
			Texture2D val = LoadTexture("Espejo.AbilityIcon.png");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			((Object)val).name = "EspejoHeld";
			return Build(val, (float)((Texture)val).height / 3.8999999f);
		}

		private static Texture2D BlitCentered(Texture2D source, int size, float fill)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00d8: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			Color[] pixels = (Color[])(object)new Color[size * size];
			val.SetPixels(pixels);
			int num = Mathf.Max(1, Mathf.RoundToInt((float)size * fill));
			int num2 = (size - num) / 2;
			int num3 = (size - num) / 2;
			Color[] pixels2 = source.GetPixels();
			int width = ((Texture)source).width;
			int height = ((Texture)source).height;
			float num4 = (float)width / (float)height;
			int num5 = num;
			int num6 = num;
			if (num4 > 1f)
			{
				num6 = Mathf.Max(1, Mathf.RoundToInt((float)num / num4));
			}
			else
			{
				num5 = Mathf.Max(1, Mathf.RoundToInt((float)num * num4));
			}
			num2 = (size - num5) / 2;
			num3 = (size - num6) / 2;
			for (int i = 0; i < num6; i++)
			{
				int num7 = Mathf.Clamp(i * height / num6, 0, height - 1);
				for (int j = 0; j < num5; j++)
				{
					int num8 = Mathf.Clamp(j * width / num5, 0, width - 1);
					Color val2 = pixels2[num7 * width + num8];
					if (!(val2.a < 0.05f))
					{
						val.SetPixel(num2 + j, num3 + i, val2);
					}
				}
			}
			return val;
		}

		private static Sprite Build(Texture2D texture, float pixelsPerUnit)
		{
			//IL_0027: 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)
			((Texture)texture).filterMode = (FilterMode)1;
			((Texture)texture).wrapMode = (TextureWrapMode)1;
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), pixelsPerUnit, 0u, (SpriteMeshType)0);
		}

		private static Texture2D LoadTexture(string resourceName)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				Plugin.Log.LogError((object)("Espejo: embedded resource '" + resourceName + "' not found."));
				return null;
			}
			byte[] array;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				stream.CopyTo(memoryStream);
				array = memoryStream.ToArray();
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				Plugin.Log.LogError((object)("Espejo: '" + resourceName + "' failed to decode as a PNG."));
				return null;
			}
			val.Apply(false, false);
			return val;
		}
	}
	[HarmonyPatch(typeof(AbilityGrid), "Awake")]
	public static class EspejoInjectionPatch
	{
		private static bool hasInjected;

		public static void Prefix(AbilityGrid __instance)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0075: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if (hasInjected)
			{
				return;
			}
			NamedSpriteList abilityIcons = __instance.abilityIcons;
			if ((Object)(object)abilityIcons == (Object)null || abilityIcons.sprites == null)
			{
				Plugin.Log.LogWarning((object)"Espejo: AbilityGrid.abilityIcons was empty this Awake; not injecting yet (will retry on the next grid build).");
				return;
			}
			NamedSprite val = default(NamedSprite);
			bool flag = false;
			foreach (NamedSprite sprite in abilityIcons.sprites)
			{
				if (sprite.name != null && sprite.name.ToLower().Contains("invis"))
				{
					val = sprite;
					flag = true;
					break;
				}
			}
			if (!flag || (Object)(object)val.associatedGameObject == (Object)null)
			{
				Plugin.Log.LogError((object)"Espejo: could not find a native instant ability to clone, so the mirror was not added. (Looked for an ability whose name contains 'invis'.)");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val.associatedGameObject);
			Object.DontDestroyOnLoad((Object)(object)val2);
			((Object)val2).name = "espejo";
			StripTemplateEffect(val2);
			InstantAbility component = val2.GetComponent<InstantAbility>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)"Espejo: the cloned ability has no InstantAbility component.");
				return;
			}
			component.SetCoolDown((Fix)6L);
			Sprite val3 = EspejoAbility.LoadIcon(val.sprite) ?? val.sprite;
			abilityIcons.sprites.Add(new NamedSprite("espejo", val3, val2, true));
			hasInjected = true;
			Plugin.Log.LogInfo((object)("Espejo: ability injected (cloned '" + val.name + "', " + $"hold up to {6}s, cooldown {6}s after release)."));
		}

		private static void StripTemplateEffect(GameObject clone)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			InstantAbility component = clone.GetComponent<InstantAbility>();
			if ((Object)(object)component != (Object)null)
			{
				component.funcOnEnter = new UnityEvent();
				component.isInvisibilty = false;
				component.EffectOnEnter = null;
			}
			Invisibility component2 = clone.GetComponent<Invisibility>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.Destroy((Object)(object)component2);
			}
			SpriteRenderer[] componentsInChildren = clone.GetComponentsInChildren<SpriteRenderer>(true);
			foreach (SpriteRenderer obj in componentsInChildren)
			{
				obj.sprite = null;
				((Renderer)obj).enabled = false;
			}
		}
	}
	[HarmonyPatch(typeof(AbilityReadyIndicator), "SetSprite")]
	public static class EspejoCirclePatch
	{
		public static void Postfix(AbilityReadyIndicator __instance, Sprite sprite)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (EspejoAbility.IsEspejoIcon(sprite))
			{
				SpriteRenderer spriteRen = __instance.GetSpriteRen();
				if (!((Object)(object)spriteRen == (Object)null) && !((Object)(object)((Renderer)spriteRen).material == (Object)null))
				{
					((Renderer)spriteRen).material.SetVector("_CircleExtents", EspejoAbility.CircleExtents);
				}
			}
		}
	}
	[HarmonyPatch(typeof(InstantAbility), "EnterAbility")]
	public static class EspejoCastPatch
	{
		public static void Postfix(InstantAbility __instance)
		{
			if (EspejoAbility.IsEspejo(((Component)__instance).gameObject))
			{
				SpriteRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<SpriteRenderer>(true);
				foreach (SpriteRenderer obj in componentsInChildren)
				{
					obj.sprite = null;
					((Renderer)obj).enabled = false;
				}
				MirrorState.Cast(__instance.playerInfo.playerId, __instance.playerInfo.AbilityButtonUsedIndex012);
			}
		}
	}
	[HarmonyPatch(typeof(Updater), "TickSimulation")]
	public static class EspejoTickPatch
	{
		public static void Postfix()
		{
			MirrorState.Tick();
		}
	}
	[HarmonyPatch(typeof(SlimeController), "OldUpdate")]
	public static class EspejoCooldownHoldPatch
	{
		public static void Postfix(SlimeController __instance)
		{
			MirrorCooldown.FreezeIfActive(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerPhysics), "Move")]
	public static class EspejoMovePatch
	{
		public static void Prefix(PlayerPhysics __instance, ref Vec2 __0)
		{
			//IL_0009: 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 (MirrorRoot.IsRooted(__instance))
			{
				__0 = Vec2.zero;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerPhysics), "Jump")]
	public static class EspejoPhysicsJumpPatch
	{
		public static bool Prefix(PlayerPhysics __instance)
		{
			return !MirrorRoot.IsRooted(__instance);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "Jump")]
	public static class EspejoSlimeJumpPatch
	{
		public static bool Prefix(SlimeController __instance)
		{
			return !MirrorState.IsActive(__instance.GetPlayerId());
		}
	}
	[HarmonyPatch(typeof(PlayerHandler), "ResetForNextStage")]
	public static class EspejoResetPatch
	{
		public static void Prefix()
		{
			MirrorState.ForgetAll();
		}
	}
	[HarmonyPatch(typeof(Updater), "PreLevelLoad")]
	public static class EspejoLevelLoadPatch
	{
		public static void Prefix()
		{
			MirrorState.ForgetAll();
		}
	}
	[HarmonyPatch(typeof(ShootScaleChange), "Shoot")]
	public static class EspejoGrowGunPatch
	{
		public static bool Prefix(ShootScaleChange __instance, Vec2 firepointFIX, Vec2 directionFIX, ref bool hasFired, int playerId, bool alreadyHitWater)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !LaserBounce.TryInterceptGun(__instance, firepointFIX, directionFIX, ref hasFired, playerId, alreadyHitWater);
		}
	}
	[HarmonyPatch(typeof(ShootDuplicator), "Shoot")]
	public static class EspejoDuplicatorGunPatch
	{
		public static bool Prefix(ShootDuplicator __instance, Vec2 firepointFIX, Vec2 directionFIX, ref bool hasFired, int playerId, bool alreadyHitWater)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !LaserBounce.TryInterceptGun(__instance, firepointFIX, directionFIX, ref hasFired, playerId, alreadyHitWater);
		}
	}
	[HarmonyPatch(typeof(ShootQuantum), "Shoot")]
	public static class EspejoQuantumGunPatch
	{
		public static bool Prefix(ShootQuantum __instance, Vec2 firepointFIX, Vec2 directionFIX, ref bool hasFired, int playerId, bool alreadyHitWater)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !LaserBounce.TryInterceptGun(__instance, firepointFIX, directionFIX, ref hasFired, playerId, alreadyHitWater);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAbility")]
	public static class EspejoAddAbilityPatch
	{
		public static void Prefix(ref AbilityMonoBehaviour ability)
		{
			ability = MirrorCooldown.CloneIfShared(ability);
		}
	}
	[HarmonyPatch(typeof(SlimeController), "AddAdditionalAbility")]
	public static class EspejoAddAdditionalAbilityPatch
	{
		public static void Prefix(ref AbilityMonoBehaviour ability)
		{
			ability = MirrorCooldown.CloneIfShared(ability);
		}
	}
	[HarmonyPatch]
	public static class EspejoBeamRaycastPatch
	{
		public static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(DetPhysics), "RaycastBeam", new Type[1] { typeof(int) }, (Type[])null);
		}

		public static void Postfix(DetPhysics __instance, int ind)
		{
			LaserBounce.AfterRaycastBeam(__instance, ind);
		}
	}
	[HarmonyPatch]
	public static class EspejoBeamGlowPatch
	{
		public static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(DetPhysics), "RaycastBeam", new Type[4]
			{
				typeof(Vec2),
				typeof(Vec2),
				typeof(Fix).MakeByRefType(),
				typeof(Fix).MakeByRefType()
			}, (Type[])null);
		}

		public static void Postfix(DetPhysics __instance, Vec2 pos, Vec2 dir, ref Fix beamLength)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			LaserBounce.AfterRaycastBeamGlow(__instance, pos, dir, ref beamLength);
		}
	}
	[HarmonyPatch(typeof(DetPhysics), "UpdateBeams")]
	public static class EspejoBeamFlushPatch
	{
		public static void Postfix(DetPhysics __instance)
		{
			LaserBounce.FlushPendingBeams(__instance);
		}
	}
	internal static class LaserBounce
	{
		private const int MaxBounces = 8;

		private static int gunDepth;

		private static bool flushingBeams;

		private static readonly List<BeamBody> pendingBeams = new List<BeamBody>();

		private static readonly FieldInfo BeamBodiesField = AccessTools.Field(typeof(DetPhysics), "beamBodies");

		private static readonly FieldInfo BeamIsReflectedField = AccessTools.Field(typeof(DetPhysics), "beamIsReflected");

		private static readonly FieldInfo BeamReflectionDistanceField = AccessTools.Field(typeof(DetPhysics), "beamReflectionDistance");

		private static readonly FieldInfo BeamRaycastHitRRsField = AccessTools.Field(typeof(DetPhysics), "beamRaycastHitRRs");

		private static readonly FieldInfo MaxBeamDistanceField = AccessTools.Field(typeof(DetPhysics), "maxBeamDistance");

		private static readonly FieldInfo BeamWidthField = AccessTools.Field(typeof(DetPhysics), "beamWidth");

		private static readonly MethodInfo RaycastBeamInd = AccessTools.Method(typeof(DetPhysics), "RaycastBeam", new Type[1] { typeof(int) }, (Type[])null);

		public static void Forget()
		{
			pendingBeams.Clear();
			gunDepth = 0;
			flushingBeams = false;
		}

		public static bool TryInterceptGun(object gun, Vec2 origin, Vec2 direction, ref bool hasFired, int playerId, bool alreadyHitWater)
		{
			//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_0020: 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: 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_0035: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0075: 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_0077: 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_007a: 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)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00d2: 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)
			if (gun == null || !MirrorState.HasAny() || gunDepth >= 8)
			{
				return false;
			}
			Fix val = ReadFix(gun, "maxDistance");
			if (val <= Fix.Zero)
			{
				return false;
			}
			Vec2 val2 = Vec2.NormalizedSafe(direction);
			DetPhysics val3 = DetPhysics.Get();
			if ((Object)(object)val3 == (Object)null)
			{
				return false;
			}
			if (RaycastInformation.op_Implicit(val3.PointCheckAllRoundedRects(origin)))
			{
				return false;
			}
			if (!MirrorState.TryHit(origin, val2, val, out var distance, out var hitPos, out var normal))
			{
				return false;
			}
			LayerMask mask = ReadMask(gun, alreadyHitWater);
			RaycastInformation val4 = RaycastNative(val3, gun, origin, val2, val, mask);
			if (RaycastInformation.op_Implicit(val4) && val4.nearDist < distance)
			{
				return false;
			}
			DrawIncoming(gun, origin, val2, distance, normal);
			Vec2 val5 = MirrorState.Reflect(val2, normal);
			Vec2 origin2 = hitPos + val5 * EspejoAbility.BounceOffset;
			gunDepth++;
			try
			{
				ShootAgain(gun, origin2, val5, ref hasFired, playerId);
			}
			finally
			{
				gunDepth--;
			}
			return true;
		}

		public static void AfterRaycastBeam(DetPhysics physics, int ind)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0072: 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_0074: 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_007a: 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)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_010c: 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_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: 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_0190: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)physics == (Object)null || !MirrorState.HasAny() || BeamBodiesField == null)
			{
				return;
			}
			BeamBody[] array = (BeamBody[])BeamBodiesField.GetValue(physics);
			if (array == null || ind < 0 || ind >= array.Length)
			{
				return;
			}
			BeamBody val = array[ind];
			Fix val2 = (Fix)((MaxBeamDistanceField == null) ? val.distance : ((Fix)MaxBeamDistanceField.GetValue(physics)));
			Fix extraRadius = BeamRadius(physics, val);
			if (!MirrorState.TryHit(val.position, val.direction, val2, extraRadius, out var distance, out var hitPos, out var normal))
			{
				return;
			}
			Fix val3 = val.distance;
			bool[] array2 = ((BeamIsReflectedField == null) ? null : ((bool[])BeamIsReflectedField.GetValue(physics)));
			Fix[] array3 = ((BeamReflectionDistanceField == null) ? null : ((Fix[])BeamReflectionDistanceField.GetValue(physics)));
			if (array2 != null && ind < array2.Length && array2[ind] && array3 != null && ind < array3.Length)
			{
				val3 = val.distance - array3[ind];
			}
			if (!(distance >= val3))
			{
				val.distance = distance;
				array[ind] = val;
				if (array2 != null && ind < array2.Length)
				{
					array2[ind] = false;
				}
				if (array3 != null && ind < array3.Length)
				{
					array3[ind] = Fix.Zero;
				}
				FixTransform[] array4 = ((BeamRaycastHitRRsField == null) ? null : ((FixTransform[])BeamRaycastHitRRsField.GetValue(physics)));
				if (array4 != null && ind < array4.Length)
				{
					array4[ind] = null;
				}
				Vec2 val4 = MirrorState.Reflect(val.direction, normal);
				BeamBody item = val;
				item.position = hitPos + val4 * EspejoAbility.BounceOffset;
				item.direction = val4;
				item.distance = val2;
				item.id = -val.id;
				pendingBeams.Add(item);
			}
		}

		public static void AfterRaycastBeamGlow(DetPhysics physics, Vec2 pos, Vec2 dir, ref Fix beamLength)
		{
			//IL_0031: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0047: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)physics == (Object)null) && MirrorState.HasAny())
			{
				Fix maxDistance = (Fix)((MaxBeamDistanceField == null) ? beamLength : ((Fix)MaxBeamDistanceField.GetValue(physics)));
				Fix extraRadius = BeamRadius(physics, default(BeamBody));
				if (MirrorState.TryHit(pos, dir, maxDistance, extraRadius, out var distance, out var _, out var _) && distance < beamLength)
				{
					beamLength = distance;
				}
			}
		}

		public static void FlushPendingBeams(DetPhysics physics)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)physics == (Object)null || flushingBeams || pendingBeams.Count == 0)
			{
				return;
			}
			flushingBeams = true;
			try
			{
				int num = 24;
				while (pendingBeams.Count > 0 && num-- > 0)
				{
					BeamBody val = pendingBeams[0];
					pendingBeams.RemoveAt(0);
					int num2 = physics.AddBeamBody(val);
					RaycastBeamInd?.Invoke(physics, new object[1] { num2 });
				}
			}
			finally
			{
				flushingBeams = false;
				pendingBeams.Clear();
			}
		}

		private static Fix BeamRadius(DetPhysics physics, BeamBody body)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0062: 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_005b: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_007e: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			Fix val = EspejoAbility.BeamRadiusFallback;
			if (BeamWidthField != null && (Object)(object)physics != (Object)null && BeamWidthField.GetValue(physics) is Fix val2 && val2 > Fix.Zero)
			{
				val = val2;
			}
			Fix val3 = ((body.scale > Fix.Zero) ? body.scale : Fix.One);
			Fix val4 = val * val3;
			if (!(val4 < EspejoAbility.BeamRadiusFallback))
			{
				return val4;
			}
			return EspejoAbility.BeamRadiusFallback;
		}

		private static RaycastInformation RaycastNative(DetPhysics physics, object gun, Vec2 origin, Vec2 dir, Fix maxDistance, LayerMask mask)
		{
			//IL_0025: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0015: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			ShootDuplicator val = (ShootDuplicator)((gun is ShootDuplicator) ? gun : null);
			if (val != null)
			{
				Fix val2 = ReadFix(val, "tripleRaycastRadius");
				return physics.RaycastToClosestTriple(origin, dir, maxDistance, mask, val2);
			}
			return physics.RaycastToClosest(origin, dir, maxDistance, mask);
		}

		private static void ShootAgain(object gun, Vec2 origin, Vec2 direction, ref bool hasFired, int playerId)
		{
			//IL_0020: 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_002d: 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_003a: 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)
			ShootScaleChange val = (ShootScaleChange)((gun is ShootScaleChange) ? gun : null);
			if (val == null)
			{
				ShootDuplicator val2 = (ShootDuplicator)((gun is ShootDuplicator) ? gun : null);
				if (val2 == null)
				{
					ShootQuantum val3 = (ShootQuantum)((gun is ShootQuantum) ? gun : null);
					if (val3 != null)
					{
						val3.Shoot(origin, direction, ref hasFired, playerId, true);
					}
				}
				else
				{
					val2.Shoot(origin, direction, ref hasFired, playerId, true);
				}
			}
			else
			{
				val.Shoot(origin, direction, ref hasFired, playerId, true);
			}
		}

		private static void DrawIncoming(object gun, Vec2 origin, Vec2 dir, Fix dist, Vec2 normal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = (Vector2)origin;
			Vector2 val2 = (Vector2)dir;
			float num = (float)dist;
			ShootScaleChange val3 = (ShootScaleChange)((gun is ShootScaleChange) ? gun : null);
			if (val3 == null)
			{
				ShootDuplicator val4 = (ShootDuplicator)((gun is ShootDuplicator) ? gun : null);
				if (val4 == null)
				{
					ShootQuantum val5 = (ShootQuantum)((gun is ShootQuantum) ? gun : null);
					if (val5 != null)
					{
						val5.spawnRayCastEffect(val, val2, num, false, normal, true);
					}
				}
				else
				{
					val4.spawnRayCastEffect(val, val2, num, false, true);
				}
			}
			else
			{
				val3.spawnRayCastEffect(val, val2, num, false, true);
			}
		}

		private static Fix ReadFix(object obj, string fieldName)
		{
			//IL_0016: 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_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), fieldName);
			if (fieldInfo == null)
			{
				return Fix.Zero;
			}
			object value = fieldInfo.GetValue(obj);
			if (value is Fix)
			{
				return (Fix)value;
			}
			return Fix.Zero;
		}

		private static LayerMask ReadMask(object gun, bool alreadyHitWater)
		{
			//IL_0057: 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_007b: 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_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_0031: 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_0038: 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)
			if (alreadyHitWater)
			{
				FieldInfo fieldInfo = AccessTools.Field(gun.GetType(), "collisionMaskNoWater");
				if (fieldInfo != null)
				{
					object value = fieldInfo.GetValue(gun);
					if (value is LayerMask)
					{
						return (LayerMask)value;
					}
				}
			}
			FieldInfo fieldInfo2 = AccessTools.Field(gun.GetType(), "collisionMask");
			if (fieldInfo2 == null)
			{
				return default(LayerMask);
			}
			object value2 = fieldInfo2.GetValue(gun);
			if (value2 is LayerMask)
			{
				return (LayerMask)value2;
			}
			return default(LayerMask);
		}
	}
	internal static class MirrorCooldown
	{
		private static readonly FieldInfo TimersField = AccessTools.Field(typeof(SlimeController), "abilityCooldownTimers");

		public static void EnsureUniqueSlots(SlimeController slime)
		{
			if ((Object)(object)slime == (Object)null || slime.abilities == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			for (int i = 0; i < slime.abilities.Count; i++)
			{
				AbilityMonoBehaviour val = slime.abilities[i];
				if ((Object)(object)val == (Object)null || !EspejoAbility.IsEspejo(((Component)val).gameObject))
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				if (!hashSet.Add(instanceID))
				{
					InstantAbility val2 = Clone(val);
					if ((Object)(object)val2 != (Object)null)
					{
						slime.abilities[i] = (AbilityMonoBehaviour)(object)val2;
					}
				}
			}
		}

		public static AbilityMonoBehaviour CloneIfShared(AbilityMonoBehaviour ability)
		{
			if ((Object)(object)ability == (Object)null || !EspejoAbility.IsEspejo(((Component)ability).gameObject))
			{
				return ability;
			}
			return (AbilityMonoBehaviour)(((object)Clone(ability)) ?? ((object)ability));
		}

		public static void FreezeIfActive(SlimeController slime)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)slime == (Object)null)
			{
				return;
			}
			EnsureUniqueSlots(slime);
			int num = MirrorState.ActiveSlot(slime.GetPlayerId());
			if (num < 0 || slime.abilities == null || TimersField == null || num >= slime.abilities.Count)
			{
				return;
			}
			AbilityMonoBehaviour val = slime.abilities[num];
			if ((Object)(object)val == (Object)null || !EspejoAbility.IsEspejo(((Component)val).gameObject) || !(TimersField.GetValue(slime) is Fix[] array) || num >= array.Length)
			{
				return;
			}
			array[num] = Fix.Zero;
			if (slime.AbilityReadyIndicators != null && num < slime.AbilityReadyIndicators.Length)
			{
				AbilityReadyIndicator val2 = slime.AbilityReadyIndicators[num];
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetCooldownProgress(0f);
				}
			}
		}

		private static InstantAbility Clone(AbilityMonoBehaviour ability)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(((Component)ability).gameObject);
			Object.DontDestroyOnLoad((Object)(object)obj);
			((Object)obj).name = "espejo";
			InstantAbility component = obj.GetComponent<InstantAbility>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetCoolDown((Fix)6L);
			}
			return component;
		}
	}
	internal static class MirrorRoot
	{
		private static readonly FieldInfo PlayerIdHolderField = AccessTools.Field(typeof(PlayerPhysics), "playerIdHolder");

		public static bool IsRooted(int playerId)
		{
			return MirrorState.IsActive(playerId);
		}

		public static bool IsRooted(PlayerPhysics physics)
		{
			int num = PlayerIdOf(physics);
			if (num >= 0)
			{
				return IsRooted(num);
			}
			return false;
		}

		public static void Apply(int playerId)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			PlayerCollision[] array = Object.FindObjectsOfType<PlayerCollision>();
			foreach (PlayerCollision val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed && ((Component)val).gameObject.activeInHierarchy && val.GetPlayerId() == playerId)
				{
					PlayerPhysics component = ((Component)val).GetComponent<PlayerPhysics>();
					if ((Object)(object)component != (Object)null)
					{
						component.groundedSpeed = Fix.Zero;
					}
					PlayerBody component2 = ((Component)val).GetComponent<PlayerBody>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.selfImposedVelocity = Vec2.zero;
					}
				}
			}
		}

		private static int PlayerIdOf(PlayerPhysics physics)
		{
			if ((Object)(object)physics == (Object)null)
			{
				return -1;
			}
			if (PlayerIdHolderField != null)
			{
				object? value = PlayerIdHolderField.GetValue(physics);
				IPlayerIdHolder val = (IPlayerIdHolder)((value is IPlayerIdHolder) ? value : null);
				if (val != null)
				{
					return val.GetPlayerId();
				}
			}
			IPlayerIdHolder val2 = ((Component)physics).GetComponent<IPlayerIdHolder>() ?? ((Component)physics).GetComponentInParent<IPlayerIdHolder>();
			if (val2 != null)
			{
				return val2.GetPlayerId();
			}
			return -1;
		}
	}
	internal static class MirrorState
	{
		internal sealed class Mirror
		{
			public int playerId;

			public int abilitySlot = -1;

			public int ticksLeft;

			public int holdArmedTicks;

			public Vec2 a;

			public Vec2 b;

			public Vec2 normal;

			public Vec2 center;

			public Fix halfTangent;

			public Fix halfNormal;
		}

		private static readonly List<Mirror> live = new List<Mirror>();

		private static readonly Fix ParallelEpsilon = (Fix)0.0001;

		public static bool HasAny()
		{
			return live.Count > 0;
		}

		public static bool IsActive(int playerId)
		{
			return Find(playerId) != null;
		}

		public static int ActiveSlot(int playerId)
		{
			return Find(playerId)?.abilitySlot ?? (-1);
		}

		public static void Cast(int playerId, int abilitySlot)
		{
			Mirror mirror = Find(playerId);
			if (mirror != null)
			{
				mirror.abilitySlot = abilitySlot;
				UpdateGeometry(mirror);
				MirrorVisuals.Refresh(playerId);
				MirrorRoot.Apply(playerId);
				return;
			}
			Mirror mirror2 = new Mirror
			{
				playerId = playerId,
				abilitySlot = abilitySlot,
				ticksLeft = 360,
				holdArmedTicks = 2
			};
			UpdateGeometry(mirror2);
			live.Add(mirror2);
			MirrorVisuals.Spawn(playerId);
			MirrorRoot.Apply(playerId);
		}

		public static void Tick()
		{
			for (int num = live.Count - 1; num >= 0; num--)
			{
				Mirror mirror = live[num];
				if (!PlayerBodies.IsAlive(mirror.playerId))
				{
					End(num);
					continue;
				}
				if (mirror.holdArmedTicks > 0)
				{
					mirror.holdArmedTicks--;
				}
				else if (!IsHolding(mirror))
				{
					End(num);
					continue;
				}
				UpdateGeometry(mirror);
				MirrorRoot.Apply(mirror.playerId);
				mirror.ticksLeft--;
				if (mirror.ticksLeft <= 0)
				{
					End(num);
				}
			}
			MirrorVisuals.Tick(live);
		}

		public static void ForgetAll()
		{
			live.Clear();
			MirrorVisuals.DestroyAll();
			LaserBounce.Forget();
		}

		private static void End(int index)
		{
			MirrorVisuals.Destroy(live[index].playerId);
			live.RemoveAt(index);
		}

		private static bool IsHolding(Mirror mirror)
		{
			PlayerHandler val = PlayerHandler.Get();
			Player val2 = ((val == null) ? null : val.GetPlayer(mirror.playerId));
			if (val2 == null)
			{
				return false;
			}
			return val2.AbilityButtonIsDown(mirror.abilitySlot);
		}

		public static Vec2 Reflect(Vec2 direction, Vec2 normal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			Vec2 val = Vec2.NormalizedSafe(normal);
			Vec2 val2 = Vec2.NormalizedSafe(direction);
			return Vec2.NormalizedSafe(val2 - val * ((Fix)2L * Vec2.Dot(val2, val)));
		}

		public static bool TryHit(Vec2 origin, Vec2 direction, Fix maxDistance, out Fix distance, out Vec2 hitPos, out Vec2 normal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return TryHit(origin, direction, maxDistance, Fix.Zero, out distance, out hitPos, out normal);
		}

		public static bool TryHit(Vec2 origin, Vec2 direction, Fix maxDistance, Fix extraRadius, out Fix distance, out Vec2 hitPos, out Vec2 normal)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_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_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_0025: 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_002b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0072: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			distance = maxDistance;
			hitPos = origin;
			normal = Vec2.up;
			bool flag = false;
			Vec2 val = Vec2.NormalizedSafe(direction);
			if (Vec2.SqrMagnitude(val) <= Fix.Zero)
			{
				return false;
			}
			for (int i = 0; i < live.Count; i++)
			{
				Mirror mirror = live[i];
				if (TryHitMirror(origin, val, maxDistance, extraRadius, mirror, out var distance2, out var hitPos2) && (!flag || distance2 < distance))
				{
					flag = true;
					distance = distance2;
					hitPos = hitPos2;
					normal = mirror.normal;
				}
			}
			return flag;
		}

		private static bool TryHitMirror(Vec2 origin, Vec2 dir, Fix maxDistance, Fix extraRadius, Mirror mirror, out Fix distance, out Vec2 hitPos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//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_001d: 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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_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_004f: 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_0059: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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)
			//IL_00a2: 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_00a9: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_010f: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			distance = maxDistance;
			hitPos = origin;
			if (Vec2.Dot(dir, mirror.normal) >= Fix.Zero)
			{
				return false;
			}
			Vec2 val = Vec2.MulByI(mirror.normal);
			Vec2 val2 = origin - mirror.center;
			Fix origin2 = Vec2.Dot(val2, val);
			Fix origin3 = Vec2.Dot(val2, mirror.normal);
			Fix dir2 = Vec2.Dot(dir, val);
			Fix dir3 = Vec2.Dot(dir, mirror.normal);
			Fix val3 = mirror.halfTangent + extraRadius;
			Fix val4 = mirror.halfNormal + extraRadius;
			Fix tEnter = (Fix)(-10000L);
			Fix tExit = maxDistance + Fix.One;
			if (!ClipSlab(origin2, dir2, -val3, val3, ref tEnter, ref tExit))
			{
				return false;
			}
			if (!ClipSlab(origin3, dir3, -val4, val4, ref tEnter, ref tExit))
			{
				return false;
			}
			if (tExit < EspejoAbility.MinHitDistance || tEnter > maxDistance)
			{
				return false;
			}
			Fix val5 = ((tEnter < EspejoAbility.MinHitDistance) ? EspejoAbility.MinHitDistance : tEnter);
			if (val5 > maxDistance)
			{
				return false;
			}
			distance = val5;
			hitPos = origin + dir * val5;
			return true;
		}

		private static bool ClipSlab(Fix origin, Fix dir, Fix min, Fix max, ref Fix tEnter, ref Fix tExit)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0056: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_001c: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (Fix.Abs(dir) <= ParallelEpsilon)
			{
				if (origin >= min)
				{
					return origin <= max;
				}
				return false;
			}
			Fix val = Fix.One / dir;
			Fix val2 = (min - origin) * val;
			Fix val3 = (max - origin) * val;
			if (val2 > val3)
			{
				Fix val4 = val2;
				val2 = val3;
				val3 = val4;
			}
			if (val2 > tEnter)
			{
				tEnter = val2;
			}
			if (val3 < tExit)
			{
				tExit = val3;
			}
			return tEnter <= tExit;
		}

		private static void UpdateGeometry(Mirror mirror)
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0044: 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_004b: 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_005b: 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_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)
			//IL_0067: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			List<Vec2> list = PlayerBodies.PositionsOf(mirror.playerId);
			if (list.Count != 0)
			{
				Vec2 val = EspejoAbility.AimOf(mirror.playerId);
				Fix val2 = EspejoAbility.PlayerScaleFix(mirror.playerId);
				Fix val3 = (Fix)1.8000001f * val2;
				Fix val4 = EspejoAbility.HalfLength * val2;
				Vec2 val5 = Vec2.MulByI(val);
				mirror.center = list[0] + val * val3;
				mirror.normal = val;
				mirror.halfTangent = val4;
				mirror.halfNormal = EspejoAbility.HalfThickness * val2;
				mirror.a = mirror.center - val5 * val4;
				mirror.b = mirror.center + val5 * val4;
			}
		}

		private static Mirror Find(int playerId)
		{
			for (int i = 0; i < live.Count; i++)
			{
				if (live[i].playerId == playerId)
				{
					return live[i];
				}
			}
			return null;
		}
	}
	internal static class MirrorVisuals
	{
		private sealed class Held
		{
			public int playerId;

			public GameObject go;
		}

		private static readonly List<Held> live = new List<Held>();

		private static Sprite heldSprite;

		public static void Spawn(int playerId)
		{
			Destroy(playerId);
			GameObject val = Create(playerId);
			if (!((Object)(object)val == (Object)null))
			{
				live.Add(new Held
				{
					playerId = playerId,
					go = val
				});
			}
		}

		public static void Refresh(int playerId)
		{
			if (Find(playerId) == null)
			{
				Spawn(playerId);
			}
		}

		public static void Tick(List<MirrorState.Mirror> mirrors)
		{
			for (int num = live.Count - 1; num >= 0; num--)
			{
				Held held = live[num];
				MirrorState.Mirror mirror = null;
				for (int i = 0; i < mirrors.Count; i++)
				{
					if (mirrors[i].playerId == held.playerId)
					{
						mirror = mirrors[i];
						break;
					}
				}
				if (mirror == null || (Object)(object)held.go == (Object)null)
				{
					if ((Object)(object)held.go != (Object)null)
					{
						Object.Destroy((Object)(object)held.go);
					}
					live.RemoveAt(num);
				}
				else
				{
					Place(held.go, held.playerId, mirror.ticksLeft);
				}
			}
		}

		public static void Destroy(int playerId)
		{
			for (int num = live.Count - 1; num >= 0; num--)
			{
				if (live[num].playerId == playerId)
				{
					if ((Object)(object)live[num].go != (Object)null)
					{
						Object.Destroy((Object)(object)live[num].go);
					}
					live.RemoveAt(num);
				}
			}
		}

		public static void DestroyAll()
		{
			foreach (Held item in live)
			{
				if ((Object)(object)item.go != (Object)null)
				{
					Object.Destroy((Object)(object)item.go);
				}
			}
			live.Clear();
		}

		private static GameObject Create(int playerId)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0073: Expected O, but got Unknown
			//IL_0074: Expected O, but got Unknown
			if ((Object)(object)heldSprite == (Object)null)
			{
				heldSprite = EspejoAbility.LoadHeldMirror();
			}
			if ((Object)(object)heldSprite == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("EspejoHeld");
			SpriteRenderer obj = val.AddComponent<SpriteRenderer>();
			obj.sprite = heldSprite;
			obj.color = new Color(0.88f, 0.97f, 1f, 0.95f);
			((Renderer)obj).sortingOrder = 80;
			Place(val, playerId, 360);
			return val;
		}

		private static void Place(GameObject go, int playerId, int ticksLeft)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_008a: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_0103: 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_014a: 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)
			SpriteRenderer val = FindPlayerSprite(playerId);
			Vec2 val2 = EspejoAbility.AimOf(playerId);
			float num = EspejoAbility.PlayerScale(playerId);
			int sortingLayerID = 0;
			int sortingOrder = 80;
			Vector3 position = default(Vector3);
			if ((Object)(object)val != (Object)null)
			{
				position = ((Component)val).transform.position;
				sortingLayerID = ((Renderer)val).sortingLayerID;
				sortingOrder = ((Renderer)val).sortingOrder + 3;
			}
			else
			{
				List<Vec2> list = PlayerBodies.PositionsOf(playerId);
				if (list.Count == 0)
				{
					return;
				}
				((Vector3)(ref position))..ctor((float)list[0].x, (float)list[0].y, 0f);
			}
			Vector3 val3 = new Vector3((float)val2.x, (float)val2.y, 0f) * (1.8000001f * num);
			go.transform.position = position + val3;
			float num2 = Mathf.Atan2((float)val2.y, (float)val2.x) * 57.29578f;
			go.transform.rotation = Quaternion.Euler(0f, 0f, num2);
			go.transform.localScale = new Vector3(num, num, 1f);
			SpriteRenderer component = go.GetComponent<SpriteRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				((Renderer)component).sortingLayerID = sortingLayerID;
				((Renderer)component).sortingOrder = sortingOrder;
				Color color = component.color;
				color.a = ((ticksLeft <= 30) ? (Mathf.Clamp01((float)ticksLeft / 30f) * 0.95f) : 0.95f);
				component.color = color;
			}
		}

		private static Held Find(int playerId)
		{
			for (int i = 0; i < live.Count; i++)
			{
				if (live[i].playerId == playerId)
				{
					return live[i];
				}
			}
			return null;
		}

		private static SpriteRenderer FindPlayerSprite(int playerId)
		{
			SlimeController[] array = Object.FindObjectsOfType<SlimeController>();
			foreach (SlimeController val in array)
			{
				if (val.GetPlayerId() == playerId)
				{
					SpriteRenderer playerSprite = val.GetPlayerSprite();
					if ((Object)(object)playerSprite != (Object)null && ((Component)playerSprite).gameObject.activeInHierarchy)
					{
						return playerSprite;
					}
				}
			}
			return null;
		}
	}
	internal static class PlayerBodies
	{
		public static List<Vec2> PositionsOf(int playerId)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			List<Vec2> list = new List<Vec2>();
			PlayerCollision[] array = Object.FindObjectsOfType<PlayerCollision>();
			foreach (PlayerCollision val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed && ((Component)val).gameObject.activeInHierarchy && val.GetPlayerId() == playerId)
				{
					FixTransform component = ((Component)val).GetComponent<FixTransform>();
					if ((Object)(object)component != (Object)null && !component.IsDestroyed)
					{
						list.Add(component.position);
					}
				}
			}
			return list;
		}

		public static bool IsAlive(int playerId)
		{
			return PositionsOf(playerId).Count > 0;
		}
	}
	[BepInPlugin("com.solsticio.boplbattle.espejo", "Espejo", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.solsticio.boplbattle.espejo";

		public const string PluginName = "Espejo";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Espejo: loading...");
			new Harmony("com.solsticio.boplbattle.espejo").PatchAll();
			Log.LogInfo((object)($"Espejo: loaded (hold up to {6}s, " + $"cooldown {6}s after release)."));
		}
	}
}