Decompiled source of DoomFX v1.0.0

OmniDoomFX.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+343329221fb329c7e3fd5a225d612df8148bb674")]
[assembly: AssemblyProduct("OmniDoomFX")]
[assembly: AssemblyTitle("OmniDoomFX")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 REPO.CursedGfx
{
	public static class Entry
	{
		[RuntimeInitializeOnLoadMethod(/*Could not decode attribute arguments.*/)]
		private static void Bootstrap()
		{
			CursedGraphicsMod.Init();
		}
	}
	[HarmonyPatch]
	public static class CursedGraphicsMod
	{
		private static Harmony _harmony;

		private static bool _patched;

		public static void Init()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!_patched)
			{
				_patched = true;
				_harmony = new Harmony("repo.cursedgfx.doom.autowad");
				_harmony.PatchAll(typeof(CursedGraphicsMod).Assembly);
				Debug.Log((object)"[OmniDoom] Harmony patches applied.");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RenderTextureMain), "Awake")]
		private static void RenderTextureMain_Awake_Postfix(RenderTextureMain __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && (Object)(object)((Component)__instance).gameObject.GetComponent<CursedGraphicsController>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<CursedGraphicsController>();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(RenderTextureMain), "SetRenderTexture")]
		private static void RenderTextureMain_SetRenderTexture_Postfix(RenderTextureMain __instance)
		{
			try
			{
				if ((Object)(object)__instance?.renderTexture != (Object)null)
				{
					((Texture)__instance.renderTexture).filterMode = (FilterMode)0;
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Sound), "Play")]
	public static class Patch_DoomifyAudio
	{
		private static void Postfix(ref AudioSource __result)
		{
			if (!((Object)(object)__result == (Object)null))
			{
				GameObject gameObject = ((Component)__result).gameObject;
				__result.spatialBlend = 1f;
				__result.reverbZoneMix = 0f;
				if ((Object)(object)gameObject.GetComponent<DoomifyFilter>() == (Object)null)
				{
					DoomifyFilter doomifyFilter = gameObject.AddComponent<DoomifyFilter>();
					((Behaviour)doomifyFilter).enabled = DoomAudioManager.GlobalSfxEnabled;
				}
				AudioLowPassFilter val = gameObject.GetComponent<AudioLowPassFilter>() ?? gameObject.AddComponent<AudioLowPassFilter>();
				val.cutoffFrequency = 6000f;
				AudioHighPassFilter val2 = gameObject.GetComponent<AudioHighPassFilter>() ?? gameObject.AddComponent<AudioHighPassFilter>();
				val2.cutoffFrequency = 40f;
			}
		}
	}
	public sealed class DoomAudioManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <LoadClipCoroutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DoomAudioManager <>4__this;

			private string <baseDir>5__1;

			private string <chosen>5__2;

			private AudioType <type>5__3;

			private string <uri>5__4;

			private string <ogg>5__5;

			private string <wav>5__6;

			private UnityWebRequest <req>5__7;

			private AudioClip <clip>5__8;

			private Exception <e>5__9;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<baseDir>5__1 = null;
				<chosen>5__2 = null;
				<uri>5__4 = null;
				<ogg>5__5 = null;
				<wav>5__6 = null;
				<req>5__7 = null;
				<clip>5__8 = null;
				<e>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						<baseDir>5__1 = <>4__this.MusicDir;
						try
						{
							Directory.CreateDirectory(<baseDir>5__1);
						}
						catch
						{
						}
						<chosen>5__2 = Path.Combine(<baseDir>5__1, "DoomMusic.mp3");
						if (!File.Exists(<chosen>5__2))
						{
							<ogg>5__5 = Path.Combine(<baseDir>5__1, "DoomMusic.ogg");
							<wav>5__6 = Path.Combine(<baseDir>5__1, "DoomMusic.wav");
							if (File.Exists(<ogg>5__5))
							{
								<chosen>5__2 = <ogg>5__5;
							}
							else if (File.Exists(<wav>5__6))
							{
								<chosen>5__2 = <wav>5__6;
							}
							<ogg>5__5 = null;
							<wav>5__6 = null;
						}
						if (!File.Exists(<chosen>5__2))
						{
							Debug.Log((object)("[OmniDoom] No music file found. Place 'DoomMusic.mp3' in: " + <baseDir>5__1));
							<>4__this._loader = null;
							result = false;
							break;
						}
						<type>5__3 = GuessAudioTypeFromExtension(<chosen>5__2);
						<uri>5__4 = new Uri(<chosen>5__2).AbsoluteUri;
						<req>5__7 = UnityWebRequestMultimedia.GetAudioClip(<uri>5__4, <type>5__3);
						<>1__state = -3;
						<>2__current = <req>5__7.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						{
							<>1__state = -3;
							if (<req>5__7.isNetworkError || <req>5__7.isHttpError)
							{
								Debug.LogWarning((object)("[OmniDoom] Failed to load " + <chosen>5__2 + ": " + <req>5__7.error));
								<>4__this._loader = null;
								result = false;
								goto IL_027e;
							}
							try
							{
								<clip>5__8 = DownloadHandlerAudioClip.GetContent(<req>5__7);
								if ((Object)(object)<clip>5__8 != (Object)null)
								{
									<>4__this._clip = <clip>5__8;
								}
								<clip>5__8 = null;
							}
							catch (Exception ex)
							{
								<e>5__9 = ex;
								Debug.LogWarning((object)("[OmniDoom] Exception decoding " + <chosen>5__2 + ": " + <e>5__9.Message));
								<>4__this._loader = null;
								result = false;
								goto IL_027e;
							}
							<>m__Finally1();
							<req>5__7 = null;
							if (<>4__this._active && (Object)(object)<>4__this._clip != (Object)null)
							{
								<>4__this._music.clip = <>4__this._clip;
								<>4__this._music.Play();
							}
							<>4__this._loader = null;
							result = false;
							break;
						}
						IL_027e:
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			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 (<req>5__7 != null)
				{
					((IDisposable)<req>5__7).Dispose();
				}
			}

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

		public static bool GlobalSfxEnabled;

		private AudioSource _music;

		private AudioClip _clip;

		private bool _active;

		private Coroutine _loader;

		public static DoomAudioManager Instance { get; private set; }

		private string MusicDir
		{
			get
			{
				try
				{
					return Path.Combine(Paths.PluginPath, "Omniscye-DoomFX", "Music");
				}
				catch
				{
					return Path.Combine(Application.dataPath, "..", "plugins", "Omniscye-DoomFX", "Music");
				}
			}
		}

		public static DoomAudioManager Ensure()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			GameObject val = new GameObject("REPO.DoomAudioManager");
			Object.DontDestroyOnLoad((Object)(object)val);
			Instance = val.AddComponent<DoomAudioManager>();
			return Instance;
		}

		private void Awake()
		{
			_music = ((Component)this).gameObject.AddComponent<AudioSource>();
			_music.loop = true;
			_music.playOnAwake = false;
			_music.spatialBlend = 0f;
			_music.reverbZoneMix = 0f;
			_music.volume = 0.6f;
		}

		public void SetActive(bool on)
		{
			_active = on;
			if (on)
			{
				if ((Object)(object)_clip == (Object)null && _loader == null)
				{
					_loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine());
				}
				else if ((Object)(object)_clip != (Object)null && !_music.isPlaying)
				{
					_music.clip = _clip;
					_music.Play();
				}
			}
			else if (_music.isPlaying)
			{
				_music.Stop();
			}
		}

		public void ToggleMusic()
		{
			if (!_active)
			{
				SetActive(on: true);
				return;
			}
			if ((Object)(object)_clip == (Object)null)
			{
				if (_loader == null)
				{
					_loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine());
				}
				return;
			}
			if (_music.isPlaying)
			{
				_music.Pause();
				return;
			}
			if ((Object)(object)_music.clip != (Object)(object)_clip)
			{
				_music.clip = _clip;
			}
			if (_music.time > 0f && _music.time < _music.clip.length)
			{
				_music.UnPause();
			}
			else
			{
				_music.Play();
			}
		}

		public void Reload()
		{
			if (_loader != null)
			{
				((MonoBehaviour)this).StopCoroutine(_loader);
			}
			_clip = null;
			if (_music.isPlaying)
			{
				_music.Stop();
			}
			_loader = ((MonoBehaviour)this).StartCoroutine(LoadClipCoroutine());
		}

		[IteratorStateMachine(typeof(<LoadClipCoroutine>d__16))]
		private IEnumerator LoadClipCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadClipCoroutine>d__16(0)
			{
				<>4__this = this
			};
		}

		private static AudioType GuessAudioTypeFromExtension(string path)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(path).ToLowerInvariant();
			if (1 == 0)
			{
			}
			AudioType result = (AudioType)(text switch
			{
				".ogg" => 14, 
				".wav" => 20, 
				".mp3" => 13, 
				_ => 0, 
			});
			if (1 == 0)
			{
			}
			return result;
		}
	}
	public class DoomifyFilter : MonoBehaviour
	{
		[Range(8000f, 16000f)]
		public float targetSampleRate = 11025f;

		[Range(0f, 24f)]
		public float preGainDb = 6f;

		[Range(0f, 1f)]
		public float drive = 0.15f;

		private int _systemRate;

		private float _holdStep;

		private float _holdCounter;

		private float _last;

		private void Awake()
		{
			_systemRate = AudioSettings.outputSampleRate;
			_holdStep = Mathf.Max(1f, (float)_systemRate / Mathf.Max(1000f, targetSampleRate));
			_holdCounter = 0f;
		}

		private void OnEnable()
		{
			_systemRate = AudioSettings.outputSampleRate;
			_holdStep = Mathf.Max(1f, (float)_systemRate / Mathf.Max(1000f, targetSampleRate));
		}

		private void OnAudioFilterRead(float[] data, int channels)
		{
			if (!DoomAudioManager.GlobalSfxEnabled || channels <= 0)
			{
				return;
			}
			float num = Mathf.Pow(10f, preGainDb / 20f);
			for (int i = 0; i < data.Length; i += channels)
			{
				float num2 = 0f;
				for (int j = 0; j < channels; j++)
				{
					num2 += data[i + j];
				}
				num2 /= (float)channels;
				_holdCounter += 1f;
				if (_holdCounter >= _holdStep)
				{
					_holdCounter = 0f;
					float num3 = Mathf.Clamp(num2 * num, -1f, 1f);
					if (drive > 0f)
					{
						num3 = (float)Math.Tanh(num3 * (1f + drive * 10f));
					}
					int num4 = Mathf.Clamp(Mathf.RoundToInt((num3 * 0.5f + 0.5f) * 255f), 0, 255);
					_last = ((float)num4 / 255f - 0.5f) * 2f;
				}
				for (int k = 0; k < channels; k++)
				{
					data[i + k] = _last;
				}
			}
		}
	}
	public sealed class CursedGraphicsController : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ApplyFlatToExistingDelayed>d__45 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float extraDelaySeconds;

			public CursedGraphicsController <>4__this;

			private EnemyParent[] <>s__1;

			private int <>s__2;

			private EnemyParent <e>5__3;

			private ValuableObject[] <>s__4;

			private int <>s__5;

			private ValuableObject <v>5__6;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>s__1 = null;
				<e>5__3 = null;
				<>s__4 = null;
				<v>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Expected O, but got Unknown
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForFixedUpdate();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (extraDelaySeconds > 0f)
					{
						<>2__current = (object)new WaitForSecondsRealtime(extraDelaySeconds);
						<>1__state = 3;
						return true;
					}
					break;
				case 3:
					<>1__state = -1;
					break;
				}
				if (!<>4__this.ModEnabled)
				{
					return false;
				}
				<>s__1 = Object.FindObjectsByType<EnemyParent>((FindObjectsSortMode)0);
				for (<>s__2 = 0; <>s__2 < <>s__1.Length; <>s__2++)
				{
					<e>5__3 = <>s__1[<>s__2];
					if (Object.op_Implicit((Object)(object)<e>5__3) && ((Component)<e>5__3).gameObject.activeInHierarchy)
					{
						FlatUtil.TryFlatify(((Component)<e>5__3).gameObject);
					}
					<e>5__3 = null;
				}
				<>s__1 = null;
				<>s__4 = Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0);
				for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++)
				{
					<v>5__6 = <>s__4[<>s__5];
					if (Object.op_Implicit((Object)(object)<v>5__6) && ((Component)<v>5__6).gameObject.activeInHierarchy)
					{
						FlatUtil.TryFlatify(((Component)<v>5__6).gameObject);
					}
					<v>5__6 = null;
				}
				<>s__4 = null;
				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 bool ModEnabled = false;

		[Range(0.25f, 4f)]
		public float DoomLightScale = 1f;

		[Range(-1f, 1f)]
		public float DoomLightBias = 0f;

		public bool DoomLightByRow = true;

		public bool Scanlines = true;

		[Range(0f, 2f)]
		public int Sharpen = 1;

		[Range(64f, 960f)]
		public int TargetWidth = 320;

		[Range(64f, 960f)]
		public int TargetHeight = 200;

		private RenderTextureMain _rtm;

		private RenderTexture _rt;

		private RawImage _gameOverlay;

		private RawImage _cursedOverlay;

		private Texture _originalGameTexture;

		private bool _installedOverlay;

		private Texture2D _workTex;

		private Color32[] _buffer;

		private Color32[] _outBuffer;

		private RenderTexture _downscaleRT;

		private bool _doomAssetsLoaded;

		private string _wadUsed = "";

		private Color32[] _doomPalette;

		private byte[,] _colormap;

		private int[] _rgbToIndexLUT;

		private void Awake()
		{
			CursedGraphicsMod.Init();
		}

		private void Start()
		{
			_rtm = RenderTextureMain.instance;
			if ((Object)(object)_rtm == (Object)null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			_gameOverlay = _rtm.overlayRawImage;
			_rt = _rtm.renderTexture;
			if ((Object)(object)_rt != (Object)null)
			{
				((Texture)_rt).filterMode = (FilterMode)0;
			}
			RawImage gameOverlay = _gameOverlay;
			if ((Object)(object)((gameOverlay != null) ? gameOverlay.texture : null) != (Object)null)
			{
				_gameOverlay.texture.filterMode = (FilterMode)0;
			}
			AllocateWorking(TargetWidth, TargetHeight);
			if ((Object)(object)_gameOverlay != (Object)null)
			{
				_originalGameTexture = _gameOverlay.texture;
			}
			TryLoadDoomAssets();
			DoomAudioManager.Ensure();
			DoomAudioManager.GlobalSfxEnabled = false;
			DoomAudioManager.Ensure().SetActive(on: false);
			SyncAllDoomifyFilters(enabled: false);
			Debug.Log((object)(_doomAssetsLoaded ? ("[OmniDoom] DOOM palette ACTIVE (from \"" + _wadUsed + "\"). Starts OFF.") : "[OmniDoom] DOOM assets not found; effect will be inert."));
		}

		private void TryLoadDoomAssets()
		{
			byte[] playpal = null;
			byte[] colormap = null;
			string dir = Path.Combine(Paths.PluginPath, "Omniscye-DoomFX");
			if (TryLoadFromPreferredNames(dir, out playpal, out colormap, out _wadUsed) || TryScanWadsInDir(dir, out playpal, out colormap, out _wadUsed) || TryScanWadsInDir(Paths.PluginPath, out playpal, out colormap, out _wadUsed))
			{
				ParseDoomLumps(playpal, colormap);
				return;
			}
			TextAsset val = Resources.Load<TextAsset>("DOOM/PLAYPAL");
			TextAsset val2 = Resources.Load<TextAsset>("DOOM/COLORMAP");
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
			{
				_wadUsed = "Resources/DOOM/*";
				ParseDoomLumps(val.bytes, val2.bytes);
			}
			else
			{
				_doomAssetsLoaded = false;
			}
		}

		private bool TryLoadFromPreferredNames(string dir, out byte[] playpal, out byte[] colormap, out string wadUsed)
		{
			playpal = (colormap = null);
			wadUsed = "";
			if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir))
			{
				return false;
			}
			string[] array = new string[6] { "freedm.wad", "freedoom.wad", "freedoom1.wad", "freedoom2.wad", "doom.wad", "doom2.wad" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = Path.Combine(dir, text);
				if (File.Exists(text2) && TryLoadFromWad(text2, "PLAYPAL", "COLORMAP", out playpal, out colormap))
				{
					wadUsed = Path.GetFileName(text2);
					return true;
				}
				string text3 = Path.Combine(dir, text.ToUpperInvariant());
				if (File.Exists(text3) && TryLoadFromWad(text3, "PLAYPAL", "COLORMAP", out playpal, out colormap))
				{
					wadUsed = Path.GetFileName(text3);
					return true;
				}
			}
			return false;
		}

		private bool TryScanWadsInDir(string dir, out byte[] playpal, out byte[] colormap, out string wadUsed)
		{
			playpal = (colormap = null);
			wadUsed = "";
			if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir))
			{
				return false;
			}
			string[] files = Directory.GetFiles(dir, "*.wad", SearchOption.TopDirectoryOnly);
			if (files.Length == 0)
			{
				files = Directory.GetFiles(dir, "*.WAD", SearchOption.TopDirectoryOnly);
			}
			string[] array = files;
			foreach (string text in array)
			{
				if (TryLoadFromWad(text, "PLAYPAL", "COLORMAP", out playpal, out colormap))
				{
					wadUsed = Path.GetFileName(text);
					return true;
				}
			}
			return false;
		}

		private bool TryLoadFromWad(string wadPath, string lumpA, string lumpB, out byte[] a, out byte[] b)
		{
			a = (b = null);
			try
			{
				using FileStream fileStream = new FileStream(wadPath, FileMode.Open, FileAccess.Read);
				using BinaryReader binaryReader = new BinaryReader(fileStream);
				string text = new string(binaryReader.ReadChars(4));
				int num = binaryReader.ReadInt32();
				int num2 = binaryReader.ReadInt32();
				if (num <= 0 || num2 <= 0)
				{
					return false;
				}
				fileStream.Position = num2;
				long position = 0L;
				long position2 = 0L;
				int num3 = 0;
				int num4 = 0;
				for (int i = 0; i < num; i++)
				{
					int num5 = binaryReader.ReadInt32();
					int num6 = binaryReader.ReadInt32();
					string text2 = new string(binaryReader.ReadChars(8)).TrimEnd('\0');
					if (text2.Equals(lumpA, StringComparison.OrdinalIgnoreCase))
					{
						position = num5;
						num3 = num6;
					}
					if (text2.Equals(lumpB, StringComparison.OrdinalIgnoreCase))
					{
						position2 = num5;
						num4 = num6;
					}
				}
				if (num3 > 0)
				{
					fileStream.Position = position;
					a = binaryReader.ReadBytes(num3);
				}
				if (num4 > 0)
				{
					fileStream.Position = position2;
					b = binaryReader.ReadBytes(num4);
				}
				return a != null && b != null;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[OmniDoom] WAD read failed: " + ex.Message));
				return false;
			}
		}

		private void ParseDoomLumps(byte[] pp, byte[] cm)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (pp == null || cm == null)
				{
					_doomAssetsLoaded = false;
					return;
				}
				if (pp.Length < 10752)
				{
					_doomAssetsLoaded = false;
					return;
				}
				_doomPalette = (Color32[])(object)new Color32[256];
				int num = 0;
				for (int i = 0; i < 256; i++)
				{
					int num2 = num + i * 3;
					_doomPalette[i] = new Color32(pp[num2], pp[num2 + 1], pp[num2 + 2], byte.MaxValue);
				}
				int num3 = cm.Length / 256;
				int num4 = Mathf.Clamp(num3, 1, 34);
				_colormap = new byte[num4, 256];
				for (int j = 0; j < num4; j++)
				{
					for (int k = 0; k < 256; k++)
					{
						_colormap[j, k] = cm[j * 256 + k];
					}
				}
				BuildRGBToIndexLUT();
				_doomAssetsLoaded = true;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[OmniDoom] Failed to parse DOOM lumps: " + ex.Message));
				_doomAssetsLoaded = false;
			}
		}

		private void BuildRGBToIndexLUT()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			_rgbToIndexLUT = new int[32768];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					for (int k = 0; k < 32; k++)
					{
						int num = (i << 3) | (i >> 2);
						int num2 = (j << 3) | (j >> 2);
						int num3 = (k << 3) | (k >> 2);
						int num4 = 0;
						int num5 = int.MaxValue;
						for (int l = 0; l < 256; l++)
						{
							Color32 val = _doomPalette[l];
							int num6 = num - val.r;
							num6 *= num6;
							int num7 = num2 - val.g;
							num7 *= num6;
							int num8 = num3 - val.b;
							num8 *= num8;
							int num9 = num6 + num7 + num8;
							if (num9 < num5)
							{
								num5 = num9;
								num4 = l;
							}
						}
						_rgbToIndexLUT[(i << 10) | (j << 5) | k] = num4;
					}
				}
			}
		}

		private void AllocateWorking(int w, int h)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if ((Object)(object)_workTex != (Object)null)
			{
				Object.Destroy((Object)(object)_workTex);
			}
			_workTex = new Texture2D(w, h, (TextureFormat)4, false, false)
			{
				filterMode = (FilterMode)0
			};
			_buffer = (Color32[])(object)new Color32[w * h];
			_outBuffer = (Color32[])(object)new Color32[w * h];
			EnsureDownscaleRT(w, h);
			if ((Object)(object)_cursedOverlay != (Object)null)
			{
				_cursedOverlay.texture = (Texture)(object)_workTex;
			}
		}

		private void EnsureDownscaleRT(int w, int h)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if ((Object)(object)_downscaleRT != (Object)null && (((Texture)_downscaleRT).width != w || ((Texture)_downscaleRT).height != h))
			{
				_downscaleRT.Release();
				Object.Destroy((Object)(object)_downscaleRT);
				_downscaleRT = null;
			}
			if ((Object)(object)_downscaleRT == (Object)null)
			{
				_downscaleRT = new RenderTexture(w, h, 0, (RenderTextureFormat)0)
				{
					filterMode = (FilterMode)0,
					useMipMap = false,
					autoGenerateMips = false
				};
				_downscaleRT.Create();
			}
		}

		private void InstallOverlay()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (!_installedOverlay && !((Object)(object)_gameOverlay == (Object)null))
			{
				GameObject val = new GameObject("OmniDoom Output", new Type[2]
				{
					typeof(RectTransform),
					typeof(RawImage)
				});
				RectTransform component = val.GetComponent<RectTransform>();
				((Transform)component).SetParent(((Component)_gameOverlay).transform.parent, false);
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				_cursedOverlay = val.GetComponent<RawImage>();
				((Graphic)_cursedOverlay).raycastTarget = false;
				((Graphic)_cursedOverlay).material = ((Graphic)_gameOverlay).material;
				_cursedOverlay.texture = (Texture)(object)_workTex;
				val.transform.SetSiblingIndex(((Component)_gameOverlay).transform.GetSiblingIndex());
				((Behaviour)_gameOverlay).enabled = false;
				_installedOverlay = true;
			}
		}

		private void RestoreOverlay()
		{
			if ((Object)(object)_gameOverlay != (Object)null)
			{
				((Behaviour)_gameOverlay).enabled = true;
				if ((Object)(object)_originalGameTexture != (Object)null)
				{
					_gameOverlay.texture = _originalGameTexture;
				}
			}
			if ((Object)(object)_cursedOverlay != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_cursedOverlay).gameObject);
			}
			_cursedOverlay = null;
			_installedOverlay = false;
		}

		private void Update()
		{
			HandleHotkeys();
		}

		private void LateUpdate()
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if (ModEnabled && _doomAssetsLoaded && !((Object)(object)_rtm?.renderTexture == (Object)null) && !((Object)(object)_workTex == (Object)null))
			{
				if (!_installedOverlay && (Object)(object)_gameOverlay != (Object)null)
				{
					InstallOverlay();
				}
				int targetWidth = TargetWidth;
				int targetHeight = TargetHeight;
				if (((Texture)_workTex).width != targetWidth || ((Texture)_workTex).height != targetHeight)
				{
					AllocateWorking(targetWidth, targetHeight);
				}
				_rt = _rtm.renderTexture;
				((Texture)_rt).filterMode = (FilterMode)0;
				RenderTexture active = RenderTexture.active;
				try
				{
					Graphics.Blit((Texture)(object)_rt, _downscaleRT);
					RenderTexture.active = _downscaleRT;
					_workTex.ReadPixels(new Rect(0f, 0f, (float)targetWidth, (float)targetHeight), 0, 0, false);
					_workTex.Apply(false, false);
				}
				finally
				{
					RenderTexture.active = active;
				}
				Color32[] pixels = _workTex.GetPixels32();
				EnsureBuffers(pixels.Length);
				ProcessDoomPalette(pixels, _outBuffer, targetWidth, targetHeight);
				_workTex.SetPixels32(_outBuffer);
				_workTex.Apply(false, false);
				if ((Object)(object)_cursedOverlay != (Object)null && (Object)(object)_cursedOverlay.texture != (Object)(object)_workTex)
				{
					_cursedOverlay.texture = (Texture)(object)_workTex;
				}
			}
		}

		private void EnsureBuffers(int n)
		{
			if (_buffer == null || _buffer.Length != n)
			{
				_buffer = (Color32[])(object)new Color32[n];
			}
			if (_outBuffer == null || _outBuffer.Length != n)
			{
				_outBuffer = (Color32[])(object)new Color32[n];
			}
		}

		private void ProcessDoomPalette(Color32[] src, Color32[] dst, int w, int h)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Min(_colormap.GetLength(0), 32);
			float doomLightBias = DoomLightBias;
			float doomLightScale = DoomLightScale;
			for (int i = 0; i < h; i++)
			{
				float num2 = (float)i / (float)(h - 1);
				float num3 = (DoomLightByRow ? (1f - num2) : 1f);
				float num4 = Mathf.Clamp01(num3 * doomLightScale + doomLightBias);
				int num5 = Mathf.Clamp(Mathf.RoundToInt((1f - num4) * (float)(num - 1)), 0, num - 1);
				int num6 = i * w;
				for (int j = 0; j < w; j++)
				{
					Color32 val = src[num6 + j];
					int num7 = (val.r >> 3 << 10) | (val.g >> 3 << 5) | (val.b >> 3);
					int num8 = _rgbToIndexLUT[num7];
					int num9 = _colormap[num5, num8];
					dst[num6 + j] = _doomPalette[num9];
				}
			}
			if (Scanlines)
			{
				DarkenEveryOtherRow(dst, w, h, 0.75f);
			}
			if (Sharpen > 0)
			{
				ApplySharpen(dst, w, h, Sharpen);
			}
		}

		private static void DarkenEveryOtherRow(Color32[] px, int w, int h, float factor)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < h; i += 2)
			{
				int num = i * w;
				for (int j = 0; j < w; j++)
				{
					int num2 = num + j;
					Color32 val = px[num2];
					val.r = (byte)((float)(int)val.r * factor);
					val.g = (byte)((float)(int)val.g * factor);
					val.b = (byte)((float)(int)val.b * factor);
					px[num2] = val;
				}
			}
		}

		private void ApplySharpen(Color32[] px, int w, int h, int strength)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			Color32[] buffer = _buffer;
			Array.Copy(px, buffer, px.Length);
			for (int i = 0; i < strength; i++)
			{
				for (int j = 1; j < h - 1; j++)
				{
					int num = j * w;
					for (int k = 1; k < w - 1; k++)
					{
						int num2 = num + k;
						Color32 val = buffer[num2];
						int num3 = val.r * 5;
						int num4 = val.g * 5;
						int num5 = val.b * 5;
						Color32 val2 = buffer[num2 - 1];
						Color32 val3 = buffer[num2 + 1];
						Color32 val4 = buffer[num2 - w];
						Color32 val5 = buffer[num2 + w];
						num3 -= val2.r + val3.r + val4.r + val5.r;
						num4 -= val2.g + val3.g + val4.g + val5.g;
						num5 -= val2.b + val3.b + val4.b + val5.b;
						px[num2] = new Color32((byte)Mathf.Clamp(num3, 0, 255), (byte)Mathf.Clamp(num4, 0, 255), (byte)Mathf.Clamp(num5, 0, 255), byte.MaxValue);
					}
				}
				Array.Copy(px, buffer, px.Length);
			}
		}

		private void HandleHotkeys()
		{
			if (Input.GetKeyDown((KeyCode)289))
			{
				ModEnabled = !ModEnabled;
				if (ModEnabled)
				{
					InstallOverlay();
					DoomAudioManager.GlobalSfxEnabled = true;
					SyncAllDoomifyFilters(enabled: true);
					DoomAudioManager.Ensure().SetActive(on: true);
					((MonoBehaviour)this).StopAllCoroutines();
					((MonoBehaviour)this).StartCoroutine(ApplyFlatToExistingDelayed(0.15f));
				}
				else
				{
					DoomAudioManager.GlobalSfxEnabled = false;
					SyncAllDoomifyFilters(enabled: false);
					DoomAudioManager.Ensure().SetActive(on: false);
					RestoreOverlay();
					RestoreAllFlatified();
				}
			}
			if (ModEnabled)
			{
				if (Input.GetKeyDown((KeyCode)59))
				{
					DoomLightScale = Mathf.Clamp(DoomLightScale * 0.9f, 0.25f, 4f);
				}
				if (Input.GetKeyDown((KeyCode)39))
				{
					DoomLightScale = Mathf.Clamp(DoomLightScale * 1.1f, 0.25f, 4f);
				}
				if (Input.GetKeyDown((KeyCode)44))
				{
					DoomLightBias = Mathf.Clamp(DoomLightBias - 0.05f, -1f, 1f);
				}
				if (Input.GetKeyDown((KeyCode)46))
				{
					DoomLightBias = Mathf.Clamp(DoomLightBias + 0.05f, -1f, 1f);
				}
				if (Input.GetKeyDown((KeyCode)288))
				{
					Scanlines = !Scanlines;
				}
				if (Input.GetKeyDown((KeyCode)91))
				{
					Sharpen = Mathf.Clamp(Sharpen - 1, 0, 2);
				}
				if (Input.GetKeyDown((KeyCode)93))
				{
					Sharpen = Mathf.Clamp(Sharpen + 1, 0, 2);
				}
				if (Input.GetKeyDown((KeyCode)280))
				{
					TargetWidth = Mathf.Clamp(TargetWidth + 16, 64, 960);
					TargetHeight = Mathf.Clamp(TargetHeight + 10, 64, 960);
					AllocateWorking(TargetWidth, TargetHeight);
				}
				else if (Input.GetKeyDown((KeyCode)281))
				{
					TargetWidth = Mathf.Clamp(TargetWidth - 16, 64, 960);
					TargetHeight = Mathf.Clamp(TargetHeight - 10, 64, 960);
					AllocateWorking(TargetWidth, TargetHeight);
				}
				if (Input.GetKeyDown((KeyCode)291))
				{
					DoomAudioManager.Ensure().ToggleMusic();
				}
				if (Input.GetKeyDown((KeyCode)293))
				{
					DoomAudioManager.Ensure().Reload();
				}
				if (Input.GetKeyDown((KeyCode)292))
				{
					DoomAudioManager.GlobalSfxEnabled = !DoomAudioManager.GlobalSfxEnabled;
					SyncAllDoomifyFilters(DoomAudioManager.GlobalSfxEnabled);
				}
			}
		}

		private void OnGUI()
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			string text = (_doomAssetsLoaded ? ("OmniDoom (PLAYPAL from \"" + _wadUsed + "\")") : "OmniDoom");
			string text2 = (ModEnabled ? ($"{text} — {TargetWidth}x{TargetHeight}\n" + "[F8 toggle | F7 scanlines | [ ] sharpen | PgUp/PgDn res]\n" + string.Format("LightScale:{0:0.00} (;/')  LightBias:{1:+0.00;-0.00;0} (,/.)  RowLight:{2}\n", DoomLightScale, DoomLightBias, DoomLightByRow ? "ON" : "OFF") + "Audio: F10 music on/off | F11 SFX Doomify (" + (DoomAudioManager.GlobalSfxEnabled ? "ON" : "OFF") + ") | F12 reload music") : (text + " — DISABLED (F8 to enable)"));
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = 12
			};
			val.normal.textColor = Color.black;
			GUIStyle val2 = val;
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(10f, 10f, (float)Screen.width, 80f);
			GUI.Label(new Rect(((Rect)(ref val3)).x + 1f, ((Rect)(ref val3)).y + 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text2, val2);
			val2.normal.textColor = Color.green;
			GUI.Label(val3, text2, val2);
		}

		private void OnDisable()
		{
			RestoreAllFlatified();
			DoomAudioManager.GlobalSfxEnabled = false;
			SyncAllDoomifyFilters(enabled: false);
			DoomAudioManager.Ensure().SetActive(on: false);
		}

		private void RestoreAllFlatified()
		{
			_FlatMarker[] array = Object.FindObjectsByType<_FlatMarker>((FindObjectsSortMode)0);
			foreach (_FlatMarker flatMarker in array)
			{
				FlatUtil.Restore(((Component)flatMarker).gameObject);
			}
		}

		[IteratorStateMachine(typeof(<ApplyFlatToExistingDelayed>d__45))]
		private IEnumerator ApplyFlatToExistingDelayed(float extraDelaySeconds)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyFlatToExistingDelayed>d__45(0)
			{
				<>4__this = this,
				extraDelaySeconds = extraDelaySeconds
			};
		}

		private void SyncAllDoomifyFilters(bool enabled)
		{
			DoomifyFilter[] array = Object.FindObjectsByType<DoomifyFilter>((FindObjectsSortMode)0);
			DoomifyFilter[] array2 = array;
			foreach (DoomifyFilter doomifyFilter in array2)
			{
				if (Object.op_Implicit((Object)(object)doomifyFilter))
				{
					((Behaviour)doomifyFilter).enabled = enabled;
				}
			}
		}
	}
	internal sealed class _FlatMarker : MonoBehaviour
	{
		public Dictionary<Transform, Vector3> original = new Dictionary<Transform, Vector3>();
	}
	internal static class FlatUtil
	{
		public static void TryFlatify(GameObject root, float depth = 0.01f)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			_FlatMarker flatMarker = root.GetComponent<_FlatMarker>() ?? root.AddComponent<_FlatMarker>();
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Transform transform = ((Component)val).transform;
				if (!flatMarker.original.ContainsKey(transform))
				{
					flatMarker.original[transform] = transform.localScale;
				}
				Vector3 localScale = transform.localScale;
				transform.localScale = new Vector3(localScale.x, localScale.y, Mathf.Max(depth, 0.0001f));
			}
		}

		public static void Restore(GameObject root)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_FlatMarker flatMarker = ((root != null) ? root.GetComponent<_FlatMarker>() : null);
			if ((Object)(object)flatMarker == (Object)null)
			{
				return;
			}
			foreach (KeyValuePair<Transform, Vector3> item in flatMarker.original)
			{
				if (Object.op_Implicit((Object)(object)item.Key))
				{
					item.Key.localScale = item.Value;
				}
			}
			Object.Destroy((Object)(object)flatMarker);
		}
	}
	internal static class FlatDelay
	{
		[CompilerGenerated]
		private sealed class <WaitThenFlat>d__0 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject go;

			public float depth;

			public float extraSeconds;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Expected O, but got Unknown
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForFixedUpdate();
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (extraSeconds > 0f)
					{
						<>2__current = (object)new WaitForSecondsRealtime(extraSeconds);
						<>1__state = 3;
						return true;
					}
					break;
				case 3:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)go != (Object)null)
				{
					FlatUtil.TryFlatify(go, depth);
				}
				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();
			}
		}

		[IteratorStateMachine(typeof(<WaitThenFlat>d__0))]
		public static IEnumerator WaitThenFlat(GameObject go, float depth, float extraSeconds = 0.1f)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitThenFlat>d__0(0)
			{
				go = go,
				depth = depth,
				extraSeconds = extraSeconds
			};
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
	internal static class Patch_FlatEnemies_OnSpawn
	{
		private const float EnemyFlatDepth = 0.01f;

		private const float EnemyExtraDelay = 0.15f;

		private static void Postfix(EnemyParent __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				CursedGraphicsController cursedGraphicsController = Object.FindFirstObjectByType<CursedGraphicsController>();
				if (!((Object)(object)cursedGraphicsController == (Object)null) && cursedGraphicsController.ModEnabled)
				{
					((MonoBehaviour)__instance).StartCoroutine(FlatDelay.WaitThenFlat(((Component)__instance).gameObject, 0.01f, 0.15f));
				}
			}
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "Start")]
	internal static class Patch_FlatValuables_OnStart
	{
		private const float ValFlatDepth = 0.01f;

		private const float ValExtraDelay = 0.1f;

		private static void Postfix(ValuableObject __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				CursedGraphicsController cursedGraphicsController = Object.FindFirstObjectByType<CursedGraphicsController>();
				if (!((Object)(object)cursedGraphicsController == (Object)null) && cursedGraphicsController.ModEnabled)
				{
					((MonoBehaviour)__instance).StartCoroutine(FlatDelay.WaitThenFlat(((Component)__instance).gameObject, 0.01f));
				}
			}
		}
	}
}
namespace OmniDoomFX
{
	[BepInPlugin("Omniscye.OmniDoomFX", "OmniDoomFX", "1.0")]
	public class OmniDoomFX : BaseUnityPlugin
	{
		internal static OmniDoomFX Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//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_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}