Decompiled source of Sunfly v1.31.0

FacilityMeltdown/FacilityMeltdown.dll

Decompiled 7 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
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 CSync.Lib;
using CSync.Util;
using FacilityMeltdown.API;
using FacilityMeltdown.Behaviours;
using FacilityMeltdown.Effects;
using FacilityMeltdown.Lang;
using FacilityMeltdown.NetcodePatcher;
using FacilityMeltdown.Networking;
using FacilityMeltdown.Util;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLib.Modules;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using TerminalApi;
using TerminalApi.Classes;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
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: AssemblyCompany("FacilityMeltdown")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6377373a5c8b6a0322a8dcae8c4369048457ffe5")]
[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]
internal class <Module>
{
	static <Module>()
	{
	}
}
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;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace FacilityMeltdown
{
	public class MeltdownHandler : NetworkBehaviour
	{
		private AudioSource musicSource;

		internal static MeltdownHandler Instance;

		internal float meltdownTimer;

		private bool meltdownStarted;

		private GameObject explosion;

		private List<MeltdownSequenceEffect> activeEffects = new List<MeltdownSequenceEffect>();

		private List<ulong> readyPlayers = new List<ulong>();

		private Vector3 effectOrigin;

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

		[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_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_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: 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 != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1281213092u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1281213092u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			meltdownTimer = SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value;
			MeltdownPlugin.logger.LogInfo((object)"Beginning Meltdown Sequence! I'd run if I was you!");
			musicSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			musicSource.clip = Assets.defaultMusic;
			musicSource.spatialBlend = 0f;
			musicSource.loop = false;
			musicSource.Play();
			((MonoBehaviour)this).StartCoroutine(PlayEffects());
			if (((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsServer)
			{
				List<string> disallowedEnemies = SyncedInstance<MeltdownConfig>.Instance.GetDisallowedEnemies();
				List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>();
				foreach (SpawnableEnemyWithRarity enemy in RoundManager.Instance.currentLevel.Enemies)
				{
					if (!disallowedEnemies.Contains(enemy.enemyType.enemyName))
					{
						list.Add(enemy);
					}
				}
				List<int> list2 = new List<int>();
				foreach (SpawnableEnemyWithRarity item in list)
				{
					if (!EnemyCannotBeSpawned(item.enemyType))
					{
						list2.Add(item.rarity);
					}
				}
				List<EnemyVent> list3 = new List<EnemyVent>();
				for (int i = 0; i < RoundManager.Instance.allEnemyVents.Length; i++)
				{
					if (!RoundManager.Instance.allEnemyVents[i].occupied)
					{
						list3.Add(RoundManager.Instance.allEnemyVents[i]);
					}
				}
				list3.Shuffle();
				for (int j = 0; j < Mathf.Min(SyncedInstance<MeltdownConfig>.Instance.MONSTER_SPAWN_AMOUNT.Value, list3.Count); j++)
				{
					EnemyVent vent = list3[j];
					RoundManager instance = RoundManager.Instance;
					List<int> list4 = list2;
					int num = 0;
					int[] array = new int[list4.Count];
					foreach (int item2 in list4)
					{
						array[num] = item2;
						num++;
					}
					int randomWeightedIndex = instance.GetRandomWeightedIndex(array, RoundManager.Instance.EnemySpawnRandom);
					if (!EnemyCannotBeSpawned(list[randomWeightedIndex].enemyType))
					{
						RoundManager instance2 = RoundManager.Instance;
						instance2.currentEnemyPower += list[randomWeightedIndex].enemyType.PowerLevel;
						MeltdownPlugin.logger.LogInfo((object)("Spawning a " + list[randomWeightedIndex].enemyType.enemyName + " during the meltdown sequence"));
						vent.SpawnEnemy(list[randomWeightedIndex]);
					}
				}
			}
			effectOrigin = RoundManager.FindMainEntrancePosition(false, true);
			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 (SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
			}
			meltdownStarted = true;
			IEnumerator PlayEffects()
			{
				foreach (MeltdownSequenceEffect effect in MeltdownSequenceEffect.effects)
				{
					((MonoBehaviour)this).StartCoroutine(PlayMeltdownSequenceEffect(effect));
					yield return (object)new WaitForSeconds(0.1f);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void MeltdownReadyServerRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3507553229u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3507553229u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				readyPlayers.Add(clientId);
				if (readyPlayers.Count == StartOfRound.Instance.GetConnectedPlayers().Count)
				{
					StartMeltdownClientRpc();
				}
			}
		}

		private void Start()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Instance = this;
			}
		}

		public override void OnNetworkSpawn()
		{
			MeltdownReadyServerRpc(((NetworkBehaviour)this).NetworkManager.LocalClientId);
		}

		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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value / 60f).ToString()),
					speakerText = "meltdown.dialogue.speaker".Translate()
				};
			}
			return array;
		}

		private void OnDisable()
		{
			Instance = null;
			if ((Object)(object)explosion != (Object)null)
			{
				Object.Destroy((Object)(object)explosion);
			}
			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.");
			}
			foreach (MeltdownSequenceEffect activeEffect in activeEffects)
			{
				try
				{
					activeEffect.Cleanup();
				}
				catch (Exception ex)
				{
					MeltdownPlugin.logger.LogError((object)(activeEffect.FullName + " produced a " + ex.GetType().Name + " during Cleanup(). Some objects may still be visible between moons.\n" + ex));
				}
			}
		}

		private IEnumerator PlayMeltdownSequenceEffect(MeltdownSequenceEffect effect)
		{
			yield return null;
			if (!effect.IsEnabledOnThisMoon(StartOfRound.Instance.currentLevel))
			{
				MeltdownPlugin.logger.LogInfo((object)(effect.Name + " will not be playing on this moon."));
				yield break;
			}
			try
			{
				effect.Setup();
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)(effect.FullName + " produced a " + ex.GetType().Name + " during Setup(). This error is fatal and the effect will not continue.\n" + ex));
				yield break;
			}
			if (!effect.IsOneShot && !effect.Playing)
			{
				MeltdownPlugin.logger.LogWarning((object)(effect.FullName + " is not playing and is not marked as one shot. By default it will play once. If you are not the dev please report this.If you are the dev, did you intend this effect to play once? Or play continously?If you meant to have it play once. Please overwrite .IsOneShot to be true.If you meant to have it play continously. Please call base.Setup() in your Setup function."));
			}
			if (effect.IsOneShot || !effect.Playing)
			{
				yield return ((MonoBehaviour)this).StartCoroutine(effect.Play(meltdownTimer));
			}
			else
			{
				while (!HasExplosionOccured() && effect.Playing)
				{
					yield return ((MonoBehaviour)this).StartCoroutine(effect.Play(meltdownTimer));
				}
			}
			yield return ((MonoBehaviour)this).StartCoroutine(effect.Stop());
		}

		private void Update()
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (meltdownStarted && !HasExplosionOccured())
			{
				StartOfRound instance = StartOfRound.Instance;
				musicSource.volume = SyncedInstance<MeltdownConfig>.Default.MUSIC_VOLUME.Value / 100f;
				if (!Player.isInsideFactory && !SyncedInstance<MeltdownConfig>.Default.MUSIC_PLAYS_OUTSIDE.Value)
				{
					musicSource.volume = 0f;
				}
				meltdownTimer -= Time.deltaTime;
				if (meltdownTimer <= 3f && !instance.shipIsLeaving)
				{
					((MonoBehaviour)this).StartCoroutine(ShipTakeOff());
				}
				if (meltdownTimer <= 0f)
				{
					musicSource.Stop();
					explosion = Object.Instantiate<GameObject>(Assets.facilityExplosionPrefab);
					explosion.transform.position = effectOrigin;
					explosion.AddComponent<FacilityExplosionHandler>();
				}
			}
		}

		private IEnumerator ShipTakeOff()
		{
			StartOfRound shipManager = StartOfRound.Instance;
			shipManager.shipLeftAutomatically = true;
			shipManager.shipIsLeaving = true;
			HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.shiptakeoff"));
			yield return (object)new WaitForSeconds(3f);
			yield return (object)new WaitForSeconds(3f);
			((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.ShipLeave();
			yield return (object)new WaitForSeconds(1.5f);
			shipManager.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null);
			if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
			{
				GameNetworkManager.Instance.localPlayerController.SetSpectatedPlayerEffects(true);
			}
			yield return (object)new WaitForSeconds(1f);
			Debug.Log((object)$"Is in elevator D?: {GameNetworkManager.Instance.localPlayerController.isInElevator}");
			yield return (object)new WaitForSeconds(9.5f);
		}

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

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_MeltdownHandler()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1281213092u, new RpcReceiveHandler(__rpc_handler_1281213092));
			NetworkManager.__rpc_func_table.Add(3507553229u, new RpcReceiveHandler(__rpc_handler_3507553229));
		}

		private static void __rpc_handler_1281213092(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)2;
				((MeltdownHandler)(object)target).StartMeltdownClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3507553229(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((MeltdownHandler)(object)target).MeltdownReadyServerRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "MeltdownHandler";
		}
	}
	[BepInPlugin("me.loaforc.facilitymeltdown", "FacilityMeltdown", "2.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[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.3.0";

		private readonly Harmony harmony = new Harmony("me.loaforc.facilitymeltdown");

		internal static MeltdownPlugin instance;

		internal static ManualLogSource logger;

		internal static MeltdownConfig meltdownConfig;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
				logger = Logger.CreateLogSource("me.loaforc.facilitymeltdown");
				logger.LogInfo((object)"Initalising assets...");
				Assets.Init();
				RegisterNetworking();
				logger.LogInfo((object)"Setting up language");
				LangParser.Init();
				logger.LogInfo((object)"Setting up config...");
				meltdownConfig = new MeltdownConfig(((BaseUnityPlugin)this).Config);
				logger.LogInfo((object)"Setting up language part 2..");
				LangParser.SetLanguage(SyncedInstance<MeltdownConfig>.Default.LANGUAGE.Value);
				logger.LogInfo((object)LangParser.GetTranslationSet("meltdown.dialogue.start"));
				RegisterPatches();
				RegisterEffects();
				logger.LogInfo((object)"Creating commands");
				TerminalHandler.Init();
				RegisterItems();
				logger.LogInfo((object)"FacilityMeltdown:2.3.0 has succesfully loaded!");
			}
		}

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

		private void RegisterNetworking()
		{
			logger.LogInfo((object)"Doing networky stuff");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				try
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
						if (customAttributes.Length != 0)
						{
							methodInfo.Invoke(null, null);
						}
					}
				}
				catch (Exception ex)
				{
					logger.LogWarning((object)("Caught exception: " + ex));
					logger.LogWarning((object)"================================");
					logger.LogWarning((object)"  NOT AN ERROR, PROBABLY A MISSING DEPENDENCY");
					logger.LogWarning((object)"================================");
				}
			}
			logger.LogInfo((object)"= Registering Network Prefabs");
		}

		private void RegisterPatches()
		{
			logger.LogInfo((object)"Applying patches.");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "me.loaforc.facilitymeltdown");
		}

		private void RegisterEffects()
		{
			logger.LogInfo((object)"Using own API to register sequence effects.");
			new EmergencyLightsEffect();
			new InsideFacilityParticleEffects();
			new ShockwaveSpawner();
			new WarningAnnouncerEffect();
			new RadiationIncreasingEffect();
			new IntroDialogueSequencer();
		}
	}
	internal class TerminalHandler
	{
		internal class ReactorHealthReport
		{
			public float reactorInstability;

			public float timeRemaining;

			public float generatedAt = Time.time;

			public string GetFlavourText()
			{
				if (timeRemaining / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value > 0.75f)
				{
					return "reactorscan.result.flavour.start";
				}
				if (timeRemaining / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value > 0.5f)
				{
					return "reactorscan.result.flavour.low";
				}
				if (timeRemaining / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value > 0.33f)
				{
					return "reactorscan.result.flavour.medium";
				}
				if (timeRemaining / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value > 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;

		internal static ReactorHealthReport lastReport;

		internal static AudioSource source;

		internal static string SubstituteVariables(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text);
			stringBuilder.Replace("<cooldown>", SyncedInstance<MeltdownConfig>.Instance.SCAN_COOLDOWN.Value.ToString());
			stringBuilder.Replace("<instability>", lastReport.reactorInstability.ToString());
			stringBuilder.Replace("<time_left>", lastReport.timeRemaining.ToString());
			return stringBuilder.ToString();
		}

		internal static bool ReactorHealthCheckReady()
		{
			return Time.time >= lastHealthCheck + SyncedInstance<MeltdownConfig>.Instance.SCAN_COOLDOWN.Value;
		}

		internal static ReactorHealthReport GetNewReactorHealthReport()
		{
			float num = ((float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value - MeltdownHandler.Instance.meltdownTimer) / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value * 100f;
			num = Mathf.Round(num / SyncedInstance<MeltdownConfig>.Instance.SCAN_ACCURACY.Value) * SyncedInstance<MeltdownConfig>.Instance.SCAN_ACCURACY.Value;
			float timeRemaining = (1f - num / 100f) * (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value;
			return new ReactorHealthReport
			{
				reactorInstability = num,
				timeRemaining = timeRemaining
			};
		}

		internal static void Init()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			TerminalNode val = TerminalApi.CreateTerminalNode("use >reactor health to check the current health of the reactor\n", true, "");
			TerminalKeyword val2 = TerminalApi.CreateTerminalKeyword("health", true, (TerminalNode)null);
			TerminalKeyword val3 = TerminalApi.CreateTerminalKeyword("reactor", false, (TerminalNode)null);
			TerminalApi.AddTerminalKeyword(val3.defaultVerb = TerminalExtenstionMethods.AddCompatibleNoun(val2, val3, val));
			TerminalApi.AddTerminalKeyword(val3, new CommandInfo
			{
				TriggerNode = val,
				DisplayTextSupplier = delegate
				{
					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();
				},
				Category = "Other",
				Description = "do actions with the reactor"
			});
		}
	}
	internal class Assets
	{
		internal static AssetBundle assetBundle;

		internal static AudioClip[] warnings;

		internal static AudioClip defaultMusic;

		internal static AudioClip shockwave;

		internal static AudioClip scannerStart;

		internal static GameObject facilityExplosionPrefab;

		internal static GameObject meltdownHandlerPrefab;

		internal static GameObject shockwavePrefab;

		internal static GameObject geigerCounterItem;

		internal static GameObject[] facilityEffects;

		internal static Item geigerCounterItemDef;

		internal static TerminalNode geigerCounterNode;

		public static void Init()
		{
			assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "facilitymeltdown"));
			warnings = (AudioClip[])(object)new AudioClip[4]
			{
				assetBundle.LoadAsset<AudioClip>("warning1.mp3"),
				assetBundle.LoadAsset<AudioClip>("warning2.mp3"),
				assetBundle.LoadAsset<AudioClip>("warning3.mp3"),
				assetBundle.LoadAsset<AudioClip>("warning4.mp3")
			};
			defaultMusic = assetBundle.LoadAsset<AudioClip>("music.mp3");
			shockwave = assetBundle.LoadAsset<AudioClip>("shockwave.mp3");
			scannerStart = assetBundle.LoadAsset<AudioClip>("scannerStart.mp3");
			facilityExplosionPrefab = assetBundle.LoadAsset<GameObject>("FacilityExplosion.prefab");
			meltdownHandlerPrefab = assetBundle.LoadAsset<GameObject>("MeltdownHandler.prefab");
			shockwavePrefab = assetBundle.LoadAsset<GameObject>("Shockwave.prefab");
			geigerCounterItem = assetBundle.LoadAsset<GameObject>("GeigerCounterItem.prefab");
			geigerCounterItemDef = assetBundle.LoadAsset<Item>("GeigerCounterItemDef.asset");
			geigerCounterNode = assetBundle.LoadAsset<TerminalNode>("GeigerCounterNode.asset");
			facilityEffects = (GameObject[])(object)new GameObject[2]
			{
				assetBundle.LoadAsset<GameObject>("Dust.prefab"),
				assetBundle.LoadAsset<GameObject>("Waterstream.prefab")
			};
		}
	}
	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_0022: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = vent.floorNode.position;
			float y = vent.floorNode.eulerAngles.y;
			RoundManager.Instance.SpawnEnemyOnServer(position, y, RoundManager.Instance.currentLevel.Enemies.IndexOf(enemy));
			MeltdownPlugin.logger.LogInfo((object)("Verifing... " + RoundManager.Instance.currentLevel.Enemies[RoundManager.Instance.currentLevel.Enemies.IndexOf(enemy)].enemyType.enemyName));
			vent.OpenVentClientRpc();
			vent.occupied = false;
		}

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

		internal static T GetFieldValue<T>(this object obj, string name)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			return (T)(obj.GetType().GetField(name, bindingAttr)?.GetValue(obj));
		}
	}
}
namespace FacilityMeltdown.Util
{
	[DataContract]
	internal class MeltdownConfig : SyncedInstance<MeltdownConfig>
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;
		}

		[DataMember]
		internal SyncedEntry<int> MONSTER_SPAWN_AMOUNT;

		[DataMember]
		internal SyncedEntry<int> APPARATUS_VALUE;

		[DataMember]
		internal SyncedEntry<int> MELTDOWN_TIME;

		[DataMember]
		internal SyncedEntry<bool> OVERRIDE_APPARATUS_VALUE;

		[DataMember]
		internal SyncedEntry<bool> EMERGENCY_LIGHTS;

		[DataMember]
		internal SyncedEntry<float> SCAN_COOLDOWN;

		[DataMember]
		internal SyncedEntry<float> SCAN_ACCURACY;

		[DataMember]
		internal SyncedEntry<string> DISALLOWED_ENEMIES;

		internal ConfigEntry<float> MUSIC_VOLUME;

		internal ConfigEntry<bool> SCREEN_SHAKE;

		internal ConfigEntry<bool> MUSIC_PLAYS_OUTSIDE;

		internal ConfigEntry<bool> PARTICLE_EFFECTS;

		internal ConfigEntry<string> LANGUAGE;

		internal List<string> GetDisallowedEnemies()
		{
			return DISALLOWED_ENEMIES.Value.Split(',').ToList();
		}

		internal MeltdownConfig(ConfigFile file)
		{
			base.InitInstance(this);
			OVERRIDE_APPARATUS_VALUE = Extensions.BindSyncedEntry<bool>(file, "GameBalance", "OverrideAppartusValue", true, "Whether or not FacilityMeltdown should override appartus value. Only use for compatibility reasons");
			APPARATUS_VALUE = Extensions.BindSyncedEntry<int>(file, "GameBalance", "AppartusValue", 240, "What the value of the appartus should be set as IF override appartus value is `true`");
			MONSTER_SPAWN_AMOUNT = Extensions.BindSyncedEntry<int>(file, "GameBalance", "MonsterSpawnAmount", 5, "How many monsters should spawn during the meltdown sequence? Set to 0 to disable.");
			EMERGENCY_LIGHTS = Extensions.BindSyncedEntry<bool>(file, "GameBalance", "EmergencyLights", true, "Should the lights turn on periodically? Disabling this option makes them permanently off. (Matches Vanilla Behaviour)");
			DISALLOWED_ENEMIES = Extensions.BindSyncedEntry<string>(file, "GameBalance", "DisallowedEnemies", "Centipede,Hoarding bug", "What enemies to exclude from spawning in the meltdown sequence. Comma seperated list. \"Should\" support modded entities");
			MELTDOWN_TIME = Extensions.BindSyncedEntry<int>(file, "GameBalance", "MeltdownTime", 120, "ABSOLUETLY NOT SUPPORTED OR RECOMMENDED! Change the length of the meltdown sequence. If this breaks I am not fixing it, you have been warned.");
			SCAN_COOLDOWN = Extensions.BindSyncedEntry<float>(file, "GameBalance", "ShipScannerCooldown", 15f, "How long until the ship's scanner can scan the reactor. (Doesn't affect the vanilla `scan` command)");
			SCAN_ACCURACY = Extensions.BindSyncedEntry<float>(file, "GameBalance", "ShipScannerAccuracy", 10f, "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)");
			MUSIC_VOLUME = file.Bind<float>("Audio", "MusicVolume", 100f, "What volume the music plays at. Should be between 0 and 100");
			MUSIC_PLAYS_OUTSIDE = file.Bind<bool>("Audio", "MusicPlaysOutside", true, "Does the music play outside the facility?");
			SCREEN_SHAKE = file.Bind<bool>("Visuals", "ScreenShake", true, "Whether or not to shake the screen during the meltdown sequence.");
			PARTICLE_EFFECTS = file.Bind<bool>("Visuals", "ParticleEffects", true, "Should meltdown sequence contain particle effects? Doesn't include particle effects on the fireball.");
			LANGUAGE = file.Bind<string>("Language", "ActiveLanguage", "en", "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));
			MeltdownPlugin.logger.LogInfo((object)"Checking for any mod settings managers...");
			if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
			{
				InitLethalConfig();
			}
			if (Chainloader.PluginInfos.ContainsKey("com.willis.lc.lethalsettings"))
			{
				InitLethalSettings();
			}
		}

		internal static void RequestSync()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<MeltdownConfig>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(ByteSerializer<MeltdownConfig>.IntSize, (Allocator)2, -1);
			try
			{
				Extensions.SendMessage(val, "me.loaforc.facilitymeltdown_OnRequestConfigSync", 0uL);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		internal static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<MeltdownConfig>.IsHost)
			{
				return;
			}
			byte[] array = ByteSerializer<MeltdownConfig>.SerializeToBytes(SyncedInstance<MeltdownConfig>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + ByteSerializer<MeltdownConfig>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				Extensions.SendMessage(val, "me.loaforc.facilitymeltdown_OnReceiveConfigSync", clientId);
			}
			catch (Exception arg)
			{
				MeltdownPlugin.logger.LogError((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		internal static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(ByteSerializer<MeltdownConfig>.IntSize))
			{
				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[] array = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref array, num, 0);
			try
			{
				SyncedInstance<MeltdownConfig>.SyncInstance(array);
				MeltdownPlugin.logger.LogInfo((object)("test sync value: " + SyncedInstance<MeltdownConfig>.Instance.APPARATUS_VALUE.Value));
			}
			catch (Exception arg)
			{
				MeltdownPlugin.logger.LogError((object)$"Error syncing config instance!\n{arg}");
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal void InitLethalConfig()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_006e: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			MeltdownPlugin.logger.LogInfo((object)"Setting up LethalConfig settings");
			LethalConfigManager.SetModDescription("Maybe taking the appartus isn't such a great idea...");
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(OVERRIDE_APPARATUS_VALUE.Entry, true));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(APPARATUS_VALUE.Entry, new IntSliderOptions
			{
				Min = 80,
				Max = 500,
				RequiresRestart = true
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(MONSTER_SPAWN_AMOUNT.Entry, new IntSliderOptions
			{
				Min = 0,
				Max = 10,
				RequiresRestart = true
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(EMERGENCY_LIGHTS.Entry, true));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(SCAN_COOLDOWN.Entry, new FloatSliderOptions
			{
				Min = 0f,
				Max = 30f,
				RequiresRestart = true
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatStepSliderConfigItem(SCAN_ACCURACY.Entry, new FloatStepSliderOptions
			{
				Min = 0f,
				Step = 1f,
				Max = 50f,
				RequiresRestart = true
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(MELTDOWN_TIME.Entry, new IntSliderOptions
			{
				Min = 0,
				Max = 300,
				RequiresRestart = true
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatStepSliderConfigItem(MUSIC_VOLUME, new FloatStepSliderOptions
			{
				Min = 0f,
				Max = 100f,
				Step = 1f,
				RequiresRestart = false
			}));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(MUSIC_PLAYS_OUTSIDE, false));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(SCREEN_SHAKE, false));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(PARTICLE_EFFECTS, false));
			LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(LANGUAGE, true));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal void InitLethalSettings()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Expected O, but got Unknown
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Expected O, but got Unknown
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Expected O, but got Unknown
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Expected O, but got Unknown
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Expected O, but got Unknown
			SliderComponent appratusValueSlider = new SliderComponent
			{
				Value = SyncedInstance<MeltdownConfig>.Default.APPARATUS_VALUE.Value,
				MinValue = 80f,
				MaxValue = 500f,
				WholeNumbers = true,
				Text = "Appartus Value",
				Enabled = OVERRIDE_APPARATUS_VALUE.Value,
				OnValueChanged = delegate(SliderComponent self, float value)
				{
					SyncedInstance<MeltdownConfig>.Default.APPARATUS_VALUE.Value = (int)value;
				}
			};
			VerticalComponent val = new VerticalComponent();
			val.Children = (MenuComponent[])(object)new MenuComponent[8]
			{
				(MenuComponent)new LabelComponent
				{
					Text = "Audio Settings [Client Side]"
				},
				(MenuComponent)new SliderComponent
				{
					Value = SyncedInstance<MeltdownConfig>.Default.MUSIC_VOLUME.Value,
					MinValue = 0f,
					MaxValue = 100f,
					WholeNumbers = true,
					Text = "Music Volume",
					OnValueChanged = delegate(SliderComponent self, float value)
					{
						SyncedInstance<MeltdownConfig>.Default.MUSIC_VOLUME.Value = (int)value;
					}
				},
				(MenuComponent)new ToggleComponent
				{
					Text = "Play Music Outside?",
					Value = SyncedInstance<MeltdownConfig>.Default.MUSIC_PLAYS_OUTSIDE.Value,
					OnValueChanged = delegate(ToggleComponent self, bool value)
					{
						SyncedInstance<MeltdownConfig>.Default.MUSIC_PLAYS_OUTSIDE.Value = value;
					}
				},
				(MenuComponent)new LabelComponent
				{
					Text = "Visual Settings [Client Side]"
				},
				(MenuComponent)new ToggleComponent
				{
					Text = "Screen Shake",
					Value = SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value,
					OnValueChanged = delegate(ToggleComponent self, bool value)
					{
						SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value = value;
					}
				},
				(MenuComponent)new ToggleComponent
				{
					Text = "Particle Effects",
					Value = SyncedInstance<MeltdownConfig>.Default.PARTICLE_EFFECTS.Value,
					OnValueChanged = delegate(ToggleComponent self, bool value)
					{
						SyncedInstance<MeltdownConfig>.Default.PARTICLE_EFFECTS.Value = value;
					}
				},
				(MenuComponent)new LabelComponent
				{
					Text = "Language Settings [Client Side]"
				},
				(MenuComponent)new DropdownComponent
				{
					Text = "Language",
					Value = new OptionData(LangParser.languages[LANGUAGE.Value]),
					Options = ((IEnumerable<string>)LangParser.languages.Values).Select((Func<string, OptionData>)((string language) => new OptionData(language))).ToList(),
					OnValueChanged = delegate(DropdownComponent self, OptionData value)
					{
						OptionData value2 = value;
						string text = (from x in LangParser.languages
							where x.Value == value2.text
							select x.Key).FirstOrDefault();
						if (text == null)
						{
							MeltdownPlugin.logger.LogError((object)"Failed to get language! defaulting to english");
							text = "en";
						}
						LANGUAGE.Value = text;
						LangParser.SetLanguage(text);
					}
				}
			};
			VerticalComponent val2 = val;
			ModSettingsConfig val3 = new ModSettingsConfig();
			val3.Name = "FacilityMeltdown";
			val3.Id = "me.loaforc.facilitymeltdown";
			val3.Version = "2.3.0";
			val3.Description = "Maybe taking the appartus isn't such a great idea...";
			val3.MenuComponents = (MenuComponent[])(object)new MenuComponent[8]
			{
				(MenuComponent)new LabelComponent
				{
					Text = "Game Balance Settings [Synced]"
				},
				(MenuComponent)new ToggleComponent
				{
					Text = "Override Appartus Value?",
					Value = SyncedInstance<MeltdownConfig>.Default.OVERRIDE_APPARATUS_VALUE.Value,
					OnValueChanged = delegate(ToggleComponent self, bool value)
					{
						SyncedInstance<MeltdownConfig>.Default.OVERRIDE_APPARATUS_VALUE.Value = value;
						appratusValueSlider.Enabled = value;
					}
				},
				(MenuComponent)appratusValueSlider,
				(MenuComponent)new SliderComponent
				{
					Value = SyncedInstance<MeltdownConfig>.Default.MONSTER_SPAWN_AMOUNT.Value,
					MinValue = 0f,
					MaxValue = 10f,
					WholeNumbers = true,
					Text = "Monster Spawn Amount",
					OnValueChanged = delegate(SliderComponent self, float value)
					{
						SyncedInstance<MeltdownConfig>.Default.MONSTER_SPAWN_AMOUNT.Value = (int)value;
					}
				},
				(MenuComponent)new ToggleComponent
				{
					Text = "Facility has Emergency Lights?",
					Value = SyncedInstance<MeltdownConfig>.Default.EMERGENCY_LIGHTS.Value,
					OnValueChanged = delegate(ToggleComponent self, bool value)
					{
						SyncedInstance<MeltdownConfig>.Default.EMERGENCY_LIGHTS.Value = value;
					}
				},
				(MenuComponent)new SliderComponent
				{
					Value = SyncedInstance<MeltdownConfig>.Default.APPARATUS_VALUE.Value,
					MinValue = 0f,
					MaxValue = 600f,
					WholeNumbers = true,
					Text = "Meltdown Sequence Time [NOT SUPPORTED, EDIT AT YOUR OWN RISK, NOT RECOMMENDED]",
					Enabled = SyncedInstance<MeltdownConfig>.Default.OVERRIDE_APPARATUS_VALUE.Value,
					OnValueChanged = delegate(SliderComponent self, float value)
					{
						SyncedInstance<MeltdownConfig>.Default.MELTDOWN_TIME.Value = (int)value;
					}
				},
				(MenuComponent)new LabelComponent
				{
					Text = "Edit what enemies can spawn in the config file."
				},
				(MenuComponent)val2
			};
			ModMenu.RegisterMod(val3);
			val3 = new ModSettingsConfig();
			val3.Name = "FacilityMeltdown";
			val3.Id = "me.loaforc.facilitymeltdown";
			val3.Version = "2.3.0";
			val3.Description = "Maybe taking the appartus isn't such a great idea... (GameSettings are hidden in game)";
			val3.MenuComponents = (MenuComponent[])(object)new MenuComponent[1] { (MenuComponent)val2 };
			ModMenu.RegisterMod(val3, false, true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (SyncedInstance<MeltdownConfig>.IsHost)
			{
				CustomMessagingManager messageManager = SyncedInstance<MeltdownConfig>.MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("me.loaforc.facilitymeltdown_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				SyncedInstance<MeltdownConfig>.Synced = true;
				return;
			}
			SyncedInstance<MeltdownConfig>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<MeltdownConfig>.MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("me.loaforc.facilitymeltdown_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<MeltdownConfig>.RevertSync();
		}
	}
}
namespace FacilityMeltdown.Patches
{
	[HarmonyPatch(typeof(LungProp))]
	internal class ApparaticePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EquipItem")]
		internal static void BeginMeltdownSequence(LungProp __instance, ref bool ___isLungDocked)
		{
			if (!((NetworkBehaviour)__instance).IsHost || !___isLungDocked)
			{
				return;
			}
			try
			{
				if (SyncedInstance<MeltdownConfig>.Instance.OVERRIDE_APPARATUS_VALUE.Value)
				{
					((GrabbableObject)__instance).scrapValue = SyncedInstance<MeltdownConfig>.Instance.APPARATUS_VALUE.Value;
				}
				GameObject val = Object.Instantiate<GameObject>(Assets.meltdownHandlerPrefab);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
			catch (Exception ex)
			{
				MeltdownPlugin.logger.LogError((object)ex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void AddRadiationSource(LungProp __instance)
		{
			try
			{
				RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
				radiationSource.radiationAmount = 40f;
				radiationSource.radiationDistance = 40f;
				if (SyncedInstance<MeltdownConfig>.Instance.OVERRIDE_APPARATUS_VALUE.Value)
				{
					((GrabbableObject)__instance).scrapValue = SyncedInstance<MeltdownConfig>.Instance.APPARATUS_VALUE.Value;
				}
			}
			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 = 10f;
			radiationSource.radiationDistance = 15f;
		}
	}
	[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
	{
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		internal static void RegisterPrefabs()
		{
			NetworkManager.Singleton.AddNetworkPrefab(Assets.meltdownHandlerPrefab);
			NetworkManager.Singleton.AddNetworkPrefab(Assets.geigerCounterItem);
		}
	}
	[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);
			}
		}
	}
}
namespace FacilityMeltdown.Networking
{
	public abstract class SaveableNetworkBehaviour : NetworkBehaviour
	{
		public int uniqueId;

		public abstract void SaveObjectData();

		public abstract void LoadObjectData();

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

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "SaveableNetworkBehaviour";
		}
	}
}
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 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 void SetLanguage(string id)
		{
			MeltdownPlugin.logger.LogInfo((object)("Loading language: " + languages[id] + " (" + id + ")"));
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FacilityMeltdown.Lang." + id + ".json");
			using StreamReader streamReader = new StreamReader(stream);
			string text = streamReader.ReadToEnd();
			loadedLanguage = JsonConvert.DeserializeObject<Dictionary<string, object>>(text);
			MeltdownPlugin.logger.LogInfo((object)("Loaded " + languages[id]));
		}

		internal static string GetTranslation(string translation)
		{
			if (loadedLanguage.TryGetValue(translation, out var value))
			{
				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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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);
			}
			JArray val = new JArray();
			val.Add(JToken.op_Implicit(GetTranslation("lang.missing").Replace("<translation_id>", translation)));
			return val;
		}
	}
}
namespace FacilityMeltdown.Effects
{
	internal class EmergencyLightsEffect : MeltdownSequenceEffect
	{
		public EmergencyLightsEffect()
			: base("me.loaforc.facilitymeltdown", "EmergencyLights")
		{
		}

		public override void Setup()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			base.Setup();
			for (int i = 0; i < RoundManager.Instance.allPoweredLights.Count; i++)
			{
				RoundManager.Instance.allPoweredLights[i].color = Color.red;
			}
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			for (int i = 0; i < RoundManager.Instance.allPoweredLightsAnimators.Count; i++)
			{
				RoundManager.Instance.allPoweredLightsAnimators[i].SetBool("on", true);
			}
			yield return (object)new WaitForSeconds(2f);
			for (int j = 0; j < RoundManager.Instance.allPoweredLightsAnimators.Count; j++)
			{
				RoundManager.Instance.allPoweredLightsAnimators[j].SetBool("on", false);
			}
			yield return (object)new WaitForSeconds(5f);
		}

		public override bool IsEnabledOnThisMoon(SelectableLevel level)
		{
			return SyncedInstance<MeltdownConfig>.Instance.EMERGENCY_LIGHTS.Value;
		}
	}
	internal class InsideFacilityParticleEffects : MeltdownSequenceEffect
	{
		public InsideFacilityParticleEffects()
			: base("me.loaforc.facilitymeltdown", "InsideFacilityEffects")
		{
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			if (SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
			{
				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 = Assets.facilityEffects[Random.Range(0, Assets.facilityEffects.Length)];
						GameObject val4 = Object.Instantiate<GameObject>(val3);
						val3.transform.position = ((RaycastHit)(ref val2)).point;
						val4.transform.parent = base.gameObject.transform;
					}
					MeltdownPlugin.logger.LogWarning((object)"Failed to spawn effect, raycast failed.");
				}
			}
			if (base.player.isInsideFactory)
			{
				Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, GetRandomPositionNearPlayer(), Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform);
			}
			if (SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
			{
				if (timeLeftUntilMeltdown > 60f)
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
				}
				else
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				}
			}
			float meltdownProgress = GetMeltdownProgress(timeLeftUntilMeltdown);
			if ((double)meltdownProgress > 0.75)
			{
				yield return (object)new WaitForSeconds(Random.Range(10f, 14f));
			}
			else if ((double)meltdownProgress > 0.5)
			{
				yield return (object)new WaitForSeconds(Random.Range(6f, 10f));
			}
			else if ((double)meltdownProgress > 0.25)
			{
				yield return (object)new WaitForSeconds(Random.Range(5f, 6.5f));
			}
			else
			{
				yield return (object)new WaitForSeconds(Random.Range(3f, 4f));
			}
		}

		public override void Cleanup()
		{
			for (int num = base.gameObject.transform.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)base.gameObject.transform.GetChild(num)).gameObject);
			}
			base.Cleanup();
		}
	}
	internal class IntroDialogueSequencer : MeltdownSequenceEffect
	{
		public IntroDialogueSequencer()
			: base("me.loaforc.facilitymeltdown", "IntroDialogueSequencer")
		{
			base.IsOneShot = true;
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			yield return (object)new WaitForSeconds(5f);
			HUDManager.Instance.ReadDialogue(MeltdownHandler.GetDialogue("meltdown.dialogue.start"));
		}
	}
	internal class RadiationIncreasingEffect : MeltdownSequenceEffect
	{
		private bool radiationHudWarning;

		private RadiationSource source;

		public RadiationIncreasingEffect()
			: base("me.loaforc.facilitymeltdown", "RadiationIncreasing")
		{
		}

		public override void Setup()
		{
			base.Setup();
			radiationHudWarning = false;
			source = base.gameObject.AddComponent<RadiationSource>();
			source.isGlobal = true;
			source.radiationAmount = 0f;
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			if ((double)GetMeltdownProgress(timeLeftUntilMeltdown) <= 0.5 && !radiationHudWarning)
			{
				HUDManager.Instance.RadiationWarningHUD();
				radiationHudWarning = true;
			}
			source.radiationAmount = GetMeltdownProgress(timeLeftUntilMeltdown) * 100f;
			yield return (object)new WaitForSeconds(1f);
		}
	}
	internal class ShockwaveSpawner : MeltdownSequenceEffect
	{
		private GameObject shockwave;

		public ShockwaveSpawner()
			: base("me.loaforc.facilitymeltdown", "ShockwaveSpawner")
		{
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			if ((Object)(object)shockwave != (Object)null)
			{
				Object.Destroy((Object)(object)shockwave);
			}
			shockwave = Object.Instantiate<GameObject>(Assets.shockwavePrefab);
			shockwave.transform.position = base.mainEntrancePosition;
			shockwave.AddComponent<Shockwave>();
			yield return (object)new WaitForSeconds(Random.Range(20f, 30f));
		}

		public override void Cleanup()
		{
			base.Cleanup();
			Object.Destroy((Object)(object)shockwave);
		}
	}
	internal class WarningAnnouncerEffect : MeltdownSequenceEffect
	{
		private AudioSource warningAudioSource;

		public WarningAnnouncerEffect()
			: base("me.loaforc.facilitymeltdown", "WarningAnnouncer")
		{
		}

		public override void Setup()
		{
			base.Setup();
			warningAudioSource = base.gameObject.AddComponent<AudioSource>();
			warningAudioSource.loop = false;
			warningAudioSource.spatialBlend = 0f;
		}

		public override IEnumerator Play(float timeLeftUntilMeltdown)
		{
			yield return (object)new WaitForSeconds(Random.Range(2f, 4f));
			warningAudioSource.volume = SyncedInstance<MeltdownConfig>.Default.MUSIC_VOLUME.Value;
			AudioClip clip = Assets.warnings[Random.Range(0, Assets.warnings.Length)];
			warningAudioSource.clip = clip;
			warningAudioSource.Play();
			yield return (object)new WaitForSeconds(warningAudioSource.clip.length);
			float meltdownProgress = GetMeltdownProgress(timeLeftUntilMeltdown);
			if ((double)meltdownProgress > 0.75)
			{
				yield return (object)new WaitForSeconds(Random.Range(5f, 10f));
			}
			else if ((double)meltdownProgress > 0.5)
			{
				yield return (object)new WaitForSeconds(Random.Range(4f, 8f));
			}
			else if ((double)meltdownProgress > 0.25)
			{
				yield return (object)new WaitForSeconds(Random.Range(3f, 6f));
			}
			else
			{
				yield return (object)new WaitForSeconds(Random.Range(2f, 4f));
			}
		}

		public override IEnumerator Stop()
		{
			warningAudioSource.Stop();
			yield return null;
		}
	}
}
namespace FacilityMeltdown.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 (SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
			{
				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)
			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);
			}
		}

		private void KillPlayer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0);
		}

		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 GeigerCounterItem : SaveableObject
	{
		[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 LoadObjectData()
		{
		}

		public override void SaveObjectData()
		{
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			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)
		{
			((GrabbableObject)this).isBeingUsed = !((GrabbableObject)this).isBeingUsed;
			MeltdownPlugin.logger.LogInfo((object)$"me when the on value is {on}. :rofl::rofl::rofl:");
			if (((GrabbableObject)this).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_00e0: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (((GrabbableObject)this).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;
				num2 *= -1f;
				needle.transform.localEulerAngles = new Vector3(0f, num2, 0f);
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "GeigerCounterItem";
		}
	}
	public class RadiationSource : MonoBehaviour
	{
		[HideInInspector]
		public static List<RadiationSource> radiators = new List<RadiationSource>();

		[Range(0f, 100f)]
		public float radiationAmount = 70f;

		public bool isGlobal;

		[Range(0f, 100f)]
		public float radiationDistance = 50f;

		[Header("Decay Settings")]
		public bool doesDecay;

		[Range(0f, 120f)]
		public float decayTime = 120f;

		public AnimationCurve radiationOutputVsDecay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 1f),
			new Keyframe(0f, 1f)
		});

		private float existingTime;

		public static float CollectRadiationFromPoint(Vector3 point)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (RadiationSource radiator in radiators)
			{
				num += radiator.GetRadiationFromPoint(point);
			}
			return num;
		}

		public float GetRadiationAtDistance(float distance)
		{
			if (distance > radiationDistance)
			{
				return 0f;
			}
			float num = Mathf.Clamp01((radiationDistance - distance) / radiationDistance);
			if (isGlobal)
			{
				num = 1f;
			}
			return num * radiationAmount * GetDecayReduction();
		}

		public float GetDecayProgress()
		{
			if (!doesDecay)
			{
				return 0f;
			}
			return Mathf.Clamp01(existingTime / decayTime);
		}

		public float GetDecayReduction()
		{
			if (!doesDecay)
			{
				return 1f;
			}
			return radiationOutputVsDecay.Evaluate(GetDecayProgress());
		}

		public float GetRadiationFromPoint(Vector3 point)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return GetRadiationAtDistance(Vector3.Distance(((Component)this).transform.position, point));
		}

		private void OnEnable()
		{
			radiators.Add(this);
			MeltdownPlugin.logger.LogInfo((object)$"A new RadiationSource was created, there is now: {radiators.Count} radiators.");
		}

		private void OnDisable()
		{
			radiators.Remove(this);
		}

		private void Update()
		{
			existingTime += Time.deltaTime;
		}
	}
	public abstract class SaveableObject : GrabbableObject
	{
		public int uniqueId;

		public override void LoadItemSaveData(int saveData)
		{
			((GrabbableObject)this).LoadItemSaveData(saveData);
			uniqueId = saveData;
		}

		public override int GetItemDataToSave()
		{
			return uniqueId;
		}

		public virtual void Awake()
		{
			if (((NetworkBehaviour)this).IsHost)
			{
				uniqueId = Random.Range(0, 1000000);
				SaveableNetworkBehaviour[] componentsInChildren = ((Component)((Component)this).transform).GetComponentsInChildren<SaveableNetworkBehaviour>();
				SaveableNetworkBehaviour[] array = componentsInChildren;
				foreach (SaveableNetworkBehaviour saveableNetworkBehaviour in array)
				{
					saveableNetworkBehaviour.uniqueId = uniqueId;
				}
			}
		}

		public abstract void SaveObjectData();

		public abstract void LoadObjectData();

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

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "SaveableObject";
		}
	}
	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 = 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 && SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
			{
				if (SyncedInstance<MeltdownConfig>.Default.SCREEN_SHAKE.Value)
				{
					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.API
{
	public static class MeltdownMusicManager
	{
		public static readonly Func<SelectableLevel, AudioClip> MusicResolver = (SelectableLevel __) => null;

		public static AudioClip GetMusic(SelectableLevel level)
		{
			List<AudioClip> list = new List<AudioClip>();
			Delegate[] invocationList = MusicResolver.GetInvocationList();
			for (int i = 0; i < invocationList.Length; i++)
			{
				Func<SelectableLevel, AudioClip> func = (Func<SelectableLevel, AudioClip>)invocationList[i];
				AudioClip val = func(level);
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
			if (list.Count == 0)
			{
				return Assets.defaultMusic;
			}
			return list[Random.Range(0, list.Count)];
		}
	}
	public abstract class MeltdownSequenceEffect
	{
		public static List<MeltdownSequenceEffect> effects = new List<MeltdownSequenceEffect>();

		protected PlayerControllerB player => GameNetworkManager.Instance.localPlayerController;

		protected Vector3 mainEntrancePosition { get; private set; }

		public bool Playing { get; protected set; }

		public bool IsOneShot { get; protected set; }

		public string Name { get; private set; }

		public string ModGUID { get; private set; }

		public string FullName { get; private set; }

		public GameObject gameObject { get; private set; }

		public MeltdownSequenceEffect(string modGUID, string name)
		{
			Name = name;
			ModGUID = modGUID;
			FullName = modGUID + "." + name;
			effects.Add(this);
		}

		public virtual void Setup()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Playing = true;
			gameObject = new GameObject(Name + "Handler");
			mainEntrancePosition = RoundManager.FindMainEntrancePosition(false, true);
		}

		public virtual IEnumerator Play(float timeLeftUntilMeltdown)
		{
			yield return null;
		}

		public virtual IEnumerator Stop()
		{
			yield return null;
		}

		public virtual void Cleanup()
		{
			Object.Destroy((Object)(object)gameObject);
		}

		public virtual bool IsEnabledOnThisMoon(SelectableLevel level)
		{
			return true;
		}

		protected float GetMeltdownProgress(float time)
		{
			return 1f - time / (float)SyncedInstance<MeltdownConfig>.Instance.MELTDOWN_TIME.Value;
		}

		protected Vector3 PlacePositionInsideFacility(Vector3 position, float radius = 10f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			RoundManager instance = RoundManager.Instance;
			Random random = new Random();
			return instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), random, -1);
		}

		protected Vector3 GetRandomPositionNearPlayer(float radius = 15f)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			return PlacePositionInsideFacility(((Component)player).transform.position + Random.insideUnitSphere * radius);
		}

		protected Vector3 GetRandomPositionInsideFacility()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			return PlacePositionInsideFacility(RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position);
		}
	}
}
namespace FacilityMeltdown.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}