Decompiled source of NotForBroadcast v1.1.1

BepInEx\plugins\NotForBroadcast\NotForBroadcast.dll

Decompiled 2 hours 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.Versioning;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using REPOLib.Modules;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Networking;
using UnityEngine.UI;

[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("NotForBroadcast")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NotForBroadcast")]
[assembly: AssemblyTitle("NotForBroadcast")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 NotForBroadcast
{
	internal static class GameAccess
	{
		private static readonly Dictionary<string, FieldInfo> Fields = new Dictionary<string, FieldInfo>();

		internal static T GetField<T>(object instance, string fieldName, T fallback = default(T))
		{
			if (instance == null)
			{
				return fallback;
			}
			try
			{
				return (GetField(instance.GetType(), fieldName)?.GetValue(instance) is T val) ? val : fallback;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not read " + instance.GetType().Name + "." + fieldName + ": " + ex.Message));
				return fallback;
			}
		}

		internal static bool SetField(object instance, string fieldName, object value)
		{
			if (instance == null)
			{
				return false;
			}
			try
			{
				FieldInfo field = GetField(instance.GetType(), fieldName);
				if (field == null)
				{
					return false;
				}
				field.SetValue(instance, value);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not write " + instance.GetType().Name + "." + fieldName + ": " + ex.Message));
				return false;
			}
		}

		private static FieldInfo GetField(Type type, string fieldName)
		{
			string key = type.FullName + ":" + fieldName;
			if (!Fields.TryGetValue(key, out var value))
			{
				value = AccessTools.Field(type, fieldName);
				Fields[key] = value;
			}
			return value;
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "StateSuccess")]
	internal static class ExtractionPointStateSuccessPatch
	{
		private static void Postfix(ExtractionPoint __instance)
		{
			Plugin.Controller?.TryBeginIntro(__instance);
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "StateExtracting")]
	internal static class ExtractionPointStateExtractingPatch
	{
		private static void Postfix(ExtractionPoint __instance)
		{
			Plugin.Controller?.TryBeginEscape(__instance);
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "StateSet")]
	internal static class ExtractionPointStateSetPatch
	{
		private static void Prefix(ExtractionPoint __instance, State __0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)__0 == 5)
			{
				Plugin.Controller?.NotifyExtractionCancelled(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "GenerateDone")]
	internal static class LevelGeneratorDonePatch
	{
		private static void Postfix()
		{
			Plugin.Controller?.ResetForLevel();
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	internal static class RunManagerChangeLevelPatch
	{
		private static void Prefix()
		{
			Plugin.Controller?.StopForLevelEnd();
		}
	}
	[HarmonyPatch(typeof(TruckDoor), "Update")]
	internal static class TruckDoorUpdatePatch
	{
		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Controller == (Object)null))
			{
				return !Plugin.Controller.ShouldHoldTruckDoor;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TruckHealer), "Update")]
	internal static class TruckHealerUpdatePatch
	{
		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Controller == (Object)null))
			{
				return !Plugin.Controller.ShouldDisableTruckHealer;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TruckScreenText), "GotoNextLevel")]
	internal static class TruckScreenTextGotoNextLevelPatch
	{
		private static bool Prefix(TruckScreenText __instance)
		{
			if (!((Object)(object)Plugin.Controller == (Object)null))
			{
				return Plugin.Controller.HandleTruckDeparture(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(AmbienceBreakers), "PlaySoundRPC")]
	internal static class AmbienceBreakersPlaySoundPatch
	{
		private static bool Prefix()
		{
			if (!((Object)(object)Plugin.Controller == (Object)null))
			{
				return !Plugin.Controller.EventActive;
			}
			return true;
		}
	}
	public sealed class NotForBroadcastBattery : MonoBehaviour
	{
		private static GameObject _template;

		private Vector3 _basePosition;

		private bool _requested;

		private float _requestRetryTimer;

		internal Vector3 SpawnPosition => _basePosition;

		internal static void RegisterPrefab()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_001e: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			if (!((Object)(object)_template != (Object)null))
			{
				GameObject val = new GameObject("Not For Broadcast Truck Battery Template");
				Object.DontDestroyOnLoad((Object)val);
				val.transform.position = new Vector3(0f, -5000f, 0f);
				Rigidbody obj = val.AddComponent<Rigidbody>();
				obj.isKinematic = true;
				obj.useGravity = false;
				BoxCollider obj2 = val.AddComponent<BoxCollider>();
				((Collider)obj2).isTrigger = true;
				obj2.size = new Vector3(1.8f, 2.2f, 1.2f);
				obj2.center = new Vector3(0f, 0.6f, 0f);
				val.AddComponent<NotForBroadcastBattery>();
				BuildVisuals(val.transform);
				val.SetActive(false);
				_template = val;
			}
		}

		private static void BuildVisuals(Transform parent)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0153: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			Material material = CreateMaterial(new Color(0.025f, 0.03f, 0.035f), new Color(0f, 0f, 0f));
			Material material2 = CreateMaterial(new Color(0.38f, 0.11f, 0.015f), new Color(1f, 0.18f, 0.01f) * 1.5f);
			Material material3 = CreateMaterial(new Color(0.015f, 0.2f, 0.04f), new Color(0.05f, 1f, 0.12f) * 2f);
			CreatePart(parent, (PrimitiveType)3, "Battery Body", new Vector3(0f, 0.6f, 0f), new Vector3(1.25f, 1.55f, 0.72f), material);
			CreatePart(parent, (PrimitiveType)3, "Battery Stripe", new Vector3(0f, 0.62f, -0.38f), new Vector3(0.92f, 0.22f, 0.05f), material2);
			CreatePart(parent, (PrimitiveType)2, "Positive Terminal", new Vector3(-0.34f, 1.48f, 0f), new Vector3(0.16f, 0.11f, 0.16f), material2);
			CreatePart(parent, (PrimitiveType)2, "Negative Terminal", new Vector3(0.34f, 1.48f, 0f), new Vector3(0.16f, 0.11f, 0.16f), material2);
			CreatePart(parent, (PrimitiveType)3, "Power Indicator", new Vector3(0f, 0.98f, -0.39f), new Vector3(0.25f, 0.13f, 0.055f), material3);
			GameObject val = new GameObject("Battery Light");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = new Vector3(0f, 1f, -0.5f);
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(0.05f, 1f, 0.15f);
			obj.intensity = 1.8f;
			obj.range = 4.5f;
		}

		private static void CreatePart(Transform parent, PrimitiveType type, string name, Vector3 position, Vector3 scale, Material material)
		{
			//IL_0000: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = position;
			obj.transform.localScale = scale;
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			obj.GetComponent<Renderer>().material = material;
		}

		private static Material CreateMaterial(Color color, Color emission)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default"));
			val.color = color;
			if (val.HasProperty("_BaseColor"))
			{
				val.SetColor("_BaseColor", color);
			}
			if (val.HasProperty("_EmissionColor"))
			{
				val.EnableKeyword("_EMISSION");
				val.SetColor("_EmissionColor", emission);
			}
			return val;
		}

		internal static NotForBroadcastBattery SpawnLocal(Vector3 position)
		{
			//IL_0028: 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)
			RegisterPrefab();
			if ((Object)(object)_template == (Object)null)
			{
				Plugin.Log.LogError((object)"The local truck battery template could not be created.");
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(_template, position, Quaternion.identity);
			((Object)obj).name = "Not For Broadcast Truck Battery";
			obj.SetActive(true);
			return obj.GetComponent<NotForBroadcastBattery>();
		}

		private void OnEnable()
		{
			//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)
			_basePosition = ((Component)this).transform.position;
			_requested = false;
			_requestRetryTimer = 0f;
			NotForBroadcastController.RegisterBattery(this);
		}

		private void OnDisable()
		{
			NotForBroadcastController.UnregisterBattery(this);
		}

		private void Update()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.Rotate(0f, 45f * Time.deltaTime, 0f, (Space)0);
			((Component)this).transform.position = _basePosition + Vector3.up * (Mathf.Sin(Time.time * 2.5f) * 0.12f);
			if (_requested)
			{
				_requestRetryTimer -= Time.deltaTime;
				if (_requestRetryTimer <= 0f)
				{
					_requested = false;
				}
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!_requested && !((Object)(object)Plugin.Controller == (Object)null) && Plugin.Controller.EventActive)
			{
				PlayerAvatar componentInParent = ((Component)other).GetComponentInParent<PlayerAvatar>();
				if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent != (Object)(object)SemiFunc.PlayerGetLocal()))
				{
					_requested = true;
					_requestRetryTimer = 2f;
					Plugin.Controller.RequestBatteryCollection(_basePosition);
				}
			}
		}
	}
	public sealed class NotForBroadcastController : MonoBehaviour
	{
		private enum EventPhase
		{
			None,
			Intro,
			Escape,
			Leaving,
			Expired,
			AbortingIntro
		}

		private struct LightState
		{
			internal bool Enabled;

			internal Color Color;

			internal float Intensity;

			internal float Range;
		}

		private const float EscapeDuration = 250f;

		private const float RedWarningTime = 73f;

		private const float ExitFadeDuration = 1.25f;

		private const float ExplosionDamageRadius = 3.75f;

		private const float ExplosionPlayerSafeRadius = 8.5f;

		private const int ExplosionDamage = 10;

		private const string PhaseProperty = "NFB_PHASE";

		private const string RemainingProperty = "NFB_REMAINING";

		private const string TotalProperty = "NFB_TOTAL";

		private const string DeadlineProperty = "NFB_DEADLINE";

		private const string BatteryPositionsProperty = "NFB_BATTERY_POSITIONS";

		internal static NetworkedEvent HazardEvent;

		internal static NetworkedEvent BatteryCollectEvent;

		private static readonly List<NotForBroadcastBattery> Batteries = new List<NotForBroadcastBattery>();

		private readonly Dictionary<AudioSource, bool> _mutedSources = new Dictionary<AudioSource, bool>();

		private readonly Dictionary<Light, LightState> _sirenLights = new Dictionary<Light, LightState>();

		private readonly List<Vector3> _batteryTargets = new List<Vector3>();

		private readonly List<GameObject> _introForceFields = new List<GameObject>();

		private EventPhase _phase;

		private ExtractionPoint _finalExtraction;

		private AudioClip _introClip;

		private AudioClip _escapeClip;

		private AudioSource _musicSource;

		private string _introPath;

		private string _escapePath;

		private bool _audioLoadStarted;

		private bool _introPlayed;

		private bool _escapePlayed;

		private bool _timerExpired;

		private bool _departureStarted;

		private bool _introAbortStarted;

		private int _remaining;

		private int _total;

		private int _previousRemaining = -1;

		private double _deadline;

		private float _nextHazardAt;

		private float _nextFireAt;

		private float _nextAudioScan;

		private float _nextLightScan;

		private float _nextMapUpdate;

		private float _nextNetworkPoll;

		private float _nextBatteryReconcile;

		private float _tubeStableTimer;

		private TruckDoor _truckDoor;

		private TextMeshProUGUI _timerText;

		private GameObject _timerObject;

		private Color _timerBaseColor = Color.white;

		internal bool EventActive
		{
			get
			{
				if (_phase != EventPhase.Intro)
				{
					return _phase == EventPhase.Escape;
				}
				return true;
			}
		}

		internal bool TruckPowered
		{
			get
			{
				if (EventActive)
				{
					return _remaining <= 0;
				}
				return false;
			}
		}

		internal bool ShouldHoldTruckDoor
		{
			get
			{
				if (EventActive)
				{
					return !TruckPowered;
				}
				return false;
			}
		}

		internal bool ShouldDisableTruckHealer
		{
			get
			{
				if (EventActive)
				{
					return !TruckPowered;
				}
				return false;
			}
		}

		internal static void RegisterBattery(NotForBroadcastBattery battery)
		{
			if ((Object)(object)battery != (Object)null && !Batteries.Contains(battery))
			{
				Batteries.Add(battery);
			}
		}

		internal static void UnregisterBattery(NotForBroadcastBattery battery)
		{
			Batteries.Remove(battery);
		}

		internal void ConfigureAudioPaths(string introPath, string escapePath)
		{
			_introPath = introPath;
			_escapePath = escapePath;
			BeginAudioLoading();
		}

		private void BeginAudioLoading()
		{
			if (!_audioLoadStarted)
			{
				_audioLoadStarted = true;
				((MonoBehaviour)this).StartCoroutine(LoadAudioClip(_introPath, delegate(AudioClip clip)
				{
					_introClip = clip;
				}));
				((MonoBehaviour)this).StartCoroutine(LoadAudioClip(_escapePath, delegate(AudioClip clip)
				{
					_escapeClip = clip;
				}));
			}
		}

		private IEnumerator LoadAudioClip(string path, Action<AudioClip> completed)
		{
			if (!File.Exists(path))
			{
				Plugin.Log.LogError((object)("Audio file does not exist: " + path));
				yield break;
			}
			string absoluteUri = new Uri(path).AbsoluteUri;
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)14);
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result != 1)
				{
					Plugin.Log.LogError((object)("Could not load " + Path.GetFileName(path) + ": " + request.error));
					yield break;
				}
				AudioClip content = DownloadHandlerAudioClip.GetContent(request);
				((Object)content).name = Path.GetFileNameWithoutExtension(path);
				completed(content);
				Plugin.Log.LogInfo((object)$"Loaded {Path.GetFileName(path)} ({content.length:0.00} seconds).");
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		internal void TryBeginIntro(ExtractionPoint extractionPoint)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			if (_phase != EventPhase.None || (Object)(object)extractionPoint == (Object)null || !SemiFunc.RunIsLevel() || (int)GameAccess.GetField<State>(extractionPoint, "currentState", (State)0) != 3)
			{
				return;
			}
			RoundDirector instance = RoundDirector.instance;
			int field = GameAccess.GetField(instance, "extractionPointsCompleted", 0);
			int field2 = GameAccess.GetField(instance, "extractionPoints", 0);
			if (field2 > 0 && field == field2 - 1)
			{
				_finalExtraction = extractionPoint;
				BeginIntroLocal();
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					int batteryCountForCurrentLevel = GetBatteryCountForCurrentLevel();
					SetSynchronizedState(EventPhase.Intro, batteryCountForCurrentLevel, batteryCountForCurrentLevel, 0.0);
					SpawnBatteries(batteryCountForCurrentLevel);
				}
			}
		}

		internal void TryBeginEscape(ExtractionPoint extractionPoint)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			if (_phase != EventPhase.Intro || (Object)(object)extractionPoint != (Object)(object)_finalExtraction)
			{
				return;
			}
			if ((int)GameAccess.GetField<State>(extractionPoint, "currentState", (State)0) != 6)
			{
				_tubeStableTimer = 0f;
				return;
			}
			bool field = GameAccess.GetField(extractionPoint, "tubeHit", fallback: false);
			bool field2 = GameAccess.GetField(extractionPoint, "cancelExtraction", fallback: false);
			State field3 = GameAccess.GetField<State>(extractionPoint, "stateSetTo", (State)0);
			if (!field || field2 || (int)field3 == 5)
			{
				_tubeStableTimer = 0f;
			}
			else if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				_tubeStableTimer += Time.deltaTime;
				if (!(_tubeStableTimer < 0.85f))
				{
					_tubeStableTimer = 0f;
					double deadline = GetClock() + 250.0;
					SetSynchronizedState(EventPhase.Escape, _remaining, _total, deadline);
				}
			}
		}

		private void BeginIntroLocal()
		{
			if (_phase == EventPhase.None)
			{
				_phase = EventPhase.Intro;
				_timerExpired = false;
				_departureStarted = false;
				_introAbortStarted = false;
				_tubeStableTimer = 0f;
				_previousRemaining = -1;
				if ((Object)(object)_finalExtraction == (Object)null)
				{
					_finalExtraction = ResolveFinalExtraction();
				}
				PlayerAvatar val = SemiFunc.PlayerGetLocal();
				if ((Object)(object)val != (Object)null && (Object)(object)val.RoomVolumeCheck != (Object)null)
				{
					val.RoomVolumeCheck.CheckSet();
				}
				bool num = (((Object)(object)val != (Object)null && (Object)(object)val.RoomVolumeCheck != (Object)null && GameAccess.GetField(val.RoomVolumeCheck, "inTruck", fallback: false)) ? EjectLocalPlayerFromTruck() : MoveLocalPlayerToFinalExtraction());
				CreateIntroForceFields();
				if (num)
				{
					CloseTruckDoor();
				}
				PlayIntroOnce();
				SuppressWorldAudio();
			}
		}

		private void BeginEscapeLocal(double deadline)
		{
			if (_phase == EventPhase.None)
			{
				BeginIntroLocal();
			}
			if (_phase == EventPhase.Escape)
			{
				if (deadline > 0.0)
				{
					_deadline = deadline;
				}
				return;
			}
			ReleaseIntroForceFields();
			_phase = EventPhase.Escape;
			_deadline = ((deadline > 0.0) ? deadline : (GetClock() + 250.0));
			_nextHazardAt = Time.time + Random.Range(0.4f, 1f);
			_nextFireAt = Time.time + Random.Range(4f, 9f);
			CreateTimerUi();
			PlayEscapeOnce();
			StartSirenLighting();
			ShowObjectiveMessage();
		}

		private void Update()
		{
			PollSynchronizedState();
			if (EventActive)
			{
				if (Time.unscaledTime >= _nextAudioScan)
				{
					_nextAudioScan = Time.unscaledTime + 0.2f;
					SuppressWorldAudio();
				}
				if (_phase == EventPhase.Escape)
				{
					UpdateTimer();
					UpdateSirenLighting();
					UpdateMapTarget();
					UpdateHazards();
				}
				if (Time.time >= _nextBatteryReconcile)
				{
					_nextBatteryReconcile = Time.time + 0.25f;
					ReconcileLocalBatteries();
				}
				if (_previousRemaining != _remaining)
				{
					HandleRemainingChanged();
					_previousRemaining = _remaining;
				}
			}
		}

		private void PollSynchronizedState()
		{
			if (!SemiFunc.IsMultiplayer() || !PhotonNetwork.InRoom || Time.unscaledTime < _nextNetworkPoll)
			{
				return;
			}
			_nextNetworkPoll = Time.unscaledTime + 0.1f;
			EventPhase roomProperty = (EventPhase)GetRoomProperty("NFB_PHASE", 0);
			if (roomProperty == EventPhase.AbortingIntro && _phase == EventPhase.Intro)
			{
				BeginIntroAbortLocal();
				return;
			}
			if (roomProperty == EventPhase.None && EventActive)
			{
				StopForLevelEnd();
				return;
			}
			int roomProperty2 = GetRoomProperty("NFB_REMAINING", _remaining);
			int roomProperty3 = GetRoomProperty("NFB_TOTAL", _total);
			double roomDouble = GetRoomDouble("NFB_DEADLINE", _deadline);
			float[] roomFloatArray = GetRoomFloatArray("NFB_BATTERY_POSITIONS");
			_remaining = roomProperty2;
			_total = roomProperty3;
			if (roomFloatArray != null)
			{
				SetBatteryTargetsFromData(roomFloatArray);
			}
			if (roomProperty == EventPhase.Intro && _phase == EventPhase.None)
			{
				BeginIntroLocal();
			}
			else if (roomProperty == EventPhase.Escape && _phase != EventPhase.Escape)
			{
				BeginEscapeLocal(roomDouble);
			}
			else if (roomProperty == EventPhase.Escape && roomDouble > 0.0)
			{
				_deadline = roomDouble;
			}
			else if (roomProperty == EventPhase.Leaving && EventActive)
			{
				BeginRemoteDeparture();
			}
			else if (roomProperty == EventPhase.Expired && EventActive)
			{
				_timerExpired = true;
				ExpireTimer();
			}
		}

		internal void NotifyExtractionCancelled(ExtractionPoint extractionPoint)
		{
			if (_phase == EventPhase.Intro && !((Object)(object)extractionPoint == (Object)null) && !((Object)(object)extractionPoint != (Object)(object)_finalExtraction))
			{
				Plugin.Log.LogInfo((object)"Final extraction received a confirmed cancel-state transition while the intro was active.");
				BeginIntroAbort();
			}
		}

		private void BeginIntroAbort()
		{
			if (_phase == EventPhase.Intro && !_introAbortStarted)
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					SetPhaseProperty(EventPhase.AbortingIntro);
				}
				BeginIntroAbortLocal();
			}
		}

		private void BeginIntroAbortLocal()
		{
			if (_introAbortStarted)
			{
				return;
			}
			_introAbortStarted = true;
			_phase = EventPhase.AbortingIntro;
			_tubeStableTimer = 0f;
			ReleaseIntroForceFields();
			UnlockTruckDoor();
			_remaining = 0;
			_total = 0;
			_batteryTargets.Clear();
			foreach (NotForBroadcastBattery item in Batteries.ToList())
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
			}
			Batteries.Clear();
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				SetRemainingProperty(0, 0);
			}
			((MonoBehaviour)this).StartCoroutine(FadeOutAbortedIntro());
		}

		private IEnumerator FadeOutAbortedIntro()
		{
			float startVolume = (((Object)(object)_musicSource != (Object)null) ? _musicSource.volume : 0f);
			float elapsed = 0f;
			while (elapsed < 0.85f)
			{
				elapsed += Time.unscaledDeltaTime;
				if ((Object)(object)_musicSource != (Object)null)
				{
					_musicSource.volume = Mathf.Lerp(startVolume, 0f, elapsed / 0.85f);
				}
				yield return null;
			}
			if ((Object)(object)_musicSource != (Object)null)
			{
				_musicSource.Stop();
				_musicSource.clip = null;
				_musicSource.volume = 1f;
			}
			RestoreWorldAudio();
			_phase = EventPhase.None;
			_finalExtraction = null;
			_introPlayed = false;
			_escapePlayed = false;
			_introAbortStarted = false;
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				SetPhaseProperty(EventPhase.None);
			}
			Plugin.Log.LogInfo((object)"Final extraction intro aborted because the extraction was cancelled.");
		}

		private void SetSynchronizedState(EventPhase phase, int remaining, int total, double deadline)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			_remaining = remaining;
			_total = total;
			_deadline = deadline;
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom)
			{
				Hashtable val = new Hashtable
				{
					[(object)"NFB_PHASE"] = (int)phase,
					[(object)"NFB_REMAINING"] = remaining,
					[(object)"NFB_TOTAL"] = total,
					[(object)"NFB_DEADLINE"] = deadline
				};
				PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
			switch (phase)
			{
			case EventPhase.Intro:
				BeginIntroLocal();
				break;
			case EventPhase.Escape:
				BeginEscapeLocal(deadline);
				break;
			}
		}

		private static int GetRoomProperty(string key, int fallback)
		{
			if (!PhotonNetwork.InRoom || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)key, out object value))
			{
				return fallback;
			}
			try
			{
				return Convert.ToInt32(value);
			}
			catch
			{
				return fallback;
			}
		}

		private static double GetRoomDouble(string key, double fallback)
		{
			if (!PhotonNetwork.InRoom || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)key, out object value))
			{
				return fallback;
			}
			try
			{
				return Convert.ToDouble(value);
			}
			catch
			{
				return fallback;
			}
		}

		private static float[] GetRoomFloatArray(string key)
		{
			if (!PhotonNetwork.InRoom || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)key, out object value))
			{
				return null;
			}
			return value as float[];
		}

		private void SetBatteryTargetsFromData(float[] data)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (data.Length % 3 == 0)
			{
				_batteryTargets.Clear();
				for (int i = 0; i < data.Length; i += 3)
				{
					_batteryTargets.Add(new Vector3(data[i], data[i + 1], data[i + 2]));
				}
			}
		}

		private float[] SerializeBatteryTargets()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			float[] array = new float[_batteryTargets.Count * 3];
			for (int i = 0; i < _batteryTargets.Count; i++)
			{
				array[i * 3] = _batteryTargets[i].x;
				array[i * 3 + 1] = _batteryTargets[i].y;
				array[i * 3 + 2] = _batteryTargets[i].z;
			}
			return array;
		}

		private static double GetClock()
		{
			if (!SemiFunc.IsMultiplayer() || !PhotonNetwork.InRoom)
			{
				return Time.timeAsDouble;
			}
			return PhotonNetwork.Time;
		}

		private int GetBatteryCountForCurrentLevel()
		{
			int num = RunManager.instance.levelsCompleted + 1;
			if (num <= 2)
			{
				return 1;
			}
			if (num <= 4)
			{
				return 2;
			}
			return 3;
		}

		private void SpawnBatteries(int count)
		{
			//IL_003c: 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_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)
			if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)LevelGenerator.Instance == (Object)null))
			{
				List<Vector3> list = SelectBatteryPositions(count);
				AddFallbackBatteryPositions(list, count);
				_batteryTargets.Clear();
				for (int i = 0; i < list.Count && i < count; i++)
				{
					_batteryTargets.Add(list[i]);
					Plugin.Log.LogInfo((object)$"Created truck battery target {i + 1} at {list[i]}.");
				}
				_remaining = _batteryTargets.Count;
				_total = _batteryTargets.Count;
				SetRemainingProperty(_remaining, _total);
				ReconcileLocalBatteries();
				if (_batteryTargets.Count < count)
				{
					Plugin.Log.LogWarning((object)$"Only {_batteryTargets.Count} of {count} truck battery targets were created.");
				}
				if (_batteryTargets.Count == 0)
				{
					Plugin.Log.LogError((object)"No truck batteries were spawned. The truck has been unlocked to prevent a softlock.");
					UnlockTruckDoor();
					SemiFunc.UIFocusText("BATTERY SYSTEM FAILED — TRUCK UNLOCKED", Color.white, Color.red, 3f);
				}
			}
		}

		private void AddFallbackBatteryPositions(List<Vector3> positions, int count)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			if (positions.Count >= count || (Object)(object)LevelGenerator.Instance == (Object)null)
			{
				return;
			}
			LevelPoint? obj = ((IEnumerable<LevelPoint>)LevelGenerator.Instance.LevelPathPoints).FirstOrDefault((Func<LevelPoint, bool>)((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null && point.Room.Truck));
			Vector3 truckPosition = ((obj != null) ? ((Component)obj).transform.position : Vector3.zero);
			Vector3 extractionPosition = (((Object)(object)_finalExtraction != (Object)null) ? ((Component)_finalExtraction).transform.position : Vector3.zero);
			NavMeshHit val = default(NavMeshHit);
			foreach (LevelPoint item in (from point in LevelGenerator.Instance.LevelPathPoints
				where (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null && !point.Room.Truck
				orderby Math.Min(Vector3.Distance(((Component)point).transform.position, truckPosition), Vector3.Distance(((Component)point).transform.position, extractionPosition)) descending
				select point).ToList())
			{
				Vector3 position = ((Component)item).transform.position;
				if (NavMesh.SamplePosition(position, ref val, 4f, -1))
				{
					position = ((NavMeshHit)(ref val)).position;
				}
				position += Vector3.up * 0.65f;
				if (!positions.Any((Vector3 existing) => Vector3.Distance(existing, position) < 8f))
				{
					positions.Add(position);
					if (positions.Count >= count)
					{
						return;
					}
				}
			}
			if (positions.Count == 0 && (Object)(object)_finalExtraction != (Object)null)
			{
				Vector3 val2 = ((Component)_finalExtraction).transform.position + ((Component)_finalExtraction).transform.forward * 5f;
				NavMeshHit val3 = default(NavMeshHit);
				if (NavMesh.SamplePosition(val2, ref val3, 8f, -1))
				{
					val2 = ((NavMeshHit)(ref val3)).position;
				}
				positions.Add(val2 + Vector3.up * 0.65f);
				Plugin.Log.LogWarning((object)"No distant battery room was available. An emergency battery target was created near the final extraction.");
			}
		}

		private List<Vector3> SelectBatteryPositions(int count)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			List<LevelPoint> list = LevelGenerator.Instance.LevelPathPoints.Where((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null).ToList();
			Dictionary<RoomVolume, HashSet<RoomVolume>> graph = BuildRoomGraph(list);
			RoomVolume origin = list.Select((LevelPoint point) => point.Room).FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume val2) => val2.Truck));
			RoomVolume origin2 = FindRoomNearest(((Component)_finalExtraction).transform.position, list);
			Dictionary<RoomVolume, int> fromTruck = GetRoomDistances(graph, origin);
			Dictionary<RoomVolume, int> fromExtraction = GetRoomDistances(graph, origin2);
			List<RoomVolume> list2 = (from room2 in graph.Keys
				where (Object)(object)room2 != (Object)null && !room2.Truck && !room2.Extraction
				orderby Math.Min(GetDistance(fromTruck, room2), GetDistance(fromExtraction, room2)) descending
				select room2).ThenByDescending((RoomVolume val2) => Vector3.Distance(((Component)val2).transform.position, ((Component)_finalExtraction).transform.position)).ToList();
			List<RoomVolume> list3 = new List<RoomVolume>();
			foreach (RoomVolume candidate in list2)
			{
				if (list3.All((RoomVolume other) => GetGraphDistance(graph, candidate, other) >= 2))
				{
					list3.Add(candidate);
					if (list3.Count >= count)
					{
						break;
					}
				}
			}
			if (list3.Count < count)
			{
				foreach (RoomVolume item in list2)
				{
					if (!list3.Contains(item))
					{
						list3.Add(item);
						if (list3.Count >= count)
						{
							break;
						}
					}
				}
			}
			List<Vector3> list4 = new List<Vector3>();
			NavMeshHit val = default(NavMeshHit);
			foreach (RoomVolume room in list3)
			{
				List<LevelPoint> list5 = list.Where((LevelPoint point) => (Object)(object)point.Room == (Object)(object)room).ToList();
				if (list5.Count != 0)
				{
					Vector3 position = ((Component)list5.OrderByDescending((LevelPoint point) => Vector3.Distance(((Component)point).transform.position, ((Component)_finalExtraction).transform.position)).First()).transform.position;
					if (NavMesh.SamplePosition(position, ref val, 3f, -1))
					{
						position = ((NavMeshHit)(ref val)).position;
					}
					list4.Add(position + Vector3.up * 0.65f);
				}
			}
			return list4;
		}

		private static Dictionary<RoomVolume, HashSet<RoomVolume>> BuildRoomGraph(List<LevelPoint> points)
		{
			Dictionary<RoomVolume, HashSet<RoomVolume>> dictionary = new Dictionary<RoomVolume, HashSet<RoomVolume>>();
			foreach (LevelPoint point in points)
			{
				if (!dictionary.ContainsKey(point.Room))
				{
					dictionary[point.Room] = new HashSet<RoomVolume>();
				}
				foreach (LevelPoint connectedPoint in point.ConnectedPoints)
				{
					if (!((Object)(object)connectedPoint == (Object)null) && !((Object)(object)connectedPoint.Room == (Object)null) && !((Object)(object)connectedPoint.Room == (Object)(object)point.Room))
					{
						if (!dictionary.ContainsKey(connectedPoint.Room))
						{
							dictionary[connectedPoint.Room] = new HashSet<RoomVolume>();
						}
						dictionary[point.Room].Add(connectedPoint.Room);
						dictionary[connectedPoint.Room].Add(point.Room);
					}
				}
			}
			return dictionary;
		}

		private static RoomVolume FindRoomNearest(Vector3 position, List<LevelPoint> points)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return points.OrderBy((LevelPoint point) => Vector3.Distance(position, ((Component)point).transform.position)).FirstOrDefault()?.Room;
		}

		private static Dictionary<RoomVolume, int> GetRoomDistances(Dictionary<RoomVolume, HashSet<RoomVolume>> graph, RoomVolume origin)
		{
			Dictionary<RoomVolume, int> dictionary = new Dictionary<RoomVolume, int>();
			if ((Object)(object)origin == (Object)null || !graph.ContainsKey(origin))
			{
				return dictionary;
			}
			Queue<RoomVolume> queue = new Queue<RoomVolume>();
			queue.Enqueue(origin);
			dictionary[origin] = 0;
			while (queue.Count > 0)
			{
				RoomVolume key = queue.Dequeue();
				foreach (RoomVolume item in graph[key])
				{
					if (!dictionary.ContainsKey(item))
					{
						dictionary[item] = dictionary[key] + 1;
						queue.Enqueue(item);
					}
				}
			}
			return dictionary;
		}

		private static int GetDistance(Dictionary<RoomVolume, int> distances, RoomVolume room)
		{
			if (!distances.TryGetValue(room, out var value))
			{
				return -1000;
			}
			return value;
		}

		private static int GetGraphDistance(Dictionary<RoomVolume, HashSet<RoomVolume>> graph, RoomVolume from, RoomVolume to)
		{
			if (!GetRoomDistances(graph, from).TryGetValue(to, out var value))
			{
				return int.MaxValue;
			}
			return value;
		}

		internal void RequestBatteryCollection(Vector3 batteryPosition)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if (EventActive && _remaining > 0)
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					HandleBatteryCollectionRequest(batteryPosition);
					return;
				}
				float[] array = new float[3] { batteryPosition.x, batteryPosition.y, batteryPosition.z };
				BatteryCollectEvent.RaiseEvent((object)array, NetworkingEvents.RaiseMasterClient, SendOptions.SendReliable);
			}
		}

		internal static void OnBatteryCollectEvent(EventData eventData)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Plugin.Controller == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer() && eventData.CustomData is float[] array && array.Length >= 3)
			{
				Vector3 requestedPosition = default(Vector3);
				((Vector3)(ref requestedPosition))..ctor(array[0], array[1], array[2]);
				Plugin.Controller.HandleBatteryCollectionRequest(requestedPosition);
			}
		}

		private void HandleBatteryCollectionRequest(Vector3 requestedPosition)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMasterClientOrSingleplayer() && EventActive && _remaining > 0 && _batteryTargets.Count != 0)
			{
				Vector3 val = _batteryTargets.OrderBy((Vector3 position) => Vector3.Distance(position, requestedPosition)).First();
				if (Vector3.Distance(val, requestedPosition) > 3f)
				{
					Plugin.Log.LogWarning((object)$"Rejected a battery collection request too far from a target: {requestedPosition}.");
					return;
				}
				_batteryTargets.Remove(val);
				_remaining = _batteryTargets.Count;
				SetRemainingProperty(_remaining, _total);
				ReconcileLocalBatteries();
				Plugin.Log.LogInfo((object)$"Collected truck battery at {val}. {_remaining} remaining.");
			}
		}

		private void SetRemainingProperty(int remaining, int total)
		{
			//IL_0013: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom)
			{
				PhotonNetwork.CurrentRoom.SetCustomProperties(new Hashtable
				{
					[(object)"NFB_REMAINING"] = remaining,
					[(object)"NFB_TOTAL"] = total,
					[(object)"NFB_BATTERY_POSITIONS"] = SerializeBatteryTargets()
				}, (Hashtable)null, (WebFlags)null);
			}
		}

		private void HandleRemainingChanged()
		{
			//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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (_total > 0)
			{
				if (_remaining > 0)
				{
					string arg = ((_remaining == 1) ? "BATTERY" : "BATTERIES");
					SemiFunc.UIFocusText($"TRUCK POWER LOST — FIND {_remaining} {arg}", Color.white, new Color(1f, 0.55f, 0f), 3f);
				}
				else
				{
					UnlockTruckDoor();
					SemiFunc.UIFocusText("TRUCK POWER RESTORED — RETURN TO THE TRUCK", Color.white, Color.green, 3f);
				}
			}
		}

		private void ShowObjectiveMessage()
		{
			//IL_002f: 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)
			int num = Math.Max(1, _remaining);
			string arg = ((num == 1) ? "BATTERY" : "BATTERIES");
			SemiFunc.UIFocusText($"TRUCK POWER LOST — FIND {num} {arg}", Color.white, new Color(1f, 0.55f, 0f), 3f);
		}

		private ExtractionPoint ResolveFinalExtraction()
		{
			return (from point in Object.FindObjectsOfType<ExtractionPoint>()
				where (Object)(object)point != (Object)null && !GameAccess.GetField(point, "isShop", fallback: false)
				select point).OrderByDescending(delegate(ExtractionPoint 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)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Invalid comparison between Unknown and I4
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				State field = GameAccess.GetField<State>(point, "currentState", (State)0);
				return (int)field == 3 || (int)field == 8 || (int)field == 6;
			}).ThenByDescending((ExtractionPoint point) => point.haulGoal).FirstOrDefault();
		}

		private bool MoveLocalPlayerToFinalExtraction()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = SemiFunc.PlayerGetLocal();
			List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints?.Where((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null).ToList();
			if ((Object)(object)val == (Object)null || (Object)(object)_finalExtraction == (Object)null || list == null || list.Count == 0)
			{
				Plugin.Log.LogWarning((object)"The local player could not be moved into the final extraction room.");
				return false;
			}
			RoomVolume finalRoom = FindRoomNearest(((Component)_finalExtraction).transform.position, list);
			List<LevelPoint> list2 = list.Where((LevelPoint point) => (Object)(object)point.Room == (Object)(object)finalRoom).ToList();
			Vector3 val2 = ((list2.Count > 0) ? (list2.Aggregate(Vector3.zero, (Vector3 sum, LevelPoint point) => sum + ((Component)point).transform.position) / (float)list2.Count) : ((Component)_finalExtraction).transform.position);
			Vector2 val3 = Random.insideUnitCircle * 0.65f;
			Vector3 val4 = val2 + new Vector3(val3.x, 0f, val3.y);
			NavMeshHit val5 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val4, ref val5, 5f, -1))
			{
				val4 = ((NavMeshHit)(ref val5)).position;
			}
			MoveLocalPlayer(val, val4 + Vector3.up * 0.8f);
			Plugin.Log.LogInfo((object)$"Moved the local player into the final extraction room at {val4} for the intro containment.");
			return true;
		}

		private static void MoveLocalPlayer(PlayerAvatar localPlayer, Vector3 destination)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			PlayerController instance = PlayerController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				if ((Object)(object)instance.rb != (Object)null)
				{
					instance.rb.velocity = Vector3.zero;
					instance.rb.angularVelocity = Vector3.zero;
					instance.rb.position = destination;
				}
				((Component)instance).transform.position = destination;
			}
			Rigidbody field = GameAccess.GetField<Rigidbody>(localPlayer, "rb");
			if ((Object)(object)field != (Object)null)
			{
				field.velocity = Vector3.zero;
				field.angularVelocity = Vector3.zero;
				field.position = destination;
			}
			((Component)localPlayer).transform.position = destination;
			if ((Object)(object)localPlayer.playerTransform != (Object)null)
			{
				localPlayer.playerTransform.position = destination;
			}
			GameAccess.SetField(localPlayer, "clientPosition", destination);
			GameAccess.SetField(localPlayer, "clientPositionCurrent", destination);
			GameAccess.SetField(localPlayer, "LastNavmeshPosition", destination);
			Physics.SyncTransforms();
			if ((Object)(object)localPlayer.RoomVolumeCheck != (Object)null)
			{
				localPlayer.RoomVolumeCheck.CheckSet();
			}
		}

		private bool EjectLocalPlayerFromTruck()
		{
			//IL_004e: 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)
			PlayerAvatar val = SemiFunc.PlayerGetLocal();
			if ((Object)(object)val == (Object)null || (Object)(object)val.RoomVolumeCheck == (Object)null || !GameAccess.GetField(val.RoomVolumeCheck, "inTruck", fallback: false))
			{
				return true;
			}
			if (!TryGetTruckExitPosition(out var destination))
			{
				Plugin.Log.LogWarning((object)"A safe position outside the truck was not found; the truck door will remain open for this intro.");
				return false;
			}
			MoveLocalPlayer(val, destination);
			Plugin.Log.LogInfo((object)$"Moved the local player out of the truck to {destination} before locking the door.");
			return true;
		}

		private bool TryGetTruckExitPosition(out Vector3 destination)
		{
			//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)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			destination = Vector3.zero;
			List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints?.Where((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null).ToList();
			if (list == null || list.Count == 0)
			{
				return false;
			}
			RoomVolume truckRoom = list.Select((LevelPoint point) => point.Room).FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume room) => (Object)(object)room != (Object)null && room.Truck));
			List<LevelPoint> list2 = list.Where((LevelPoint point) => (Object)(object)point.Room == (Object)(object)truckRoom || point.Truck).ToList();
			Vector3 truckCenter = ((list2.Count > 0) ? (list2.Aggregate(Vector3.zero, (Vector3 sum, LevelPoint point) => sum + ((Component)point).transform.position) / (float)list2.Count) : Vector3.zero);
			RoomVolume truckStagingRoom = GetTruckStagingRoom(list);
			List<LevelPoint> list3 = list.Where((LevelPoint point) => !point.Room.Truck && !point.Truck && ((Object)(object)truckStagingRoom == (Object)null || (Object)(object)point.Room == (Object)(object)truckStagingRoom)).ToList();
			if (list3.Count == 0)
			{
				list3 = list.Where((LevelPoint point) => !point.Room.Truck && !point.Truck).ToList();
			}
			if (list3.Count == 0)
			{
				return false;
			}
			ExtractionPoint val = (from point in Object.FindObjectsOfType<ExtractionPoint>()
				where (Object)(object)point != (Object)null && !GameAccess.GetField(point, "isShop", fallback: false)
				orderby Vector3.Distance(((Component)point).transform.position, truckCenter)
				select point).FirstOrDefault();
			Vector3 preferredPosition = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : truckCenter);
			NavMeshHit val2 = default(NavMeshHit);
			foreach (LevelPoint item in from point in list3
				orderby Vector3.Distance(((Component)point).transform.position, preferredPosition), Vector3.Distance(((Component)point).transform.position, truckCenter)
				select point)
			{
				if (NavMesh.SamplePosition(((Component)item).transform.position, ref val2, 4f, -1))
				{
					destination = ((NavMeshHit)(ref val2)).position + Vector3.up * 0.8f;
					return true;
				}
			}
			return false;
		}

		private RoomVolume GetTruckStagingRoom(List<LevelPoint> points)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			RoomVolume truckRoom = points.Select((LevelPoint point) => point.Room).FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume room) => (Object)(object)room != (Object)null && room.Truck));
			Dictionary<RoomVolume, HashSet<RoomVolume>> dictionary = BuildRoomGraph(points);
			if ((Object)(object)truckRoom == (Object)null || !dictionary.TryGetValue(truckRoom, out var value))
			{
				return null;
			}
			ExtractionPoint? obj = (from point in Object.FindObjectsOfType<ExtractionPoint>()
				where (Object)(object)point != (Object)null && !GameAccess.GetField(point, "isShop", fallback: false)
				orderby Vector3.Distance(((Component)point).transform.position, ((Component)truckRoom).transform.position)
				select point).FirstOrDefault();
			Vector3 preferredPosition = ((obj != null) ? ((Component)obj).transform.position : ((Component)truckRoom).transform.position);
			return (from room in value
				where (Object)(object)room != (Object)null && !room.Truck
				orderby Vector3.Distance(((Component)room).transform.position, preferredPosition)
				select room).FirstOrDefault();
		}

		private void CreateIntroForceFields()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			ReleaseIntroForceFields();
			List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints?.Where((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null).ToList();
			if (list == null || list.Count == 0 || (Object)(object)_finalExtraction == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Intro forcefields could not be created because room data was unavailable.");
				return;
			}
			RoomVolume val = FindRoomNearest(((Component)_finalExtraction).transform.position, list);
			RoomVolume truckStagingRoom = GetTruckStagingRoom(list);
			HashSet<RoomVolume> hashSet = new HashSet<RoomVolume>();
			if ((Object)(object)val != (Object)null)
			{
				hashSet.Add(val);
			}
			if ((Object)(object)truckStagingRoom != (Object)null)
			{
				hashSet.Add(truckStagingRoom);
			}
			List<Vector3> list2 = new List<Vector3>();
			foreach (RoomVolume room in hashSet)
			{
				foreach (LevelPoint item in list.Where((LevelPoint point) => (Object)(object)point.Room == (Object)(object)room))
				{
					foreach (LevelPoint connectedPoint in item.ConnectedPoints)
					{
						if ((Object)(object)connectedPoint == (Object)null || (Object)(object)connectedPoint.Room == (Object)null || (Object)(object)connectedPoint.Room == (Object)(object)room)
						{
							continue;
						}
						Vector3 midpoint = Vector3.Lerp(((Component)item).transform.position, ((Component)connectedPoint).transform.position, 0.5f);
						if (!list2.Any((Vector3 existing) => Vector3.Distance(existing, midpoint) < 1.25f))
						{
							Vector3 doorwayDirection = ((Component)connectedPoint).transform.position - ((Component)item).transform.position;
							doorwayDirection.y = 0f;
							if (((Vector3)(ref doorwayDirection)).sqrMagnitude < 0.01f)
							{
								doorwayDirection = ((Component)item).transform.forward;
							}
							CreateForceField(midpoint, doorwayDirection);
							list2.Add(midpoint);
						}
					}
				}
			}
			Plugin.Log.LogInfo((object)$"Created {_introForceFields.Count} intro forcefields around the final extraction and truck staging rooms.");
		}

		private void CreateForceField(Vector3 doorwayPosition, Vector3 doorwayDirection)
		{
			//IL_0018: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_00ac: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = "Not For Broadcast Intro Forcefield";
			val.transform.position = doorwayPosition + Vector3.up * 1.85f;
			val.transform.rotation = Quaternion.LookRotation(((Vector3)(ref doorwayDirection)).normalized, Vector3.up);
			val.transform.localScale = new Vector3(4.4f, 3.7f, 0.22f);
			Renderer component = val.GetComponent<Renderer>();
			Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
			if ((Object)(object)component != (Object)null && (Object)(object)val2 != (Object)null)
			{
				Material val3 = new Material(val2);
				Color val4 = default(Color);
				((Color)(ref val4))..ctor(0.06f, 0.65f, 1f, 0.72f);
				val3.color = val4;
				if (val3.HasProperty("_BaseColor"))
				{
					val3.SetColor("_BaseColor", val4);
				}
				if (val3.HasProperty("_EmissionColor"))
				{
					val3.EnableKeyword("_EMISSION");
					val3.SetColor("_EmissionColor", new Color(0.02f, 0.35f, 1.4f));
				}
				component.material = val3;
			}
			_introForceFields.Add(val);
		}

		private void ReleaseIntroForceFields()
		{
			foreach (GameObject introForceField in _introForceFields)
			{
				if ((Object)(object)introForceField != (Object)null)
				{
					Object.Destroy((Object)(object)introForceField);
				}
			}
			_introForceFields.Clear();
		}

		private void CloseTruckDoor()
		{
			//IL_003f: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			_truckDoor = Object.FindObjectOfType<TruckDoor>();
			if ((Object)(object)_truckDoor == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Truck door was not found.");
				return;
			}
			float field = GameAccess.GetField(_truckDoor, "startYPosition", ((Component)_truckDoor).transform.position.y - 2.5f);
			Vector3 position = ((Component)_truckDoor).transform.position;
			position.y = field;
			((Component)_truckDoor).transform.position = position;
			GameAccess.SetField(_truckDoor, "doorEval", 0f);
			GameAccess.SetField(_truckDoor, "fullyOpen", false);
			GameAccess.SetField(_truckDoor, "doorOpen", false);
			GameAccess.SetField(_truckDoor, "doorDelay", 0f);
		}

		private void UnlockTruckDoor()
		{
			if ((Object)(object)_truckDoor == (Object)null)
			{
				_truckDoor = Object.FindObjectOfType<TruckDoor>();
			}
			if ((Object)(object)_truckDoor != (Object)null)
			{
				GameAccess.SetField(_truckDoor, "doorDelay", 0f);
			}
		}

		private void EnsureMusicSource()
		{
			if (!((Object)(object)_musicSource != (Object)null))
			{
				_musicSource = ((Component)this).gameObject.AddComponent<AudioSource>();
				_musicSource.playOnAwake = false;
				_musicSource.loop = false;
				_musicSource.spatialBlend = 0f;
				_musicSource.volume = 1f;
				_musicSource.priority = 0;
				if ((Object)(object)AudioManager.instance != (Object)null)
				{
					_musicSource.outputAudioMixerGroup = AudioManager.instance.MusicMasterGroup;
				}
			}
		}

		private void PlayIntroOnce()
		{
			if (!_introPlayed)
			{
				_introPlayed = true;
				((MonoBehaviour)this).StartCoroutine(PlayWhenReady(EventPhase.Intro));
			}
		}

		private void PlayEscapeOnce()
		{
			if (!_escapePlayed)
			{
				_escapePlayed = true;
				((MonoBehaviour)this).StartCoroutine(PlayWhenReady(EventPhase.Escape));
			}
		}

		private IEnumerator PlayWhenReady(EventPhase requestedPhase)
		{
			AudioClip val = ((requestedPhase == EventPhase.Intro) ? _introClip : _escapeClip);
			float waitUntil = Time.realtimeSinceStartup + 15f;
			while ((Object)(object)val == (Object)null && Time.realtimeSinceStartup < waitUntil)
			{
				yield return null;
				val = ((requestedPhase == EventPhase.Intro) ? _introClip : _escapeClip);
			}
			if (!((Object)(object)val == (Object)null) && (requestedPhase != EventPhase.Intro || _phase == EventPhase.Intro))
			{
				EnsureMusicSource();
				_musicSource.Stop();
				_musicSource.clip = val;
				_musicSource.volume = 1f;
				if (requestedPhase == EventPhase.Escape)
				{
					float time = Mathf.Clamp((float)(250.0 - Math.Max(0.0, _deadline - GetClock())), 0f, Math.Max(0f, val.length - 0.05f));
					_musicSource.time = time;
				}
				_musicSource.Play();
			}
		}

		private void SuppressWorldAudio()
		{
			EnsureMusicSource();
			AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
			foreach (AudioSource val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_musicSource) && IsMusicOrAmbienceSource(val))
				{
					if (!_mutedSources.ContainsKey(val))
					{
						_mutedSources[val] = val.mute;
					}
					val.mute = true;
				}
			}
		}

		private static bool IsMusicOrAmbienceSource(AudioSource source)
		{
			if (IsVoiceSource(source))
			{
				return false;
			}
			if ((Object)(object)AudioManager.instance != (Object)null)
			{
				if ((Object)(object)source.outputAudioMixerGroup == (Object)(object)AudioManager.instance.MusicMasterGroup)
				{
					return true;
				}
				if ((Object)(object)AudioManager.instance.MusicParent != (Object)null && ((Component)source).transform.IsChildOf(AudioManager.instance.MusicParent))
				{
					return true;
				}
			}
			if ((Object)(object)((Component)source).GetComponentInParent<LevelMusic>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<ConstantMusic>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<MusicEnemyCatch>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<MusicEnemyNear>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<MusicEnemySighting>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<AmbienceLoop>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<AmbienceLoopOverride>() != (Object)null)
			{
				return true;
			}
			string obj = ((Object)((Component)source).gameObject).name ?? string.Empty;
			string text = (((Object)(object)source.clip != (Object)null) ? ((Object)source.clip).name : string.Empty);
			string text2 = (obj + " " + text).ToLowerInvariant();
			if (text2.Contains("music") || text2.Contains("ambience") || text2.Contains("ambient") || text2.Contains("soundtrack") || text2.Contains("bgm"))
			{
				return true;
			}
			if (source.loop)
			{
				return source.spatialBlend <= 0.05f;
			}
			return false;
		}

		private static bool IsVoiceSource(AudioSource source)
		{
			if ((Object)(object)((Component)source).GetComponentInParent<PlayerVoice>() != (Object)null || (Object)(object)((Component)source).GetComponentInParent<PlayerVoiceChat>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)AudioManager.instance == (Object)null || (Object)(object)source.outputAudioMixerGroup == (Object)null)
			{
				return false;
			}
			AudioMixerGroup outputAudioMixerGroup = source.outputAudioMixerGroup;
			if (!((Object)(object)outputAudioMixerGroup == (Object)(object)AudioManager.instance.MicrophoneSoundGroup) && !((Object)(object)outputAudioMixerGroup == (Object)(object)AudioManager.instance.MicrophoneSpectateGroup) && !((Object)(object)outputAudioMixerGroup == (Object)(object)AudioManager.instance.TTSSoundGroup))
			{
				return (Object)(object)outputAudioMixerGroup == (Object)(object)AudioManager.instance.TTSSpectateGroup;
			}
			return true;
		}

		private void RestoreWorldAudio()
		{
			foreach (KeyValuePair<AudioSource, bool> item in _mutedSources.ToList())
			{
				if ((Object)(object)item.Key != (Object)null)
				{
					item.Key.mute = item.Value;
				}
			}
			_mutedSources.Clear();
		}

		private void CreateTimerUi()
		{
			//IL_009e: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_019c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_timerObject != (Object)null))
			{
				if ((Object)(object)LevelUI.instance == (Object)null || (Object)(object)LevelUI.instance.textNumber == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Level HUD text was not available for the escape timer.");
					return;
				}
				TextMeshProUGUI textNumber = LevelUI.instance.textNumber;
				GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud");
				Transform val2 = (((Object)(object)val != (Object)null) ? val.transform : ((TMP_Text)textNumber).transform.parent);
				_timerObject = Object.Instantiate<GameObject>(((Component)textNumber).gameObject, val2);
				((Object)_timerObject).name = "Not For Broadcast Escape Timer";
				_timerObject.transform.localScale = Vector3.one;
				_timerObject.transform.localRotation = Quaternion.identity;
				_timerText = _timerObject.GetComponent<TextMeshProUGUI>();
				((TMP_Text)_timerText).text = "04:10";
				((TMP_Text)_timerText).fontSize = Math.Max(32f, ((TMP_Text)textNumber).fontSize * 1.5f);
				((TMP_Text)_timerText).enableAutoSizing = false;
				((TMP_Text)_timerText).alignment = (TextAlignmentOptions)514;
				((Graphic)_timerText).raycastTarget = false;
				_timerBaseColor = ((Graphic)textNumber).color;
				RectTransform component = _timerObject.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, -48f);
				component.sizeDelta = new Vector2(420f, 80f);
				_timerObject.transform.SetAsLastSibling();
				_timerObject.SetActive(true);
			}
		}

		private void UpdateTimer()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			double num = Math.Max(0.0, _deadline - GetClock());
			float num2 = (float)num;
			int num3 = Mathf.CeilToInt(num2);
			if ((Object)(object)_timerText != (Object)null)
			{
				((TMP_Text)_timerText).text = $"{num3 / 60:00}:{num3 % 60:00}";
				if (num2 <= 73f)
				{
					float num4 = Mathf.Lerp(0.1f, 0.85f, num2 / 73f);
					bool flag = Mathf.Repeat(Time.unscaledTime, num4) < num4 * 0.55f;
					((Graphic)_timerText).color = (Color)(flag ? new Color(1f, 0.025f, 0.01f) : _timerBaseColor);
				}
				else
				{
					((Graphic)_timerText).color = _timerBaseColor;
				}
			}
			if (num <= 0.0 && !_timerExpired)
			{
				_timerExpired = true;
				ExpireTimer();
			}
		}

		private void ExpireTimer()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = SemiFunc.PlayerGetLocal();
			if ((Object)(object)val != (Object)null)
			{
				bool field = GameAccess.GetField(val, "deadSet", fallback: false);
				Plugin.Log.LogInfo((object)$"Escape timer expired. Local player position: {GetPlayerWorldPosition(val)}; already dead: {field}.");
				if (!field)
				{
					SpawnExplosionVisual(GetPlayerWorldPosition(val), 1.5f, playSound: true);
					val.PlayerDeath(-1);
					Plugin.Log.LogInfo((object)"The local player was executed by the expired escape timer.");
				}
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				SetPhaseProperty(EventPhase.Expired);
			}
			_phase = EventPhase.Expired;
			DestroyTimerUi();
			((MonoBehaviour)this).StartCoroutine(FinishExpiredEventCleanup());
		}

		private static Vector3 GetPlayerWorldPosition(PlayerAvatar player)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerController.instance != (Object)null)
			{
				return ((Component)PlayerController.instance).transform.position;
			}
			if (!((Object)(object)player.playerTransform != (Object)null))
			{
				return ((Component)player).transform.position;
			}
			return player.playerTransform.position;
		}

		private IEnumerator FinishExpiredEventCleanup()
		{
			yield return (object)new WaitForSecondsRealtime(0.75f);
			if ((Object)(object)_musicSource != (Object)null)
			{
				_musicSource.Stop();
			}
			RestoreWorldAudio();
			RestoreSirenLighting();
		}

		private void StartSirenLighting()
		{
			_nextLightScan = 0f;
			UpdateSirenLighting();
		}

		private void UpdateSirenLighting()
		{
			//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_0194: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime >= _nextLightScan)
			{
				_nextLightScan = Time.unscaledTime + 0.5f;
				Light[] array = Object.FindObjectsOfType<Light>(true);
				foreach (Light val in array)
				{
					if (!((Object)(object)val == (Object)null) && !((Component)val).transform.IsChildOf(((Component)this).transform) && !((Object)(object)((Component)val).GetComponentInParent<Canvas>() != (Object)null) && !((Object)(object)((Component)val).GetComponentInParent<NotForBroadcastBattery>() != (Object)null) && !_sirenLights.ContainsKey(val))
					{
						_sirenLights[val] = new LightState
						{
							Enabled = ((Behaviour)val).enabled,
							Color = val.color,
							Intensity = val.intensity,
							Range = val.range
						};
					}
				}
			}
			bool flag = SemiFunc.Photosensitivity();
			foreach (KeyValuePair<Light, LightState> item in _sirenLights.ToList())
			{
				Light key = item.Key;
				if (!((Object)(object)key == (Object)null))
				{
					float num = (float)(Math.Abs(((Object)key).GetInstanceID()) % 17) * 0.2f;
					float num2 = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * (flag ? 2f : 5f) + num);
					float num3 = (flag ? Mathf.Lerp(0.7f, 1f, num2) : Mathf.Lerp(0.25f, 1.35f, num2));
					((Behaviour)key).enabled = true;
					key.color = new Color(1f, 0.015f, 0.01f);
					key.intensity = Math.Max(0.4f, item.Value.Intensity) * num3;
					key.range = Math.Max(item.Value.Range, 6f);
				}
			}
		}

		private void RestoreSirenLighting()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Light, LightState> sirenLight in _sirenLights)
			{
				if (!((Object)(object)sirenLight.Key == (Object)null))
				{
					((Behaviour)sirenLight.Key).enabled = sirenLight.Value.Enabled;
					sirenLight.Key.color = sirenLight.Value.Color;
					sirenLight.Key.intensity = sirenLight.Value.Intensity;
					sirenLight.Key.range = sirenLight.Value.Range;
				}
			}
			_sirenLights.Clear();
		}

		private void ReconcileLocalBatteries()
		{
			//IL_00bc: 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)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			Batteries.RemoveAll((NotForBroadcastBattery notForBroadcastBattery) => (Object)(object)notForBroadcastBattery == (Object)null);
			foreach (NotForBroadcastBattery battery in Batteries.ToList())
			{
				if (!EventActive || !_batteryTargets.Any((Vector3 val) => Vector3.Distance(val, battery.SpawnPosition) < 0.75f))
				{
					Object.Destroy((Object)(object)((Component)battery).gameObject);
				}
			}
			if (!EventActive)
			{
				return;
			}
			foreach (Vector3 target in _batteryTargets)
			{
				if (!Batteries.Any((NotForBroadcastBattery notForBroadcastBattery) => (Object)(object)notForBroadcastBattery != (Object)null && Vector3.Distance(target, notForBroadcastBattery.SpawnPosition) < 0.75f) && (Object)(object)NotForBroadcastBattery.SpawnLocal(target) != (Object)null)
				{
					Plugin.Log.LogInfo((object)$"Rendered local truck battery at {target}.");
				}
			}
		}

		private void UpdateMapTarget()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < _nextMapUpdate)
			{
				return;
			}
			_nextMapUpdate = Time.time + 0.2f;
			Batteries.RemoveAll((NotForBroadcastBattery battery) => (Object)(object)battery == (Object)null);
			Vector3 val;
			if (_remaining > 0)
			{
				PlayerAvatar localPlayer = SemiFunc.PlayerGetLocal();
				if ((Object)(object)localPlayer == (Object)null)
				{
					return;
				}
				if (_batteryTargets.Count > 0)
				{
					val = _batteryTargets.OrderBy((Vector3 position) => Vector3.Distance(((Component)localPlayer).transform.position, position)).First();
				}
				else
				{
					if (Batteries.Count <= 0)
					{
						return;
					}
					NotForBroadcastBattery notForBroadcastBattery = Batteries.OrderBy((NotForBroadcastBattery battery) => Vector3.Distance(((Component)localPlayer).transform.position, battery.SpawnPosition)).FirstOrDefault();
					if ((Object)(object)notForBroadcastBattery == (Object)null)
					{
						return;
					}
					val = notForBroadcastBattery.SpawnPosition;
				}
			}
			else
			{
				LevelPoint val2 = ((IEnumerable<LevelPoint>)LevelGenerator.Instance?.LevelPathPoints).FirstOrDefault((Func<LevelPoint, bool>)((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null && point.Room.Truck));
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				val = ((Component)val2).transform.position;
			}
			NavMeshHit val3 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val, ref val3, 3f, -1))
			{
				val = ((NavMeshHit)(ref val3)).position;
			}
			MapBacktrack[] array = Object.FindObjectsOfType<MapBacktrack>();
			for (int num = 0; num < array.Length; num++)
			{
				GameAccess.SetField(array[num], "truckDestination", val);
			}
		}

		private void UpdateHazards()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			List<LevelPoint> list = LevelGenerator.Instance?.LevelPathPoints;
			if (list == null || list.Count == 0)
			{
				return;
			}
			List<LevelPoint> list2 = list.Where((LevelPoint point) => (Object)(object)point != (Object)null && (Object)(object)point.Room != (Object)null && !point.Room.Truck).ToList();
			if (list2.Count == 0)
			{
				return;
			}
			if (Time.time >= _nextHazardAt)
			{
				_nextHazardAt = Time.time + Random.Range(0.35f, 1.15f);
				if (TrySelectExplosionPosition(list2, out var position))
				{
					SendHazard(position, 0);
				}
			}
			if (Time.time >= _nextFireAt)
			{
				_nextFireAt = Time.time + Random.Range(3.5f, 8f);
				SendHazard(SelectRandomHazardPosition(list2), 1);
			}
		}

		private static Vector3 SelectRandomHazardPosition(List<LevelPoint> candidates)
		{
			//IL_0012: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			LevelPoint obj = candidates[Random.Range(0, candidates.Count)];
			Vector2 val = Random.insideUnitCircle * Random.Range(0f, 4f);
			Vector3 val2 = ((Component)obj).transform.position + new Vector3(val.x, 0f, val.y);
			NavMeshHit val3 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val2, ref val3, 5f, -1))
			{
				val2 = ((NavMeshHit)(ref val3)).position;
			}
			return val2;
		}

		private static bool TrySelectExplosionPosition(List<LevelPoint> candidates, out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009e: 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)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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)
			position = Vector3.zero;
			List<Vector3> list = (from player in SemiFunc.PlayerGetList()?.Where((PlayerAvatar player) => (Object)(object)player != (Object)null && !GameAccess.GetField(player, "deadSet", fallback: false))
				select (!((Object)(object)player.playerTransform != (Object)null)) ? ((Component)player).transform.position : player.playerTransform.position).ToList() ?? new List<Vector3>();
			if (list.Count == 0)
			{
				position = SelectRandomHazardPosition(candidates);
				return true;
			}
			float num = float.MinValue;
			Vector3 val = Vector3.zero;
			for (int num2 = 0; num2 < 32; num2++)
			{
				Vector3 candidate = SelectRandomHazardPosition(candidates);
				float num3 = list.Min((Vector3 playerPosition) => Vector3.Distance(candidate, playerPosition));
				if (num3 > num)
				{
					num = num3;
					val = candidate;
				}
				if (num3 >= 8.5f)
				{
					position = candidate;
					return true;
				}
			}
			if (num >= 8.5f)
			{
				position = val;
				return true;
			}
			return false;
		}

		private static void SendHazard(Vector3 position, int hazardType)
		{
			//IL_0008: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			object[] array = new object[4] { position.x, position.y, position.z, hazardType };
			HazardEvent.RaiseEvent((object)array, NetworkingEvents.RaiseAll, SendOptions.SendReliable);
		}

		internal static void OnHazardEvent(EventData eventData)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Plugin.Controller == (Object)null || !Plugin.Controller.EventActive || !(eventData.CustomData is object[] array) || array.Length < 4)
			{
				return;
			}
			try
			{
				Vector3 position = default(Vector3);
				((Vector3)(ref position))..ctor(Convert.ToSingle(array[0]), Convert.ToSingle(array[1]), Convert.ToSingle(array[2]));
				int hazardType = Convert.ToInt32(array[3]);
				Plugin.Controller.ReceiveHazard(position, hazardType);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Invalid hazard event: " + ex.Message));
			}
		}

		private void ReceiveHazard(Vector3 position, int hazardType)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (hazardType == 1)
			{
				NotForBroadcastFireHazard.Spawn(position);
				return;
			}
			SpawnExplosionVisual(position, 1f, playSound: true);
			ShakeForMapExplosion();
			PlayerAvatar val = SemiFunc.PlayerGetLocal();
			if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)val).transform.position, position) <= 3.75f)
			{
				val.playerHealth.Hurt(10, false, -1, false);
			}
		}

		private void ShakeForMapExplosion()
		{
			if (!((Object)(object)GameDirector.instance == (Object)null))
			{
				float num = (float)Math.Max(0.0, _deadline - GetClock());
				float num2 = Mathf.Clamp(250f - num, 0f, 250f);
				float num3 = 180f;
				float num4 = Mathf.Clamp01(num2 / num3);
				float num5 = Mathf.Clamp01((70f - num) / 70f);
				float num6 = Mathf.Lerp(0.3f, 4f, Mathf.Pow(num4, 1.2f)) + num5 * 1.5f;
				float num7 = Mathf.Lerp(0.08f, 0.3f, num4) + num5 * 0.08f;
				CameraShake cameraImpact = GameDirector.instance.CameraImpact;
				if (cameraImpact != null)
				{
					cameraImpact.Shake(num6, num7);
				}
				CameraShake cameraShake = GameDirector.instance.CameraShake;
				if (cameraShake != null)
				{
					cameraShake.Shake(num6 * 0.58f, num7 * 1.15f);
				}
			}
		}

		internal static void SpawnExplosionVisual(Vector3 position, float scale, bool playSound = false)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0072: 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_007d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_012c: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (playSound)
			{
				ParticleScriptExplosion val = ((IEnumerable<ParticleScriptExplosion>)Resources.FindObjectsOfTypeAll<ParticleScriptExplosion>()).FirstOrDefault((Func<ParticleScriptExplosion, bool>)((ParticleScriptExplosion source) => (Object)(object)source != (Object)null && (Object)(object)source.explosionPreset != (Object)null));
				if ((Object)(object)val != (Object)null)
				{
					val.PlayExplosionSoundMedium(position);
				}
				else
				{
					Plugin.Log.LogWarning((object)"No explosion sound preset was available for a map detonation.");
				}
			}
			GameObject val2 = new GameObject("Not For Broadcast Visual-Only Explosion");
			val2.layer = LayerMask.NameToLayer("Ignore Raycast");
			val2.transform.position = position + Vector3.up * 0.15f;
			ParticleSystem val3 = val2.AddComponent<ParticleSystem>();
			MainModule main = val3.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).duration = 0.65f;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.35f, 1.15f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(4.5f * scale, 10f * scale);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.12f * scale, 0.55f * scale);
			((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.85f, 0.18f, 1f), new Color(1f, 0.08f, 0.005f, 1f));
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.45f);
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).maxParticles = 160;
			EmissionModule emission = val3.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f);
			((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1]
			{
				new Burst(0f, (short)Mathf.RoundToInt(80f * scale))
			});
			ShapeModule shape = val3.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.25f * scale;
			ColorOverLifetimeModule colorOverLifetime = val3.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			Gradient val4 = new Gradient();
			val4.SetKeys((GradientColorKey[])(object)new GradientColorKey[3]
			{
				new GradientColorKey(new Color(1f, 1f, 0.45f), 0f),
				new GradientColorKey(new Color(1f, 0.12f, 0.01f), 0.35f),
				new GradientColorKey(new Color(0.08f, 0.01f, 0.005f), 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[3]
			{
				new GradientAlphaKey(1f, 0f),
				new GradientAlphaKey(0.9f, 0.45f),
				new GradientAlphaKey(0f, 1f)
			});
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val4);
			CollisionModule collision = val3.collision;
			((CollisionModule)(ref collision)).enabled = false;
			TriggerModule trigger = val3.trigger;
			((TriggerModule)(ref trigger)).enabled = false;
			ParticleSystemRenderer component = ((Component)val3).GetComponent<ParticleSystemRenderer>();
			Shader val5 = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Universal Render Pipeline/Particles/Unlit");
			if ((Object)(object)val5 != (Object)null)
			{
				((Renderer)component).material = new Material(val5);
			}
			GameObject val6 = new GameObject("Explosion Flash")
			{
				layer = val2.layer
			};
			val6.transform.SetParent(val2.transform, false);
			Light obj = val6.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(1f, 0.15f, 0.01f);
			obj.intensity = 5f * scale;
			obj.range = 9f * scale;
			val3.Play();
			Object.Destroy((Object)(object)val2, 1.5f);
		}

		internal bool HandleTruckDeparture(TruckScreenText screen)
		{
			//IL_0017: 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)
			if (!EventActive)
			{
				return true;
			}
			if (!TruckPowered)
			{
				SemiFunc.UIFocusText("TRUCK HAS NO POWER — FIND THE BATTERIES", Color.white, new Color(1f, 0.1f, 0.02f), 3f);
				return false;
			}
			if (!_departureStarted && SemiFunc.IsMasterClientOrSingleplayer())
			{
				_departureStarted = true;
				SetPhaseProperty(EventPhase.Leaving);
				((MonoBehaviour)this).StartCoroutine(DepartureSequence(screen));
			}
			return false;
		}

		private IEnumerator DepartureSequence(TruckScreenText screen)
		{
			_phase = EventPhase.Leaving;
			DestroyTimerUi();
			float startVolume = (((Object)(object)_musicSource != (Object)null) ? _musicSource.volume : 0f);
			float elapsed = 0f;
			while (elapsed < 1.25f)
			{
				elapsed += Time.unscaledDeltaTime;
				if ((Object)(object)_musicSource != (Object)null)
				{
					_musicSource.volume = Mathf.Lerp(startVolume, 0f, elapsed / 1.25f);
				}
				yield return null;
			}
			if ((Object)(object)_musicSource != (Object)null)
			{
				_musicSource.Stop();
			}
			RestoreWorldAudio();
			RestoreSirenLighting();
			AccessTools.Method(typeof(TruckScreenText), "EngineStartSound", (Type[])null, (Type[])null)?.Invoke(screen, null);
			RunManager.instance.ChangeLevel(true, false, (ChangeLevelType)0);
		}

		private void BeginRemoteDeparture()
		{
			if (_phase != EventPhase.Leaving)
			{
				_phase = EventPhase.Leaving;
				DestroyTimerUi();
				((MonoBehaviour)this).StartCoroutine(FadeRemoteAudio());
			}
		}

		private IEnumerator FadeRemoteAudio()
		{
			float startVolume = (((Object)(object)_musicSource != (Object)null) ? _mus