using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; 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: AssemblyTitle("LitanyEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LitanyEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e9825634-eec7-4ae6-80c6-e82bbadddd91")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace LitanyEntity; public class LitanyBehaviour : MonoBehaviour { private enum LitanyState { Hidden, Preparing, Warning, EyeOpen, BetweenEyes, Screamer } 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 string modFolder; private void Start() { modFolder = Path.Combine(Paths.PluginPath, "LitanyEntity"); string[] directories = Directory.GetDirectories(Paths.PluginPath, "LitanyEntity", SearchOption.AllDirectories); if (directories.Length != 0) { modFolder = directories[0]; } LoadSprites(); CreateOverlay(); LoadAudio(); nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.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(); idleSource.loop = true; idleSource.playOnAwake = false; screamsSource = ((Component)this).gameObject.AddComponent(); screamsSource.loop = true; screamsSource.playOnAwake = false; oneShotSource = ((Component)this).gameObject.AddComponent(); 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_0290: 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: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if (currentState != 0) { AnimateBody(); } if (val.isPlayerDead) { ForceHide(); } else if (isOnCooldown) { cooldownTimer += Time.deltaTime; if (cooldownTimer >= cooldownTime) { isOnCooldown = false; cooldownTimer = 0f; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } } else { if (!IsPlayerInGame()) { return; } if (val.quickMenuManager.isMenuOpen) { rootObject.SetActive(false); return; } if (currentState != 0 && currentState != LitanyState.Screamer) { rootObject.SetActive(true); } timer += Time.deltaTime; switch (currentState) { case LitanyState.Hidden: if (timer >= nextAppearTime) { Appear(); } break; case LitanyState.Preparing: if (timer >= Plugin.PrepareDuration.Value) { StartWarning(); } break; case LitanyState.Warning: AnimateWarning(); if (timer >= Plugin.WarningDuration.Value) { OpenEye(); } break; case LitanyState.EyeOpen: if (!IsPlayerCrouching()) { TriggerDeath(); } else if (timer >= Plugin.OpenEyeDuration.Value) { CloseEye(); } break; case LitanyState.BetweenEyes: if (timer >= Plugin.BetweenEyesDuration.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.ShakeSpeed.Value) { shakeTimer = 0f; float num = Random.Range(-8f, 8f); float num2 = Random.Range(-8f, 8f); float num3 = Random.Range(-5f, 5f); rootObject.GetComponent().anchoredPosition = new Vector2(basePosition.x + num, basePosition.y + num2); ((Transform)rootObject.GetComponent()).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().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().anchoredPosition = basePosition; currentState = LitanyState.BetweenEyes; timer = 0f; } private void TriggerDeath() { //IL_008e: 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(); 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; } private void Hide() { currentState = LitanyState.Hidden; timer = 0f; rootObject.SetActive(false); isOnCooldown = true; cooldownTimer = 0f; cooldownTime = Plugin.CooldownTime.Value; idleSource.Stop(); screamsSource.Stop(); oneShotSource.Stop(); } public void ForceHide() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) currentState = LitanyState.Hidden; timer = 0f; rootObject.SetActive(false); isOnCooldown = false; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.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.MinSpawnTime.Value, Plugin.MaxSpawnTime.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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0122: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LitanyCanvas"); Canvas val2 = val.AddComponent(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 100; Object.DontDestroyOnLoad((Object)(object)val); rootObject = new GameObject("LitanyRoot"); rootObject.transform.SetParent(val.transform, false); RectTransform val3 = rootObject.AddComponent(); 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(); RectTransform component = val4.GetComponent(); 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(); RectTransform component2 = val5.GetComponent(); 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.playOnAwake = false; videoPlayer.renderMode = (VideoRenderMode)2; videoPlayer.targetTexture = videoTexture; videoPlayer.loopPointReached += new EventHandler(OnVideoFinished); GameObject val7 = new GameObject("LitanyVideo"); val7.transform.SetParent(val.transform, false); videoImage = val7.AddComponent(); videoImage.texture = (Texture)(object)videoTexture; ((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f); RectTransform component3 = val7.GetComponent(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.sizeDelta = Vector2.zero; rootObject.SetActive(false); } } public class LitanyDomain : MonoBehaviour { private enum DomainState { Inactive, Active } private DomainState currentState = DomainState.Inactive; private float eventTimer = 0f; private float eventDuration = 278f; private float commandTimer = 0f; private float commandInterval = 5f; private float commandDuration = 2f; private float commandActiveTimer = 0f; private bool commandActive = false; private bool isJumpCommand = false; private bool playerReacted = false; private bool playerViolated = false; private float scheduleTimer = 0f; private float scheduledTime = 0f; private bool scheduled = false; private float litanyTimer = 0f; private float litanyDelay = 65f; private bool litanyPhaseStarted = false; private GameObject commandObject; private Image commandImage; private Sprite jumpSprite; private Sprite dontJumpSprite; private AudioSource musicSource; private AudioSource orderBGSource; private AudioSource orderSource; private AudioClip musicClip; private AudioClip orderBGClip; private AudioClip[] orderClips = (AudioClip[])(object)new AudioClip[4]; private float textShakeTimer = 0f; private float textShakeSpeed = 0.05f; private Vector2 textBasePosition = new Vector2(0f, -120f); private bool orderPlayedFinal = false; private float previousFallValue = -7f; private string modFolder; private void Start() { modFolder = Path.Combine(Paths.PluginPath, "LitanyEntity"); string[] directories = Directory.GetDirectories(Paths.PluginPath, "LitanyEntity", SearchOption.AllDirectories); if (directories.Length != 0) { modFolder = directories[0]; } LoadAssets(); CreateUI(); } private void LoadAssets() { jumpSprite = LoadSprite("jump.png"); dontJumpSprite = LoadSprite("dont_jump.png"); musicClip = LoadAudioClip("OWYH.mp3"); orderBGClip = LoadAudioClip("orderBG.mp3"); for (int i = 0; i < 4; i++) { orderClips[i] = LoadAudioClip($"order{i + 1}.mp3"); } musicSource = ((Component)this).gameObject.AddComponent(); musicSource.loop = false; musicSource.playOnAwake = false; if ((Object)(object)musicClip != (Object)null) { musicSource.clip = musicClip; } orderBGSource = ((Component)this).gameObject.AddComponent(); orderBGSource.loop = false; orderBGSource.playOnAwake = false; orderSource = ((Component)this).gameObject.AddComponent(); orderSource.loop = false; orderSource.playOnAwake = false; } private Sprite LoadSprite(string filename) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) string path = Path.Combine(modFolder, filename); if (!File.Exists(path)) { return null; } byte[] array = File.ReadAllBytes(path); 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 AudioClip LoadAudioClip(string filename) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown string text = Path.Combine(modFolder, filename); if (!File.Exists(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 Update() { if (scheduled && currentState == DomainState.Inactive) { scheduleTimer += Time.deltaTime; if (scheduleTimer >= scheduledTime) { scheduled = false; StartEvent(); } } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.shipHasLanded) { if (currentState == DomainState.Active) { EndEvent(); } } else if (val.isInHangarShipRoom) { if (commandActive) { HideCommand(); } } else if (val.isPlayerDead) { if (commandActive) { HideCommand(); } } else { if (currentState == DomainState.Inactive) { return; } eventTimer += Time.deltaTime; if (eventTimer >= eventDuration) { EndEvent(); return; } if (!litanyPhaseStarted && eventTimer >= litanyDelay) { litanyPhaseStarted = true; TriggerLitany(); } if (litanyPhaseStarted) { litanyTimer += Time.deltaTime; if (litanyTimer >= Random.Range(15f, 20f)) { litanyTimer = 0f; TriggerLitany(); } } if (!commandActive) { commandTimer += Time.deltaTime; if (commandTimer >= commandInterval) { commandTimer = 0f; ShowCommand(); } return; } ShakeCommand(); commandActiveTimer += Time.deltaTime; if (!orderPlayedFinal && commandActiveTimer >= commandDuration - 3f) { orderPlayedFinal = true; int num = Random.Range(0, 4); if ((Object)(object)orderClips[num] != (Object)null) { orderSource.clip = orderClips[num]; orderSource.Play(); } } if (!playerReacted) { bool flag = IngamePlayerSettings.Instance.playerInput.actions["Jump"].WasPressedThisFrame(); if (isJumpCommand && flag) { playerReacted = true; } if (!isJumpCommand && flag) { playerViolated = true; } } if (commandActiveTimer >= commandDuration) { if (isJumpCommand && !playerReacted) { DamagePlayer(val); } else if (!isJumpCommand && playerViolated) { DamagePlayer(val); } HideCommand(); } } } private void ShakeCommand() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) textShakeTimer += Time.deltaTime; if (textShakeTimer >= textShakeSpeed) { textShakeTimer = 0f; float num = Random.Range(-5f, 5f); float num2 = Random.Range(-5f, 5f); commandObject.GetComponent().anchoredPosition = new Vector2(textBasePosition.x + num, textBasePosition.y + num2); } } private void TriggerLitany() { LitanyBehaviour litanyBehaviour = Object.FindObjectOfType(); if ((Object)(object)litanyBehaviour != (Object)null) { litanyBehaviour.ForceAppear(); } } private void ShowCommand() { isJumpCommand = Random.Range(0, 2) == 0; commandActive = true; commandActiveTimer = 0f; playerReacted = false; playerViolated = false; orderPlayedFinal = false; commandImage.sprite = (isJumpCommand ? jumpSprite : dontJumpSprite); commandObject.SetActive(true); if ((Object)(object)orderBGClip != (Object)null) { orderBGSource.clip = orderBGClip; orderBGSource.time = Random.Range(0f, orderBGClip.length * 0.7f); orderBGSource.Play(); } } private void HideCommand() { commandActive = false; commandActiveTimer = 0f; orderPlayedFinal = false; commandObject.SetActive(false); orderBGSource.Stop(); } private void DamagePlayer(PlayerControllerB player) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) player.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); } public void StartEvent() { currentState = DomainState.Active; eventTimer = 0f; commandTimer = 0f; litanyTimer = 0f; litanyPhaseStarted = false; musicSource.Play(); Debug.Log((object)"Litany Domain: событие началось!"); } private void EndEvent() { currentState = DomainState.Inactive; HideCommand(); Debug.Log((object)"Litany Domain: событие закончилось!"); } public void ScheduleEvent(float delay) { scheduledTime = delay; scheduled = true; scheduleTimer = 0f; } private void CreateUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00b4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DomainCanvas"); Canvas val2 = val.AddComponent(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 99; Object.DontDestroyOnLoad((Object)(object)val); commandObject = new GameObject("DomainCommand"); commandObject.transform.SetParent(val.transform, false); commandImage = commandObject.AddComponent(); RectTransform component = commandObject.GetComponent(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.sizeDelta = new Vector2(300f, 100f); component.anchoredPosition = textBasePosition; commandObject.SetActive(false); } } public class LitanyDomainNetwork : NetworkBehaviour { [CompilerGenerated] private sealed class d__4 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public LitanyDomainNetwork <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.StartDomainEventClientRpc(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static LitanyDomainNetwork Instance; private void Awake() { Instance = this; } [ClientRpc] public void StartDomainEventClientRpc() { Debug.Log((object)"Litany Domain: получена команда начать событие!"); LitanyDomain litanyDomain = Object.FindObjectOfType(); if ((Object)(object)litanyDomain != (Object)null) { litanyDomain.StartEvent(); } } public void ScheduleEventForAll(float delay) { ((MonoBehaviour)this).StartCoroutine(ScheduleCoroutine(delay)); } [IteratorStateMachine(typeof(d__4))] private IEnumerator ScheduleCoroutine(float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(0) { <>4__this = this, delay = delay }; } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")] public class LitanyDomainPatch { public static bool eventHappenedThisRound; private static void Postfix() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown if (eventHappenedThisRound || (Object)(object)GameObject.Find("LitanyDomainManager") != (Object)null) { return; } GameObject val = new GameObject("LitanyDomainManager"); val.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val); if (GameNetworkManager.Instance.isHostingGame) { int num = Random.Range(0, 100); if (num >= Plugin.DomainChance.Value) { Debug.Log((object)"Litany Domain: событие не выпало"); return; } eventHappenedThisRound = true; GameObject val2 = new GameObject("LitanyDomainNetworkManager"); LitanyDomainNetwork litanyDomainNetwork = val2.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val2); float num2 = Random.Range(Plugin.DomainMinDelay.Value, Plugin.DomainMaxDelay.Value); litanyDomainNetwork.ScheduleEventForAll(num2); Debug.Log((object)$"Litany Domain: событие запланировано через {num2} секунд!"); } } } [HarmonyPatch(typeof(RoundManager), "UnloadSceneObjectsEarly")] public class LitanyDomainCleanupPatch { private static void Postfix() { LitanyDomainPatch.eventHappenedThisRound = false; GameObject val = GameObject.Find("LitanyDomainManager"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } GameObject val2 = GameObject.Find("LitanyDomainNetworkManager"); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class LitanyPatch { private static void Postfix(PlayerControllerB __instance) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if (((NetworkBehaviour)__instance).IsOwner && !((Object)(object)Object.FindObjectOfType() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Litany Entity: won't appear this round (roll {num})"); return; } GameObject val = new GameObject("LitanyManager"); val.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)"Litany Entity: manager created!"); } } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] public class LitanyDeathPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { LitanyBehaviour litanyBehaviour = Object.FindObjectOfType(); if ((Object)(object)litanyBehaviour != (Object)null) { litanyBehaviour.ForceHide(); } } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class LitanyRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { LitanyBehaviour litanyBehaviour = Object.FindObjectOfType(); if ((Object)(object)litanyBehaviour != (Object)null) { litanyBehaviour.ResetLitany(); Debug.Log((object)"Litany Entity: reset after respawn!"); } } } } [BepInPlugin("com.yourname.litanyentity", "Litany Entity", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.yourname.litanyentity"); public static ConfigEntry SpawnChance; public static ConfigEntry MinSpawnTime; public static ConfigEntry MaxSpawnTime; public static ConfigEntry PrepareDuration; public static ConfigEntry WarningDuration; public static ConfigEntry OpenEyeDuration; public static ConfigEntry BetweenEyesDuration; public static ConfigEntry CooldownTime; public static ConfigEntry ShakeSpeed; public static ConfigEntry DomainChance; public static ConfigEntry DomainMinDelay; public static ConfigEntry DomainMaxDelay; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnChance", 35, "Chance of Litany appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MinSpawnTime", 10f, "Minimum time before Litany appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MaxSpawnTime", 30f, "Maximum time before Litany appears"); PrepareDuration = ((BaseUnityPlugin)this).Config.Bind("Timing", "PrepareDuration", 4f, "Time before first eye warning"); WarningDuration = ((BaseUnityPlugin)this).Config.Bind("Timing", "WarningDuration", 1.5f, "Duration of warning animation"); OpenEyeDuration = ((BaseUnityPlugin)this).Config.Bind("Timing", "OpenEyeDuration", 0.5f, "How long eye stays open"); BetweenEyesDuration = ((BaseUnityPlugin)this).Config.Bind("Timing", "BetweenEyesDuration", 2f, "Time between each eye attack"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "CooldownTime", 60f, "Cooldown time in seconds before Litany can appear again"); ShakeSpeed = ((BaseUnityPlugin)this).Config.Bind("Visual", "ShakeSpeed", 0.05f, "Speed of Litany shaking (lower = faster)"); DomainChance = ((BaseUnityPlugin)this).Config.Bind("Domain", "DomainChance", 50, "Chance of Litany Domain event (0-100)"); DomainMinDelay = ((BaseUnityPlugin)this).Config.Bind("Domain", "DomainMinDelay", 30f, "Minimum time before event starts"); DomainMaxDelay = ((BaseUnityPlugin)this).Config.Bind("Domain", "DomainMaxDelay", 60f, "Maximum time before event starts"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Litany Entity loaded!"); harmony.PatchAll(); } }