Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LethalGrace v1.2.1
LethalGrace.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
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 (