Decompiled source of MirroredStageVariants v1.2.5

plugins/MirroredStageVariants/MirroredStageVariants.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using HG.Coroutines;
using HG.Reflection;
using HarmonyLib;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using MirroredStageVariants.Components;
using MirroredStageVariants.ModCompatibility;
using MirroredStageVariants.Utils;
using MirroredStageVariants.Utils.Extensions;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.RoR2;
using On.RoR2.CameraModes;
using On.RoR2.UI;
using R2API.Utils;
using Rewired;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.CameraModes;
using RoR2.ContentManagement;
using RoR2.UI;
using RoR2BepInExPack.GameAssetPathsBetter;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

[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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MirroredStageVariants")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d25bf8ee1aa1619f001b0924b2db2692b9816e6a")]
[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]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[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 Assets
	{
		private interface IAssetReference
		{
			Object Asset { get; set; }
		}

		private sealed class AssetLoadOperation
		{
			public string AssetName { get; }

			public AssetBundleRequest LoadRequest { get; }

			public IAssetReference AssetReference { get; }

			public bool IsDone => ((AsyncOperation)LoadRequest).isDone;

			public AssetLoadOperation(string assetName, AssetBundleRequest loadRequest, IAssetReference assetReference)
			{
				AssetName = assetName;
				LoadRequest = loadRequest ?? throw new ArgumentNullException("loadRequest");
				AssetReference = assetReference ?? throw new ArgumentNullException("assetReference");
				base..ctor();
			}

			public void Update()
			{
				if (((AsyncOperation)LoadRequest).isDone)
				{
					Object asset = LoadRequest.asset;
					if (!Object.op_Implicit(asset))
					{
						Log.Error("Missing asset '" + AssetName + "', check editor export!", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Update", 36);
					}
					else
					{
						AssetReference.Asset = asset;
					}
				}
			}
		}

		private sealed class AssetReference<T> : IAssetReference where T : Object
		{
			public T Asset;

			Object IAssetReference.Asset
			{
				get
				{
					return (Object)(object)Asset;
				}
				set
				{
					Asset = (T)(object)value;
				}
			}
		}

		[StructLayout(LayoutKind.Auto)]
		[CompilerGenerated]
		private struct <>c__DisplayClass9_0
		{
			public AssetBundle assetBundle;
		}

		[CompilerGenerated]
		private sealed class <Init>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private AssetBundleCreateRequest <assetBundleLoad>5__2;

			private List<AssetLoadOperation> <loadOperations>5__3;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<assetBundleLoad>5__2 = null;
				<loadOperations>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				<>c__DisplayClass9_0 <>c__DisplayClass9_ = default(<>c__DisplayClass9_0);
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)MirroredStageVariantsPlugin.Instance).Info.Location), "mirror_assets");
					if (!File.Exists(text))
					{
						Log.Error("Assets file not found, expected path: " + text, "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Init", 73);
						return false;
					}
					<assetBundleLoad>5__2 = AssetBundle.LoadFromFileAsync(text);
					goto IL_008c;
				}
				case 1:
					<>1__state = -1;
					goto IL_008c;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_008c:
					if (!((AsyncOperation)<assetBundleLoad>5__2).isDone)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>c__DisplayClass9_.assetBundle = <assetBundleLoad>5__2.assetBundle;
					if (!Object.op_Implicit((Object)(object)<>c__DisplayClass9_.assetBundle))
					{
						Log.Error("Failed to load asset bundle", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Assets.cs", "Init", 88);
						return false;
					}
					<loadOperations>5__3 = new List<AssetLoadOperation>();
					<loadOperations>5__3.Add(Assets.<Init>g__getLoadOperation|9_0<Material>("Mirror", _mirrorMaterialRef, ref <>c__DisplayClass9_));
					<loadOperations>5__3.Add(Assets.<Init>g__getLoadOperation|9_0<Shader>("MirrorOverlay", _mirrorOverlayShaderRef, ref <>c__DisplayClass9_));
					break;
				}
				if (<loadOperations>5__3.Count > 0)
				{
					for (int num = <loadOperations>5__3.Count - 1; num >= 0; num--)
					{
						AssetLoadOperation assetLoadOperation = <loadOperations>5__3[num];
						assetLoadOperation.Update();
						if (assetLoadOperation.IsDone)
						{
							<loadOperations>5__3.RemoveAt(num);
						}
					}
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				return false;
			}

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

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

		private static readonly AssetReference<Material> _mirrorMaterialRef = new AssetReference<Material>();

		private static readonly AssetReference<Shader> _mirrorOverlayShaderRef = new AssetReference<Shader>();

		public static Material MirrorMaterial => _mirrorMaterialRef.Asset;

		public static Shader MirrorOverlayShader => _mirrorOverlayShaderRef.Asset;

		[IteratorStateMachine(typeof(<Init>d__9))]
		[SystemInitializer(new Type[] { })]
		private static IEnumerator Init()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Init>d__9(0);
		}
	}
	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
	{
		private static readonly StringBuilder _sharedStringBuilder;

		private static readonly object _stringBuilderLock;

		private static readonly int _cachedCallerPathPrefixLength;

		private static ManualLogSource _logSource;

		static Log()
		{
			_sharedStringBuilder = new StringBuilder(256);
			_stringBuilderLock = new object();
			_cachedCallerPathPrefixLength = getCallerPathPrefixLength("D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Log.cs");
			static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null)
			{
				int num = callerPath.LastIndexOf("MirroredStageVariants\\");
				if (num >= 0)
				{
					return num + "MirroredStageVariants\\".Length;
				}
				Debug.LogError((object)"[MirroredStageVariants] Logger failed to determine caller path prefix length");
				return 0;
			}
		}

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

		private static string buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data)
		{
			lock (_stringBuilderLock)
			{
				return _sharedStringBuilder.Clear().Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':')
					.Append(callerLineNumber)
					.Append(" (")
					.Append(callerMemberName)
					.Append("): ")
					.Append(data)
					.ToString();
			}
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

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

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		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)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		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)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		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)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		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)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogType_NoCallerPrefix(LogLevel level, object data)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, data);
			}
		}
	}
	[BepInPlugin("Gorakh.MirroredStageVariants", "MirroredStageVariants", "1.2.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class MirroredStageVariantsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.MirroredStageVariants";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "MirroredStageVariants";

		public const string PluginVersion = "1.2.5";

		internal static MirroredStageVariantsPlugin Instance { get; private set; }

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

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

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

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = SingletonHelper.Assign<MirroredStageVariantsPlugin>(Instance, this);
			initConfigs(((BaseUnityPlugin)this).Config);
			stopwatch.Stop();
			Log.Message_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalMilliseconds:F0}ms");
		}

		private void OnDestroy()
		{
			Instance = SingletonHelper.Unassign<MirroredStageVariantsPlugin>(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.");
			MirrorHiddenRealms = file.Bind<bool>("General", "Mirror Hidden Realms", true, "If stages outside the normal stage one through five rotation can be mirrored.");
			if (RiskOfOptionsCompat.IsEnabled)
			{
				RiskOfOptionsCompat.AddConfigOptions();
			}
		}
	}
}
namespace MirroredStageVariants.Utils
{
	public static class AssetLoadUtils
	{
		public static AsyncOperationHandle<T> LoadAssetAsync<T>(string guid, bool autoUnload = false) where T : Object
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return LoadAssetAsync<T>(new AssetReferenceT<T>(guid), autoUnload);
		}

		public static AsyncOperationHandle<T> LoadAssetAsync<T>(AssetReferenceT<T> assetReference, bool autoUnload = false) where T : Object
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<T> result = AssetAsyncReferenceManager<T>.LoadAsset(assetReference, (AsyncReferenceHandleUnloadType)2);
			if (autoUnload)
			{
				result.Completed += delegate
				{
					AssetAsyncReferenceManager<T>.UnloadAsset(assetReference);
				};
			}
			return result;
		}
	}
	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;
		}
	}
	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
	{
		[CompilerGenerated]
		private sealed class <GetAllChildrenRecursive>d__1 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private Transform transform;

			public Transform <>3__transform;

			private int <i>5__2;

			private IEnumerator<Transform> <>7__wrap2;

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

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

			[DebuggerHidden]
			public <GetAllChildrenRecursive>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = transform;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<i>5__2 = 0;
						goto IL_00cc;
					case 2:
						{
							<>1__state = -3;
							goto IL_00a2;
						}
						IL_00cc:
						if (<i>5__2 < transform.childCount)
						{
							<>7__wrap2 = transform.GetChild(<i>5__2).GetAllChildrenRecursive().GetEnumerator();
							<>1__state = -3;
							goto IL_00a2;
						}
						return false;
						IL_00a2:
						if (<>7__wrap2.MoveNext())
						{
							Transform current = <>7__wrap2.Current;
							<>2__current = current;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>7__wrap2 = null;
						<i>5__2++;
						goto IL_00cc;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<GetAllChildrenRecursive>d__1 <GetAllChildrenRecursive>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAllChildrenRecursive>d__ = this;
				}
				else
				{
					<GetAllChildrenRecursive>d__ = new <GetAllChildrenRecursive>d__1(0);
				}
				<GetAllChildrenRecursive>d__.transform = <>3__transform;
				return <GetAllChildrenRecursive>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		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;
		}

		[IteratorStateMachine(typeof(<GetAllChildrenRecursive>d__1))]
		public static IEnumerable<Transform> GetAllChildrenRecursive(this Transform transform)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllChildrenRecursive>d__1(-2)
			{
				<>3__transform = transform
			};
		}
	}
}
namespace MirroredStageVariants.Utils.Extensions
{
	public static class AssetLoadExtensions
	{
		[CompilerGenerated]
		private sealed class <AsProgressCoroutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IProgress<float> progressReceiver;

			public AsyncOperation asyncOperation;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					progressReceiver.Report(asyncOperation.progress);
					break;
				}
				if (!asyncOperation.isDone)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <AsProgressCoroutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IProgress<float> progressReceiver;

			public AsyncOperationHandle asyncOperation;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					progressReceiver.Report(((AsyncOperationHandle)(ref asyncOperation)).PercentComplete);
					break;
				}
				if (!((AsyncOperationHandle)(ref asyncOperation)).IsDone)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

		[CompilerGenerated]
		private sealed class <AsProgressCoroutine>d__4<T> : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public IProgress<float> progressReceiver;

			public AsyncOperationHandle<T> asyncOperation;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					progressReceiver.Report(asyncOperation.PercentComplete);
					break;
				}
				if (!asyncOperation.IsDone)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

		public static void OnSuccess(this in AsyncOperationHandle handle, Action<object> onSuccess)
		{
			//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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			StackTrace stackTrace = new StackTrace();
			AsyncOperationHandle val = handle;
			if (((AsyncOperationHandle)(ref val)).IsDone)
			{
				handleCompleted(handle);
				return;
			}
			val = handle;
			((AsyncOperationHandle)(ref val)).Completed += handleCompleted;
			void handleCompleted(AsyncOperationHandle handle)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)((AsyncOperationHandle)(ref handle)).Status == 1)
				{
					onSuccess(((AsyncOperationHandle)(ref handle)).Result);
				}
				else
				{
					Log.Error($"Failed to load asset '{((AsyncOperationHandle)(ref handle)).LocationName}'. {stackTrace}", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\AssetLoadExtensions.cs", "OnSuccess", 25);
				}
			}
		}

		public static void OnSuccess<T>(this in AsyncOperationHandle<T> handle, Action<T> onSuccess)
		{
			//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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			StackTrace stackTrace = new StackTrace();
			if (handle.IsDone)
			{
				handleCompleted(handle);
				return;
			}
			AsyncOperationHandle<T> val = handle;
			val.Completed += handleCompleted;
			void handleCompleted(AsyncOperationHandle<T> handle)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)handle.Status == 1)
				{
					onSuccess(handle.Result);
				}
				else
				{
					Log.Error($"Failed to load asset '{handle.LocationName}'. {stackTrace}", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\AssetLoadExtensions.cs", "OnSuccess", 51);
				}
			}
		}

		[IteratorStateMachine(typeof(<AsProgressCoroutine>d__2))]
		public static IEnumerator AsProgressCoroutine(this AsyncOperation asyncOperation, IProgress<float> progressReceiver)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AsProgressCoroutine>d__2(0)
			{
				asyncOperation = asyncOperation,
				progressReceiver = progressReceiver
			};
		}

		[IteratorStateMachine(typeof(<AsProgressCoroutine>d__3))]
		public static IEnumerator AsProgressCoroutine(this AsyncOperationHandle asyncOperation, IProgress<float> progressReceiver)
		{
			//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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AsProgressCoroutine>d__3(0)
			{
				asyncOperation = asyncOperation,
				progressReceiver = progressReceiver
			};
		}

		[IteratorStateMachine(typeof(<AsProgressCoroutine>d__4<>))]
		public static IEnumerator AsProgressCoroutine<T>(this AsyncOperationHandle<T> asyncOperation, IProgress<float> progressReceiver)
		{
			//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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AsProgressCoroutine>d__4<T>(0)
			{
				asyncOperation = asyncOperation,
				progressReceiver = progressReceiver
			};
		}

		public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperation asyncOperation)
		{
			ReadableProgress<float> val = new ReadableProgress<float>();
			parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine((IProgress<float>)val), val);
		}

		public static void Add(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperationHandle asyncOperation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			ReadableProgress<float> val = new ReadableProgress<float>();
			parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine((IProgress<float>)val), val);
		}

		public static void Add<T>(this ParallelProgressCoroutine parallelProgressCoroutine, AsyncOperationHandle<T> asyncOperation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			ReadableProgress<float> val = new ReadableProgress<float>();
			parallelProgressCoroutine.Add(asyncOperation.AsProgressCoroutine<T>((IProgress<float>)val), val);
		}
	}
	public static class CollectionExtensions
	{
		public static void EnsureCapacity<T>(this List<T> list, int capacity)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (list.Capacity < capacity)
			{
				list.Capacity = capacity;
			}
		}

		public static T Take<T>(this IList<T> list, int index)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			T result = list[index];
			list.RemoveAt(index);
			return result;
		}

		public static object Take(this IList list, int index)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			object? result = list[index];
			list.RemoveAt(index);
			return result;
		}
	}
	public static class FileExtensions
	{
		public static bool IsChildOf(this DirectoryInfo dir, DirectoryInfo other)
		{
			if (dir != null && other != null)
			{
				return dir.FullName.StartsWith(other.FullName, ignoreCase: true, CultureInfo.InvariantCulture);
			}
			return false;
		}
	}
	public static class PatchExtensions
	{
		public static void EmitSkipMethodCall(this ILCursor c)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			c.EmitSkipMethodCall(OpCodes.Br);
		}

		public static void EmitSkipMethodCall(this ILCursor c, OpCode branchOpCode)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			c.EmitSkipMethodCall(branchOpCode, null);
		}

		public static void EmitSkipMethodCall(this ILCursor c, OpCode branchOpCode, Action<ILCursor> emitSkippedReturnValue)
		{
			//IL_0010: 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: Invalid comparison between Unknown and I4
			//IL_0026: 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)
			//IL_0160: 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)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Invalid comparison between Unknown and I4
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			if (c == null)
			{
				throw new ArgumentNullException("c");
			}
			if ((int)((OpCode)(ref branchOpCode)).FlowControl != 0 && (int)((OpCode)(ref branchOpCode)).FlowControl != 3)
			{
				throw new ArgumentException($"Invalid branch OpCode: {branchOpCode}");
			}
			MethodReference val = default(MethodReference);
			if (c.Next == null || !ILPatternMatchingExt.MatchCallOrCallvirt(c.Next, ref val))
			{
				Log.Error($"Failed to find method call to skip: {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 61);
				return;
			}
			MethodDefinition val2 = Extensions.SafeResolve(val);
			if (val2 == null)
			{
				Log.Error($"Failed to resolve method '{((MemberReference)val).FullName}': {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 69);
				return;
			}
			int num = ((MethodReference)val2).Parameters.Count + ((!val2.IsStatic) ? 1 : 0);
			bool flag = Extensions.Is((MemberReference)(object)((MethodReference)val2).ReturnType, (MemberInfo)typeof(void));
			ILLabel val3 = c.DefineLabel();
			if ((int)((OpCode)(ref branchOpCode)).FlowControl == 0)
			{
				c.Emit(OpCodes.Ldc_I4_0);
				c.Emit(((int)((OpCode)(ref branchOpCode)).OperandType == 15) ? OpCodes.Brfalse_S : OpCodes.Brfalse, (object)val3);
			}
			else
			{
				c.Emit(branchOpCode, (object)val3);
			}
			int index = c.Index;
			c.Index = index + 1;
			if (num == 0 && flag)
			{
				c.MarkLabel(val3);
				return;
			}
			ILLabel val4 = c.DefineLabel();
			c.Emit(OpCodes.Br, (object)val4);
			c.MarkLabel(val3);
			for (int i = 0; i < num; i++)
			{
				c.Emit(OpCodes.Pop);
			}
			if (emitSkippedReturnValue != null)
			{
				emitSkippedReturnValue(c);
			}
			else if (!flag)
			{
				Log.Warning($"Skipped method ({((MemberReference)val2).FullName}) is not void, emitting default value: {((MemberReference)c.Context.Method).FullName} at instruction {c.Next.SafeToString()} ({c.Index})", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "EmitSkipMethodCall", 115);
				c.EmitDefaultValue(((MethodReference)val2).ReturnType);
			}
			c.MarkLabel(val4);
		}

		public static void EmitDefaultValue(this ILCursor cursor, TypeReference type)
		{
			//IL_001f: 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_007e: 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_0097: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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)
			if (type == null || Extensions.Is((MemberReference)(object)type, (MemberInfo)typeof(void)))
			{
				return;
			}
			if (!type.IsValueType)
			{
				cursor.Emit(OpCodes.Ldnull);
				return;
			}
			switch (type.GetTypeCode())
			{
			case TypeCode.Boolean:
			case TypeCode.Char:
			case TypeCode.SByte:
			case TypeCode.Byte:
			case TypeCode.Int16:
			case TypeCode.UInt16:
			case TypeCode.Int32:
			case TypeCode.UInt32:
				cursor.Emit(OpCodes.Ldc_I4_0);
				break;
			case TypeCode.Int64:
			case TypeCode.UInt64:
				cursor.Emit(OpCodes.Ldc_I4_0);
				cursor.Emit(OpCodes.Conv_I8);
				break;
			case TypeCode.Single:
				cursor.Emit(OpCodes.Ldc_R4, 0f);
				break;
			case TypeCode.Double:
				cursor.Emit(OpCodes.Ldc_R8, 0.0);
				break;
			case TypeCode.Decimal:
				cursor.Emit(OpCodes.Ldsfld, typeof(decimal).GetField("Zero"));
				break;
			default:
			{
				VariableDefinition val = cursor.Context.AddVariable(type);
				cursor.Emit(OpCodes.Ldloca, val);
				cursor.Emit(OpCodes.Initobj, type);
				cursor.Emit(OpCodes.Ldloc, val);
				break;
			}
			}
		}

		public static TypeCode GetTypeCode(this TypeReference type)
		{
			if (type == null)
			{
				return TypeCode.Empty;
			}
			TypeReference val = null;
			TypeDefinition val2 = Extensions.SafeResolve(type);
			if (val2 != null && val2.IsEnum)
			{
				try
				{
					val = TypeDefinitionRocks.GetEnumUnderlyingType(val2);
				}
				catch
				{
				}
			}
			return ((MemberReference)(val ?? type)).FullName switch
			{
				"System.DBNull" => TypeCode.DBNull, 
				"System.Boolean" => TypeCode.Boolean, 
				"System.Char" => TypeCode.Char, 
				"System.SByte" => TypeCode.SByte, 
				"System.Byte" => TypeCode.Byte, 
				"System.Int16" => TypeCode.Int16, 
				"System.UInt16" => TypeCode.UInt16, 
				"System.Int32" => TypeCode.Int32, 
				"System.UInt32" => TypeCode.UInt32, 
				"System.Int64" => TypeCode.Int64, 
				"System.UInt64" => TypeCode.UInt64, 
				"System.Single" => TypeCode.Single, 
				"System.Double" => TypeCode.Double, 
				"System.Decimal" => TypeCode.Decimal, 
				"System.DateTime" => TypeCode.DateTime, 
				"System.String" => TypeCode.String, 
				_ => TypeCode.Object, 
			};
		}

		public static bool TryFindForeachContinueLabel(this ILCursor cursor, out ILLabel continueLabel)
		{
			ILCursor val = cursor.Clone();
			int enumeratorLocalIndex = -1;
			MethodReference method2 = default(MethodReference);
			if (!val.TryGotoPrev(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, ref method2) && isEnumerableGetEnumerator(method2)
			}) || !val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref enumeratorLocalIndex)
			}))
			{
				Log.Warning("Failed to find GetEnumerator call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "TryFindForeachContinueLabel", 256);
				continueLabel = null;
				return false;
			}
			val = cursor.Clone();
			if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, enumeratorLocalIndex),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<IEnumerator>(x, "MoveNext")
			}))
			{
				Log.Warning("Failed to find matching MoveNext call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Utils\\Extensions\\PatchExtensions.cs", "TryFindForeachContinueLabel", 266);
				continueLabel = null;
				return false;
			}
			continueLabel = val.MarkLabel();
			return true;
			static bool isEnumerableGetEnumerator(MethodReference method)
			{
				if (method == null)
				{
					return false;
				}
				if (!string.Equals(((MemberReference)method).Name, "GetEnumerator"))
				{
					return false;
				}
				return true;
			}
		}

		public static string SafeToString(this Instruction instruction)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (instruction == null)
			{
				return "NULL";
			}
			try
			{
				return ((object)instruction).ToString();
			}
			catch
			{
			}
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder.Append(formatLabel(instruction)).Append(": ");
			OpCode opCode = instruction.OpCode;
			stringBuilder2.Append(((OpCode)(ref opCode)).Name);
			if (instruction.Operand != null)
			{
				stringBuilder.Append(' ');
				object operand = instruction.Operand;
				Instruction val = (Instruction)((operand is Instruction) ? operand : null);
				if (val == null)
				{
					if (operand is IEnumerable<Instruction> source)
					{
						stringBuilder.Append('[').Append(string.Join(", ", source.Select(formatLabel))).Append(']');
					}
					else
					{
						stringBuilder.Append(instruction.Operand);
					}
				}
				else
				{
					stringBuilder.Append(formatLabel(val));
				}
			}
			return stringBuilder.ToString();
			static string formatLabel(Instruction instruction)
			{
				if (instruction == null)
				{
					return "IL_????";
				}
				return $"IL_{instruction.Offset:x4}";
			}
		}

		public static bool TryFindParameter(this MethodReference method, Type parameterType, string parameterName, out ParameterDefinition parameter)
		{
			//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)
			if (method == null)
			{
				throw new ArgumentNullException("method");
			}
			if (parameterType == null && string.IsNullOrEmpty(parameterName))
			{
				throw new ArgumentException("Cannot find parameter for method " + ((MemberReference)method).FullName + ": Neither parameter type or name specified");
			}
			if (method.HasParameters)
			{
				Enumerator<ParameterDefinition> enumerator = method.Parameters.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						ParameterDefinition current = enumerator.Current;
						if ((string.IsNullOrEmpty(parameterName) || ((ParameterReference)current).Name == parameterName) && (parameterType == null || Extensions.Is((MemberReference)(object)((ParameterReference)current).ParameterType, (MemberInfo)parameterType)))
						{
							parameter = current;
							return true;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator).Dispose();
				}
			}
			parameter = null;
			return false;
		}

		public static bool TryFindParameter(this MethodReference method, string name, out ParameterDefinition parameter)
		{
			return method.TryFindParameter(null, name, out parameter);
		}

		public static bool TryFindParameter(this MethodReference method, Type type, out ParameterDefinition parameter)
		{
			return method.TryFindParameter(type, null, out parameter);
		}

		public static bool TryFindParameter<T>(this MethodReference method, string name, out ParameterDefinition parameter)
		{
			return method.TryFindParameter(typeof(T), name, out parameter);
		}

		public static bool TryFindParameter<T>(this MethodReference method, out ParameterDefinition parameter)
		{
			return method.TryFindParameter(typeof(T), null, out parameter);
		}

		public static VariableDefinition AddVariable(this ILContext context, TypeReference variableType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			VariableDefinition val = new VariableDefinition(variableType);
			context.Method.Body.Variables.Add(val);
			return val;
		}

		public static VariableDefinition AddVariable(this ILContext context, Type variableType)
		{
			return context.AddVariable(context.Import(variableType));
		}

		public static VariableDefinition AddVariable<T>(this ILContext context)
		{
			return context.AddVariable(context.Import(typeof(T)));
		}

		public static void EmitStoreStack(this ILCursor cursor, [ParamCollection] IReadOnlyList<VariableDefinition> variables)
		{
			//IL_0031: 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_0058: 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)
			if (cursor == null)
			{
				throw new ArgumentNullException("cursor");
			}
			if (variables == null)
			{
				throw new ArgumentNullException("variables");
			}
			if (variables.Count != 0)
			{
				for (int num = variables.Count - 1; num >= 1; num--)
				{
					cursor.Emit(OpCodes.Stloc, variables[num]);
				}
				cursor.Emit(OpCodes.Dup);
				cursor.Emit(OpCodes.Stloc, variables[0]);
				for (int i = 1; i < variables.Count; i++)
				{
					cursor.Emit(OpCodes.Ldloc, variables[i]);
				}
			}
		}

		private static bool matchLocalIndex(int localIndex, Type variableType, ILContext ilContext)
		{
			if ((object)variableType == null)
			{
				throw new ArgumentNullException("variableType");
			}
			if (ilContext == null)
			{
				throw new ArgumentNullException("ilContext");
			}
			if (ilContext.Method == null || !ilContext.Method.HasBody)
			{
				return false;
			}
			if (localIndex < ilContext.Method.Body.Variables.Count)
			{
				return Extensions.Is((MemberReference)(object)((VariableReference)ilContext.Method.Body.Variables[localIndex]).VariableType, (MemberInfo)variableType);
			}
			return false;
		}

		public static bool MatchLdloc(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex)
		{
			if (instruction == null)
			{
				throw new ArgumentNullException("instruction");
			}
			if (ILPatternMatchingExt.MatchLdloc(instruction, ref localIndex))
			{
				return matchLocalIndex(localIndex, variableType, ilContext);
			}
			return false;
		}

		public static bool MatchLdloca(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex)
		{
			if (instruction == null)
			{
				throw new ArgumentNullException("instruction");
			}
			if (ILPatternMatchingExt.MatchLdloca(instruction, ref localIndex))
			{
				return matchLocalIndex(localIndex, variableType, ilContext);
			}
			return false;
		}

		public static bool MatchStloc(this Instruction instruction, Type variableType, ILContext ilContext, out int localIndex)
		{
			if (instruction == null)
			{
				throw new ArgumentNullException("instruction");
			}
			if (ILPatternMatchingExt.MatchStloc(instruction, ref localIndex))
			{
				return matchLocalIndex(localIndex, variableType, ilContext);
			}
			return false;
		}
	}
}
namespace MirroredStageVariants.Patches
{
	internal static class CostTextMirrorFix
	{
		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.CostHologramContent_prefab, autoUnload: false);
			handle.OnSuccess(delegate(GameObject costHologramContent)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				costHologramContent.AddComponent<ScaleOnAwakeIfMirrored>().ScaleMultiplier = new Vector3(-1f, 1f, 1f);
			});
		}
	}
	internal static class HideStunEffect
	{
		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Common_VFX.StunVfx_prefab, autoUnload: false);
			handle.OnSuccess(delegate(GameObject stunVfx)
			{
				TextMeshPro componentInChildren = stunVfx.GetComponentInChildren<TextMeshPro>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					((Behaviour)componentInChildren).enabled = false;
				}
			});
		}
	}
	internal static class InvertDamageNumberPositionsPatch
	{
		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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_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)
			AsyncOperationHandle<GameObject> handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_Base_Core.DamageNumberManager_prefab, autoUnload: false);
			handle.OnSuccess(delegate(GameObject damageNumberManager)
			{
				damageNumberManager.AddComponent<FlipParticleSystemIfMirrored>();
			});
			handle = AssetLoadUtils.LoadAssetAsync<GameObject>(RoR2_DLC1_CritGlassesVoid.CritGlassesVoidExecuteEffect_prefab, autoUnload: false);
			handle.OnSuccess(delegate(GameObject effectPrefab)
			{
				Transform val = effectPrefab.transform.Find("FakeDamageNumbers");
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.AddComponent<FlipParticleSystemIfMirrored>();
				}
				else
				{
					Log.Error("Failed to find fake damage number emitter on CritGlassesVoidExecuteEffect", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertDamageNumberPositionsPatch.cs", "Init", 29);
				}
			});
		}
	}
	internal static class InvertInputPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_CollectLookInput <0>__CameraModeBase_CollectLookInput;

			public static Manipulator <1>__PlayerCharacterMasterController_Update;

			public static <>A{00000001}<Vector2> <2>__tryMirrorMoveInput;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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_0107: 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;
					if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<InputBankTest>(x, "SetRawMoveStates")
					}))
					{
						Log.Error("Failed to find raw move state call", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 52);
					}
					val.Emit(OpCodes.Ldloca, moveInputLocalIndex);
					val.EmitDelegate<<>A{00000001}<Vector2>>((<>A{00000001}<Vector2>)tryMirrorMoveInput);
				}
				else
				{
					Log.Error("Failed to find move input local index", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 67);
				}
			}
			else
			{
				Log.Error("Failed to find patch location", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertInputPatch.cs", "PlayerCharacterMasterController_Update", 72);
			}
			static void tryMirrorMoveInput(ref Vector2 moveInput)
			{
				if (StageMirrorController.CurrentlyIsMirrored)
				{
					moveInput.x *= -1f;
				}
			}
		}
	}
	internal static class InvertScreenCoordinatesPatch
	{
		private delegate Vector3 ScreenCoordinateDelegate(Camera self, Vector3 position, MonoOrStereoscopicEye eye);

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

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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_00b6: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			new Hook((Expression<Action>)(() => ((Camera)null).WorldToScreenPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateResult));
			new Hook((Expression<Action>)(() => ((Camera)null).WorldToViewportPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateResult));
			new Hook((Expression<Action>)(() => ((Camera)null).ScreenToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertPixelCoordinateInput));
			new Hook((Expression<Action>)(() => ((Camera)null).ViewportToWorldPoint(default(Vector3), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenCoordinateDelegate, Camera, Vector3, MonoOrStereoscopicEye, Vector3>(invertNormalizedCoordinateInput));
			new Hook((Expression<Action>)(() => ((Camera)null).ScreenPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayPixelCoordinateInput));
			new Hook((Expression<Action>)(() => ((Camera)null).ViewportPointToRay(default(Vector2), (MonoOrStereoscopicEye)0)), (Delegate)new Func<ScreenRayDelegate, Camera, Vector2, MonoOrStereoscopicEye, Ray>(invertRayNormalizedCoordinateInput));
		}

		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
	{
		[DisallowMultipleComponent]
		private sealed class InvertTypewriterInfo : MonoBehaviour
		{
			public static InvertTypewriterInfo Current;

			public TextMeshProUGUI[] InvertedLabels;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__AssignStageToken_Start;

			public static hook_SetTypingTime <1>__TypewriteTextController_SetTypingTime;

			public static Manipulator <2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel;

			public static Func<TextMeshProUGUI, bool> <3>__shouldMirrorLabel;

			public static Action<TMP_Text, int> <4>__setVisibleCharactersMirrored;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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
			//IL_0093: 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_0093: Expected O, but got Unknown
			object obj = <>O.<0>__AssignStageToken_Start;
			if (obj == null)
			{
				hook_Start val = AssignStageToken_Start;
				<>O.<0>__AssignStageToken_Start = val;
				obj = (object)val;
			}
			AssignStageToken.Start += (hook_Start)obj;
			object obj2 = <>O.<1>__TypewriteTextController_SetTypingTime;
			if (obj2 == null)
			{
				hook_SetTypingTime val2 = TypewriteTextController_SetTypingTime;
				<>O.<1>__TypewriteTextController_SetTypingTime = val2;
				obj2 = (object)val2;
			}
			TypewriteTextController.SetTypingTime += (hook_SetTypingTime)obj2;
			MethodInfo methodInfo = AccessTools.GetDeclaredMethods(typeof(TypewriteTextController)).FirstOrDefault((MethodInfo m) => m.Name.StartsWith("<SetTypingTime>g__UpdateCurrentLabel|"));
			if ((object)methodInfo != null)
			{
				object obj3 = <>O.<2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel;
				if (obj3 == null)
				{
					Manipulator val3 = TypewriteTextController_SetTypingTime_UpdateCurrentLabel;
					<>O.<2>__TypewriteTextController_SetTypingTime_UpdateCurrentLabel = val3;
					obj3 = (object)val3;
				}
				new ILHook((MethodBase)methodInfo, (Manipulator)obj3);
			}
			else
			{
				Log.Error("Failed to find local function UpdateCurrentLabel", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "Init", 34);
			}
		}

		private static void AssignStageToken_Start(orig_Start orig, AssignStageToken self)
		{
			((Component)self).gameObject.AddComponent<InvertTypewriterInfo>().InvertedLabels = (TextMeshProUGUI[])(object)new TextMeshProUGUI[2] { self.titleText, self.subtitleText };
			orig.Invoke(self);
		}

		private static void TypewriteTextController_SetTypingTime(orig_SetTypingTime orig, TypewriteTextController self, float typingTime)
		{
			InvertTypewriterInfo.Current = ((Component)self).GetComponent<InvertTypewriterInfo>();
			try
			{
				orig.Invoke(self, typingTime);
			}
			finally
			{
				InvertTypewriterInfo.Current = null;
			}
		}

		private static void TypewriteTextController_SetTypingTime_UpdateCurrentLabel(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0016: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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)
			ILCursor val = new ILCursor(il);
			ParameterDefinition val2 = null;
			TypeDefinition val3 = null;
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)il.Method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					TypeReference elementType = ((ParameterReference)current).ParameterType.GetElementType();
					if (((MemberReference)elementType).Name.StartsWith("<>c__DisplayClass") && ((MemberReference)elementType).DeclaringType != null && Extensions.Is((MemberReference)(object)((MemberReference)elementType).DeclaringType, (MemberInfo)typeof(TypewriteTextController)))
					{
						TypeDefinition val4 = Extensions.SafeResolve(elementType);
						if (val4 != null)
						{
							val3 = val4;
							val2 = current;
							break;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if (val2 == null)
			{
				Log.Error("Failed to find locals parameter", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 87);
				return;
			}
			FieldDefinition val5 = Extensions.FindField(val3, "currentLabel");
			if (val5 == null || !Extensions.Is((MemberReference)(object)((FieldReference)val5).FieldType, (MemberInfo)typeof(TextMeshProUGUI)))
			{
				Log.Error("Failed to find currentLabel local field", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 94);
			}
			else if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertySetter(typeof(TMP_Text), "maxVisibleCharacters"))
			}))
			{
				ILLabel val6 = val.DefineLabel();
				ILLabel val7 = val.DefineLabel();
				val.Emit(OpCodes.Ldarg, val2);
				val.Emit(OpCodes.Ldfld, (FieldReference)(object)val5);
				val.EmitDelegate<Func<TextMeshProUGUI, bool>>((Func<TextMeshProUGUI, bool>)shouldMirrorLabel);
				val.Emit(OpCodes.Brtrue, (object)val6);
				int index = val.Index;
				val.Index = index + 1;
				val.Emit(OpCodes.Br, (object)val7);
				val.MarkLabel(val6);
				val.MoveAfterLabels();
				val.EmitDelegate<Action<TMP_Text, int>>((Action<TMP_Text, int>)setVisibleCharactersMirrored);
				val.MarkLabel(val7);
			}
			else
			{
				Log.Error("Failed to find patch location", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\InvertTypewriteTextControllerPatch.cs", "TypewriteTextController_SetTypingTime_UpdateCurrentLabel", 132);
			}
			static void setVisibleCharactersMirrored(TMP_Text label, int maxVisibleCharacters)
			{
				label.firstVisibleCharacter = label.text.Length - maxVisibleCharacters;
			}
			static bool shouldMirrorLabel(TextMeshProUGUI label)
			{
				if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)InvertTypewriterInfo.Current))
				{
					return Array.IndexOf(InvertTypewriterInfo.Current.InvertedLabels, label) != -1;
				}
				return false;
			}
		}
	}
	internal static class MirrorAudioPatch
	{
		private delegate int SetObjectPositionDelegate(ulong akObjectId, Vector3 position, Vector3 forward, Vector3 up);

		private sealed class AkObjectData
		{
			public readonly ulong Id;

			public readonly GameObject GameObject;

			public readonly AkGameObj AkObj;

			public Vector3 Position { get; private set; }

			public Vector3 Forward { get; private set; }

			public Vector3 Up { get; private set; }

			public AkObjectData(ulong id, GameObject gameObject)
			{
				//IL_0043: 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_0069: 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_008f: 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)
				Id = id;
				GameObject = gameObject;
				AkObj = gameObject.GetComponent<AkGameObj>();
				Transform transform = gameObject.transform;
				Position = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetPosition() : transform.position);
				Forward = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetForward() : transform.forward);
				Up = (Object.op_Implicit((Object)(object)AkObj) ? AkObj.GetUpward() : transform.up);
			}

			private bool tryGetListenerMirrorTransformation(out Matrix4x4 mirrorTransform)
			{
				//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_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)
				MirrorCamera mirrorCamera = default(MirrorCamera);
				foreach (AkAudioListener item in (Object.op_Implicit((Object)(object)AkObj) && !AkObj.IsUsingDefaultListeners) ? AkObj.ListenerList : ((BaseListenerList)AkAudioListener.DefaultListeners).ListenerList)
				{
					if (((Component)item).TryGetComponent<MirrorCamera>(ref mirrorCamera))
					{
						mirrorTransform = mirrorCamera.MirrorAroundCameraTransformation;
						return true;
					}
				}
				mirrorTransform = Matrix4x4.identity;
				return false;
			}

			public void UpdatePosition(Vector3 position, Vector3 forward, Vector3 up)
			{
				//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
				Position = position;
				Forward = forward;
				Up = up;
			}

			public void GetMirrorPosition(out Vector3 position, out Vector3 forward, out Vector3 up)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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_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_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_003c: 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_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_0058: 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)
				position = Position;
				forward = Forward;
				up = Up;
				if (tryGetListenerMirrorTransformation(out var mirrorTransform))
				{
					position = ((Matrix4x4)(ref mirrorTransform)).MultiplyPoint(position);
					forward = ((Matrix4x4)(ref mirrorTransform)).MultiplyVector(forward);
					up = ((Matrix4x4)(ref mirrorTransform)).MultiplyVector(up);
				}
			}

			public AKRESULT UpdateMirrorPosition()
			{
				//IL_0036: 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)
				GetMirrorPosition(out var position, out var forward, out var up);
				if (_origSetPosition == null)
				{
					Log.Error("Missing set position function", "D:\\Git\\RoR2\\MirroredStageVariants\\VS\\MirroredStageVariants\\Patches\\MirrorAudioPatch.cs", "UpdateMirrorPosition", 85);
					return (AKRESULT)2;
				}
				return (AKRESULT)_origSetPosition(Id, position, forward, up);
			}
		}

		private delegate void orig_AkSoundEngine_PostRegisterGameObjUserHook(AKRESULT result, GameObject gameObject, ulong id);

		private delegate void orig_AkSoundEngine_PostUnregisterGameObjUserHook(AKRESULT result, GameObject gameObject, ulong id);

		private delegate void orig_AkSoundEngine_ClearRegisteredGameObjects();

		private static SetObjectPositionDelegate _origSetPosition;

		private static readonly Dictionary<ulong, AkObjectData> _akObjects = new Dictionary<ulong, AkObjectData>();

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//IL_0033: 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_0053: 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_0073: 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_00d6: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			_origSetPosition = new NativeDetour((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEnginePINVOKE.CSharp_SetObjectPosition(0uL, default(Vector3), default(Vector3), default(Vector3)))), (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine_SetObjectPosition(0uL, default(Vector3), default(Vector3), default(Vector3))))).GenerateTrampoline<SetObjectPositionDelegate>();
			new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostRegisterGameObjUserHook((AKRESULT)0, (GameObject)null, 0uL))), (Delegate)new Action<orig_AkSoundEngine_PostRegisterGameObjUserHook, AKRESULT, GameObject, ulong>(AkSoundEngine_PostRegisterGameObjUserHook));
			new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.PostUnregisterGameObjUserHook((AKRESULT)0, (GameObject)null, 0uL))), (Delegate)new Action<orig_AkSoundEngine_PostUnregisterGameObjUserHook, AKRESULT, GameObject, ulong>(AkSoundEngine_PostUnregisterGameObjUserHook));
			new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => AkSoundEngine.ClearRegisteredGameObjects())), (Delegate)new Action<orig_AkSoundEngine_ClearRegisteredGameObjects>(AkSoundEngine_ClearRegisteredGameObjects));
			MirrorCamera.OnMirrorTransformationChanged += onCameraMirrorTransformationChanged;
		}

		private static void onCameraMirrorTransformationChanged()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			foreach (AkObjectData value in _akObjects.Values)
			{
				value.UpdateMirrorPosition();
			}
		}

		private static void AkSoundEngine_PostRegisterGameObjUserHook(orig_AkSoundEngine_PostRegisterGameObjUserHook orig, AKRESULT result, GameObject gameObject, ulong id)
		{
			//IL_0001: 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_000b: Invalid comparison between Unknown and I4
			orig(result, gameObject, id);
			if ((int)result == 1 && Object.op_Implicit((Object)(object)gameObject) && !_akObjects.ContainsKey(id))
			{
				_akObjects.Add(id, new AkObjectData(id, gameObject));
			}
		}

		private static void AkSoundEngine_PostUnregisterGameObjUserHook(orig_AkSoundEngine_PostUnregisterGameObjUserHook orig, AKRESULT result, GameObject gameObject, ulong id)
		{
			//IL_0001: 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_000b: Invalid comparison between Unknown and I4
			orig(result, gameObject, id);
			if ((int)result == 1)
			{
				_akObjects.Remove(id);
			}
		}

		private static void AkSoundEngine_ClearRegisteredGameObjects(orig_AkSoundEngine_ClearRegisteredGameObjects orig)
		{
			orig();
			_akObjects.Clear();
		}

		private static int AkSoundEngine_SetObjectPosition(ulong akObjectId, Vector3 position, Vector3 forward, Vector3 up)
		{
			//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_002c: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (_akObjects.TryGetValue(akObjectId, out var value))
			{
				value.UpdatePosition(position, forward, up);
				value.GetMirrorPosition(out position, out forward, out up);
			}
			return _origSetPosition(akObjectId, position, forward, up);
		}
	}
	internal static class MirrorEffectsPatch
	{
		[SystemInitializer(new Type[] { typeof(EffectCatalog) })]
		private static void Init()
		{
			//IL_0007: 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_009c: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			List<TMP_Text> list = new List<TMP_Text>();
			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.Clear();
				prefab.GetComponentsInChildren<TMP_Text>(list);
				foreach (TMP_Text item in list)
				{
					if (((Component)item).gameObject.layer == LayerIndex.uiWorldSpace.intVal && !Object.op_Implicit((Object)(object)((Component)item).GetComponent<MirrorTextLabelIfMirrored>()))
					{
						((Component)item).gameObject.AddComponent<MirrorTextLabelIfMirrored>();
					}
				}
			}
		}
	}
}
namespace MirroredStageVariants.ModCompatibility
{
	internal static class RiskOfOptionsCompat
	{
		public static bool IsEnabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigOptions()
		{
			//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_0015: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(MirroredStageVariantsPlugin.MirrorChance, new StepSliderConfig
			{
				formatString = "{0}%",
				min = 0f,
				max = 100f,
				increment = 0.1f
			}), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(MirroredStageVariantsPlugin.MirrorNonStages), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(MirroredStageVariantsPlugin.MirrorHiddenRealms), "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			ModSettingsManager.SetModDescription("Options for Mirrored Stage Variants", "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
			FileInfo fileInfo = null;
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)MirroredStageVariantsPlugin.Instance).Info.Location));
			do
			{
				FileInfo[] files = directoryInfo.GetFiles("icon.png", SearchOption.TopDirectoryOnly);
				if (files != null && files.Length != 0)
				{
					fileInfo = files[0];
					break;
				}
				directoryInfo = directoryInfo.Parent;
			}
			while (directoryInfo != null && directoryInfo.Exists && !string.Equals(directoryInfo.Name, "plugins", StringComparison.OrdinalIgnoreCase));
			if (fileInfo != null)
			{
				Texture2D val = new Texture2D(256, 256);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(fileInfo.FullName)))
				{
					Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					((Object)obj).name = "MirroredStageVariantsIcon";
					ModSettingsManager.SetModIcon(obj, "Gorakh.MirroredStageVariants", "Mirrored Stage Variants");
				}
			}
		}
	}
}
namespace MirroredStageVariants.Components
{
	[DisallowMultipleComponent]
	public sealed class FlipParticleSystemIfMirrored : MonoBehaviour
	{
		private ParticleSystemRenderer _particleRenderer;

		private bool _isFlipped;

		private void Awake()
		{
			_particleRenderer = ((Component)this).GetComponent<ParticleSystemRenderer>();
		}

		private void OnEnable()
		{
			updateIsFlipped();
		}

		private void FixedUpdate()
		{
			updateIsFlipped();
		}

		private void updateIsFlipped()
		{
			bool currentlyIsMirrored = StageMirrorController.CurrentlyIsMirrored;
			setFlipped(currentlyIsMirrored);
		}

		private void setFlipped(bool flipped)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (_isFlipped != flipped)
			{
				_isFlipped = flipped;
				if (Object.op_Implicit((Object)(object)_particleRenderer))
				{
					Vector3 flip = _particleRenderer.flip;
					flip.x = (_isFlipped ? 1f : 0f);
					_particleRenderer.flip = flip;
				}
			}
		}
	}
	public sealed 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>();
			}
		}

		private Matrix4x4 _mirrorAroundCameraTransformation = Matrix4x4.identity;

		public Matrix4x4 MirrorAroundCameraTransformation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _mirrorAroundCameraTransformation;
			}
			private set
			{
				//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
				if (!((Matrix4x4)(ref _mirrorAroundCameraTransformation)).Equals(value))
				{
					_mirrorAroundCameraTransformation = value;
					MirrorCamera.OnMirrorTransformationChanged?.Invoke();
				}
			}
		}

		public static event Action OnMirrorTransformationChanged;

		[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 OnEnable()
		{
			recalculateMirrorTransformation();
		}

		private void Update()
		{
			recalculateMirrorTransformation();
		}

		private void recalculateMirrorTransformation()
		{
			//IL_0033: 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_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)
			if (StageMirrorController.CurrentlyIsMirrored)
			{
				MirrorAroundCameraTransformation = ((Component)this).transform.GlobalTransformationFromLocal(Matrix4x4.Scale(new Vector3(-1f, 1f, 1f)));
			}
			else
			{
				MirrorAroundCameraTransformation = Matrix4x4.identity;
			}
		}

		private void OnRenderImage(RenderTexture source, RenderTexture destination)
		{
			Material mirrorMaterial = Assets.MirrorMaterial;
			if (StageMirrorController.CurrentlyIsMirrored && Object.op_Implicit((Object)(object)mirrorMaterial))
			{
				Graphics.Blit((Texture)(object)source, destination, mirrorMaterial);
			}
			else
			{
				Graphics.Blit((Texture)(object)source, destination);
			}
		}
	}
	[DisallowMultipleComponent]
	public sealed class MirrorTextLabelIfMirrored : MonoBehaviour
	{
		private bool _isRenderingAsMirrored;

		private Vector3 _originalScale;

		private void OnEnable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			Camera.onPreRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(onPreRender));
			Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(onPostRender));
		}

		private void OnDisable()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			Camera.onPreRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(onPreRender));
			Camera.onPostRender = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(onPostRender));
		}

		private void onPreRender(Camera cam)
		{
			//IL_0021: 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_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_0048: Unknown result type (might be due to invalid IL or missing references)
			_isRenderingAsMirrored = cam.ShouldRenderObjectAsMirrored(((Component)this).gameObject);
			if (_isRenderingAsMirrored)
			{
				_originalScale = ((Component)this).transform.localScale;
				Vector3 originalScale = _originalScale;
				originalScale.x *= -1f;
				((Component)this).transform.localScale = originalScale;
			}
		}

		private void onPostRender(Camera cam)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (_isRenderingAsMirrored)
			{
				((Component)this).transform.localScale = _originalScale;
				_isRenderingAsMirrored = false;
			}
		}
	}
	[DefaultExecutionOrder(-1)]
	public sealed 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 sealed 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;

		public static StageMirrorController Instance => _instance;

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

		public bool IsMirrored { get; private set; }

		[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;
			}
			if (MirroredStageVariantsPlugin.MirrorHiddenRealms.Value)
			{
				return true;
			}
			if (scene.stageOrder > 0)
			{
				return scene.stageOrder <= 5;
			}
			return false;
		}

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

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

		private void Awake()
		{
			//IL_0017: 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_0033: Expected O, but got Unknown
			Xoroshiro128Plus val = RoR2Application.rng;
			if (Object.op_Implicit((Object)(object)Run.instance))
			{
				val = new Xoroshiro128Plus((ulong)(Run.instance.NetworkstartTimeUtc._binaryValue + Run.instance.stageClearCount));
			}
			IsMirrored = val.nextNormalizedFloat <= MirroredStageVariantsPlugin.MirrorChance.Value / 100f;
		}
	}
}