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 GraceEntities v1.1.0
BepInEx/plugins/DozerEntity.dll
Decompiled 2 weeks agousing System; 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; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DozerEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DozerEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("707b5311-bc50-4ec1-ac25-901818a7c6a1")] [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 DozerEntity; public class DozerBehaviour : MonoBehaviour { private enum DozerState { Hidden, ClosedEyes, OpenEyes, Screamer } 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 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_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)("Dozer Entity: звук не найден — " + text)); return null; } WWW val = new WWW("file://" + text); try { while (!val.isDone) { } return val.GetAudioClip(false, false, (AudioType)20); } finally { ((IDisposable)val)?.Dispose(); } } private void Start() { string pluginPath = Paths.PluginPath; string[] directories = Directory.GetDirectories(pluginPath, "DozerEntity", SearchOption.AllDirectories); if (directories.Length != 0) { modFolder = directories[0]; } else { modFolder = Path.Combine(pluginPath, "DozerEntity"); } Debug.Log((object)("Dozer Entity: папка мода — " + modFolder)); LoadSprites(); closedSound = LoadAudioClip("closed_sound.wav"); openSound = LoadAudioClip("open_sound.wav"); killSound = LoadAudioClip("kill_sound.wav"); audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.loop = true; audioSource.volume = 1f; CreateOverlay(); nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } private void LoadSprites() { for (int i = 0; i < 14; i++) { closedSprites[i] = LoadSprite("Closed_eyes" + (i + 1).ToString("D4") + ".png"); } for (int j = 0; j < 14; j++) { openSprites[j] = LoadSprite("Opened_eyes" + (j + 1).ToString("D4") + ".png"); } for (int k = 0; k < 50; k++) { screamerSprites[k] = LoadSprite("Kill" + (k + 1).ToString("D4") + ".png"); } for (int l = 0; l < 25; l++) { textSprites[l] = LoadSprite($"text{l + 1}.png"); } } public void ForceHide() { currentState = DozerState.Hidden; timer = 0f; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); AudioListener.volume = previousVolume; isOnCooldown = false; audioSource.Stop(); } 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)("Dozer 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() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if (currentState == DozerState.Hidden || currentState == DozerState.ClosedEyes || currentState == DozerState.OpenEyes) { previousVolume = AudioListener.volume; } 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 (val.isPlayerDead) { if (currentState != 0) { overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); audioSource.Stop(); currentState = DozerState.Hidden; timer = 0f; isOnCooldown = false; } } else { if (!IsPlayerInGame()) { return; } if (val.quickMenuManager.isMenuOpen) { overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); return; } timer += Time.deltaTime; switch (currentState) { case DozerState.Hidden: 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 (timer >= nextAppearTime) { ShowClosedEyes(); } break; case DozerState.ClosedEyes: AnimateClosed(); if (timer >= Plugin.EyeOpenDelay.Value) { OpenEyes(); } break; case DozerState.OpenEyes: AnimateOpen(); if (timer >= 0.1f && !IsPlayerSafe()) { TriggerScreamer(); } else if (timer >= Plugin.OpenEyesDuration.Value) { Hide(); } break; case DozerState.Screamer: AnimateScreamer(); AnimateText(); if (timer >= 2.05f) { KillPlayer(); } break; } } } private void AnimateClosed() { if (currentState != DozerState.ClosedEyes) { return; } animTimer += Time.deltaTime; if (animTimer >= animSpeed) { animTimer = 0f; animFrame = (animFrame + 1) % 14; if ((Object)(object)closedSprites[animFrame] != (Object)null) { overlayImage.sprite = closedSprites[animFrame]; } } } private void AnimateScreamer() { animTimer += Time.deltaTime; if (animTimer >= 0.05f) { animTimer = 0f; animFrame++; if (animFrame >= 50) { overlayObject.SetActive(false); } else if ((Object)(object)screamerSprites[animFrame] != (Object)null) { overlayImage.sprite = screamerSprites[animFrame]; } } } private void AnimateOpen() { animTimer += Time.deltaTime; if (animTimer >= 0.05f) { animTimer = 0f; animFrame = (animFrame + 1) % 14; if ((Object)(object)openSprites[animFrame] != (Object)null) { overlayImage.sprite = openSprites[animFrame]; } } } private void ShowClosedEyes() { currentState = DozerState.ClosedEyes; timer = 0f; animFrame = 0; animTimer = 0f; overlayObject.SetActive(true); if ((Object)(object)closedSprites[0] != (Object)null) { overlayImage.sprite = closedSprites[0]; } if ((Object)(object)closedSound != (Object)null) { audioSource.loop = true; audioSource.clip = closedSound; audioSource.Play(); } } private void OpenEyes() { currentState = DozerState.OpenEyes; timer = 0f; animFrame = 0; animTimer = 0f; if ((Object)(object)openSound != (Object)null) { audioSource.loop = false; audioSource.clip = openSound; audioSource.Play(); } if ((Object)(object)openSprites[0] != (Object)null) { overlayImage.sprite = openSprites[0]; } } private void TriggerScreamer() { currentState = DozerState.Screamer; timer = 0f; animFrame = 0; animTimer = 0f; textAnimFrame = 0; textAnimTimer = 0f; textAnimStarted = false; if ((Object)(object)textSprites[0] != (Object)null) { textImage.sprite = textSprites[0]; } textObject.SetActive(true); AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>(); val.loop = false; val.volume = 1f; if ((Object)(object)killSound != (Object)null) { val.clip = killSound; val.Play(); } AudioSource[] array = Object.FindObjectsOfType<AudioSource>(); AudioSource[] array2 = array; foreach (AudioSource val2 in array2) { if ((Object)(object)val2 != (Object)(object)val && (Object)(object)val2 != (Object)(object)audioSource) { val2.mute = true; } } ((Component)blackBackground).gameObject.SetActive(true); overlayObject.SetActive(false); overlayObject.SetActive(true); if ((Object)(object)screamerSprites[0] != (Object)null) { overlayImage.sprite = screamerSprites[0]; } } private void AnimateText() { textAnimTimer += Time.deltaTime; if (!textAnimStarted && textAnimTimer >= 1.5f) { textAnimStarted = true; textAnimTimer = 0f; textAnimFrame = 1; } if (!textAnimStarted) { return; } textAnimTimer += Time.deltaTime; if (textAnimTimer >= 0.0667f) { textAnimTimer = 0f; textAnimFrame++; if (textAnimFrame < 25 && (Object)(object)textSprites[textAnimFrame] != (Object)null) { textImage.sprite = textSprites[textAnimFrame]; } } } public void ResetDozer() { currentState = DozerState.Hidden; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); overlayObject.SetActive(false); } private void Hide() { currentState = DozerState.Hidden; timer = 0f; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); isOnCooldown = true; cooldownTimer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); audioSource.Stop(); } private void KillPlayer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController != (Object)null) { localPlayerController.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false); } AudioListener.volume = previousVolume; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); audioSource.Stop(); textObject.SetActive(false); currentState = DozerState.Hidden; timer = 0f; isOnCooldown = false; AudioSource[] array = Object.FindObjectsOfType<AudioSource>(); AudioSource[] array2 = array; foreach (AudioSource val in array2) { val.mute = false; } } private bool IsPlayerSafe() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return true; } bool isCrouching = val.isCrouching; Vector3 velocity = val.thisController.velocity; bool flag = ((Vector3)(ref velocity)).magnitude > 0.1f; return isCrouching && !flag; } 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DozerCanvas"); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 100; Object.DontDestroyOnLoad((Object)(object)val); GameObject val3 = new GameObject("DozerBlackBg"); val3.transform.SetParent(val.transform, false); blackBackground = val3.AddComponent<Image>(); ((Graphic)blackBackground).color = new Color(0f, 0f, 0f, 1f); RectTransform component = val3.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; val3.SetActive(false); overlayObject = new GameObject("DozerImage"); overlayObject.transform.SetParent(val.transform, false); overlayImage = overlayObject.AddComponent<Image>(); RectTransform component2 = overlayObject.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(600f, 600f); component2.anchoredPosition = Vector2.zero; GameObject val4 = new GameObject("DozerText"); val4.transform.SetParent(val.transform, false); textImage = val4.AddComponent<Image>(); RectTransform component3 = val4.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.sizeDelta = new Vector2(1000f, 1000f); component3.anchoredPosition = new Vector2(-320f, -60f); textObject = val4; textObject.SetActive(false); overlayObject.SetActive(false); } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class DozerPatch { private static void Postfix(PlayerControllerB __instance) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (((NetworkBehaviour)__instance).IsOwner && !((Object)(object)Object.FindObjectOfType<DozerBehaviour>() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Dozer Entity: не появится в этом раунде (бросок {num}, нужно < {Plugin.SpawnChance.Value})"); return; } GameObject val = new GameObject("DozerManager"); val.AddComponent<DozerBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)$"Dozer Entity: менеджер создан! (бросок {num})"); } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class DozerRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { DozerBehaviour dozerBehaviour = Object.FindObjectOfType<DozerBehaviour>(); if ((Object)(object)dozerBehaviour != (Object)null) { dozerBehaviour.ResetDozer(); Debug.Log((object)"Dozer Entity: сброс после возрождения!"); } } } } [BepInPlugin("com.yourname.dozerentity", "Dozer Entity", "1.0.1")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] public class DozerDeathPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { DozerBehaviour dozerBehaviour = Object.FindObjectOfType<DozerBehaviour>(); if ((Object)(object)dozerBehaviour != (Object)null) { dozerBehaviour.ForceHide(); } } } } private readonly Harmony harmony = new Harmony("com.yourname.dozerentity"); public static ConfigEntry<int> SpawnChance; public static ConfigEntry<float> EyeOpenDelay; public static ConfigEntry<float> OpenEyesDuration; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 35, "Dozer appear chance each round (0-100)"); EyeOpenDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "EyeOpenDelay", 1.5f, "Time in seconds before Dozer opens it's eyes"); OpenEyesDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "OpenEyesDuration", 3f, "How long Dozer stays with open eyes in seconds"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 10f, "Minimum time in seconds before Dozer appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 30f, "Maximum time in seconds before Dozer appears"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Dozer Entity загружен!"); harmony.PatchAll(); } }
BepInEx/plugins/KookooEntity.dll
Decompiled 2 weeks agousing System; 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; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("KookooEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("KookooEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("df24efe7-a262-4aa5-981a-01c019d26f0a")] [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 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 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 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() { string[] directories = Directory.GetDirectories(Paths.PluginPath, "KookooEntity", SearchOption.AllDirectories); modFolder = ((directories.Length != 0) ? directories[0] : Path.Combine(Paths.PluginPath, "KookooEntity")); 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.MinSpawnTime.Value, Plugin.MaxSpawnTime.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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) if (scanBlocked) { scanBlockTimer += Time.deltaTime; if (scanBlockTimer >= Plugin.ScanBlockDuration.Value) { scanBlocked = false; scanBlockTimer = 0f; } } if (scanAttackPlaying) { scanAttackTimer += Time.deltaTime; if (!(scanAttackTimer >= 0.5f)) { return; } scanAttackPlaying = false; rootObject.SetActive(false); ((Component)particlesImage).gameObject.SetActive(false); PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val != (Object)null) { int num = val.health - 1; if (num > 0) { val.DamagePlayer(num, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); } } scanBlocked = true; scanBlockTimer = 0f; return; } PlayerControllerB val2 = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val2 == (Object)null) { return; } 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 (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) { 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(); PlayerControllerB val3 = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val3 != (Object)null) { val3.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false); } Hide(); } else if (val2.isPlayerDead) { ForceHide(); } else { if (!IsPlayerInGame()) { return; } timer += Time.deltaTime; if (currentState != 0) { AnimateBody(); } switch (currentState) { case KookooState.Hidden: if (timer >= nextAppearTime) { Appear(); } break; case KookooState.Appearing: if (timer >= Plugin.AppearDuration.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 PlayScanError() { if ((Object)(object)scanErrorClip != (Object)null) { scanErrorSource.clip = scanErrorClip; scanErrorSource.Play(); } } public void TryTriggerScanAttack() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!scanAttackPlaying && Random.Range(0, Plugin.ScanAttackChance.Value) == 0) { scanAttackPlaying = true; scanAttackTimer = 0f; rootObject.SetActive(true); if ((Object)(object)closingSprites[3] != (Object)null) { bodyImage.sprite = closingSprites[3]; } ((Component)particlesImage).gameObject.SetActive(true); if ((Object)(object)scanDamageClip != (Object)null) { scanDamageSource.clip = scanDamageClip; scanDamageSource.Play(); } float num = Random.Range(-500f, 500f); float num2 = Random.Range(-250f, 250f); rootObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(num, num2); } } 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.CountInterval.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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) 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; Object.DontDestroyOnLoad((Object)(object)val); } 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.CooldownTime.Value; ((Component)particlesImage).gameObject.SetActive(false); rememberSource.Stop(); countSource.Stop(); checkSource.Stop(); killSource.Stop(); } public void ForceHide() { currentState = KookooState.Hidden; timer = 0f; rootObject.SetActive(false); isOnCooldown = false; ((Component)particlesImage).gameObject.SetActive(false); ((MonoBehaviour)this).CancelInvoke("StartClosing"); deathAnimPlaying = false; shouldSpawnErrorSprites = false; if ((Object)(object)deathCanvas != (Object)null) { deathCanvas.SetActive(false); } foreach (GameObject deathCopy in deathCopies) { 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(); rememberSource.Stop(); countSource.Stop(); checkSource.Stop(); killSource.Stop(); } public void ResetKookoo() { ForceHide(); nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); 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; } 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0295: 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; Object.DontDestroyOnLoad((Object)(object)val); deathCanvas = new GameObject("KookooDeathCanvas"); Canvas val3 = deathCanvas.AddComponent<Canvas>(); val3.renderMode = (RenderMode)0; val3.sortingOrder = 200; Object.DontDestroyOnLoad((Object)(object)deathCanvas); 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); } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class KookooPatch { 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<KookooBehaviour>() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Kookoo Entity: не появится в этом раунде (бросок {num})"); return; } GameObject val = new GameObject("KookooManager"); val.AddComponent<KookooBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)"Kookoo Entity: менеджер создан!"); } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class KookooRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { KookooBehaviour kookooBehaviour = Object.FindObjectOfType<KookooBehaviour>(); if ((Object)(object)kookooBehaviour != (Object)null) { kookooBehaviour.ResetKookoo(); } } } } [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(); } } } } [HarmonyPatch(typeof(HUDManager), "CanPlayerScan")] public class TestPatch { private static void Postfix() { Debug.Log((object)"MethodFinder: CanPlayerScan!"); } } public class KookooScanPatch { public static void OnScan() { Debug.Log((object)"Kookoo: скан нажат!"); KookooBehaviour kookooBehaviour = Object.FindObjectOfType<KookooBehaviour>(); if ((Object)(object)kookooBehaviour != (Object)null) { kookooBehaviour.TryTriggerScanAttack(); } } } [BepInPlugin("com.yourname.kookooentity", "Kookoo Entity", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.yourname.kookooentity"); public static ConfigEntry<int> SpawnChance; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; public static ConfigEntry<float> CooldownTime; public static ConfigEntry<float> AppearDuration; public static ConfigEntry<float> CountInterval; public static ConfigEntry<int> ScanAttackChance; public static ConfigEntry<float> ScanBlockDuration; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 50, "Chance of Kookoo appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 30f, "Minimum time before Kookoo appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 90f, "Maximum time before Kookoo appears"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CooldownTime", 60f, "Cooldown before Kookoo can appear again"); AppearDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "AppearDuration", 2f, "Time Kookoo shows the number before counting"); CountInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CountInterval", 1f, "Time between each count"); ScanAttackChance = ((BaseUnityPlugin)this).Config.Bind<int>("Scan", "ScanAttackChance", 5, "1 in X chance of Kookoo appearing on scan"); ScanBlockDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Scan", "ScanBlockDuration", 30f, "How long scan is blocked after Kookoo attack"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Kookoo Entity loaded!"); harmony.PatchAll(); } }
BepInEx/plugins/LitanyEntity.dll
Decompiled 2 weeks agousing 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<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_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<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_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<Canvas>(); 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<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); 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); } } 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<AudioSource>(); musicSource.loop = false; musicSource.playOnAwake = false; if ((Object)(object)musicClip != (Object)null) { musicSource.clip = musicClip; } orderBGSource = ((Component)this).gameObject.AddComponent<AudioSource>(); orderBGSource.loop = false; orderBGSource.playOnAwake = false; orderSource = ((Component)this).gameObject.AddComponent<AudioSource>(); 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<RectTransform>().anchoredPosition = new Vector2(textBasePosition.x + num, textBasePosition.y + num2); } } private void TriggerLitany() { LitanyBehaviour litanyBehaviour = Object.FindObjectOfType<LitanyBehaviour>(); 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<Canvas>(); 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<Image>(); RectTransform component = commandObject.GetComponent<RectTransform>(); 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 <ScheduleCoroutine>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public LitanyDomainNetwork <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ScheduleCoroutine>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<LitanyDomain>(); if ((Object)(object)litanyDomain != (Object)null) { litanyDomain.StartEvent(); } } public void ScheduleEventForAll(float delay) { ((MonoBehaviour)this).StartCoroutine(ScheduleCoroutine(delay)); } [IteratorStateMachine(typeof(<ScheduleCoroutine>d__4))] private IEnumerator ScheduleCoroutine(float delay) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ScheduleCoroutine>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<LitanyDomain>(); 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<LitanyDomainNetwork>(); 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<LitanyBehaviour>() != (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<LitanyBehaviour>(); 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<LitanyBehaviour>(); 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<LitanyBehaviour>(); 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<int> SpawnChance; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; public static ConfigEntry<float> PrepareDuration; public static ConfigEntry<float> WarningDuration; public static ConfigEntry<float> OpenEyeDuration; public static ConfigEntry<float> BetweenEyesDuration; public static ConfigEntry<float> CooldownTime; public static ConfigEntry<float> ShakeSpeed; public static ConfigEntry<int> DomainChance; public static ConfigEntry<float> DomainMinDelay; public static ConfigEntry<float> DomainMaxDelay; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 35, "Chance of Litany appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 10f, "Minimum time before Litany appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 30f, "Maximum time before Litany appears"); PrepareDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "PrepareDuration", 4f, "Time before first eye warning"); WarningDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "WarningDuration", 1.5f, "Duration of warning animation"); OpenEyeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "OpenEyeDuration", 0.5f, "How long eye stays open"); BetweenEyesDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "BetweenEyesDuration", 2f, "Time between each eye attack"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CooldownTime", 60f, "Cooldown time in seconds before Litany can appear again"); ShakeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "ShakeSpeed", 0.05f, "Speed of Litany shaking (lower = faster)"); DomainChance = ((BaseUnityPlugin)this).Config.Bind<int>("Domain", "DomainChance", 50, "Chance of Litany Domain event (0-100)"); DomainMinDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Domain", "DomainMinDelay", 30f, "Minimum time before event starts"); DomainMaxDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Domain", "DomainMaxDelay", 60f, "Maximum time before event starts"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Litany Entity loaded!"); harmony.PatchAll(); } }
BepInEx/plugins/SeesayEntity.dll
Decompiled 2 weeks agousing System; 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("SeesayEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SeesayEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e798d498-5a9e-440e-8887-01ec34d10e37")] [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 SeesayEntity; [BepInPlugin("com.yourname.seesayentity", "Seesay Entity", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.yourname.seesayentity"); public static ConfigEntry<int> SpawnChance; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; public static ConfigEntry<float> SeesaySpeed; public static ConfigEntry<float> CooldownTime; public static ConfigEntry<bool> EnableTrainSound; public static ConfigEntry<float> MinFollowTime; public static ConfigEntry<float> MaxFollowTime; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 50, "Chance of Seesay appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 30f, "Minimum time before Seesay appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 90f, "Maximum time before Seesay appears"); SeesaySpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SeesaySpeed", 5f, "Speed of Seesay flying towards player"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CooldownTime", 60f, "Cooldown time in seconds before Seesay can appear again"); MinFollowTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinFollowTime", 3f, "Minimum time before Seesay opens its eye"); MaxFollowTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxFollowTime", 8f, "Maximum time before Seesay opens its eye"); EnableTrainSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Fun", "EnableTrainSound", true, "Don't"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Seesay Entity loaded!"); harmony.PatchAll(); } } public class SeesayBehaviour : MonoBehaviour { private enum SeesayState { Hidden, Following, Opening, Flying, Screamer } private VideoPlayer videoPlayer; private RawImage videoImage; private RenderTexture videoTexture; private bool videoFinished = false; 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 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 void Start() { string[] directories = Directory.GetDirectories(Paths.PluginPath, "SeesayEntity", SearchOption.AllDirectories); modFolder = ((directories.Length != 0) ? directories[0] : Path.Combine(Paths.PluginPath, "SeesayEntity")); 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.MinSpawnTime.Value, Plugin.MaxSpawnTime.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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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); GameObject val = new GameObject("SeesayCanvas"); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 200; Object.DontDestroyOnLoad((Object)(object)val); 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); 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_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: 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 ((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 (isOnCooldown) { cooldownTimer += Time.deltaTime; if (cooldownTimer >= cooldownTime) { isOnCooldown = false; cooldownTimer = 0f; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } } else if (val.isPlayerDead) { ForceHide(); } else { if (!IsPlayerInGame()) { return; } timer += Time.deltaTime; switch (currentState) { case SeesayState.Hidden: if (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) { seesayObject.transform.rotation = ((Component)mainCamera).transform.rotation; } AnimateOpening(val); break; case SeesayState.Flying: if (isFlashed) { flashedTimer += Time.deltaTime; if (flashedTimer >= 0.5f) { Hide(); } return; } FlyTowardsPlayer(val); 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_001e: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)mainCamera == (Object)null)) { Vector3 val = ((Component)mainCamera).transform.position + ((Component)mainCamera).transform.forward * distanceFromCamera; seesayObject.transform.position = val + shakeOffset; seesayObject.transform.rotation = ((Component)mainCamera).transform.rotation; } } 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) currentState = SeesayState.Opening; timer = 0f; animFrame = 0; animTimer = 0f; animPaused = false; if ((Object)(object)mainCamera != (Object)null) { frozenWorldPos = ((Component)mainCamera).transform.position + ((Component)mainCamera).transform.forward * distanceFromCamera; } 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_006a: Unknown result type (might be due to invalid IL or missing references) 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_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) //IL_0074: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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; seesayObject.transform.position = Vector3.MoveTowards(seesayObject.transform.position, position, Plugin.SeesaySpeed.Value * Time.deltaTime); seesayObject.transform.rotation = ((Component)mainCamera).transform.rotation; if (IsFlashlightAimingAtSeesay(player)) { TriggerFlashed(); return; } float num = Vector3.Distance(seesayObject.transform.position, position); if (Plugin.EnableTrainSound.Value && num < 10f) { if ((Object)(object)trainClip != (Object)null && !trainAudioSource.isPlaying) { ((Component)trainAudioSource).transform.position = seesayObject.transform.position; trainAudioSource.clip = trainClip; trainAudioSource.Play(); } } else if (trainAudioSource.isPlaying) { trainAudioSource.Stop(); } ((Component)trainAudioSource).transform.position = seesayObject.transform.position; if (num < 0.5f) { TriggerScreamer(); } ((Component)flyingAudioSource).transform.position = seesayObject.transform.position; } private void TriggerScreamer() { //IL_006a: 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; 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) GrabbableObject[] itemSlots = player.ItemSlots; foreach (GrabbableObject val in itemSlots) { if (!((Object)(object)val != (Object)null)) { continue; } FlashlightItem val2 = (FlashlightItem)(object)((val is FlashlightItem) ? val : null); if (val2 != null && ((GrabbableObject)val2).isBeingUsed) { if ((Object)(object)mainCamera == (Object)null) { return false; } Vector3 val3 = mainCamera.WorldToViewportPoint(seesayObject.transform.position); if (val3.z > 0f && val3.x > 0.2f && val3.x < 0.8f && val3.y > 0.2f && val3.y < 0.8f) { return true; } } } if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; FlashlightItem val4 = (FlashlightItem)(object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null); if (val4 != null && ((GrabbableObject)val4).isBeingUsed) { if ((Object)(object)mainCamera == (Object)null) { return false; } Vector3 val5 = mainCamera.WorldToViewportPoint(seesayObject.transform.position); if (val5.z > 0f && val5.x > 0.2f && val5.x < 0.8f && val5.y > 0.2f && val5.y < 0.8f) { return true; } } } return false; } private void Appear(PlayerControllerB player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) currentState = SeesayState.Following; timer = 0f; seesayObject.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f); followDuration = Random.Range(Plugin.MinFollowTime.Value, Plugin.MaxFollowTime.Value); if ((Object)(object)appearClip != (Object)null) { audioSource.clip = appearClip; audioSource.Play(); } seesayObject.SetActive(true); if ((Object)(object)closedSprite != (Object)null) { spriteRenderer.sprite = closedSprite; } } private void Hide() { currentState = SeesayState.Hidden; timer = 0f; seesayObject.SetActive(false); isFlashed = false; isOnCooldown = true; cooldownTimer = 0f; cooldownTime = Plugin.CooldownTime.Value; flyingAudioSource.Stop(); trainAudioSource.Stop(); } public void ForceHide() { currentState = SeesayState.Hidden; timer = 0f; seesayObject.SetActive(false); isOnCooldown = false; } public void ResetSeesay() { currentState = SeesayState.Hidden; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.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; } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class SeesayPatch { 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<SeesayBehaviour>() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Seesay Entity: не появится в этом раунде (бросок {num})"); return; } GameObject val = new GameObject("SeesayManager"); val.AddComponent<SeesayBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)"Seesay Entity: менеджер создан!"); } } } [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(); } } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class SeesayRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { SeesayBehaviour seesayBehaviour = Object.FindObjectOfType<SeesayBehaviour>(); if ((Object)(object)seesayBehaviour != (Object)null) { seesayBehaviour.ResetSeesay(); } } } }
BepInEx/plugins/StemEntity.dll
Decompiled 2 weeks agousing System; 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 DozerEntity; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("StemEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("StemEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("dea806e2-4ea2-4416-8557-a5243135a1f3")] [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 StemEntity; [BepInPlugin("com.yourname.stementity", "Stem Entity", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.yourname.stementity"); public static ConfigEntry<int> SpawnChance; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; public static ConfigEntry<float> OpenEyeDuration; public static ConfigEntry<float> CooldownTime; public static ConfigEntry<float> OpeningPauseTime; public static ConfigEntry<float> CheckDelay; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 50, "Chance of Stem appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 30f, "Minimum time before Stem appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 90f, "Maximum time before Stem appears"); OpenEyeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "OpenEyeDuration", 3f, "How long Stem stays with open eye"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CooldownTime", 60f, "Cooldown before Stem can appear again"); OpeningPauseTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "OpeningPauseTime", 1f, "Pause duration at opening7"); CheckDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "CheckDelay", 0.1f, "Delay before checking sprint condition"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Stem Entity loaded!"); harmony.PatchAll(); } } public class StemBehaviour : MonoBehaviour { private enum StemState { Hidden, Opening, OpenEye } private List<List<GameObject>> vineChains = new List<List<GameObject>>(); private float[] vineAngles = new float[8]; private float[] vineCurves = new float[8]; private bool deathAnimPlaying = false; private float deathTimer = 0f; private float vineGrowTimer = 0f; private int[] vineSegmentCounts = new int[8]; private GameObject deathCanvas; private Vector2 stemScreenPos = Vector2.zero; private StemState currentState = StemState.Hidden; private float timer = 0f; private float nextAppearTime = 0f; private float shakeTimer = 0f; private float shakeSpeed = 0.05f; private Vector2 basePosition = new Vector2(-500f, -200f); private bool isOnCooldown = false; private float cooldownTimer = 0f; private float cooldownTime = 0f; private AudioSource audioSource; private AudioClip spawnClip; private AudioClip deathClip; private float animTimer = 0f; private int animFrame = 0; private bool animPaused = false; private float animPauseTimer = 0f; private float checkDelayTimer = 0f; private bool checkStarted = false; private GameObject rootObject; private Image eyeImage; private Sprite[] openingSprites = (Sprite[])(object)new Sprite[11]; private Sprite vineSprite; private string modFolder; private void Start() { string[] directories = Directory.GetDirectories(Paths.PluginPath, "StemEntity", SearchOption.AllDirectories); modFolder = ((directories.Length != 0) ? directories[0] : Path.Combine(Paths.PluginPath, "StemEntity")); LoadSprites(); CreateOverlay(); CreateDeathCanvas(); nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.loop = false; audioSource.playOnAwake = false; audioSource.volume = 1f; spawnClip = LoadAudioClip("spawn.mp3"); deathClip = LoadAudioClip("death.mp3"); } 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)("Stem 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() { //IL_0064: 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) for (int i = 0; i < 11; i++) { openingSprites[i] = LoadSprite($"opening{i + 1}.png"); } Texture2D val = LoadTexture("vine.png"); if ((Object)(object)val != (Object)null) { vineSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)1); } } private Texture2D LoadTexture(string filename) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown 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 val; } 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)("Stem 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_0097: 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_00a7: 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 == StemState.Opening) { Shake(); } if (deathAnimPlaying) { UpdateDeathAnim(); if (deathTimer >= 1f) { deathAnimPlaying = false; deathCanvas.SetActive(false); PlayerControllerB val2 = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val2 != (Object)null) { val2.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3), false); } Hide(); } } 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 (val.isPlayerDead) { ForceHide(); } else { if (!IsPlayerInGame()) { return; } timer += Time.deltaTime; switch (currentState) { case StemState.Hidden: if (timer >= nextAppearTime) { Appear(); } break; case StemState.Opening: Shake(); if (!IsScreenBusy()) { AnimateOpening(); } break; case StemState.OpenEye: if (!checkStarted) { checkDelayTimer += Time.deltaTime; if (checkDelayTimer >= Plugin.CheckDelay.Value) { checkStarted = true; } } else if (!IsPlayerSprinting(val)) { TriggerDeath(val); } else if (timer >= Plugin.OpenEyeDuration.Value) { Hide(); } break; } } } private bool IsScreenBusy() { GameObject val = GameObject.Find("DozerManager"); if ((Object)(object)val != (Object)null) { DozerBehaviour component = val.GetComponent<DozerBehaviour>(); GameObject val2 = GameObject.Find("DozerImage"); if ((Object)(object)val2 != (Object)null && val2.activeSelf) { return true; } } GameObject val3 = GameObject.Find("LitanyRoot"); if ((Object)(object)val3 != (Object)null && val3.activeSelf) { return true; } return false; } private void Shake() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) shakeTimer += Time.deltaTime; if (shakeTimer >= shakeSpeed) { 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 CreateDeathCanvas() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown deathCanvas = new GameObject("StemDeathCanvas"); Canvas val = deathCanvas.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 150; Object.DontDestroyOnLoad((Object)(object)deathCanvas); deathCanvas.SetActive(false); for (int i = 0; i < 8; i++) { vineAngles[i] = (float)i * 45f; vineChains.Add(new List<GameObject>()); } } private GameObject CreateVineSegment(int vineIndex, int segmentIndex) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_006f: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) float num = vineAngles[vineIndex]; float num2 = vineCurves[vineIndex]; GameObject val = new GameObject($"Vine_{vineIndex}_{segmentIndex}"); val.transform.SetParent(deathCanvas.transform, false); Image val2 = val.AddComponent<Image>(); val2.sprite = vineSprite; 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(600f, 600f); float num3 = (num + num2 * (float)segmentIndex * 0.3f) * ((float)Math.PI / 180f); float num4 = (float)segmentIndex * 200f; float num5 = stemScreenPos.x + Mathf.Cos(num3) * num4; float num6 = stemScreenPos.y + Mathf.Sin(num3) * num4; component.anchoredPosition = new Vector2(num5, num6); float num7 = num + num2 * (float)segmentIndex * 0.3f; ((Transform)component).localRotation = Quaternion.Euler(0f, 0f, num7 - 90f); return val; } private void UpdateDeathAnim() { deathTimer += Time.deltaTime; vineGrowTimer += Time.deltaTime; if (vineGrowTimer >= 0.06f) { vineGrowTimer = 0f; for (int i = 0; i < 8; i++) { int segmentIndex = vineSegmentCounts[i]; GameObject item = CreateVineSegment(i, segmentIndex); vineChains[i].Add(item); vineSegmentCounts[i]++; } } } private void AnimateOpening() { if (animPaused) { animPauseTimer += Time.deltaTime; if (animPauseTimer >= Plugin.OpeningPauseTime.Value) { animPaused = false; animPauseTimer = 0f; } return; } animTimer += Time.deltaTime; if (animTimer >= 0.0667f) { animTimer = 0f; animFrame++; if (animFrame == 6) { animPaused = true; eyeImage.sprite = openingSprites[6]; } else if (animFrame >= 10) { OpenEye(); } else if ((Object)(object)openingSprites[animFrame] != (Object)null) { eyeImage.sprite = openingSprites[animFrame]; } } } private void Appear() { if ((Object)(object)spawnClip != (Object)null) { audioSource.clip = spawnClip; audioSource.Play(); } currentState = StemState.Opening; timer = 0f; animFrame = 0; animTimer = 0f; animPaused = false; rootObject.SetActive(true); if ((Object)(object)openingSprites[0] != (Object)null) { eyeImage.sprite = openingSprites[0]; } } private void OpenEye() { currentState = StemState.OpenEye; timer = 0f; checkDelayTimer = 0f; checkStarted = false; if ((Object)(object)openingSprites[10] != (Object)null) { eyeImage.sprite = openingSprites[10]; } } private void TriggerDeath(PlayerControllerB player) { //IL_005a: 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) deathAnimPlaying = true; deathTimer = 0f; vineGrowTimer = 0f; if ((Object)(object)deathClip != (Object)null) { audioSource.clip = deathClip; audioSource.Play(); } stemScreenPos = rootObject.GetComponent<RectTransform>().anchoredPosition; for (int i = 0; i < 8; i++) { vineCurves[i] = Random.Range(-15f, 15f); vineSegmentCounts[i] = 0; foreach (GameObject item in vineChains[i]) { Object.Destroy((Object)(object)item); } vineChains[i].Clear(); } deathCanvas.SetActive(true); } private void Hide() { currentState = StemState.Hidden; timer = 0f; rootObject.SetActive(false); isOnCooldown = true; cooldownTimer = 0f; cooldownTime = Plugin.CooldownTime.Value; } public void ForceHide() { currentState = StemState.Hidden; timer = 0f; rootObject.SetActive(false); isOnCooldown = false; if (deathAnimPlaying) { deathAnimPlaying = false; deathCanvas.SetActive(false); } } private bool IsPlayerSprinting(PlayerControllerB player) { return player.isSprinting; } 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; } public void ResetStem() { currentState = StemState.Hidden; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); rootObject.SetActive(false); isOnCooldown = false; cooldownTimer = 0f; deathAnimPlaying = false; deathCanvas.SetActive(false); } 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("StemCanvas"); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 100; Object.DontDestroyOnLoad((Object)(object)val); rootObject = new GameObject("StemRoot"); 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(600f, 600f); val3.anchoredPosition = new Vector2(-500f, -200f); GameObject val4 = new GameObject("StemEye"); val4.transform.SetParent(rootObject.transform, false); eyeImage = val4.AddComponent<Image>(); RectTransform component = val4.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; rootObject.SetActive(false); } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class StemPatch { 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<StemBehaviour>() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Stem Entity: не появится в этом раунде (бросок {num})"); return; } GameObject val = new GameObject("StemManager"); val.AddComponent<StemBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)"Stem Entity: менеджер создан!"); } } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] public class StemDeathPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { StemBehaviour stemBehaviour = Object.FindObjectOfType<StemBehaviour>(); if ((Object)(object)stemBehaviour != (Object)null) { stemBehaviour.ForceHide(); } } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class StemRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { StemBehaviour stemBehaviour = Object.FindObjectOfType<StemBehaviour>(); if ((Object)(object)stemBehaviour != (Object)null) { stemBehaviour.ResetStem(); } } } }