Decompiled source of LethalGrace v1.2.1

LethalGrace.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DozerEntity;
using GameNetcodeStuff;
using HarmonyLib;
using KookooEntity;
using LethalGrace;
using LitanyEntity;
using Microsoft.CodeAnalysis;
using SeesayEntity;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 LethalGrace
{
	[BepInPlugin("LethalGrace", "LethalGrace", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigEntry<int> DozerSpawnChance;

		public static ConfigEntry<float> DozerEyeOpenDelay;

		public static ConfigEntry<float> DozerOpenEyesDuration;

		public static ConfigEntry<float> DozerMinSpawnTime;

		public static ConfigEntry<float> DozerMaxSpawnTime;

		public static ConfigEntry<float> DozerCooldownTime;

		public static ConfigEntry<int> KookooSpawnChance;

		public static ConfigEntry<float> KookooMinSpawnTime;

		public static ConfigEntry<float> KookooMaxSpawnTime;

		public static ConfigEntry<float> KookooCooldownTime;

		public static ConfigEntry<float> KookooAppearDuration;

		public static ConfigEntry<float> KookooCountInterval;

		public static ConfigEntry<int> KookooScanAttackChance;

		public static ConfigEntry<float> KookooScanBlockDuration;

		public static ConfigEntry<int> LitanySpawnChance;

		public static ConfigEntry<float> LitanyMinSpawnTime;

		public static ConfigEntry<float> LitanyMaxSpawnTime;

		public static ConfigEntry<float> LitanyPrepareDuration;

		public static ConfigEntry<float> LitanyWarningDuration;

		public static ConfigEntry<float> LitanyOpenEyeDuration;

		public static ConfigEntry<float> LitanyBetweenEyesDuration;

		public static ConfigEntry<float> LitanyCooldownTime;

		public static ConfigEntry<float> LitanyShakeSpeed;

		public static ConfigEntry<int> SeesaySpawnChance;

		public static ConfigEntry<float> SeesayMinSpawnTime;

		public static ConfigEntry<float> SeesayMaxSpawnTime;

		public static ConfigEntry<float> SeesaySpeed;

		public static ConfigEntry<float> SeesayCooldownTime;

		public static ConfigEntry<bool> SeesayEnableTrainSound;

		public static ConfigEntry<float> SeesayMinFollowTime;

		public static ConfigEntry<float> SeesayMaxFollowTime;

		public static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			DozerSpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("Dozer", "SpawnChance", 30, "Dozer appear chance each round (0-100)");
			DozerEyeOpenDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Dozer", "EyeOpenDelay", 1.5f, "Time before Dozer opens its eyes");
			DozerOpenEyesDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Dozer", "OpenEyesDuration", 0.5f, "How long Dozer keeps its eyes open");
			DozerMinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Dozer", "MinSpawnTime", 30f, "Minimum time before Dozer appears");
			DozerMaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Dozer", "MaxSpawnTime", 200f, "Maximum time before Dozer appears");
			DozerCooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Dozer", "CooldownTime", 60f, "Cooldown before Dozer can appear again");
			KookooSpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("Kookoo", "SpawnChance", 30, "Chance of Kookoo appearing each round (0-100)");
			KookooMinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "MinSpawnTime", 30f, "Minimum time before Kookoo appears");
			KookooMaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "MaxSpawnTime", 200f, "Maximum time before Kookoo appears");
			KookooCooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "CooldownTime", 60f, "Cooldown before Kookoo can appear again");
			KookooAppearDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "AppearDuration", 2f, "Time Kookoo shows the number before counting");
			KookooCountInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "CountInterval", 1f, "Time between each count");
			KookooScanAttackChance = ((BaseUnityPlugin)this).Config.Bind<int>("Kookoo", "ScanAttackChance", 1, "1 in X chance of Kookoo appearing on scan");
			KookooScanBlockDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Kookoo", "ScanBlockDuration", 30f, "How long scan is blocked after Kookoo attack");
			LitanySpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("Litany", "SpawnChance", 35, "Chance of Litany appearing each round (0-100)");
			LitanyMinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "MinSpawnTime", 10f, "Minimum time before Litany appears");
			LitanyMaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "MaxSpawnTime", 30f, "Maximum time before Litany appears");
			LitanyPrepareDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "PrepareDuration", 4f, "Time before first eye warning");
			LitanyWarningDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "WarningDuration", 1.5f, "Duration of warning animation");
			LitanyOpenEyeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "OpenEyeDuration", 0.5f, "How long eye stays open");
			LitanyBetweenEyesDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "BetweenEyesDuration", 2f, "Time between each eye attack");
			LitanyCooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "CooldownTime", 60f, "Cooldown time in seconds before Litany can appear again");
			LitanyShakeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Litany", "ShakeSpeed", 0.05f, "Speed of Litany shaking (lower = faster)");
			SeesaySpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("Seesay", "SpawnChance", 50, "Chance of Seesay appearing each round (0-100)");
			SeesayMinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "MinSpawnTime", 30f, "Minimum time before Seesay appears");
			SeesayMaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "MaxSpawnTime", 90f, "Maximum time before Seesay appears");
			SeesaySpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "SeesaySpeed", 5f, "Speed of Seesay flying towards player");
			SeesayCooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "CooldownTime", 60f, "Cooldown time in seconds before Seesay can appear again");
			SeesayMinFollowTime = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "MinFollowTime", 3f, "Minimum time before Seesay opens its eye");
			SeesayMaxFollowTime = ((BaseUnityPlugin)this).Config.Bind<float>("Seesay", "MaxFollowTime", 8f, "Maximum time before Seesay opens its eye");
			SeesayEnableTrainSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Seesay", "EnableTrainSound", true, "Enable Seesay train sound");
			Patch();
			SceneManager.sceneLoaded += OnSceneLoaded;
			Logger.LogInfo((object)"LethalGrace v1.0.0 has loaded!");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			if (!(((Scene)(ref scene)).name != "SampleSceneRelay") || ((Scene)(ref scene)).name.Contains("Sample"))
			{
				Logger.LogInfo((object)"LethalGrace: игровая сцена загружена!");
				if ((Object)(object)Object.FindObjectOfType<DozerBehaviour>() == (Object)null)
				{
					GameObject val = new GameObject("DozerManager");
					val.AddComponent<DozerBehaviour>();
					Logger.LogInfo((object)"LethalGrace: DozerManager создан!");
				}
				if ((Object)(object)Object.FindObjectOfType<KookooBehaviour>() == (Object)null)
				{
					GameObject val2 = new GameObject("KookooManager");
					val2.AddComponent<KookooBehaviour>();
					Logger.LogInfo((object)"LethalGrace: KookooManager создан!");
				}
				if ((Object)(object)Object.FindObjectOfType<LitanyBehaviour>() == (Object)null)
				{
					GameObject val3 = new GameObject("LitanyManager");
					val3.AddComponent<LitanyBehaviour>();
					Debug.Log((object)"LethalGrace: LitanyManager создан!");
				}
				if ((Object)(object)Object.FindObjectOfType<SeesayBehaviour>() == (Object)null)
				{
					GameObject val4 = new GameObject("SeesayManager");
					val4.AddComponent<SeesayBehaviour>();
					Debug.Log((object)"LethalGrace: SeesayManager создан!");
				}
			}
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("LethalGrace");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalGrace";

		public const string PLUGIN_NAME = "LethalGrace";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalGrace.Patches
{
	[HarmonyPatch(typeof(TVScript))]
	public class ExampleTVPatch
	{
		[HarmonyPatch("SwitchTVLocalClient")]
		[HarmonyPrefix]
		private static void SwitchTVPrefix(TVScript __instance)
		{
			StartOfRound.Instance.shipRoomLights.SetShipLightsBoolean(__instance.tvOn);
		}
	}
}
namespace SeesayEntity
{
	public class SeesayBehaviour : MonoBehaviour
	{
		private enum SeesayState
		{
			Hidden,
			Following,
			Opening,
			Flying,
			Screamer
		}

		private Dictionary<AudioSource, float> mutedAudioSources = new Dictionary<AudioSource, float>();

		private bool gameAudioMuted = false;

		private GameObject canvasObject;

		private VideoPlayer videoPlayer;

		private AudioSource videoAudioSource;

		private RawImage videoImage;

		private RenderTexture videoTexture;

		private bool videoFinished = false;

		private float flyingShakeStrength = 0.035f;

		private float flyingShakeSpeed = 45f;

		private float flyingRotationStrength = 5f;

		private float flyingShakeTimer = 0f;

		private Vector3 flyingShakeOffset = Vector3.zero;

		private float flyingRotationOffset = 0f;

		private Vector3 flyingBasePosition;

		private SeesayState currentState = SeesayState.Hidden;

		private float timer = 0f;

		private float nextAppearTime = 0f;

		private float followDuration = 5f;

		private bool isOnCooldown = false;

		private float cooldownTimer = 0f;

		private float cooldownTime = 0f;

		private bool wasLanded = false;

		private bool seesayAllowedThisRound = false;

		private AudioSource audioSource;

		private AudioClip appearClip;

		private AudioClip open1Clip;

		private AudioClip open2Clip;

		private AudioClip attackClip;

		private AudioClip flashedClip;

		private AudioSource flyingAudioSource;

		private AudioClip flyingClip;

		private AudioClip trainClip;

		private AudioSource trainAudioSource;

		private GameObject seesayObject;

		private SpriteRenderer spriteRenderer;

		private Camera mainCamera;

		private Sprite closedSprite;

		private Sprite[] animSprites = (Sprite[])(object)new Sprite[10];

		private Sprite flashedSprite;

		private float animTimer = 0f;

		private int animFrame = 0;

		private bool animPaused = false;

		private float animPauseTimer = 0f;

		private bool isFlashed = false;

		private float flashedTimer = 0f;

		private float distanceFromCamera = 3f;

		private Vector3 frozenWorldPos = Vector3.zero;

		private float shakeTimer = 0f;

		private float shakeSpeed = 0.05f;

		private Vector3 shakeOffset = Vector3.zero;

		private string modFolder;

		private Vector3 previousFlyingShakeOffset = Vector3.zero;

		private void Start()
		{
			modFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Seesay");
			Debug.Log((object)("Seesay DEBUG: путь к ресурсам: " + modFolder));
			LoadSprites();
			CreateSeesay3D();
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			audioSource.loop = false;
			audioSource.playOnAwake = false;
			audioSource.volume = 10f;
			audioSource.spatialBlend = 0f;
			flyingClip = LoadAudioClip("Flying.mp3");
			flyingAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			flyingAudioSource.loop = true;
			flyingAudioSource.playOnAwake = false;
			flyingAudioSource.volume = 1f;
			flyingAudioSource.spatialBlend = 1f;
			flyingAudioSource.maxDistance = 20f;
			flyingAudioSource.rolloffMode = (AudioRolloffMode)1;
			trainClip = LoadAudioClip("Train.mp3");
			trainAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			trainAudioSource.loop = true;
			trainAudioSource.playOnAwake = false;
			trainAudioSource.volume = 1f;
			trainAudioSource.spatialBlend = 1f;
			trainAudioSource.maxDistance = 15f;
			trainAudioSource.rolloffMode = (AudioRolloffMode)1;
			appearClip = LoadAudioClip("Appear.mp3");
			open1Clip = LoadAudioClip("Open1.mp3");
			open2Clip = LoadAudioClip("Open2.mp3");
			attackClip = LoadAudioClip("Attack.mp3");
			flashedClip = LoadAudioClip("Flashed.mp3");
			nextAppearTime = Random.Range(Plugin.SeesayMinSpawnTime.Value, Plugin.SeesayMaxSpawnTime.Value);
		}

		private void CreateSeesay3D()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01e4: 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_0206: 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)
			seesayObject = new GameObject("SeesaySprite");
			spriteRenderer = seesayObject.AddComponent<SpriteRenderer>();
			((Renderer)spriteRenderer).sortingOrder = 100;
			seesayObject.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
			seesayObject.SetActive(false);
			canvasObject = new GameObject("SeesayCanvas");
			GameObject val = canvasObject;
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 200;
			videoTexture = new RenderTexture(1920, 1080, 0);
			GameObject val3 = new GameObject("SeesayVideoPlayer");
			val3.transform.SetParent(val.transform, false);
			videoPlayer = val3.AddComponent<VideoPlayer>();
			videoPlayer.playOnAwake = false;
			videoPlayer.renderMode = (VideoRenderMode)2;
			videoPlayer.targetTexture = videoTexture;
			videoPlayer.loopPointReached += new EventHandler(OnVideoFinished);
			videoAudioSource = val3.AddComponent<AudioSource>();
			videoAudioSource.playOnAwake = false;
			videoAudioSource.spatialBlend = 0f;
			videoAudioSource.volume = 1f;
			videoPlayer.audioOutputMode = (VideoAudioOutputMode)1;
			videoPlayer.controlledAudioTrackCount = 1;
			videoPlayer.EnableAudioTrack((ushort)0, true);
			videoPlayer.SetTargetAudioSource((ushort)0, videoAudioSource);
			GameObject val4 = new GameObject("SeesayVideo");
			val4.transform.SetParent(val.transform, false);
			videoImage = val4.AddComponent<RawImage>();
			videoImage.texture = (Texture)(object)videoTexture;
			((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
			RectTransform component = val4.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.sizeDelta = Vector2.zero;
		}

		private void OnVideoFinished(VideoPlayer vp)
		{
			videoFinished = true;
		}

		private AudioClip LoadAudioClip(string filename)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Seesay Entity: звук не найден — " + text));
				return null;
			}
			WWW val = new WWW("file://" + text);
			try
			{
				while (!val.isDone)
				{
				}
				return val.GetAudioClip(false, false, (AudioType)13);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private void LoadSprites()
		{
			closedSprite = LoadSprite("closed.png");
			flashedSprite = LoadSprite("flashed.png");
			for (int i = 0; i < 10; i++)
			{
				animSprites[i] = LoadSprite($"anim{i + 1}.png");
			}
		}

		private Sprite LoadSprite(string filename)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Seesay Entity: файл не найден — " + text));
				return null;
			}
			byte[] array = File.ReadAllBytes(text);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private void Update()
		{
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded && (Object)(object)StartOfRound.Instance.currentLevel != (Object)null && StartOfRound.Instance.currentLevel.sceneName != "CompanyBuilding";
			if (flag && !wasLanded)
			{
				int num = Random.Range(0, 100);
				bool flag2 = (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.timesFulfilledQuota >= 1;
				seesayAllowedThisRound = flag2 && num < Mathf.Clamp(Plugin.SeesaySpawnChance.Value, 0, 100);
				Debug.Log((object)("Seesay DEBUG: новый раунд! " + $"Шанс={Plugin.SeesaySpawnChance.Value}%, " + $"выпало={num}, " + $"вторая квота достигнута={flag2}, " + $"Seesay разрешена={seesayAllowedThisRound}"));
			}
			if (!flag && wasLanded)
			{
				seesayAllowedThisRound = false;
				ForceHide();
			}
			wasLanded = flag;
			if ((Object)(object)mainCamera == (Object)null)
			{
				Camera[] allCameras = Camera.allCameras;
				foreach (Camera val2 in allCameras)
				{
					if (((Behaviour)val2).isActiveAndEnabled && ((Object)val2).name == "MainCamera")
					{
						mainCamera = val2;
						break;
					}
				}
			}
			if (val.isPlayerDead)
			{
				if (currentState != SeesayState.Hidden)
				{
					ForceHide();
				}
				return;
			}
			if (!IsPlayerInGame())
			{
				if (currentState != SeesayState.Hidden)
				{
					ForceHide();
				}
				return;
			}
			if (isOnCooldown)
			{
				cooldownTimer += Time.deltaTime;
				if (cooldownTimer >= cooldownTime)
				{
					isOnCooldown = false;
					cooldownTimer = 0f;
					timer = 0f;
					nextAppearTime = Random.Range(Plugin.SeesayMinSpawnTime.Value, Plugin.SeesayMaxSpawnTime.Value);
				}
				return;
			}
			timer += Time.deltaTime;
			switch (currentState)
			{
			case SeesayState.Hidden:
				if (seesayAllowedThisRound && timer >= nextAppearTime)
				{
					Appear(val);
				}
				break;
			case SeesayState.Following:
				UpdateFollowingPosition(val);
				if (timer >= followDuration)
				{
					StartOpening();
				}
				break;
			case SeesayState.Opening:
				seesayObject.transform.position = frozenWorldPos + shakeOffset;
				if ((Object)(object)mainCamera != (Object)null)
				{
					Vector3 val4 = ((Component)mainCamera).transform.position - seesayObject.transform.position;
					if (((Vector3)(ref val4)).sqrMagnitude > 0.001f)
					{
						seesayObject.transform.rotation = Quaternion.LookRotation(val4, Vector3.up);
					}
				}
				AnimateOpening(val);
				break;
			case SeesayState.Flying:
				if (isFlashed)
				{
					flashedTimer += Time.deltaTime;
					if (flashedTimer >= 0.5f)
					{
						Hide();
					}
					return;
				}
				FlyTowardsPlayer(val);
				UpdateFlyingShake();
				break;
			case SeesayState.Screamer:
				if (videoFinished)
				{
					((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
					PlayerControllerB val3 = GameNetworkManager.Instance?.localPlayerController;
					if ((Object)(object)val3 != (Object)null)
					{
						val3.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false);
					}
					Hide();
				}
				break;
			}
			if (currentState == SeesayState.Following || currentState == SeesayState.Opening)
			{
				UpdateShake();
			}
		}

		private void UpdateFollowingPosition(PlayerControllerB player)
		{
			//IL_0032: 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_004d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)mainCamera == (Object)null) && !((Object)(object)seesayObject == (Object)null))
			{
				Vector3 val = ((Component)mainCamera).transform.position + ((Component)mainCamera).transform.forward * distanceFromCamera;
				float num = 3f;
				seesayObject.transform.position = Vector3.Lerp(seesayObject.transform.position, val, 1f - Mathf.Exp((0f - num) * Time.deltaTime));
				Vector3 val2 = ((Component)mainCamera).transform.position - seesayObject.transform.position;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
				{
					seesayObject.transform.rotation = Quaternion.LookRotation(val2, Vector3.up);
				}
			}
		}

		private void UpdateShake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			shakeTimer += Time.deltaTime;
			if (shakeTimer >= shakeSpeed)
			{
				shakeTimer = 0f;
				shakeOffset = new Vector3(Random.Range(-0.05f, 0.05f), Random.Range(-0.05f, 0.05f), 0f);
			}
		}

		private void StartOpening()
		{
			//IL_0048: 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_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)
			currentState = SeesayState.Opening;
			timer = 0f;
			animFrame = 0;
			animTimer = 0f;
			animPaused = false;
			if ((Object)(object)mainCamera != (Object)null)
			{
				frozenWorldPos = seesayObject.transform.position - shakeOffset;
			}
			if ((Object)(object)animSprites[0] != (Object)null)
			{
				spriteRenderer.sprite = animSprites[0];
			}
		}

		private void AnimateOpening(PlayerControllerB player)
		{
			if (animPaused)
			{
				animPauseTimer += Time.deltaTime;
				if (animPauseTimer >= 0.2f)
				{
					animPaused = false;
					animPauseTimer = 0f;
					if ((Object)(object)open2Clip != (Object)null)
					{
						audioSource.clip = open2Clip;
						audioSource.Play();
					}
				}
				return;
			}
			animTimer += Time.deltaTime;
			if (animTimer >= 0.0667f)
			{
				animTimer = 0f;
				animFrame++;
				if (animFrame == 1 && (Object)(object)open1Clip != (Object)null)
				{
					audioSource.clip = open1Clip;
					audioSource.Play();
				}
				if (animFrame == 3)
				{
					animPaused = true;
					spriteRenderer.sprite = animSprites[3];
				}
				else if (animFrame >= 10)
				{
					StartFlying(player);
				}
				else if ((Object)(object)animSprites[animFrame] != (Object)null)
				{
					spriteRenderer.sprite = animSprites[animFrame];
				}
			}
		}

		private void StartFlying(PlayerControllerB player)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//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_0096: Unknown result type (might be due to invalid IL or missing references)
			flyingBasePosition = seesayObject.transform.position;
			flyingShakeTimer = 0f;
			previousFlyingShakeOffset = Vector3.zero;
			currentState = SeesayState.Flying;
			timer = 0f;
			if ((Object)(object)attackClip != (Object)null)
			{
				audioSource.clip = attackClip;
				audioSource.Play();
			}
			if ((Object)(object)flyingClip != (Object)null)
			{
				((Component)flyingAudioSource).transform.position = seesayObject.transform.position;
				flyingAudioSource.clip = flyingClip;
				flyingAudioSource.Play();
			}
		}

		private void FlyTowardsPlayer(PlayerControllerB player)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0055: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00bf: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)mainCamera).transform.position;
			flyingBasePosition = Vector3.MoveTowards(flyingBasePosition, position, Plugin.SeesaySpeed.Value * Time.deltaTime);
			seesayObject.transform.position = flyingBasePosition;
			Vector3 val = position - flyingBasePosition;
			if (((Vector3)(ref val)).sqrMagnitude > 0.001f)
			{
				seesayObject.transform.rotation = Quaternion.LookRotation(val, Vector3.up);
			}
			if (IsFlashlightAimingAtSeesay(player))
			{
				TriggerFlashed();
				return;
			}
			float num = Vector3.Distance(flyingBasePosition, position);
			if (Plugin.SeesayEnableTrainSound.Value && num < 10f)
			{
				if ((Object)(object)trainClip != (Object)null && !trainAudioSource.isPlaying)
				{
					trainAudioSource.clip = trainClip;
					trainAudioSource.Play();
				}
			}
			else if (trainAudioSource.isPlaying)
			{
				trainAudioSource.Stop();
			}
			((Component)trainAudioSource).transform.position = flyingBasePosition;
			((Component)flyingAudioSource).transform.position = flyingBasePosition;
			if (num < 0.5f)
			{
				TriggerScreamer();
			}
		}

		private void TriggerScreamer()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			currentState = SeesayState.Screamer;
			videoFinished = false;
			seesayObject.SetActive(false);
			string text = Path.Combine(modFolder, "Death.mp4");
			videoPlayer.url = "file://" + text;
			MuteGameAudio();
			videoPlayer.Play();
			((Graphic)videoImage).color = new Color(1f, 1f, 1f, 1f);
			flyingAudioSource.Stop();
			trainAudioSource.Stop();
		}

		private void TriggerFlashed()
		{
			if ((Object)(object)flashedClip != (Object)null)
			{
				audioSource.clip = flashedClip;
				audioSource.Play();
			}
			isFlashed = true;
			flashedTimer = 0f;
			if ((Object)(object)flashedSprite != (Object)null)
			{
				spriteRenderer.sprite = flashedSprite;
			}
			flyingAudioSource.Stop();
		}

		private bool CheckFlashlightCondition(PlayerControllerB player)
		{
			GrabbableObject[] itemSlots = player.ItemSlots;
			foreach (GrabbableObject val in itemSlots)
			{
				if ((Object)(object)val != (Object)null && val is FlashlightItem)
				{
					return true;
				}
			}
			if ((Object)(object)player.currentlyHeldObjectServer != (Object)null && player.currentlyHeldObjectServer is FlashlightItem)
			{
				return true;
			}
			return false;
		}

		private bool IsFlashlightAimingAtSeesay(PlayerControllerB player)
		{
			//IL_003d: 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_0047: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mainCamera == (Object)null || (Object)(object)seesayObject == (Object)null)
			{
				return false;
			}
			Vector3 val = mainCamera.WorldToViewportPoint(seesayObject.transform.position);
			if (!(val.z > 0f) || !(val.x > 0.2f) || !(val.x < 0.8f) || !(val.y > 0.2f) || !(val.y < 0.8f))
			{
				return false;
			}
			GrabbableObject[] itemSlots = player.ItemSlots;
			foreach (GrabbableObject val2 in itemSlots)
			{
				FlashlightItem val3 = (FlashlightItem)(object)((val2 is FlashlightItem) ? val2 : null);
				if (val3 != null && ((GrabbableObject)val3).isBeingUsed)
				{
					return true;
				}
			}
			GrabbableObject itemOnlySlot = player.ItemOnlySlot;
			FlashlightItem val4 = (FlashlightItem)(object)((itemOnlySlot is FlashlightItem) ? itemOnlySlot : null);
			if (val4 != null && ((GrabbableObject)val4).isBeingUsed)
			{
				return true;
			}
			GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
			FlashlightItem val5 = (FlashlightItem)(object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null);
			if (val5 != null && ((GrabbableObject)val5).isBeingUsed)
			{
				return true;
			}
			return false;
		}

		private void Appear(PlayerControllerB player)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mainCamera != (Object)null)
			{
				seesayObject.transform.position = ((Component)mainCamera).transform.position + ((Component)mainCamera).transform.forward * distanceFromCamera;
				seesayObject.transform.rotation = Quaternion.LookRotation(((Component)mainCamera).transform.position - seesayObject.transform.position, Vector3.up);
			}
			currentState = SeesayState.Following;
			timer = 0f;
			seesayObject.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
			followDuration = Random.Range(Plugin.SeesayMinFollowTime.Value, Plugin.SeesayMaxFollowTime.Value);
			if ((Object)(object)closedSprite != (Object)null)
			{
				spriteRenderer.sprite = closedSprite;
			}
			seesayObject.SetActive(true);
			if ((Object)(object)appearClip != (Object)null)
			{
				audioSource.clip = appearClip;
				audioSource.Play();
			}
		}

		private void Hide()
		{
			RestoreGameAudio();
			currentState = SeesayState.Hidden;
			timer = 0f;
			seesayObject.SetActive(false);
			isFlashed = false;
			isOnCooldown = true;
			cooldownTimer = 0f;
			cooldownTime = Plugin.SeesayCooldownTime.Value;
			flyingAudioSource.Stop();
			trainAudioSource.Stop();
		}

		public void ForceHide()
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			RestoreGameAudio();
			currentState = SeesayState.Hidden;
			timer = 0f;
			seesayObject.SetActive(false);
			isFlashed = false;
			flashedTimer = 0f;
			animPaused = false;
			animTimer = 0f;
			animFrame = 0;
			isOnCooldown = false;
			cooldownTimer = 0f;
			nextAppearTime = Random.Range(Plugin.SeesayMinSpawnTime.Value, Plugin.SeesayMaxSpawnTime.Value);
			audioSource.Stop();
			flyingAudioSource.Stop();
			trainAudioSource.Stop();
			if ((Object)(object)videoPlayer != (Object)null)
			{
				videoPlayer.Stop();
			}
			if ((Object)(object)videoImage != (Object)null)
			{
				((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
			}
			videoFinished = false;
		}

		public void ResetSeesay()
		{
			currentState = SeesayState.Hidden;
			timer = 0f;
			nextAppearTime = Random.Range(Plugin.SeesayMinSpawnTime.Value, Plugin.SeesayMaxSpawnTime.Value);
			seesayObject.SetActive(false);
			isOnCooldown = false;
			cooldownTimer = 0f;
		}

		private bool IsPlayerInGame()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (val.isPlayerDead)
			{
				return false;
			}
			if (StartOfRound.Instance?.currentLevel?.sceneName == "CompanyBuilding")
			{
				return false;
			}
			if ((Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.timesFulfilledQuota < 1)
			{
				return false;
			}
			return !val.isInHangarShipRoom && (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded;
		}

		private void OnDestroy()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			RestoreGameAudio();
			if ((Object)(object)videoPlayer != (Object)null)
			{
				videoPlayer.loopPointReached -= new EventHandler(OnVideoFinished);
				videoPlayer.Stop();
				videoPlayer.targetTexture = null;
			}
			if ((Object)(object)canvasObject != (Object)null)
			{
				Object.Destroy((Object)(object)canvasObject);
				canvasObject = null;
			}
			if ((Object)(object)videoTexture != (Object)null)
			{
				videoTexture.Release();
				Object.Destroy((Object)(object)videoTexture);
				videoTexture = null;
			}
			if ((Object)(object)seesayObject != (Object)null)
			{
				Object.Destroy((Object)(object)seesayObject);
				seesayObject = null;
			}
		}

		private void MuteGameAudio()
		{
			if (gameAudioMuted)
			{
				return;
			}
			mutedAudioSources.Clear();
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
			foreach (AudioSource val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)videoAudioSource))
				{
					mutedAudioSources[val] = val.volume;
					val.volume = 0f;
				}
			}
			gameAudioMuted = true;
		}

		private void RestoreGameAudio()
		{
			if (!gameAudioMuted)
			{
				return;
			}
			foreach (KeyValuePair<AudioSource, float> mutedAudioSource in mutedAudioSources)
			{
				if ((Object)(object)mutedAudioSource.Key != (Object)null)
				{
					mutedAudioSource.Key.volume = mutedAudioSource.Value;
				}
			}
			mutedAudioSources.Clear();
			gameAudioMuted = false;
		}

		private void UpdateFlyingShake()
		{
			//IL_00b8: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_0135: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)seesayObject == (Object)null) && !((Object)(object)mainCamera == (Object)null))
			{
				flyingShakeTimer += Time.deltaTime;
				if (flyingShakeTimer >= 1f / flyingShakeSpeed)
				{
					flyingShakeTimer = 0f;
					flyingShakeOffset = new Vector3(Random.Range(0f - flyingShakeStrength, flyingShakeStrength), Random.Range(0f - flyingShakeStrength, flyingShakeStrength), 0f);
					flyingRotationOffset = Random.Range(0f - flyingRotationStrength, flyingRotationStrength);
				}
				Vector3 val = ((Component)mainCamera).transform.right * flyingShakeOffset.x + ((Component)mainCamera).transform.up * flyingShakeOffset.y;
				seesayObject.transform.position = flyingBasePosition + val;
				Vector3 val2 = ((Component)mainCamera).transform.position - seesayObject.transform.position;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
				{
					Quaternion val3 = Quaternion.LookRotation(val2, Vector3.up);
					seesayObject.transform.rotation = val3 * Quaternion.Euler(0f, 0f, flyingRotationOffset);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
	public class SeesayDeathPatch
	{
		private static void Postfix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				SeesayBehaviour seesayBehaviour = Object.FindObjectOfType<SeesayBehaviour>();
				if ((Object)(object)seesayBehaviour != (Object)null)
				{
					seesayBehaviour.ForceHide();
				}
			}
		}
	}
}
namespace LitanyEntity
{
	public class LitanyBehaviour : MonoBehaviour
	{
		private enum LitanyState
		{
			Hidden,
			Preparing,
			Warning,
			EyeOpen,
			BetweenEyes,
			Screamer
		}

		private GameObject canvasObject;

		private bool wasOnMoon = false;

		private bool litanyAllowedThisRound = false;

		private AudioSource videoAudioSource;

		private LitanyState currentState = LitanyState.Hidden;

		private float timer = 0f;

		private float nextAppearTime = 0f;

		private int currentEye = 0;

		private bool isOnCooldown = false;

		private float cooldownTimer = 0f;

		private float cooldownTime = 0f;

		private GameObject rootObject;

		private Image bodyImage;

		private Image eyeImage;

		private Sprite bodySprite;

		private Sprite eyesClosedSprite;

		private Sprite[] eyeWarningSprites = (Sprite[])(object)new Sprite[3];

		private Sprite[] eyeOpenedSprites = (Sprite[])(object)new Sprite[3];

		private float shakeTimer = 0f;

		private float eyeAnimTimer = 0f;

		private int eyeAnimFrame = 0;

		private Vector2 basePosition;

		private AudioSource idleSource;

		private AudioSource screamsSource;

		private AudioSource oneShotSource;

		private AudioClip idleClip;

		private AudioClip prepareClip;

		private AudioClip[] openClips = (AudioClip[])(object)new AudioClip[3];

		private AudioClip screamsClip;

		private VideoPlayer videoPlayer;

		private RawImage videoImage;

		private RenderTexture videoTexture;

		private bool videoFinished = false;

		private readonly Dictionary<AudioSource, float> mutedSources = new Dictionary<AudioSource, float>();

		private string modFolder;

		private void MuteGameSounds()
		{
			mutedSources.Clear();
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
			foreach (AudioSource val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)videoAudioSource))
				{
					mutedSources[val] = val.volume;
					val.volume = 0f;
				}
			}
			Debug.Log((object)$"Litany DEBUG: заглушено {mutedSources.Count} источников звука");
		}

		private void RestoreGameSounds()
		{
			foreach (KeyValuePair<AudioSource, float> mutedSource in mutedSources)
			{
				if ((Object)(object)mutedSource.Key != (Object)null)
				{
					mutedSource.Key.volume = mutedSource.Value;
				}
			}
			mutedSources.Clear();
			Debug.Log((object)"Litany DEBUG: звуки игры восстановлены");
		}

		private void Start()
		{
			modFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Litany");
			Debug.Log((object)("Litany DEBUG: папка ресурсов = " + modFolder));
			LoadSprites();
			CreateOverlay();
			LoadAudio();
			nextAppearTime = Random.Range(Plugin.LitanyMinSpawnTime.Value, Plugin.LitanyMaxSpawnTime.Value);
		}

		private void LoadSprites()
		{
			bodySprite = LoadSprite("body.png");
			eyesClosedSprite = LoadSprite("eyes_closed.png");
			for (int i = 0; i < 3; i++)
			{
				eyeWarningSprites[i] = LoadSprite($"eye{i + 1}_warning.png");
				eyeOpenedSprites[i] = LoadSprite($"eye{i + 1}_opened.png");
			}
		}

		private void LoadAudio()
		{
			idleClip = LoadAudioClip("idle.mp3");
			prepareClip = LoadAudioClip("prepare.mp3");
			openClips[0] = LoadAudioClip("open1.mp3");
			openClips[1] = LoadAudioClip("open2.mp3");
			openClips[2] = LoadAudioClip("open3.mp3");
			screamsClip = LoadAudioClip("screams.mp3");
			idleSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			idleSource.loop = true;
			idleSource.playOnAwake = false;
			screamsSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			screamsSource.loop = true;
			screamsSource.playOnAwake = false;
			oneShotSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			oneShotSource.loop = false;
			oneShotSource.playOnAwake = false;
		}

		private AudioClip LoadAudioClip(string filename)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Litany Entity: звук не найден — " + text));
				return null;
			}
			WWW val = new WWW("file://" + text);
			try
			{
				while (!val.isDone)
				{
				}
				return val.GetAudioClip(false, false, (AudioType)13);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private Sprite LoadSprite(string filename)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Litany Entity: file not found — " + text));
				return null;
			}
			byte[] array = File.ReadAllBytes(text);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private void Update()
		{
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			StartOfRound instance = StartOfRound.Instance;
			bool flag = (Object)(object)instance != (Object)null && (Object)(object)instance.currentLevel != (Object)null && instance.currentLevel.sceneName != "CompanyBuilding" && instance.shipHasLanded;
			if (flag && !wasOnMoon)
			{
				isOnCooldown = false;
				cooldownTimer = 0f;
				cooldownTime = Plugin.LitanyCooldownTime.Value;
				int num = Random.Range(0, 100);
				litanyAllowedThisRound = num < Mathf.Clamp(Plugin.LitanySpawnChance.Value, 0, 100);
				Debug.Log((object)($"Litany DEBUG: новый раунд! Шанс = {Plugin.LitanySpawnChance.Value}%, " + $"выпало {num}, Litany разрешена = {litanyAllowedThisRound}"));
				timer = 0f;
				nextAppearTime = Random.Range(Plugin.LitanyMinSpawnTime.Value, Plugin.LitanyMaxSpawnTime.Value);
			}
			if (!flag && wasOnMoon)
			{
				Debug.Log((object)"Litany DEBUG: раунд завершён");
				litanyAllowedThisRound = false;
				ForceHide();
				isOnCooldown = false;
				cooldownTimer = 0f;
				timer = 0f;
			}
			wasOnMoon = flag;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (currentState != LitanyState.Hidden)
			{
				AnimateBody();
			}
			if (val.isPlayerDead)
			{
				ForceHide();
				return;
			}
			if (isOnCooldown)
			{
				cooldownTimer += Time.deltaTime;
				if (cooldownTimer >= cooldownTime)
				{
					isOnCooldown = false;
					cooldownTimer = 0f;
					timer = 0f;
					nextAppearTime = Random.Range(Plugin.LitanyMinSpawnTime.Value, Plugin.LitanyMaxSpawnTime.Value);
				}
				return;
			}
			if (!IsPlayerInGame())
			{
				if (currentState != LitanyState.Hidden)
				{
					ForceHide();
					Debug.Log((object)"Litany DEBUG: атака отменена — игрок вне игровой зоны");
				}
				return;
			}
			if (val.quickMenuManager.isMenuOpen)
			{
				rootObject.SetActive(false);
				return;
			}
			if (currentState != LitanyState.Hidden && currentState != LitanyState.Screamer)
			{
				rootObject.SetActive(true);
			}
			timer += Time.deltaTime;
			switch (currentState)
			{
			case LitanyState.Hidden:
				if (litanyAllowedThisRound && timer >= nextAppearTime)
				{
					Appear();
				}
				break;
			case LitanyState.Preparing:
				if (timer >= Plugin.LitanyPrepareDuration.Value)
				{
					StartWarning();
				}
				break;
			case LitanyState.Warning:
				AnimateWarning();
				if (timer >= Plugin.LitanyWarningDuration.Value)
				{
					OpenEye();
				}
				break;
			case LitanyState.EyeOpen:
				if (!IsPlayerCrouching())
				{
					TriggerDeath();
				}
				else if (timer >= Plugin.LitanyOpenEyeDuration.Value)
				{
					CloseEye();
				}
				break;
			case LitanyState.BetweenEyes:
				if (timer >= Plugin.LitanyBetweenEyesDuration.Value)
				{
					if (currentEye >= 3)
					{
						Hide();
					}
					else
					{
						StartWarning();
					}
				}
				break;
			case LitanyState.Screamer:
				if (videoFinished)
				{
					((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
					PlayerControllerB val2 = GameNetworkManager.Instance?.localPlayerController;
					if ((Object)(object)val2 != (Object)null)
					{
						val2.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false);
					}
					Hide();
				}
				break;
			}
		}

		private void AnimateBody()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			shakeTimer += Time.deltaTime;
			if (shakeTimer >= Plugin.LitanyShakeSpeed.Value)
			{
				shakeTimer = 0f;
				float num = Random.Range(-8f, 8f);
				float num2 = Random.Range(-8f, 8f);
				float num3 = Random.Range(-5f, 5f);
				rootObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(basePosition.x + num, basePosition.y + num2);
				((Transform)rootObject.GetComponent<RectTransform>()).localRotation = Quaternion.Euler(0f, 0f, num3);
			}
		}

		private void AnimateWarning()
		{
			eyeAnimTimer += Time.deltaTime;
			if (eyeAnimTimer >= 0.15f)
			{
				eyeAnimTimer = 0f;
				eyeAnimFrame = (eyeAnimFrame + 1) % 2;
				eyeImage.sprite = ((eyeAnimFrame == 0) ? eyesClosedSprite : eyeWarningSprites[currentEye]);
			}
		}

		private void Appear()
		{
			//IL_003d: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			currentState = LitanyState.Preparing;
			timer = 0f;
			currentEye = 0;
			float num = Random.Range(-500f, 500f);
			float num2 = Random.Range(-250f, 250f);
			basePosition = new Vector2(num, num2);
			rootObject.GetComponent<RectTransform>().anchoredPosition = basePosition;
			rootObject.SetActive(true);
			if ((Object)(object)bodySprite != (Object)null)
			{
				bodyImage.sprite = bodySprite;
			}
			if ((Object)(object)eyesClosedSprite != (Object)null)
			{
				eyeImage.sprite = eyesClosedSprite;
			}
			if ((Object)(object)idleClip != (Object)null)
			{
				idleSource.clip = idleClip;
				idleSource.Play();
			}
		}

		private void StartWarning()
		{
			currentState = LitanyState.Warning;
			timer = 0f;
			eyeAnimFrame = 0;
			eyeAnimTimer = 0f;
			if ((Object)(object)prepareClip != (Object)null)
			{
				oneShotSource.Stop();
				oneShotSource.clip = prepareClip;
				oneShotSource.Play();
			}
		}

		private void OpenEye()
		{
			currentState = LitanyState.EyeOpen;
			timer = 0f;
			if ((Object)(object)eyeOpenedSprites[currentEye] != (Object)null)
			{
				eyeImage.sprite = eyeOpenedSprites[currentEye];
			}
			if ((Object)(object)openClips[currentEye] != (Object)null)
			{
				oneShotSource.Stop();
				oneShotSource.clip = openClips[currentEye];
				oneShotSource.Play();
			}
			if (currentEye == 0 && (Object)(object)screamsClip != (Object)null)
			{
				screamsSource.clip = screamsClip;
				screamsSource.Play();
			}
		}

		private void CloseEye()
		{
			//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_0084: Unknown result type (might be due to invalid IL or missing references)
			currentEye++;
			if (currentEye >= 3)
			{
				Hide();
				return;
			}
			if ((Object)(object)eyesClosedSprite != (Object)null)
			{
				eyeImage.sprite = eyesClosedSprite;
			}
			float num = Random.Range(-500f, 500f);
			float num2 = Random.Range(-250f, 250f);
			basePosition = new Vector2(num, num2);
			rootObject.GetComponent<RectTransform>().anchoredPosition = basePosition;
			currentState = LitanyState.BetweenEyes;
			timer = 0f;
		}

		private void TriggerDeath()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			currentState = LitanyState.Screamer;
			videoFinished = false;
			rootObject.SetActive(false);
			idleSource.Stop();
			screamsSource.Stop();
			oneShotSource.Stop();
			MuteGameSounds();
			string text = Path.Combine(modFolder, "Death.mp4");
			videoPlayer.url = "file://" + text;
			videoPlayer.Play();
			((Graphic)videoImage).color = new Color(1f, 1f, 1f, 1f);
		}

		private void OnVideoFinished(VideoPlayer vp)
		{
			videoFinished = true;
			RestoreGameSounds();
			Debug.Log((object)"Litany DEBUG: видеоскример завершён, звуки восстановлены");
		}

		private void Hide()
		{
			currentState = LitanyState.Hidden;
			timer = 0f;
			rootObject.SetActive(false);
			isOnCooldown = true;
			cooldownTimer = 0f;
			cooldownTime = Plugin.LitanyCooldownTime.Value;
			idleSource.Stop();
			screamsSource.Stop();
			oneShotSource.Stop();
		}

		public void ForceHide()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			RestoreGameSounds();
			currentState = LitanyState.Hidden;
			timer = 0f;
			rootObject.SetActive(false);
			isOnCooldown = false;
			nextAppearTime = Random.Range(Plugin.LitanyMinSpawnTime.Value, Plugin.LitanyMaxSpawnTime.Value);
			idleSource.Stop();
			screamsSource.Stop();
			oneShotSource.Stop();
			if ((Object)(object)videoPlayer != (Object)null)
			{
				videoPlayer.Stop();
			}
			if ((Object)(object)videoImage != (Object)null)
			{
				((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
			}
		}

		public void ResetLitany()
		{
			currentState = LitanyState.Hidden;
			timer = 0f;
			nextAppearTime = Random.Range(Plugin.LitanyMinSpawnTime.Value, Plugin.LitanyMaxSpawnTime.Value);
			rootObject.SetActive(false);
			isOnCooldown = false;
			cooldownTimer = 0f;
			idleSource.Stop();
			screamsSource.Stop();
			oneShotSource.Stop();
		}

		public void ForceAppear()
		{
			if (currentState == LitanyState.Hidden)
			{
				isOnCooldown = false;
				timer = nextAppearTime + 1f;
			}
		}

		private bool IsPlayerCrouching()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			return val.isCrouching;
		}

		private bool IsPlayerInGame()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (val.isPlayerDead)
			{
				return false;
			}
			if (StartOfRound.Instance?.currentLevel?.sceneName == "CompanyBuilding")
			{
				return false;
			}
			return !val.isInHangarShipRoom && (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded;
		}

		private void CreateOverlay()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: 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)
			canvasObject = new GameObject("LitanyCanvas");
			GameObject val = canvasObject;
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 100;
			rootObject = new GameObject("LitanyRoot");
			rootObject.transform.SetParent(val.transform, false);
			RectTransform val3 = rootObject.AddComponent<RectTransform>();
			val3.anchorMin = new Vector2(0.5f, 0.5f);
			val3.anchorMax = new Vector2(0.5f, 0.5f);
			val3.sizeDelta = new Vector2(500f, 500f);
			val3.anchoredPosition = Vector2.zero;
			basePosition = Vector2.zero;
			GameObject val4 = new GameObject("LitanyBody");
			val4.transform.SetParent(rootObject.transform, false);
			bodyImage = val4.AddComponent<Image>();
			RectTransform component = val4.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.sizeDelta = Vector2.zero;
			GameObject val5 = new GameObject("LitanyEyes");
			val5.transform.SetParent(rootObject.transform, false);
			eyeImage = val5.AddComponent<Image>();
			RectTransform component2 = val5.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.sizeDelta = Vector2.zero;
			videoTexture = new RenderTexture(1920, 1080, 0);
			GameObject val6 = new GameObject("LitanyVideoPlayer");
			val6.transform.SetParent(val.transform, false);
			videoPlayer = val6.AddComponent<VideoPlayer>();
			videoPlayer.playOnAwake = false;
			videoPlayer.renderMode = (VideoRenderMode)2;
			videoPlayer.targetTexture = videoTexture;
			videoPlayer.loopPointReached += new EventHandler(OnVideoFinished);
			videoAudioSource = val6.AddComponent<AudioSource>();
			videoAudioSource.playOnAwake = false;
			videoAudioSource.spatialBlend = 0f;
			videoAudioSource.volume = 1f;
			videoPlayer.audioOutputMode = (VideoAudioOutputMode)1;
			videoPlayer.controlledAudioTrackCount = 1;
			videoPlayer.EnableAudioTrack((ushort)0, true);
			videoPlayer.SetTargetAudioSource((ushort)0, videoAudioSource);
			GameObject val7 = new GameObject("LitanyVideo");
			val7.transform.SetParent(val.transform, false);
			videoImage = val7.AddComponent<RawImage>();
			videoImage.texture = (Texture)(object)videoTexture;
			((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f);
			RectTransform component3 = val7.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.sizeDelta = Vector2.zero;
			rootObject.SetActive(false);
		}

		private void OnDestroy()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			RestoreGameSounds();
			if ((Object)(object)videoPlayer != (Object)null)
			{
				videoPlayer.loopPointReached -= new EventHandler(OnVideoFinished);
				videoPlayer.Stop();
			}
			if ((Object)(object)canvasObject != (Object)null)
			{
				Object.Destroy((Object)(object)canvasObject);
				canvasObject = null;
			}
			if ((Object)(object)videoTexture != (Object)null)
			{
				videoTexture.Release();
				Object.Destroy((Object)(object)videoTexture);
				videoTexture = null;
			}
			Debug.Log((object)"Litany DEBUG: Canvas и видеоресурсы очищены");
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
	public class LitanyDeathPatch
	{
		private static void Postfix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				LitanyBehaviour litanyBehaviour = Object.FindObjectOfType<LitanyBehaviour>();
				if ((Object)(object)litanyBehaviour != (Object)null)
				{
					litanyBehaviour.ForceHide();
				}
			}
		}
	}
}
namespace KookooEntity
{
	public class KookooBehaviour : MonoBehaviour
	{
		private enum KookooState
		{
			Hidden,
			Appearing,
			Counting,
			WaitingClosing,
			Closing,
			HoldingClose
		}

		private float basePitch = 0.7f;

		private bool conditionChecked = false;

		private KookooState currentState = KookooState.Hidden;

		private float timer = 0f;

		private float nextAppearTime = 0f;

		private bool wasOnMoon = false;

		private bool kookooAllowedThisRound = false;

		private List<GameObject> deathCopies = new List<GameObject>();

		private bool deathAnimPlaying = false;

		private float deathTimer = 0f;

		private float copyTimer = 0f;

		private GameObject deathCanvas;

		private Sprite lastClosingSprite;

		private AudioClip rememberClip;

		private AudioClip countClip;

		private AudioClip checkClip;

		private AudioClip killClip;

		private AudioSource rememberSource;

		private AudioSource countSource;

		private AudioSource checkSource;

		private AudioSource killSource;

		private bool isOnCooldown = false;

		private float cooldownTimer = 0f;

		private float cooldownTime = 0f;

		private GameObject rootObject;

		private Image bodyImage;

		private Image[] digitImages = (Image[])(object)new Image[2];

		private Image particlesImage;

		private Sprite[] rememberSprites = (Sprite[])(object)new Sprite[2];

		private Sprite[] numSprites = (Sprite[])(object)new Sprite[10];

		private Sprite particlesSprite;

		private Sprite[] countSprites = (Sprite[])(object)new Sprite[6];

		private Sprite[] closingSprites = (Sprite[])(object)new Sprite[4];

		private Sprite errorSprite;

		private bool shouldSpawnErrorSprites = false;

		private float errorSpriteSpawnTimer = 0f;

		private List<GameObject> errorSpriteInstances = new List<GameObject>();

		private float bodyAnimTimer = 0f;

		private int bodyAnimFrame = 0;

		private float countAnimTimer = 0f;

		private int countAnimFrame = 0;

		private bool countAnimPlaying = false;

		private float closingAnimTimer = 0f;

		private int closingAnimFrame = 0;

		private float particlesTimer = 0f;

		private float particlesInterval = 0f;

		private bool particlesVisible = false;

		private float particlesVisibleTimer = 0f;

		private int targetNumber = 0;

		private int currentCount = 0;

		private float countTimer = 0f;

		private float shakeTimer = 0f;

		private Vector2 basePosition = Vector2.zero;

		private bool scanBlocked = false;

		private float scanBlockTimer = 0f;

		private AudioSource scanDamageSource;

		private AudioSource scanErrorSource;

		private AudioClip scanDamageClip;

		private AudioClip scanErrorClip;

		private bool scanAttackPlaying = false;

		private float scanAttackTimer = 0f;

		private GameObject scanAttackRoot;

		private Image scanAttackBodyImage;

		private Image scanAttackParticlesImage;

		private string modFolder;

		private AudioClip LoadAudioClip(string filename)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Kookoo Entity: звук не найден — " + text));
				return null;
			}
			WWW val = new WWW("file://" + text);
			try
			{
				while (!val.isDone)
				{
				}
				return val.GetAudioClip(false, false, (AudioType)13);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}

		private void Start()
		{
			modFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Kookoo");
			Debug.Log((object)("Kookoo Entity: папка ресурсов — " + modFolder));
			if (!Directory.Exists(modFolder))
			{
				Debug.LogError((object)("Kookoo Entity: папка Kookoo не найдена — " + modFolder));
			}
			LoadSprites();
			rememberClip = LoadAudioClip("remember.mp3");
			countClip = LoadAudioClip("count.mp3");
			checkClip = LoadAudioClip("check.mp3");
			killClip = LoadAudioClip("kill.mp3");
			rememberSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			rememberSource.loop = false;
			rememberSource.playOnAwake = false;
			countSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			countSource.loop = false;
			countSource.playOnAwake = false;
			checkSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			checkSource.loop = false;
			checkSource.playOnAwake = false;
			killSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			killSource.loop = false;
			killSource.playOnAwake = false;
			scanDamageClip = LoadAudioClip("scandamage.mp3");
			scanErrorClip = LoadAudioClip("scanerror.mp3");
			scanDamageSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			scanDamageSource.loop = false;
			scanDamageSource.playOnAwake = false;
			scanErrorSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			scanErrorSource.loop = false;
			scanErrorSource.playOnAwake = false;
			CreateOverlay();
			nextAppearTime = Random.Range(Plugin.KookooMinSpawnTime.Value, Plugin.KookooMaxSpawnTime.Value);
		}

		private void LoadSprites()
		{
			rememberSprites[0] = LoadSprite("remember1.png");
			rememberSprites[1] = LoadSprite("remember2.png");
			for (int i = 0; i < 10; i++)
			{
				numSprites[i] = LoadSprite($"num{i}.png");
			}
			particlesSprite = LoadSprite("particles.png");
			for (int j = 0; j < 6; j++)
			{
				countSprites[j] = LoadSprite($"count{j + 1}.png");
			}
			for (int k = 0; k < 4; k++)
			{
				closingSprites[k] = LoadSprite($"closing{k + 1}.png");
			}
			errorSprite = LoadSprite("error.png");
		}

		private Sprite LoadSprite(string filename)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(modFolder, filename);
			if (!File.Exists(text))
			{
				Debug.LogError((object)("Kookoo Entity: файл не найден — " + text));
				return null;
			}
			byte[] array = File.ReadAllBytes(text);
			Texture2D val = new Texture2D(2, 2);
			ImageConversion.LoadImage(val, array);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		private void Update()
		{
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			StartOfRound instance = StartOfRound.Instance;
			bool flag = (Object)(object)instance != (Object)null && (Object)(object)instance.currentLevel != (Object)null && instance.currentLevel.sceneName != "CompanyBuilding" && instance.shipHasLanded;
			if (flag && !wasOnMoon)
			{
				int num = Random.Range(0, 100);
				kookooAllowedThisRound = num < Mathf.Clamp(Plugin.KookooSpawnChance.Value, 0, 100);
				Debug.Log((object)($"Kookoo DEBUG: новый раунд! Шанс = {Plugin.KookooSpawnChance.Value}%, " + $"выпало {num}, Kookoo разрешён = {kookooAllowedThisRound}"));
				timer = 0f;
				nextAppearTime = Random.Range(Plugin.KookooMinSpawnTime.Value, Plugin.KookooMaxSpawnTime.Value);
			}
			if (!flag && wasOnMoon)
			{
				Debug.Log((object)"Kookoo DEBUG: раунд завершён");
				kookooAllowedThisRound = false;
				timer = 0f;
				ForceHide();
				ResetScanBlock();
			}
			wasOnMoon = flag;
			if (scanBlocked)
			{
				scanBlockTimer += Time.deltaTime;
				if (scanBlockTimer >= Plugin.KookooScanBlockDuration.Value)
				{
					scanBlocked = false;
					scanBlockTimer = 0f;
				}
			}
			if ((Object)(object)val == (Object)null || !IsPlayerInGame())
			{
				if (currentState != KookooState.Hidden || deathAnimPlaying || scanAttackPlaying)
				{
					ForceHide();
				}
				timer = 0f;
				return;
			}
			if (scanAttackPlaying)
			{
				scanAttackTimer += Time.deltaTime;
				if ((Object)(object)scanAttackRoot != (Object)null)
				{
					RectTransform component = scanAttackRoot.GetComponent<RectTransform>();
					float num2 = Random.Range(-35f, 35f);
					float num3 = Random.Range(-35f, 35f);
					component.anchoredPosition += new Vector2(num2, num3);
				}
				if (scanAttackTimer >= 0.5f)
				{
					scanAttackPlaying = false;
					scanAttackTimer = 0f;
					if ((Object)(object)scanAttackRoot != (Object)null)
					{
						scanAttackRoot.SetActive(false);
					}
				}
			}
			if (isOnCooldown)
			{
				cooldownTimer += Time.deltaTime;
				if (cooldownTimer >= cooldownTime)
				{
					isOnCooldown = false;
					cooldownTimer = 0f;
					timer = 0f;
					nextAppearTime = Random.Range(Plugin.KookooMinSpawnTime.Value, Plugin.KookooMaxSpawnTime.Value);
				}
				return;
			}
			if (deathAnimPlaying)
			{
				deathTimer += Time.deltaTime;
				copyTimer += Time.deltaTime;
				if (shouldSpawnErrorSprites && (Object)(object)errorSprite != (Object)null && deathTimer >= 1f)
				{
					errorSpriteSpawnTimer += Time.deltaTime;
					if (errorSpriteSpawnTimer >= 0.01f)
					{
						errorSpriteSpawnTimer = 0f;
						SpawnErrorSprite();
					}
				}
				if (copyTimer >= 0.01f)
				{
					copyTimer = 0f;
					CreateDeathCopy();
				}
				if (!(deathTimer >= 2f))
				{
					return;
				}
				deathAnimPlaying = false;
				shouldSpawnErrorSprites = false;
				deathCanvas.SetActive(false);
				foreach (GameObject deathCopy in deathCopies)
				{
					if ((Object)(object)deathCopy != (Object)null)
					{
						Object.Destroy((Object)(object)deathCopy);
					}
				}
				deathCopies.Clear();
				foreach (GameObject errorSpriteInstance in errorSpriteInstances)
				{
					if ((Object)(object)errorSpriteInstance != (Object)null)
					{
						Object.Destroy((Object)(object)errorSpriteInstance);
					}
				}
				errorSpriteInstances.Clear();
				val.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false);
				Hide();
				return;
			}
			timer += Time.deltaTime;
			if (currentState != KookooState.Hidden)
			{
				AnimateBody();
			}
			switch (currentState)
			{
			case KookooState.Hidden:
				if (kookooAllowedThisRound && timer >= nextAppearTime)
				{
					Appear();
				}
				break;
			case KookooState.Appearing:
				if (timer >= Plugin.KookooAppearDuration.Value)
				{
					StartCounting();
				}
				break;
			case KookooState.Counting:
				UpdateCounting();
				UpdateParticles();
				if (countAnimPlaying)
				{
					AnimateCount();
				}
				Shake();
				break;
			case KookooState.WaitingClosing:
				if (countAnimPlaying)
				{
					AnimateCount();
				}
				UpdateParticles();
				Shake();
				if (timer >= 1f)
				{
					StartClosing();
				}
				break;
			case KookooState.Closing:
				AnimateClosing();
				break;
			case KookooState.HoldingClose:
				if (!conditionChecked)
				{
					conditionChecked = true;
					CheckCondition();
				}
				break;
			}
		}

		private void AnimateBody()
		{
			if (currentState != KookooState.Appearing)
			{
				return;
			}
			bodyAnimTimer += Time.deltaTime;
			if (bodyAnimTimer >= 0.0667f)
			{
				bodyAnimTimer = 0f;
				bodyAnimFrame = (bodyAnimFrame + 1) % 2;
				if ((Object)(object)rememberSprites[bodyAnimFrame] != (Object)null)
				{
					bodyImage.sprite = rememberSprites[bodyAnimFrame];
				}
			}
		}

		public bool IsScanBlocked()
		{
			return scanBlocked;
		}

		public void ResetScanBlock()
		{
			scanBlocked = false;
			scanBlockTimer = 0f;
		}

		public void PlayScanError()
		{
			if ((Object)(object)scanErrorClip != (Object)null)
			{
				scanErrorSource.clip = scanErrorClip;
				scanErrorSource.Play();
			}
		}

		public void TryTriggerScanAttack()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			if (IsPlayerInGame() && !scanBlocked && !scanAttackPlaying && !((Object)(object)scanAttackRoot == (Object)null) && Random.Range(0, 100) < Plugin.KookooScanAttackChance.Value)
			{
				scanAttackPlaying = true;
				scanAttackTimer = 0f;
				scanBlocked = true;
				scanBlockTimer = 0f;
				if ((Object)(object)scanAttackBodyImage != (Object)null)
				{
					scanAttackBodyImage.sprite = closingSprites[3];
				}
				if ((Object)(object)scanAttackParticlesImage != (Object)null)
				{
					((Component)scanAttackParticlesImage).gameObject.SetActive(true);
				}
				float num = Random.Range(-500f, 500f);
				float num2 = Random.Range(-250f, 250f);
				RectTransform component = scanAttackRoot.GetComponent<RectTransform>();
				component.anchoredPosition = new Vector2(num, num2);
				scanAttackRoot.SetActive(true);
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				}
				if ((Object)(object)scanDamageClip != (Object)null && (Object)(object)scanDamageSource != (Object)null)
				{
					scanDamageSource.clip = scanDamageClip;
					scanDamageSource.Play();
				}
			}
		}

		private void AnimateCount()
		{
			countAnimTimer += Time.deltaTime;
			if (!(countAnimTimer >= 0.0667f))
			{
				return;
			}
			countAnimTimer = 0f;
			countAnimFrame++;
			if (countAnimFrame >= 6)
			{
				countAnimPlaying = false;
				countAnimFrame = 0;
				if ((Object)(object)countSprites[5] != (Object)null)
				{
					bodyImage.sprite = countSprites[5];
				}
			}
			else if ((Object)(object)countSprites[countAnimFrame] != (Object)null)
			{
				bodyImage.sprite = countSprites[countAnimFrame];
			}
		}

		private void AnimateClosing()
		{
			closingAnimTimer += Time.deltaTime;
			if (closingAnimTimer >= 0.0667f)
			{
				closingAnimTimer = 0f;
				closingAnimFrame++;
				if (closingAnimFrame >= 4)
				{
					currentState = KookooState.HoldingClose;
					timer = 0f;
				}
				else if ((Object)(object)closingSprites[closingAnimFrame] != (Object)null)
				{
					bodyImage.sprite = closingSprites[closingAnimFrame];
				}
			}
		}

		private void UpdateCounting()
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			countTimer += Time.deltaTime;
			if (countTimer >= Plugin.KookooCountInterval.Value)
			{
				countTimer = 0f;
				currentCount++;
				if ((Object)(object)countClip != (Object)null)
				{
					countSource.clip = countClip;
					countSource.Play();
					countSource.pitch = basePitch + (float)currentCount / (float)targetNumber * 0.6f;
				}
				UpdateDigits(currentCount);
				float num = Random.Range(-500f, 500f);
				float num2 = Random.Range(-250f, 250f);
				basePosition = new Vector2(num, num2);
				rootObject.GetComponent<RectTransform>().anchoredPosition = basePosition;
				countAnimPlaying = true;
				countAnimFrame = 0;
				countAnimTimer = 0f;
				if ((Object)(object)countSprites[0] != (Object)null)
				{
					bodyImage.sprite = countSprites[0];
				}
				if (currentCount >= targetNumber)
				{
					currentState = KookooState.WaitingClosing;
					timer = 0f;
				}
			}
		}

		private void UpdateParticles()
		{
			if (particlesVisible)
			{
				particlesVisibleTimer += Time.deltaTime;
				if (particlesVisibleTimer >= 0.2f)
				{
					particlesVisible = false;
					((Component)particlesImage).gameObject.SetActive(false);
				}
				return;
			}
			particlesTimer += Time.deltaTime;
			if (particlesTimer >= particlesInterval)
			{
				particlesTimer = 0f;
				particlesInterval = Random.Range(0.1f, 1f);
				particlesVisible = true;
				particlesVisibleTimer = 0f;
				((Component)particlesImage).gameObject.SetActive(true);
			}
		}

		private void Shake()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			shakeTimer += Time.deltaTime;
			if (shakeTimer >= 0.05f)
			{
				shakeTimer = 0f;
				float num = Random.Range(-5f, 5f);
				float num2 = Random.Range(-5f, 5f);
				rootObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(basePosition.x + num, basePosition.y + num2);
			}
		}

		private void UpdateDigits(int number)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (number < 10)
			{
				((Component)digitImages[0]).gameObject.SetActive(false);
				((Component)digitImages[1]).gameObject.SetActive(true);
				digitImages[1].sprite = numSprites[number];
				((Component)digitImages[1]).GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
				return;
			}
			int num = number / 10;
			int num2 = number % 10;
			((Component)digitImages[0]).gameObject.SetActive(true);
			((Component)digitImages[1]).gameObject.SetActive(true);
			digitImages[0].sprite = numSprites[num];
			digitImages[1].sprite = numSprites[num2];
			((Component)digitImages[0]).GetComponent<RectTransform>().anchoredPosition = new Vector2(-40f, 0f);
			((Component)digitImages[1]).GetComponent<RectTransform>().anchoredPosition = new Vector2(40f, 0f);
		}

		private void Appear()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			currentState = KookooState.Appearing;
			timer = 0f;
			currentCount = 0;
			targetNumber = Random.Range(1, 31);
			float num = Random.Range(-500f, 500f);
			float num2 = Random.Range(-250f, 250f);
			basePosition = new Vector2(num, num2);
			rootObject.GetComponent<RectTransform>().anchoredPosition = basePosition;
			if ((Object)(object)rememberClip != (Object)null)
			{
				rememberSource.clip = rememberClip;
				rememberSource.Play();
			}
			rootObject.SetActive(true);
			if ((Object)(object)rememberSprites[0] != (Object)null)
			{
				bodyImage.sprite = rememberSprites[0];
			}
			UpdateDigits(targetNumber);
		}

		private void StartCounting()
		{
			currentState = KookooState.Counting;
			timer = 0f;
			countTimer = 0f;
			currentCount = 0;
			UpdateDigits(0);
			countSource.pitch = basePitch;
		}

		private void StartClosing()
		{
			conditionChecked = false;
			currentState = KookooState.Closing;
			closingAnimFrame = 0;
			closingAnimTimer = 0f;
			countAnimPlaying = false;
			((Component)digitImages[0]).gameObject.SetActive(false);
			((Component)digitImages[1]).gameObject.SetActive(false);
			((Component)particlesImage).gameObject.SetActive(false);
			if ((Object)(object)checkClip != (Object)null)
			{
				checkSource.clip = checkClip;
				checkSource.Play();
			}
			if ((Object)(object)closingSprites[0] != (Object)null)
			{
				bodyImage.sprite = closingSprites[0];
			}
		}

		public void CheckCondition()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null)
			{
				Hide();
			}
			else if ((Object)(object)val.currentlyHeldObjectServer != (Object)null)
			{
				if ((Object)(object)killClip != (Object)null)
				{
					killSource.clip = killClip;
					killSource.Play();
				}
				deathAnimPlaying = true;
				shouldSpawnErrorSprites = true;
				errorSpriteSpawnTimer = 0f;
				deathTimer = 0f;
				copyTimer = 0f;
				lastClosingSprite = closingSprites[3];
				deathCanvas.SetActive(true);
				rootObject.SetActive(true);
			}
			else
			{
				Hide();
			}
		}

		private void SpawnErrorSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_008e: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("KookooErrorSpriteCanvas");
			Canvas val2;
			if ((Object)(object)val == (Object)null)
			{
				val = new GameObject("KookooErrorSpriteCanvas");
				val2 = val.AddComponent<Canvas>();
				val2.renderMode = (RenderMode)0;
				val2.sortingOrder = 10000;
			}
			else
			{
				val2 = val.GetComponent<Canvas>();
			}
			GameObject val3 = new GameObject("KookooErrorSprite");
			val3.transform.SetParent(((Component)val2).transform, false);
			Image val4 = val3.AddComponent<Image>();
			val4.sprite = errorSprite;
			RectTransform component = val3.GetComponent<RectTransform>();
			Rect rect = errorSprite.rect;
			float width = ((Rect)(ref rect)).width;
			rect = errorSprite.rect;
			component.sizeDelta = new Vector2(width, ((Rect)(ref rect)).height);
			component.anchoredPosition = new Vector2((float)Random.Range(-Screen.width / 2 + 160, Screen.width / 2 - 160), (float)Random.Range(-Screen.height / 2 + 80, Screen.height / 2 - 80));
			errorSpriteInstances.Add(val3);
		}

		private void CreateDeathCopy()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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)
			float num = Random.Range((float)(-Screen.width) * 0.5f, (float)Screen.width * 0.5f);
			float num2 = Random.Range((float)(-Screen.height) * 0.5f, (float)Screen.height * 0.5f);
			GameObject val = new GameObject("KookooCopy");
			val.transform.SetParent(deathCanvas.transform, false);
			Image val2 = val.AddComponent<Image>();
			val2.sprite = lastClosingSprite;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(800f, 800f);
			component.anchoredPosition = new Vector2(num, num2);
			deathCopies.Add(val);
		}

		private void Hide()
		{
			currentState = KookooState.Hidden;
			timer = 0f;
			rootObject.SetActive(false);
			isOnCooldown = true;
			cooldownTimer = 0f;
			cooldownTime = Plugin.KookooCooldownTime.Value;
			((Component)particlesImage).gameObject.SetActive(false);
			rememberSource.Stop();
			countSource.Stop();
			checkSource.Stop();
			killSource.Stop();
		}

		public void ForceHide()
		{
			currentState = KookooState.Hidden;
			timer = 0f;
			nextAppearTime = Random.Range(Plugin.KookooMinSpawnTime.Value, Plugin.KookooMaxSpawnTime.Value);
			isOnCooldown = false;
			cooldownTimer = 0f;
			deathAnimPlaying = false;
			shouldSpawnErrorSprites = false;
			deathTimer = 0f;
			copyTimer = 0f;
			scanAttackPlaying = false;
			scanAttackTimer = 0f;
			if ((Object)(object)scanAttackRoot != (Object)null)
			{
				scanAttackRoot.SetActive(false);
			}
			conditionChecked = false;
			countAnimPlaying = false;
			particlesVisible = false;
			((MonoBehaviour)this).CancelInvoke("StartClosing");
			if ((Object)(object)rootObject != (Object)null)
			{
				rootObject.SetActive(false);
			}
			if ((Object)(object)particlesImage != (Object)null)
			{
				((Component)particlesImage).gameObject.SetActive(false);
			}
			if ((Object)(object)deathCanvas != (Object)null)
			{
				deathCanvas.SetActive(false);
			}
			foreach (GameObject deathCopy in deathCopies)
			{
				if ((Object)(object)deathCopy != (Object)null)
				{
					Object.Destroy((Object)(object)deathCopy);
				}
			}
			deathCopies.Clear();
			foreach (GameObject errorSpriteInstance in errorSpriteInstances)
			{
				if ((Object)(object)errorSpriteInstance != (Object)null)
				{
					Object.Destroy((Object)(object)errorSpriteInstance);
				}
			}
			errorSpriteInstances.Clear();
			if ((Object)(object)rememberSource != (Object)null)
			{
				rememberSource.Stop();
			}
			if ((Object)(object)countSource != (Object)null)
			{
				countSource.Stop();
			}
			if ((Object)(object)checkSource != (Object)null)
			{
				checkSource.Stop();
			}
			if ((Object)(object)killSource != (Object)null)
			{
				killSource.Stop();
			}
			if ((Object)(object)scanDamageSource != (Object)null)
			{
				scanDamageSource.Stop();
			}
			if ((Object)(object)scanErrorSource != (Object)null)
			{
				scanErrorSource.Stop();
			}
		}

		public void ResetKookoo()
		{
			ForceHide();
			nextAppearTime = Random.Range(Plugin.KookooMinSpawnTime.Value, Plugin.KookooMaxSpawnTime.Value);
			cooldownTimer = 0f;
		}

		private bool IsPlayerInGame()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)val == (Object)null || (Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (val.isPlayerDead || !val.isPlayerControlled)
			{
				return false;
			}
			if ((Object)(object)instance.currentLevel == (Object)null)
			{
				return false;
			}
			if (instance.currentLevel.sceneName == "CompanyBuilding")
			{
				return false;
			}
			if (!instance.shipHasLanded)
			{
				return false;
			}
			if (val.isInHangarShipRoom)
			{
				return false;
			}
			return true;
		}

		private void CreateOverlay()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_0144: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: 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_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: 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_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("KookooCanvas");
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 100;
			deathCanvas = new GameObject("KookooDeathCanvas");
			Canvas val3 = deathCanvas.AddComponent<Canvas>();
			val3.renderMode = (RenderMode)0;
			val3.sortingOrder = 200;
			deathCanvas.SetActive(false);
			rootObject = new GameObject("KookooRoot");
			rootObject.transform.SetParent(val.transform, false);
			RectTransform val4 = rootObject.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(0.5f, 0.5f);
			val4.anchorMax = new Vector2(0.5f, 0.5f);
			val4.sizeDelta = new Vector2(800f, 800f);
			val4.anchoredPosition = Vector2.zero;
			GameObject val5 = new GameObject("KookooParticles");
			val5.transform.SetParent(rootObject.transform, false);
			particlesImage = val5.AddComponent<Image>();
			if ((Object)(object)particlesSprite != (Object)null)
			{
				particlesImage.sprite = particlesSprite;
			}
			RectTransform component = val5.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.sizeDelta = Vector2.zero;
			val5.SetActive(false);
			GameObject val6 = new GameObject("KookooBody");
			val6.transform.SetParent(rootObject.transform, false);
			bodyImage = val6.AddComponent<Image>();
			RectTransform component2 = val6.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.sizeDelta = Vector2.zero;
			for (int i = 0; i < 2; i++)
			{
				GameObject val7 = new GameObject($"KookooDigit_{i}");
				val7.transform.SetParent(rootObject.transform, false);
				digitImages[i] = val7.AddComponent<Image>();
				RectTransform component3 = val7.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0.5f, 0.5f);
				component3.anchorMax = new Vector2(0.5f, 0.5f);
				component3.sizeDelta = new Vector2(800f, 800f);
				component3.anchoredPosition = new Vector2(((float)i - 0.5f) * 35f, 0f);
				val7.SetActive(false);
			}
			rootObject.SetActive(false);
			scanAttackRoot = new GameObject("KookooScanAttackRoot");
			scanAttackRoot.transform.SetParent(val.transform, false);
			RectTransform val8 = scanAttackRoot.AddComponent<RectTransform>();
			val8.anchorMin = new Vector2(0.5f, 0.5f);
			val8.anchorMax = new Vector2(0.5f, 0.5f);
			val8.sizeDelta = new Vector2(800f, 800f);
			val8.anchoredPosition = Vector2.zero;
			GameObject val9 = new GameObject("KookooScanParticles");
			val9.transform.SetParent(scanAttackRoot.transform, false);
			scanAttackParticlesImage = val9.AddComponent<Image>();
			scanAttackParticlesImage.sprite = particlesSprite;
			((Graphic)scanAttackParticlesImage).raycastTarget = false;
			RectTransform component4 = val9.GetComponent<RectTransform>();
			component4.anchorMin = Vector2.zero;
			component4.anchorMax = Vector2.one;
			component4.sizeDelta = Vector2.zero;
			GameObject val10 = new GameObject("KookooScanBody");
			val10.transform.SetParent(scanAttackRoot.transform, false);
			scanAttackBodyImage = val10.AddComponent<Image>();
			scanAttackBodyImage.sprite = closingSprites[3];
			((Graphic)scanAttackBodyImage).raycastTarget = false;
			RectTransform component5 = val10.GetComponent<RectTransform>();
			component5.anchorMin = Vector2.zero;
			component5.anchorMax = Vector2.one;
			component5.sizeDelta = Vector2.zero;
			scanAttackRoot.SetActive(false);
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
	public class KookooDeathPatch
	{
		private static void Postfix(PlayerControllerB __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				KookooBehaviour kookooBehaviour = Object.FindObjectOfType<KookooBehaviour>();
				if ((Object)(object)kookooBehaviour != (Object)null)
				{
					kookooBehaviour.ForceHide();
					kookooBehaviour.ResetScanBlock();
				}
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "PingScan_performed")]
	public class KookooScanPatch
	{
		private static bool Prefix(HUDManager __instance, CallbackContext context)
		{
			if (!((CallbackContext)(ref context)).performed)
			{
				return true;
			}
			KookooBehaviour kookooBehaviour = Object.FindObjectOfType<KookooBehaviour>();
			if ((Object)(object)kookooBehaviour == (Object)null)
			{
				return true;
			}
			if (kookooBehaviour.IsScanBlocked())
			{
				kookooBehaviour.PlayScanError();
				return false;
			}
			if (!(bool)AccessTools.Method(typeof(HUDManager), "CanPlayerScan", (Type[])null, (Type[])null).Invoke(__instance, null))
			{
				return true;
			}
			float num = (float)AccessTools.Field(typeof(HUDManager), "playerPingingScan").GetValue(__instance);
			if (num > -1f)
			{
				return true;
			}
			kookooBehaviour.TryTriggerScanAttack();
			return true;
		}
	}
}
namespace DozerEntity
{
	public class DozerBehaviour : MonoBehaviour
	{
		private enum DozerState
		{
			Hidden,
			ClosedEyes,
			OpenEyes,
			Screamer
		}

		private bool wasOnMoon = false;

		private bool dozerAllowedThisRound = false;

		private DozerState currentState = DozerState.Hidden;

		private float timer = 0f;

		private float nextAppearTime = 0f;

		private float cooldownTimer = 0f;

		private float cooldownTime = 0f;

		private bool isOnCooldown = false;

		private float previousVolume = 1f;

		private GameObject canvasObject;

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

		private AudioSource screamerAudioSource;

		private GameObject overlayObject;

		private Image overlayImage;

		private Image blackBackground;

		private GameObject textObject;

		private Image textImage;

		private Sprite[] textSprites = (Sprite[])(object)new Sprite[25];

		private float textAnimTimer = 0f;

		private int textAnimFrame = 0;

		private bool textAnimStarted = false;

		private AudioClip openSound;

		private AudioClip killSound;

		private AudioSource audioSource;

		private AudioClip closedSound;

		private Sprite[] closedSprites = (Sprite[])(object)new Sprite[14];

		private Sprite[] openSprites = (Sprite[])(object)new Sprite[14];

		private Sprite[] screamerSprites = (Sprite[])(object)new Sprite[50];

		private float animTimer = 0f;

		private int animFrame = 0;

		private float animSpeed = 0.0667f;

		private string modFolder;

		private AudioClip LoadAudioClip(string filename)
		{
			//IL_0041: Unknown result type (