Decompiled source of Elias Hadi Modpack v1.0.0

BepInEx/plugins/BGN-PizzaTowerEscapeMusic/PizzaTowerEscapeMusic.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PizzaTowerEscapeMusic.Scripting;
using PizzaTowerEscapeMusic.Scripting.Conditions;
using PizzaTowerEscapeMusic.Scripting.ScriptEvents;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PizzaTowerEscapeMusic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Plays music from Pizza Tower when the early ship leave alert appears")]
[assembly: AssemblyFileVersion("2.4.0.0")]
[assembly: AssemblyInformationalVersion("2.4.0")]
[assembly: AssemblyProduct("PizzaTowerEscapeMusic")]
[assembly: AssemblyTitle("PizzaTowerEscapeMusic")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.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 PizzaTowerEscapeMusic
{
	public class Configuration
	{
		private readonly ConfigFile config;

		internal ConfigEntry<float> volumeMaster;

		internal ConfigEntry<string> scriptingScripts;

		public Configuration(ConfigFile config)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			this.config = config;
			scriptingScripts = config.Bind<string>("Scripting", "Scripts", "Default", new ConfigDescription("The names of the JSON script files that will be loaded (Separated by commas, do not put a space after the commas)", (AcceptableValueBase)null, Array.Empty<object>()));
			volumeMaster = config.Bind<float>("Volume", "Master", 0.5f, new ConfigDescription("The volume of the music as a whole, all volumes are scaled by this value", (AcceptableValueBase)null, Array.Empty<object>()));
			RemoveObsoleteEntries();
		}

		private void RemoveObsoleteEntry(string section, string key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			config.Bind<string>(val, "", (ConfigDescription)null);
			config.Remove(val);
		}

		private void ReplaceObsoleteEntry<T>(string section, string key, ConfigEntry<T> replacement)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ConfigDefinition val = new ConfigDefinition(section, key);
			ConfigEntry<T> val2 = config.Bind<T>(val, (T)((ConfigEntryBase)replacement).DefaultValue, (ConfigDescription)null);
			if (!EqualityComparer<T>.Default.Equals(val2.Value, (T)((ConfigEntryBase)replacement).DefaultValue))
			{
				replacement.Value = val2.Value;
			}
			config.Remove(val);
		}

		private void RemoveObsoleteEntries()
		{
			RemoveObsoleteEntry("Volume", "InsideFacility");
			RemoveObsoleteEntry("Volume", "OutsideFacility");
			RemoveObsoleteEntry("Volume", "InsideShip");
			RemoveObsoleteEntry("Volume", "CrouchingScale");
			RemoveObsoleteEntry("Music", "InsideFacility");
			RemoveObsoleteEntry("Music", "OutsideFacility");
			RemoveObsoleteEntry("Music", "HeavyWeather");
			ReplaceObsoleteEntry<string>("Scripting", "Script", scriptingScripts);
			config.Save();
		}
	}
	internal static class CustomManager
	{
		public static string GetFilePath(string path, string fallbackPath)
		{
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			for (int i = 0; i < directories.Length; i++)
			{
				string text = directories[i] + "/BGN-PizzaTowerEscapeMusic/" + path;
				if (File.Exists(text))
				{
					return text;
				}
			}
			string text2 = Paths.PluginPath + "/BGN-PizzaTowerEscapeMusic_Custom/" + path;
			if (File.Exists(text2))
			{
				return text2;
			}
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/" + fallbackPath;
		}
	}
	public class GameEventListener : MonoBehaviour
	{
		private ManualLogSource logger;

		public Action OnFrameUpdate = delegate
		{
		};

		public Action OnSoundManagerCreated = delegate
		{
		};

		public Action OnSoundManagerDestroyed = delegate
		{
		};

		public Action OnDungeonDoneGenerating = delegate
		{
		};

		public Action OnShipLanded = delegate
		{
		};

		public Action OnShipTakeOff = delegate
		{
		};

		public Action OnShipReturnToOrbit = delegate
		{
		};

		public Action OnShipLeavingAlertCalled = delegate
		{
		};

		public Action OnPlayerDamaged = delegate
		{
		};

		public Action OnPlayerDeath = delegate
		{
		};

		public Action OnPlayerEnteredFacility = delegate
		{
		};

		public Action OnPlayerExitedFacility = delegate
		{
		};

		public Action OnPlayerEnteredShip = delegate
		{
		};

		public Action OnPlayerExitedShip = delegate
		{
		};

		public Action OnApparatusTaken = delegate
		{
		};

		public Action<SelectableLevel?> OnCurrentMoonChanged = delegate
		{
		};

		private readonly Dictionary<string, object?> previousValues = new Dictionary<string, object>();

		private static LungProp? dockedApparatus;

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic GameEventListener");
			OnShipLanded = (Action)Delegate.Combine(OnShipLanded, new Action(FindDockedApparatus));
		}

		private void FindDockedApparatus()
		{
			logger.LogDebug((object)"Checking for docked Apparatus...");
			LungProp[] array = Object.FindObjectsOfType<LungProp>();
			foreach (LungProp val in array)
			{
				if (val.isLungDocked)
				{
					logger.LogDebug((object)"Found docked Apparatus");
					dockedApparatus = val;
					return;
				}
			}
			logger.LogDebug((object)"Could not find docked Apparatus");
		}

		public static bool IsApparatusDocked()
		{
			return (Object)(object)dockedApparatus != (Object)null;
		}

		private void Update()
		{
			if ((Object)(object)SoundManager.Instance != (Object)null)
			{
				OnFrameUpdate();
			}
			CheckSoundManager();
			CheckDungeonDoneGenerating();
			CheckShipLanded();
			CheckShipReturnToOrbit();
			CheckShipLeavingAlertCalled();
			CheckPlayerDamaged();
			CheckPlayerDeath();
			CheckPlayerInsideFacility();
			CheckPlayerInsideShip();
			CheckApparatusTaken();
			CheckCurrentMoonChanged();
		}

		private T? UpdateCached<T>(string key, T? currentValue, T? defaultValue)
		{
			if (!previousValues.TryGetValue(key, out object value))
			{
				value = defaultValue;
			}
			previousValues[key] = currentValue;
			return (T)value;
		}

		private void CheckSoundManager()
		{
			bool flag = (Object)(object)SoundManager.Instance != (Object)null;
			if (UpdateCached("SoundManager", flag, defaultValue: false) != flag)
			{
				if (flag)
				{
					logger.LogDebug((object)"Sound Manager created");
					OnSoundManagerCreated();
				}
				else
				{
					logger.LogDebug((object)"Sound Manager destroyed");
					OnSoundManagerDestroyed();
				}
			}
		}

		private void CheckDungeonDoneGenerating()
		{
			bool flag = (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonCompletedGenerating;
			bool flag2 = UpdateCached("DungeonDoneGenerating", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Dungeon done generating");
				OnDungeonDoneGenerating();
			}
		}

		private void CheckShipLanded()
		{
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded;
			bool flag2 = UpdateCached("ShipLanded", flag, defaultValue: true);
			if (flag != flag2 && !((Object)(object)StartOfRound.Instance == (Object)null))
			{
				if (flag)
				{
					logger.LogDebug((object)"Ship has landed");
					OnShipLanded();
				}
				else
				{
					logger.LogDebug((object)"Ship has taken off");
					OnShipTakeOff();
				}
			}
		}

		private void CheckShipReturnToOrbit()
		{
			bool flag = (Object)(object)StartOfRound.Instance == (Object)null || (!StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving);
			bool flag2 = UpdateCached("ShipReturnToOrbit", flag, defaultValue: true);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship returned to orbit");
				OnShipReturnToOrbit();
			}
		}

		private void CheckShipLeavingAlertCalled()
		{
			bool flag = (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.shipLeavingAlertCalled;
			bool flag2 = UpdateCached("ShipLeavingAlertCalled", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Ship leaving alert called");
				OnShipLeavingAlertCalled();
			}
		}

		private void CheckPlayerDamaged()
		{
			if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				int health = GameNetworkManager.Instance.localPlayerController.health;
				int num = UpdateCached("PlayerDamaged", health, 100);
				if (health < num)
				{
					logger.LogDebug((object)$"Player took damage (Health: {GameNetworkManager.Instance.localPlayerController.health})");
					OnPlayerDamaged();
				}
			}
		}

		private void CheckPlayerDeath()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isPlayerDead;
			bool flag2 = UpdateCached("PlayerDeath", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				logger.LogDebug((object)"Player has died");
				OnPlayerDeath();
			}
		}

		private void CheckPlayerInsideFacility()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInsideFactory;
			bool flag2 = UpdateCached("PlayerInsideFacility", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered facility");
					OnPlayerEnteredFacility();
				}
				else
				{
					logger.LogDebug((object)"Player exited facility");
					OnPlayerExitedFacility();
				}
			}
		}

		private void CheckPlayerInsideShip()
		{
			bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom;
			bool flag2 = UpdateCached("PlayerInsideShip", flag, defaultValue: false);
			if (flag != flag2)
			{
				if (flag)
				{
					logger.LogDebug((object)"Player entered ship");
					OnPlayerEnteredShip();
				}
				else
				{
					logger.LogDebug((object)"Player exited ship");
					OnPlayerExitedShip();
				}
			}
		}

		private void CheckApparatusTaken()
		{
			bool flag = (Object)(object)dockedApparatus != (Object)null && !dockedApparatus.isLungDocked;
			bool flag2 = UpdateCached("ApparatusTaken", flag, defaultValue: false);
			if (flag != flag2 && flag)
			{
				dockedApparatus = null;
				logger.LogDebug((object)"Apparatus was taken");
				OnApparatusTaken();
			}
		}

		private void CheckCurrentMoonChanged()
		{
			SelectableLevel val = TimeOfDay.Instance?.currentLevel;
			SelectableLevel val2 = UpdateCached<SelectableLevel>("CurrentMoon", val, null);
			if (!((Object)(object)val == (Object)(object)val2))
			{
				logger.LogDebug((object)("Level has changed to " + val?.PlanetName));
				OnCurrentMoonChanged(val);
			}
		}
	}
	public class MusicManager : MonoBehaviour
	{
		private class MusicInstance
		{
			public Script script;

			public ScriptEvent_PlayMusic musicEvent;

			public AudioSource audioSource;

			public Script.VolumeGroup volumeGroup;

			private bool isStopping;

			private float volume;

			public float FadeSpeed { get; private set; }

			public MusicInstance(Script script, ScriptEvent_PlayMusic musicEvent, AudioSource audioSource, AudioClip? musicClip)
			{
				this.script = script;
				this.musicEvent = musicEvent;
				this.audioSource = audioSource;
				audioSource.clip = musicClip;
				audioSource.loop = musicEvent.loop;
				audioSource.Play();
				musicInstances.Add(this);
				if (musicEvent.tag != null)
				{
					if (!musicInstancesByTag.TryGetValue(musicEvent.tag, out List<MusicInstance> value))
					{
						value = new List<MusicInstance>(1);
						musicInstancesByTag.Add(musicEvent.tag, value);
					}
					value.Add(this);
				}
				volumeGroup = script.TryGetVolumeGroupOrDefault(musicEvent.tag);
				volume = volumeGroup.GetVolume(script);
			}

			public void Update(float deltaTime)
			{
				float num = (isStopping ? 0f : volumeGroup.GetVolume(script));
				float num2 = (isStopping ? volumeGroup.stoppingVolumeLerpSpeed : volumeGroup.volumeLerpSpeed);
				volume = Mathf.Lerp(volume, num, num2 * deltaTime);
				audioSource.volume = volume * PizzaTowerEscapeMusicManager.Configuration.volumeMaster.Value;
				if (!audioSource.isPlaying || (isStopping && audioSource.volume < 0.005f))
				{
					StopCompletely();
				}
			}

			public void FadeStop()
			{
				if (!isStopping)
				{
					isStopping = true;
					FadeSpeed = volumeGroup.stoppingVolumeLerpSpeed;
				}
			}

			public void StopCompletely()
			{
				audioSource.Stop();
				audioSourcePool.Push(audioSource);
				musicInstances.Remove(this);
				if (musicEvent.tag != null && musicInstancesByTag.TryGetValue(musicEvent.tag, out List<MusicInstance> value))
				{
					value.Remove(this);
				}
			}
		}

		private ManualLogSource logger;

		private static readonly List<MusicInstance> musicInstances = new List<MusicInstance>();

		private static readonly Dictionary<string, List<MusicInstance>> musicInstancesByTag = new Dictionary<string, List<MusicInstance>>();

		private static readonly Stack<AudioSource> audioSourcePool = new Stack<AudioSource>();

		private readonly Dictionary<string, AudioClip> loadedMusic = new Dictionary<string, AudioClip>();

		private void Awake()
		{
			logger = Logger.CreateLogSource("PizzaTowerEscapeMusic MusicManager");
		}

		private void Update()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return;
			}
			for (int num = musicInstances.Count - 1; num >= 0; num--)
			{
				musicInstances[num].Update(Time.deltaTime);
			}
			bool flag = false;
			foreach (MusicInstance musicInstance in musicInstances)
			{
				if (musicInstance.musicEvent.silenceGameMusic)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				if (SoundManager.Instance.playingOutsideMusic && GetIsMusicPlaying())
				{
					SoundManager.Instance.playingOutsideMusic = false;
					logger.LogInfo((object)"Silenced the outside music because alternate music is playing");
				}
				if (TimeOfDay.Instance.TimeOfDayMusic.isPlaying && GetIsMusicPlaying())
				{
					TimeOfDay.Instance.TimeOfDayMusic.Stop();
					logger.LogInfo((object)"Silenced the time of day music because alternate music is playing");
				}
			}
		}

		public bool GetIsMusicPlaying(string? tag = null)
		{
			if (tag == null)
			{
				return musicInstances.Count > 0;
			}
			if (musicInstancesByTag.TryGetValue(tag, out List<MusicInstance> value))
			{
				logger.LogDebug((object)$"GetIsMusicPlaying says there's {value.Count} music instance(s) with the tag \"{tag}\"");
				return value.Count > 0;
			}
			logger.LogDebug((object)("GetIsMusicPlaying says there was no music instance list for tag \"" + tag + "\""));
			return false;
		}

		public void PlayMusic(Script script, ScriptEvent_PlayMusic musicEvent)
		{
			logger.LogDebug((object)("PlayMusic called\nTag:                         " + musicEvent.tag + $"\nOverlap handling:            {musicEvent.overlapHandling}" + $"\nAny music playing?:          {GetIsMusicPlaying()}" + $"\nAny music playing with tag?: {GetIsMusicPlaying(musicEvent.tag)}"));
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreAll && GetIsMusicPlaying())
			{
				logger.LogDebug((object)"PlayMusic canceled because other music was playing");
				return;
			}
			if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreTag && GetIsMusicPlaying(musicEvent.tag))
			{
				logger.LogDebug((object)("PlayMusic canceled because other music with the tag \"" + musicEvent.tag + "\" was playing"));
				return;
			}
			switch (musicEvent.overlapHandling)
			{
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideAll:
				StopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideTag:
				StopMusic(musicEvent.tag);
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeAll:
				FadeStopMusic();
				break;
			case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeTag:
				FadeStopMusic(musicEvent.tag);
				break;
			}
			string text = musicEvent.musicNames[Random.Range(0, musicEvent.musicNames.Length)];
			loadedMusic.TryGetValue(text, out AudioClip value);
			if ((Object)(object)value != (Object)null)
			{
				new MusicInstance(script, musicEvent, GetAudioSource(), value);
				logger.LogInfo((object)("Playing music (" + text + ")"));
			}
			else
			{
				logger.LogWarning((object)("Music (" + text + ") is null, cannot play. Maybe it wasn't loaded correctly?"));
			}
		}

		public void StopMusic(string? targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.StopCompletely();
				}
			}
		}

		public void FadeStopMusic(string? targetTag = null)
		{
			foreach (MusicInstance item in new List<MusicInstance>(musicInstances))
			{
				if (targetTag == null || !(item.musicEvent.tag != targetTag))
				{
					item.FadeStop();
				}
			}
		}

		private AudioSource GetAudioSource()
		{
			if (!audioSourcePool.TryPop(out AudioSource result))
			{
				return ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			return result;
		}

		public async void LoadNecessaryMusicClips()
		{
			if (PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts.Count == 0)
			{
				logger.LogError((object)"No scripts are loaded, cannot load their music!");
				return;
			}
			UnloadMusicClips();
			foreach (Script loadedScript in PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts)
			{
				ScriptEvent[] scriptEvents = loadedScript.scriptEvents;
				for (int i = 0; i < scriptEvents.Length; i++)
				{
					if (!(scriptEvents[i] is ScriptEvent_PlayMusic scriptEvent_PlayMusic))
					{
						continue;
					}
					string[] musicNames = scriptEvent_PlayMusic.musicNames;
					foreach (string musicName in musicNames)
					{
						if (!loadedMusic.ContainsKey(musicName))
						{
							AudioClip val = await LoadMusicClip(musicName);
							if (!((Object)(object)val == (Object)null))
							{
								loadedMusic.Add(musicName, val);
							}
						}
					}
				}
			}
			logger.LogInfo((object)"Music clips done loading");
		}

		public void UnloadMusicClips()
		{
			foreach (AudioClip value in loadedMusic.Values)
			{
				value.UnloadAudioData();
			}
			loadedMusic.Clear();
			logger.LogInfo((object)"All music clips unloaded");
		}

		private async Task<AudioClip?> LoadMusicClip(string musicFileName)
		{
			InterpretMusicFileName(musicFileName, out AudioType audioType, out string finalFileName);
			string path = "file:///" + CustomManager.GetFilePath("Music/" + finalFileName, "DefaultMusic/" + finalFileName);
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
			try
			{
				request.SendWebRequest();
				while (!request.isDone)
				{
					await Task.Delay(50);
				}
				if ((int)request.result == 1)
				{
					logger.LogInfo((object)("Loaded music (" + musicFileName + ") from file"));
					AudioClip content = DownloadHandlerAudioClip.GetContent(request);
					((Object)content).name = musicFileName;
					return content;
				}
				logger.LogError((object)($"Failed to load music ({musicFileName}) from file as audio type {audioType}, if the file extension and the audio type do not match the file extension may not be supported." + "\n- Path: " + path + "\n- Error: " + request.error));
				return null;
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		private void InterpretMusicFileName(string musicFileName, out AudioType audioType, out string finalFileName)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected I4, but got Unknown
			//IL_0053: 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)
			if (!musicFileName.Contains('.'))
			{
				audioType = (AudioType)20;
				finalFileName = musicFileName + ".wav";
				return;
			}
			string text = musicFileName.Split('.').Last().ToLower();
			AudioType val = ((text == "ogg") ? ((AudioType)14) : ((!(text == "mp3")) ? ((AudioType)20) : ((AudioType)13)));
			audioType = (AudioType)(int)val;
			finalFileName = musicFileName;
		}
	}
	public class PizzaTowerEscapeMusicManager : MonoBehaviour
	{
		private GameEventListener gameEventListener;

		private ManualLogSource logger;

		public static Configuration Configuration { get; private set; }

		public static ScriptManager ScriptManager { get; private set; }

		public static MusicManager MusicManager { get; private set; }

		public void Initialise(ManualLogSource logger, ConfigFile config)
		{
			this.logger = logger;
			Configuration = new Configuration(config);
			MusicManager = ((Component)this).gameObject.AddComponent<MusicManager>();
			gameEventListener = ((Component)this).gameObject.AddComponent<GameEventListener>();
			GameEventListener obj = gameEventListener;
			obj.OnSoundManagerCreated = (Action)Delegate.Combine(obj.OnSoundManagerCreated, new Action(MusicManager.LoadNecessaryMusicClips));
			GameEventListener obj2 = gameEventListener;
			obj2.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj2.OnSoundManagerDestroyed, (Action)delegate
			{
				MusicManager.StopMusic();
			});
			GameEventListener obj3 = gameEventListener;
			obj3.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj3.OnSoundManagerDestroyed, new Action(MusicManager.UnloadMusicClips));
			ScriptManager = new ScriptManager(Configuration.scriptingScripts.Value.Split(','), gameEventListener);
			GameEventListener obj4 = gameEventListener;
			obj4.OnSoundManagerDestroyed = (Action)Delegate.Combine(obj4.OnSoundManagerDestroyed, new Action(ScriptManager.ClearAllScriptTimers));
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			logger.LogInfo((object)"Plugin bgn.pizzatowerescapemusic is loaded!");
		}

		private void Update()
		{
			ScriptManager.UpdateAllScriptTimers(Time.deltaTime);
		}
	}
	[BepInPlugin("bgn.pizzatowerescapemusic", "PizzaTowerEscapeMusic", "2.4.0")]
	[BepInProcess("Lethal Company.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "bgn.pizzatowerescapemusic";

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PizzaTowerEscapeMusic Manager");
			val.AddComponent<PizzaTowerEscapeMusicManager>().Initialise(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
			((Object)val).hideFlags = (HideFlags)61;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PizzaTowerEscapeMusic";

		public const string PLUGIN_NAME = "PizzaTowerEscapeMusic";

		public const string PLUGIN_VERSION = "2.4.0";
	}
}
namespace PizzaTowerEscapeMusic.Scripting
{
	public class Script
	{
		public class VolumeRule
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volume;

			public Condition? condition;
		}

		public class VolumeModifier
		{
			public string comment = string.Empty;

			[JsonRequired]
			public float volumeScale;

			public Condition? condition;
		}

		public class VolumeGroup
		{
			public string comment = string.Empty;

			public string tag = string.Empty;

			public float volumeLerpSpeed = 1f;

			public float stoppingVolumeLerpSpeed = 1f;

			public float masterVolume = 1f;

			public VolumeRule[] volumeRules = Array.Empty<VolumeRule>();

			public VolumeModifier[] volumeModifiers = Array.Empty<VolumeModifier>();

			public float GetVolume(Script script)
			{
				float num = 1f;
				VolumeRule[] array = volumeRules;
				foreach (VolumeRule volumeRule in array)
				{
					if (volumeRule.condition == null || volumeRule.condition.Check(script))
					{
						num = volumeRule.volume;
						break;
					}
				}
				VolumeModifier[] array2 = volumeModifiers;
				foreach (VolumeModifier volumeModifier in array2)
				{
					if (volumeModifier.condition == null || volumeModifier.condition.Check(script))
					{
						num *= volumeModifier.volumeScale;
					}
				}
				return num * masterVolume;
			}
		}

		public class Timer
		{
			public string name;

			public float time;

			public Timer(string name)
			{
				this.name = name;
			}
		}

		public string comment = string.Empty;

		public bool isAddon;

		public VolumeGroup[] volumeGroups = Array.Empty<VolumeGroup>();

		[JsonRequired]
		public ScriptEvent[] scriptEvents = Array.Empty<ScriptEvent>();

		[JsonIgnore]
		public readonly Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>> loadedScriptEvents = new Dictionary<ScriptEvent.GameEventType, List<ScriptEvent>>();

		[JsonIgnore]
		public readonly Dictionary<string, VolumeGroup> loadedScriptVolumeGroups = new Dictionary<string, VolumeGroup>();

		[JsonIgnore]
		public readonly Dictionary<string, Timer> activeTimers = new Dictionary<string, Timer>();

		[JsonIgnore]
		public static VolumeGroup DefaultVolumeGroup { get; private set; } = new VolumeGroup();


		public void Initialise(ManualLogSource logger)
		{
			ScriptEvent[] array = scriptEvents;
			foreach (ScriptEvent scriptEvent in array)
			{
				if (!loadedScriptEvents.TryGetValue(scriptEvent.gameEventType, out List<ScriptEvent> value))
				{
					value = new List<ScriptEvent>(1);
					loadedScriptEvents.Add(scriptEvent.gameEventType, value);
				}
				value.Add(scriptEvent);
			}
			VolumeGroup[] array2 = volumeGroups;
			foreach (VolumeGroup volumeGroup in array2)
			{
				if (!loadedScriptVolumeGroups.TryAdd(volumeGroup.tag, volumeGroup))
				{
					logger.LogError((object)("Volume group tag \"" + volumeGroup.tag + "\" was already declared, you cannot have two volume groups with the same tag"));
				}
			}
		}

		public VolumeGroup TryGetVolumeGroupOrDefault(string? tag)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				return DefaultVolumeGroup;
			}
			return loadedScriptVolumeGroups[tag];
		}

		public bool TryGetVolumeGroup(string? tag, [NotNullWhen(true)] out VolumeGroup? volumeGroup)
		{
			if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag))
			{
				volumeGroup = null;
				return false;
			}
			volumeGroup = loadedScriptVolumeGroups[tag];
			return true;
		}

		public void UpdateTimers(float deltaTime)
		{
			foreach (Timer value in activeTimers.Values)
			{
				value.time += deltaTime;
			}
		}

		public void ClearTimers()
		{
			activeTimers.Clear();
		}

		internal void ClearTimer(string timerName)
		{
			activeTimers.Remove(timerName);
		}
	}
	public class ScriptManager
	{
		public readonly List<Script> loadedScripts = new List<Script>();

		public ManualLogSource Logger { get; private set; }

		public ScriptManager(string[] scriptNames, GameEventListener gameEventListener)
		{
			Logger = Logger.CreateLogSource("PizzaTowerEscapeMusic ScriptManager");
			Script script = new Script();
			loadedScripts.Add(script);
			foreach (string text in scriptNames)
			{
				Script script2 = DeserializeScript(text);
				if (script2 != null)
				{
					script2.Initialise(Logger);
					if (script2.isAddon)
					{
						List<Script.VolumeGroup> list = script.volumeGroups.ToList();
						list.AddRange(script2.volumeGroups);
						script.volumeGroups = list.ToArray();
						List<ScriptEvent> list2 = script.scriptEvents.ToList();
						list2.AddRange(script2.scriptEvents);
						script.scriptEvents = list2.ToArray();
					}
					else
					{
						loadedScripts.Add(script2);
					}
					if (script2.isAddon)
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded as addon"));
					}
					else
					{
						Logger.LogInfo((object)("Script (" + text + ") loaded"));
					}
				}
			}
			script.Initialise(Logger);
			gameEventListener.OnFrameUpdate = (Action)Delegate.Combine(gameEventListener.OnFrameUpdate, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.FrameUpdated);
			});
			gameEventListener.OnShipLanded = (Action)Delegate.Combine(gameEventListener.OnShipLanded, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLanded);
			});
			gameEventListener.OnShipTakeOff = (Action)Delegate.Combine(gameEventListener.OnShipTakeOff, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipTakeOff);
			});
			gameEventListener.OnShipLeavingAlertCalled = (Action)Delegate.Combine(gameEventListener.OnShipLeavingAlertCalled, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ShipLeavingAlertCalled);
			});
			gameEventListener.OnPlayerDamaged = (Action)Delegate.Combine(gameEventListener.OnPlayerDamaged, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDamaged);
			});
			gameEventListener.OnPlayerDeath = (Action)Delegate.Combine(gameEventListener.OnPlayerDeath, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerDied);
			});
			gameEventListener.OnPlayerEnteredFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredFacility);
			});
			gameEventListener.OnPlayerExitedFacility = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedFacility, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedFacility);
			});
			gameEventListener.OnPlayerEnteredShip = (Action)Delegate.Combine(gameEventListener.OnPlayerEnteredShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerEnteredShip);
			});
			gameEventListener.OnPlayerExitedShip = (Action)Delegate.Combine(gameEventListener.OnPlayerExitedShip, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.PlayerExitedShip);
			});
			gameEventListener.OnApparatusTaken = (Action)Delegate.Combine(gameEventListener.OnApparatusTaken, (Action)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.ApparatusTaken);
			});
			gameEventListener.OnCurrentMoonChanged = (Action<SelectableLevel>)Delegate.Combine(gameEventListener.OnCurrentMoonChanged, (Action<SelectableLevel>)delegate
			{
				CheckScriptEvents(ScriptEvent.GameEventType.CurrentMoonChanged);
			});
			Logger.LogInfo((object)"Done loading scripts");
		}

		private void CheckScriptEvents(ScriptEvent.GameEventType eventType)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				if (!loadedScript.loadedScriptEvents.TryGetValue(eventType, out List<ScriptEvent> value))
				{
					continue;
				}
				foreach (ScriptEvent item in value)
				{
					if (item.CheckConditions(loadedScript))
					{
						Logger.LogDebug((object)("Conditions for a script event have been met!\n Script Event Type: " + item.scriptEventType + $"\n   Game Event Type: {item.gameEventType}" + "\n           Comment: " + item.comment));
						item.Run(loadedScript);
					}
				}
			}
		}

		private Script? DeserializeScript(string name)
		{
			string filePath = CustomManager.GetFilePath("Scripts/" + name + ".json", "DefaultScripts/" + name + ".json");
			if (!File.Exists(filePath))
			{
				Logger.LogError((object)("Script \"" + name + "\" does not exist! Make sure you spelt it right the config, and make sure its file extension is \".json\""));
				return null;
			}
			string text = File.ReadAllText(filePath);
			try
			{
				return JsonConvert.DeserializeObject<Script>(text);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Failed to deserialize script \"" + name + "\":\n" + ex.Message));
				return null;
			}
		}

		public void UpdateAllScriptTimers(float deltaTime)
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.UpdateTimers(deltaTime);
			}
		}

		public void ClearAllScriptTimers()
		{
			foreach (Script loadedScript in loadedScripts)
			{
				loadedScript.ClearTimers();
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.ScriptEvents
{
	public class ScriptEventConverter : JsonConverter<ScriptEvent>
	{
		public override bool CanWrite => false;

		public override ScriptEvent ReadJson(JsonReader reader, Type objectType, ScriptEvent? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			JToken val2 = default(JToken);
			if (!val.TryGetValue("scriptEventType", ref val2))
			{
				throw new Exception("scriptEventType type is null!");
			}
			ScriptEvent scriptEvent = Extensions.Value<string>((IEnumerable<JToken>)val2) switch
			{
				"PlayMusic" => new ScriptEvent_PlayMusic(), 
				"StopMusic" => new ScriptEvent_StopMusic(), 
				"ResetTimers" => new ScriptEvent_ResetTimers(), 
				"SetVolumeGroupMasterVolume" => new ScriptEvent_SetVolumeGroupMasterVolume(), 
				_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
			};
			serializer.Populate(((JToken)val).CreateReader(), (object)scriptEvent);
			return scriptEvent;
		}

		public override void WriteJson(JsonWriter writer, ScriptEvent? value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	[JsonConverter(typeof(ScriptEventConverter))]
	public abstract class ScriptEvent
	{
		public enum GameEventType
		{
			FrameUpdated,
			ShipLanded,
			ShipTakeOff,
			ShipLeavingAlertCalled,
			PlayerDamaged,
			PlayerDied,
			PlayerEnteredFacility,
			PlayerExitedFacility,
			PlayerEnteredShip,
			PlayerExitedShip,
			ApparatusTaken,
			CurrentMoonChanged
		}

		public string comment = string.Empty;

		[JsonRequired]
		public string scriptEventType = string.Empty;

		[JsonRequired]
		public GameEventType gameEventType;

		public Condition[] conditions = Array.Empty<Condition>();

		public bool CheckConditions(Script script)
		{
			Script script2 = script;
			return !conditions.Any((Condition c) => !c.Check(script2));
		}

		public abstract void Run(Script script);
	}
	public class ScriptEvent_PlayMusic : ScriptEvent
	{
		public enum OverlapHandling
		{
			IgnoreAll,
			IgnoreTag,
			OverrideAll,
			OverrideTag,
			OverrideFadeAll,
			OverrideFadeTag,
			Overlap
		}

		public bool loop;

		public bool silenceGameMusic = true;

		[JsonRequired]
		public OverlapHandling overlapHandling;

		public string? tag;

		[JsonRequired]
		public string[] musicNames = Array.Empty<string>();

		public override void Run(Script script)
		{
			if (musicNames.Length != 0)
			{
				PizzaTowerEscapeMusicManager.MusicManager.PlayMusic(script, this);
			}
		}
	}
	public class ScriptEvent_StopMusic : ScriptEvent
	{
		public string[]? targetTags;

		public bool instant;

		public override void Run(Script script)
		{
			if (targetTags != null)
			{
				string[] array = targetTags;
				foreach (string targetTag in array)
				{
					if (instant)
					{
						PizzaTowerEscapeMusicManager.MusicManager.StopMusic(targetTag);
					}
					else
					{
						PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic(targetTag);
					}
				}
			}
			else if (instant)
			{
				PizzaTowerEscapeMusicManager.MusicManager.StopMusic();
			}
			else
			{
				PizzaTowerEscapeMusicManager.MusicManager.FadeStopMusic();
			}
		}
	}
	public class ScriptEvent_ResetTimers : ScriptEvent
	{
		public string[]? targetTimerNames;

		public override void Run(Script script)
		{
			if (targetTimerNames == null)
			{
				script.ClearTimers();
				return;
			}
			string[] array = targetTimerNames;
			foreach (string timerName in array)
			{
				script.ClearTimer(timerName);
			}
		}
	}
	public class ScriptEvent_SetVolumeGroupMasterVolume : ScriptEvent
	{
		public string[] targetTags = Array.Empty<string>();

		[JsonRequired]
		public float masterVolume;

		public override void Run(Script script)
		{
			if (targetTags.Length == 0)
			{
				Script.DefaultVolumeGroup.masterVolume = masterVolume;
				return;
			}
			string[] array = targetTags;
			foreach (string text in array)
			{
				if (!script.loadedScriptVolumeGroups.TryGetValue(text, out Script.VolumeGroup value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("Script Event SetVolumeGroupMasterVolume was called for volume group with tag \"" + text + "\", but there is no volume group of that tag"));
				}
				else
				{
					value.masterVolume = masterVolume;
				}
			}
		}
	}
}
namespace PizzaTowerEscapeMusic.Scripting.Conditions
{
	public class ConditionConverter : JsonConverter<Condition>
	{
		public override bool CanWrite => false;

		public override Condition ReadJson(JsonReader reader, Type objectType, Condition? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			JToken val2 = default(JToken);
			if (!val.TryGetValue("conditionType", ref val2))
			{
				throw new Exception("Condition type is null!");
			}
			Condition condition = Extensions.Value<string>((IEnumerable<JToken>)val2) switch
			{
				"And" => new Condition_And(), 
				"Or" => new Condition_Or(), 
				"Not" => new Condition_Not(), 
				"Weather" => new Condition_Weather(), 
				"PlayerLocation" => new Condition_PlayerLocation(), 
				"PlayerAlive" => new Condition_PlayerAlive(), 
				"PlayerHealth" => new Condition_PlayerHealth(), 
				"PlayerCrouching" => new Condition_PlayerCrouching(), 
				"PlayerInsanity" => new Condition_PlayerInsanity(), 
				"ShipLanded" => new Condition_ShipLanded(), 
				"ShipLeavingAlertCalled" => new Condition_ShipLeavingAlertCalled(), 
				"MusicWithTagPlaying" => new Condition_MusicWithTagPlaying(), 
				"CurrentMoon" => new Condition_CurrentMoon(), 
				"Timer" => new Condition_Timer(), 
				"Random" => new Condition_Random(), 
				"ApparatusDocked" => new Condition_ApparatusDocked(), 
				"TimeOfDay" => new Condition_TimeOfDay(), 
				_ => throw new Exception($"Condition type \"{val2}\" does not exist"), 
			};
			serializer.Populate(((JToken)val).CreateReader(), (object)condition);
			return condition;
		}

		public override void WriteJson(JsonWriter writer, Condition? value, JsonSerializer serializer)
		{
			throw new NotImplementedException();
		}
	}
	[JsonConverter(typeof(ConditionConverter))]
	public abstract class Condition
	{
		[JsonRequired]
		public string conditionType = string.Empty;

		public abstract bool Check(Script script);
	}
	public abstract class ConditionComparableNumber : Condition
	{
		public enum ComparisonType
		{
			Equals,
			NotEquals,
			GreaterThan,
			LessThan,
			GreaterThanOrEquals,
			LessThanOrEquals
		}

		[JsonRequired]
		public ComparisonType comparisonType;
	}
	public class Condition_And : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			Script script2 = script;
			return !conditions.Any((Condition c) => !c.Check(script2));
		}
	}
	public class Condition_Or : Condition
	{
		[JsonRequired]
		public Condition[] conditions = Array.Empty<Condition>();

		public override bool Check(Script script)
		{
			Script script2 = script;
			return conditions.Any((Condition c) => c.Check(script2));
		}
	}
	public class Condition_Not : Condition
	{
		[JsonRequired]
		public Condition? condition;

		public override bool Check(Script script)
		{
			if (condition == null)
			{
				return true;
			}
			return !condition.Check(script);
		}
	}
	public class Condition_Weather : Condition
	{
		[JsonRequired]
		public LevelWeatherType weather;

		public override bool Check(Script script)
		{
			//IL_0014: 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)
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			return TimeOfDay.Instance.currentLevelWeather == weather;
		}
	}
	public class Condition_PlayerLocation : Condition
	{
		public enum Location
		{
			Ship,
			Facility
		}

		[JsonRequired]
		public Location location;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return location switch
			{
				Location.Ship => GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom, 
				Location.Facility => GameNetworkManager.Instance.localPlayerController.isInsideFactory, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerAlive : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return !GameNetworkManager.Instance.localPlayerController.isPlayerDead;
		}
	}
	public class Condition_PlayerHealth : ConditionComparableNumber
	{
		[JsonRequired]
		public int value;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			int health = GameNetworkManager.Instance.localPlayerController.health;
			return comparisonType switch
			{
				ComparisonType.Equals => health == value, 
				ComparisonType.NotEquals => health != value, 
				ComparisonType.GreaterThan => health > value, 
				ComparisonType.LessThan => health < value, 
				ComparisonType.GreaterThanOrEquals => health >= value, 
				ComparisonType.LessThanOrEquals => health <= value, 
				_ => false, 
			};
		}
	}
	public class Condition_PlayerCrouching : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			return GameNetworkManager.Instance.localPlayerController.isCrouching;
		}
	}
	public class Condition_PlayerInsanity : ConditionComparableNumber
	{
		[JsonRequired]
		public float level;

		public override bool Check(Script script)
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			float num = GameNetworkManager.Instance.localPlayerController.insanityLevel / GameNetworkManager.Instance.localPlayerController.maxInsanityLevel;
			return comparisonType switch
			{
				ComparisonType.Equals => level == num, 
				ComparisonType.NotEquals => level != num, 
				ComparisonType.GreaterThan => level > num, 
				ComparisonType.LessThan => level < num, 
				ComparisonType.GreaterThanOrEquals => level >= num, 
				ComparisonType.LessThanOrEquals => level <= num, 
				_ => false, 
			};
		}
	}
	public class Condition_ShipLanded : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			return StartOfRound.Instance.shipHasLanded;
		}
	}
	public class Condition_ShipLeavingAlertCalled : Condition
	{
		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			return TimeOfDay.Instance.shipLeavingAlertCalled;
		}
	}
	public class Condition_MusicWithTagPlaying : Condition
	{
		[JsonRequired]
		public string tag = string.Empty;

		public override bool Check(Script script)
		{
			return PizzaTowerEscapeMusicManager.MusicManager.GetIsMusicPlaying(tag);
		}
	}
	public class Condition_CurrentMoon : Condition
	{
		private static readonly Dictionary<string, int> moonNameToId = new Dictionary<string, int>();

		[JsonRequired]
		public string moonName = string.Empty;

		private bool isDisabled;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			if (isDisabled)
			{
				return false;
			}
			if (!moonNameToId.TryGetValue(moonName, out var value))
			{
				SelectableLevel[] levels = StartOfRound.Instance.levels;
				foreach (SelectableLevel val in levels)
				{
					moonNameToId.TryAdd(val.PlanetName, val.levelID);
				}
				if (!moonNameToId.TryGetValue(moonName, out value))
				{
					PizzaTowerEscapeMusicManager.ScriptManager.Logger.LogError((object)("From CurrentMoon condition: Found no existing level with the name \"" + moonName + "\""));
					isDisabled = true;
					return false;
				}
			}
			return TimeOfDay.Instance.currentLevel.levelID == value;
		}
	}
	public class Condition_Timer : Condition
	{
		[JsonRequired]
		public string timerName = string.Empty;

		[JsonRequired]
		public float timeGoal;

		public bool resetsTimer = true;

		public override bool Check(Script script)
		{
			if (!script.activeTimers.TryGetValue(timerName, out Script.Timer value))
			{
				value = new Script.Timer(timerName);
				script.activeTimers.Add(timerName, value);
			}
			if (value.time >= timeGoal)
			{
				if (resetsTimer)
				{
					value.time = 0f;
				}
				return true;
			}
			return false;
		}
	}
	public class Condition_Random : Condition
	{
		[JsonRequired]
		public float chance;

		public override bool Check(Script script)
		{
			return Random.Range(0f, 1f) <= chance;
		}
	}
	public class Condition_ApparatusDocked : Condition
	{
		public override bool Check(Script script)
		{
			return GameEventListener.IsApparatusDocked();
		}
	}
	public class Condition_TimeOfDay : ConditionComparableNumber
	{
		[JsonRequired]
		public float time;

		public override bool Check(Script script)
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return false;
			}
			float num = TimeOfDay.Instance.currentDayTime / TimeOfDay.Instance.totalTime;
			return comparisonType switch
			{
				ComparisonType.Equals => num == time, 
				ComparisonType.NotEquals => num != time, 
				ComparisonType.GreaterThan => num > time, 
				ComparisonType.LessThan => num < time, 
				ComparisonType.GreaterThanOrEquals => num >= time, 
				ComparisonType.LessThanOrEquals => num <= time, 
				_ => false, 
			};
		}
	}
}

BepInEx/plugins/loaforc-FacilityMeltdownExperimental/FacilityMeltdown/FacilityMeltdown.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
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 Biodiversity.Util.Assetloading;
using FacilityMeltdown.API;
using FacilityMeltdown.Behaviours;
using FacilityMeltdown.Config;
using FacilityMeltdown.Equipment;
using FacilityMeltdown.Integrations;
using FacilityMeltdown.Lang;
using FacilityMeltdown.MeltdownSequence.Behaviours;
using FacilityMeltdown.NetcodePatcher;
using FacilityMeltdown.Patches;
using FacilityMeltdown.Util;
using FacilityMeltdown.Util.Attributes;
using FacilityMeltdown.Util.Config;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLib.Modules;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("WeatherRegistry")]
[assembly: AssemblyCompany("FacilityMeltdown")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+74a2b8f0ecd190d1420e40c840c77a124518a3f9")]
[assembly: AssemblyProduct("FacilityMeltdown")]
[assembly: AssemblyTitle("FacilityMeltdown")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 Biodiversity.Util.Assetloading
{
	[AttributeUsage(AttributeTargets.Property)]
	internal class LoadFromBundleAttribute : Attribute
	{
		public string BundleFile { get; private set; }

		public LoadFromBundleAttribute(string bundleFile)
		{
			BundleFile = bundleFile;
			base..ctor();
		}
	}
}
namespace FacilityMeltdown
{
	[BepInPlugin("me.loaforc.facilitymeltdown", "FacilityMeltdown", "2.6.15")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MeltdownPlugin : BaseUnityPlugin
	{
		internal const string modGUID = "me.loaforc.facilitymeltdown";

		internal const string modName = "FacilityMeltdown";

		internal const string modVersion = "2.6.15";

		internal static MeltdownPlugin instance;

		internal static ManualLogSource logger;

		internal static Harmony harmony = new Harmony("me.loaforc.facilitymeltdown");

		internal static MeltdownAssets assets { get; private set; }

		public static bool loadedFully { get; private set; } = false;


		internal static MeltdownConfig config { get; set; }

		internal static MeltdownClientConfig clientConfig { get; private set; }

		private void Awake()
		{
			if (!((Object)(object)instance == (Object)null))
			{
				return;
			}
			instance = this;
			logger = Logger.CreateLogSource("me.loaforc.facilitymeltdown");
			if (RunLoadStep("Assets.Init", "Getting assets", delegate
			{
				assets = new MeltdownAssets();
			}) && RunLoadStep("LangParser.Init", "Getting possible languages", LangParser.Init) && RunLoadStep("new MeltdownConfig()", "Setting up config", delegate
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				config = new MeltdownConfig(((BaseUnityPlugin)this).Config);
				clientConfig = new MeltdownClientConfig(new ConfigFile(Utility.CombinePaths(new string[2]
				{
					Paths.ConfigPath,
					"me.loaforc.facilitymeltdown.Client.cfg"
				}), false, MetadataHelper.GetMetadata((object)this)));
				logger.LogDebug((object)$"Test Config Value: {config.ApparatusValue}");
				((BaseUnityPlugin)this).Config.ClearOrphans();
				clientConfig.configFile.ClearOrphans();
			}) && RunLoadStep("LangParser.SetLanguage", "Setting language", delegate
			{
				LangParser.SetLanguage(clientConfig.Language);
			}) && RunLoadStep("RegisterPatches", "Integrating into LethalCompany", RegisterPatches) && RunLoadStep("RegisterNetworking", "Making sure everything is networked", RegisterNetworking))
			{
				if (!RunLoadStep("RegisterItems", "Adding the Geiger Counter", RegisterItems))
				{
					logger.LogWarning((object)"Failed to register the geiger counter.");
				}
				if (!RunLoadStep("CompatibleDependency.Init", "Checking for any soft dependencies", delegate
				{
					CompatibleDependencyAttribute.Init((BaseUnityPlugin)(object)this);
				}))
				{
					logger.LogWarning((object)"Doing something with soft dependencies broke, meltdown itself should be fine.");
				}
				loadedFully = true;
				logger.LogInfo((object)"FacilityMeltdown:2.6.15 by loaforc has loaded! have fun :3");
				logger.LogInfo((object)"         .-_; ;_-.          ");
				logger.LogInfo((object)"        / /     \\ \\        ");
				logger.LogInfo((object)"       | |       | |      ");
				logger.LogInfo((object)"        \\ \\.---./ /       ");
				logger.LogInfo((object)"  .-\\\"\"~   .---.   ~\"\"-.");
				logger.LogInfo((object)" ,`.-~// .'`---`'. \\\\~-.`,");
				logger.LogInfo((object)" ' `   | | \\(_)/ | |   `' ");
				logger.LogInfo((object)"  ,    \\  \\ | | /  /    , ");
				logger.LogInfo((object)"  ;`'.,_\\  `-'-'  /_,.'`; ");
				logger.LogInfo((object)"   '-._  _.-'^'-._  _.-'    ");
			}
		}

		private bool RunLoadStep(string stepName, string descrption, Action callback)
		{
			try
			{
				callback();
			}
			catch (Exception ex)
			{
				logger.LogError((object)("`" + stepName + "` caused an exception to be thrown, meltdown may or may not work, look for more errors."));
				logger.LogError((object)ex);
				return false;
			}
			logger.LogInfo((object)(stepName.PadRight(25) + " == " + descrption));
			return true;
		}

		private void RegisterItems()
		{
			logger.LogInfo((object)"Registering Items");
			Items.RegisterShopItem(assets.geigerCounterItemDef, (TerminalNode)null, (TerminalNode)null, assets.geigerCounterNode, 90);
		}

		private void OnDisable()
		{
			if (!loadedFully)
			{
				Harmony.UnpatchID("me.loaforc.facilitymeltdown");
				logger.LogInfo((object)"Unpatching as something failed while loading.");
			}
			else if (Chainloader.PluginInfos.ContainsKey("den.meltdownchance") || Chainloader.PluginInfos.ContainsKey("PizzaProbability"))
			{
				logger.LogInfo((object)"You are using a mod that makes meltdown have a random chance of occuring.");
				logger.LogInfo((object)"Keep in mind this goes against meltdown's core design, but your choice.");
				logger.LogWarning((object)"However; BY DESIGN these mods need to mess with the internals of meltdown");
				logger.LogWarning((object)"so I personally will be offering low to no support with these mods installed.");
			}
		}

		private void RegisterNetworking()
		{
			Type[] array = new Type[2]
			{
				typeof(MeltdownHandler),
				typeof(GeigerCounterItem)
			};
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				try
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array3 = methods;
					foreach (MethodInfo methodInfo in array3)
					{
						object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
						if (customAttributes.Length != 0)
						{
							methodInfo.Invoke(null, null);
						}
					}
				}
				catch (Exception)
				{
					logger.LogWarning((object)"supressed an error from netcode patcher, probably fine but should still log that something happened.");
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private void RegisterPatches()
		{
			foreach (Type item in from t in Assembly.GetExecutingAssembly().GetLoadableTypes()
				where t.IsClass && t.Namespace == "FacilityMeltdown.Patches"
				select t)
			{
				logger.LogDebug((object)("Registering Patch handler: " + item.Name));
				harmony.PatchAll(item);
			}
		}
	}
	internal static class ExtensionMethods
	{
		private static Random rng = new Random();

		public static void Shuffle<T>(this IList<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int index = rng.Next(num + 1);
				T value = list[index];
				list[index] = list[num];
				list[num] = value;
			}
		}

		public static float Remap(this float value, float from1, float to1, float from2, float to2)
		{
			return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
		}

		public static List<PlayerControllerB> GetConnectedPlayers(this StartOfRound startOfRound)
		{
			return startOfRound.allPlayerScripts.Where((PlayerControllerB player) => player.isPlayerControlled).ToList();
		}

		public static void SpawnEnemy(this EnemyVent vent, SpawnableEnemyWithRarity enemy)
		{
			//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_0012: 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_0034: 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)
			Vector3 position = vent.floorNode.position;
			float y = vent.floorNode.eulerAngles.y;
			GameObject val = Object.Instantiate<GameObject>(enemy.enemyType.enemyPrefab, position, Quaternion.Euler(new Vector3(0f, y, 0f)));
			EnemyAI component = val.GetComponent<EnemyAI>();
			((NetworkBehaviour)component).NetworkObject.Spawn(true);
			RoundManager.Instance.SpawnedEnemies.Add(component);
			vent.OpenVentClientRpc();
			vent.occupied = false;
		}

		internal static string Translate(this string text)
		{
			return LangParser.GetTranslation(text);
		}

		internal static void ClearOrphans(this ConfigFile config)
		{
			PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null);
			dictionary.Clear();
			config.Save();
		}

		internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("assembly");
			}
			try
			{
				return assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				return ex.Types.Where((Type t) => t != null);
			}
		}

		internal static (int hours, int minutes) GetCurrentTime(this TimeOfDay timeOfDay)
		{
			int num = Mathf.FloorToInt(timeOfDay.normalizedTimeOfDay * 60f * (float)timeOfDay.numberOfHours + 360f);
			int item = Mathf.FloorToInt((float)(num / 60));
			return (item, num % 60);
		}
	}
	internal class MeltdownAssets : AssetBundleLoader<MeltdownAssets>
	{
		[LoadFromBundle("meltdownmusic.mp3")]
		public AudioClip defaultMusic { get; private set; }

		[LoadFromBundle("shockwave.mp3")]
		public AudioClip shockwave { get; private set; }

		[LoadFromBundle("FacilityExplosion.prefab")]
		public GameObject facilityExplosionPrefab { get; private set; }

		[LoadFromBundle("MeltdownHandler.prefab")]
		public GameObject meltdownHandlerPrefab { get; private set; }

		[LoadFromBundle("Shockwave.prefab")]
		public GameObject shockwavePrefab { get; private set; }

		[LoadFromBundle("GeigerCounterItemDef.asset")]
		public Item geigerCounterItemDef { get; private set; }

		[LoadFromBundle("GeigerCounterNode.asset")]
		public TerminalNode geigerCounterNode { get; private set; }

		[LoadFromBundle("HealthKeyword.asset")]
		public TerminalKeyword healthKeyword { get; private set; }

		[LoadFromBundle("ReactorKeyword.asset")]
		public TerminalKeyword reactorKeyword { get; private set; }

		[LoadFromBundle("ReactorHealthReport.asset")]
		public TerminalNode reactorHealthNode { get; private set; }

		public GameObject[] facilityEffects { get; private set; }

		public AudioClip[] warnings { get; private set; }

		public MeltdownAssets()
			: base("facilitymeltdown")
		{
		}

		protected override void FinishLoadingAssets(AssetBundle bundle)
		{
			warnings = (AudioClip[])(object)new AudioClip[4]
			{
				LoadAsset<AudioClip>(bundle, "warning1.mp3"),
				LoadAsset<AudioClip>(bundle, "warning2.mp3"),
				LoadAsset<AudioClip>(bundle, "warning3.mp3"),
				LoadAsset<AudioClip>(bundle, "warning4.mp3")
			};
			facilityEffects = (GameObject[])(object)new GameObject[2]
			{
				LoadAsset<GameObject>(bundle, "Dust.prefab"),
				LoadAsset<GameObject>(bundle, "Waterstream.prefab")
			};
			TerminalPatch.terminalKeywordsToRegister.Add(healthKeyword);
			TerminalPatch.terminalKeywordsToRegister.Add(reactorKeyword);
			TerminalPatch.terminalNodesToRegister.Add(reactorHealthNode);
		}
	}
}
namespace FacilityMeltdown.Util
{
	internal abstract class AssetBundleLoader<T> where T : AssetBundleLoader<T>
	{
		public AssetBundleLoader(string filePath)
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath));
			MeltdownPlugin.logger.LogDebug((object)("[Assets] AssetBundle `" + filePath + "` contains these objects: \n" + string.Join("\n", val.GetAllAssetNames())));
			Type typeFromHandle = typeof(T);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				LoadFromBundleAttribute loadFromBundleAttribute = (LoadFromBundleAttribute)propertyInfo.GetCustomAttribute(typeof(LoadFromBundleAttribute));
				if (loadFromBundleAttribute != null)
				{
					MeltdownPlugin.logger.LogDebug((object)("[Assets] Got LoadFromBundle attribute on `" + propertyInfo.Name + "`. Loading asset: `" + loadFromBundleAttribute.BundleFile + "` into the [roperty."));
					propertyInfo.SetValue(this, LoadAsset<Object>(val, loadFromBundleAttribute.BundleFile.ToLower(CultureInfo.GetCultureInfo("en-GB"))));
				}
			}
			GameObject[] array = val.LoadAllAssets<GameObject>();
			foreach (GameObject val2 in array)
			{
				if (!((Object)(object)val2.GetComponent<NetworkObject>() == (Object)null) && !GameNetworkManagerPatch.networkPrefabsToRegister.Contains(val2))
				{
					GameNetworkManagerPatch.networkPrefabsToRegister.Add(val2);
				}
			}
			FinishLoadingAssets(val);
		}

		protected virtual void FinishLoadingAssets(AssetBundle bundle)
		{
		}

		protected AssetType LoadAsset<AssetType>(AssetBundle bundle, string path) where AssetType : Object
		{
			AssetType val = bundle.LoadAsset<AssetType>(path);
			if ((Object)(object)val == (Object)null)
			{
				throw new ArgumentException(path + " is not valid in the assetbundle!");
			}
			return val;
		}
	}
}
namespace FacilityMeltdown.Util.Config
{
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigDescAttribute : Attribute
	{
		public string Description { get; private set; }

		public ConfigDescAttribute(string desc)
		{
			Description = desc;
			base..ctor();
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigGroupAttribute : Attribute
	{
		public string Group { get; private set; }

		public ConfigGroupAttribute(string Group)
		{
			this.Group = Group;
			base..ctor();
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property)]
	internal class ConfigRangeAttribute : Attribute
	{
		internal float Min { get; private set; }

		internal float Max { get; private set; }

		internal ConfigRangeAttribute(float min, float max)
		{
			Min = min;
			Max = max;
		}
	}
	[Serializable]
	internal abstract class LoafConfig<T> where T : LoafConfig<T>
	{
		internal List<(PropertyInfo, object)> configEntries = new List<(PropertyInfo, object)>();

		internal ConfigFile configFile { get; private set; }

		public LoafConfig(ConfigFile configFile)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			if (configFile == null)
			{
				return;
			}
			this.configFile = configFile;
			string header = "Misc";
			Type typeFromHandle = typeof(T);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.GetCustomAttribute(typeof(ConfigIgnoreAttribute)) == null)
				{
					ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigGroupAttribute));
					if (configGroupAttribute != null)
					{
						header = configGroupAttribute.Group.Replace(" ", "");
					}
					string text = "no description here :pensive:";
					ConfigDescAttribute configDescAttribute = (ConfigDescAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigDescAttribute));
					if (configDescAttribute != null)
					{
						text = configDescAttribute.Description;
					}
					ConfigDescription val = new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>());
					ConfigRangeAttribute configRangeAttribute = (ConfigRangeAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigRangeAttribute));
					val = ((configRangeAttribute == null) ? new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>()) : ((!(propertyInfo.PropertyType == typeof(int))) ? new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<float>(configRangeAttribute.Min, configRangeAttribute.Max), Array.Empty<object>()) : new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<int>((int)configRangeAttribute.Min, (int)configRangeAttribute.Max), Array.Empty<object>())));
					if (propertyInfo.PropertyType == typeof(float))
					{
						BindProperty<float>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(int))
					{
						BindProperty<int>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(string))
					{
						BindProperty<string>(propertyInfo, header, val);
					}
					if (propertyInfo.PropertyType == typeof(bool))
					{
						BindProperty<bool>(propertyInfo, header, val);
					}
				}
			}
		}

		protected void BindProperty<V>(PropertyInfo property, string header, ConfigDescription description)
		{
			ConfigEntry<V> val = configFile.Bind<V>(header, property.Name, (V)property.GetValue(this), description);
			configEntries.Add((property, val));
			property.SetValue(this, val.Value);
		}
	}
	internal abstract class LoafSyncedConfig<T> : LoafConfig<T> where T : LoafSyncedConfig<T>
	{
		internal static T Default { get; private set; }

		internal LoafSyncedConfig(ConfigFile file)
			: base(file)
		{
			if (Default == null)
			{
				Default = (T)this;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
	internal class RequiresRestartAttribute : Attribute
	{
		public bool RequiresRestart { get; private set; }

		public RequiresRestartAttribute(bool requiresRestart = true)
		{
			RequiresRestart = requiresRestart;
			base..ctor();
		}
	}
}
namespace FacilityMeltdown.Util.Attributes
{
	internal class CompatibleDependencyAttribute : BepInDependency
	{
		public Type Handler;

		public CompatibleDependencyAttribute(string guid, Type handlerType)
			: base(guid, (DependencyFlags)2)
		{
			Handler = handlerType;
		}

		public static void Init(BaseUnityPlugin source)
		{
			IEnumerable<CompatibleDependencyAttribute> customAttributes = ((MemberInfo)((object)source).GetType()).GetCustomAttributes<CompatibleDependencyAttribute>();
			foreach (CompatibleDependencyAttribute item in customAttributes)
			{
				if (Chainloader.PluginInfos.ContainsKey(((BepInDependency)item).DependencyGUID))
				{
					item.Handler.GetMethod("Initialize", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, null);
					item.Handler = null;
				}
			}
		}
	}
}
namespace FacilityMeltdown.Patches
{
	[HarmonyPatch(typeof(LungProp))]
	internal static class ApparaticePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EquipItem")]
		internal static void BeginMeltdownSequence(LungProp __instance, ref bool ___isLungDocked)
		{
			if (!((NetworkBehaviour)__instance).IsHost || !___isLungDocked || MeltdownAPI.MeltdownStarted)
			{
				return;
			}
			try
			{
				if (MeltdownPlugin.config.OverrideApparatusValue)
				{
					((GrabbableObject)__instance).scrapValue = Mathf.RoundToInt((float)MeltdownPlugin.config.ApparatusValue * WeatherRegistryIntegration.GetWeatherMultiplier());
				}
				GameObject val = Object.Instantiate<GameObject>(MeltdownPlugin.assets.meltdownHandlerPrefab);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)ex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void AddRadiationSource(LungProp __instance)
		{
			MeltdownMoonMapper.EnsureMeltdownMoonMapper();
			MeltdownInteriorMapper.EnsureMeltdownInteriorMapper();
			try
			{
				RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
				radiationSource.radiationAmount = 80f;
				radiationSource.radiationDistance = 60f;
				MeltdownMoonMapper.EnsureMeltdownMoonMapper();
				if (MeltdownPlugin.config.OverrideApparatusValue)
				{
					((GrabbableObject)__instance).scrapValue = Mathf.RoundToInt((float)MeltdownPlugin.config.ApparatusValue * WeatherRegistryIntegration.GetWeatherMultiplier());
				}
				MeltdownPlugin.logger.LogDebug((object)((GrabbableObject)__instance).scrapValue);
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)ex);
			}
		}
	}
	[HarmonyPatch(typeof(BlobAI))]
	internal class BlobAIPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void AddRadiationSource(BlobAI __instance)
		{
			RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
			radiationSource.radiationAmount = 30f;
			radiationSource.radiationDistance = 25f;
		}
	}
	[HarmonyPatch(typeof(EntranceTeleport))]
	internal static class EntranceTeleportPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("FindExitPoint")]
		private static bool dontAllowReneter(ref bool __result)
		{
			if ((Object)(object)MeltdownHandler.Instance != (Object)null && MeltdownHandler.Instance.HasExplosionOccured())
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatch
	{
		internal static List<GameObject> networkPrefabsToRegister = new List<GameObject>();

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void AddNetworkPrefabs()
		{
			foreach (GameObject item in networkPrefabsToRegister)
			{
				NetworkManager.Singleton.AddNetworkPrefab(item);
				MeltdownPlugin.logger.LogDebug((object)("Registered " + ((Object)item).name + " as a network prefab."));
			}
			MeltdownPlugin.logger.LogInfo((object)$"Succesfully registered {networkPrefabsToRegister.Count} network prefabs.");
		}

		[HarmonyPostfix]
		[HarmonyPatch("StartDisconnect")]
		public static void PlayerLeave()
		{
			MeltdownPlugin.config = LoafSyncedConfig<MeltdownConfig>.Default;
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	public class GrabbableObjectPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		internal static void ApplyMinPeople(GrabbableObject __instance)
		{
			LungProp apparatus = (LungProp)(object)((__instance is LungProp) ? __instance : null);
			if (apparatus == null)
			{
				return;
			}
			if (!apparatus.isLungDocked)
			{
				if (!((GrabbableObject)apparatus).grabbable)
				{
					((GrabbableObject)apparatus).customGrabTooltip = "";
					((GrabbableObject)apparatus).grabbable = true;
				}
				return;
			}
			int num = StartOfRound.Instance.GetConnectedPlayers().Count((PlayerControllerB player) => Vector3.Distance(((Component)player).transform.position, ((Component)apparatus).transform.position) < 15f);
			int num2 = Mathf.Min(MeltdownPlugin.config.MinPeopleToPullApparatus, StartOfRound.Instance.livingPlayers);
			if (num < num2 && TimeOfDay.Instance.GetCurrentTime().hours < 21)
			{
				((GrabbableObject)apparatus).customGrabTooltip = $"[ NEEDS {num2} PEOPLE ]";
				((GrabbableObject)apparatus).grabbable = false;
			}
			else
			{
				((GrabbableObject)apparatus).customGrabTooltip = "";
				((GrabbableObject)apparatus).grabbable = true;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		private const string MESSAGE_REQUEST = "meltdown_OnRequestConfigSync";

		private const string MESSAGE_RECIEVE = "meltdown_OnRecieveConfigSync";

		private const int IntSize = 4;

		[HarmonyPostfix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		private static void SyncConfig()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if (NetworkManager.Singleton.IsHost)
			{
				CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("meltdown_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				return;
			}
			CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			customMessagingManager2.RegisterNamedMessageHandler("meltdown_OnRecieveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		public static void RequestSync()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
			try
			{
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0052: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkManager.Singleton.IsHost)
			{
				return;
			}
			MeltdownPlugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object)MeltdownPlugin.config));
			int num = bytes.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + 4, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(bytes, -1, 0);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRecieveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				MeltdownPlugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0020: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!((FastBufferReader)(ref reader)).TryBeginRead(4))
			{
				MeltdownPlugin.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				MeltdownPlugin.logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] bytes = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref bytes, num, 0);
			MeltdownPlugin.logger.LogDebug((object)Encoding.UTF8.GetString(bytes));
			MeltdownPlugin.config = JsonConvert.DeserializeObject<MeltdownConfig>(Encoding.UTF8.GetString(bytes), new JsonSerializerSettings
			{
				ContractResolver = (IContractResolver)(object)new IncludePrivateSetterContractResolver()
			});
			MeltdownPlugin.logger.LogDebug((object)"Deserialized values are: ");
			PropertyInfo[] properties = MeltdownPlugin.config.GetType().GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				MeltdownPlugin.logger.LogDebug((object)$"{propertyInfo.Name} => {propertyInfo.GetValue(MeltdownPlugin.config)}");
			}
			MeltdownPlugin.logger.LogInfo((object)"Successfully synced config with host.");
		}
	}
	internal class IncludePrivateSetterContractResolver : DefaultContractResolver
	{
		protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			JsonProperty val = ((DefaultContractResolver)this).CreateProperty(member, memberSerialization);
			if (!val.Writable && member is PropertyInfo propertyInfo)
			{
				val.Writable = propertyInfo.GetSetMethod(nonPublic: true) != null;
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("EndOfGame")]
		internal static void UnloadMeltdownHandler()
		{
			if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownHandler.Instance).gameObject);
			}
			if (Object.op_Implicit((Object)(object)MeltdownMoonMapper.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownMoonMapper.Instance).gameObject);
			}
			if (Object.op_Implicit((Object)(object)MeltdownInteriorMapper.Instance))
			{
				Object.Destroy((Object)(object)((Component)MeltdownInteriorMapper.Instance).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		internal class ReactorHealthReport
		{
			public float reactorInstability;

			public float timeRemaining;

			public float generatedAt = Time.time;

			public string GetFlavourText()
			{
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.75f)
				{
					return "reactorscan.result.flavour.start";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.5f)
				{
					return "reactorscan.result.flavour.low";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.33f)
				{
					return "reactorscan.result.flavour.medium";
				}
				if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.15f)
				{
					return "reactorscan.result.flavour.high";
				}
				return "";
			}

			public string GetTeminalOutput()
			{
				string text = "reactorscan.result.unstable".Translate();
				text = SubstituteVariables(text);
				return text + "\n\n" + SubstituteVariables(GetFlavourText().Translate()) + "\n\n";
			}
		}

		internal static float lastHealthCheck = 0f;

		internal static ReactorHealthReport lastReport = null;

		internal static List<TerminalKeyword> terminalKeywordsToRegister = new List<TerminalKeyword>();

		internal static List<TerminalNode> terminalNodesToRegister = new List<TerminalNode>();

		internal static string SubstituteVariables(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text);
			stringBuilder.Replace("<cooldown>", MeltdownPlugin.config.ShipScanCooldown.ToString());
			stringBuilder.Replace("<instability>", lastReport.reactorInstability.ToString());
			stringBuilder.Replace("<time_left>", lastReport.timeRemaining.ToString());
			return stringBuilder.ToString();
		}

		internal static string GetTextForNode()
		{
			if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
			{
				string text = "reactorscan.error.overheat";
				if (ReactorHealthCheckReady())
				{
					lastHealthCheck = Time.time;
					lastReport = GetNewReactorHealthReport();
					text = "reactorscan.success";
				}
				return SubstituteVariables(text.Translate()) + lastReport.GetTeminalOutput();
			}
			return "reactorscan.result.stable".Translate();
		}

		internal static bool ReactorHealthCheckReady()
		{
			return Time.time >= lastHealthCheck + MeltdownPlugin.config.ShipScanCooldown;
		}

		internal static ReactorHealthReport GetNewReactorHealthReport()
		{
			float num = ((float)MeltdownPlugin.config.MeltdownTime - MeltdownHandler.Instance.meltdownTimer) / (float)MeltdownPlugin.config.MeltdownTime * 100f;
			num = Mathf.Round(num / MeltdownPlugin.config.ShipScanAccuracy) * MeltdownPlugin.config.ShipScanAccuracy;
			float timeRemaining = (1f - num / 100f) * (float)MeltdownPlugin.config.MeltdownTime;
			return new ReactorHealthReport
			{
				reactorInstability = num,
				timeRemaining = timeRemaining
			};
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		internal static void RegisterNodes(Terminal __instance)
		{
			__instance.terminalNodes.allKeywords = CollectionExtensions.AddRangeToArray<TerminalKeyword>(__instance.terminalNodes.allKeywords, terminalKeywordsToRegister.ToArray());
			__instance.terminalNodes.terminalNodes.AddRange(terminalNodesToRegister);
		}

		[HarmonyPostfix]
		[HarmonyPatch("TextPostProcess")]
		internal static void ProcessReactorText(TerminalNode node, ref string __result)
		{
			if ((Object)(object)node == (Object)(object)MeltdownPlugin.assets.reactorHealthNode)
			{
				__result = "\n\n\n" + GetTextForNode();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StormyWeather), "GetMetalObjectsAfterDelay")]
		internal static void CancelCoroutine(StormyWeather __instance, ref IEnumerator __result)
		{
			((MonoBehaviour)__instance).StopCoroutine(__result);
		}
	}
}
namespace FacilityMeltdown.MeltdownSequence
{
	public static class MeltdownEffects
	{
		[CompilerGenerated]
		private sealed class <AtProgress>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float progress;

			public IEnumerator enumerator;

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

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

			[DebuggerHidden]
			public <AtProgress>d__6(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;
					goto IL_003b;
				case 1:
					<>1__state = -1;
					goto IL_003b;
				case 2:
					{
						<>1__state = -1;
						return false;
					}
					IL_003b:
					if (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<>2__current = enumerator;
					<>1__state = 2;
					return true;
				}
			}

			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 <AtProgress>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float progress;

			public Action callback;

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

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

			[DebuggerHidden]
			public <AtProgress>d__7(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;
					break;
				}
				if (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				callback();
				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 <EmergencyLights>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float onTime;

			public List<(Light light, Color originalColour)> originalLightColours;

			public float offTime;

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

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

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

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

			private bool MoveNext()
			{
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Expected O, but got Unknown
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0152: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					MeltdownPlugin.logger.LogDebug((object)"Switching lights ON");
					for (int j = 0; j < RoundManager.Instance.allPoweredLightsAnimators.Count; j++)
					{
						RoundManager.Instance.allPoweredLightsAnimators[j].SetBool("on", true);
					}
					for (int k = 0; k < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; k++)
					{
						MeltdownMoonMapper.Instance.outsideEmergencyLights[k].color = MeltdownMoonMapper.Instance.outsideEmergencyLightColour;
					}
					<>2__current = (object)new WaitForSeconds(onTime);
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					MeltdownPlugin.logger.LogDebug((object)"Switching lights OFF");
					for (int i = 0; i < RoundManager.Instance.allPoweredLightsAnimators.Count; i++)
					{
						RoundManager.Instance.allPoweredLightsAnimators[i].SetBool("on", false);
					}
					foreach (var (val, color) in originalLightColours)
					{
						val.color = color;
					}
					<>2__current = (object)new WaitForSeconds(offTime);
					<>1__state = 2;
					return true;
				}
				case 2:
					<>1__state = -1;
					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 <RepeatUntilEndOfMeltdown>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<IEnumerator> enumerator;

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

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

			[DebuggerHidden]
			public <RepeatUntilEndOfMeltdown>d__1(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
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(Random.Range(0f, 1f));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				MeltdownPlugin.logger.LogDebug((object)"looping effect");
				<>2__current = enumerator();
				<>1__state = 2;
				return true;
			}

			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 <WarningAnnouncer>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public AudioSource source;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					source.volume = MeltdownPlugin.clientConfig.MusicVolume;
					AudioClip clip = MeltdownPlugin.assets.warnings[Random.Range(0, MeltdownPlugin.assets.warnings.Length)];
					source.clip = clip;
					source.Play();
					<>2__current = (object)new WaitForSeconds(source.clip.length);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					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 <WithDelay>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public IEnumerator enumerator;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = enumerator;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					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 <WithDelay>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public float delay;

			public Action callback;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					callback();
					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 <WithRandomDelay>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Func<IEnumerator> enumerator;

			public float min;

			public float max;

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

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

			[DebuggerHidden]
			public <WithRandomDelay>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;
					<>2__current = WithDelay(enumerator(), Random.Range(min, max));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					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 <WithRandomDelay>d__5 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Action callback;

			public float min;

			public float max;

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

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

			[DebuggerHidden]
			public <WithRandomDelay>d__5(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;
					<>2__current = WithDelay(callback, Random.Range(min, max));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					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 List<(Light light, Color originalColour)> SetupEmergencyLights()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < RoundManager.Instance.allPoweredLights.Count; i++)
			{
				RoundManager.Instance.allPoweredLights[i].color = MeltdownInteriorMapper.Instance.outsideEmergencyLightColour;
			}
			List<(Light, Color)> list = new List<(Light, Color)>();
			for (int j = 0; j < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; j++)
			{
				list.Add((MeltdownMoonMapper.Instance.outsideEmergencyLights[j], MeltdownMoonMapper.Instance.outsideEmergencyLights[j].color));
			}
			return list;
		}

		[IteratorStateMachine(typeof(<RepeatUntilEndOfMeltdown>d__1))]
		public static IEnumerator RepeatUntilEndOfMeltdown(Func<IEnumerator> enumerator)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RepeatUntilEndOfMeltdown>d__1(0)
			{
				enumerator = enumerator
			};
		}

		[IteratorStateMachine(typeof(<WithDelay>d__2))]
		public static IEnumerator WithDelay(IEnumerator enumerator, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WithDelay>d__2(0)
			{
				enumerator = enumerator,
				delay = delay
			};
		}

		[IteratorStateMachine(typeof(<WithDelay>d__3))]
		public static IEnumerator WithDelay(Action callback, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WithDelay>d__3(0)
			{
				callback = callback,
				delay = delay
			};
		}

		[IteratorStateMachine(typeof(<WithRandomDelay>d__4))]
		public static IEnumerator WithRandomDelay(Func<IEnumerator> enumerator, float min, float max)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WithRandomDelay>d__4(0)
			{
				enumerator = enumerator,
				min = min,
				max = max
			};
		}

		[IteratorStateMachine(typeof(<WithRandomDelay>d__5))]
		public static IEnumerator WithRandomDelay(Action callback, float min, float max)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WithRandomDelay>d__5(0)
			{
				callback = callback,
				min = min,
				max = max
			};
		}

		[IteratorStateMachine(typeof(<AtProgress>d__6))]
		public static IEnumerator AtProgress(IEnumerator enumerator, float progress)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AtProgress>d__6(0)
			{
				enumerator = enumerator,
				progress = progress
			};
		}

		[IteratorStateMachine(typeof(<AtProgress>d__7))]
		public static IEnumerator AtProgress(Action callback, float progress)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AtProgress>d__7(0)
			{
				callback = callback,
				progress = progress
			};
		}

		[IteratorStateMachine(typeof(<EmergencyLights>d__8))]
		public static IEnumerator EmergencyLights(float onTime, float offTime, List<(Light light, Color originalColour)> originalLightColours)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EmergencyLights>d__8(0)
			{
				onTime = onTime,
				offTime = offTime,
				originalLightColours = originalLightColours
			};
		}

		public static void InsideParticleEffects()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				RaycastHit val2 = default(RaycastHit);
				for (int i = 0; i < Random.Range(5, 15); i++)
				{
					Vector3 val = GetRandomPositionInsideFacility() + Vector3.up;
					if (Physics.Raycast(new Ray(val, Vector3.up), ref val2, 20f, 256))
					{
						GameObject val3 = MeltdownPlugin.assets.facilityEffects[Random.Range(0, MeltdownPlugin.assets.facilityEffects.Length)];
						GameObject val4 = Object.Instantiate<GameObject>(val3);
						val3.transform.position = ((RaycastHit)(ref val2)).point;
						val4.transform.parent = ((Component)MeltdownHandler.Instance).transform;
					}
				}
			}
			if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, GetRandomPositionNearPlayer(), Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform);
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				if (MeltdownHandler.Instance.Progress > 0.5f)
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
				}
				else
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				}
			}
		}

		[IteratorStateMachine(typeof(<WarningAnnouncer>d__10))]
		public static IEnumerator WarningAnnouncer(AudioSource source)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WarningAnnouncer>d__10(0)
			{
				source = source
			};
		}

		private static Vector3 PlacePositionInsideFacility(Vector3 position, float radius = 10f)
		{
			//IL_0005: 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_000f: 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)
			return RoundManager.Instance.GetRandomNavMeshPositionInRadius(position, radius, default(NavMeshHit));
		}

		private static Vector3 GetRandomPositionNearPlayer(float radius = 15f)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0029: Unknown result type (might be due to invalid IL or missing references)
			return PlacePositionInsideFacility(((Component)GameNetworkManager.Instance.localPlayerController).transform.position + Random.insideUnitSphere * radius);
		}

		private static Vector3 GetRandomPositionInsideFacility()
		{
			//IL_0022: 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)
			return PlacePositionInsideFacility(RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position);
		}
	}
}
namespace FacilityMeltdown.MeltdownSequence.Behaviours
{
	internal class FacilityExplosionHandler : MonoBehaviour
	{
		private PlayerControllerB player;

		private float size;

		private float time;

		private LocalVolumetricFog internalFog;

		private void Awake()
		{
			player = GameNetworkManager.Instance.localPlayerController;
			internalFog = ((Component)this).GetComponent<LocalVolumetricFog>();
			if ((Object)(object)internalFog == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"Failed to get volumetric fog!");
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
			}
			if (!player.isPlayerDead && player.isInsideFactory)
			{
				if (player.isInElevator)
				{
					MeltdownPlugin.logger.LogWarning((object)"Player is inside ship and facility at the same time!! Did you teleport out? Aborting kill");
				}
				else
				{
					KillPlayer();
				}
			}
		}

		private void Update()
		{
			//IL_0030: 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_005e: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			time += Time.deltaTime * 10f;
			size = TimeToSize(time);
			((Component)this).transform.localScale = Vector3.one * size;
			if ((Object)(object)internalFog != (Object)null)
			{
				internalFog.parameters.size = Vector3.one * size * 1.25f;
			}
			if (!ShouldIgnorePlayer() && PlayerIsInsideFireball())
			{
				player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0, default(Vector3));
			}
		}

		private void KillPlayer()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0, default(Vector3));
		}

		private bool PlayerIsInsideFireball()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < size;
		}

		private bool ShouldIgnorePlayer()
		{
			if (!player.isPlayerDead)
			{
				if (player.isInElevator)
				{
					return StartOfRound.Instance.shipIsLeaving;
				}
				return false;
			}
			return true;
		}

		private float TimeToSize(float time)
		{
			return Mathf.Log(time) + 3f + 2f * time;
		}
	}
	public class MeltdownHandler : NetworkBehaviour
	{
		[CompilerGenerated]
		private sealed class <ShipTakeOff>d__25 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private StartOfRound <shipManager>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Expected O, but got Unknown
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Expected O, but got Unknown
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Expected O, but got Unknown
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Expected O, but got Unknown
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<shipManager>5__2 = StartOfRound.Instance;
					<shipManager>5__2.shipLeftAutomatically = true;
					<shipManager>5__2.shipIsLeaving = true;
					HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.shiptakeoff"));
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 2;
					return true;
				case 2:
				{
					<>1__state = -1;
					((Behaviour)HUDManager.Instance.shipLeavingEarlyIcon).enabled = false;
					StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
					val.triggerScript.animationString = "SA_PushLeverBack";
					val.leverHasBeenPulled = false;
					val.triggerScript.interactable = false;
					val.leverAnimatorObject.SetBool("pullLever", false);
					<shipManager>5__2.ShipLeave();
					<>2__current = (object)new WaitForSeconds(1.5f);
					<>1__state = 3;
					return true;
				}
				case 3:
					<>1__state = -1;
					<shipManager>5__2.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null);
					if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
					{
						GameNetworkManager.Instance.localPlayerController.SetSpectatedPlayerEffects(true);
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(9.5f);
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					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();
			}
		}

		internal float meltdownTimer;

		private bool meltdownStarted;

		private GameObject explosion;

		private GameObject shockwave;

		[SerializeField]
		private AudioSource meltdownMusic;

		[SerializeField]
		private AudioSource warningSource;

		public float TimeLeftUntilMeltdown => meltdownTimer;

		public float Progress => 1f - TimeLeftUntilMeltdown / (float)MeltdownPlugin.config.MeltdownTime;

		private static PlayerControllerB Player => GameNetworkManager.Instance.localPlayerController;

		internal static MeltdownHandler Instance { get; private set; }

		private Vector3 effectOrigin => MeltdownMoonMapper.Instance.EffectOrigin;

		[ClientRpc]
		private void StartMeltdownClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3631067672u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3631067672u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if ((Object)(object)Instance != (Object)null)
			{
				return;
			}
			Instance = this;
			Stopwatch stopwatch = new Stopwatch();
			MeltdownPlugin.logger.LogInfo((object)"Beginning Meltdown Sequence! I'd run if I were you!");
			stopwatch.Start();
			MeltdownMoonMapper.EnsureMeltdownMoonMapper();
			MeltdownInteriorMapper.EnsureMeltdownInteriorMapper();
			if ((Object)(object)MeltdownInteriorMapper.Instance == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the interior mapper exists and it doesnt?!?");
			}
			if ((Object)(object)MeltdownMoonMapper.Instance == (Object)null)
			{
				MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the moon mapper exists and it doesnt?!?");
			}
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Ensuring data objects exist: {stopwatch.ElapsedMilliseconds}ms");
			meltdownTimer = MeltdownPlugin.config.MeltdownTime;
			stopwatch.Restart();
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Creating audio: {stopwatch.ElapsedMilliseconds}ms");
			stopwatch.Restart();
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(delegate
			{
				HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.start"));
			}, 5f));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay(() => MeltdownEffects.WarningAnnouncer(warningSource), 10f, 15f)), 10f));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay((Action)MeltdownEffects.InsideParticleEffects, 10f, 15f)));
			if (MeltdownPlugin.config.EmergencyLights)
			{
				try
				{
					List<(Light, Color)> originalLightColours = MeltdownEffects.SetupEmergencyLights();
					((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.EmergencyLights(2f, 5f, originalLightColours)));
				}
				catch (Exception arg)
				{
					MeltdownPlugin.logger.LogError((object)$"Failed to set the emergency light colour: {arg}");
				}
			}
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay(delegate
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)shockwave != (Object)null)
				{
					Object.Destroy((Object)(object)shockwave);
				}
				shockwave = Object.Instantiate<GameObject>(MeltdownPlugin.assets.shockwavePrefab);
				shockwave.transform.position = effectOrigin;
			}, 25f, 35f)));
			((MonoBehaviour)this).StartCoroutine(MeltdownEffects.AtProgress((Action)HUDManager.Instance.RadiationWarningHUD, 0.5f));
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Starting effects: {stopwatch.ElapsedMilliseconds}ms");
			if (((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsServer)
			{
				SpawnEnemies();
			}
			stopwatch.Restart();
			if (effectOrigin == Vector3.zero)
			{
				MeltdownPlugin.logger.LogError((object)"Effect Origin is Vector3.Zero! We couldn't find the effect origin");
				HUDManager.Instance.DisplayGlobalNotification("Failed to find effect origin... Things will look broken.");
			}
			if (MeltdownPlugin.clientConfig.ScreenShake)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
			}
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Getting effect origin: {stopwatch.ElapsedMilliseconds}ms");
			stopwatch.Restart();
			MeltdownAPI.OnMeltdownStart();
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"MeltdownAPI.OnMeltdownStart(): {stopwatch.ElapsedMilliseconds}ms");
			meltdownStarted = true;
		}

		private void SpawnEnemies()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			List<string> disallowed = MeltdownPlugin.config.GetDisallowedEnemies();
			List<SpawnableEnemyWithRarity> list = RoundManager.Instance.currentLevel.Enemies.Where((SpawnableEnemyWithRarity enemy) => !EnemyCannotBeSpawned(enemy.enemyType) && !disallowed.Contains(enemy.enemyType.enemyName)).ToList();
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Filtering enemies: {stopwatch.ElapsedMilliseconds}ms");
			stopwatch.Restart();
			List<EnemyVent> list2 = RoundManager.Instance.allEnemyVents.Where((EnemyVent vent) => !vent.occupied).ToList();
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Filtering vents: {stopwatch.ElapsedMilliseconds}ms");
			stopwatch.Restart();
			for (int i = 0; i < Mathf.Min(MeltdownPlugin.config.MonsterSpawnAmount, list2.Count); i++)
			{
				EnemyVent val = list2[Random.Range(0, list2.Count)];
				list2.Remove(val);
				SpawnableEnemyWithRarity val2 = list[Random.Range(0, list2.Count)];
				RoundManager instance = RoundManager.Instance;
				instance.currentEnemyPower += val2.enemyType.PowerLevel;
				MeltdownPlugin.logger.LogInfo((object)("Spawning a " + val2.enemyType.enemyName + " during the meltdown sequence"));
				val.SpawnEnemy(val2);
			}
			stopwatch.Stop();
			MeltdownPlugin.logger.LogDebug((object)$"Spawning enemies: {stopwatch.ElapsedMilliseconds}ms");
		}

		public override void OnNetworkSpawn()
		{
			if (MeltdownPlugin.loadedFully && ((NetworkBehaviour)this).IsHost)
			{
				StartMeltdownClientRpc();
			}
		}

		internal bool EnemyCannotBeSpawned(EnemyType type)
		{
			if (!type.spawningDisabled)
			{
				return type.numberSpawned >= type.MaxCount;
			}
			return true;
		}

		internal static DialogueSegment[] GetDialogue(string translation)
		{
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			JArray translationSet = LangParser.GetTranslationSet(translation);
			DialogueSegment[] array = (DialogueSegment[])(object)new DialogueSegment[((JContainer)translationSet).Count];
			for (int i = 0; i < ((JContainer)translationSet).Count; i++)
			{
				array[i] = new DialogueSegment
				{
					bodyText = ((string)translationSet[i]).Replace("<meltdown_time>", Math.Round((float)MeltdownPlugin.config.MeltdownTime / 60f).ToString()),
					speakerText = "meltdown.dialogue.speaker".Translate()
				};
			}
			return array;
		}

		private void OnDisable()
		{
			if (!((Object)(object)Instance != (Object)(object)this))
			{
				MeltdownPlugin.logger.LogInfo((object)"Cleaning up MeltdownHandler.");
				Instance = null;
				if ((Object)(object)explosion != (Object)null)
				{
					Object.Destroy((Object)(object)explosion);
				}
				if ((Object)(object)shockwave != (Object)null)
				{
					Object.Destroy((Object)(object)shockwave);
				}
				if (!meltdownStarted)
				{
					MeltdownPlugin.logger.LogError((object)"MeltdownHandler was disabled without starting a meltdown, a client most likely failed the MeltdownReadyCheck. If you are going to report this make sure to provide ALL client logs.");
				}
			}
		}

		private void Update()
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (!meltdownStarted || HasExplosionOccured())
			{
				return;
			}
			StartOfRound instance = StartOfRound.Instance;
			meltdownMusic.volume = (float)MeltdownPlugin.clientConfig.MusicVolume / 100f;
			if (!Player.isInsideFactory && !MeltdownPlugin.clientConfig.MusicPlaysOutside)
			{
				meltdownMusic.volume = 0f;
			}
			meltdownTimer -= Time.deltaTime;
			if (meltdownTimer <= 3f && !instance.shipIsLeaving)
			{
				((MonoBehaviour)this).StartCoroutine(ShipTakeOff());
			}
			if (meltdownTimer <= 0f)
			{
				meltdownMusic.Stop();
				GameObject val = MeltdownMoonMapper.Instance.explosionPrefab;
				if ((Object)(object)val == (Object)null)
				{
					val = MeltdownPlugin.assets.facilityExplosionPrefab;
				}
				explosion = Object.Instantiate<GameObject>(val);
				explosion.transform.position = effectOrigin;
				FacilityExplosionHandler facilityExplosionHandler = default(FacilityExplosionHandler);
				if (!explosion.TryGetComponent<FacilityExplosionHandler>(ref facilityExplosionHandler))
				{
					explosion.AddComponent<FacilityExplosionHandler>();
				}
			}
		}

		[IteratorStateMachine(typeof(<ShipTakeOff>d__25))]
		private IEnumerator ShipTakeOff()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShipTakeOff>d__25(0);
		}

		public bool HasExplosionOccured()
		{
			return (Object)(object)explosion != (Object)null;
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(3631067672u, new RpcReceiveHandler(__rpc_handler_3631067672), "StartMeltdownClientRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_3631067672(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MeltdownHandler)(object)target).StartMeltdownClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "MeltdownHandler";
		}
	}
	public class Shockwave : MonoBehaviour
	{
		private bool localPlayerCameraShake;

		private float size;

		private AudioSource sound;

		private Renderer renderer;

		private void Awake()
		{
			sound = ((Component)this).gameObject.AddComponent<AudioSource>();
			sound.clip = MeltdownPlugin.assets.shockwave;
			sound.spatialBlend = 0f;
			sound.loop = false;
			renderer = ((Component)this).GetComponent<Renderer>();
		}

		private void Update()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			size += Time.deltaTime * 50f;
			((Component)this).transform.localScale = Vector3.one * size;
			if (localPlayerController.isInsideFactory)
			{
				renderer.enabled = false;
				return;
			}
			renderer.enabled = true;
			if (PlayerIsInsideShockwave() && !localPlayerCameraShake && MeltdownPlugin.clientConfig.ScreenShake)
			{
				ScreenShake();
				localPlayerCameraShake = true;
				sound.Play();
			}
		}

		private void ScreenShake()
		{
			HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
		}

		internal bool PlayerIsInsideShockwave()
		{
			//IL_0006: 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)
			return Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) <= size;
		}
	}
}
namespace FacilityMeltdown.Lang
{
	internal static class LangParser
	{
		internal static Dictionary<string, string> languages { get; private set; }

		internal static Dictionary<string, object> loadedLanguage { get; private set; }

		internal static Dictionary<string, object> defaultLanguage { get; private set; }

		internal static void Init()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FacilityMeltdown.Lang.defs.json");
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadToEnd();
			languages = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
		}

		internal static Dictionary<string, object> LoadLanguage(string id)
		{
			using Stream stream = File.Open(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lang", id + ".json"), FileMode.Open);
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadToEnd();
			return JsonConvert.DeserializeObject<Dictionary<string, object>>(text);
		}

		internal static void SetLanguage(string id)
		{
			MeltdownPlugin.logger.LogInfo((object)("Loading language: " + languages[id] + " (" + id + ")"));
			loadedLanguage = LoadLanguage(id);
			MeltdownPlugin.logger.LogInfo((object)("Loaded " + languages[id]));
		}

		internal static string GetTranslation(string translation)
		{
			if (loadedLanguage.TryGetValue(translation, out var value))
			{
				return (string)value;
			}
			if (defaultLanguage.TryGetValue(translation, out value))
			{
				MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation: " + translation));
				return (string)value;
			}
			if (translation == "lang.missing")
			{
				MeltdownPlugin.logger.LogError((object)"LANG.MISSING IS MISSING!!!!!  THIS IS BAD!! VERY BAD!!");
				return "lang.missing; <translation_id>";
			}
			return GetTranslation("lang.missing").Replace("<translation_id>", translation);
		}

		internal static JArray GetTranslationSet(string translation)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (loadedLanguage.TryGetValue(translation, out var value))
			{
				MeltdownPlugin.logger.LogInfo((object)value.GetType());
				return (JArray)((value is JArray) ? value : null);
			}
			if (defaultLanguage.TryGetValue(translation, out value))
			{
				MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation (dialogue): " + translation));
				return (JArray)((value is JArray) ? value : null);
			}
			JArray val = new JArray();
			val.Add(JToken.op_Implicit(GetTranslation("lang.missing").Replace("<translation_id>", translation)));
			return val;
		}
	}
}
namespace FacilityMeltdown.Integrations
{
	internal class LethalConfigIntergration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			Enabled = true;
			LethalConfigManager.SetModDescription("Maybe taking the appartus isn't such a great idea...");
			HandleConfig(MeltdownPlugin.config);
			HandleConfig(MeltdownPlugin.clientConfig);
		}

		private static void HandleConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			bool flag = true;
			if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
			{
				flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
			}
			foreach (var configEntry in config.configEntries)
			{
				PropertyInfo property = configEntry.Item1;
				object uncastedEntry = configEntry.Item2;
				bool flag2 = flag;
				RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
				if (customAttribute != null)
				{
					flag2 = customAttribute.RequiresRestart;
				}
				ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
				if (property.PropertyType == typeof(int))
				{
					if (customAttribute2 == null)
					{
						throw new NotImplementedException(property.Name + ": config entry of type: int, must have a range attribute, because i was too lazy lmao");
					}
					ConfigEntry<int> obj2 = (ConfigEntry<int>)uncastedEntry;
					IntSliderOptions val = new IntSliderOptions();
					((BaseRangeOptions<int>)val).Min = (int)customAttribute2.Min;
					((BaseRangeOptions<int>)val).Max = (int)customAttribute2.Max;
					((BaseOptions)val).RequiresRestart = flag2;
					LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(obj2, val));
					if (!flag2)
					{
						((ConfigEntry<int>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<int>)uncastedEntry).Value);
						};
					}
				}
				if (property.PropertyType == typeof(float))
				{
					if (customAttribute2 == null)
					{
						throw new NotImplementedException(property.Name + ": config entry of type: float, must have a range attribute, because i was too lazy lmao");
					}
					ConfigEntry<float> obj3 = (ConfigEntry<float>)uncastedEntry;
					FloatSliderOptions val2 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val2).Min = customAttribute2.Min;
					((BaseRangeOptions<float>)val2).Max = customAttribute2.Max;
					((BaseOptions)val2).RequiresRestart = flag2;
					LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(obj3, val2));
					if (!flag2)
					{
						((ConfigEntry<float>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<float>)uncastedEntry).Value);
						};
					}
				}
				if (property.PropertyType == typeof(bool))
				{
					LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem((ConfigEntry<bool>)uncastedEntry, flag2));
					if (!flag2)
					{
						((ConfigEntry<bool>)uncastedEntry).SettingChanged += delegate
						{
							property.SetValue(config, ((ConfigEntry<bool>)uncastedEntry).Value);
						};
					}
				}
				if (!(property.PropertyType == typeof(string)))
				{
					continue;
				}
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem((ConfigEntry<string>)uncastedEntry, flag2));
				if (!flag2)
				{
					((ConfigEntry<string>)uncastedEntry).SettingChanged += delegate
					{
						property.SetValue(config, ((ConfigEntry<string>)uncastedEntry).Value);
					};
				}
			}
		}
	}
	internal class LethalSettingsIntegration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			Enabled = true;
			VerticalComponent val = BuildConfig(MeltdownPlugin.clientConfig);
			ModSettingsConfig val2 = new ModSettingsConfig();
			val2.Name = "FacilityMeltdown";
			val2.Id = "me.loaforc.facilitymeltdown";
			val2.Version = "2.6.15";
			val2.Description = "Maybe taking the appartus isn't such a great idea...";
			val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[2]
			{
				(MenuComponent)BuildConfig(MeltdownPlugin.config),
				(MenuComponent)val
			};
			ModMenu.RegisterMod(val2);
			val2 = new ModSettingsConfig();
			val2.Name = "FacilityMeltdown";
			val2.Id = "me.loaforc.facilitymeltdown";
			val2.Version = "2.6.15";
			val2.Description = "Maybe taking the appartus isn't such a great idea... (GameSettings are hidden in game)";
			val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[1] { (MenuComponent)val };
			ModMenu.RegisterMod(val2, false, true);
		}

		private static VerticalComponent BuildConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_013e: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Expected O, but got Unknown
			bool flag = true;
			if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
			{
				flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
			}
			List<MenuComponent> list = new List<MenuComponent>();
			string text = "Misc";
			foreach (var configEntry in config.configEntries)
			{
				PropertyInfo property = configEntry.Item1;
				object uncastedEntry = configEntry.Item2;
				bool requiresRestart = flag;
				RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
				if (customAttribute != null)
				{
					requiresRestart = customAttribute.RequiresRestart;
				}
				ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)property.GetCustomAttribute(typeof(ConfigGroupAttribute));
				if (configGroupAttribute != null)
				{
					text = configGroupAttribute.Group;
					list.Add((MenuComponent)new LabelComponent
					{
						Text = text
					});
				}
				else if (text == "Misc")
				{
					list.Add((MenuComponent)new LabelComponent
					{
						Text = text
					});
				}
				ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
				if (property.PropertyType == typeof(int))
				{
					list.Add((MenuComponent)new SliderComponent
					{
						Value = (int)property.GetValue(config),
						WholeNumbers = true,
						MinValue = customAttribute2.Min,
						MaxValue = customAttribute2.Max,
						Text = property.Name,
						OnValueChanged = delegate(SliderComponent self, float value)
						{
							((ConfigEntry<int>)uncastedEntry).Value = (int)value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (property.PropertyType == typeof(float))
				{
					list.Add((MenuComponent)new SliderComponent
					{
						Value = (float)property.GetValue(config),
						MinValue = customAttribute2.Min,
						MaxValue = customAttribute2.Max,
						Text = property.Name,
						OnValueChanged = delegate(SliderComponent self, float value)
						{
							((ConfigEntry<float>)uncastedEntry).Value = value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (property.PropertyType == typeof(bool))
				{
					list.Add((MenuComponent)new ToggleComponent
					{
						Text = property.Name,
						Value = (bool)property.GetValue(config),
						OnValueChanged = delegate(ToggleComponent self, bool value)
						{
							((ConfigEntry<bool>)uncastedEntry).Value = value;
							if (!requiresRestart)
							{
								property.SetValue(config, value);
							}
						}
					});
				}
				if (!(property.PropertyType == typeof(string)))
				{
					continue;
				}
				list.Add((MenuComponent)new InputComponent
				{
					Placeholder = property.Name,
					Value = (string)property.GetValue(config),
					OnValueChanged = delegate(InputComponent self, string value)
					{
						((ConfigEntry<string>)uncastedEntry).Value = value;
						if (!requiresRestart)
						{
							property.SetValue(config, value);
						}
					}
				});
			}
			return null;
		}
	}
	internal class LobbyCompatibilityIntegration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			Enabled = true;
			PluginHelper.RegisterPlugin("me.loaforc.facilitymeltdown", Version.Parse("2.6.15"), (CompatibilityLevel)2, (VersionStrictness)3);
		}
	}
	internal class WeatherRegistryIntegration
	{
		public static bool Enabled { get; private set; }

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void Initialize()
		{
			Enabled = true;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static float GetWeatherMultiplier()
		{
			return 1f;
		}
	}
}
namespace FacilityMeltdown.Equipment
{
	public class GeigerCounterItem : GrabbableObject
	{
		[Space(15f)]
		[Header("Audio")]
		public AudioSource generalAudioSource;

		public AudioSource lowRadiation;

		public AudioSource mediumRadiation;

		public AudioSource highRadiation;

		public AudioClip toggle;

		public AudioClip outOfBattery;

		public GameObject needle;

		public float maxRotation = 25f;

		public float maxDetection = 50f;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			MeltdownPlugin.logger.LogInfo((object)"ACTIVATED GEIGER COUNTER");
			SwitchPoweredState(used);
			generalAudioSource.clip = toggle;
			generalAudioSource.Play();
		}

		public override void UseUpBatteries()
		{
			((GrabbableObject)this).UseUpBatteries();
			SwitchPoweredState(on: false);
			generalAudioSource.clip = outOfBattery;
			generalAudioSource.Play();
		}

		public void SwitchPoweredState(bool on)
		{
			MeltdownPlugin.logger.LogInfo((object)$"me when the on value is {on}. :rofl::rofl::rofl:");
			if (base.isBeingUsed)
			{
				lowRadiation.Play();
				mediumRadiation.Play();
				highRadiation.Play();
			}
			else
			{
				lowRadiation.Stop();
				mediumRadiation.Stop();
				highRadiation.Stop();
			}
		}

		public override void Update()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (base.isBeingUsed)
			{
				float num = RadiationSource.CollectRadiationFromPoint(((Component)this).transform.position);
				lowRadiation.volume = 0f;
				mediumRadiation.volume = 0f;
				highRadiation.volume = 0f;
				if (num > maxDetection)
				{
					highRadiation.volume = 1f;
				}
				else if (num > maxDetection / 2f)
				{
					mediumRadiation.volume = 1f;
				}
				else
				{
					lowRadiation.volume = 1f;
				}
				float num2 = Mathf.Clamp01(num / maxDetection) * (maxRotation * 2f);
				num2 -= maxRotation;
				needle.transform.localEulerAngles = new Vector3(-90f, num2, 0f);
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			((GrabbableObject)this).__initializeRpcs();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "GeigerCounterItem";
		}
	}
}
namespace FacilityMeltdown.Config
{
	[RequiresRestart(false)]
	internal class MeltdownClientConfig : LoafConfig<MeltdownClientConfig>
	{
		[ConfigGroup("Audio")]
		[ConfigDesc("What volume the music plays at. Also controls the volume of the random voicelines that play")]
		[ConfigRange(0f, 100f)]
		public int MusicVolume { get; private set; } = 100;


		[ConfigDesc("Does the music play outside the facility?")]
		public bool MusicPlaysOutside { get; private set; } = true;


		[ConfigGroup("Visuals")]
		[ConfigDesc("Whether or not to shake the screen during the meltdown sequence. Doesn't control other places of screen shake in the game.")]
		public bool ScreenShake { get; private set; } = true;


		[ConfigDesc("Should meltdown sequence contain particle effects? Doesn't include particle effects on the fireball.")]
		public bool ParticleEffects { get; private set; } = true;


		[ConfigIgnore]
		[RequiresRestart(true)]
		public string Language { get; private set; } = "en";


		internal MeltdownClientConfig(ConfigFile file)
			: base(file)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			BindProperty<string>(typeof(MeltdownClientConfig).GetProperty("Language"), "Language", new ConfigDescription("What language should FacilityMeltdown use? NOTE: This only affects facility meltdown and won't change the rest of the games langauge\nSome Languages may also need FontPatcher(https://thunderstore.io/c/lethal-company/p/LeKAKiD/FontPatcher/)\nLanguages Available: " + string.Join(", ", LangParser.languages.Keys), (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal class MeltdownConfig : LoafSyncedConfig<MeltdownConfig>
	{
		[ConfigGroup("GameBalance")]
		[ConfigDesc("Whether or not FacilityMeltdown should override appartus value. Only disable for compatibility reasons.")]
		public bool OverrideApparatusValue { get; private set; } = true;


		[ConfigDesc("When overriding the apparatus value what should it's base value be?")]
		[ConfigRange(80f, 500f)]
		public int ApparatusValue { get; private set; } = 240;


		[ConfigDesc("How many monsters should spawn during the meltdown sequence? Set to 0 to disable.")]
		[ConfigRange(0f, 10f)]
		public int MonsterSpawnAmount { get; private set; } = 5;


		[ConfigDesc("Should the lights turn on periodically? Disabling this option makes them permanently off. (Matches Vanilla Behaviour)")]
		public bool EmergencyLights { get; private set; } = true;


		[ConfigDesc("How many people need to be nearby to the apparatus for it to be collectable? Will go UP TO the value, e.g. if it's set to 3 and there are only 2 people in the lobby, everyone will need to be there.\nThis value is ignored and anybody can grab it from 9PM")]
		[ConfigRange(1f, 10f)]
		public int MinPeopleToPullApparatus { get; private set; } = 2;


		[ConfigDesc("What enemies to exclude from spawning in the meltdown sequence. Comma seperated list. Supports modded entities.")]
		public string DisallowedEnemies { get; private set; } = "Centipede,Hoarding bug";


		[ConfigDesc("How long until the ship's scanner can scan the reactor. (Doesn't affect the vanilla `scan` command)")]
		[ConfigRange(0f, 20f)]
		public float ShipScanCooldown { get; private set; } = 15f;


		[ConfigDesc("How accurate is the ship's scanner when scanning the reactor. Higher values mean it is more uncertain, and lower values is more accurate. (Doesn't affect the vanilla `scan` command)")]
		[ConfigRange(0f, 100f)]
		public float ShipScanAccuracy { get; private set; } = 15f;


		[ConfigGroup("Integrations")]
		[ConfigDesc("Should the apparatus value be multiplied by the current weather. Requires WeatherRegistry to work.")]
		public bool WeatherRegistryIntegration { get; private set; } = true;


		[ConfigGroup("UNSUPPORTED")]
		[ConfigDesc("ABSOLUETLY NOT SUPPORTED OR RECOMMENDED! Change the length of the meltdown sequence. If this breaks I am not fixing it, you have been warned.")]
		[ConfigRange(60f, 300f)]
		public int MeltdownTime { get; private set; } = 120;


		public MeltdownConfig(ConfigFile file)
			: base(file)
		{
		}

		public List<string> GetDisallowedEnemies()
		{
			return DisallowedEnemies.Split(',').ToList();
		}
	}
}
namespace FacilityMeltdown.Behaviours
{
	public class MeltdownEvents : MonoBehaviour
	{
		[Serializable]
		public class Marker
		{
			internal bool Triggered;

			[field: SerializeField]
			public float Progress { get; private set; } = 0.5f;


			[field: SerializeField]
			public UnityEvent OnMarker { get; private set; }
		}

		[SerializeField]
		private UnityEvent OnMeltdownStart;

		[SerializeField]
		private List<Marker> markers = new List<Marker>();

		private void OnEnable()
		{
			MeltdownAPI.OnMeltdownStart = (Action)Delegate.Combine(MeltdownAPI.OnMeltdownStart, new Action(OnMeltdownStart.Invoke));
		}

		private void On