using 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 SpawnChance; public static ConfigEntry MinSpawnTime; public static ConfigEntry MaxSpawnTime; public static ConfigEntry SeesaySpeed; public static ConfigEntry CooldownTime; public static ConfigEntry EnableTrainSound; public static ConfigEntry MinFollowTime; public static ConfigEntry MaxFollowTime; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnChance", 50, "Chance of Seesay appearing each round (0-100)"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MinSpawnTime", 30f, "Minimum time before Seesay appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MaxSpawnTime", 90f, "Maximum time before Seesay appears"); SeesaySpeed = ((BaseUnityPlugin)this).Config.Bind("General", "SeesaySpeed", 5f, "Speed of Seesay flying towards player"); CooldownTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "CooldownTime", 60f, "Cooldown time in seconds before Seesay can appear again"); MinFollowTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MinFollowTime", 3f, "Minimum time before Seesay opens its eye"); MaxFollowTime = ((BaseUnityPlugin)this).Config.Bind("Timing", "MaxFollowTime", 8f, "Maximum time before Seesay opens its eye"); EnableTrainSound = ((BaseUnityPlugin)this).Config.Bind("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.loop = false; audioSource.playOnAwake = false; audioSource.volume = 10f; audioSource.spatialBlend = 0f; flyingClip = LoadAudioClip("Flying.mp3"); flyingAudioSource = ((Component)this).gameObject.AddComponent(); 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(); 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(); ((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(); 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.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(); videoImage.texture = (Texture)(object)videoTexture; ((Graphic)videoImage).color = new Color(1f, 1f, 1f, 0f); RectTransform component = val4.GetComponent(); 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() != (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(); 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(); 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(); if ((Object)(object)seesayBehaviour != (Object)null) { seesayBehaviour.ResetSeesay(); } } } }