Decompiled source of MirroredStageVariants v1.1.1

plugins/MirroredStageVariants/MirroredStageVariants.dll

Decompiled 5 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG.Reflection;
using HarmonyLib;
using IL.RoR2;
using LeTai.Asset.TranslucentImage;
using Microsoft.CodeAnalysis;
using MirroredStageVariants.Components;
using MirroredStageVariants.ModCompatibility;
using MirroredStageVariants.Patches;
using MirroredStageVariants.Utils;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.RoR2;
using On.RoR2.CameraModes;
using R2API.Utils;
using Rewired;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.CameraModes;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("MirroredStageVariants")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75839dc2f27153ccff0f0de5f9067186fb316da9")]
[assembly: AssemblyProduct("MirroredStageVariants")]
[assembly: AssemblyTitle("MirroredStageVariants")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MirroredStageVariants
{
	internal static class Commands
	{
		public static bool? OverrideStageIsMirrored { get; private set; }

		[ConCommand(commandName = "msv_force_all", helpText = "Sets or clears mirror override [mirrored/normal/random]")]
		private static void CCOverrideStageIsMirrored(ConCommandArgs args)
		{
			if (((ConCommandArgs)(ref args)).Count < 1)
			{
				if (OverrideStageIsMirrored.HasValue)
				{
					Debug.Log((object)("All stages forced " + (OverrideStageIsMirrored.Value ? "mirrored" : "normal")));
				}
				else
				{
					Debug.Log((object)"No active override");
				}
				return;
			}
			bool? flag;
			switch (((ConCommandArgs)(ref args)).GetArgString(0).ToLower())
			{
			case "mirrored":
			case "mirror":
			case "m":
				flag = true;
				break;
			case "normal":
			case "n":
				flag = false;
				break;
			default:
				flag = null;
				break;
			}
			bool? flag2 = flag;
			if (OverrideStageIsMirrored != flag2)
			{
				OverrideStageIsMirrored = flag2;
				if (OverrideStageIsMirrored.HasValue)
				{
					Debug.Log((object)("All stages forced " + (OverrideStageIsMirrored.Value ? "mirrored" : "normal")));
				}
				else
				{
					Debug.Log((object)"All stages mirrored override cleared");
				}
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("MirroredStageVariants\\");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "MirroredStageVariants\\".Length);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("Gorakh.MirroredStageVariants", "MirroredStageVariants", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.MirroredStageVariants";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "MirroredStageVariants";

		public const string PluginVersion = "1.1.1";

		internal static Main Instance { get; private set; }

		public Material MirrorMaterial { get; private set; }

		public Shader MirrorOverlayShader { get; private set; }

		public static ConfigEntry<float> MirrorChance { get; private set; }

		public static ConfigEntry<bool> MirrorNonStages { get; private set; }

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = SingletonHelper.Assign<Main>(Instance, this);
			initConfigs(((BaseUnityPlugin)this).Config);
			loadAssets();
			MirrorAudioPatch.Apply();
			InvertScreenCoordinatesPatch.Apply();
			InvertInputPatch.Apply();
			InvertScreenBlurPatch.Apply();
			InvertDamageNumberPositionsPatch.Apply();
			InvertTypewriteTextControllerPatch.Apply();
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
		}

		private void OnDestroy()
		{
			MirrorAudioPatch.Undo();
			InvertScreenCoordinatesPatch.Undo();
			InvertInputPatch.Undo();
			InvertScreenBlurPatch.Undo();
			InvertDamageNumberPositionsPatch.Undo();
			InvertTypewriteTextControllerPatch.Undo();
			Instance = SingletonHelper.Unassign<Main>(Instance, this);
		}

		private static void initConfigs(ConfigFile file)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			MirrorChance = file.Bind<float>("General", "Mirror Chance", 50f, new ConfigDescription("The percent chance that any given stage will be mirrored", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			MirrorNonStages = file.Bind<bool>("General", "Mirror Non-Stages", true, "If non-stage scenes (menu, cutscenes) should be mirrored, if enabled, they are always mirrored, if disabled, they are never mirrored.");
			if (RiskOfOptionsCompat.IsEnabled)
			{
				RiskOfOptionsCompat.AddConfigOptions();
			}
		}

		private void loadAssets()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "assets");
			if (!File.Exists(text))
			{
				Log.Error("Assets file not found, expected path: " + text, "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Main.cs", "loadAssets", 87);
				return;
			}
			AssetBundle val;
			try
			{
				val = AssetBundle.LoadFromFile(text);
			}
			catch (Exception data)
			{
				Log.Error_NoCallerPrefix(data);
				return;
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				MirrorMaterial = val.LoadAsset<Material>("Mirror");
				MirrorOverlayShader = val.LoadAsset<Shader>("MirrorOverlay");
			}
		}
	}
}
namespace MirroredStageVariants.Utils
{
	public static class CameraEvents
	{
		[CompilerGenerated]
		private static CameraCallback m_OnPreCull;

		[CompilerGenerated]
		private static CameraCallback m_OnPreRender;

		[CompilerGenerated]
		private static CameraCallback m_OnPostRender;

		public static event CameraCallback OnPreCull
		{
			[CompilerGenerated]
			add
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPreCull;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPreCull, value2, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPreCull;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPreCull, value2, val2);
				}
				while (val != val2);
			}
		}

		public static event CameraCallback OnPreRender
		{
			[CompilerGenerated]
			add
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPreRender;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPreRender, value2, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPreRender;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPreRender, value2, val2);
				}
				while (val != val2);
			}
		}

		public static event CameraCallback OnPostRender
		{
			[CompilerGenerated]
			add
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPostRender;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPostRender, value2, val2);
				}
				while (val != val2);
			}
			[CompilerGenerated]
			remove
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Expected O, but got Unknown
				CameraCallback val = CameraEvents.m_OnPostRender;
				CameraCallback val2;
				do
				{
					val2 = val;
					CameraCallback value2 = (CameraCallback)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)value);
					val = Interlocked.CompareExchange(ref CameraEvents.m_OnPostRender, value2, val2);
				}
				while (val != val2);
			}
		}

		static CameraEvents()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)(CameraCallback)delegate(Camera cam)
			{
				CameraCallback onPreCull = CameraEvents.OnPreCull;
				if (onPreCull != null)
				{
					onPreCull.Invoke(cam);
				}
			});
			Camera.onPreRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)(CameraCallback)delegate(Camera cam)
			{
				CameraCallback onPreRender = CameraEvents.OnPreRender;
				if (onPreRender != null)
				{
					onPreRender.Invoke(cam);
				}
			});
			Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)(CameraCallback)delegate(Camera cam)
			{
				CameraCallback onPostRender = CameraEvents.OnPostRender;
				if (onPostRender != null)
				{
					onPostRender.Invoke(cam);
				}
			});
		}
	}
	public static class CameraUtils
	{
		public static bool ShouldRenderObjectAsMirrored(this Camera camera, GameObject obj)
		{
			if (StageMirrorController.CurrentlyIsMirrored && (camera.cullingMask & (1 << obj.layer)) != 0)
			{
				if (Object.op_Implicit((Object)(object)((Component)camera).GetComponent<MirrorCamera>()))
				{
					return true;
				}
				UICamera val = default(UICamera);
				CameraRigController val2 = ((!((Component)camera).TryGetComponent<UICamera>(ref val)) ? ((Component)camera).GetComponentInParent<CameraRigController>() : val.cameraRigController);
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.sceneCam) && Object.op_Implicit((Object)(object)((Component)val2.sceneCam).GetComponent<MirrorCamera>()))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class CommonShaderIDs
	{
		public static readonly int _SwapCount = Shader.PropertyToID("_SwapCount");

		public static readonly int _SwapPositions = Shader.PropertyToID("_SwapPositions");

		public static readonly int _SwapSizes = Shader.PropertyToID("_SwapSizes");

		public static readonly int _InputTex = Shader.PropertyToID("_InputTex");

		public static readonly int _OverlayTex = Shader.PropertyToID("_OverlayTex");
	}
	public static class CoordinateUtils
	{
		public static float GetInvertedScreenXCoordinate(float coordinate, Rect space)
		{
			float xMin = ((Rect)(ref space)).xMin;
			float xMax = ((Rect)(ref space)).xMax;
			return Util.Remap(coordinate, xMin, xMax, xMax, xMin);
		}

		public static void InvertScreenXCoordinate(ref float coordinate, Rect space)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			coordinate = GetInvertedScreenXCoordinate(coordinate, space);
		}

		public static Vector2 Remap(Vector2 value, Rect inputSpace, Rect outputSpace)
		{
			//IL_0000: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = Util.Remap(value.x, ((Rect)(ref inputSpace)).xMin, ((Rect)(ref inputSpace)).xMax, ((Rect)(ref outputSpace)).xMin, ((Rect)(ref outputSpace)).xMax);
			float num2 = Util.Remap(value.y, ((Rect)(ref inputSpace)).yMin, ((Rect)(ref inputSpace)).yMax, ((Rect)(ref outputSpace)).yMin, ((Rect)(ref outputSpace)).yMax);
			return new Vector2(num, num2);
		}
	}
	public static class TransformExtensions
	{
		public static Matrix4x4 GlobalTransformationFromLocal(this Transform transform, Matrix4x4 localTransformation)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return transform.localToWorldMatrix * localTransformation * transform.worldToLocalMatrix;
		}

		public static IEnumerable<Transform> GetAllChildrenRecursive(this Transform transform)
		{
			yield return transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				foreach (Transform item in transform.GetChild(i).GetAllChildrenRecursive())
				{
					yield return item;
				}
			}
		}
	}
}
namespace MirroredStageVariants.Patches
{
	internal static class CostTextMirrorFix
	{
		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0005: 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_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)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/CostHologramContent.prefab").WaitForCompletion();
			if (Object.op_Implicit((Object)(object)val))
			{
				val.AddComponent<ScaleOnAwakeIfMirrored>().ScaleMultiplier = new Vector3(-1f, 1f, 1f);
			}
			else
			{
				Log.Error("Failed to load cost hologram prefab", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\CostTextMirrorFix.cs", "Init", 21);
			}
		}
	}
	internal static class InvertDamageNumberPositionsPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__DamageNumberManager_Awake;

			public static Manipulator <1>__DamageNumberManager_SpawnDamageNumber;
		}

		public static void Apply()
		{
			//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_001b: Expected O, but got Unknown
			//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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__DamageNumberManager_Awake;
			if (obj == null)
			{
				hook_Awake val = DamageNumberManager_Awake;
				<>O.<0>__DamageNumberManager_Awake = val;
				obj = (object)val;
			}
			DamageNumberManager.Awake += (hook_Awake)obj;
			object obj2 = <>O.<1>__DamageNumberManager_SpawnDamageNumber;
			if (obj2 == null)
			{
				Manipulator val2 = DamageNumberManager_SpawnDamageNumber;
				<>O.<1>__DamageNumberManager_SpawnDamageNumber = val2;
				obj2 = (object)val2;
			}
			DamageNumberManager.SpawnDamageNumber += (Manipulator)obj2;
		}

		public static void Undo()
		{
			//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_001b: Expected O, but got Unknown
			//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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__DamageNumberManager_Awake;
			if (obj == null)
			{
				hook_Awake val = DamageNumberManager_Awake;
				<>O.<0>__DamageNumberManager_Awake = val;
				obj = (object)val;
			}
			DamageNumberManager.Awake -= (hook_Awake)obj;
			object obj2 = <>O.<1>__DamageNumberManager_SpawnDamageNumber;
			if (obj2 == null)
			{
				Manipulator val2 = DamageNumberManager_SpawnDamageNumber;
				<>O.<1>__DamageNumberManager_SpawnDamageNumber = val2;
				obj2 = (object)val2;
			}
			DamageNumberManager.SpawnDamageNumber -= (Manipulator)obj2;
		}

		private static void DamageNumberManager_Awake(orig_Awake orig, DamageNumberManager self)
		{
			orig.Invoke(self);
			((Component)self).gameObject.AddComponent<InvertParticlePositionsOnRender>();
		}

		private static void DamageNumberManager_SpawnDamageNumber(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int emitParamsLocalIndex = -1;
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref emitParamsLocalIndex),
				(Instruction x) => ILPatternMatchingExt.MatchInitobj<EmitParams>(x)
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldloca, emitParamsLocalIndex);
			val.EmitDelegate<<>A{00000001}<EmitParams>>((<>A{00000001}<EmitParams>)delegate(ref EmitParams emitParams)
			{
				//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)
				//IL_0022: 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_002f: Unknown result type (might be due to invalid IL or missing references)
				if (StageMirrorController.CurrentlyIsMirrored)
				{
					Quaternion val2 = Quaternion.Euler(((EmitParams)(ref emitParams)).rotation3D) * Quaternion.Euler(0f, 180f, 0f);
					((EmitParams)(ref emitParams)).rotation3D = ((Quaternion)(ref val2)).eulerAngles;
				}
			});
		}
	}
	internal static class InvertInputPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_CollectLookInput <0>__CameraModeBase_CollectLookInput;

			public static Manipulator <1>__PlayerCharacterMasterController_Update;
		}

		public static void Apply()
		{
			//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_001b: Expected O, but got Unknown
			//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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__CameraModeBase_CollectLookInput;
			if (obj == null)
			{
				hook_CollectLookInput val = CameraModeBase_CollectLookInput;
				<>O.<0>__CameraModeBase_CollectLookInput = val;
				obj = (object)val;
			}
			CameraModeBase.CollectLookInput += (hook_CollectLookInput)obj;
			object obj2 = <>O.<1>__PlayerCharacterMasterController_Update;
			if (obj2 == null)
			{
				Manipulator val2 = PlayerCharacterMasterController_Update;
				<>O.<1>__PlayerCharacterMasterController_Update = val2;
				obj2 = (object)val2;
			}
			PlayerCharacterMasterController.Update += (Manipulator)obj2;
		}

		public static void Undo()
		{
			//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_001b: Expected O, but got Unknown
			//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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__CameraModeBase_CollectLookInput;
			if (obj == null)
			{
				hook_CollectLookInput val = CameraModeBase_CollectLookInput;
				<>O.<0>__CameraModeBase_CollectLookInput = val;
				obj = (object)val;
			}
			CameraModeBase.CollectLookInput -= (hook_CollectLookInput)obj;
			object obj2 = <>O.<1>__PlayerCharacterMasterController_Update;
			if (obj2 == null)
			{
				Manipulator val2 = PlayerCharacterMasterController_Update;
				<>O.<1>__PlayerCharacterMasterController_Update = val2;
				obj2 = (object)val2;
			}
			PlayerCharacterMasterController.Update -= (Manipulator)obj2;
		}

		private static void CameraModeBase_CollectLookInput(orig_CollectLookInput orig, CameraModeBase self, ref CameraModeContext context, out CollectLookInputResult result)
		{
			orig.Invoke(self, ref context, ref result);
			if (StageMirrorController.CurrentlyIsMirrored)
			{
				result.lookInput.x *= -1f;
			}
		}

		private static void PlayerCharacterMasterController_Update(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			ILCursor[] array = default(ILCursor[]);
			if (new ILCursor(il).TryFindNext(ref array, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<Player>((Expression<Action<Player>>)((Player _) => _.GetAxis(0)))),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo<Player>((Expression<Action<Player>>)((Player _) => _.GetAxis(0)))),
				(Instruction x) => ILPatternMatchingExt.MatchCall(x, (MethodBase)AccessTools.DeclaredConstructor(typeof(Vector2), new Type[2]
				{
					typeof(float),
					typeof(float)
				}, false))
			}))
			{
				ILCursor val = array[2];
				int index = val.Index + 1;
				int moveInputLocalIndex = -1;
				if (val.TryGotoPrev(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref moveInputLocalIndex)
				}))
				{
					val.Index = index;
					val.Emit(OpCodes.Ldloca, moveInputLocalIndex);
					val.EmitDelegate<<>A{00000001}<Vector2>>((<>A{00000001}<Vector2>)delegate(ref Vector2 moveInput)
					{
						if (StageMirrorController.CurrentlyIsMirrored)
						{
							moveInput.x *= -1f;
						}
					});
				}
				else
				{
					Log.Error("Failed to find move input local index", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 67);
				}
			}
			else
			{
				Log.Error("Failed to find patch location", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 72);
			}
		}
	}
	internal static class InvertScreenBlurPatch
	{
		private delegate void orig_TranslucentImageSource_ProgressiveBlur(TranslucentImageSource self, RenderTexture sourceRt);

		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__TranslucentImageSource_ProgressiveBlur;
		}

		private static ILHook TranslucentImageSource_ProgressiveBlur_Hook;

		public static void Apply()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			MethodInfo methodInfo = SymbolExtensions.GetMethodInfo<TranslucentImageSource>((Expression<Action<TranslucentImageSource>>)((TranslucentImageSource _) => _.ProgressiveBlur((RenderTexture)null)));
			object obj = <>O.<0>__TranslucentImageSource_ProgressiveBlur;
			if (obj == null)
			{
				Manipulator val = TranslucentImageSource_ProgressiveBlur;
				<>O.<0>__TranslucentImageSource_ProgressiveBlur = val;
				obj = (object)val;
			}
			TranslucentImageSource_ProgressiveBlur_Hook = new ILHook((MethodBase)methodInfo, (Manipulator)obj);
		}

		public static void Undo()
		{
			ILHook translucentImageSource_ProgressiveBlur_Hook = TranslucentImageSource_ProgressiveBlur_Hook;
			if (translucentImageSource_ProgressiveBlur_Hook != null)
			{
				translucentImageSource_ProgressiveBlur_Hook.Undo();
			}
		}

		private static void TranslucentImageSource_ProgressiveBlur(ILContext il)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_00a8: 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)
			ILCursor val = new ILCursor(il);
			int index = val.Index;
			val.Index = index - 1;
			if (val.TryGotoPrev(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCall(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => Graphics.Blit((Texture)null, (RenderTexture)null, (Material)null, 0))))
			}))
			{
				int temporaryTextureLocalIndex = -1;
				if (val.TryGotoPrev((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref temporaryTextureLocalIndex) && Extensions.Is((MemberReference)(object)((VariableReference)il.Body.Variables[temporaryTextureLocalIndex]).VariableType, (MemberInfo)typeof(RenderTexture))
				}))
				{
					val.EmitDelegate<Func<RenderTexture, RenderTexture>>((Func<RenderTexture, RenderTexture>)delegate(RenderTexture texture)
					{
						//IL_0037: Unknown result type (might be due to invalid IL or missing references)
						if (StageMirrorController.CurrentlyIsMirrored)
						{
							Material val2 = (Object.op_Implicit((Object)(object)Main.Instance) ? Main.Instance.MirrorMaterial : null);
							if (Object.op_Implicit((Object)(object)val2))
							{
								RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, texture.format);
								((Texture)temporary).filterMode = (FilterMode)1;
								Graphics.Blit((Texture)(object)texture, temporary, val2);
								RenderTexture.ReleaseTemporary(texture);
								return temporary;
							}
						}
						return texture;
					});
					val.Emit(OpCodes.Dup);
					val.Emit(OpCodes.Stloc, temporaryTextureLocalIndex);
				}
				else
				{
					Log.Error("Failed to find patch location", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertScreenBlurPatch.cs", "TranslucentImageSource_ProgressiveBlur", 68);
				}
			}
			else
			{
				Log.Error("Failed to find Blit call", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertScreenBlurPatch.cs", "TranslucentImageSource_ProgressiveBlur", 73);
			}
		}
	}
	internal static class InvertScreenCoordinatesPatch
	{
		private delegate Vector3 ScreenCoordinateDelegate(Camera self, Vector3 position, MonoOrStereoscopicEye eye);

		private delegate Ray ScreenRayDelegate(Camera self, Vector2 pos, MonoOrStereoscopicEye eye);

		private static Hook Camera_WorldToScreenPoint_Hook;

		private static Hook Camera_WorldToViewportPoint_Hook;

		private static Hook Camera_ViewportToWorldPoint_Hook;

		private static Hook Camera_ScreenToWorldPoint_Hook;

		private static Hook Camera_ViewportPointToRay_Hook;

		private static Hook Camera_ScreenPointToRay_Hook;

		public static void Apply()
		{
			//IL_0029: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00ba: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Expected O, but got Unknown
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Expected O, but got Unknown
			Camera_WorldToScreenPoint_Hook = new Hook((Expression<Action>)(() => ((Camera)null).WorldToScreenPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateResult));
			Camera_WorldToViewportPoint_Hook = new Hook((Expression<Action>)(() => ((Camera)null).WorldToViewportPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateResult));
			Camera_ScreenToWorldPoint_Hook = new Hook((Expression<Action>)(() => ((Camera)null).ScreenToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateInput));
			Camera_ViewportToWorldPoint_Hook = new Hook((Expression<Action>)(() => ((Camera)null).ViewportToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateInput));
			Camera_ScreenPointToRay_Hook = new Hook((Expression<Action>)(() => ((Camera)null).ScreenPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayPixelCoordinateInput));
			Camera_ViewportPointToRay_Hook = new Hook((Expression<Action>)(() => ((Camera)null).ViewportPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayNormalizedCoordinateInput));
		}

		public static void Undo()
		{
			Hook camera_WorldToScreenPoint_Hook = Camera_WorldToScreenPoint_Hook;
			if (camera_WorldToScreenPoint_Hook != null)
			{
				camera_WorldToScreenPoint_Hook.Undo();
			}
			Hook camera_WorldToViewportPoint_Hook = Camera_WorldToViewportPoint_Hook;
			if (camera_WorldToViewportPoint_Hook != null)
			{
				camera_WorldToViewportPoint_Hook.Undo();
			}
			Hook camera_ViewportToWorldPoint_Hook = Camera_ViewportToWorldPoint_Hook;
			if (camera_ViewportToWorldPoint_Hook != null)
			{
				camera_ViewportToWorldPoint_Hook.Undo();
			}
			Hook camera_ScreenToWorldPoint_Hook = Camera_ScreenToWorldPoint_Hook;
			if (camera_ScreenToWorldPoint_Hook != null)
			{
				camera_ScreenToWorldPoint_Hook.Undo();
			}
			Hook camera_ViewportPointToRay_Hook = Camera_ViewportPointToRay_Hook;
			if (camera_ViewportPointToRay_Hook != null)
			{
				camera_ViewportPointToRay_Hook.Undo();
			}
			Hook camera_ScreenPointToRay_Hook = Camera_ScreenPointToRay_Hook;
			if (camera_ScreenPointToRay_Hook != null)
			{
				camera_ScreenPointToRay_Hook.Undo();
			}
		}

		private static bool isMirrored(Camera camera)
		{
			if (StageMirrorController.CurrentlyIsMirrored)
			{
				return Object.op_Implicit((Object)(object)((Component)camera).GetComponent<MirrorCamera>());
			}
			return false;
		}

		private static Vector3 invertPixelCoordinateResult(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye)
		{
			//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_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			Vector3 result = orig(self, position, eye);
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref result.x, self.pixelRect);
			}
			return result;
		}

		private static Vector3 invertPixelCoordinateInput(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref position.x, self.pixelRect);
			}
			return orig(self, position, eye);
		}

		private static Vector3 invertNormalizedCoordinateResult(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye)
		{
			//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_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			Vector3 result = orig(self, position, eye);
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref result.x, self.rect);
			}
			return result;
		}

		private static Vector3 invertNormalizedCoordinateInput(ScreenCoordinateDelegate orig, Camera self, Vector3 position, MonoOrStereoscopicEye eye)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref position.x, self.rect);
			}
			return orig(self, position, eye);
		}

		private static Ray invertRayPixelCoordinateInput(ScreenRayDelegate orig, Camera self, Vector2 pos, MonoOrStereoscopicEye eye)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref pos.x, self.pixelRect);
			}
			return orig(self, pos, eye);
		}

		private static Ray invertRayNormalizedCoordinateInput(ScreenRayDelegate orig, Camera self, Vector2 pos, MonoOrStereoscopicEye eye)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (isMirrored(self))
			{
				CoordinateUtils.InvertScreenXCoordinate(ref pos.x, self.rect);
			}
			return orig(self, pos, eye);
		}
	}
	internal static class InvertTypewriteTextControllerPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__TypewriteTextController_SetTypingTime;
		}

		private static ILHook TypewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook;

		public static void Apply()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.GetDeclaredMethods(typeof(TypewriteTextController)).FirstOrDefault((MethodInfo m) => m.Name.StartsWith("<SetTypingTime>g__UpdateCurrentLabel|"));
			if ((object)methodInfo != null)
			{
				object obj = <>O.<0>__TypewriteTextController_SetTypingTime;
				if (obj == null)
				{
					Manipulator val = TypewriteTextController_SetTypingTime;
					<>O.<0>__TypewriteTextController_SetTypingTime = val;
					obj = (object)val;
				}
				TypewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook = new ILHook((MethodBase)methodInfo, (Manipulator)obj);
			}
			else
			{
				Log.Error("Failed to find local function UpdateCurrentLabel", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "Apply", 27);
			}
		}

		public static void Undo()
		{
			ILHook typewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook = TypewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook;
			if (typewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook != null)
			{
				typewriteTextController_SetTypingTime_UpdateCurrentLabel_Hook.Undo();
			}
		}

		private static void TypewriteTextController_SetTypingTime(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0070: 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)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertySetter(typeof(TMP_Text), "maxVisibleCharacters"))
			}))
			{
				ILLabel val2 = val.DefineLabel();
				ILLabel val3 = val.DefineLabel();
				val.EmitDelegate<Func<bool>>((Func<bool>)(() => StageMirrorController.CurrentlyIsMirrored));
				val.Emit(OpCodes.Brtrue, (object)val2);
				int index = val.Index;
				val.Index = index + 1;
				val.Emit(OpCodes.Br, (object)val3);
				val.MarkLabel(val2);
				val.MoveAfterLabels();
				val.EmitDelegate<Action<TMP_Text, int>>((Action<TMP_Text, int>)delegate(TMP_Text label, int maxVisibleCharacters)
				{
					label.firstVisibleCharacter = label.text.Length - maxVisibleCharacters;
				});
				val.MarkLabel(val3);
			}
			else
			{
				Log.Error("Failed to find patch location", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime", 64);
			}
		}
	}
	internal static class MirrorAudioPatch
	{
		private delegate Vector3 AkGameObj_GetVectorDelegate(AkGameObj self);

		private static Hook AkGameObj_MirrorPosition_Hook;

		private static Hook AkGameObj_MirrorForwardVector_Hook;

		private static Hook AkGameObj_MirrorUpVector_Hook;

		public static void Apply()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			AkGameObj_MirrorPosition_Hook = new Hook((Expression<Action>)(() => ((AkGameObj)null).GetPosition()), (Delegate)new Func<AkGameObj_GetVectorDelegate, AkGameObj, Vector3>(AkGameObj_GenericTryMirrorPositionResult));
			AkGameObj_MirrorForwardVector_Hook = new Hook((Expression<Action>)(() => ((AkGameObj)null).GetForward()), (Delegate)new Func<AkGameObj_GetVectorDelegate, AkGameObj, Vector3>(AkGameObj_GenericTryMirrorVectorResult));
			AkGameObj_MirrorUpVector_Hook = new Hook((Expression<Action>)(() => ((AkGameObj)null).GetUpward()), (Delegate)new Func<AkGameObj_GetVectorDelegate, AkGameObj, Vector3>(AkGameObj_GenericTryMirrorVectorResult));
		}

		public static void Undo()
		{
			Hook akGameObj_MirrorPosition_Hook = AkGameObj_MirrorPosition_Hook;
			if (akGameObj_MirrorPosition_Hook != null)
			{
				akGameObj_MirrorPosition_Hook.Undo();
			}
			Hook akGameObj_MirrorForwardVector_Hook = AkGameObj_MirrorForwardVector_Hook;
			if (akGameObj_MirrorForwardVector_Hook != null)
			{
				akGameObj_MirrorForwardVector_Hook.Undo();
			}
			Hook akGameObj_MirrorUpVector_Hook = AkGameObj_MirrorUpVector_Hook;
			if (akGameObj_MirrorUpVector_Hook != null)
			{
				akGameObj_MirrorUpVector_Hook.Undo();
			}
		}

		private static Matrix4x4 getSoundEmitterMirrorTransformation(AkGameObj self)
		{
			//IL_0065: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (StageMirrorController.CurrentlyIsMirrored)
			{
				List<AkAudioListener> list = (self.IsUsingDefaultListeners ? ((BaseListenerList)AkAudioListener.DefaultListeners).ListenerList : self.ListenerList);
				if (list.Count == 1)
				{
					AkAudioListener val = list[0];
					if (Object.op_Implicit((Object)(object)((Component)val).GetComponent<MirrorCamera>()))
					{
						return ((Component)val).transform.GlobalTransformationFromLocal(Matrix4x4.Scale(new Vector3(-1f, 1f, 1f)));
					}
				}
			}
			return Matrix4x4.identity;
		}

		private static Vector3 AkGameObj_GenericTryMirrorPositionResult(AkGameObj_GetVectorDelegate orig, AkGameObj self)
		{
			//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_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)
			Matrix4x4 soundEmitterMirrorTransformation = getSoundEmitterMirrorTransformation(self);
			return ((Matrix4x4)(ref soundEmitterMirrorTransformation)).MultiplyPoint(orig(self));
		}

		private static Vector3 AkGameObj_GenericTryMirrorVectorResult(AkGameObj_GetVectorDelegate orig, AkGameObj self)
		{
			//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_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)
			Matrix4x4 soundEmitterMirrorTransformation = getSoundEmitterMirrorTransformation(self);
			return ((Matrix4x4)(ref soundEmitterMirrorTransformation)).MultiplyVector(orig(self));
		}
	}
}
namespace MirroredStageVariants.ModCompatibility
{
	internal static class RiskOfOptionsCompat
	{
		public static bool IsEnabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		public static void AddConfigOptions()
		{
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Options for Mirrored Stage Variants", "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(Main.MirrorChance, new StepSliderConfig
			{
				formatString = "{0}%",
				min = 0f,
				max = 100f,
				increment = 0.1f
			}), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Main.MirrorNonStages), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
		}
	}
}
namespace MirroredStageVariants.Components
{
	[DisallowMultipleComponent]
	public class InvertParticlePositionsOnRender : MonoBehaviour
	{
		private class ApplyInvertShader : MonoBehaviour
		{
			public InvertParticlePositionsOnRender Owner;

			public Camera Camera { get; private set; }

			public RenderTexture TargetTexture { get; private set; }

			public Material Material { get; private set; }

			private void Awake()
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Expected O, but got Unknown
				Camera = ((Component)this).GetComponent<Camera>();
				updateRenderTexture();
				Shader val = (Object.op_Implicit((Object)(object)Main.Instance) ? Main.Instance.MirrorOverlayShader : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					Material = new Material(val);
					if (Object.op_Implicit((Object)(object)TargetTexture))
					{
						Material.SetTexture(CommonShaderIDs._OverlayTex, (Texture)(object)TargetTexture);
					}
				}
			}

			private void updateRenderTexture()
			{
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)TargetTexture))
				{
					if (Object.op_Implicit((Object)(object)Camera) && ((Texture)TargetTexture).width == Camera.pixelWidth && ((Texture)TargetTexture).height == Camera.pixelHeight)
					{
						return;
					}
					RenderTexture.ReleaseTemporary(TargetTexture);
					TargetTexture = null;
				}
				if (Object.op_Implicit((Object)(object)Camera))
				{
					RenderTextureDescriptor val = default(RenderTextureDescriptor);
					((RenderTextureDescriptor)(ref val))..ctor(Camera.pixelWidth, Camera.pixelHeight, (RenderTextureFormat)0);
					((RenderTextureDescriptor)(ref val)).sRGB = true;
					((RenderTextureDescriptor)(ref val)).useMipMap = false;
					TargetTexture = RenderTexture.GetTemporary(val);
					((Texture)TargetTexture).filterMode = (FilterMode)1;
					if (Object.op_Implicit((Object)(object)Material))
					{
						Material.SetTexture(CommonShaderIDs._OverlayTex, (Texture)(object)TargetTexture);
					}
				}
			}

			private void FixedUpdate()
			{
				updateRenderTexture();
				if (!Object.op_Implicit((Object)(object)Owner))
				{
					Object.Destroy((Object)(object)this);
				}
			}

			private void OnDestroy()
			{
				if (Object.op_Implicit((Object)(object)Material))
				{
					Object.Destroy((Object)(object)Material);
				}
				if (Object.op_Implicit((Object)(object)TargetTexture))
				{
					RenderTexture.ReleaseTemporary(TargetTexture);
				}
			}

			private void OnRenderImage(RenderTexture source, RenderTexture destination)
			{
				if (Object.op_Implicit((Object)(object)Material))
				{
					Graphics.Blit((Texture)(object)source, destination, Material);
				}
				else
				{
					Graphics.Blit((Texture)(object)source, destination);
				}
			}
		}

		private static Camera _manualRenderCamera;

		private readonly List<ApplyInvertShader> _ownedInvertAppliers = new List<ApplyInvertShader>();

		private Camera _currentRenderingCamera;

		private int _originalLayer;

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0005: 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)
			GameObject val = new GameObject("ManualRenderCamera");
			val.AddComponent<SetDontDestroyOnLoad>();
			_manualRenderCamera = val.AddComponent<Camera>();
			((Behaviour)_manualRenderCamera).enabled = false;
		}

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			CameraEvents.OnPreCull += new CameraCallback(onPreCull);
			CameraEvents.OnPostRender += new CameraCallback(onPostRender);
		}

		private void OnDisable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			CameraEvents.OnPreCull -= new CameraCallback(onPreCull);
			CameraEvents.OnPostRender -= new CameraCallback(onPostRender);
			if (Object.op_Implicit((Object)(object)_currentRenderingCamera))
			{
				((Component)this).gameObject.layer = _originalLayer;
				_currentRenderingCamera = null;
			}
			removeAllInvertAppliers();
		}

		private void removeAllInvertAppliers()
		{
			foreach (ApplyInvertShader ownedInvertApplier in _ownedInvertAppliers)
			{
				ownedInvertApplier.Owner = null;
				Object.Destroy((Object)(object)ownedInvertApplier);
			}
			_ownedInvertAppliers.Clear();
		}

		private void onPreCull(Camera cam)
		{
			if ((Object)(object)cam == (Object)(object)_manualRenderCamera || !cam.ShouldRenderObjectAsMirrored(((Component)this).gameObject))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_currentRenderingCamera))
			{
				if ((Object)(object)_currentRenderingCamera != (Object)(object)cam)
				{
					Log.Warning($"Cannot swap UV position of {((Object)this).name} rendered from {cam}, already being rendered by {_currentRenderingCamera}", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Components\\InvertParticlePositionsOnRender.cs", "onPreCull", 70);
				}
			}
			else
			{
				_currentRenderingCamera = cam;
				_originalLayer = ((Component)this).gameObject.layer;
				((Component)this).gameObject.layer = LayerIndex.manualRender.intVal;
			}
		}

		private void onPostRender(Camera cam)
		{
			//IL_009d: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)cam == (Object)(object)_manualRenderCamera) && !((Object)(object)_currentRenderingCamera != (Object)(object)cam))
			{
				ApplyInvertShader applyInvertShader = _ownedInvertAppliers.Find((ApplyInvertShader a) => (Object)(object)a.Camera == (Object)(object)cam);
				if (!Object.op_Implicit((Object)(object)applyInvertShader))
				{
					applyInvertShader = ((Component)cam).gameObject.AddComponent<ApplyInvertShader>();
					applyInvertShader.Owner = this;
					_ownedInvertAppliers.Add(applyInvertShader);
				}
				_manualRenderCamera.CopyFrom(cam);
				((Component)_manualRenderCamera).transform.position = ((Component)cam).transform.position;
				((Component)_manualRenderCamera).transform.rotation = ((Component)cam).transform.rotation;
				_manualRenderCamera.cullingMask = LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.manualRender)).mask);
				_manualRenderCamera.clearFlags = (CameraClearFlags)2;
				_manualRenderCamera.backgroundColor = Color.clear;
				_manualRenderCamera.targetTexture = applyInvertShader.TargetTexture;
				_manualRenderCamera.Render();
				((Component)this).gameObject.layer = _originalLayer;
				_currentRenderingCamera = null;
			}
		}
	}
	[DisallowMultipleComponent]
	public class InvertScreenCoordinatesOnRender : MonoBehaviour
	{
		private Camera _currentRenderingCamera;

		private Vector3 _preRenderPosition;

		[SystemInitializer(new Type[] { typeof(EffectCatalog) })]
		private static void Init()
		{
			//IL_0001: 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_0131: Invalid comparison between Unknown and I4
			//IL_0007: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			for (EffectIndex val = (EffectIndex)0; (int)val < EffectCatalog.effectCount; val = (EffectIndex)(val + 1))
			{
				EffectDef effectDef = EffectCatalog.GetEffectDef(val);
				if (effectDef == null)
				{
					continue;
				}
				GameObject prefab = effectDef.prefab;
				if (!Object.op_Implicit((Object)(object)prefab))
				{
					continue;
				}
				List<Transform> list = new List<Transform>();
				foreach (Transform item in from t in prefab.transform.GetAllChildrenRecursive()
					where ((Component)t).gameObject.layer == LayerIndex.uiWorldSpace.intVal
					select t)
				{
					if (list.Exists((Predicate<Transform>)item.IsChildOf))
					{
						continue;
					}
					for (int num = list.Count - 1; num >= 0; num--)
					{
						if (list[num].IsChildOf(item))
						{
							list.RemoveAt(num);
						}
					}
					list.Add(item);
				}
				foreach (Transform item2 in list)
				{
					if (Object.op_Implicit((Object)(object)((Component)item2).GetComponent<ParticleSystemRenderer>()))
					{
						((Component)item2).gameObject.AddComponent<InvertParticlePositionsOnRender>();
					}
					else
					{
						((Component)item2).gameObject.AddComponent<InvertScreenCoordinatesOnRender>();
					}
				}
			}
		}

		private void OnEnable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			CameraEvents.OnPreCull += new CameraCallback(onPreCull);
			CameraEvents.OnPostRender += new CameraCallback(onPostRender);
		}

		private void OnDisable()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			restorePreRenderPosition();
			CameraEvents.OnPreCull -= new CameraCallback(onPreCull);
			CameraEvents.OnPostRender -= new CameraCallback(onPostRender);
		}

		private void storePreRenderPosition()
		{
			//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)
			_preRenderPosition = ((Component)this).transform.position;
		}

		private void restorePreRenderPosition()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_currentRenderingCamera))
			{
				((Component)this).transform.position = _preRenderPosition;
			}
		}

		private void onPreCull(Camera camera)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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)
			if (!camera.ShouldRenderObjectAsMirrored(((Component)this).gameObject))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)_currentRenderingCamera))
			{
				if ((Object)(object)_currentRenderingCamera != (Object)(object)camera)
				{
					Log.Warning($"Cannot store position of {((Object)this).name} rendered from {camera}, already being rendered by {_currentRenderingCamera}", "E:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Components\\InvertScreenCoordinatesOnRender.cs", "onPreCull", 101);
				}
			}
			else
			{
				_currentRenderingCamera = camera;
				storePreRenderPosition();
				Vector3 val = camera.WorldToViewportPoint(((Component)this).transform.position);
				CoordinateUtils.InvertScreenXCoordinate(ref val.x, camera.rect);
				((Component)this).transform.position = camera.ViewportToWorldPoint(val);
			}
		}

		private void onPostRender(Camera camera)
		{
			if (!((Object)(object)_currentRenderingCamera != (Object)(object)camera))
			{
				restorePreRenderPosition();
				_currentRenderingCamera = null;
			}
		}
	}
	internal class MirrorCamera : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Awake <>9__0_0;

			internal void <Init>b__0_0(orig_Awake orig, SceneCamera self)
			{
				orig.Invoke(self);
				((Component)self).gameObject.AddComponent<MirrorCamera>();
			}
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				hook_Awake val = delegate(orig_Awake orig, SceneCamera self)
				{
					orig.Invoke(self);
					((Component)self).gameObject.AddComponent<MirrorCamera>();
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			SceneCamera.Awake += (hook_Awake)obj;
		}

		private void OnRenderImage(RenderTexture source, RenderTexture destination)
		{
			Material val = (Object.op_Implicit((Object)(object)Main.Instance) ? Main.Instance.MirrorMaterial : null);
			if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)val))
			{
				Graphics.Blit((Texture)(object)source, destination, val);
			}
			else
			{
				Graphics.Blit((Texture)(object)source, destination);
			}
		}
	}
	[DefaultExecutionOrder(-1)]
	public class ScaleOnAwakeIfMirrored : MonoBehaviour
	{
		public Vector3 ScaleMultiplier = Vector3.one;

		private void Awake()
		{
			//IL_0013: 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)
			if (StageMirrorController.CurrentlyIsMirrored)
			{
				((Component)this).transform.localScale = Vector3.Scale(((Component)this).transform.localScale, ScaleMultiplier);
			}
		}
	}
	public class StageMirrorController : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_OnEnable <>9__0_0;

			internal void <Init>b__0_0(orig_OnEnable orig, Stage self)
			{
				orig.Invoke(self);
				if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<StageMirrorController>()))
				{
					((Component)self).gameObject.AddComponent<StageMirrorController>();
				}
			}
		}

		private static StageMirrorController _instance;

		private bool _isMirrored;

		public static bool CurrentlyIsMirrored
		{
			get
			{
				if (!CanMirrorScene(SceneCatalog.mostRecentSceneDef))
				{
					return false;
				}
				if (!Object.op_Implicit((Object)(object)_instance))
				{
					return Main.MirrorNonStages.Value;
				}
				if (Commands.OverrideStageIsMirrored.HasValue)
				{
					return Commands.OverrideStageIsMirrored.Value;
				}
				return _instance._isMirrored;
			}
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				hook_OnEnable val = delegate(orig_OnEnable orig, Stage self)
				{
					orig.Invoke(self);
					if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<StageMirrorController>()))
					{
						((Component)self).gameObject.AddComponent<StageMirrorController>();
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			Stage.OnEnable += (hook_OnEnable)obj;
		}

		public static bool CanMirrorScene(SceneDef scene)
		{
			if (!Object.op_Implicit((Object)(object)scene))
			{
				return false;
			}
			string cachedName = scene.cachedName;
			if (cachedName == "lobby" || cachedName == "logbook")
			{
				return false;
			}
			return true;
		}

		private void OnEnable()
		{
			SingletonHelper.Assign<StageMirrorController>(ref _instance, this);
		}

		private void OnDisable()
		{
			SingletonHelper.Unassign<StageMirrorController>(ref _instance, this);
		}

		private void Awake()
		{
			_isMirrored = RoR2Application.rng.nextNormalizedFloat <= Main.MirrorChance.Value / 100f;
		}
	}
}